1819833afSPeter Tyser /* 2819833afSPeter Tyser * This file is subject to the terms and conditions of the GNU General Public 3819833afSPeter Tyser * License. See the file "COPYING" in the main directory of this archive 4819833afSPeter Tyser * for more details. 5819833afSPeter Tyser * 6819833afSPeter Tyser * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle 7819833afSPeter Tyser * Copyright (C) 1999 by Silicon Graphics, Inc. 8819833afSPeter Tyser * Copyright (C) 2001 MIPS Technologies, Inc. 9819833afSPeter Tyser * Copyright (C) 2002 Maciej W. Rozycki 10819833afSPeter Tyser * 11819833afSPeter Tyser * Some useful macros for MIPS assembler code 12819833afSPeter Tyser * 13819833afSPeter Tyser * Some of the routines below contain useless nops that will be optimized 14819833afSPeter Tyser * away by gas in -O mode. These nops are however required to fill delay 15819833afSPeter Tyser * slots in noreorder mode. 16819833afSPeter Tyser */ 17819833afSPeter Tyser #ifndef __ASM_ASM_H 18819833afSPeter Tyser #define __ASM_ASM_H 19819833afSPeter Tyser 20819833afSPeter Tyser #include <asm/sgidefs.h> 21819833afSPeter Tyser 22819833afSPeter Tyser #ifndef CAT 23819833afSPeter Tyser #ifdef __STDC__ 24819833afSPeter Tyser #define __CAT(str1, str2) str1##str2 25819833afSPeter Tyser #else 26819833afSPeter Tyser #define __CAT(str1, str2) str1/**/str2 27819833afSPeter Tyser #endif 28819833afSPeter Tyser #define CAT(str1, str2) __CAT(str1, str2) 29819833afSPeter Tyser #endif 30819833afSPeter Tyser 31819833afSPeter Tyser /* 32819833afSPeter Tyser * PIC specific declarations 33819833afSPeter Tyser * Not used for the kernel but here seems to be the right place. 34819833afSPeter Tyser */ 35819833afSPeter Tyser #ifdef __PIC__ 36819833afSPeter Tyser #define CPRESTORE(register) \ 37819833afSPeter Tyser .cprestore register 38819833afSPeter Tyser #define CPADD(register) \ 39819833afSPeter Tyser .cpadd register 40819833afSPeter Tyser #define CPLOAD(register) \ 41819833afSPeter Tyser .cpload register 42819833afSPeter Tyser #else 43819833afSPeter Tyser #define CPRESTORE(register) 44819833afSPeter Tyser #define CPADD(register) 45819833afSPeter Tyser #define CPLOAD(register) 46819833afSPeter Tyser #endif 47819833afSPeter Tyser 48819833afSPeter Tyser /* 49819833afSPeter Tyser * LEAF - declare leaf routine 50819833afSPeter Tyser */ 51819833afSPeter Tyser #define LEAF(symbol) \ 52819833afSPeter Tyser .globl symbol; \ 53819833afSPeter Tyser .align 2; \ 54819833afSPeter Tyser .type symbol, @function; \ 55819833afSPeter Tyser .ent symbol, 0; \ 56819833afSPeter Tyser symbol: .frame sp, 0, ra 57819833afSPeter Tyser 58819833afSPeter Tyser /* 59819833afSPeter Tyser * NESTED - declare nested routine entry point 60819833afSPeter Tyser */ 61819833afSPeter Tyser #define NESTED(symbol, framesize, rpc) \ 62819833afSPeter Tyser .globl symbol; \ 63819833afSPeter Tyser .align 2; \ 64819833afSPeter Tyser .type symbol, @function; \ 65819833afSPeter Tyser .ent symbol, 0; \ 66819833afSPeter Tyser symbol: .frame sp, framesize, rpc 67819833afSPeter Tyser 68819833afSPeter Tyser /* 69819833afSPeter Tyser * END - mark end of function 70819833afSPeter Tyser */ 71819833afSPeter Tyser #define END(function) \ 72819833afSPeter Tyser .end function; \ 73819833afSPeter Tyser .size function, .-function 74819833afSPeter Tyser 75819833afSPeter Tyser /* 76819833afSPeter Tyser * EXPORT - export definition of symbol 77819833afSPeter Tyser */ 78819833afSPeter Tyser #define EXPORT(symbol) \ 79819833afSPeter Tyser .globl symbol; \ 80819833afSPeter Tyser symbol: 81819833afSPeter Tyser 82819833afSPeter Tyser /* 83819833afSPeter Tyser * FEXPORT - export definition of a function symbol 84819833afSPeter Tyser */ 85819833afSPeter Tyser #define FEXPORT(symbol) \ 86819833afSPeter Tyser .globl symbol; \ 87819833afSPeter Tyser .type symbol, @function; \ 88819833afSPeter Tyser symbol: 89819833afSPeter Tyser 90819833afSPeter Tyser /* 91819833afSPeter Tyser * ABS - export absolute symbol 92819833afSPeter Tyser */ 93819833afSPeter Tyser #define ABS(symbol,value) \ 94819833afSPeter Tyser .globl symbol; \ 95819833afSPeter Tyser symbol = value 96819833afSPeter Tyser 97819833afSPeter Tyser #define PANIC(msg) \ 98819833afSPeter Tyser .set push; \ 99819833afSPeter Tyser .set reorder; \ 100819833afSPeter Tyser PTR_LA a0, 8f; \ 101819833afSPeter Tyser jal panic; \ 102819833afSPeter Tyser 9: b 9b; \ 103819833afSPeter Tyser .set pop; \ 104819833afSPeter Tyser TEXT(msg) 105819833afSPeter Tyser 106819833afSPeter Tyser /* 107819833afSPeter Tyser * Print formatted string 108819833afSPeter Tyser */ 109819833afSPeter Tyser #ifdef CONFIG_PRINTK 110819833afSPeter Tyser #define PRINT(string) \ 111819833afSPeter Tyser .set push; \ 112819833afSPeter Tyser .set reorder; \ 113819833afSPeter Tyser PTR_LA a0, 8f; \ 114819833afSPeter Tyser jal printk; \ 115819833afSPeter Tyser .set pop; \ 116819833afSPeter Tyser TEXT(string) 117819833afSPeter Tyser #else 118819833afSPeter Tyser #define PRINT(string) 119819833afSPeter Tyser #endif 120819833afSPeter Tyser 121819833afSPeter Tyser #define TEXT(msg) \ 122819833afSPeter Tyser .pushsection .data; \ 123819833afSPeter Tyser 8: .asciiz msg; \ 124819833afSPeter Tyser .popsection; 125819833afSPeter Tyser 126819833afSPeter Tyser /* 127819833afSPeter Tyser * Build text tables 128819833afSPeter Tyser */ 129819833afSPeter Tyser #define TTABLE(string) \ 130819833afSPeter Tyser .pushsection .text; \ 131819833afSPeter Tyser .word 1f; \ 132819833afSPeter Tyser .popsection \ 133819833afSPeter Tyser .pushsection .data; \ 134819833afSPeter Tyser 1: .asciiz string; \ 135819833afSPeter Tyser .popsection 136819833afSPeter Tyser 137819833afSPeter Tyser /* 138819833afSPeter Tyser * MIPS IV pref instruction. 139819833afSPeter Tyser * Use with .set noreorder only! 140819833afSPeter Tyser * 141819833afSPeter Tyser * MIPS IV implementations are free to treat this as a nop. The R5000 142819833afSPeter Tyser * is one of them. So we should have an option not to use this instruction. 143819833afSPeter Tyser */ 144819833afSPeter Tyser #ifdef CONFIG_CPU_HAS_PREFETCH 145819833afSPeter Tyser 146819833afSPeter Tyser #define PREF(hint,addr) \ 147819833afSPeter Tyser .set push; \ 148819833afSPeter Tyser .set mips4; \ 149819833afSPeter Tyser pref hint, addr; \ 150819833afSPeter Tyser .set pop 151819833afSPeter Tyser 152819833afSPeter Tyser #define PREFX(hint,addr) \ 153819833afSPeter Tyser .set push; \ 154819833afSPeter Tyser .set mips4; \ 155819833afSPeter Tyser prefx hint, addr; \ 156819833afSPeter Tyser .set pop 157819833afSPeter Tyser 158819833afSPeter Tyser #else /* !CONFIG_CPU_HAS_PREFETCH */ 159819833afSPeter Tyser 160819833afSPeter Tyser #define PREF(hint, addr) 161819833afSPeter Tyser #define PREFX(hint, addr) 162819833afSPeter Tyser 163819833afSPeter Tyser #endif /* !CONFIG_CPU_HAS_PREFETCH */ 164819833afSPeter Tyser 165819833afSPeter Tyser /* 166819833afSPeter Tyser * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. 167819833afSPeter Tyser */ 168819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS1) 169819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 170819833afSPeter Tyser .set push; \ 171819833afSPeter Tyser .set reorder; \ 172819833afSPeter Tyser beqz rt, 9f; \ 173819833afSPeter Tyser move rd, rs; \ 174819833afSPeter Tyser .set pop; \ 175819833afSPeter Tyser 9: 176819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 177819833afSPeter Tyser .set push; \ 178819833afSPeter Tyser .set reorder; \ 179819833afSPeter Tyser bnez rt, 9f; \ 180819833afSPeter Tyser move rd, rs; \ 181819833afSPeter Tyser .set pop; \ 182819833afSPeter Tyser 9: 183819833afSPeter Tyser #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ 184819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) 185819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 186819833afSPeter Tyser .set push; \ 187819833afSPeter Tyser .set noreorder; \ 188819833afSPeter Tyser bnezl rt, 9f; \ 189819833afSPeter Tyser move rd, rs; \ 190819833afSPeter Tyser .set pop; \ 191819833afSPeter Tyser 9: 192819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 193819833afSPeter Tyser .set push; \ 194819833afSPeter Tyser .set noreorder; \ 195819833afSPeter Tyser beqzl rt, 9f; \ 196819833afSPeter Tyser move rd, rs; \ 197819833afSPeter Tyser .set pop; \ 198819833afSPeter Tyser 9: 199819833afSPeter Tyser #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ 200819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ 201819833afSPeter Tyser (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 202819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 203819833afSPeter Tyser movn rd, rs, rt 204819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 205819833afSPeter Tyser movz rd, rs, rt 206819833afSPeter Tyser #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ 207819833afSPeter Tyser 208819833afSPeter Tyser /* 209819833afSPeter Tyser * Stack alignment 210819833afSPeter Tyser */ 211819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 212819833afSPeter Tyser #define ALSZ 7 213819833afSPeter Tyser #define ALMASK ~7 214819833afSPeter Tyser #endif 215819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 216819833afSPeter Tyser #define ALSZ 15 217819833afSPeter Tyser #define ALMASK ~15 218819833afSPeter Tyser #endif 219819833afSPeter Tyser 220819833afSPeter Tyser /* 221819833afSPeter Tyser * Macros to handle different pointer/register sizes for 32/64-bit code 222819833afSPeter Tyser */ 223819833afSPeter Tyser 224819833afSPeter Tyser /* 225819833afSPeter Tyser * Size of a register 226819833afSPeter Tyser */ 227819833afSPeter Tyser #ifdef __mips64 228819833afSPeter Tyser #define SZREG 8 229819833afSPeter Tyser #else 230819833afSPeter Tyser #define SZREG 4 231819833afSPeter Tyser #endif 232819833afSPeter Tyser 233819833afSPeter Tyser /* 234819833afSPeter Tyser * Use the following macros in assemblercode to load/store registers, 235819833afSPeter Tyser * pointers etc. 236819833afSPeter Tyser */ 237819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 238819833afSPeter Tyser #define REG_S sw 239819833afSPeter Tyser #define REG_L lw 240819833afSPeter Tyser #define REG_SUBU subu 241819833afSPeter Tyser #define REG_ADDU addu 242819833afSPeter Tyser #endif 243819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 244819833afSPeter Tyser #define REG_S sd 245819833afSPeter Tyser #define REG_L ld 246819833afSPeter Tyser #define REG_SUBU dsubu 247819833afSPeter Tyser #define REG_ADDU daddu 248819833afSPeter Tyser #endif 249819833afSPeter Tyser 250819833afSPeter Tyser /* 251819833afSPeter Tyser * How to add/sub/load/store/shift C int variables. 252819833afSPeter Tyser */ 253819833afSPeter Tyser #if (_MIPS_SZINT == 32) 254819833afSPeter Tyser #define INT_ADD add 255819833afSPeter Tyser #define INT_ADDU addu 256819833afSPeter Tyser #define INT_ADDI addi 257819833afSPeter Tyser #define INT_ADDIU addiu 258819833afSPeter Tyser #define INT_SUB sub 259819833afSPeter Tyser #define INT_SUBU subu 260819833afSPeter Tyser #define INT_L lw 261819833afSPeter Tyser #define INT_S sw 262819833afSPeter Tyser #define INT_SLL sll 263819833afSPeter Tyser #define INT_SLLV sllv 264819833afSPeter Tyser #define INT_SRL srl 265819833afSPeter Tyser #define INT_SRLV srlv 266819833afSPeter Tyser #define INT_SRA sra 267819833afSPeter Tyser #define INT_SRAV srav 268819833afSPeter Tyser #endif 269819833afSPeter Tyser 270819833afSPeter Tyser #if (_MIPS_SZINT == 64) 271819833afSPeter Tyser #define INT_ADD dadd 272819833afSPeter Tyser #define INT_ADDU daddu 273819833afSPeter Tyser #define INT_ADDI daddi 274819833afSPeter Tyser #define INT_ADDIU daddiu 275819833afSPeter Tyser #define INT_SUB dsub 276819833afSPeter Tyser #define INT_SUBU dsubu 277819833afSPeter Tyser #define INT_L ld 278819833afSPeter Tyser #define INT_S sd 279819833afSPeter Tyser #define INT_SLL dsll 280819833afSPeter Tyser #define INT_SLLV dsllv 281819833afSPeter Tyser #define INT_SRL dsrl 282819833afSPeter Tyser #define INT_SRLV dsrlv 283819833afSPeter Tyser #define INT_SRA dsra 284819833afSPeter Tyser #define INT_SRAV dsrav 285819833afSPeter Tyser #endif 286819833afSPeter Tyser 287819833afSPeter Tyser /* 288819833afSPeter Tyser * How to add/sub/load/store/shift C long variables. 289819833afSPeter Tyser */ 290819833afSPeter Tyser #if (_MIPS_SZLONG == 32) 291819833afSPeter Tyser #define LONG_ADD add 292819833afSPeter Tyser #define LONG_ADDU addu 293819833afSPeter Tyser #define LONG_ADDI addi 294819833afSPeter Tyser #define LONG_ADDIU addiu 295819833afSPeter Tyser #define LONG_SUB sub 296819833afSPeter Tyser #define LONG_SUBU subu 297819833afSPeter Tyser #define LONG_L lw 298819833afSPeter Tyser #define LONG_S sw 299819833afSPeter Tyser #define LONG_SLL sll 300819833afSPeter Tyser #define LONG_SLLV sllv 301819833afSPeter Tyser #define LONG_SRL srl 302819833afSPeter Tyser #define LONG_SRLV srlv 303819833afSPeter Tyser #define LONG_SRA sra 304819833afSPeter Tyser #define LONG_SRAV srav 305819833afSPeter Tyser 306819833afSPeter Tyser #define LONG .word 307819833afSPeter Tyser #define LONGSIZE 4 308819833afSPeter Tyser #define LONGMASK 3 309819833afSPeter Tyser #define LONGLOG 2 310819833afSPeter Tyser #endif 311819833afSPeter Tyser 312819833afSPeter Tyser #if (_MIPS_SZLONG == 64) 313819833afSPeter Tyser #define LONG_ADD dadd 314819833afSPeter Tyser #define LONG_ADDU daddu 315819833afSPeter Tyser #define LONG_ADDI daddi 316819833afSPeter Tyser #define LONG_ADDIU daddiu 317819833afSPeter Tyser #define LONG_SUB dsub 318819833afSPeter Tyser #define LONG_SUBU dsubu 319819833afSPeter Tyser #define LONG_L ld 320819833afSPeter Tyser #define LONG_S sd 321819833afSPeter Tyser #define LONG_SLL dsll 322819833afSPeter Tyser #define LONG_SLLV dsllv 323819833afSPeter Tyser #define LONG_SRL dsrl 324819833afSPeter Tyser #define LONG_SRLV dsrlv 325819833afSPeter Tyser #define LONG_SRA dsra 326819833afSPeter Tyser #define LONG_SRAV dsrav 327819833afSPeter Tyser 328819833afSPeter Tyser #define LONG .dword 329819833afSPeter Tyser #define LONGSIZE 8 330819833afSPeter Tyser #define LONGMASK 7 331819833afSPeter Tyser #define LONGLOG 3 332819833afSPeter Tyser #endif 333819833afSPeter Tyser 334819833afSPeter Tyser /* 335819833afSPeter Tyser * How to add/sub/load/store/shift pointers. 336819833afSPeter Tyser */ 337819833afSPeter Tyser #if (_MIPS_SZPTR == 32) 338819833afSPeter Tyser #define PTR_ADD add 339819833afSPeter Tyser #define PTR_ADDU addu 340819833afSPeter Tyser #define PTR_ADDI addi 341819833afSPeter Tyser #define PTR_ADDIU addiu 342819833afSPeter Tyser #define PTR_SUB sub 343819833afSPeter Tyser #define PTR_SUBU subu 344819833afSPeter Tyser #define PTR_L lw 345819833afSPeter Tyser #define PTR_S sw 346819833afSPeter Tyser #define PTR_LA la 347819833afSPeter Tyser #define PTR_LI li 348819833afSPeter Tyser #define PTR_SLL sll 349819833afSPeter Tyser #define PTR_SLLV sllv 350819833afSPeter Tyser #define PTR_SRL srl 351819833afSPeter Tyser #define PTR_SRLV srlv 352819833afSPeter Tyser #define PTR_SRA sra 353819833afSPeter Tyser #define PTR_SRAV srav 354819833afSPeter Tyser 355819833afSPeter Tyser #define PTR_SCALESHIFT 2 356819833afSPeter Tyser 357819833afSPeter Tyser #define PTR .word 358819833afSPeter Tyser #define PTRSIZE 4 359819833afSPeter Tyser #define PTRLOG 2 360819833afSPeter Tyser #endif 361819833afSPeter Tyser 362819833afSPeter Tyser #if (_MIPS_SZPTR == 64) 363819833afSPeter Tyser #define PTR_ADD dadd 364819833afSPeter Tyser #define PTR_ADDU daddu 365819833afSPeter Tyser #define PTR_ADDI daddi 366819833afSPeter Tyser #define PTR_ADDIU daddiu 367819833afSPeter Tyser #define PTR_SUB dsub 368819833afSPeter Tyser #define PTR_SUBU dsubu 369819833afSPeter Tyser #define PTR_L ld 370819833afSPeter Tyser #define PTR_S sd 371819833afSPeter Tyser #define PTR_LA dla 372819833afSPeter Tyser #define PTR_LI dli 373819833afSPeter Tyser #define PTR_SLL dsll 374819833afSPeter Tyser #define PTR_SLLV dsllv 375819833afSPeter Tyser #define PTR_SRL dsrl 376819833afSPeter Tyser #define PTR_SRLV dsrlv 377819833afSPeter Tyser #define PTR_SRA dsra 378819833afSPeter Tyser #define PTR_SRAV dsrav 379819833afSPeter Tyser 380819833afSPeter Tyser #define PTR_SCALESHIFT 3 381819833afSPeter Tyser 382819833afSPeter Tyser #define PTR .dword 383819833afSPeter Tyser #define PTRSIZE 8 384819833afSPeter Tyser #define PTRLOG 3 385819833afSPeter Tyser #endif 386819833afSPeter Tyser 387819833afSPeter Tyser /* 388819833afSPeter Tyser * Some cp0 registers were extended to 64bit for MIPS III. 389819833afSPeter Tyser */ 390819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 391819833afSPeter Tyser #define MFC0 mfc0 392819833afSPeter Tyser #define MTC0 mtc0 393819833afSPeter Tyser #endif 394819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 395819833afSPeter Tyser #define MFC0 dmfc0 396819833afSPeter Tyser #define MTC0 dmtc0 397819833afSPeter Tyser #endif 398819833afSPeter Tyser 399819833afSPeter Tyser #define SSNOP sll zero, zero, 1 400819833afSPeter Tyser 401819833afSPeter Tyser #ifdef CONFIG_SGI_IP28 402819833afSPeter Tyser /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 403819833afSPeter Tyser #include <asm/cacheops.h> 404*cb0a6a1eSZhi-zhou Zhang #define R10KCBARRIER(addr) cache CACHE_BARRIER, addr; 405819833afSPeter Tyser #else 406819833afSPeter Tyser #define R10KCBARRIER(addr) 407819833afSPeter Tyser #endif 408819833afSPeter Tyser 409819833afSPeter Tyser #endif /* __ASM_ASM_H */ 410