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