1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * This file is subject to the terms and conditions of the GNU General Public 3*4882a593Smuzhiyun * License. See the file "COPYING" in the main directory of this archive 4*4882a593Smuzhiyun * for more details. 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle 7*4882a593Smuzhiyun * Copyright (C) 1999 by Silicon Graphics, Inc. 8*4882a593Smuzhiyun * Copyright (C) 2001 MIPS Technologies, Inc. 9*4882a593Smuzhiyun * Copyright (C) 2002 Maciej W. Rozycki 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * Some useful macros for MIPS assembler code 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * Some of the routines below contain useless nops that will be optimized 14*4882a593Smuzhiyun * away by gas in -O mode. These nops are however required to fill delay 15*4882a593Smuzhiyun * slots in noreorder mode. 16*4882a593Smuzhiyun */ 17*4882a593Smuzhiyun #ifndef __ASM_ASM_H 18*4882a593Smuzhiyun #define __ASM_ASM_H 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #include <asm/sgidefs.h> 21*4882a593Smuzhiyun #include <asm/asm-eva.h> 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #ifndef __VDSO__ 24*4882a593Smuzhiyun /* 25*4882a593Smuzhiyun * Emit CFI data in .debug_frame sections, not .eh_frame sections. 26*4882a593Smuzhiyun * We don't do DWARF unwinding at runtime, so only the offline DWARF 27*4882a593Smuzhiyun * information is useful to anyone. Note we should change this if we 28*4882a593Smuzhiyun * ever decide to enable DWARF unwinding at runtime. 29*4882a593Smuzhiyun */ 30*4882a593Smuzhiyun #define CFI_SECTIONS .cfi_sections .debug_frame 31*4882a593Smuzhiyun #else 32*4882a593Smuzhiyun /* 33*4882a593Smuzhiyun * For the vDSO, emit both runtime unwind information and debug 34*4882a593Smuzhiyun * symbols for the .dbg file. 35*4882a593Smuzhiyun */ 36*4882a593Smuzhiyun #define CFI_SECTIONS 37*4882a593Smuzhiyun #endif 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun /* 40*4882a593Smuzhiyun * LEAF - declare leaf routine 41*4882a593Smuzhiyun */ 42*4882a593Smuzhiyun #define LEAF(symbol) \ 43*4882a593Smuzhiyun CFI_SECTIONS; \ 44*4882a593Smuzhiyun .globl symbol; \ 45*4882a593Smuzhiyun .align 2; \ 46*4882a593Smuzhiyun .type symbol, @function; \ 47*4882a593Smuzhiyun .ent symbol, 0; \ 48*4882a593Smuzhiyun symbol: .frame sp, 0, ra; \ 49*4882a593Smuzhiyun .cfi_startproc; \ 50*4882a593Smuzhiyun .insn 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* 53*4882a593Smuzhiyun * NESTED - declare nested routine entry point 54*4882a593Smuzhiyun */ 55*4882a593Smuzhiyun #define NESTED(symbol, framesize, rpc) \ 56*4882a593Smuzhiyun CFI_SECTIONS; \ 57*4882a593Smuzhiyun .globl symbol; \ 58*4882a593Smuzhiyun .align 2; \ 59*4882a593Smuzhiyun .type symbol, @function; \ 60*4882a593Smuzhiyun .ent symbol, 0; \ 61*4882a593Smuzhiyun symbol: .frame sp, framesize, rpc; \ 62*4882a593Smuzhiyun .cfi_startproc; \ 63*4882a593Smuzhiyun .insn 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun /* 66*4882a593Smuzhiyun * END - mark end of function 67*4882a593Smuzhiyun */ 68*4882a593Smuzhiyun #define END(function) \ 69*4882a593Smuzhiyun .cfi_endproc; \ 70*4882a593Smuzhiyun .end function; \ 71*4882a593Smuzhiyun .size function, .-function 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun /* 74*4882a593Smuzhiyun * EXPORT - export definition of symbol 75*4882a593Smuzhiyun */ 76*4882a593Smuzhiyun #define EXPORT(symbol) \ 77*4882a593Smuzhiyun .globl symbol; \ 78*4882a593Smuzhiyun symbol: 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun /* 81*4882a593Smuzhiyun * FEXPORT - export definition of a function symbol 82*4882a593Smuzhiyun */ 83*4882a593Smuzhiyun #define FEXPORT(symbol) \ 84*4882a593Smuzhiyun .globl symbol; \ 85*4882a593Smuzhiyun .type symbol, @function; \ 86*4882a593Smuzhiyun symbol: .insn 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun /* 89*4882a593Smuzhiyun * ABS - export absolute symbol 90*4882a593Smuzhiyun */ 91*4882a593Smuzhiyun #define ABS(symbol,value) \ 92*4882a593Smuzhiyun .globl symbol; \ 93*4882a593Smuzhiyun symbol = value 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun #define TEXT(msg) \ 96*4882a593Smuzhiyun .pushsection .data; \ 97*4882a593Smuzhiyun 8: .asciiz msg; \ 98*4882a593Smuzhiyun .popsection; 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun #define ASM_PANIC(msg) \ 101*4882a593Smuzhiyun .set push; \ 102*4882a593Smuzhiyun .set reorder; \ 103*4882a593Smuzhiyun PTR_LA a0, 8f; \ 104*4882a593Smuzhiyun jal panic; \ 105*4882a593Smuzhiyun 9: b 9b; \ 106*4882a593Smuzhiyun .set pop; \ 107*4882a593Smuzhiyun TEXT(msg) 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun /* 110*4882a593Smuzhiyun * Print formatted string 111*4882a593Smuzhiyun */ 112*4882a593Smuzhiyun #ifdef CONFIG_PRINTK 113*4882a593Smuzhiyun #define ASM_PRINT(string) \ 114*4882a593Smuzhiyun .set push; \ 115*4882a593Smuzhiyun .set reorder; \ 116*4882a593Smuzhiyun PTR_LA a0, 8f; \ 117*4882a593Smuzhiyun jal printk; \ 118*4882a593Smuzhiyun .set pop; \ 119*4882a593Smuzhiyun TEXT(string) 120*4882a593Smuzhiyun #else 121*4882a593Smuzhiyun #define ASM_PRINT(string) 122*4882a593Smuzhiyun #endif 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun /* 125*4882a593Smuzhiyun * Stack alignment 126*4882a593Smuzhiyun */ 127*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_ABI32) 128*4882a593Smuzhiyun #define ALSZ 7 129*4882a593Smuzhiyun #define ALMASK ~7 130*4882a593Smuzhiyun #endif 131*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 132*4882a593Smuzhiyun #define ALSZ 15 133*4882a593Smuzhiyun #define ALMASK ~15 134*4882a593Smuzhiyun #endif 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun /* 137*4882a593Smuzhiyun * Macros to handle different pointer/register sizes for 32/64-bit code 138*4882a593Smuzhiyun */ 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun /* 141*4882a593Smuzhiyun * Size of a register 142*4882a593Smuzhiyun */ 143*4882a593Smuzhiyun #ifdef __mips64 144*4882a593Smuzhiyun #define SZREG 8 145*4882a593Smuzhiyun #else 146*4882a593Smuzhiyun #define SZREG 4 147*4882a593Smuzhiyun #endif 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun /* 150*4882a593Smuzhiyun * Use the following macros in assemblercode to load/store registers, 151*4882a593Smuzhiyun * pointers etc. 152*4882a593Smuzhiyun */ 153*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_ABI32) 154*4882a593Smuzhiyun #define REG_S sw 155*4882a593Smuzhiyun #define REG_L lw 156*4882a593Smuzhiyun #define REG_SUBU subu 157*4882a593Smuzhiyun #define REG_ADDU addu 158*4882a593Smuzhiyun #endif 159*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 160*4882a593Smuzhiyun #define REG_S sd 161*4882a593Smuzhiyun #define REG_L ld 162*4882a593Smuzhiyun #define REG_SUBU dsubu 163*4882a593Smuzhiyun #define REG_ADDU daddu 164*4882a593Smuzhiyun #endif 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun /* 167*4882a593Smuzhiyun * How to add/sub/load/store/shift C int variables. 168*4882a593Smuzhiyun */ 169*4882a593Smuzhiyun #if (_MIPS_SZINT == 32) 170*4882a593Smuzhiyun #define INT_ADD add 171*4882a593Smuzhiyun #define INT_ADDU addu 172*4882a593Smuzhiyun #define INT_ADDI addi 173*4882a593Smuzhiyun #define INT_ADDIU addiu 174*4882a593Smuzhiyun #define INT_SUB sub 175*4882a593Smuzhiyun #define INT_SUBU subu 176*4882a593Smuzhiyun #define INT_L lw 177*4882a593Smuzhiyun #define INT_S sw 178*4882a593Smuzhiyun #define INT_SLL sll 179*4882a593Smuzhiyun #define INT_SLLV sllv 180*4882a593Smuzhiyun #define INT_SRL srl 181*4882a593Smuzhiyun #define INT_SRLV srlv 182*4882a593Smuzhiyun #define INT_SRA sra 183*4882a593Smuzhiyun #define INT_SRAV srav 184*4882a593Smuzhiyun #endif 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun #if (_MIPS_SZINT == 64) 187*4882a593Smuzhiyun #define INT_ADD dadd 188*4882a593Smuzhiyun #define INT_ADDU daddu 189*4882a593Smuzhiyun #define INT_ADDI daddi 190*4882a593Smuzhiyun #define INT_ADDIU daddiu 191*4882a593Smuzhiyun #define INT_SUB dsub 192*4882a593Smuzhiyun #define INT_SUBU dsubu 193*4882a593Smuzhiyun #define INT_L ld 194*4882a593Smuzhiyun #define INT_S sd 195*4882a593Smuzhiyun #define INT_SLL dsll 196*4882a593Smuzhiyun #define INT_SLLV dsllv 197*4882a593Smuzhiyun #define INT_SRL dsrl 198*4882a593Smuzhiyun #define INT_SRLV dsrlv 199*4882a593Smuzhiyun #define INT_SRA dsra 200*4882a593Smuzhiyun #define INT_SRAV dsrav 201*4882a593Smuzhiyun #endif 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun /* 204*4882a593Smuzhiyun * How to add/sub/load/store/shift C long variables. 205*4882a593Smuzhiyun */ 206*4882a593Smuzhiyun #if (_MIPS_SZLONG == 32) 207*4882a593Smuzhiyun #define LONG_ADD add 208*4882a593Smuzhiyun #define LONG_ADDU addu 209*4882a593Smuzhiyun #define LONG_ADDI addi 210*4882a593Smuzhiyun #define LONG_ADDIU addiu 211*4882a593Smuzhiyun #define LONG_SUB sub 212*4882a593Smuzhiyun #define LONG_SUBU subu 213*4882a593Smuzhiyun #define LONG_L lw 214*4882a593Smuzhiyun #define LONG_S sw 215*4882a593Smuzhiyun #define LONG_SP swp 216*4882a593Smuzhiyun #define LONG_SLL sll 217*4882a593Smuzhiyun #define LONG_SLLV sllv 218*4882a593Smuzhiyun #define LONG_SRL srl 219*4882a593Smuzhiyun #define LONG_SRLV srlv 220*4882a593Smuzhiyun #define LONG_SRA sra 221*4882a593Smuzhiyun #define LONG_SRAV srav 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun #ifdef __ASSEMBLY__ 224*4882a593Smuzhiyun #define LONG .word 225*4882a593Smuzhiyun #endif 226*4882a593Smuzhiyun #define LONGSIZE 4 227*4882a593Smuzhiyun #define LONGMASK 3 228*4882a593Smuzhiyun #define LONGLOG 2 229*4882a593Smuzhiyun #endif 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun #if (_MIPS_SZLONG == 64) 232*4882a593Smuzhiyun #define LONG_ADD dadd 233*4882a593Smuzhiyun #define LONG_ADDU daddu 234*4882a593Smuzhiyun #define LONG_ADDI daddi 235*4882a593Smuzhiyun #define LONG_ADDIU daddiu 236*4882a593Smuzhiyun #define LONG_SUB dsub 237*4882a593Smuzhiyun #define LONG_SUBU dsubu 238*4882a593Smuzhiyun #define LONG_L ld 239*4882a593Smuzhiyun #define LONG_S sd 240*4882a593Smuzhiyun #define LONG_SP sdp 241*4882a593Smuzhiyun #define LONG_SLL dsll 242*4882a593Smuzhiyun #define LONG_SLLV dsllv 243*4882a593Smuzhiyun #define LONG_SRL dsrl 244*4882a593Smuzhiyun #define LONG_SRLV dsrlv 245*4882a593Smuzhiyun #define LONG_SRA dsra 246*4882a593Smuzhiyun #define LONG_SRAV dsrav 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun #ifdef __ASSEMBLY__ 249*4882a593Smuzhiyun #define LONG .dword 250*4882a593Smuzhiyun #endif 251*4882a593Smuzhiyun #define LONGSIZE 8 252*4882a593Smuzhiyun #define LONGMASK 7 253*4882a593Smuzhiyun #define LONGLOG 3 254*4882a593Smuzhiyun #endif 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun /* 257*4882a593Smuzhiyun * How to add/sub/load/store/shift pointers. 258*4882a593Smuzhiyun */ 259*4882a593Smuzhiyun #if (_MIPS_SZPTR == 32) 260*4882a593Smuzhiyun #define PTR_ADD add 261*4882a593Smuzhiyun #define PTR_ADDU addu 262*4882a593Smuzhiyun #define PTR_ADDI addi 263*4882a593Smuzhiyun #define PTR_ADDIU addiu 264*4882a593Smuzhiyun #define PTR_SUB sub 265*4882a593Smuzhiyun #define PTR_SUBU subu 266*4882a593Smuzhiyun #define PTR_L lw 267*4882a593Smuzhiyun #define PTR_S sw 268*4882a593Smuzhiyun #define PTR_LA la 269*4882a593Smuzhiyun #define PTR_LI li 270*4882a593Smuzhiyun #define PTR_SLL sll 271*4882a593Smuzhiyun #define PTR_SLLV sllv 272*4882a593Smuzhiyun #define PTR_SRL srl 273*4882a593Smuzhiyun #define PTR_SRLV srlv 274*4882a593Smuzhiyun #define PTR_SRA sra 275*4882a593Smuzhiyun #define PTR_SRAV srav 276*4882a593Smuzhiyun 277*4882a593Smuzhiyun #define PTR_SCALESHIFT 2 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun #define PTR .word 280*4882a593Smuzhiyun #define PTRSIZE 4 281*4882a593Smuzhiyun #define PTRLOG 2 282*4882a593Smuzhiyun #endif 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun #if (_MIPS_SZPTR == 64) 285*4882a593Smuzhiyun #define PTR_ADD dadd 286*4882a593Smuzhiyun #define PTR_ADDU daddu 287*4882a593Smuzhiyun #define PTR_ADDI daddi 288*4882a593Smuzhiyun #define PTR_ADDIU daddiu 289*4882a593Smuzhiyun #define PTR_SUB dsub 290*4882a593Smuzhiyun #define PTR_SUBU dsubu 291*4882a593Smuzhiyun #define PTR_L ld 292*4882a593Smuzhiyun #define PTR_S sd 293*4882a593Smuzhiyun #define PTR_LA dla 294*4882a593Smuzhiyun #define PTR_LI dli 295*4882a593Smuzhiyun #define PTR_SLL dsll 296*4882a593Smuzhiyun #define PTR_SLLV dsllv 297*4882a593Smuzhiyun #define PTR_SRL dsrl 298*4882a593Smuzhiyun #define PTR_SRLV dsrlv 299*4882a593Smuzhiyun #define PTR_SRA dsra 300*4882a593Smuzhiyun #define PTR_SRAV dsrav 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun #define PTR_SCALESHIFT 3 303*4882a593Smuzhiyun 304*4882a593Smuzhiyun #define PTR .dword 305*4882a593Smuzhiyun #define PTRSIZE 8 306*4882a593Smuzhiyun #define PTRLOG 3 307*4882a593Smuzhiyun #endif 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun /* 310*4882a593Smuzhiyun * Some cp0 registers were extended to 64bit for MIPS III. 311*4882a593Smuzhiyun */ 312*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_ABI32) 313*4882a593Smuzhiyun #define MFC0 mfc0 314*4882a593Smuzhiyun #define MTC0 mtc0 315*4882a593Smuzhiyun #endif 316*4882a593Smuzhiyun #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 317*4882a593Smuzhiyun #define MFC0 dmfc0 318*4882a593Smuzhiyun #define MTC0 dmtc0 319*4882a593Smuzhiyun #endif 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun #define SSNOP sll zero, zero, 1 322*4882a593Smuzhiyun 323*4882a593Smuzhiyun #ifdef CONFIG_SGI_IP28 324*4882a593Smuzhiyun /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 325*4882a593Smuzhiyun #include <asm/cacheops.h> 326*4882a593Smuzhiyun #define R10KCBARRIER(addr) cache Cache_Barrier, addr; 327*4882a593Smuzhiyun #else 328*4882a593Smuzhiyun #define R10KCBARRIER(addr) 329*4882a593Smuzhiyun #endif 330*4882a593Smuzhiyun 331*4882a593Smuzhiyun #endif /* __ASM_ASM_H */ 332