xref: /linux-6.15/arch/mips/include/asm/asm.h (revision fce362c7)
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  * Build text tables
117  */
118 #define TTABLE(string)					\
119 		.pushsection .text;			\
120 		.word	1f;				\
121 		.popsection				\
122 		.pushsection .data;			\
123 1:		.asciiz string;				\
124 		.popsection
125 
126 /*
127  * MIPS IV pref instruction.
128  * Use with .set noreorder only!
129  *
130  * MIPS IV implementations are free to treat this as a nop.  The R5000
131  * is one of them.  So we should have an option not to use this instruction.
132  */
133 #ifdef CONFIG_CPU_HAS_PREFETCH
134 
135 #define PREF(hint,addr)					\
136 		.set	push;				\
137 		.set	arch=r5000;			\
138 		pref	hint, addr;			\
139 		.set	pop
140 
141 #define PREFE(hint, addr)				\
142 		.set	push;				\
143 		.set	mips0;				\
144 		.set	eva;				\
145 		prefe	hint, addr;			\
146 		.set	pop
147 
148 #define PREFX(hint,addr)				\
149 		.set	push;				\
150 		.set	arch=r5000;			\
151 		prefx	hint, addr;			\
152 		.set	pop
153 
154 #else /* !CONFIG_CPU_HAS_PREFETCH */
155 
156 #define PREF(hint, addr)
157 #define PREFE(hint, addr)
158 #define PREFX(hint, addr)
159 
160 #endif /* !CONFIG_CPU_HAS_PREFETCH */
161 
162 /*
163  * Stack alignment
164  */
165 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
166 #define ALSZ	7
167 #define ALMASK	~7
168 #endif
169 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
170 #define ALSZ	15
171 #define ALMASK	~15
172 #endif
173 
174 /*
175  * Macros to handle different pointer/register sizes for 32/64-bit code
176  */
177 
178 /*
179  * Size of a register
180  */
181 #ifdef __mips64
182 #define SZREG	8
183 #else
184 #define SZREG	4
185 #endif
186 
187 /*
188  * Use the following macros in assemblercode to load/store registers,
189  * pointers etc.
190  */
191 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
192 #define REG_S		sw
193 #define REG_L		lw
194 #define REG_SUBU	subu
195 #define REG_ADDU	addu
196 #endif
197 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
198 #define REG_S		sd
199 #define REG_L		ld
200 #define REG_SUBU	dsubu
201 #define REG_ADDU	daddu
202 #endif
203 
204 /*
205  * How to add/sub/load/store/shift C int variables.
206  */
207 #if (_MIPS_SZINT == 32)
208 #define INT_ADD		add
209 #define INT_ADDU	addu
210 #define INT_ADDI	addi
211 #define INT_ADDIU	addiu
212 #define INT_SUB		sub
213 #define INT_SUBU	subu
214 #define INT_L		lw
215 #define INT_S		sw
216 #define INT_SLL		sll
217 #define INT_SLLV	sllv
218 #define INT_SRL		srl
219 #define INT_SRLV	srlv
220 #define INT_SRA		sra
221 #define INT_SRAV	srav
222 #endif
223 
224 #if (_MIPS_SZINT == 64)
225 #define INT_ADD		dadd
226 #define INT_ADDU	daddu
227 #define INT_ADDI	daddi
228 #define INT_ADDIU	daddiu
229 #define INT_SUB		dsub
230 #define INT_SUBU	dsubu
231 #define INT_L		ld
232 #define INT_S		sd
233 #define INT_SLL		dsll
234 #define INT_SLLV	dsllv
235 #define INT_SRL		dsrl
236 #define INT_SRLV	dsrlv
237 #define INT_SRA		dsra
238 #define INT_SRAV	dsrav
239 #endif
240 
241 /*
242  * How to add/sub/load/store/shift C long variables.
243  */
244 #if (_MIPS_SZLONG == 32)
245 #define LONG_ADD	add
246 #define LONG_ADDU	addu
247 #define LONG_ADDI	addi
248 #define LONG_ADDIU	addiu
249 #define LONG_SUB	sub
250 #define LONG_SUBU	subu
251 #define LONG_L		lw
252 #define LONG_S		sw
253 #define LONG_SP		swp
254 #define LONG_SLL	sll
255 #define LONG_SLLV	sllv
256 #define LONG_SRL	srl
257 #define LONG_SRLV	srlv
258 #define LONG_SRA	sra
259 #define LONG_SRAV	srav
260 
261 #define LONG		.word
262 #define LONGSIZE	4
263 #define LONGMASK	3
264 #define LONGLOG		2
265 #endif
266 
267 #if (_MIPS_SZLONG == 64)
268 #define LONG_ADD	dadd
269 #define LONG_ADDU	daddu
270 #define LONG_ADDI	daddi
271 #define LONG_ADDIU	daddiu
272 #define LONG_SUB	dsub
273 #define LONG_SUBU	dsubu
274 #define LONG_L		ld
275 #define LONG_S		sd
276 #define LONG_SP		sdp
277 #define LONG_SLL	dsll
278 #define LONG_SLLV	dsllv
279 #define LONG_SRL	dsrl
280 #define LONG_SRLV	dsrlv
281 #define LONG_SRA	dsra
282 #define LONG_SRAV	dsrav
283 
284 #define LONG		.dword
285 #define LONGSIZE	8
286 #define LONGMASK	7
287 #define LONGLOG		3
288 #endif
289 
290 /*
291  * How to add/sub/load/store/shift pointers.
292  */
293 #if (_MIPS_SZPTR == 32)
294 #define PTR_ADD		add
295 #define PTR_ADDU	addu
296 #define PTR_ADDI	addi
297 #define PTR_ADDIU	addiu
298 #define PTR_SUB		sub
299 #define PTR_SUBU	subu
300 #define PTR_L		lw
301 #define PTR_S		sw
302 #define PTR_LA		la
303 #define PTR_LI		li
304 #define PTR_SLL		sll
305 #define PTR_SLLV	sllv
306 #define PTR_SRL		srl
307 #define PTR_SRLV	srlv
308 #define PTR_SRA		sra
309 #define PTR_SRAV	srav
310 
311 #define PTR_SCALESHIFT	2
312 
313 #define PTR		.word
314 #define PTRSIZE		4
315 #define PTRLOG		2
316 #endif
317 
318 #if (_MIPS_SZPTR == 64)
319 #define PTR_ADD		dadd
320 #define PTR_ADDU	daddu
321 #define PTR_ADDI	daddi
322 #define PTR_ADDIU	daddiu
323 #define PTR_SUB		dsub
324 #define PTR_SUBU	dsubu
325 #define PTR_L		ld
326 #define PTR_S		sd
327 #define PTR_LA		dla
328 #define PTR_LI		dli
329 #define PTR_SLL		dsll
330 #define PTR_SLLV	dsllv
331 #define PTR_SRL		dsrl
332 #define PTR_SRLV	dsrlv
333 #define PTR_SRA		dsra
334 #define PTR_SRAV	dsrav
335 
336 #define PTR_SCALESHIFT	3
337 
338 #define PTR		.dword
339 #define PTRSIZE		8
340 #define PTRLOG		3
341 #endif
342 
343 /*
344  * Some cp0 registers were extended to 64bit for MIPS III.
345  */
346 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
347 #define MFC0		mfc0
348 #define MTC0		mtc0
349 #endif
350 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
351 #define MFC0		dmfc0
352 #define MTC0		dmtc0
353 #endif
354 
355 #define SSNOP		sll zero, zero, 1
356 
357 #ifdef CONFIG_SGI_IP28
358 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
359 #include <asm/cacheops.h>
360 #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
361 #else
362 #define R10KCBARRIER(addr)
363 #endif
364 
365 #endif /* __ASM_ASM_H */
366