Back to index

glibc  2.9
asm.h
Go to the documentation of this file.
00001 /* Copyright (C) 1997, 1998, 2002, 2003, 2004, 2005
00002    Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ralf Baechle <ralf@gnu.org>.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #ifndef _SYS_ASM_H
00022 #define _SYS_ASM_H
00023 
00024 #include <sgidefs.h>
00025 
00026 #ifndef CAT
00027 # ifdef __STDC__
00028 #  define __CAT(str1,str2) str1##str2
00029 # else
00030 #  define __CAT(str1,str2) str1str2
00031 # endif
00032 # define CAT(str1,str2) __CAT(str1,str2)
00033 #endif
00034 
00035 /*
00036  * Macros to handle different pointer/register sizes for 32/64-bit code
00037  *
00038  * 64 bit address space isn't used yet, so we may use the R3000 32 bit
00039  * defines for now.
00040  */
00041 #if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
00042 # define PTR .word
00043 # define PTRSIZE 4
00044 # define PTRLOG 2
00045 #elif _MIPS_SIM == _ABI64
00046 # define PTR .dword
00047 # define PTRSIZE 8
00048 # define PTRLOG 3
00049 #endif
00050 
00051 /*
00052  * PIC specific declarations
00053  */
00054 #if _MIPS_SIM == _ABIO32
00055 # ifdef __PIC__
00056 #  define CPRESTORE(register) \
00057               .cprestore register
00058 #  define CPLOAD(register) \
00059               .cpload register
00060 # else
00061 #  define CPRESTORE(register)
00062 #  define CPLOAD(register)
00063 # endif
00064 
00065 # define CPADD(register) \
00066               .cpadd register
00067 
00068 /*
00069  * Set gp when at 1st instruction
00070  */
00071 # define SETUP_GP                                \
00072               .set noreorder;                           \
00073               .cpload $25;                       \
00074               .set reorder
00075 /* Set gp when not at 1st instruction */
00076 # define SETUP_GPX(r)                                   \
00077               .set noreorder;                           \
00078               move r, $31;   /* Save old ra.  */ \
00079               bal 10f; /* Find addr of cpload.  */      \
00080               nop;                               \
00081 10:                                              \
00082               .cpload $31;                       \
00083               move $31, r;                       \
00084               .set reorder
00085 # define SETUP_GPX_L(r, l)                       \
00086               .set noreorder;                           \
00087               move r, $31;   /* Save old ra.  */ \
00088               bal l;   /* Find addr of cpload.  */      \
00089               nop;                               \
00090 l:                                               \
00091               .cpload $31;                       \
00092               move $31, r;                       \
00093               .set reorder
00094 # define SAVE_GP(x) \
00095               .cprestore x /* Save gp trigger t9/jalr conversion.      */
00096 # define SETUP_GP64(a, b)
00097 # define SETUP_GPX64(a, b)
00098 # define SETUP_GPX64_L(cp_reg, ra_save, l)
00099 # define RESTORE_GP64
00100 # define USE_ALT_CP(a)
00101 #else /* _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32 */
00102 /*
00103  * For callee-saved gp calling convention:
00104  */
00105 # define SETUP_GP
00106 # define SETUP_GPX(r)
00107 # define SETUP_GPX_L(r, l)
00108 # define SAVE_GP(x)
00109 
00110 # define SETUP_GP64(gpoffset, proc) \
00111               .cpsetup $25, gpoffset, proc
00112 # define SETUP_GPX64(cp_reg, ra_save)                   \
00113               move ra_save, $31; /* Save old ra.  */    \
00114               .set noreorder;                           \
00115               bal 10f; /* Find addr of .cpsetup.  */    \
00116               nop;                               \
00117 10:                                              \
00118               .set reorder;                      \
00119               .cpsetup $31, cp_reg, 10b;         \
00120               move $31, ra_save
00121 # define SETUP_GPX64_L(cp_reg, ra_save, l)  \
00122               move ra_save, $31; /* Save old ra.  */    \
00123               .set noreorder;                           \
00124               bal l;   /* Find addr of .cpsetup.  */    \
00125               nop;                               \
00126 l:                                               \
00127               .set reorder;                      \
00128               .cpsetup $31, cp_reg, l;           \
00129               move $31, ra_save
00130 # define RESTORE_GP64 \
00131               .cpreturn
00132 /* Use alternate register for context pointer.  */
00133 # define USE_ALT_CP(reg)    \
00134               .cplocal reg
00135 #endif /* _MIPS_SIM != _ABIO32 */
00136 
00137 /*
00138  * Stack Frame Definitions
00139  */
00140 #if _MIPS_SIM == _ABIO32
00141 # define NARGSAVE 4 /* Space for 4 argument registers must be allocated.  */
00142 #endif
00143 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
00144 # define NARGSAVE 0 /* No caller responsibilities.  */
00145 #endif
00146 
00147 
00148 /*
00149  * LEAF - declare leaf routine
00150  */
00151 #define       LEAF(symbol)                                    \
00152               .globl symbol;                         \
00153               .align 2;                              \
00154               .type  symbol,@function;               \
00155               .ent   symbol,0;                       \
00156 symbol:              .frame sp,0,ra
00157 
00158 /*
00159  * NESTED - declare nested routine entry point
00160  */
00161 #define       NESTED(symbol, framesize, rpc)                  \
00162               .globl symbol;                         \
00163               .align 2;                              \
00164               .type  symbol,@function;               \
00165               .ent   symbol,0;                       \
00166 symbol:              .frame sp, framesize, rpc
00167 
00168 /*
00169  * END - mark end of function
00170  */
00171 #ifndef END
00172 # define END(function)                                   \
00173               .end   function;                    \
00174               .size  function,.-function
00175 #endif
00176 
00177 /*
00178  * EXPORT - export definition of symbol
00179  */
00180 #define       EXPORT(symbol)                                  \
00181               .globl symbol;                         \
00182 symbol:
00183 
00184 /*
00185  * ABS - export absolute symbol
00186  */
00187 #define       ABS(symbol,value)                               \
00188               .globl symbol;                         \
00189 symbol        =      value
00190 
00191 #define       PANIC(msg)                                      \
00192               .set   push;                       \
00193               .set   reorder;                        \
00194               la     a0,8f;                          \
00195               jal    panic;                          \
00196 9:            b      9b;                             \
00197               .set   pop;                        \
00198               TEXT(msg)
00199 
00200 /*
00201  * Print formated string
00202  */
00203 #define PRINT(string)                                   \
00204               .set   push;                       \
00205               .set   reorder;                        \
00206               la     a0,8f;                          \
00207               jal    printk;                         \
00208               .set   pop;                        \
00209               TEXT(string)
00210 
00211 #define       TEXT(msg)                                       \
00212               .data;                                  \
00213 8:            .asciiz       msg;                            \
00214               .previous;
00215 
00216 /*
00217  * Build text tables
00218  */
00219 #define TTABLE(string)                                  \
00220               .text;                                  \
00221               .word  1f;                             \
00222               .previous;                              \
00223               .data;                                  \
00224 1:            .asciz string;                         \
00225               .previous
00226 
00227 /*
00228  * MIPS IV pref instruction.
00229  * Use with .set noreorder only!
00230  *
00231  * MIPS IV implementations are free to treat this as a nop.  The R5000
00232  * is one of them.  So we should have an option not to use this instruction.
00233  */
00234 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
00235     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
00236 # define PREF(hint,addr)                                 \
00237               pref   hint,addr
00238 # define PREFX(hint,addr)                                \
00239               prefx  hint,addr
00240 #else
00241 # define PREF
00242 # define PREFX
00243 #endif
00244 
00245 /*
00246  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
00247  */
00248 #if _MIPS_ISA == _MIPS_ISA_MIPS1
00249 # define MOVN(rd,rs,rt)                                 \
00250               .set   push;                       \
00251               .set   reorder;                    \
00252               beqz   rt,9f;                      \
00253               move   rd,rs;                      \
00254               .set   pop;                        \
00255 9:
00256 # define MOVZ(rd,rs,rt)                                 \
00257               .set   push;                       \
00258               .set   reorder;                    \
00259               bnez   rt,9f;                      \
00260               move   rd,rt;                      \
00261               .set   pop;                        \
00262 9:
00263 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
00264 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
00265 # define MOVN(rd,rs,rt)                                 \
00266               .set   push;                       \
00267               .set   noreorder;                  \
00268               bnezl  rt,9f;                      \
00269               move   rd,rs;                      \
00270               .set   pop;                        \
00271 9:
00272 # define MOVZ(rd,rs,rt)                                 \
00273               .set   push;                       \
00274               .set   noreorder;                  \
00275               beqzl  rt,9f;                      \
00276               movz   rd,rs;                      \
00277               .set   pop;                        \
00278 9:
00279 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
00280 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
00281     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
00282 # define MOVN(rd,rs,rt)                                 \
00283               movn   rd,rs,rt
00284 # define MOVZ(rd,rs,rt)                                 \
00285               movz   rd,rs,rt
00286 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
00287 
00288 /*
00289  * Stack alignment
00290  */
00291 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
00292 # define ALSZ 15
00293 # define ALMASK      ~15
00294 #else
00295 # define ALSZ 7
00296 # define ALMASK      ~7
00297 #endif
00298 
00299 /*
00300  * Size of a register
00301  */
00302 #if _MIPS_SIM == _ABI64 || _MIPS_SIM == _ABIN32
00303 # define SZREG       8
00304 #else
00305 # define SZREG       4
00306 #endif
00307 
00308 /*
00309  * Use the following macros in assemblercode to load/store registers,
00310  * pointers etc.
00311  */
00312 #if (SZREG == 4)
00313 # define REG_S sw
00314 # define REG_L lw
00315 #else
00316 # define REG_S sd
00317 # define REG_L ld
00318 #endif
00319 
00320 /*
00321  * How to add/sub/load/store/shift C int variables.
00322  */
00323 #if (_MIPS_SZINT == 32)
00324 # define INT_ADD     add
00325 # define INT_ADDI    addi
00326 # define INT_ADDU    addu
00327 # define INT_ADDIU   addiu
00328 # define INT_SUB     add
00329 # define INT_SUBI    subi
00330 # define INT_SUBU    subu
00331 # define INT_SUBIU   subu
00332 # define INT_L              lw
00333 # define INT_S              sw
00334 #endif
00335 
00336 #if (_MIPS_SZINT == 64)
00337 # define INT_ADD     dadd
00338 # define INT_ADDI    daddi
00339 # define INT_ADDU    daddu
00340 # define INT_ADDIU   daddiu
00341 # define INT_SUB     dadd
00342 # define INT_SUBI    dsubi
00343 # define INT_SUBU    dsubu
00344 # define INT_SUBIU   dsubu
00345 # define INT_L              ld
00346 # define INT_S              sd
00347 #endif
00348 
00349 /*
00350  * How to add/sub/load/store/shift C long variables.
00351  */
00352 #if (_MIPS_SZLONG == 32)
00353 # define LONG_ADD    add
00354 # define LONG_ADDI   addi
00355 # define LONG_ADDU   addu
00356 # define LONG_ADDIU  addiu
00357 # define LONG_SUB    add
00358 # define LONG_SUBI   subi
00359 # define LONG_SUBU   subu
00360 # define LONG_SUBIU  subu
00361 # define LONG_L             lw
00362 # define LONG_S             sw
00363 # define LONG_SLL    sll
00364 # define LONG_SLLV   sllv
00365 # define LONG_SRL    srl
00366 # define LONG_SRLV   srlv
00367 # define LONG_SRA    sra
00368 # define LONG_SRAV   srav
00369 #endif
00370 
00371 #if (_MIPS_SZLONG == 64)
00372 # define LONG_ADD    dadd
00373 # define LONG_ADDI   daddi
00374 # define LONG_ADDU   daddu
00375 # define LONG_ADDIU  daddiu
00376 # define LONG_SUB    dadd
00377 # define LONG_SUBI   dsubi
00378 # define LONG_SUBU   dsubu
00379 # define LONG_SUBIU  dsubu
00380 # define LONG_L             ld
00381 # define LONG_S             sd
00382 # define LONG_SLL    dsll
00383 # define LONG_SLLV   dsllv
00384 # define LONG_SRL    dsrl
00385 # define LONG_SRLV   dsrlv
00386 # define LONG_SRA    dsra
00387 # define LONG_SRAV   dsrav
00388 #endif
00389 
00390 /*
00391  * How to add/sub/load/store/shift pointers.
00392  */
00393 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 32)
00394 # define PTR_ADD     add
00395 # define PTR_ADDI    addi
00396 # define PTR_ADDU    addu
00397 # define PTR_ADDIU   addiu
00398 # define PTR_SUB     add
00399 # define PTR_SUBI    subi
00400 # define PTR_SUBU    subu
00401 # define PTR_SUBIU   subu
00402 # define PTR_L              lw
00403 # define PTR_LA             la
00404 # define PTR_S              sw
00405 # define PTR_SLL     sll
00406 # define PTR_SLLV    sllv
00407 # define PTR_SRL     srl
00408 # define PTR_SRLV    srlv
00409 # define PTR_SRA     sra
00410 # define PTR_SRAV    srav
00411 
00412 # define PTR_SCALESHIFT     2
00413 #endif
00414 
00415 #if _MIPS_SIM == _ABIN32
00416 # define PTR_ADD     add
00417 # define PTR_ADDI    addi
00418 # define PTR_ADDU    add /* no u */
00419 # define PTR_ADDIU   addi /* no u */
00420 # define PTR_SUB     add
00421 # define PTR_SUBI    subi
00422 # define PTR_SUBU    sub /* no u */
00423 # define PTR_SUBIU   sub /* no u */
00424 # define PTR_L              lw
00425 # define PTR_LA             la
00426 # define PTR_S              sw
00427 # define PTR_SLL     sll
00428 # define PTR_SLLV    sllv
00429 # define PTR_SRL     srl
00430 # define PTR_SRLV    srlv
00431 # define PTR_SRA     sra
00432 # define PTR_SRAV    srav
00433 
00434 # define PTR_SCALESHIFT     2
00435 #endif
00436 
00437 #if (_MIPS_SIM == _ABIO32 && _MIPS_SZPTR == 64 /* o64??? */) \
00438     || _MIPS_SIM == _ABI64
00439 # define PTR_ADD     dadd
00440 # define PTR_ADDI    daddi
00441 # define PTR_ADDU    daddu
00442 # define PTR_ADDIU   daddiu
00443 # define PTR_SUB     dadd
00444 # define PTR_SUBI    dsubi
00445 # define PTR_SUBU    dsubu
00446 # define PTR_SUBIU   dsubu
00447 # define PTR_L              ld
00448 # define PTR_LA             dla
00449 # define PTR_S              sd
00450 # define PTR_SLL     dsll
00451 # define PTR_SLLV    dsllv
00452 # define PTR_SRL     dsrl
00453 # define PTR_SRLV    dsrlv
00454 # define PTR_SRA     dsra
00455 # define PTR_SRAV    dsrav
00456 
00457 # define PTR_SCALESHIFT     3
00458 #endif
00459 
00460 /*
00461  * Some cp0 registers were extended to 64bit for MIPS III.
00462  */
00463 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
00464     (_MIPS_ISA == _MIPS_ISA_MIPS32)
00465 # define MFC0 mfc0
00466 # define MTC0 mtc0
00467 #endif
00468 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
00469     (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
00470 # define MFC0 dmfc0
00471 # define MTC0 dmtc0
00472 #endif
00473 
00474 /* The MIPS archtectures do not have a uniform memory model.  Particular
00475    platforms may provide additional guarantees - for instance, the R4000
00476    LL and SC instructions implicitly perform a SYNC, and the 4K promises
00477    strong ordering.
00478 
00479    However, in the absence of those guarantees, we must assume weak ordering
00480    and SYNC explicitly where necessary.
00481 
00482    Some obsolete MIPS processors may not support the SYNC instruction.  This
00483    applies to "true" MIPS I processors; most of the processors which compile
00484    using MIPS I implement parts of MIPS II.  */
00485 
00486 #ifndef MIPS_SYNC
00487 # define MIPS_SYNC   sync
00488 #endif
00489 
00490 #endif /* sys/asm.h */