xref: /openbmc/u-boot/arch/mips/include/asm/asm.h (revision 61a4392a)
1 /*
2  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
3  * Copyright (C) 1999 by Silicon Graphics, Inc.
4  * Copyright (C) 2001 MIPS Technologies, Inc.
5  * Copyright (C) 2002  Maciej W. Rozycki
6  *
7  * Some useful macros for MIPS assembler code
8  *
9  * Some of the routines below contain useless nops that will be optimized
10  * away by gas in -O mode. These nops are however required to fill delay
11  * slots in noreorder mode.
12  *
13  * SPDX-License-Identifier:	GPL-2.0
14  */
15 #ifndef __ASM_ASM_H
16 #define __ASM_ASM_H
17 
18 #include <asm/sgidefs.h>
19 
20 #ifndef CAT
21 #ifdef __STDC__
22 #define __CAT(str1, str2) str1##str2
23 #else
24 #define __CAT(str1, str2) str1/**/str2
25 #endif
26 #define CAT(str1, str2) __CAT(str1, str2)
27 #endif
28 
29 /*
30  * PIC specific declarations
31  * Not used for the kernel but here seems to be the right place.
32  */
33 #ifdef __PIC__
34 #define CPRESTORE(register)				\
35 		.cprestore register
36 #define CPADD(register)					\
37 		.cpadd	register
38 #define CPLOAD(register)				\
39 		.cpload register
40 #else
41 #define CPRESTORE(register)
42 #define CPADD(register)
43 #define CPLOAD(register)
44 #endif
45 
46 #define ENTRY(symbol)					\
47 		.globl	symbol;				\
48 		.type	symbol, @function;		\
49 		.ent	symbol, 0;			\
50 symbol:
51 
52 /*
53  * LEAF - declare leaf routine
54  */
55 #define LEAF(symbol)					\
56 		.globl	symbol;				\
57 		.align	2;				\
58 		.type	symbol, @function;		\
59 		.ent	symbol, 0;			\
60 		.section .text.symbol, "x";             \
61 symbol:		.frame	sp, 0, ra
62 
63 /*
64  * NESTED - declare nested routine entry point
65  */
66 #define NESTED(symbol, framesize, rpc)			\
67 		.globl	symbol;				\
68 		.align	2;				\
69 		.type	symbol, @function;		\
70 		.ent	symbol, 0;			\
71 		.section .text.symbol, "x";             \
72 symbol:		.frame	sp, framesize, rpc
73 
74 /*
75  * END - mark end of function
76  */
77 #define END(function)					\
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:
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  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
181  */
182 #if (_MIPS_ISA == _MIPS_ISA_MIPS1)
183 #define MOVN(rd, rs, rt)				\
184 		.set	push;				\
185 		.set	reorder;			\
186 		beqz	rt, 9f;				\
187 		move	rd, rs;				\
188 		.set	pop;				\
189 9:
190 #define MOVZ(rd, rs, rt)				\
191 		.set	push;				\
192 		.set	reorder;			\
193 		bnez	rt, 9f;				\
194 		move	rd, rs;				\
195 		.set	pop;				\
196 9:
197 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
198 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
199 #define MOVN(rd, rs, rt)				\
200 		.set	push;				\
201 		.set	noreorder;			\
202 		bnezl	rt, 9f;				\
203 		 move	rd, rs;				\
204 		.set	pop;				\
205 9:
206 #define MOVZ(rd, rs, rt)				\
207 		.set	push;				\
208 		.set	noreorder;			\
209 		beqzl	rt, 9f;				\
210 		 move	rd, rs;				\
211 		.set	pop;				\
212 9:
213 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
214 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
215     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
216 #define MOVN(rd, rs, rt)				\
217 		movn	rd, rs, rt
218 #define MOVZ(rd, rs, rt)				\
219 		movz	rd, rs, rt
220 #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
221 
222 /*
223  * Stack alignment
224  */
225 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
226 #define ALSZ	7
227 #define ALMASK	~7
228 #endif
229 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
230 #define ALSZ	15
231 #define ALMASK	~15
232 #endif
233 
234 /*
235  * Macros to handle different pointer/register sizes for 32/64-bit code
236  */
237 
238 /*
239  * Size of a register
240  */
241 #ifdef __mips64
242 #define SZREG	8
243 #else
244 #define SZREG	4
245 #endif
246 
247 /*
248  * Use the following macros in assemblercode to load/store registers,
249  * pointers etc.
250  */
251 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
252 #define REG_S		sw
253 #define REG_L		lw
254 #define REG_SUBU	subu
255 #define REG_ADDU	addu
256 #endif
257 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
258 #define REG_S		sd
259 #define REG_L		ld
260 #define REG_SUBU	dsubu
261 #define REG_ADDU	daddu
262 #endif
263 
264 /*
265  * How to add/sub/load/store/shift C int variables.
266  */
267 #if (_MIPS_SZINT == 32)
268 #define INT_ADD		add
269 #define INT_ADDU	addu
270 #define INT_ADDI	addi
271 #define INT_ADDIU	addiu
272 #define INT_SUB		sub
273 #define INT_SUBU	subu
274 #define INT_L		lw
275 #define INT_S		sw
276 #define INT_SLL		sll
277 #define INT_SLLV	sllv
278 #define INT_SRL		srl
279 #define INT_SRLV	srlv
280 #define INT_SRA		sra
281 #define INT_SRAV	srav
282 #endif
283 
284 #if (_MIPS_SZINT == 64)
285 #define INT_ADD		dadd
286 #define INT_ADDU	daddu
287 #define INT_ADDI	daddi
288 #define INT_ADDIU	daddiu
289 #define INT_SUB		dsub
290 #define INT_SUBU	dsubu
291 #define INT_L		ld
292 #define INT_S		sd
293 #define INT_SLL		dsll
294 #define INT_SLLV	dsllv
295 #define INT_SRL		dsrl
296 #define INT_SRLV	dsrlv
297 #define INT_SRA		dsra
298 #define INT_SRAV	dsrav
299 #endif
300 
301 /*
302  * How to add/sub/load/store/shift C long variables.
303  */
304 #if (_MIPS_SZLONG == 32)
305 #define LONG_ADD	add
306 #define LONG_ADDU	addu
307 #define LONG_ADDI	addi
308 #define LONG_ADDIU	addiu
309 #define LONG_SUB	sub
310 #define LONG_SUBU	subu
311 #define LONG_L		lw
312 #define LONG_S		sw
313 #define LONG_SP		swp
314 #define LONG_SLL	sll
315 #define LONG_SLLV	sllv
316 #define LONG_SRL	srl
317 #define LONG_SRLV	srlv
318 #define LONG_SRA	sra
319 #define LONG_SRAV	srav
320 
321 #define LONG		.word
322 #define LONGSIZE	4
323 #define LONGMASK	3
324 #define LONGLOG		2
325 #endif
326 
327 #if (_MIPS_SZLONG == 64)
328 #define LONG_ADD	dadd
329 #define LONG_ADDU	daddu
330 #define LONG_ADDI	daddi
331 #define LONG_ADDIU	daddiu
332 #define LONG_SUB	dsub
333 #define LONG_SUBU	dsubu
334 #define LONG_L		ld
335 #define LONG_S		sd
336 #define LONG_SP		sdp
337 #define LONG_SLL	dsll
338 #define LONG_SLLV	dsllv
339 #define LONG_SRL	dsrl
340 #define LONG_SRLV	dsrlv
341 #define LONG_SRA	dsra
342 #define LONG_SRAV	dsrav
343 
344 #define LONG		.dword
345 #define LONGSIZE	8
346 #define LONGMASK	7
347 #define LONGLOG		3
348 #endif
349 
350 /*
351  * How to add/sub/load/store/shift pointers.
352  */
353 #if (_MIPS_SZPTR == 32)
354 #define PTR_ADD		add
355 #define PTR_ADDU	addu
356 #define PTR_ADDI	addi
357 #define PTR_ADDIU	addiu
358 #define PTR_SUB		sub
359 #define PTR_SUBU	subu
360 #define PTR_L		lw
361 #define PTR_S		sw
362 #define PTR_LA		la
363 #define PTR_LI		li
364 #define PTR_SLL		sll
365 #define PTR_SLLV	sllv
366 #define PTR_SRL		srl
367 #define PTR_SRLV	srlv
368 #define PTR_SRA		sra
369 #define PTR_SRAV	srav
370 
371 #define PTR_SCALESHIFT	2
372 
373 #define PTR		.word
374 #define PTRSIZE		4
375 #define PTRLOG		2
376 #endif
377 
378 #if (_MIPS_SZPTR == 64)
379 #define PTR_ADD		dadd
380 #define PTR_ADDU	daddu
381 #define PTR_ADDI	daddi
382 #define PTR_ADDIU	daddiu
383 #define PTR_SUB		dsub
384 #define PTR_SUBU	dsubu
385 #define PTR_L		ld
386 #define PTR_S		sd
387 #define PTR_LA		dla
388 #define PTR_LI		dli
389 #define PTR_SLL		dsll
390 #define PTR_SLLV	dsllv
391 #define PTR_SRL		dsrl
392 #define PTR_SRLV	dsrlv
393 #define PTR_SRA		dsra
394 #define PTR_SRAV	dsrav
395 
396 #define PTR_SCALESHIFT	3
397 
398 #define PTR		.dword
399 #define PTRSIZE		8
400 #define PTRLOG		3
401 #endif
402 
403 /*
404  * Some cp0 registers were extended to 64bit for MIPS III.
405  */
406 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
407 #define MFC0		mfc0
408 #define MTC0		mtc0
409 #endif
410 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
411 #define MFC0		dmfc0
412 #define MTC0		dmtc0
413 #endif
414 
415 #define SSNOP		sll zero, zero, 1
416 
417 #ifdef CONFIG_SGI_IP28
418 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
419 #include <asm/cacheops.h>
420 #define R10KCBARRIER(addr)  cache   CACHE_BARRIER, addr;
421 #else
422 #define R10KCBARRIER(addr)
423 #endif
424 
425 #endif /* __ASM_ASM_H */
426