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