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