]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/mips/include/asm/asm.h
MIPS: End asm function prologue macros with .insn
[karo-tx-linux.git] / arch / mips / include / asm / 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 <asm/sgidefs.h>
21 #include <asm/asm-eva.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                 .insn
59
60 /*
61  * NESTED - declare nested routine entry point
62  */
63 #define NESTED(symbol, framesize, rpc)                  \
64                 .globl  symbol;                         \
65                 .align  2;                              \
66                 .type   symbol, @function;              \
67                 .ent    symbol, 0;                      \
68 symbol:         .frame  sp, framesize, rpc;             \
69                 .insn
70
71 /*
72  * END - mark end of function
73  */
74 #define END(function)                                   \
75                 .end    function;                       \
76                 .size   function, .-function
77
78 /*
79  * EXPORT - export definition of symbol
80  */
81 #define EXPORT(symbol)                                  \
82                 .globl  symbol;                         \
83 symbol:
84
85 /*
86  * FEXPORT - export definition of a function symbol
87  */
88 #define FEXPORT(symbol)                                 \
89                 .globl  symbol;                         \
90                 .type   symbol, @function;              \
91 symbol:         .insn
92
93 /*
94  * ABS - export absolute symbol
95  */
96 #define ABS(symbol,value)                               \
97                 .globl  symbol;                         \
98 symbol          =       value
99
100 #define PANIC(msg)                                      \
101                 .set    push;                           \
102                 .set    reorder;                        \
103                 PTR_LA  a0, 8f;                          \
104                 jal     panic;                          \
105 9:              b       9b;                             \
106                 .set    pop;                            \
107                 TEXT(msg)
108
109 /*
110  * Print formatted string
111  */
112 #ifdef CONFIG_PRINTK
113 #define PRINT(string)                                   \
114                 .set    push;                           \
115                 .set    reorder;                        \
116                 PTR_LA  a0, 8f;                          \
117                 jal     printk;                         \
118                 .set    pop;                            \
119                 TEXT(string)
120 #else
121 #define PRINT(string)
122 #endif
123
124 #define TEXT(msg)                                       \
125                 .pushsection .data;                     \
126 8:              .asciiz msg;                            \
127                 .popsection;
128
129 /*
130  * Build text tables
131  */
132 #define TTABLE(string)                                  \
133                 .pushsection .text;                     \
134                 .word   1f;                             \
135                 .popsection                             \
136                 .pushsection .data;                     \
137 1:              .asciiz string;                         \
138                 .popsection
139
140 /*
141  * MIPS IV pref instruction.
142  * Use with .set noreorder only!
143  *
144  * MIPS IV implementations are free to treat this as a nop.  The R5000
145  * is one of them.  So we should have an option not to use this instruction.
146  */
147 #ifdef CONFIG_CPU_HAS_PREFETCH
148
149 #define PREF(hint,addr)                                 \
150                 .set    push;                           \
151                 .set    arch=r5000;                     \
152                 pref    hint, addr;                     \
153                 .set    pop
154
155 #define PREFE(hint, addr)                               \
156                 .set    push;                           \
157                 .set    mips0;                          \
158                 .set    eva;                            \
159                 prefe   hint, addr;                     \
160                 .set    pop
161
162 #define PREFX(hint,addr)                                \
163                 .set    push;                           \
164                 .set    arch=r5000;                     \
165                 prefx   hint, addr;                     \
166                 .set    pop
167
168 #else /* !CONFIG_CPU_HAS_PREFETCH */
169
170 #define PREF(hint, addr)
171 #define PREFE(hint, addr)
172 #define PREFX(hint, addr)
173
174 #endif /* !CONFIG_CPU_HAS_PREFETCH */
175
176 /*
177  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
178  */
179 #if (_MIPS_ISA == _MIPS_ISA_MIPS1)
180 #define MOVN(rd, rs, rt)                                \
181                 .set    push;                           \
182                 .set    reorder;                        \
183                 beqz    rt, 9f;                         \
184                 move    rd, rs;                         \
185                 .set    pop;                            \
186 9:
187 #define MOVZ(rd, rs, rt)                                \
188                 .set    push;                           \
189                 .set    reorder;                        \
190                 bnez    rt, 9f;                         \
191                 move    rd, rs;                         \
192                 .set    pop;                            \
193 9:
194 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
195 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
196 #define MOVN(rd, rs, rt)                                \
197                 .set    push;                           \
198                 .set    noreorder;                      \
199                 bnezl   rt, 9f;                         \
200                  move   rd, rs;                         \
201                 .set    pop;                            \
202 9:
203 #define MOVZ(rd, rs, rt)                                \
204                 .set    push;                           \
205                 .set    noreorder;                      \
206                 beqzl   rt, 9f;                         \
207                  move   rd, rs;                         \
208                 .set    pop;                            \
209 9:
210 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
211 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
212     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
213 #define MOVN(rd, rs, rt)                                \
214                 movn    rd, rs, rt
215 #define MOVZ(rd, rs, rt)                                \
216                 movz    rd, rs, rt
217 #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
218
219 /*
220  * Stack alignment
221  */
222 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
223 #define ALSZ    7
224 #define ALMASK  ~7
225 #endif
226 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
227 #define ALSZ    15
228 #define ALMASK  ~15
229 #endif
230
231 /*
232  * Macros to handle different pointer/register sizes for 32/64-bit code
233  */
234
235 /*
236  * Size of a register
237  */
238 #ifdef __mips64
239 #define SZREG   8
240 #else
241 #define SZREG   4
242 #endif
243
244 /*
245  * Use the following macros in assemblercode to load/store registers,
246  * pointers etc.
247  */
248 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
249 #define REG_S           sw
250 #define REG_L           lw
251 #define REG_SUBU        subu
252 #define REG_ADDU        addu
253 #endif
254 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
255 #define REG_S           sd
256 #define REG_L           ld
257 #define REG_SUBU        dsubu
258 #define REG_ADDU        daddu
259 #endif
260
261 /*
262  * How to add/sub/load/store/shift C int variables.
263  */
264 #if (_MIPS_SZINT == 32)
265 #define INT_ADD         add
266 #define INT_ADDU        addu
267 #define INT_ADDI        addi
268 #define INT_ADDIU       addiu
269 #define INT_SUB         sub
270 #define INT_SUBU        subu
271 #define INT_L           lw
272 #define INT_S           sw
273 #define INT_SLL         sll
274 #define INT_SLLV        sllv
275 #define INT_SRL         srl
276 #define INT_SRLV        srlv
277 #define INT_SRA         sra
278 #define INT_SRAV        srav
279 #endif
280
281 #if (_MIPS_SZINT == 64)
282 #define INT_ADD         dadd
283 #define INT_ADDU        daddu
284 #define INT_ADDI        daddi
285 #define INT_ADDIU       daddiu
286 #define INT_SUB         dsub
287 #define INT_SUBU        dsubu
288 #define INT_L           ld
289 #define INT_S           sd
290 #define INT_SLL         dsll
291 #define INT_SLLV        dsllv
292 #define INT_SRL         dsrl
293 #define INT_SRLV        dsrlv
294 #define INT_SRA         dsra
295 #define INT_SRAV        dsrav
296 #endif
297
298 /*
299  * How to add/sub/load/store/shift C long variables.
300  */
301 #if (_MIPS_SZLONG == 32)
302 #define LONG_ADD        add
303 #define LONG_ADDU       addu
304 #define LONG_ADDI       addi
305 #define LONG_ADDIU      addiu
306 #define LONG_SUB        sub
307 #define LONG_SUBU       subu
308 #define LONG_L          lw
309 #define LONG_S          sw
310 #define LONG_SP         swp
311 #define LONG_SLL        sll
312 #define LONG_SLLV       sllv
313 #define LONG_SRL        srl
314 #define LONG_SRLV       srlv
315 #define LONG_SRA        sra
316 #define LONG_SRAV       srav
317
318 #define LONG            .word
319 #define LONGSIZE        4
320 #define LONGMASK        3
321 #define LONGLOG         2
322 #endif
323
324 #if (_MIPS_SZLONG == 64)
325 #define LONG_ADD        dadd
326 #define LONG_ADDU       daddu
327 #define LONG_ADDI       daddi
328 #define LONG_ADDIU      daddiu
329 #define LONG_SUB        dsub
330 #define LONG_SUBU       dsubu
331 #define LONG_L          ld
332 #define LONG_S          sd
333 #define LONG_SP         sdp
334 #define LONG_SLL        dsll
335 #define LONG_SLLV       dsllv
336 #define LONG_SRL        dsrl
337 #define LONG_SRLV       dsrlv
338 #define LONG_SRA        dsra
339 #define LONG_SRAV       dsrav
340
341 #define LONG            .dword
342 #define LONGSIZE        8
343 #define LONGMASK        7
344 #define LONGLOG         3
345 #endif
346
347 /*
348  * How to add/sub/load/store/shift pointers.
349  */
350 #if (_MIPS_SZPTR == 32)
351 #define PTR_ADD         add
352 #define PTR_ADDU        addu
353 #define PTR_ADDI        addi
354 #define PTR_ADDIU       addiu
355 #define PTR_SUB         sub
356 #define PTR_SUBU        subu
357 #define PTR_L           lw
358 #define PTR_S           sw
359 #define PTR_LA          la
360 #define PTR_LI          li
361 #define PTR_SLL         sll
362 #define PTR_SLLV        sllv
363 #define PTR_SRL         srl
364 #define PTR_SRLV        srlv
365 #define PTR_SRA         sra
366 #define PTR_SRAV        srav
367
368 #define PTR_SCALESHIFT  2
369
370 #define PTR             .word
371 #define PTRSIZE         4
372 #define PTRLOG          2
373 #endif
374
375 #if (_MIPS_SZPTR == 64)
376 #define PTR_ADD         dadd
377 #define PTR_ADDU        daddu
378 #define PTR_ADDI        daddi
379 #define PTR_ADDIU       daddiu
380 #define PTR_SUB         dsub
381 #define PTR_SUBU        dsubu
382 #define PTR_L           ld
383 #define PTR_S           sd
384 #define PTR_LA          dla
385 #define PTR_LI          dli
386 #define PTR_SLL         dsll
387 #define PTR_SLLV        dsllv
388 #define PTR_SRL         dsrl
389 #define PTR_SRLV        dsrlv
390 #define PTR_SRA         dsra
391 #define PTR_SRAV        dsrav
392
393 #define PTR_SCALESHIFT  3
394
395 #define PTR             .dword
396 #define PTRSIZE         8
397 #define PTRLOG          3
398 #endif
399
400 /*
401  * Some cp0 registers were extended to 64bit for MIPS III.
402  */
403 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
404 #define MFC0            mfc0
405 #define MTC0            mtc0
406 #endif
407 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
408 #define MFC0            dmfc0
409 #define MTC0            dmtc0
410 #endif
411
412 #define SSNOP           sll zero, zero, 1
413
414 #ifdef CONFIG_SGI_IP28
415 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
416 #include <asm/cacheops.h>
417 #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
418 #else
419 #define R10KCBARRIER(addr)
420 #endif
421
422 #endif /* __ASM_ASM_H */