xref: /rk3399_rockchip-uboot/arch/mips/include/asm/asm.h (revision cb0a6a1ecc8dfe4dbdad6f9376ef78879337b118)
1819833afSPeter Tyser /*
2819833afSPeter Tyser  * This file is subject to the terms and conditions of the GNU General Public
3819833afSPeter Tyser  * License.  See the file "COPYING" in the main directory of this archive
4819833afSPeter Tyser  * for more details.
5819833afSPeter Tyser  *
6819833afSPeter Tyser  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
7819833afSPeter Tyser  * Copyright (C) 1999 by Silicon Graphics, Inc.
8819833afSPeter Tyser  * Copyright (C) 2001 MIPS Technologies, Inc.
9819833afSPeter Tyser  * Copyright (C) 2002  Maciej W. Rozycki
10819833afSPeter Tyser  *
11819833afSPeter Tyser  * Some useful macros for MIPS assembler code
12819833afSPeter Tyser  *
13819833afSPeter Tyser  * Some of the routines below contain useless nops that will be optimized
14819833afSPeter Tyser  * away by gas in -O mode. These nops are however required to fill delay
15819833afSPeter Tyser  * slots in noreorder mode.
16819833afSPeter Tyser  */
17819833afSPeter Tyser #ifndef __ASM_ASM_H
18819833afSPeter Tyser #define __ASM_ASM_H
19819833afSPeter Tyser 
20819833afSPeter Tyser #include <asm/sgidefs.h>
21819833afSPeter Tyser 
22819833afSPeter Tyser #ifndef CAT
23819833afSPeter Tyser #ifdef __STDC__
24819833afSPeter Tyser #define __CAT(str1, str2) str1##str2
25819833afSPeter Tyser #else
26819833afSPeter Tyser #define __CAT(str1, str2) str1/**/str2
27819833afSPeter Tyser #endif
28819833afSPeter Tyser #define CAT(str1, str2) __CAT(str1, str2)
29819833afSPeter Tyser #endif
30819833afSPeter Tyser 
31819833afSPeter Tyser /*
32819833afSPeter Tyser  * PIC specific declarations
33819833afSPeter Tyser  * Not used for the kernel but here seems to be the right place.
34819833afSPeter Tyser  */
35819833afSPeter Tyser #ifdef __PIC__
36819833afSPeter Tyser #define CPRESTORE(register)                             \
37819833afSPeter Tyser 		.cprestore register
38819833afSPeter Tyser #define CPADD(register)                                 \
39819833afSPeter Tyser 		.cpadd	register
40819833afSPeter Tyser #define CPLOAD(register)                                \
41819833afSPeter Tyser 		.cpload	register
42819833afSPeter Tyser #else
43819833afSPeter Tyser #define CPRESTORE(register)
44819833afSPeter Tyser #define CPADD(register)
45819833afSPeter Tyser #define CPLOAD(register)
46819833afSPeter Tyser #endif
47819833afSPeter Tyser 
48819833afSPeter Tyser /*
49819833afSPeter Tyser  * LEAF - declare leaf routine
50819833afSPeter Tyser  */
51819833afSPeter Tyser #define	LEAF(symbol)                                    \
52819833afSPeter Tyser 		.globl	symbol;                         \
53819833afSPeter Tyser 		.align	2;                              \
54819833afSPeter Tyser 		.type	symbol, @function;              \
55819833afSPeter Tyser 		.ent	symbol, 0;                      \
56819833afSPeter Tyser symbol:		.frame	sp, 0, ra
57819833afSPeter Tyser 
58819833afSPeter Tyser /*
59819833afSPeter Tyser  * NESTED - declare nested routine entry point
60819833afSPeter Tyser  */
61819833afSPeter Tyser #define	NESTED(symbol, framesize, rpc)                  \
62819833afSPeter Tyser 		.globl	symbol;                         \
63819833afSPeter Tyser 		.align	2;                              \
64819833afSPeter Tyser 		.type	symbol, @function;              \
65819833afSPeter Tyser 		.ent	symbol, 0;                       \
66819833afSPeter Tyser symbol:		.frame	sp, framesize, rpc
67819833afSPeter Tyser 
68819833afSPeter Tyser /*
69819833afSPeter Tyser  * END - mark end of function
70819833afSPeter Tyser  */
71819833afSPeter Tyser #define	END(function)                                   \
72819833afSPeter Tyser 		.end	function;		        \
73819833afSPeter Tyser 		.size	function, .-function
74819833afSPeter Tyser 
75819833afSPeter Tyser /*
76819833afSPeter Tyser  * EXPORT - export definition of symbol
77819833afSPeter Tyser  */
78819833afSPeter Tyser #define EXPORT(symbol)					\
79819833afSPeter Tyser 		.globl	symbol;                         \
80819833afSPeter Tyser symbol:
81819833afSPeter Tyser 
82819833afSPeter Tyser /*
83819833afSPeter Tyser  * FEXPORT - export definition of a function symbol
84819833afSPeter Tyser  */
85819833afSPeter Tyser #define FEXPORT(symbol)					\
86819833afSPeter Tyser 		.globl	symbol;				\
87819833afSPeter Tyser 		.type	symbol, @function;		\
88819833afSPeter Tyser symbol:
89819833afSPeter Tyser 
90819833afSPeter Tyser /*
91819833afSPeter Tyser  * ABS - export absolute symbol
92819833afSPeter Tyser  */
93819833afSPeter Tyser #define	ABS(symbol,value)                               \
94819833afSPeter Tyser 		.globl	symbol;                         \
95819833afSPeter Tyser symbol		=	value
96819833afSPeter Tyser 
97819833afSPeter Tyser #define	PANIC(msg)                                      \
98819833afSPeter Tyser 		.set	push;				\
99819833afSPeter Tyser 		.set	reorder;                        \
100819833afSPeter Tyser 		PTR_LA	a0, 8f;                          \
101819833afSPeter Tyser 		jal	panic;                          \
102819833afSPeter Tyser 9:		b	9b;                             \
103819833afSPeter Tyser 		.set	pop;				\
104819833afSPeter Tyser 		TEXT(msg)
105819833afSPeter Tyser 
106819833afSPeter Tyser /*
107819833afSPeter Tyser  * Print formatted string
108819833afSPeter Tyser  */
109819833afSPeter Tyser #ifdef CONFIG_PRINTK
110819833afSPeter Tyser #define PRINT(string)                                   \
111819833afSPeter Tyser 		.set	push;				\
112819833afSPeter Tyser 		.set	reorder;                        \
113819833afSPeter Tyser 		PTR_LA	a0, 8f;                          \
114819833afSPeter Tyser 		jal	printk;                         \
115819833afSPeter Tyser 		.set	pop;				\
116819833afSPeter Tyser 		TEXT(string)
117819833afSPeter Tyser #else
118819833afSPeter Tyser #define PRINT(string)
119819833afSPeter Tyser #endif
120819833afSPeter Tyser 
121819833afSPeter Tyser #define	TEXT(msg)                                       \
122819833afSPeter Tyser 		.pushsection .data;			\
123819833afSPeter Tyser 8:		.asciiz	msg;                            \
124819833afSPeter Tyser 		.popsection;
125819833afSPeter Tyser 
126819833afSPeter Tyser /*
127819833afSPeter Tyser  * Build text tables
128819833afSPeter Tyser  */
129819833afSPeter Tyser #define TTABLE(string)                                  \
130819833afSPeter Tyser 		.pushsection .text;			\
131819833afSPeter Tyser 		.word	1f;                             \
132819833afSPeter Tyser 		.popsection				\
133819833afSPeter Tyser 		.pushsection .data;			\
134819833afSPeter Tyser 1:		.asciiz	string;                         \
135819833afSPeter Tyser 		.popsection
136819833afSPeter Tyser 
137819833afSPeter Tyser /*
138819833afSPeter Tyser  * MIPS IV pref instruction.
139819833afSPeter Tyser  * Use with .set noreorder only!
140819833afSPeter Tyser  *
141819833afSPeter Tyser  * MIPS IV implementations are free to treat this as a nop.  The R5000
142819833afSPeter Tyser  * is one of them.  So we should have an option not to use this instruction.
143819833afSPeter Tyser  */
144819833afSPeter Tyser #ifdef CONFIG_CPU_HAS_PREFETCH
145819833afSPeter Tyser 
146819833afSPeter Tyser #define PREF(hint,addr)                                 \
147819833afSPeter Tyser 		.set	push;				\
148819833afSPeter Tyser 		.set	mips4;				\
149819833afSPeter Tyser 		pref	hint, addr;			\
150819833afSPeter Tyser 		.set	pop
151819833afSPeter Tyser 
152819833afSPeter Tyser #define PREFX(hint,addr)                                \
153819833afSPeter Tyser 		.set	push;				\
154819833afSPeter Tyser 		.set	mips4;				\
155819833afSPeter Tyser 		prefx	hint, addr;			\
156819833afSPeter Tyser 		.set	pop
157819833afSPeter Tyser 
158819833afSPeter Tyser #else /* !CONFIG_CPU_HAS_PREFETCH */
159819833afSPeter Tyser 
160819833afSPeter Tyser #define PREF(hint, addr)
161819833afSPeter Tyser #define PREFX(hint, addr)
162819833afSPeter Tyser 
163819833afSPeter Tyser #endif /* !CONFIG_CPU_HAS_PREFETCH */
164819833afSPeter Tyser 
165819833afSPeter Tyser /*
166819833afSPeter Tyser  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
167819833afSPeter Tyser  */
168819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS1)
169819833afSPeter Tyser #define MOVN(rd, rs, rt)                                \
170819833afSPeter Tyser 		.set	push;				\
171819833afSPeter Tyser 		.set	reorder;			\
172819833afSPeter Tyser 		beqz	rt, 9f;                         \
173819833afSPeter Tyser 		move	rd, rs;                         \
174819833afSPeter Tyser 		.set	pop;				\
175819833afSPeter Tyser 9:
176819833afSPeter Tyser #define MOVZ(rd, rs, rt)                                \
177819833afSPeter Tyser 		.set	push;				\
178819833afSPeter Tyser 		.set	reorder;			\
179819833afSPeter Tyser 		bnez	rt, 9f;                         \
180819833afSPeter Tyser 		move	rd, rs;                         \
181819833afSPeter Tyser 		.set	pop;				\
182819833afSPeter Tyser 9:
183819833afSPeter Tyser #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
184819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
185819833afSPeter Tyser #define MOVN(rd, rs, rt)                                \
186819833afSPeter Tyser 		.set	push;				\
187819833afSPeter Tyser 		.set	noreorder;			\
188819833afSPeter Tyser 		bnezl	rt, 9f;                         \
189819833afSPeter Tyser 		 move	rd, rs;                         \
190819833afSPeter Tyser 		.set	pop;				\
191819833afSPeter Tyser 9:
192819833afSPeter Tyser #define MOVZ(rd, rs, rt)                                \
193819833afSPeter Tyser 		.set	push;				\
194819833afSPeter Tyser 		.set	noreorder;			\
195819833afSPeter Tyser 		beqzl	rt, 9f;                         \
196819833afSPeter Tyser 		 move	rd, rs;                         \
197819833afSPeter Tyser 		.set	pop;				\
198819833afSPeter Tyser 9:
199819833afSPeter Tyser #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
200819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
201819833afSPeter Tyser     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
202819833afSPeter Tyser #define MOVN(rd, rs, rt)                                \
203819833afSPeter Tyser 		movn	rd, rs, rt
204819833afSPeter Tyser #define MOVZ(rd, rs, rt)                                \
205819833afSPeter Tyser 		movz	rd, rs, rt
206819833afSPeter Tyser #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
207819833afSPeter Tyser 
208819833afSPeter Tyser /*
209819833afSPeter Tyser  * Stack alignment
210819833afSPeter Tyser  */
211819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32)
212819833afSPeter Tyser #define ALSZ	7
213819833afSPeter Tyser #define ALMASK	~7
214819833afSPeter Tyser #endif
215819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
216819833afSPeter Tyser #define ALSZ	15
217819833afSPeter Tyser #define ALMASK	~15
218819833afSPeter Tyser #endif
219819833afSPeter Tyser 
220819833afSPeter Tyser /*
221819833afSPeter Tyser  * Macros to handle different pointer/register sizes for 32/64-bit code
222819833afSPeter Tyser  */
223819833afSPeter Tyser 
224819833afSPeter Tyser /*
225819833afSPeter Tyser  * Size of a register
226819833afSPeter Tyser  */
227819833afSPeter Tyser #ifdef __mips64
228819833afSPeter Tyser #define SZREG	8
229819833afSPeter Tyser #else
230819833afSPeter Tyser #define SZREG	4
231819833afSPeter Tyser #endif
232819833afSPeter Tyser 
233819833afSPeter Tyser /*
234819833afSPeter Tyser  * Use the following macros in assemblercode to load/store registers,
235819833afSPeter Tyser  * pointers etc.
236819833afSPeter Tyser  */
237819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32)
238819833afSPeter Tyser #define REG_S		sw
239819833afSPeter Tyser #define REG_L		lw
240819833afSPeter Tyser #define REG_SUBU	subu
241819833afSPeter Tyser #define REG_ADDU	addu
242819833afSPeter Tyser #endif
243819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
244819833afSPeter Tyser #define REG_S		sd
245819833afSPeter Tyser #define REG_L		ld
246819833afSPeter Tyser #define REG_SUBU	dsubu
247819833afSPeter Tyser #define REG_ADDU	daddu
248819833afSPeter Tyser #endif
249819833afSPeter Tyser 
250819833afSPeter Tyser /*
251819833afSPeter Tyser  * How to add/sub/load/store/shift C int variables.
252819833afSPeter Tyser  */
253819833afSPeter Tyser #if (_MIPS_SZINT == 32)
254819833afSPeter Tyser #define INT_ADD		add
255819833afSPeter Tyser #define INT_ADDU	addu
256819833afSPeter Tyser #define INT_ADDI	addi
257819833afSPeter Tyser #define INT_ADDIU	addiu
258819833afSPeter Tyser #define INT_SUB		sub
259819833afSPeter Tyser #define INT_SUBU	subu
260819833afSPeter Tyser #define INT_L		lw
261819833afSPeter Tyser #define INT_S		sw
262819833afSPeter Tyser #define INT_SLL		sll
263819833afSPeter Tyser #define INT_SLLV	sllv
264819833afSPeter Tyser #define INT_SRL		srl
265819833afSPeter Tyser #define INT_SRLV	srlv
266819833afSPeter Tyser #define INT_SRA		sra
267819833afSPeter Tyser #define INT_SRAV	srav
268819833afSPeter Tyser #endif
269819833afSPeter Tyser 
270819833afSPeter Tyser #if (_MIPS_SZINT == 64)
271819833afSPeter Tyser #define INT_ADD		dadd
272819833afSPeter Tyser #define INT_ADDU	daddu
273819833afSPeter Tyser #define INT_ADDI	daddi
274819833afSPeter Tyser #define INT_ADDIU	daddiu
275819833afSPeter Tyser #define INT_SUB		dsub
276819833afSPeter Tyser #define INT_SUBU	dsubu
277819833afSPeter Tyser #define INT_L		ld
278819833afSPeter Tyser #define INT_S		sd
279819833afSPeter Tyser #define INT_SLL		dsll
280819833afSPeter Tyser #define INT_SLLV	dsllv
281819833afSPeter Tyser #define INT_SRL		dsrl
282819833afSPeter Tyser #define INT_SRLV	dsrlv
283819833afSPeter Tyser #define INT_SRA		dsra
284819833afSPeter Tyser #define INT_SRAV	dsrav
285819833afSPeter Tyser #endif
286819833afSPeter Tyser 
287819833afSPeter Tyser /*
288819833afSPeter Tyser  * How to add/sub/load/store/shift C long variables.
289819833afSPeter Tyser  */
290819833afSPeter Tyser #if (_MIPS_SZLONG == 32)
291819833afSPeter Tyser #define LONG_ADD	add
292819833afSPeter Tyser #define LONG_ADDU	addu
293819833afSPeter Tyser #define LONG_ADDI	addi
294819833afSPeter Tyser #define LONG_ADDIU	addiu
295819833afSPeter Tyser #define LONG_SUB	sub
296819833afSPeter Tyser #define LONG_SUBU	subu
297819833afSPeter Tyser #define LONG_L		lw
298819833afSPeter Tyser #define LONG_S		sw
299819833afSPeter Tyser #define LONG_SLL	sll
300819833afSPeter Tyser #define LONG_SLLV	sllv
301819833afSPeter Tyser #define LONG_SRL	srl
302819833afSPeter Tyser #define LONG_SRLV	srlv
303819833afSPeter Tyser #define LONG_SRA	sra
304819833afSPeter Tyser #define LONG_SRAV	srav
305819833afSPeter Tyser 
306819833afSPeter Tyser #define LONG		.word
307819833afSPeter Tyser #define LONGSIZE	4
308819833afSPeter Tyser #define LONGMASK	3
309819833afSPeter Tyser #define LONGLOG		2
310819833afSPeter Tyser #endif
311819833afSPeter Tyser 
312819833afSPeter Tyser #if (_MIPS_SZLONG == 64)
313819833afSPeter Tyser #define LONG_ADD	dadd
314819833afSPeter Tyser #define LONG_ADDU	daddu
315819833afSPeter Tyser #define LONG_ADDI	daddi
316819833afSPeter Tyser #define LONG_ADDIU	daddiu
317819833afSPeter Tyser #define LONG_SUB	dsub
318819833afSPeter Tyser #define LONG_SUBU	dsubu
319819833afSPeter Tyser #define LONG_L		ld
320819833afSPeter Tyser #define LONG_S		sd
321819833afSPeter Tyser #define LONG_SLL	dsll
322819833afSPeter Tyser #define LONG_SLLV	dsllv
323819833afSPeter Tyser #define LONG_SRL	dsrl
324819833afSPeter Tyser #define LONG_SRLV	dsrlv
325819833afSPeter Tyser #define LONG_SRA	dsra
326819833afSPeter Tyser #define LONG_SRAV	dsrav
327819833afSPeter Tyser 
328819833afSPeter Tyser #define LONG		.dword
329819833afSPeter Tyser #define LONGSIZE	8
330819833afSPeter Tyser #define LONGMASK	7
331819833afSPeter Tyser #define LONGLOG		3
332819833afSPeter Tyser #endif
333819833afSPeter Tyser 
334819833afSPeter Tyser /*
335819833afSPeter Tyser  * How to add/sub/load/store/shift pointers.
336819833afSPeter Tyser  */
337819833afSPeter Tyser #if (_MIPS_SZPTR == 32)
338819833afSPeter Tyser #define PTR_ADD		add
339819833afSPeter Tyser #define PTR_ADDU	addu
340819833afSPeter Tyser #define PTR_ADDI	addi
341819833afSPeter Tyser #define PTR_ADDIU	addiu
342819833afSPeter Tyser #define PTR_SUB		sub
343819833afSPeter Tyser #define PTR_SUBU	subu
344819833afSPeter Tyser #define PTR_L		lw
345819833afSPeter Tyser #define PTR_S		sw
346819833afSPeter Tyser #define PTR_LA		la
347819833afSPeter Tyser #define PTR_LI		li
348819833afSPeter Tyser #define PTR_SLL		sll
349819833afSPeter Tyser #define PTR_SLLV	sllv
350819833afSPeter Tyser #define PTR_SRL		srl
351819833afSPeter Tyser #define PTR_SRLV	srlv
352819833afSPeter Tyser #define PTR_SRA		sra
353819833afSPeter Tyser #define PTR_SRAV	srav
354819833afSPeter Tyser 
355819833afSPeter Tyser #define PTR_SCALESHIFT	2
356819833afSPeter Tyser 
357819833afSPeter Tyser #define PTR		.word
358819833afSPeter Tyser #define PTRSIZE		4
359819833afSPeter Tyser #define PTRLOG		2
360819833afSPeter Tyser #endif
361819833afSPeter Tyser 
362819833afSPeter Tyser #if (_MIPS_SZPTR == 64)
363819833afSPeter Tyser #define PTR_ADD		dadd
364819833afSPeter Tyser #define PTR_ADDU	daddu
365819833afSPeter Tyser #define PTR_ADDI	daddi
366819833afSPeter Tyser #define PTR_ADDIU	daddiu
367819833afSPeter Tyser #define PTR_SUB		dsub
368819833afSPeter Tyser #define PTR_SUBU	dsubu
369819833afSPeter Tyser #define PTR_L		ld
370819833afSPeter Tyser #define PTR_S		sd
371819833afSPeter Tyser #define PTR_LA		dla
372819833afSPeter Tyser #define PTR_LI		dli
373819833afSPeter Tyser #define PTR_SLL		dsll
374819833afSPeter Tyser #define PTR_SLLV	dsllv
375819833afSPeter Tyser #define PTR_SRL		dsrl
376819833afSPeter Tyser #define PTR_SRLV	dsrlv
377819833afSPeter Tyser #define PTR_SRA		dsra
378819833afSPeter Tyser #define PTR_SRAV	dsrav
379819833afSPeter Tyser 
380819833afSPeter Tyser #define PTR_SCALESHIFT	3
381819833afSPeter Tyser 
382819833afSPeter Tyser #define PTR		.dword
383819833afSPeter Tyser #define PTRSIZE		8
384819833afSPeter Tyser #define PTRLOG		3
385819833afSPeter Tyser #endif
386819833afSPeter Tyser 
387819833afSPeter Tyser /*
388819833afSPeter Tyser  * Some cp0 registers were extended to 64bit for MIPS III.
389819833afSPeter Tyser  */
390819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32)
391819833afSPeter Tyser #define MFC0		mfc0
392819833afSPeter Tyser #define MTC0		mtc0
393819833afSPeter Tyser #endif
394819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
395819833afSPeter Tyser #define MFC0		dmfc0
396819833afSPeter Tyser #define MTC0		dmtc0
397819833afSPeter Tyser #endif
398819833afSPeter Tyser 
399819833afSPeter Tyser #define SSNOP		sll zero, zero, 1
400819833afSPeter Tyser 
401819833afSPeter Tyser #ifdef CONFIG_SGI_IP28
402819833afSPeter Tyser /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
403819833afSPeter Tyser #include <asm/cacheops.h>
404*cb0a6a1eSZhi-zhou Zhang #define R10KCBARRIER(addr)  cache   CACHE_BARRIER, addr;
405819833afSPeter Tyser #else
406819833afSPeter Tyser #define R10KCBARRIER(addr)
407819833afSPeter Tyser #endif
408819833afSPeter Tyser 
409819833afSPeter Tyser #endif /* __ASM_ASM_H */
410