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

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