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