xref: /linux-6.15/arch/mips/include/asm/asm.h (revision 7b2d13f2)
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  * Stack alignment
181  */
182 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
183 #define ALSZ	7
184 #define ALMASK	~7
185 #endif
186 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
187 #define ALSZ	15
188 #define ALMASK	~15
189 #endif
190 
191 /*
192  * Macros to handle different pointer/register sizes for 32/64-bit code
193  */
194 
195 /*
196  * Size of a register
197  */
198 #ifdef __mips64
199 #define SZREG	8
200 #else
201 #define SZREG	4
202 #endif
203 
204 /*
205  * Use the following macros in assemblercode to load/store registers,
206  * pointers etc.
207  */
208 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
209 #define REG_S		sw
210 #define REG_L		lw
211 #define REG_SUBU	subu
212 #define REG_ADDU	addu
213 #endif
214 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
215 #define REG_S		sd
216 #define REG_L		ld
217 #define REG_SUBU	dsubu
218 #define REG_ADDU	daddu
219 #endif
220 
221 /*
222  * How to add/sub/load/store/shift C int variables.
223  */
224 #if (_MIPS_SZINT == 32)
225 #define INT_ADD		add
226 #define INT_ADDU	addu
227 #define INT_ADDI	addi
228 #define INT_ADDIU	addiu
229 #define INT_SUB		sub
230 #define INT_SUBU	subu
231 #define INT_L		lw
232 #define INT_S		sw
233 #define INT_SLL		sll
234 #define INT_SLLV	sllv
235 #define INT_SRL		srl
236 #define INT_SRLV	srlv
237 #define INT_SRA		sra
238 #define INT_SRAV	srav
239 #endif
240 
241 #if (_MIPS_SZINT == 64)
242 #define INT_ADD		dadd
243 #define INT_ADDU	daddu
244 #define INT_ADDI	daddi
245 #define INT_ADDIU	daddiu
246 #define INT_SUB		dsub
247 #define INT_SUBU	dsubu
248 #define INT_L		ld
249 #define INT_S		sd
250 #define INT_SLL		dsll
251 #define INT_SLLV	dsllv
252 #define INT_SRL		dsrl
253 #define INT_SRLV	dsrlv
254 #define INT_SRA		dsra
255 #define INT_SRAV	dsrav
256 #endif
257 
258 /*
259  * How to add/sub/load/store/shift C long variables.
260  */
261 #if (_MIPS_SZLONG == 32)
262 #define LONG_ADD	add
263 #define LONG_ADDU	addu
264 #define LONG_ADDI	addi
265 #define LONG_ADDIU	addiu
266 #define LONG_SUB	sub
267 #define LONG_SUBU	subu
268 #define LONG_L		lw
269 #define LONG_S		sw
270 #define LONG_SP		swp
271 #define LONG_SLL	sll
272 #define LONG_SLLV	sllv
273 #define LONG_SRL	srl
274 #define LONG_SRLV	srlv
275 #define LONG_SRA	sra
276 #define LONG_SRAV	srav
277 
278 #define LONG		.word
279 #define LONGSIZE	4
280 #define LONGMASK	3
281 #define LONGLOG		2
282 #endif
283 
284 #if (_MIPS_SZLONG == 64)
285 #define LONG_ADD	dadd
286 #define LONG_ADDU	daddu
287 #define LONG_ADDI	daddi
288 #define LONG_ADDIU	daddiu
289 #define LONG_SUB	dsub
290 #define LONG_SUBU	dsubu
291 #define LONG_L		ld
292 #define LONG_S		sd
293 #define LONG_SP		sdp
294 #define LONG_SLL	dsll
295 #define LONG_SLLV	dsllv
296 #define LONG_SRL	dsrl
297 #define LONG_SRLV	dsrlv
298 #define LONG_SRA	dsra
299 #define LONG_SRAV	dsrav
300 
301 #define LONG		.dword
302 #define LONGSIZE	8
303 #define LONGMASK	7
304 #define LONGLOG		3
305 #endif
306 
307 /*
308  * How to add/sub/load/store/shift pointers.
309  */
310 #if (_MIPS_SZPTR == 32)
311 #define PTR_ADD		add
312 #define PTR_ADDU	addu
313 #define PTR_ADDI	addi
314 #define PTR_ADDIU	addiu
315 #define PTR_SUB		sub
316 #define PTR_SUBU	subu
317 #define PTR_L		lw
318 #define PTR_S		sw
319 #define PTR_LA		la
320 #define PTR_LI		li
321 #define PTR_SLL		sll
322 #define PTR_SLLV	sllv
323 #define PTR_SRL		srl
324 #define PTR_SRLV	srlv
325 #define PTR_SRA		sra
326 #define PTR_SRAV	srav
327 
328 #define PTR_SCALESHIFT	2
329 
330 #define PTR		.word
331 #define PTRSIZE		4
332 #define PTRLOG		2
333 #endif
334 
335 #if (_MIPS_SZPTR == 64)
336 #define PTR_ADD		dadd
337 #define PTR_ADDU	daddu
338 #define PTR_ADDI	daddi
339 #define PTR_ADDIU	daddiu
340 #define PTR_SUB		dsub
341 #define PTR_SUBU	dsubu
342 #define PTR_L		ld
343 #define PTR_S		sd
344 #define PTR_LA		dla
345 #define PTR_LI		dli
346 #define PTR_SLL		dsll
347 #define PTR_SLLV	dsllv
348 #define PTR_SRL		dsrl
349 #define PTR_SRLV	dsrlv
350 #define PTR_SRA		dsra
351 #define PTR_SRAV	dsrav
352 
353 #define PTR_SCALESHIFT	3
354 
355 #define PTR		.dword
356 #define PTRSIZE		8
357 #define PTRLOG		3
358 #endif
359 
360 /*
361  * Some cp0 registers were extended to 64bit for MIPS III.
362  */
363 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
364 #define MFC0		mfc0
365 #define MTC0		mtc0
366 #endif
367 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
368 #define MFC0		dmfc0
369 #define MTC0		dmtc0
370 #endif
371 
372 #define SSNOP		sll zero, zero, 1
373 
374 #ifdef CONFIG_SGI_IP28
375 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
376 #include <asm/cacheops.h>
377 #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
378 #else
379 #define R10KCBARRIER(addr)
380 #endif
381 
382 #endif /* __ASM_ASM_H */
383