xref: /linux/arch/mips/include/asm/asm.h (revision 9dbbc3b9d09d6deba9f3b9e1d5b355032ed46a75)
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 __VDSO__
24 /*
25  * Emit CFI data in .debug_frame sections, not .eh_frame sections.
26  * We don't do DWARF unwinding at runtime, so only the offline DWARF
27  * information is useful to anyone. Note we should change this if we
28  * ever decide to enable DWARF unwinding at runtime.
29  */
30 #define CFI_SECTIONS	.cfi_sections .debug_frame
31 #else
32  /*
33   * For the vDSO, emit both runtime unwind information and debug
34   * symbols for the .dbg file.
35   */
36 #define CFI_SECTIONS
37 #endif
38 
39 /*
40  * LEAF - declare leaf routine
41  */
42 #define LEAF(symbol)					\
43 		CFI_SECTIONS;				\
44 		.globl	symbol;				\
45 		.align	2;				\
46 		.type	symbol, @function;		\
47 		.ent	symbol, 0;			\
48 symbol:		.frame	sp, 0, ra;			\
49 		.cfi_startproc;				\
50 		.insn
51 
52 /*
53  * NESTED - declare nested routine entry point
54  */
55 #define NESTED(symbol, framesize, rpc)			\
56 		CFI_SECTIONS;				\
57 		.globl	symbol;				\
58 		.align	2;				\
59 		.type	symbol, @function;		\
60 		.ent	symbol, 0;			\
61 symbol:		.frame	sp, framesize, rpc;		\
62 		.cfi_startproc;				\
63 		.insn
64 
65 /*
66  * END - mark end of function
67  */
68 #define END(function)					\
69 		.cfi_endproc;				\
70 		.end	function;			\
71 		.size	function, .-function
72 
73 /*
74  * EXPORT - export definition of symbol
75  */
76 #define EXPORT(symbol)					\
77 		.globl	symbol;				\
78 symbol:
79 
80 /*
81  * FEXPORT - export definition of a function symbol
82  */
83 #define FEXPORT(symbol)					\
84 		.globl	symbol;				\
85 		.type	symbol, @function;		\
86 symbol:		.insn
87 
88 /*
89  * ABS - export absolute symbol
90  */
91 #define ABS(symbol,value)				\
92 		.globl	symbol;				\
93 symbol		=	value
94 
95 #define TEXT(msg)					\
96 		.pushsection .data;			\
97 8:		.asciiz msg;				\
98 		.popsection;
99 
100 #define ASM_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 ASM_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 ASM_PRINT(string)
122 #endif
123 
124 /*
125  * Stack alignment
126  */
127 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
128 #define ALSZ	7
129 #define ALMASK	~7
130 #endif
131 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
132 #define ALSZ	15
133 #define ALMASK	~15
134 #endif
135 
136 /*
137  * Macros to handle different pointer/register sizes for 32/64-bit code
138  */
139 
140 /*
141  * Size of a register
142  */
143 #ifdef __mips64
144 #define SZREG	8
145 #else
146 #define SZREG	4
147 #endif
148 
149 /*
150  * Use the following macros in assemblercode to load/store registers,
151  * pointers etc.
152  */
153 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
154 #define REG_S		sw
155 #define REG_L		lw
156 #define REG_SUBU	subu
157 #define REG_ADDU	addu
158 #endif
159 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
160 #define REG_S		sd
161 #define REG_L		ld
162 #define REG_SUBU	dsubu
163 #define REG_ADDU	daddu
164 #endif
165 
166 /*
167  * How to add/sub/load/store/shift C int variables.
168  */
169 #if (_MIPS_SZINT == 32)
170 #define INT_ADD		add
171 #define INT_ADDU	addu
172 #define INT_ADDI	addi
173 #define INT_ADDIU	addiu
174 #define INT_SUB		sub
175 #define INT_SUBU	subu
176 #define INT_L		lw
177 #define INT_S		sw
178 #define INT_SLL		sll
179 #define INT_SLLV	sllv
180 #define INT_SRL		srl
181 #define INT_SRLV	srlv
182 #define INT_SRA		sra
183 #define INT_SRAV	srav
184 #endif
185 
186 #if (_MIPS_SZINT == 64)
187 #define INT_ADD		dadd
188 #define INT_ADDU	daddu
189 #define INT_ADDI	daddi
190 #define INT_ADDIU	daddiu
191 #define INT_SUB		dsub
192 #define INT_SUBU	dsubu
193 #define INT_L		ld
194 #define INT_S		sd
195 #define INT_SLL		dsll
196 #define INT_SLLV	dsllv
197 #define INT_SRL		dsrl
198 #define INT_SRLV	dsrlv
199 #define INT_SRA		dsra
200 #define INT_SRAV	dsrav
201 #endif
202 
203 /*
204  * How to add/sub/load/store/shift C long variables.
205  */
206 #if (_MIPS_SZLONG == 32)
207 #define LONG_ADD	add
208 #define LONG_ADDU	addu
209 #define LONG_ADDI	addi
210 #define LONG_ADDIU	addiu
211 #define LONG_SUB	sub
212 #define LONG_SUBU	subu
213 #define LONG_L		lw
214 #define LONG_S		sw
215 #define LONG_SP		swp
216 #define LONG_SLL	sll
217 #define LONG_SLLV	sllv
218 #define LONG_SRL	srl
219 #define LONG_SRLV	srlv
220 #define LONG_SRA	sra
221 #define LONG_SRAV	srav
222 
223 #ifdef __ASSEMBLY__
224 #define LONG		.word
225 #endif
226 #define LONGSIZE	4
227 #define LONGMASK	3
228 #define LONGLOG		2
229 #endif
230 
231 #if (_MIPS_SZLONG == 64)
232 #define LONG_ADD	dadd
233 #define LONG_ADDU	daddu
234 #define LONG_ADDI	daddi
235 #define LONG_ADDIU	daddiu
236 #define LONG_SUB	dsub
237 #define LONG_SUBU	dsubu
238 #define LONG_L		ld
239 #define LONG_S		sd
240 #define LONG_SP		sdp
241 #define LONG_SLL	dsll
242 #define LONG_SLLV	dsllv
243 #define LONG_SRL	dsrl
244 #define LONG_SRLV	dsrlv
245 #define LONG_SRA	dsra
246 #define LONG_SRAV	dsrav
247 
248 #ifdef __ASSEMBLY__
249 #define LONG		.dword
250 #endif
251 #define LONGSIZE	8
252 #define LONGMASK	7
253 #define LONGLOG		3
254 #endif
255 
256 /*
257  * How to add/sub/load/store/shift pointers.
258  */
259 #if (_MIPS_SZPTR == 32)
260 #define PTR_ADD		add
261 #define PTR_ADDU	addu
262 #define PTR_ADDI	addi
263 #define PTR_ADDIU	addiu
264 #define PTR_SUB		sub
265 #define PTR_SUBU	subu
266 #define PTR_L		lw
267 #define PTR_S		sw
268 #define PTR_LA		la
269 #define PTR_LI		li
270 #define PTR_SLL		sll
271 #define PTR_SLLV	sllv
272 #define PTR_SRL		srl
273 #define PTR_SRLV	srlv
274 #define PTR_SRA		sra
275 #define PTR_SRAV	srav
276 
277 #define PTR_SCALESHIFT	2
278 
279 #define PTR		.word
280 #define PTRSIZE		4
281 #define PTRLOG		2
282 #endif
283 
284 #if (_MIPS_SZPTR == 64)
285 #define PTR_ADD		dadd
286 #define PTR_ADDU	daddu
287 #define PTR_ADDI	daddi
288 #define PTR_ADDIU	daddiu
289 #define PTR_SUB		dsub
290 #define PTR_SUBU	dsubu
291 #define PTR_L		ld
292 #define PTR_S		sd
293 #define PTR_LA		dla
294 #define PTR_LI		dli
295 #define PTR_SLL		dsll
296 #define PTR_SLLV	dsllv
297 #define PTR_SRL		dsrl
298 #define PTR_SRLV	dsrlv
299 #define PTR_SRA		dsra
300 #define PTR_SRAV	dsrav
301 
302 #define PTR_SCALESHIFT	3
303 
304 #define PTR		.dword
305 #define PTRSIZE		8
306 #define PTRLOG		3
307 #endif
308 
309 /*
310  * Some cp0 registers were extended to 64bit for MIPS III.
311  */
312 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
313 #define MFC0		mfc0
314 #define MTC0		mtc0
315 #endif
316 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
317 #define MFC0		dmfc0
318 #define MTC0		dmtc0
319 #endif
320 
321 #define SSNOP		sll zero, zero, 1
322 
323 #ifdef CONFIG_SGI_IP28
324 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
325 #include <asm/cacheops.h>
326 #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
327 #else
328 #define R10KCBARRIER(addr)
329 #endif
330 
331 #endif /* __ASM_ASM_H */
332