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