xref: /OK3568_Linux_fs/kernel/arch/mips/include/asm/asm.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * This file is subject to the terms and conditions of the GNU General Public
3*4882a593Smuzhiyun  * License.  See the file "COPYING" in the main directory of this archive
4*4882a593Smuzhiyun  * for more details.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
7*4882a593Smuzhiyun  * Copyright (C) 1999 by Silicon Graphics, Inc.
8*4882a593Smuzhiyun  * Copyright (C) 2001 MIPS Technologies, Inc.
9*4882a593Smuzhiyun  * Copyright (C) 2002  Maciej W. Rozycki
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * Some useful macros for MIPS assembler code
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * Some of the routines below contain useless nops that will be optimized
14*4882a593Smuzhiyun  * away by gas in -O mode. These nops are however required to fill delay
15*4882a593Smuzhiyun  * slots in noreorder mode.
16*4882a593Smuzhiyun  */
17*4882a593Smuzhiyun #ifndef __ASM_ASM_H
18*4882a593Smuzhiyun #define __ASM_ASM_H
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <asm/sgidefs.h>
21*4882a593Smuzhiyun #include <asm/asm-eva.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #ifndef __VDSO__
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun  * Emit CFI data in .debug_frame sections, not .eh_frame sections.
26*4882a593Smuzhiyun  * We don't do DWARF unwinding at runtime, so only the offline DWARF
27*4882a593Smuzhiyun  * information is useful to anyone. Note we should change this if we
28*4882a593Smuzhiyun  * ever decide to enable DWARF unwinding at runtime.
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun #define CFI_SECTIONS	.cfi_sections .debug_frame
31*4882a593Smuzhiyun #else
32*4882a593Smuzhiyun  /*
33*4882a593Smuzhiyun   * For the vDSO, emit both runtime unwind information and debug
34*4882a593Smuzhiyun   * symbols for the .dbg file.
35*4882a593Smuzhiyun   */
36*4882a593Smuzhiyun #define CFI_SECTIONS
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /*
40*4882a593Smuzhiyun  * LEAF - declare leaf routine
41*4882a593Smuzhiyun  */
42*4882a593Smuzhiyun #define LEAF(symbol)					\
43*4882a593Smuzhiyun 		CFI_SECTIONS;				\
44*4882a593Smuzhiyun 		.globl	symbol;				\
45*4882a593Smuzhiyun 		.align	2;				\
46*4882a593Smuzhiyun 		.type	symbol, @function;		\
47*4882a593Smuzhiyun 		.ent	symbol, 0;			\
48*4882a593Smuzhiyun symbol:		.frame	sp, 0, ra;			\
49*4882a593Smuzhiyun 		.cfi_startproc;				\
50*4882a593Smuzhiyun 		.insn
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun /*
53*4882a593Smuzhiyun  * NESTED - declare nested routine entry point
54*4882a593Smuzhiyun  */
55*4882a593Smuzhiyun #define NESTED(symbol, framesize, rpc)			\
56*4882a593Smuzhiyun 		CFI_SECTIONS;				\
57*4882a593Smuzhiyun 		.globl	symbol;				\
58*4882a593Smuzhiyun 		.align	2;				\
59*4882a593Smuzhiyun 		.type	symbol, @function;		\
60*4882a593Smuzhiyun 		.ent	symbol, 0;			\
61*4882a593Smuzhiyun symbol:		.frame	sp, framesize, rpc;		\
62*4882a593Smuzhiyun 		.cfi_startproc;				\
63*4882a593Smuzhiyun 		.insn
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun  * END - mark end of function
67*4882a593Smuzhiyun  */
68*4882a593Smuzhiyun #define END(function)					\
69*4882a593Smuzhiyun 		.cfi_endproc;				\
70*4882a593Smuzhiyun 		.end	function;			\
71*4882a593Smuzhiyun 		.size	function, .-function
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun  * EXPORT - export definition of symbol
75*4882a593Smuzhiyun  */
76*4882a593Smuzhiyun #define EXPORT(symbol)					\
77*4882a593Smuzhiyun 		.globl	symbol;				\
78*4882a593Smuzhiyun symbol:
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /*
81*4882a593Smuzhiyun  * FEXPORT - export definition of a function symbol
82*4882a593Smuzhiyun  */
83*4882a593Smuzhiyun #define FEXPORT(symbol)					\
84*4882a593Smuzhiyun 		.globl	symbol;				\
85*4882a593Smuzhiyun 		.type	symbol, @function;		\
86*4882a593Smuzhiyun symbol:		.insn
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /*
89*4882a593Smuzhiyun  * ABS - export absolute symbol
90*4882a593Smuzhiyun  */
91*4882a593Smuzhiyun #define ABS(symbol,value)				\
92*4882a593Smuzhiyun 		.globl	symbol;				\
93*4882a593Smuzhiyun symbol		=	value
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun #define TEXT(msg)					\
96*4882a593Smuzhiyun 		.pushsection .data;			\
97*4882a593Smuzhiyun 8:		.asciiz msg;				\
98*4882a593Smuzhiyun 		.popsection;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun #define ASM_PANIC(msg)					\
101*4882a593Smuzhiyun 		.set	push;				\
102*4882a593Smuzhiyun 		.set	reorder;			\
103*4882a593Smuzhiyun 		PTR_LA	a0, 8f;				\
104*4882a593Smuzhiyun 		jal	panic;				\
105*4882a593Smuzhiyun 9:		b	9b;				\
106*4882a593Smuzhiyun 		.set	pop;				\
107*4882a593Smuzhiyun 		TEXT(msg)
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun /*
110*4882a593Smuzhiyun  * Print formatted string
111*4882a593Smuzhiyun  */
112*4882a593Smuzhiyun #ifdef CONFIG_PRINTK
113*4882a593Smuzhiyun #define ASM_PRINT(string)				\
114*4882a593Smuzhiyun 		.set	push;				\
115*4882a593Smuzhiyun 		.set	reorder;			\
116*4882a593Smuzhiyun 		PTR_LA	a0, 8f;				\
117*4882a593Smuzhiyun 		jal	printk;				\
118*4882a593Smuzhiyun 		.set	pop;				\
119*4882a593Smuzhiyun 		TEXT(string)
120*4882a593Smuzhiyun #else
121*4882a593Smuzhiyun #define ASM_PRINT(string)
122*4882a593Smuzhiyun #endif
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun /*
125*4882a593Smuzhiyun  * Stack alignment
126*4882a593Smuzhiyun  */
127*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_ABI32)
128*4882a593Smuzhiyun #define ALSZ	7
129*4882a593Smuzhiyun #define ALMASK	~7
130*4882a593Smuzhiyun #endif
131*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
132*4882a593Smuzhiyun #define ALSZ	15
133*4882a593Smuzhiyun #define ALMASK	~15
134*4882a593Smuzhiyun #endif
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun /*
137*4882a593Smuzhiyun  * Macros to handle different pointer/register sizes for 32/64-bit code
138*4882a593Smuzhiyun  */
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun /*
141*4882a593Smuzhiyun  * Size of a register
142*4882a593Smuzhiyun  */
143*4882a593Smuzhiyun #ifdef __mips64
144*4882a593Smuzhiyun #define SZREG	8
145*4882a593Smuzhiyun #else
146*4882a593Smuzhiyun #define SZREG	4
147*4882a593Smuzhiyun #endif
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun /*
150*4882a593Smuzhiyun  * Use the following macros in assemblercode to load/store registers,
151*4882a593Smuzhiyun  * pointers etc.
152*4882a593Smuzhiyun  */
153*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_ABI32)
154*4882a593Smuzhiyun #define REG_S		sw
155*4882a593Smuzhiyun #define REG_L		lw
156*4882a593Smuzhiyun #define REG_SUBU	subu
157*4882a593Smuzhiyun #define REG_ADDU	addu
158*4882a593Smuzhiyun #endif
159*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
160*4882a593Smuzhiyun #define REG_S		sd
161*4882a593Smuzhiyun #define REG_L		ld
162*4882a593Smuzhiyun #define REG_SUBU	dsubu
163*4882a593Smuzhiyun #define REG_ADDU	daddu
164*4882a593Smuzhiyun #endif
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /*
167*4882a593Smuzhiyun  * How to add/sub/load/store/shift C int variables.
168*4882a593Smuzhiyun  */
169*4882a593Smuzhiyun #if (_MIPS_SZINT == 32)
170*4882a593Smuzhiyun #define INT_ADD		add
171*4882a593Smuzhiyun #define INT_ADDU	addu
172*4882a593Smuzhiyun #define INT_ADDI	addi
173*4882a593Smuzhiyun #define INT_ADDIU	addiu
174*4882a593Smuzhiyun #define INT_SUB		sub
175*4882a593Smuzhiyun #define INT_SUBU	subu
176*4882a593Smuzhiyun #define INT_L		lw
177*4882a593Smuzhiyun #define INT_S		sw
178*4882a593Smuzhiyun #define INT_SLL		sll
179*4882a593Smuzhiyun #define INT_SLLV	sllv
180*4882a593Smuzhiyun #define INT_SRL		srl
181*4882a593Smuzhiyun #define INT_SRLV	srlv
182*4882a593Smuzhiyun #define INT_SRA		sra
183*4882a593Smuzhiyun #define INT_SRAV	srav
184*4882a593Smuzhiyun #endif
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun #if (_MIPS_SZINT == 64)
187*4882a593Smuzhiyun #define INT_ADD		dadd
188*4882a593Smuzhiyun #define INT_ADDU	daddu
189*4882a593Smuzhiyun #define INT_ADDI	daddi
190*4882a593Smuzhiyun #define INT_ADDIU	daddiu
191*4882a593Smuzhiyun #define INT_SUB		dsub
192*4882a593Smuzhiyun #define INT_SUBU	dsubu
193*4882a593Smuzhiyun #define INT_L		ld
194*4882a593Smuzhiyun #define INT_S		sd
195*4882a593Smuzhiyun #define INT_SLL		dsll
196*4882a593Smuzhiyun #define INT_SLLV	dsllv
197*4882a593Smuzhiyun #define INT_SRL		dsrl
198*4882a593Smuzhiyun #define INT_SRLV	dsrlv
199*4882a593Smuzhiyun #define INT_SRA		dsra
200*4882a593Smuzhiyun #define INT_SRAV	dsrav
201*4882a593Smuzhiyun #endif
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun /*
204*4882a593Smuzhiyun  * How to add/sub/load/store/shift C long variables.
205*4882a593Smuzhiyun  */
206*4882a593Smuzhiyun #if (_MIPS_SZLONG == 32)
207*4882a593Smuzhiyun #define LONG_ADD	add
208*4882a593Smuzhiyun #define LONG_ADDU	addu
209*4882a593Smuzhiyun #define LONG_ADDI	addi
210*4882a593Smuzhiyun #define LONG_ADDIU	addiu
211*4882a593Smuzhiyun #define LONG_SUB	sub
212*4882a593Smuzhiyun #define LONG_SUBU	subu
213*4882a593Smuzhiyun #define LONG_L		lw
214*4882a593Smuzhiyun #define LONG_S		sw
215*4882a593Smuzhiyun #define LONG_SP		swp
216*4882a593Smuzhiyun #define LONG_SLL	sll
217*4882a593Smuzhiyun #define LONG_SLLV	sllv
218*4882a593Smuzhiyun #define LONG_SRL	srl
219*4882a593Smuzhiyun #define LONG_SRLV	srlv
220*4882a593Smuzhiyun #define LONG_SRA	sra
221*4882a593Smuzhiyun #define LONG_SRAV	srav
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun #ifdef __ASSEMBLY__
224*4882a593Smuzhiyun #define LONG		.word
225*4882a593Smuzhiyun #endif
226*4882a593Smuzhiyun #define LONGSIZE	4
227*4882a593Smuzhiyun #define LONGMASK	3
228*4882a593Smuzhiyun #define LONGLOG		2
229*4882a593Smuzhiyun #endif
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun #if (_MIPS_SZLONG == 64)
232*4882a593Smuzhiyun #define LONG_ADD	dadd
233*4882a593Smuzhiyun #define LONG_ADDU	daddu
234*4882a593Smuzhiyun #define LONG_ADDI	daddi
235*4882a593Smuzhiyun #define LONG_ADDIU	daddiu
236*4882a593Smuzhiyun #define LONG_SUB	dsub
237*4882a593Smuzhiyun #define LONG_SUBU	dsubu
238*4882a593Smuzhiyun #define LONG_L		ld
239*4882a593Smuzhiyun #define LONG_S		sd
240*4882a593Smuzhiyun #define LONG_SP		sdp
241*4882a593Smuzhiyun #define LONG_SLL	dsll
242*4882a593Smuzhiyun #define LONG_SLLV	dsllv
243*4882a593Smuzhiyun #define LONG_SRL	dsrl
244*4882a593Smuzhiyun #define LONG_SRLV	dsrlv
245*4882a593Smuzhiyun #define LONG_SRA	dsra
246*4882a593Smuzhiyun #define LONG_SRAV	dsrav
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun #ifdef __ASSEMBLY__
249*4882a593Smuzhiyun #define LONG		.dword
250*4882a593Smuzhiyun #endif
251*4882a593Smuzhiyun #define LONGSIZE	8
252*4882a593Smuzhiyun #define LONGMASK	7
253*4882a593Smuzhiyun #define LONGLOG		3
254*4882a593Smuzhiyun #endif
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun /*
257*4882a593Smuzhiyun  * How to add/sub/load/store/shift pointers.
258*4882a593Smuzhiyun  */
259*4882a593Smuzhiyun #if (_MIPS_SZPTR == 32)
260*4882a593Smuzhiyun #define PTR_ADD		add
261*4882a593Smuzhiyun #define PTR_ADDU	addu
262*4882a593Smuzhiyun #define PTR_ADDI	addi
263*4882a593Smuzhiyun #define PTR_ADDIU	addiu
264*4882a593Smuzhiyun #define PTR_SUB		sub
265*4882a593Smuzhiyun #define PTR_SUBU	subu
266*4882a593Smuzhiyun #define PTR_L		lw
267*4882a593Smuzhiyun #define PTR_S		sw
268*4882a593Smuzhiyun #define PTR_LA		la
269*4882a593Smuzhiyun #define PTR_LI		li
270*4882a593Smuzhiyun #define PTR_SLL		sll
271*4882a593Smuzhiyun #define PTR_SLLV	sllv
272*4882a593Smuzhiyun #define PTR_SRL		srl
273*4882a593Smuzhiyun #define PTR_SRLV	srlv
274*4882a593Smuzhiyun #define PTR_SRA		sra
275*4882a593Smuzhiyun #define PTR_SRAV	srav
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun #define PTR_SCALESHIFT	2
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun #define PTR		.word
280*4882a593Smuzhiyun #define PTRSIZE		4
281*4882a593Smuzhiyun #define PTRLOG		2
282*4882a593Smuzhiyun #endif
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun #if (_MIPS_SZPTR == 64)
285*4882a593Smuzhiyun #define PTR_ADD		dadd
286*4882a593Smuzhiyun #define PTR_ADDU	daddu
287*4882a593Smuzhiyun #define PTR_ADDI	daddi
288*4882a593Smuzhiyun #define PTR_ADDIU	daddiu
289*4882a593Smuzhiyun #define PTR_SUB		dsub
290*4882a593Smuzhiyun #define PTR_SUBU	dsubu
291*4882a593Smuzhiyun #define PTR_L		ld
292*4882a593Smuzhiyun #define PTR_S		sd
293*4882a593Smuzhiyun #define PTR_LA		dla
294*4882a593Smuzhiyun #define PTR_LI		dli
295*4882a593Smuzhiyun #define PTR_SLL		dsll
296*4882a593Smuzhiyun #define PTR_SLLV	dsllv
297*4882a593Smuzhiyun #define PTR_SRL		dsrl
298*4882a593Smuzhiyun #define PTR_SRLV	dsrlv
299*4882a593Smuzhiyun #define PTR_SRA		dsra
300*4882a593Smuzhiyun #define PTR_SRAV	dsrav
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun #define PTR_SCALESHIFT	3
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun #define PTR		.dword
305*4882a593Smuzhiyun #define PTRSIZE		8
306*4882a593Smuzhiyun #define PTRLOG		3
307*4882a593Smuzhiyun #endif
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun /*
310*4882a593Smuzhiyun  * Some cp0 registers were extended to 64bit for MIPS III.
311*4882a593Smuzhiyun  */
312*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_ABI32)
313*4882a593Smuzhiyun #define MFC0		mfc0
314*4882a593Smuzhiyun #define MTC0		mtc0
315*4882a593Smuzhiyun #endif
316*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
317*4882a593Smuzhiyun #define MFC0		dmfc0
318*4882a593Smuzhiyun #define MTC0		dmtc0
319*4882a593Smuzhiyun #endif
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun #define SSNOP		sll zero, zero, 1
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun #ifdef CONFIG_SGI_IP28
324*4882a593Smuzhiyun /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
325*4882a593Smuzhiyun #include <asm/cacheops.h>
326*4882a593Smuzhiyun #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
327*4882a593Smuzhiyun #else
328*4882a593Smuzhiyun #define R10KCBARRIER(addr)
329*4882a593Smuzhiyun #endif
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun #endif /* __ASM_ASM_H */
332