File: /usr/src/linux/include/asm-mips64/asm.h

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      *
10      * Some useful macros for MIPS assembler code
11      *
12      * Some of the routines below contain useless nops that will be optimized
13      * away by gas in -O mode. These nops are however required to fill delay
14      * slots in noreorder mode.
15      */
16     #ifndef	__ASM_ASM_H
17     #define	__ASM_ASM_H
18     
19     #include <asm/sgidefs.h>
20     
21     /*
22      * PIC specific declarations
23      * Not used for the kernel but here seems to be the right place.
24      */
25     #ifdef __PIC__
26     #define CPRESTORE(register)                             \
27     		.cprestore register
28     #define CPADD(register)                                 \
29     		.cpadd	register
30     #define CPLOAD(register)                                \
31     		.cpload	register
32     #else
33     #define CPRESTORE(register)
34     #define CPADD(register)
35     #define CPLOAD(register)
36     #endif
37     
38     /*
39      * LEAF - declare leaf routine
40      */
41     #define	LEAF(symbol)                                    \
42     		.globl	symbol;                         \
43     		.align	2;                              \
44     		.type	symbol,@function;               \
45     		.ent	symbol,0;                       \
46     symbol:		.frame	sp,0,ra
47     
48     /*
49      * NESTED - declare nested routine entry point
50      */
51     #define	NESTED(symbol, framesize, rpc)                  \
52     		.globl	symbol;                         \
53     		.align	2;                              \
54     		.type	symbol,@function;               \
55     		.ent	symbol,0;                       \
56     symbol:		.frame	sp, framesize, rpc
57     
58     /*
59      * END - mark end of function
60      */
61     #define	END(function)                                   \
62     		.end	function;		        \
63     		.size	function,.-function
64     
65     /*
66      * EXPORT - export definition of symbol
67      */
68     #define EXPORT(symbol)					\
69     		.globl	symbol;                         \
70     symbol:
71     
72     /*
73      * FEXPORT - export definition of a function symbol
74      */
75     #define FEXPORT(symbol)					\
76     		.globl	symbol;				\
77     		.type	symbol,@function;		\
78     symbol:
79     
80     /*
81      * ABS - export absolute symbol
82      */
83     #define	ABS(symbol,value)                               \
84     		.globl	symbol;                         \
85     symbol		=	value
86     
87     #define	PANIC(msg)                                      \
88     		.set	push;				\
89     		.set	reorder;                        \
90     		la	a0,8f;                          \
91     		jal	panic;                          \
92     9:		b	9b;                             \
93     		.set	pop;				\
94     		TEXT(msg)
95     
96     /*
97      * Print formatted string
98      */
99     #define PRINT(string)                                   \
100     		.set	push;				\
101     		.set	reorder;                        \
102     		la	a0,8f;                          \
103     		jal	printk;                         \
104     		.set	pop;				\
105     		TEXT(string)
106     
107     #define	TEXT(msg)                                       \
108     		.data;                                  \
109     8:		.asciiz	msg;                            \
110     		.previous;
111     
112     /*
113      * Build text tables
114      */
115     #define TTABLE(string)                                  \
116     		.text;                                  \
117     		.word	1f;                             \
118     		.previous;                              \
119     		.data;                                  \
120     1:		.asciz	string;                         \
121     		.previous
122     
123     /*
124      * MIPS IV pref instruction.
125      * Use with .set noreorder only!
126      *
127      * MIPS IV implementations are free to treat this as a nop.  The R5000
128      * is one of them.  So we should have an option not to use this instruction.
129      */
130     #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
131         (_MIPS_ISA == _MIPS_ISA_MIPS64)
132     #define PREF(hint,addr)                                 \
133     		pref	hint,addr
134     #define PREFX(hint,addr)                                \
135     		prefx	hint,addr
136     #else
137     #define PREF
138     #define PREFX
139     #endif
140     
141     /*
142      * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
143      */
144     #if _MIPS_ISA == _MIPS_ISA_MIPS1
145     #define MOVN(rd,rs,rt)                                  \
146     		.set	push;				\
147     		.set	reorder;			\
148     		beqz	rt,9f;                          \
149     		move	rd,rs;                          \
150     		.set	pop;				\
151     9:
152     #define MOVZ(rd,rs,rt)                                  \
153     		.set	push;				\
154     		.set	reorder;			\
155     		bnez	rt,9f;                          \
156     		move	rd,rt;                          \
157     		.set	pop;				\
158     9:
159     #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
160     #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
161     #define MOVN(rd,rs,rt)                                  \
162     		.set	push;				\
163     		.set	noreorder;			\
164     		bnezl	rt,9f;                          \
165     		move	rd,rs;                          \
166     		.set	pop;				\
167     9:
168     #define MOVZ(rd,rs,rt)                                  \
169     		.set	push;				\
170     		.set	noreorder;			\
171     		beqzl	rt,9f;                          \
172     		movz	rd,rs;                          \
173     		.set	pop;				\
174     9:
175     #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
176     #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
177         (_MIPS_ISA == _MIPS_ISA_MIPS64)
178     #define MOVN(rd,rs,rt)                                  \
179     		movn	rd,rs,rt
180     #define MOVZ(rd,rs,rt)                                  \
181     		movz	rd,rs,rt
182     #endif /* MIPS IV, MIPS V or MIPS64 */
183     
184     /*
185      * Stack alignment
186      */
187     #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
188         (_MIPS_ISA == _MIPS_ISA_MIPS32)
189     #define ALSZ	7
190     #define ALMASK	~7
191     #endif
192     #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
193         (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
194     #define ALSZ	15
195     #define ALMASK	~15
196     #endif
197     
198     /*
199      * Size of a register
200      */
201     #ifdef __mips64
202     #define SZREG	8
203     #else
204     #define SZREG	4
205     #endif
206     
207     /*
208      * Use the following macros in assemblercode to load/store registers,
209      * pointers etc.
210      */
211     #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
212         (_MIPS_ISA == _MIPS_ISA_MIPS32)
213     #define REG_S sw
214     #define REG_L lw
215     #define PTR_SUBU dsubu
216     #define PTR_ADDU daddu
217     #endif
218     #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
219         (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
220     #define REG_S sd
221     #define REG_L ld
222     /* We still live in a 32 bit address space ...  */
223     #define PTR_SUBU dsubu
224     #define PTR_ADDU daddu
225     #endif
226     
227     /*
228      * How to add/sub/load/store/shift C int variables.
229      */
230     #if (_MIPS_SZINT == 32)
231     #define INT_ADD	add
232     #define INT_ADDI	addi
233     #define INT_ADDU	addu
234     #define INT_ADDIU	addiu
235     #define INT_SUB		add
236     #define INT_SUBI	subi
237     #define INT_SUBU	subu
238     #define INT_SUBIU	subu
239     #define INT_L		lw
240     #define INT_S		sw
241     #endif
242     
243     #if (_MIPS_SZINT == 64)
244     #define INT_ADD	dadd
245     #define INT_ADDI	daddi
246     #define INT_ADDU	daddu
247     #define INT_ADDIU	daddiu
248     #define INT_SUB		dadd
249     #define INT_SUBI	dsubi
250     #define INT_SUBU	dsubu
251     #define INT_SUBIU	dsubu
252     #define INT_L		ld
253     #define INT_S		sd
254     #endif
255     
256     /*
257      * How to add/sub/load/store/shift C long variables.
258      */
259     #if (_MIPS_SZLONG == 32)
260     #define LONG_ADD	add
261     #define LONG_ADDI	addi
262     #define LONG_ADDU	addu
263     #define LONG_ADDIU	addiu
264     #define LONG_SUB	add
265     #define LONG_SUBI	subi
266     #define LONG_SUBU	subu
267     #define LONG_SUBIU	subu
268     #define LONG_L		lw
269     #define LONG_S		sw
270     #define LONG_SLL	sll
271     #define LONG_SLLV	sllv
272     #define LONG_SRL	srl
273     #define LONG_SRLV	srlv
274     #define LONG_SRA	sra
275     #define LONG_SRAV	srav
276     #endif
277     
278     #if (_MIPS_SZLONG == 64)
279     #define LONG_ADD	dadd
280     #define LONG_ADDI	daddi
281     #define LONG_ADDU	daddu
282     #define LONG_ADDIU	daddiu
283     #define LONG_SUB	dadd
284     #define LONG_SUBI	dsubi
285     #define LONG_SUBU	dsubu
286     #define LONG_SUBIU	dsubu
287     #define LONG_L		ld
288     #define LONG_S		sd
289     #define LONG_SLL	dsll
290     #define LONG_SLLV	dsllv
291     #define LONG_SRL	dsrl
292     #define LONG_SRLV	dsrlv
293     #define LONG_SRA	dsra
294     #define LONG_SRAV	dsrav
295     #endif
296     
297     /*
298      * How to add/sub/load/store/shift pointers.
299      */
300     #if (_MIPS_SZPTR == 32)
301     #define PTR_ADD	add
302     #define PTR_ADDI	addi
303     #define PTR_ADDU	addu
304     #define PTR_ADDIU	addiu
305     #define PTR_SUB		add
306     #define PTR_SUBI	subi
307     #define PTR_SUBU	subu
308     #define PTR_SUBIU	subu
309     #define PTR_L		lw
310     #define PTR_S		sw
311     #define PTR_SLL		sll
312     #define PTR_SLLV	sllv
313     #define PTR_SRL		srl
314     #define PTR_SRLV	srlv
315     #define PTR_SRA		sra
316     #define PTR_SRAV	srav
317     
318     #define PTR_SCALESHIFT	2
319     
320     #define PTR		.word
321     #define PTRSIZE		4
322     #define PTRLOG		2
323     #endif
324     
325     #if (_MIPS_SZPTR == 64)
326     #define PTR_ADD	dadd
327     #define PTR_ADDI	daddi
328     #define PTR_ADDU	daddu
329     #define PTR_ADDIU	daddiu
330     #define PTR_SUB		dadd
331     #define PTR_SUBI	dsubi
332     #define PTR_SUBU	dsubu
333     #define PTR_SUBIU	dsubu
334     #define PTR_L		ld
335     #define PTR_S		sd
336     #define PTR_SLL		dsll
337     #define PTR_SLLV	dsllv
338     #define PTR_SRL		dsrl
339     #define PTR_SRLV	dsrlv
340     #define PTR_SRA		dsra
341     #define PTR_SRAV	dsrav
342     
343     #define PTR_SCALESHIFT	3
344     
345     #define PTR		.dword
346     #define PTRSIZE		8
347     #define PTRLOG		3
348     #endif
349     
350     /*
351      * Some cp0 registers were extended to 64bit for MIPS III.
352      */
353     #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
354         (_MIPS_ISA == _MIPS_ISA_MIPS32)
355     #define MFC0	mfc0
356     #define MTC0	mtc0
357     #endif
358     #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
359         (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
360     #define MFC0	dmfc0
361     #define MTC0	dmtc0
362     #endif
363     
364     #endif /* __ASM_ASM_H */
365