| Viewing file:  asm.h (8.2 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
/** This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
 * Copyright (C) 1999 by Silicon Graphics, Inc.
 * Copyright (C) 2001 MIPS Technologies, Inc.
 * Copyright (C) 2002  Maciej W. Rozycki
 *
 * Some useful macros for MIPS assembler code
 *
 * Some of the routines below contain useless nops that will be optimized
 * away by gas in -O mode. These nops are however required to fill delay
 * slots in noreorder mode.
 */
 #ifndef __ASM_ASM_H
 #define __ASM_ASM_H
 
 #include <asm/sgidefs.h>
 
 #ifndef CAT
 #ifdef __STDC__
 #define __CAT(str1, str2) str1##str2
 #else
 #define __CAT(str1, str2) str1/**/str2
 #endif
 #define CAT(str1, str2) __CAT(str1, str2)
 #endif
 
 /*
 * PIC specific declarations
 * Not used for the kernel but here seems to be the right place.
 */
 #ifdef __PIC__
 #define CPRESTORE(register)                \
 .cprestore register
 #define CPADD(register)                    \
 .cpadd    register
 #define CPLOAD(register)                \
 .cpload register
 #else
 #define CPRESTORE(register)
 #define CPADD(register)
 #define CPLOAD(register)
 #endif
 
 /*
 * LEAF - declare leaf routine
 */
 #define LEAF(symbol)                    \
 .globl    symbol;                \
 .align    2;                \
 .type    symbol, @function;        \
 .ent    symbol, 0;            \
 symbol:        .frame    sp, 0, ra
 
 /*
 * NESTED - declare nested routine entry point
 */
 #define NESTED(symbol, framesize, rpc)            \
 .globl    symbol;                \
 .align    2;                \
 .type    symbol, @function;        \
 .ent    symbol, 0;             \
 symbol:        .frame    sp, framesize, rpc
 
 /*
 * END - mark end of function
 */
 #define END(function)                    \
 .end    function;            \
 .size    function, .-function
 
 /*
 * EXPORT - export definition of symbol
 */
 #define EXPORT(symbol)                    \
 .globl    symbol;                \
 symbol:
 
 /*
 * FEXPORT - export definition of a function symbol
 */
 #define FEXPORT(symbol)                    \
 .globl    symbol;                \
 .type    symbol, @function;        \
 symbol:
 
 /*
 * ABS - export absolute symbol
 */
 #define ABS(symbol,value)                \
 .globl    symbol;                \
 symbol        =    value
 
 #define PANIC(msg)                    \
 .set    push;                \
 .set    reorder;            \
 PTR_LA    a0, 8f;                 \
 jal    panic;                \
 9:        b    9b;                \
 .set    pop;                \
 TEXT(msg)
 
 /*
 * Print formatted string
 */
 #ifdef CONFIG_PRINTK
 #define PRINT(string)                    \
 .set    push;                \
 .set    reorder;            \
 PTR_LA    a0, 8f;                 \
 jal    printk;                \
 .set    pop;                \
 TEXT(string)
 #else
 #define PRINT(string)
 #endif
 
 #define TEXT(msg)                    \
 .pushsection .data;            \
 8:        .asciiz msg;                \
 .popsection;
 
 /*
 * Build text tables
 */
 #define TTABLE(string)                    \
 .pushsection .text;            \
 .word    1f;                \
 .popsection                \
 .pushsection .data;            \
 1:        .asciiz string;                \
 .popsection
 
 /*
 * MIPS IV pref instruction.
 * Use with .set noreorder only!
 *
 * MIPS IV implementations are free to treat this as a nop.  The R5000
 * is one of them.  So we should have an option not to use this instruction.
 */
 #ifdef CONFIG_CPU_HAS_PREFETCH
 
 #define PREF(hint,addr)                    \
 .set    push;                \
 .set    mips4;                \
 pref    hint, addr;            \
 .set    pop
 
 #define PREFX(hint,addr)                \
 .set    push;                \
 .set    mips4;                \
 prefx    hint, addr;            \
 .set    pop
 
 #else /* !CONFIG_CPU_HAS_PREFETCH */
 
 #define PREF(hint, addr)
 #define PREFX(hint, addr)
 
 #endif /* !CONFIG_CPU_HAS_PREFETCH */
 
 /*
 * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
 */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS1)
 #define MOVN(rd, rs, rt)                \
 .set    push;                \
 .set    reorder;            \
 beqz    rt, 9f;                \
 move    rd, rs;                \
 .set    pop;                \
 9:
 #define MOVZ(rd, rs, rt)                \
 .set    push;                \
 .set    reorder;            \
 bnez    rt, 9f;                \
 move    rd, rs;                \
 .set    pop;                \
 9:
 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
 #define MOVN(rd, rs, rt)                \
 .set    push;                \
 .set    noreorder;            \
 bnezl    rt, 9f;                \
 move    rd, rs;                \
 .set    pop;                \
 9:
 #define MOVZ(rd, rs, rt)                \
 .set    push;                \
 .set    noreorder;            \
 beqzl    rt, 9f;                \
 move    rd, rs;                \
 .set    pop;                \
 9:
 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
 #define MOVN(rd, rs, rt)                \
 movn    rd, rs, rt
 #define MOVZ(rd, rs, rt)                \
 movz    rd, rs, rt
 #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
 
 /*
 * Stack alignment
 */
 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
 #define ALSZ    7
 #define ALMASK    ~7
 #endif
 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
 #define ALSZ    15
 #define ALMASK    ~15
 #endif
 
 /*
 * Macros to handle different pointer/register sizes for 32/64-bit code
 */
 
 /*
 * Size of a register
 */
 #ifdef __mips64
 #define SZREG    8
 #else
 #define SZREG    4
 #endif
 
 /*
 * Use the following macros in assemblercode to load/store registers,
 * pointers etc.
 */
 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
 #define REG_S        sw
 #define REG_L        lw
 #define REG_SUBU    subu
 #define REG_ADDU    addu
 #endif
 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
 #define REG_S        sd
 #define REG_L        ld
 #define REG_SUBU    dsubu
 #define REG_ADDU    daddu
 #endif
 
 /*
 * How to add/sub/load/store/shift C int variables.
 */
 #if (_MIPS_SZINT == 32)
 #define INT_ADD        add
 #define INT_ADDU    addu
 #define INT_ADDI    addi
 #define INT_ADDIU    addiu
 #define INT_SUB        sub
 #define INT_SUBU    subu
 #define INT_L        lw
 #define INT_S        sw
 #define INT_SLL        sll
 #define INT_SLLV    sllv
 #define INT_SRL        srl
 #define INT_SRLV    srlv
 #define INT_SRA        sra
 #define INT_SRAV    srav
 #endif
 
 #if (_MIPS_SZINT == 64)
 #define INT_ADD        dadd
 #define INT_ADDU    daddu
 #define INT_ADDI    daddi
 #define INT_ADDIU    daddiu
 #define INT_SUB        dsub
 #define INT_SUBU    dsubu
 #define INT_L        ld
 #define INT_S        sd
 #define INT_SLL        dsll
 #define INT_SLLV    dsllv
 #define INT_SRL        dsrl
 #define INT_SRLV    dsrlv
 #define INT_SRA        dsra
 #define INT_SRAV    dsrav
 #endif
 
 /*
 * How to add/sub/load/store/shift C long variables.
 */
 #if (_MIPS_SZLONG == 32)
 #define LONG_ADD    add
 #define LONG_ADDU    addu
 #define LONG_ADDI    addi
 #define LONG_ADDIU    addiu
 #define LONG_SUB    sub
 #define LONG_SUBU    subu
 #define LONG_L        lw
 #define LONG_S        sw
 #define LONG_SP        swp
 #define LONG_SLL    sll
 #define LONG_SLLV    sllv
 #define LONG_SRL    srl
 #define LONG_SRLV    srlv
 #define LONG_SRA    sra
 #define LONG_SRAV    srav
 
 #define LONG        .word
 #define LONGSIZE    4
 #define LONGMASK    3
 #define LONGLOG        2
 #endif
 
 #if (_MIPS_SZLONG == 64)
 #define LONG_ADD    dadd
 #define LONG_ADDU    daddu
 #define LONG_ADDI    daddi
 #define LONG_ADDIU    daddiu
 #define LONG_SUB    dsub
 #define LONG_SUBU    dsubu
 #define LONG_L        ld
 #define LONG_S        sd
 #define LONG_SP        sdp
 #define LONG_SLL    dsll
 #define LONG_SLLV    dsllv
 #define LONG_SRL    dsrl
 #define LONG_SRLV    dsrlv
 #define LONG_SRA    dsra
 #define LONG_SRAV    dsrav
 
 #define LONG        .dword
 #define LONGSIZE    8
 #define LONGMASK    7
 #define LONGLOG        3
 #endif
 
 /*
 * How to add/sub/load/store/shift pointers.
 */
 #if (_MIPS_SZPTR == 32)
 #define PTR_ADD        add
 #define PTR_ADDU    addu
 #define PTR_ADDI    addi
 #define PTR_ADDIU    addiu
 #define PTR_SUB        sub
 #define PTR_SUBU    subu
 #define PTR_L        lw
 #define PTR_S        sw
 #define PTR_LA        la
 #define PTR_LI        li
 #define PTR_SLL        sll
 #define PTR_SLLV    sllv
 #define PTR_SRL        srl
 #define PTR_SRLV    srlv
 #define PTR_SRA        sra
 #define PTR_SRAV    srav
 
 #define PTR_SCALESHIFT    2
 
 #define PTR        .word
 #define PTRSIZE        4
 #define PTRLOG        2
 #endif
 
 #if (_MIPS_SZPTR == 64)
 #define PTR_ADD        dadd
 #define PTR_ADDU    daddu
 #define PTR_ADDI    daddi
 #define PTR_ADDIU    daddiu
 #define PTR_SUB        dsub
 #define PTR_SUBU    dsubu
 #define PTR_L        ld
 #define PTR_S        sd
 #define PTR_LA        dla
 #define PTR_LI        dli
 #define PTR_SLL        dsll
 #define PTR_SLLV    dsllv
 #define PTR_SRL        dsrl
 #define PTR_SRLV    dsrlv
 #define PTR_SRA        dsra
 #define PTR_SRAV    dsrav
 
 #define PTR_SCALESHIFT    3
 
 #define PTR        .dword
 #define PTRSIZE        8
 #define PTRLOG        3
 #endif
 
 /*
 * Some cp0 registers were extended to 64bit for MIPS III.
 */
 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
 #define MFC0        mfc0
 #define MTC0        mtc0
 #endif
 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
 #define MFC0        dmfc0
 #define MTC0        dmtc0
 #endif
 
 #define SSNOP        sll zero, zero, 1
 
 #ifdef CONFIG_SGI_IP28
 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
 #include <asm/cacheops.h>
 #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
 #else
 #define R10KCBARRIER(addr)
 #endif
 
 #endif /* __ASM_ASM_H */
 
 |