chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / ports / sysdeps / mips / sys / asm.h
1 /* Copyright (C) 1997, 1998, 2002, 2003, 2004, 2005
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ralf Baechle <ralf@gnu.org>.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #ifndef _SYS_ASM_H
22 #define _SYS_ASM_H
23
24 #include <sgidefs.h>
25
26 #ifndef CAT
27 # ifdef __STDC__
28 #  define __CAT(str1,str2) str1##str2
29 # else
30 #  define __CAT(str1,str2) str1/**/str2
31 # endif
32 # define CAT(str1,str2) __CAT(str1,str2)
33 #endif
34
35 /*
36  * Macros to handle different pointer/register sizes for 32/64-bit code
37  *
38  * 64 bit address space isn't used yet, so we may use the R3000 32 bit
39  * defines for now.
40  */
41 #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
42 # define PTR .word
43 # define PTRSIZE 4
44 # define PTRLOG 2
45 #elif _MIPS_SIM == _ABI64
46 # define PTR .dword
47 # define PTRSIZE 8
48 # define PTRLOG 3
49 #endif
50
51 /*
52  * PIC specific declarations
53  */
54 #if _MIPS_SIM == _ABIO32
55 # ifdef __PIC__
56 #  define CPRESTORE(register) \
57                 .cprestore register
58 #  define CPLOAD(register) \
59                 .cpload register
60 # else
61 #  define CPRESTORE(register)
62 #  define CPLOAD(register)
63 # endif
64
65 # define CPADD(register) \
66                 .cpadd  register
67
68 /*
69  * Set gp when at 1st instruction
70  */
71 # define SETUP_GP                                       \
72                 .set noreorder;                         \
73                 .cpload $25;                            \
74                 .set reorder
75 /* Set gp when not at 1st instruction */
76 # define SETUP_GPX(r)                                   \
77                 .set noreorder;                         \
78                 move r, $31;     /* Save old ra.  */    \
79                 bal 10f; /* Find addr of cpload.  */    \
80                 nop;                                    \
81 10:                                                     \
82                 .cpload $31;                            \
83                 move $31, r;                            \
84                 .set reorder
85 # define SETUP_GPX_L(r, l)                              \
86                 .set noreorder;                         \
87                 move r, $31;     /* Save old ra.  */    \
88                 bal l;   /* Find addr of cpload.  */    \
89                 nop;                                    \
90 l:                                                      \
91                 .cpload $31;                            \
92                 move $31, r;                            \
93                 .set reorder
94 # define SAVE_GP(x) \
95                 .cprestore x /* Save gp trigger t9/jalr conversion.      */
96 # define SETUP_GP64(a, b)
97 # define SETUP_GPX64(a, b)
98 # define SETUP_GPX64_L(cp_reg, ra_save, l)
99 # define RESTORE_GP64
100 # define USE_ALT_CP(a)
101 #else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */
102 /*
103  * For callee-saved gp calling convention:
104  */
105 # define SETUP_GP
106 # define SETUP_GPX(r)
107 # define SETUP_GPX_L(r, l)
108 # define SAVE_GP(x)
109
110 # define SETUP_GP64(gpoffset, proc) \
111                 .cpsetup $25, gpoffset, proc
112 # define SETUP_GPX64(cp_reg, ra_save)                   \
113                 move ra_save, $31; /* Save old ra.  */  \
114                 .set noreorder;                         \
115                 bal 10f; /* Find addr of .cpsetup.  */  \
116                 nop;                                    \
117 10:                                                     \
118                 .set reorder;                           \
119                 .cpsetup $31, cp_reg, 10b;              \
120                 move $31, ra_save
121 # define SETUP_GPX64_L(cp_reg, ra_save, l)  \
122                 move ra_save, $31; /* Save old ra.  */  \
123                 .set noreorder;                         \
124                 bal l;   /* Find addr of .cpsetup.  */  \
125                 nop;                                    \
126 l:                                                      \
127                 .set reorder;                           \
128                 .cpsetup $31, cp_reg, l;                \
129                 move $31, ra_save
130 # define RESTORE_GP64 \
131                 .cpreturn
132 /* Use alternate register for context pointer.  */
133 # define USE_ALT_CP(reg)        \
134                 .cplocal reg
135 #endif /* _MIPS_SIM != _ABIO32 */
136
137 /*
138  * Stack Frame Definitions
139  */
140 #if _MIPS_SIM == _ABIO32
141 # define NARGSAVE 4 /* Space for 4 argument registers must be allocated.  */
142 #endif
143 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
144 # define NARGSAVE 0 /* No caller responsibilities.  */
145 #endif
146
147
148 /*
149  * LEAF - declare leaf routine
150  */
151 #define LEAF(symbol)                                    \
152                 .globl  symbol;                         \
153                 .align  2;                              \
154                 .type   symbol,@function;               \
155                 .ent    symbol,0;                       \
156 symbol:         .frame  sp,0,ra
157
158 /*
159  * NESTED - declare nested routine entry point
160  */
161 #define NESTED(symbol, framesize, rpc)                  \
162                 .globl  symbol;                         \
163                 .align  2;                              \
164                 .type   symbol,@function;               \
165                 .ent    symbol,0;                       \
166 symbol:         .frame  sp, framesize, rpc
167
168 /*
169  * END - mark end of function
170  */
171 #ifndef END
172 # define END(function)                                   \
173                 .end    function;                       \
174                 .size   function,.-function
175 #endif
176
177 /*
178  * EXPORT - export definition of symbol
179  */
180 #define EXPORT(symbol)                                  \
181                 .globl  symbol;                         \
182 symbol:
183
184 /*
185  * ABS - export absolute symbol
186  */
187 #define ABS(symbol,value)                               \
188                 .globl  symbol;                         \
189 symbol          =       value
190
191 #define PANIC(msg)                                      \
192                 .set    push;                           \
193                 .set    reorder;                        \
194                 la      a0,8f;                          \
195                 jal     panic;                          \
196 9:              b       9b;                             \
197                 .set    pop;                            \
198                 TEXT(msg)
199
200 /*
201  * Print formated string
202  */
203 #define PRINT(string)                                   \
204                 .set    push;                           \
205                 .set    reorder;                        \
206                 la      a0,8f;                          \
207                 jal     printk;                         \
208                 .set    pop;                            \
209                 TEXT(string)
210
211 #define TEXT(msg)                                       \
212                 .data;                                  \
213 8:              .asciiz msg;                            \
214                 .previous;
215
216 /*
217  * Build text tables
218  */
219 #define TTABLE(string)                                  \
220                 .text;                                  \
221                 .word   1f;                             \
222                 .previous;                              \
223                 .data;                                  \
224 1:              .asciz  string;                         \
225                 .previous
226
227 /*
228  * MIPS IV pref instruction.
229  * Use with .set noreorder only!
230  *
231  * MIPS IV implementations are free to treat this as a nop.  The R5000
232  * is one of them.  So we should have an option not to use this instruction.
233  */
234 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
235     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
236 # define PREF(hint,addr)                                 \
237                 pref    hint,addr
238 # define PREFX(hint,addr)                                \
239                 prefx   hint,addr
240 #else
241 # define PREF
242 # define PREFX
243 #endif
244
245 /*
246  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
247  */
248 #if _MIPS_ISA == _MIPS_ISA_MIPS1
249 # define MOVN(rd,rs,rt)                                 \
250                 .set    push;                           \
251                 .set    reorder;                        \
252                 beqz    rt,9f;                          \
253                 move    rd,rs;                          \
254                 .set    pop;                            \
255 9:
256 # define MOVZ(rd,rs,rt)                                 \
257                 .set    push;                           \
258                 .set    reorder;                        \
259                 bnez    rt,9f;                          \
260                 move    rd,rt;                          \
261                 .set    pop;                            \
262 9:
263 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
264 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
265 # define MOVN(rd,rs,rt)                                 \
266                 .set    push;                           \
267                 .set    noreorder;                      \
268                 bnezl   rt,9f;                          \
269                 move    rd,rs;                          \
270                 .set    pop;                            \
271 9:
272 # define MOVZ(rd,rs,rt)                                 \
273                 .set    push;                           \
274                 .set    noreorder;                      \
275                 beqzl   rt,9f;                          \
276                 movz    rd,rs;                          \
277                 .set    pop;                            \
278 9:
279 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
280 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
281     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
282 # define MOVN(rd,rs,rt)                                 \
283                 movn    rd,rs,rt
284 # define MOVZ(rd,rs,rt)                                 \
285                 movz    rd,rs,rt
286 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
287
288 /*
289  * Stack alignment
290  */
291 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
292 # define ALSZ   15
293 # define ALMASK ~15
294 #else
295 # define ALSZ   7
296 # define ALMASK ~7
297 #endif
298
299 /*
300  * Size of a register
301  */
302 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
303 # define SZREG  8
304 #else
305 # define SZREG  4
306 #endif
307
308 /*
309  * Use the following macros in assemblercode to load/store registers,
310  * pointers etc.
311  */
312 #if (SZREG == 4)
313 # define REG_S sw
314 # define REG_L lw
315 #else
316 # define REG_S sd
317 # define REG_L ld
318 #endif
319
320 /*
321  * How to add/sub/load/store/shift C int variables.
322  */
323 #if (_MIPS_SZINT == 32)
324 # define INT_ADD        add
325 # define INT_ADDI       addi
326 # define INT_ADDU       addu
327 # define INT_ADDIU      addiu
328 # define INT_SUB        add
329 # define INT_SUBI       subi
330 # define INT_SUBU       subu
331 # define INT_SUBIU      subu
332 # define INT_L          lw
333 # define INT_S          sw
334 #endif
335
336 #if (_MIPS_SZINT == 64)
337 # define INT_ADD        dadd
338 # define INT_ADDI       daddi
339 # define INT_ADDU       daddu
340 # define INT_ADDIU      daddiu
341 # define INT_SUB        dadd
342 # define INT_SUBI       dsubi
343 # define INT_SUBU       dsubu
344 # define INT_SUBIU      dsubu
345 # define INT_L          ld
346 # define INT_S          sd
347 #endif
348
349 /*
350  * How to add/sub/load/store/shift C long variables.
351  */
352 #if (_MIPS_SZLONG == 32)
353 # define LONG_ADD       add
354 # define LONG_ADDI      addi
355 # define LONG_ADDU      addu
356 # define LONG_ADDIU     addiu
357 # define LONG_SUB       add
358 # define LONG_SUBI      subi
359 # define LONG_SUBU      subu
360 # define LONG_SUBIU     subu
361 # define LONG_L         lw
362 # define LONG_S         sw
363 # define LONG_SLL       sll
364 # define LONG_SLLV      sllv
365 # define LONG_SRL       srl
366 # define LONG_SRLV      srlv
367 # define LONG_SRA       sra
368 # define LONG_SRAV      srav
369 #endif
370
371 #if (_MIPS_SZLONG == 64)
372 # define LONG_ADD       dadd
373 # define LONG_ADDI      daddi
374 # define LONG_ADDU      daddu
375 # define LONG_ADDIU     daddiu
376 # define LONG_SUB       dadd
377 # define LONG_SUBI      dsubi
378 # define LONG_SUBU      dsubu
379 # define LONG_SUBIU     dsubu
380 # define LONG_L         ld
381 # define LONG_S         sd
382 # define LONG_SLL       dsll
383 # define LONG_SLLV      dsllv
384 # define LONG_SRL       dsrl
385 # define LONG_SRLV      dsrlv
386 # define LONG_SRA       dsra
387 # define LONG_SRAV      dsrav
388 #endif
389
390 /*
391  * How to add/sub/load/store/shift pointers.
392  */
393 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32)
394 # define PTR_ADD        add
395 # define PTR_ADDI       addi
396 # define PTR_ADDU       addu
397 # define PTR_ADDIU      addiu
398 # define PTR_SUB        add
399 # define PTR_SUBI       subi
400 # define PTR_SUBU       subu
401 # define PTR_SUBIU      subu
402 # define PTR_L          lw
403 # define PTR_LA         la
404 # define PTR_S          sw
405 # define PTR_SLL        sll
406 # define PTR_SLLV       sllv
407 # define PTR_SRL        srl
408 # define PTR_SRLV       srlv
409 # define PTR_SRA        sra
410 # define PTR_SRAV       srav
411
412 # define PTR_SCALESHIFT 2
413 #endif
414
415 #if _MIPS_SIM == _ABIN32
416 # define PTR_ADD        add
417 # define PTR_ADDI       addi
418 # define PTR_ADDU       add /* no u */
419 # define PTR_ADDIU      addi /* no u */
420 # define PTR_SUB        add
421 # define PTR_SUBI       subi
422 # define PTR_SUBU       sub /* no u */
423 # define PTR_SUBIU      sub /* no u */
424 # define PTR_L          lw
425 # define PTR_LA         la
426 # define PTR_S          sw
427 # define PTR_SLL        sll
428 # define PTR_SLLV       sllv
429 # define PTR_SRL        srl
430 # define PTR_SRLV       srlv
431 # define PTR_SRA        sra
432 # define PTR_SRAV       srav
433
434 # define PTR_SCALESHIFT 2
435 #endif
436
437 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \
438     || _MIPS_SIM == _ABI64
439 # define PTR_ADD        dadd
440 # define PTR_ADDI       daddi
441 # define PTR_ADDU       daddu
442 # define PTR_ADDIU      daddiu
443 # define PTR_SUB        dadd
444 # define PTR_SUBI       dsubi
445 # define PTR_SUBU       dsubu
446 # define PTR_SUBIU      dsubu
447 # define PTR_L          ld
448 # define PTR_LA         dla
449 # define PTR_S          sd
450 # define PTR_SLL        dsll
451 # define PTR_SLLV       dsllv
452 # define PTR_SRL        dsrl
453 # define PTR_SRLV       dsrlv
454 # define PTR_SRA        dsra
455 # define PTR_SRAV       dsrav
456
457 # define PTR_SCALESHIFT 3
458 #endif
459
460 /*
461  * Some cp0 registers were extended to 64bit for MIPS III.
462  */
463 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
464     (_MIPS_ISA == _MIPS_ISA_MIPS32)
465 # define MFC0   mfc0
466 # define MTC0   mtc0
467 #endif
468 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
469     (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
470 # define MFC0   dmfc0
471 # define MTC0   dmtc0
472 #endif
473
474 /* The MIPS archtectures do not have a uniform memory model.  Particular
475    platforms may provide additional guarantees - for instance, the R4000
476    LL and SC instructions implicitly perform a SYNC, and the 4K promises
477    strong ordering.
478
479    However, in the absence of those guarantees, we must assume weak ordering
480    and SYNC explicitly where necessary.
481
482    Some obsolete MIPS processors may not support the SYNC instruction.  This
483    applies to "true" MIPS I processors; most of the processors which compile
484    using MIPS I implement parts of MIPS II.  */
485
486 #ifndef MIPS_SYNC
487 # define MIPS_SYNC      sync
488 #endif
489
490 #endif /* sys/asm.h */