import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.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 by Ralf Baechle
7  * Copyright (C) 2002  Maciej W. Rozycki
8  *
9  * Some useful macros for MIPS assembler code
10  *
11  * Some of the routines below contain useless nops that will be optimized
12  * away by gas in -O mode. These nops are however required to fill delay
13  * slots in noreorder mode.
14  */
15 #ifndef __ASM_ASM_H
16 #define __ASM_ASM_H
17
18 #include <linux/config.h>
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  * PIC specific declarations
32  * Not used for the kernel but here seems to be the right place.
33  */
34 #ifdef __PIC__
35 #define CPRESTORE(register)                             \
36                 .cprestore register
37 #define CPADD(register)                                 \
38                 .cpadd  register
39 #define CPLOAD(register)                                \
40                 .cpload register
41 #else
42 #define CPRESTORE(register)
43 #define CPADD(register)
44 #define CPLOAD(register)
45 #endif
46
47 /*
48  * LEAF - declare leaf routine
49  */
50 #define LEAF(symbol)                                    \
51                 .globl  symbol;                         \
52                 .align  2;                              \
53                 .type   symbol,@function;               \
54                 .ent    symbol,0;                       \
55 symbol:         .frame  sp,0,ra
56
57 /*
58  * NESTED - declare nested routine entry point
59  */
60 #define NESTED(symbol, framesize, rpc)                  \
61                 .globl  symbol;                         \
62                 .align  2;                              \
63                 .type   symbol,@function;               \
64                 .ent    symbol,0;                       \
65 symbol:         .frame  sp, framesize, rpc
66
67 /*
68  * END - mark end of function
69  */
70 #define END(function)                                   \
71                 .end    function;                       \
72                 .size   function,.-function
73
74 /*
75  * EXPORT - export definition of symbol
76  */
77 #define EXPORT(symbol)                                  \
78                 .globl  symbol;                         \
79 symbol:
80
81 /*
82  * FEXPORT - export definition of a function symbol
83  */
84 #define FEXPORT(symbol)                                 \
85                 .globl  symbol;                         \
86                 .type   symbol,@function;               \
87 symbol:
88
89 /*
90  * ABS - export absolute symbol
91  */
92 #define ABS(symbol,value)                               \
93                 .globl  symbol;                         \
94 symbol          =       value
95
96 #define PANIC(msg)                                      \
97                 .set    push;                           \
98                 .set    reorder;                        \
99                 PTR_LA  a0,8f;                          \
100                 jal     panic;                          \
101 9:              b       9b;                             \
102                 .set    pop;                            \
103                 TEXT(msg)
104
105 /*
106  * Print formatted string
107  */
108 #define PRINT(string)                                   \
109                 .set    push;                           \
110                 .set    reorder;                        \
111                 PTR_LA  a0,8f;                          \
112                 jal     printk;                         \
113                 .set    pop;                            \
114                 TEXT(string)
115
116 #define TEXT(msg)                                       \
117                 .pushsection .data;                     \
118 8:              .asciiz msg;                            \
119                 .popsection;
120
121 /*
122  * Build text tables
123  */
124 #define TTABLE(string)                                  \
125                 .pushsection .text;                     \
126                 .word   1f;                             \
127                 .popsection                             \
128                 .pushsection .data;                     \
129 1:              .asciiz string;                         \
130                 .popsection
131
132 /*
133  * MIPS IV pref instruction.
134  * Use with .set noreorder only!
135  *
136  * MIPS IV implementations are free to treat this as a nop.  The R5000
137  * is one of them.  So we should have an option not to use this instruction.
138  */
139 #if CONFIG_CPU_HAS_PREFETCH
140
141 #define PREF(hint,addr)                                 \
142                 .set    push;                           \
143                 .set    mips4;                          \
144                 pref    hint,addr;                      \
145                 .set    pop
146
147 #define PREFX(hint,addr)                                \
148                 .set    push;                           \
149                 .set    mips4;                          \
150                 prefx   hint,addr;                      \
151                 .set    pop
152
153 #else
154
155 #define PREF(hint,addr)
156 #define PREFX(hint,addr)
157
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    reorder;                        \
167                 beqz    rt,9f;                          \
168                 move    rd,rs;                          \
169                 .set    pop;                            \
170 9:
171 #define MOVZ(rd,rs,rt)                                  \
172                 .set    push;                           \
173                 .set    reorder;                        \
174                 bnez    rt,9f;                          \
175                 move    rd,rs;                          \
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                  move   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_MIPS32) || (_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, MIPS32 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  * 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_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
235     (_MIPS_ISA == _MIPS_ISA_MIPS32)
236 #define REG_S           sw
237 #define REG_L           lw
238 #define REG_SUBU        subu
239 #define REG_ADDU        addu
240 #endif
241 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
242     (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
243 #define REG_S           sd
244 #define REG_L           ld
245 #define REG_SUBU        dsubu
246 #define REG_ADDU        daddu
247 #endif
248
249 /*
250  * How to add/sub/load/store/shift C int variables.
251  */
252 #if (_MIPS_SZINT == 32)
253 #define INT_ADD         add
254 #define INT_ADDU        addu
255 #define INT_ADDI        addi
256 #define INT_ADDIU       addiu
257 #define INT_SUB         sub
258 #define INT_SUBU        subu
259 #define INT_L           lw
260 #define INT_S           sw
261 #define INT_SLL         sll
262 #define INT_SLLV        sllv
263 #define INT_SRL         srl
264 #define INT_SRLV        srlv
265 #define INT_SRA         sra
266 #define INT_SRAV        srav
267 #endif
268
269 #if (_MIPS_SZINT == 64)
270 #define INT_ADD         dadd
271 #define INT_ADDU        daddu
272 #define INT_ADDI        daddi
273 #define INT_ADDIU       daddiu
274 #define INT_SUB         dsub
275 #define INT_SUBU        dsubu
276 #define INT_L           ld
277 #define INT_S           sd
278 #define INT_SLL         dsll
279 #define INT_SLLV        dsllv
280 #define INT_SRL         dsrl
281 #define INT_SRLV        dsrlv
282 #define INT_SRA         dsra
283 #define INT_SRAV        dsrav
284 #endif
285
286 /*
287  * How to add/sub/load/store/shift C long variables.
288  */
289 #if (_MIPS_SZLONG == 32)
290 #define LONG_ADD        add
291 #define LONG_ADDU       addu
292 #define LONG_ADDI       addi
293 #define LONG_ADDIU      addiu
294 #define LONG_SUB        sub
295 #define LONG_SUBU       subu
296 #define LONG_L          lw
297 #define LONG_S          sw
298 #define LONG_SLL        sll
299 #define LONG_SLLV       sllv
300 #define LONG_SRL        srl
301 #define LONG_SRLV       srlv
302 #define LONG_SRA        sra
303 #define LONG_SRAV       srav
304 #endif
305
306 #if (_MIPS_SZLONG == 64)
307 #define LONG_ADD        dadd
308 #define LONG_ADDU       daddu
309 #define LONG_ADDI       daddi
310 #define LONG_ADDIU      daddiu
311 #define LONG_SUB        dsub
312 #define LONG_SUBU       dsubu
313 #define LONG_L          ld
314 #define LONG_S          sd
315 #define LONG_SLL        dsll
316 #define LONG_SLLV       dsllv
317 #define LONG_SRL        dsrl
318 #define LONG_SRLV       dsrlv
319 #define LONG_SRA        dsra
320 #define LONG_SRAV       dsrav
321 #endif
322
323 /*
324  * How to add/sub/load/store/shift pointers.
325  */
326 #if (_MIPS_SZPTR == 32)
327 #define PTR_ADD         add
328 #define PTR_ADDU        addu
329 #define PTR_ADDI        addi
330 #define PTR_ADDIU       addiu
331 #define PTR_SUB         sub
332 #define PTR_SUBU        subu
333 #define PTR_L           lw
334 #define PTR_S           sw
335 #define PTR_LA          la
336 #define PTR_SLL         sll
337 #define PTR_SLLV        sllv
338 #define PTR_SRL         srl
339 #define PTR_SRLV        srlv
340 #define PTR_SRA         sra
341 #define PTR_SRAV        srav
342
343 #define PTR_SCALESHIFT  2
344
345 #define PTR             .word
346 #define PTRSIZE         4
347 #define PTRLOG          2
348 #endif
349
350 #if (_MIPS_SZPTR == 64)
351 #define PTR_ADD         dadd
352 #define PTR_ADDU        daddu
353 #define PTR_ADDI        daddi
354 #define PTR_ADDIU       daddiu
355 #define PTR_SUB         dsub
356 #define PTR_SUBU        dsubu
357 #define PTR_L           ld
358 #define PTR_S           sd
359 #define PTR_LA          dla
360 #define PTR_SLL         dsll
361 #define PTR_SLLV        dsllv
362 #define PTR_SRL         dsrl
363 #define PTR_SRLV        dsrlv
364 #define PTR_SRA         dsra
365 #define PTR_SRAV        dsrav
366
367 #define PTR_SCALESHIFT  3
368
369 #define PTR             .dword
370 #define PTRSIZE         8
371 #define PTRLOG          3
372 #endif
373
374 /*
375  * Some cp0 registers were extended to 64bit for MIPS III.
376  */
377 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
378     (_MIPS_ISA == _MIPS_ISA_MIPS32)
379 #define MFC0            mfc0
380 #define MTC0            mtc0
381 #endif
382 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
383     (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
384 #define MFC0            dmfc0
385 #define MTC0            dmtc0
386 #endif
387
388 #define SSNOP           sll zero,zero,1
389
390 #endif /* __ASM_ASM_H */