xref: /openbmc/linux/arch/mips/include/asm/asm.h (revision 160b8e75)
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
7  * Copyright (C) 1999 by Silicon Graphics, Inc.
8  * Copyright (C) 2001 MIPS Technologies, Inc.
9  * Copyright (C) 2002  Maciej W. Rozycki
10  *
11  * Some useful macros for MIPS assembler code
12  *
13  * Some of the routines below contain useless nops that will be optimized
14  * away by gas in -O mode. These nops are however required to fill delay
15  * slots in noreorder mode.
16  */
17 #ifndef __ASM_ASM_H
18 #define __ASM_ASM_H
19 
20 #include <asm/sgidefs.h>
21 #include <asm/asm-eva.h>
22 
23 #ifndef CAT
24 #ifdef __STDC__
25 #define __CAT(str1, str2) str1##str2
26 #else
27 #define __CAT(str1, str2) str1/**/str2
28 #endif
29 #define CAT(str1, str2) __CAT(str1, str2)
30 #endif
31 
32 /*
33  * PIC specific declarations
34  * Not used for the kernel but here seems to be the right place.
35  */
36 #ifdef __PIC__
37 #define CPRESTORE(register)				\
38 		.cprestore register
39 #define CPADD(register)					\
40 		.cpadd	register
41 #define CPLOAD(register)				\
42 		.cpload register
43 #else
44 #define CPRESTORE(register)
45 #define CPADD(register)
46 #define CPLOAD(register)
47 #endif
48 
49 /*
50  * LEAF - declare leaf routine
51  */
52 #define LEAF(symbol)					\
53 		.globl	symbol;				\
54 		.align	2;				\
55 		.type	symbol, @function;		\
56 		.ent	symbol, 0;			\
57 symbol:		.frame	sp, 0, ra;			\
58 		.cfi_startproc;				\
59 		.insn
60 
61 /*
62  * NESTED - declare nested routine entry point
63  */
64 #define NESTED(symbol, framesize, rpc)			\
65 		.globl	symbol;				\
66 		.align	2;				\
67 		.type	symbol, @function;		\
68 		.ent	symbol, 0;			\
69 symbol:		.frame	sp, framesize, rpc;		\
70 		.cfi_startproc;				\
71 		.insn
72 
73 /*
74  * END - mark end of function
75  */
76 #define END(function)					\
77 		.cfi_endproc;				\
78 		.end	function;			\
79 		.size	function, .-function
80 
81 /*
82  * EXPORT - export definition of symbol
83  */
84 #define EXPORT(symbol)					\
85 		.globl	symbol;				\
86 symbol:
87 
88 /*
89  * FEXPORT - export definition of a function symbol
90  */
91 #define FEXPORT(symbol)					\
92 		.globl	symbol;				\
93 		.type	symbol, @function;		\
94 symbol:		.insn
95 
96 /*
97  * ABS - export absolute symbol
98  */
99 #define ABS(symbol,value)				\
100 		.globl	symbol;				\
101 symbol		=	value
102 
103 #define PANIC(msg)					\
104 		.set	push;				\
105 		.set	reorder;			\
106 		PTR_LA	a0, 8f;				 \
107 		jal	panic;				\
108 9:		b	9b;				\
109 		.set	pop;				\
110 		TEXT(msg)
111 
112 /*
113  * Print formatted string
114  */
115 #ifdef CONFIG_PRINTK
116 #define PRINT(string)					\
117 		.set	push;				\
118 		.set	reorder;			\
119 		PTR_LA	a0, 8f;				 \
120 		jal	printk;				\
121 		.set	pop;				\
122 		TEXT(string)
123 #else
124 #define PRINT(string)
125 #endif
126 
127 #define TEXT(msg)					\
128 		.pushsection .data;			\
129 8:		.asciiz msg;				\
130 		.popsection;
131 
132 /*
133  * Build text tables
134  */
135 #define TTABLE(string)					\
136 		.pushsection .text;			\
137 		.word	1f;				\
138 		.popsection				\
139 		.pushsection .data;			\
140 1:		.asciiz string;				\
141 		.popsection
142 
143 /*
144  * MIPS IV pref instruction.
145  * Use with .set noreorder only!
146  *
147  * MIPS IV implementations are free to treat this as a nop.  The R5000
148  * is one of them.  So we should have an option not to use this instruction.
149  */
150 #ifdef CONFIG_CPU_HAS_PREFETCH
151 
152 #define PREF(hint,addr)					\
153 		.set	push;				\
154 		.set	arch=r5000;			\
155 		pref	hint, addr;			\
156 		.set	pop
157 
158 #define PREFE(hint, addr)				\
159 		.set	push;				\
160 		.set	mips0;				\
161 		.set	eva;				\
162 		prefe	hint, addr;			\
163 		.set	pop
164 
165 #define PREFX(hint,addr)				\
166 		.set	push;				\
167 		.set	arch=r5000;			\
168 		prefx	hint, addr;			\
169 		.set	pop
170 
171 #else /* !CONFIG_CPU_HAS_PREFETCH */
172 
173 #define PREF(hint, addr)
174 #define PREFE(hint, addr)
175 #define PREFX(hint, addr)
176 
177 #endif /* !CONFIG_CPU_HAS_PREFETCH */
178 
179 /*
180  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
181  */
182 #if (_MIPS_ISA == _MIPS_ISA_MIPS1)
183 #define MOVN(rd, rs, rt)				\
184 		.set	push;				\
185 		.set	reorder;			\
186 		beqz	rt, 9f;				\
187 		move	rd, rs;				\
188 		.set	pop;				\
189 9:
190 #define MOVZ(rd, rs, rt)				\
191 		.set	push;				\
192 		.set	reorder;			\
193 		bnez	rt, 9f;				\
194 		move	rd, rs;				\
195 		.set	pop;				\
196 9:
197 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
198 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
199 #define MOVN(rd, rs, rt)				\
200 		.set	push;				\
201 		.set	noreorder;			\
202 		bnezl	rt, 9f;				\
203 		 move	rd, rs;				\
204 		.set	pop;				\
205 9:
206 #define MOVZ(rd, rs, rt)				\
207 		.set	push;				\
208 		.set	noreorder;			\
209 		beqzl	rt, 9f;				\
210 		 move	rd, rs;				\
211 		.set	pop;				\
212 9:
213 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
214 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
215     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
216 #define MOVN(rd, rs, rt)				\
217 		movn	rd, rs, rt
218 #define MOVZ(rd, rs, rt)				\
219 		movz	rd, rs, rt
220 #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
221 
222 /*
223  * Stack alignment
224  */
225 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
226 #define ALSZ	7
227 #define ALMASK	~7
228 #endif
229 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
230 #define ALSZ	15
231 #define ALMASK	~15
232 #endif
233 
234 /*
235  * Macros to handle different pointer/register sizes for 32/64-bit code
236  */
237 
238 /*
239  * Size of a register
240  */
241 #ifdef __mips64
242 #define SZREG	8
243 #else
244 #define SZREG	4
245 #endif
246 
247 /*
248  * Use the following macros in assemblercode to load/store registers,
249  * pointers etc.
250  */
251 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
252 #define REG_S		sw
253 #define REG_L		lw
254 #define REG_SUBU	subu
255 #define REG_ADDU	addu
256 #endif
257 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
258 #define REG_S		sd
259 #define REG_L		ld
260 #define REG_SUBU	dsubu
261 #define REG_ADDU	daddu
262 #endif
263 
264 /*
265  * How to add/sub/load/store/shift C int variables.
266  */
267 #if (_MIPS_SZINT == 32)
268 #define INT_ADD		add
269 #define INT_ADDU	addu
270 #define INT_ADDI	addi
271 #define INT_ADDIU	addiu
272 #define INT_SUB		sub
273 #define INT_SUBU	subu
274 #define INT_L		lw
275 #define INT_S		sw
276 #define INT_SLL		sll
277 #define INT_SLLV	sllv
278 #define INT_SRL		srl
279 #define INT_SRLV	srlv
280 #define INT_SRA		sra
281 #define INT_SRAV	srav
282 #endif
283 
284 #if (_MIPS_SZINT == 64)
285 #define INT_ADD		dadd
286 #define INT_ADDU	daddu
287 #define INT_ADDI	daddi
288 #define INT_ADDIU	daddiu
289 #define INT_SUB		dsub
290 #define INT_SUBU	dsubu
291 #define INT_L		ld
292 #define INT_S		sd
293 #define INT_SLL		dsll
294 #define INT_SLLV	dsllv
295 #define INT_SRL		dsrl
296 #define INT_SRLV	dsrlv
297 #define INT_SRA		dsra
298 #define INT_SRAV	dsrav
299 #endif
300 
301 /*
302  * How to add/sub/load/store/shift C long variables.
303  */
304 #if (_MIPS_SZLONG == 32)
305 #define LONG_ADD	add
306 #define LONG_ADDU	addu
307 #define LONG_ADDI	addi
308 #define LONG_ADDIU	addiu
309 #define LONG_SUB	sub
310 #define LONG_SUBU	subu
311 #define LONG_L		lw
312 #define LONG_S		sw
313 #define LONG_SP		swp
314 #define LONG_SLL	sll
315 #define LONG_SLLV	sllv
316 #define LONG_SRL	srl
317 #define LONG_SRLV	srlv
318 #define LONG_SRA	sra
319 #define LONG_SRAV	srav
320 
321 #define LONG		.word
322 #define LONGSIZE	4
323 #define LONGMASK	3
324 #define LONGLOG		2
325 #endif
326 
327 #if (_MIPS_SZLONG == 64)
328 #define LONG_ADD	dadd
329 #define LONG_ADDU	daddu
330 #define LONG_ADDI	daddi
331 #define LONG_ADDIU	daddiu
332 #define LONG_SUB	dsub
333 #define LONG_SUBU	dsubu
334 #define LONG_L		ld
335 #define LONG_S		sd
336 #define LONG_SP		sdp
337 #define LONG_SLL	dsll
338 #define LONG_SLLV	dsllv
339 #define LONG_SRL	dsrl
340 #define LONG_SRLV	dsrlv
341 #define LONG_SRA	dsra
342 #define LONG_SRAV	dsrav
343 
344 #define LONG		.dword
345 #define LONGSIZE	8
346 #define LONGMASK	7
347 #define LONGLOG		3
348 #endif
349 
350 /*
351  * How to add/sub/load/store/shift pointers.
352  */
353 #if (_MIPS_SZPTR == 32)
354 #define PTR_ADD		add
355 #define PTR_ADDU	addu
356 #define PTR_ADDI	addi
357 #define PTR_ADDIU	addiu
358 #define PTR_SUB		sub
359 #define PTR_SUBU	subu
360 #define PTR_L		lw
361 #define PTR_S		sw
362 #define PTR_LA		la
363 #define PTR_LI		li
364 #define PTR_SLL		sll
365 #define PTR_SLLV	sllv
366 #define PTR_SRL		srl
367 #define PTR_SRLV	srlv
368 #define PTR_SRA		sra
369 #define PTR_SRAV	srav
370 
371 #define PTR_SCALESHIFT	2
372 
373 #define PTR		.word
374 #define PTRSIZE		4
375 #define PTRLOG		2
376 #endif
377 
378 #if (_MIPS_SZPTR == 64)
379 #define PTR_ADD		dadd
380 #define PTR_ADDU	daddu
381 #define PTR_ADDI	daddi
382 #define PTR_ADDIU	daddiu
383 #define PTR_SUB		dsub
384 #define PTR_SUBU	dsubu
385 #define PTR_L		ld
386 #define PTR_S		sd
387 #define PTR_LA		dla
388 #define PTR_LI		dli
389 #define PTR_SLL		dsll
390 #define PTR_SLLV	dsllv
391 #define PTR_SRL		dsrl
392 #define PTR_SRLV	dsrlv
393 #define PTR_SRA		dsra
394 #define PTR_SRAV	dsrav
395 
396 #define PTR_SCALESHIFT	3
397 
398 #define PTR		.dword
399 #define PTRSIZE		8
400 #define PTRLOG		3
401 #endif
402 
403 /*
404  * Some cp0 registers were extended to 64bit for MIPS III.
405  */
406 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
407 #define MFC0		mfc0
408 #define MTC0		mtc0
409 #endif
410 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
411 #define MFC0		dmfc0
412 #define MTC0		dmtc0
413 #endif
414 
415 #define SSNOP		sll zero, zero, 1
416 
417 #ifdef CONFIG_SGI_IP28
418 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
419 #include <asm/cacheops.h>
420 #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
421 #else
422 #define R10KCBARRIER(addr)
423 #endif
424 
425 #endif /* __ASM_ASM_H */
426