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