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