1*819833afSPeter Tyser /* 2*819833afSPeter Tyser * This file is subject to the terms and conditions of the GNU General Public 3*819833afSPeter Tyser * License. See the file "COPYING" in the main directory of this archive 4*819833afSPeter Tyser * for more details. 5*819833afSPeter Tyser * 6*819833afSPeter Tyser * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle 7*819833afSPeter Tyser * Copyright (C) 1999 by Silicon Graphics, Inc. 8*819833afSPeter Tyser * Copyright (C) 2001 MIPS Technologies, Inc. 9*819833afSPeter Tyser * Copyright (C) 2002 Maciej W. Rozycki 10*819833afSPeter Tyser * 11*819833afSPeter Tyser * Some useful macros for MIPS assembler code 12*819833afSPeter Tyser * 13*819833afSPeter Tyser * Some of the routines below contain useless nops that will be optimized 14*819833afSPeter Tyser * away by gas in -O mode. These nops are however required to fill delay 15*819833afSPeter Tyser * slots in noreorder mode. 16*819833afSPeter Tyser */ 17*819833afSPeter Tyser #ifndef __ASM_ASM_H 18*819833afSPeter Tyser #define __ASM_ASM_H 19*819833afSPeter Tyser 20*819833afSPeter Tyser #include <asm/sgidefs.h> 21*819833afSPeter Tyser 22*819833afSPeter Tyser #ifndef CAT 23*819833afSPeter Tyser #ifdef __STDC__ 24*819833afSPeter Tyser #define __CAT(str1, str2) str1##str2 25*819833afSPeter Tyser #else 26*819833afSPeter Tyser #define __CAT(str1, str2) str1/**/str2 27*819833afSPeter Tyser #endif 28*819833afSPeter Tyser #define CAT(str1, str2) __CAT(str1, str2) 29*819833afSPeter Tyser #endif 30*819833afSPeter Tyser 31*819833afSPeter Tyser /* 32*819833afSPeter Tyser * PIC specific declarations 33*819833afSPeter Tyser * Not used for the kernel but here seems to be the right place. 34*819833afSPeter Tyser */ 35*819833afSPeter Tyser #ifdef __PIC__ 36*819833afSPeter Tyser #define CPRESTORE(register) \ 37*819833afSPeter Tyser .cprestore register 38*819833afSPeter Tyser #define CPADD(register) \ 39*819833afSPeter Tyser .cpadd register 40*819833afSPeter Tyser #define CPLOAD(register) \ 41*819833afSPeter Tyser .cpload register 42*819833afSPeter Tyser #else 43*819833afSPeter Tyser #define CPRESTORE(register) 44*819833afSPeter Tyser #define CPADD(register) 45*819833afSPeter Tyser #define CPLOAD(register) 46*819833afSPeter Tyser #endif 47*819833afSPeter Tyser 48*819833afSPeter Tyser /* 49*819833afSPeter Tyser * LEAF - declare leaf routine 50*819833afSPeter Tyser */ 51*819833afSPeter Tyser #define LEAF(symbol) \ 52*819833afSPeter Tyser .globl symbol; \ 53*819833afSPeter Tyser .align 2; \ 54*819833afSPeter Tyser .type symbol, @function; \ 55*819833afSPeter Tyser .ent symbol, 0; \ 56*819833afSPeter Tyser symbol: .frame sp, 0, ra 57*819833afSPeter Tyser 58*819833afSPeter Tyser /* 59*819833afSPeter Tyser * NESTED - declare nested routine entry point 60*819833afSPeter Tyser */ 61*819833afSPeter Tyser #define NESTED(symbol, framesize, rpc) \ 62*819833afSPeter Tyser .globl symbol; \ 63*819833afSPeter Tyser .align 2; \ 64*819833afSPeter Tyser .type symbol, @function; \ 65*819833afSPeter Tyser .ent symbol, 0; \ 66*819833afSPeter Tyser symbol: .frame sp, framesize, rpc 67*819833afSPeter Tyser 68*819833afSPeter Tyser /* 69*819833afSPeter Tyser * END - mark end of function 70*819833afSPeter Tyser */ 71*819833afSPeter Tyser #define END(function) \ 72*819833afSPeter Tyser .end function; \ 73*819833afSPeter Tyser .size function, .-function 74*819833afSPeter Tyser 75*819833afSPeter Tyser /* 76*819833afSPeter Tyser * EXPORT - export definition of symbol 77*819833afSPeter Tyser */ 78*819833afSPeter Tyser #define EXPORT(symbol) \ 79*819833afSPeter Tyser .globl symbol; \ 80*819833afSPeter Tyser symbol: 81*819833afSPeter Tyser 82*819833afSPeter Tyser /* 83*819833afSPeter Tyser * FEXPORT - export definition of a function symbol 84*819833afSPeter Tyser */ 85*819833afSPeter Tyser #define FEXPORT(symbol) \ 86*819833afSPeter Tyser .globl symbol; \ 87*819833afSPeter Tyser .type symbol, @function; \ 88*819833afSPeter Tyser symbol: 89*819833afSPeter Tyser 90*819833afSPeter Tyser /* 91*819833afSPeter Tyser * ABS - export absolute symbol 92*819833afSPeter Tyser */ 93*819833afSPeter Tyser #define ABS(symbol,value) \ 94*819833afSPeter Tyser .globl symbol; \ 95*819833afSPeter Tyser symbol = value 96*819833afSPeter Tyser 97*819833afSPeter Tyser #define PANIC(msg) \ 98*819833afSPeter Tyser .set push; \ 99*819833afSPeter Tyser .set reorder; \ 100*819833afSPeter Tyser PTR_LA a0, 8f; \ 101*819833afSPeter Tyser jal panic; \ 102*819833afSPeter Tyser 9: b 9b; \ 103*819833afSPeter Tyser .set pop; \ 104*819833afSPeter Tyser TEXT(msg) 105*819833afSPeter Tyser 106*819833afSPeter Tyser /* 107*819833afSPeter Tyser * Print formatted string 108*819833afSPeter Tyser */ 109*819833afSPeter Tyser #ifdef CONFIG_PRINTK 110*819833afSPeter Tyser #define PRINT(string) \ 111*819833afSPeter Tyser .set push; \ 112*819833afSPeter Tyser .set reorder; \ 113*819833afSPeter Tyser PTR_LA a0, 8f; \ 114*819833afSPeter Tyser jal printk; \ 115*819833afSPeter Tyser .set pop; \ 116*819833afSPeter Tyser TEXT(string) 117*819833afSPeter Tyser #else 118*819833afSPeter Tyser #define PRINT(string) 119*819833afSPeter Tyser #endif 120*819833afSPeter Tyser 121*819833afSPeter Tyser #define TEXT(msg) \ 122*819833afSPeter Tyser .pushsection .data; \ 123*819833afSPeter Tyser 8: .asciiz msg; \ 124*819833afSPeter Tyser .popsection; 125*819833afSPeter Tyser 126*819833afSPeter Tyser /* 127*819833afSPeter Tyser * Build text tables 128*819833afSPeter Tyser */ 129*819833afSPeter Tyser #define TTABLE(string) \ 130*819833afSPeter Tyser .pushsection .text; \ 131*819833afSPeter Tyser .word 1f; \ 132*819833afSPeter Tyser .popsection \ 133*819833afSPeter Tyser .pushsection .data; \ 134*819833afSPeter Tyser 1: .asciiz string; \ 135*819833afSPeter Tyser .popsection 136*819833afSPeter Tyser 137*819833afSPeter Tyser /* 138*819833afSPeter Tyser * MIPS IV pref instruction. 139*819833afSPeter Tyser * Use with .set noreorder only! 140*819833afSPeter Tyser * 141*819833afSPeter Tyser * MIPS IV implementations are free to treat this as a nop. The R5000 142*819833afSPeter Tyser * is one of them. So we should have an option not to use this instruction. 143*819833afSPeter Tyser */ 144*819833afSPeter Tyser #ifdef CONFIG_CPU_HAS_PREFETCH 145*819833afSPeter Tyser 146*819833afSPeter Tyser #define PREF(hint,addr) \ 147*819833afSPeter Tyser .set push; \ 148*819833afSPeter Tyser .set mips4; \ 149*819833afSPeter Tyser pref hint, addr; \ 150*819833afSPeter Tyser .set pop 151*819833afSPeter Tyser 152*819833afSPeter Tyser #define PREFX(hint,addr) \ 153*819833afSPeter Tyser .set push; \ 154*819833afSPeter Tyser .set mips4; \ 155*819833afSPeter Tyser prefx hint, addr; \ 156*819833afSPeter Tyser .set pop 157*819833afSPeter Tyser 158*819833afSPeter Tyser #else /* !CONFIG_CPU_HAS_PREFETCH */ 159*819833afSPeter Tyser 160*819833afSPeter Tyser #define PREF(hint, addr) 161*819833afSPeter Tyser #define PREFX(hint, addr) 162*819833afSPeter Tyser 163*819833afSPeter Tyser #endif /* !CONFIG_CPU_HAS_PREFETCH */ 164*819833afSPeter Tyser 165*819833afSPeter Tyser /* 166*819833afSPeter Tyser * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. 167*819833afSPeter Tyser */ 168*819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS1) 169*819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 170*819833afSPeter Tyser .set push; \ 171*819833afSPeter Tyser .set reorder; \ 172*819833afSPeter Tyser beqz rt, 9f; \ 173*819833afSPeter Tyser move rd, rs; \ 174*819833afSPeter Tyser .set pop; \ 175*819833afSPeter Tyser 9: 176*819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 177*819833afSPeter Tyser .set push; \ 178*819833afSPeter Tyser .set reorder; \ 179*819833afSPeter Tyser bnez rt, 9f; \ 180*819833afSPeter Tyser move rd, rs; \ 181*819833afSPeter Tyser .set pop; \ 182*819833afSPeter Tyser 9: 183*819833afSPeter Tyser #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ 184*819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) 185*819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 186*819833afSPeter Tyser .set push; \ 187*819833afSPeter Tyser .set noreorder; \ 188*819833afSPeter Tyser bnezl rt, 9f; \ 189*819833afSPeter Tyser move rd, rs; \ 190*819833afSPeter Tyser .set pop; \ 191*819833afSPeter Tyser 9: 192*819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 193*819833afSPeter Tyser .set push; \ 194*819833afSPeter Tyser .set noreorder; \ 195*819833afSPeter Tyser beqzl rt, 9f; \ 196*819833afSPeter Tyser move rd, rs; \ 197*819833afSPeter Tyser .set pop; \ 198*819833afSPeter Tyser 9: 199*819833afSPeter Tyser #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ 200*819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ 201*819833afSPeter Tyser (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 202*819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 203*819833afSPeter Tyser movn rd, rs, rt 204*819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 205*819833afSPeter Tyser movz rd, rs, rt 206*819833afSPeter Tyser #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ 207*819833afSPeter Tyser 208*819833afSPeter Tyser /* 209*819833afSPeter Tyser * Stack alignment 210*819833afSPeter Tyser */ 211*819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 212*819833afSPeter Tyser #define ALSZ 7 213*819833afSPeter Tyser #define ALMASK ~7 214*819833afSPeter Tyser #endif 215*819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 216*819833afSPeter Tyser #define ALSZ 15 217*819833afSPeter Tyser #define ALMASK ~15 218*819833afSPeter Tyser #endif 219*819833afSPeter Tyser 220*819833afSPeter Tyser /* 221*819833afSPeter Tyser * Macros to handle different pointer/register sizes for 32/64-bit code 222*819833afSPeter Tyser */ 223*819833afSPeter Tyser 224*819833afSPeter Tyser /* 225*819833afSPeter Tyser * Size of a register 226*819833afSPeter Tyser */ 227*819833afSPeter Tyser #ifdef __mips64 228*819833afSPeter Tyser #define SZREG 8 229*819833afSPeter Tyser #else 230*819833afSPeter Tyser #define SZREG 4 231*819833afSPeter Tyser #endif 232*819833afSPeter Tyser 233*819833afSPeter Tyser /* 234*819833afSPeter Tyser * Use the following macros in assemblercode to load/store registers, 235*819833afSPeter Tyser * pointers etc. 236*819833afSPeter Tyser */ 237*819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 238*819833afSPeter Tyser #define REG_S sw 239*819833afSPeter Tyser #define REG_L lw 240*819833afSPeter Tyser #define REG_SUBU subu 241*819833afSPeter Tyser #define REG_ADDU addu 242*819833afSPeter Tyser #endif 243*819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 244*819833afSPeter Tyser #define REG_S sd 245*819833afSPeter Tyser #define REG_L ld 246*819833afSPeter Tyser #define REG_SUBU dsubu 247*819833afSPeter Tyser #define REG_ADDU daddu 248*819833afSPeter Tyser #endif 249*819833afSPeter Tyser 250*819833afSPeter Tyser /* 251*819833afSPeter Tyser * How to add/sub/load/store/shift C int variables. 252*819833afSPeter Tyser */ 253*819833afSPeter Tyser #if (_MIPS_SZINT == 32) 254*819833afSPeter Tyser #define INT_ADD add 255*819833afSPeter Tyser #define INT_ADDU addu 256*819833afSPeter Tyser #define INT_ADDI addi 257*819833afSPeter Tyser #define INT_ADDIU addiu 258*819833afSPeter Tyser #define INT_SUB sub 259*819833afSPeter Tyser #define INT_SUBU subu 260*819833afSPeter Tyser #define INT_L lw 261*819833afSPeter Tyser #define INT_S sw 262*819833afSPeter Tyser #define INT_SLL sll 263*819833afSPeter Tyser #define INT_SLLV sllv 264*819833afSPeter Tyser #define INT_SRL srl 265*819833afSPeter Tyser #define INT_SRLV srlv 266*819833afSPeter Tyser #define INT_SRA sra 267*819833afSPeter Tyser #define INT_SRAV srav 268*819833afSPeter Tyser #endif 269*819833afSPeter Tyser 270*819833afSPeter Tyser #if (_MIPS_SZINT == 64) 271*819833afSPeter Tyser #define INT_ADD dadd 272*819833afSPeter Tyser #define INT_ADDU daddu 273*819833afSPeter Tyser #define INT_ADDI daddi 274*819833afSPeter Tyser #define INT_ADDIU daddiu 275*819833afSPeter Tyser #define INT_SUB dsub 276*819833afSPeter Tyser #define INT_SUBU dsubu 277*819833afSPeter Tyser #define INT_L ld 278*819833afSPeter Tyser #define INT_S sd 279*819833afSPeter Tyser #define INT_SLL dsll 280*819833afSPeter Tyser #define INT_SLLV dsllv 281*819833afSPeter Tyser #define INT_SRL dsrl 282*819833afSPeter Tyser #define INT_SRLV dsrlv 283*819833afSPeter Tyser #define INT_SRA dsra 284*819833afSPeter Tyser #define INT_SRAV dsrav 285*819833afSPeter Tyser #endif 286*819833afSPeter Tyser 287*819833afSPeter Tyser /* 288*819833afSPeter Tyser * How to add/sub/load/store/shift C long variables. 289*819833afSPeter Tyser */ 290*819833afSPeter Tyser #if (_MIPS_SZLONG == 32) 291*819833afSPeter Tyser #define LONG_ADD add 292*819833afSPeter Tyser #define LONG_ADDU addu 293*819833afSPeter Tyser #define LONG_ADDI addi 294*819833afSPeter Tyser #define LONG_ADDIU addiu 295*819833afSPeter Tyser #define LONG_SUB sub 296*819833afSPeter Tyser #define LONG_SUBU subu 297*819833afSPeter Tyser #define LONG_L lw 298*819833afSPeter Tyser #define LONG_S sw 299*819833afSPeter Tyser #define LONG_SLL sll 300*819833afSPeter Tyser #define LONG_SLLV sllv 301*819833afSPeter Tyser #define LONG_SRL srl 302*819833afSPeter Tyser #define LONG_SRLV srlv 303*819833afSPeter Tyser #define LONG_SRA sra 304*819833afSPeter Tyser #define LONG_SRAV srav 305*819833afSPeter Tyser 306*819833afSPeter Tyser #define LONG .word 307*819833afSPeter Tyser #define LONGSIZE 4 308*819833afSPeter Tyser #define LONGMASK 3 309*819833afSPeter Tyser #define LONGLOG 2 310*819833afSPeter Tyser #endif 311*819833afSPeter Tyser 312*819833afSPeter Tyser #if (_MIPS_SZLONG == 64) 313*819833afSPeter Tyser #define LONG_ADD dadd 314*819833afSPeter Tyser #define LONG_ADDU daddu 315*819833afSPeter Tyser #define LONG_ADDI daddi 316*819833afSPeter Tyser #define LONG_ADDIU daddiu 317*819833afSPeter Tyser #define LONG_SUB dsub 318*819833afSPeter Tyser #define LONG_SUBU dsubu 319*819833afSPeter Tyser #define LONG_L ld 320*819833afSPeter Tyser #define LONG_S sd 321*819833afSPeter Tyser #define LONG_SLL dsll 322*819833afSPeter Tyser #define LONG_SLLV dsllv 323*819833afSPeter Tyser #define LONG_SRL dsrl 324*819833afSPeter Tyser #define LONG_SRLV dsrlv 325*819833afSPeter Tyser #define LONG_SRA dsra 326*819833afSPeter Tyser #define LONG_SRAV dsrav 327*819833afSPeter Tyser 328*819833afSPeter Tyser #define LONG .dword 329*819833afSPeter Tyser #define LONGSIZE 8 330*819833afSPeter Tyser #define LONGMASK 7 331*819833afSPeter Tyser #define LONGLOG 3 332*819833afSPeter Tyser #endif 333*819833afSPeter Tyser 334*819833afSPeter Tyser /* 335*819833afSPeter Tyser * How to add/sub/load/store/shift pointers. 336*819833afSPeter Tyser */ 337*819833afSPeter Tyser #if (_MIPS_SZPTR == 32) 338*819833afSPeter Tyser #define PTR_ADD add 339*819833afSPeter Tyser #define PTR_ADDU addu 340*819833afSPeter Tyser #define PTR_ADDI addi 341*819833afSPeter Tyser #define PTR_ADDIU addiu 342*819833afSPeter Tyser #define PTR_SUB sub 343*819833afSPeter Tyser #define PTR_SUBU subu 344*819833afSPeter Tyser #define PTR_L lw 345*819833afSPeter Tyser #define PTR_S sw 346*819833afSPeter Tyser #define PTR_LA la 347*819833afSPeter Tyser #define PTR_LI li 348*819833afSPeter Tyser #define PTR_SLL sll 349*819833afSPeter Tyser #define PTR_SLLV sllv 350*819833afSPeter Tyser #define PTR_SRL srl 351*819833afSPeter Tyser #define PTR_SRLV srlv 352*819833afSPeter Tyser #define PTR_SRA sra 353*819833afSPeter Tyser #define PTR_SRAV srav 354*819833afSPeter Tyser 355*819833afSPeter Tyser #define PTR_SCALESHIFT 2 356*819833afSPeter Tyser 357*819833afSPeter Tyser #define PTR .word 358*819833afSPeter Tyser #define PTRSIZE 4 359*819833afSPeter Tyser #define PTRLOG 2 360*819833afSPeter Tyser #endif 361*819833afSPeter Tyser 362*819833afSPeter Tyser #if (_MIPS_SZPTR == 64) 363*819833afSPeter Tyser #define PTR_ADD dadd 364*819833afSPeter Tyser #define PTR_ADDU daddu 365*819833afSPeter Tyser #define PTR_ADDI daddi 366*819833afSPeter Tyser #define PTR_ADDIU daddiu 367*819833afSPeter Tyser #define PTR_SUB dsub 368*819833afSPeter Tyser #define PTR_SUBU dsubu 369*819833afSPeter Tyser #define PTR_L ld 370*819833afSPeter Tyser #define PTR_S sd 371*819833afSPeter Tyser #define PTR_LA dla 372*819833afSPeter Tyser #define PTR_LI dli 373*819833afSPeter Tyser #define PTR_SLL dsll 374*819833afSPeter Tyser #define PTR_SLLV dsllv 375*819833afSPeter Tyser #define PTR_SRL dsrl 376*819833afSPeter Tyser #define PTR_SRLV dsrlv 377*819833afSPeter Tyser #define PTR_SRA dsra 378*819833afSPeter Tyser #define PTR_SRAV dsrav 379*819833afSPeter Tyser 380*819833afSPeter Tyser #define PTR_SCALESHIFT 3 381*819833afSPeter Tyser 382*819833afSPeter Tyser #define PTR .dword 383*819833afSPeter Tyser #define PTRSIZE 8 384*819833afSPeter Tyser #define PTRLOG 3 385*819833afSPeter Tyser #endif 386*819833afSPeter Tyser 387*819833afSPeter Tyser /* 388*819833afSPeter Tyser * Some cp0 registers were extended to 64bit for MIPS III. 389*819833afSPeter Tyser */ 390*819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 391*819833afSPeter Tyser #define MFC0 mfc0 392*819833afSPeter Tyser #define MTC0 mtc0 393*819833afSPeter Tyser #endif 394*819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 395*819833afSPeter Tyser #define MFC0 dmfc0 396*819833afSPeter Tyser #define MTC0 dmtc0 397*819833afSPeter Tyser #endif 398*819833afSPeter Tyser 399*819833afSPeter Tyser #define SSNOP sll zero, zero, 1 400*819833afSPeter Tyser 401*819833afSPeter Tyser #ifdef CONFIG_SGI_IP28 402*819833afSPeter Tyser /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 403*819833afSPeter Tyser #include <asm/cacheops.h> 404*819833afSPeter Tyser #define R10KCBARRIER(addr) cache Cache_Barrier, addr; 405*819833afSPeter Tyser #else 406*819833afSPeter Tyser #define R10KCBARRIER(addr) 407*819833afSPeter Tyser #endif 408*819833afSPeter Tyser 409*819833afSPeter Tyser #endif /* __ASM_ASM_H */ 410