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