1819833afSPeter Tyser /* 2819833afSPeter Tyser * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle 3819833afSPeter Tyser * Copyright (C) 1999 by Silicon Graphics, Inc. 4819833afSPeter Tyser * Copyright (C) 2001 MIPS Technologies, Inc. 5819833afSPeter Tyser * Copyright (C) 2002 Maciej W. Rozycki 6819833afSPeter Tyser * 7819833afSPeter Tyser * Some useful macros for MIPS assembler code 8819833afSPeter Tyser * 9819833afSPeter Tyser * Some of the routines below contain useless nops that will be optimized 10819833afSPeter Tyser * away by gas in -O mode. These nops are however required to fill delay 11819833afSPeter Tyser * slots in noreorder mode. 12*a3ab2ae7SDaniel Schwierzeck * 13*a3ab2ae7SDaniel Schwierzeck * SPDX-License-Identifier: GPL-2.0 14819833afSPeter Tyser */ 15819833afSPeter Tyser #ifndef __ASM_ASM_H 16819833afSPeter Tyser #define __ASM_ASM_H 17819833afSPeter Tyser 18819833afSPeter Tyser #include <asm/sgidefs.h> 19819833afSPeter Tyser 20819833afSPeter Tyser #ifndef CAT 21819833afSPeter Tyser #ifdef __STDC__ 22819833afSPeter Tyser #define __CAT(str1, str2) str1##str2 23819833afSPeter Tyser #else 24819833afSPeter Tyser #define __CAT(str1, str2) str1/**/str2 25819833afSPeter Tyser #endif 26819833afSPeter Tyser #define CAT(str1, str2) __CAT(str1, str2) 27819833afSPeter Tyser #endif 28819833afSPeter Tyser 29819833afSPeter Tyser /* 30819833afSPeter Tyser * PIC specific declarations 31819833afSPeter Tyser * Not used for the kernel but here seems to be the right place. 32819833afSPeter Tyser */ 33819833afSPeter Tyser #ifdef __PIC__ 34819833afSPeter Tyser #define CPRESTORE(register) \ 35819833afSPeter Tyser .cprestore register 36819833afSPeter Tyser #define CPADD(register) \ 37819833afSPeter Tyser .cpadd register 38819833afSPeter Tyser #define CPLOAD(register) \ 39819833afSPeter Tyser .cpload register 40819833afSPeter Tyser #else 41819833afSPeter Tyser #define CPRESTORE(register) 42819833afSPeter Tyser #define CPADD(register) 43819833afSPeter Tyser #define CPLOAD(register) 44819833afSPeter Tyser #endif 45819833afSPeter Tyser 4611349298SDaniel Schwierzeck #define ENTRY(symbol) \ 4711349298SDaniel Schwierzeck .globl symbol; \ 4811349298SDaniel Schwierzeck .type symbol, @function; \ 4911349298SDaniel Schwierzeck .ent symbol, 0; \ 5011349298SDaniel Schwierzeck symbol: 5111349298SDaniel Schwierzeck 52819833afSPeter Tyser /* 53819833afSPeter Tyser * LEAF - declare leaf routine 54819833afSPeter Tyser */ 55819833afSPeter Tyser #define LEAF(symbol) \ 56819833afSPeter Tyser .globl symbol; \ 57819833afSPeter Tyser .align 2; \ 58819833afSPeter Tyser .type symbol, @function; \ 59819833afSPeter Tyser .ent symbol, 0; \ 605b6f357fSDaniel Schwierzeck .section .text.symbol, "x"; \ 61819833afSPeter Tyser symbol: .frame sp, 0, ra 62819833afSPeter Tyser 63819833afSPeter Tyser /* 64819833afSPeter Tyser * NESTED - declare nested routine entry point 65819833afSPeter Tyser */ 66819833afSPeter Tyser #define NESTED(symbol, framesize, rpc) \ 67819833afSPeter Tyser .globl symbol; \ 68819833afSPeter Tyser .align 2; \ 69819833afSPeter Tyser .type symbol, @function; \ 70819833afSPeter Tyser .ent symbol, 0; \ 715b6f357fSDaniel Schwierzeck .section .text.symbol, "x"; \ 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; \ 154*a3ab2ae7SDaniel Schwierzeck .set arch=r5000; \ 155819833afSPeter Tyser pref hint, addr; \ 156819833afSPeter Tyser .set pop 157819833afSPeter Tyser 158*a3ab2ae7SDaniel Schwierzeck #define PREFE(hint, addr) \ 159*a3ab2ae7SDaniel Schwierzeck .set push; \ 160*a3ab2ae7SDaniel Schwierzeck .set mips0; \ 161*a3ab2ae7SDaniel Schwierzeck .set eva; \ 162*a3ab2ae7SDaniel Schwierzeck prefe hint, addr; \ 163*a3ab2ae7SDaniel Schwierzeck .set pop 164*a3ab2ae7SDaniel Schwierzeck 165819833afSPeter Tyser #define PREFX(hint, addr) \ 166819833afSPeter Tyser .set push; \ 167*a3ab2ae7SDaniel Schwierzeck .set arch=r5000; \ 168819833afSPeter Tyser prefx hint, addr; \ 169819833afSPeter Tyser .set pop 170819833afSPeter Tyser 171819833afSPeter Tyser #else /* !CONFIG_CPU_HAS_PREFETCH */ 172819833afSPeter Tyser 173819833afSPeter Tyser #define PREF(hint, addr) 174*a3ab2ae7SDaniel Schwierzeck #define PREFE(hint, addr) 175819833afSPeter Tyser #define PREFX(hint, addr) 176819833afSPeter Tyser 177819833afSPeter Tyser #endif /* !CONFIG_CPU_HAS_PREFETCH */ 178819833afSPeter Tyser 179819833afSPeter Tyser /* 180819833afSPeter Tyser * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. 181819833afSPeter Tyser */ 182819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS1) 183819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 184819833afSPeter Tyser .set push; \ 185819833afSPeter Tyser .set reorder; \ 186819833afSPeter Tyser beqz rt, 9f; \ 187819833afSPeter Tyser move rd, rs; \ 188819833afSPeter Tyser .set pop; \ 189819833afSPeter Tyser 9: 190819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 191819833afSPeter Tyser .set push; \ 192819833afSPeter Tyser .set reorder; \ 193819833afSPeter Tyser bnez rt, 9f; \ 194819833afSPeter Tyser move rd, rs; \ 195819833afSPeter Tyser .set pop; \ 196819833afSPeter Tyser 9: 197819833afSPeter Tyser #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ 198819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) 199819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 200819833afSPeter Tyser .set push; \ 201819833afSPeter Tyser .set noreorder; \ 202819833afSPeter Tyser bnezl rt, 9f; \ 203819833afSPeter Tyser move rd, rs; \ 204819833afSPeter Tyser .set pop; \ 205819833afSPeter Tyser 9: 206819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 207819833afSPeter Tyser .set push; \ 208819833afSPeter Tyser .set noreorder; \ 209819833afSPeter Tyser beqzl rt, 9f; \ 210819833afSPeter Tyser move rd, rs; \ 211819833afSPeter Tyser .set pop; \ 212819833afSPeter Tyser 9: 213819833afSPeter Tyser #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ 214819833afSPeter Tyser #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ 215819833afSPeter Tyser (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 216819833afSPeter Tyser #define MOVN(rd, rs, rt) \ 217819833afSPeter Tyser movn rd, rs, rt 218819833afSPeter Tyser #define MOVZ(rd, rs, rt) \ 219819833afSPeter Tyser movz rd, rs, rt 220819833afSPeter Tyser #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ 221819833afSPeter Tyser 222819833afSPeter Tyser /* 223819833afSPeter Tyser * Stack alignment 224819833afSPeter Tyser */ 225819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 226819833afSPeter Tyser #define ALSZ 7 227819833afSPeter Tyser #define ALMASK ~7 228819833afSPeter Tyser #endif 229819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 230819833afSPeter Tyser #define ALSZ 15 231819833afSPeter Tyser #define ALMASK ~15 232819833afSPeter Tyser #endif 233819833afSPeter Tyser 234819833afSPeter Tyser /* 235819833afSPeter Tyser * Macros to handle different pointer/register sizes for 32/64-bit code 236819833afSPeter Tyser */ 237819833afSPeter Tyser 238819833afSPeter Tyser /* 239819833afSPeter Tyser * Size of a register 240819833afSPeter Tyser */ 241819833afSPeter Tyser #ifdef __mips64 242819833afSPeter Tyser #define SZREG 8 243819833afSPeter Tyser #else 244819833afSPeter Tyser #define SZREG 4 245819833afSPeter Tyser #endif 246819833afSPeter Tyser 247819833afSPeter Tyser /* 248819833afSPeter Tyser * Use the following macros in assemblercode to load/store registers, 249819833afSPeter Tyser * pointers etc. 250819833afSPeter Tyser */ 251819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 252819833afSPeter Tyser #define REG_S sw 253819833afSPeter Tyser #define REG_L lw 254819833afSPeter Tyser #define REG_SUBU subu 255819833afSPeter Tyser #define REG_ADDU addu 256819833afSPeter Tyser #endif 257819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 258819833afSPeter Tyser #define REG_S sd 259819833afSPeter Tyser #define REG_L ld 260819833afSPeter Tyser #define REG_SUBU dsubu 261819833afSPeter Tyser #define REG_ADDU daddu 262819833afSPeter Tyser #endif 263819833afSPeter Tyser 264819833afSPeter Tyser /* 265819833afSPeter Tyser * How to add/sub/load/store/shift C int variables. 266819833afSPeter Tyser */ 267819833afSPeter Tyser #if (_MIPS_SZINT == 32) 268819833afSPeter Tyser #define INT_ADD add 269819833afSPeter Tyser #define INT_ADDU addu 270819833afSPeter Tyser #define INT_ADDI addi 271819833afSPeter Tyser #define INT_ADDIU addiu 272819833afSPeter Tyser #define INT_SUB sub 273819833afSPeter Tyser #define INT_SUBU subu 274819833afSPeter Tyser #define INT_L lw 275819833afSPeter Tyser #define INT_S sw 276819833afSPeter Tyser #define INT_SLL sll 277819833afSPeter Tyser #define INT_SLLV sllv 278819833afSPeter Tyser #define INT_SRL srl 279819833afSPeter Tyser #define INT_SRLV srlv 280819833afSPeter Tyser #define INT_SRA sra 281819833afSPeter Tyser #define INT_SRAV srav 282819833afSPeter Tyser #endif 283819833afSPeter Tyser 284819833afSPeter Tyser #if (_MIPS_SZINT == 64) 285819833afSPeter Tyser #define INT_ADD dadd 286819833afSPeter Tyser #define INT_ADDU daddu 287819833afSPeter Tyser #define INT_ADDI daddi 288819833afSPeter Tyser #define INT_ADDIU daddiu 289819833afSPeter Tyser #define INT_SUB dsub 290819833afSPeter Tyser #define INT_SUBU dsubu 291819833afSPeter Tyser #define INT_L ld 292819833afSPeter Tyser #define INT_S sd 293819833afSPeter Tyser #define INT_SLL dsll 294819833afSPeter Tyser #define INT_SLLV dsllv 295819833afSPeter Tyser #define INT_SRL dsrl 296819833afSPeter Tyser #define INT_SRLV dsrlv 297819833afSPeter Tyser #define INT_SRA dsra 298819833afSPeter Tyser #define INT_SRAV dsrav 299819833afSPeter Tyser #endif 300819833afSPeter Tyser 301819833afSPeter Tyser /* 302819833afSPeter Tyser * How to add/sub/load/store/shift C long variables. 303819833afSPeter Tyser */ 304819833afSPeter Tyser #if (_MIPS_SZLONG == 32) 305819833afSPeter Tyser #define LONG_ADD add 306819833afSPeter Tyser #define LONG_ADDU addu 307819833afSPeter Tyser #define LONG_ADDI addi 308819833afSPeter Tyser #define LONG_ADDIU addiu 309819833afSPeter Tyser #define LONG_SUB sub 310819833afSPeter Tyser #define LONG_SUBU subu 311819833afSPeter Tyser #define LONG_L lw 312819833afSPeter Tyser #define LONG_S sw 313*a3ab2ae7SDaniel Schwierzeck #define LONG_SP swp 314819833afSPeter Tyser #define LONG_SLL sll 315819833afSPeter Tyser #define LONG_SLLV sllv 316819833afSPeter Tyser #define LONG_SRL srl 317819833afSPeter Tyser #define LONG_SRLV srlv 318819833afSPeter Tyser #define LONG_SRA sra 319819833afSPeter Tyser #define LONG_SRAV srav 320819833afSPeter Tyser 321819833afSPeter Tyser #define LONG .word 322819833afSPeter Tyser #define LONGSIZE 4 323819833afSPeter Tyser #define LONGMASK 3 324819833afSPeter Tyser #define LONGLOG 2 325819833afSPeter Tyser #endif 326819833afSPeter Tyser 327819833afSPeter Tyser #if (_MIPS_SZLONG == 64) 328819833afSPeter Tyser #define LONG_ADD dadd 329819833afSPeter Tyser #define LONG_ADDU daddu 330819833afSPeter Tyser #define LONG_ADDI daddi 331819833afSPeter Tyser #define LONG_ADDIU daddiu 332819833afSPeter Tyser #define LONG_SUB dsub 333819833afSPeter Tyser #define LONG_SUBU dsubu 334819833afSPeter Tyser #define LONG_L ld 335819833afSPeter Tyser #define LONG_S sd 336*a3ab2ae7SDaniel Schwierzeck #define LONG_SP sdp 337819833afSPeter Tyser #define LONG_SLL dsll 338819833afSPeter Tyser #define LONG_SLLV dsllv 339819833afSPeter Tyser #define LONG_SRL dsrl 340819833afSPeter Tyser #define LONG_SRLV dsrlv 341819833afSPeter Tyser #define LONG_SRA dsra 342819833afSPeter Tyser #define LONG_SRAV dsrav 343819833afSPeter Tyser 344819833afSPeter Tyser #define LONG .dword 345819833afSPeter Tyser #define LONGSIZE 8 346819833afSPeter Tyser #define LONGMASK 7 347819833afSPeter Tyser #define LONGLOG 3 348819833afSPeter Tyser #endif 349819833afSPeter Tyser 350819833afSPeter Tyser /* 351819833afSPeter Tyser * How to add/sub/load/store/shift pointers. 352819833afSPeter Tyser */ 353819833afSPeter Tyser #if (_MIPS_SZPTR == 32) 354819833afSPeter Tyser #define PTR_ADD add 355819833afSPeter Tyser #define PTR_ADDU addu 356819833afSPeter Tyser #define PTR_ADDI addi 357819833afSPeter Tyser #define PTR_ADDIU addiu 358819833afSPeter Tyser #define PTR_SUB sub 359819833afSPeter Tyser #define PTR_SUBU subu 360819833afSPeter Tyser #define PTR_L lw 361819833afSPeter Tyser #define PTR_S sw 362819833afSPeter Tyser #define PTR_LA la 363819833afSPeter Tyser #define PTR_LI li 364819833afSPeter Tyser #define PTR_SLL sll 365819833afSPeter Tyser #define PTR_SLLV sllv 366819833afSPeter Tyser #define PTR_SRL srl 367819833afSPeter Tyser #define PTR_SRLV srlv 368819833afSPeter Tyser #define PTR_SRA sra 369819833afSPeter Tyser #define PTR_SRAV srav 370819833afSPeter Tyser 371819833afSPeter Tyser #define PTR_SCALESHIFT 2 372819833afSPeter Tyser 373819833afSPeter Tyser #define PTR .word 374819833afSPeter Tyser #define PTRSIZE 4 375819833afSPeter Tyser #define PTRLOG 2 376819833afSPeter Tyser #endif 377819833afSPeter Tyser 378819833afSPeter Tyser #if (_MIPS_SZPTR == 64) 379819833afSPeter Tyser #define PTR_ADD dadd 380819833afSPeter Tyser #define PTR_ADDU daddu 381819833afSPeter Tyser #define PTR_ADDI daddi 382819833afSPeter Tyser #define PTR_ADDIU daddiu 383819833afSPeter Tyser #define PTR_SUB dsub 384819833afSPeter Tyser #define PTR_SUBU dsubu 385819833afSPeter Tyser #define PTR_L ld 386819833afSPeter Tyser #define PTR_S sd 387819833afSPeter Tyser #define PTR_LA dla 388819833afSPeter Tyser #define PTR_LI dli 389819833afSPeter Tyser #define PTR_SLL dsll 390819833afSPeter Tyser #define PTR_SLLV dsllv 391819833afSPeter Tyser #define PTR_SRL dsrl 392819833afSPeter Tyser #define PTR_SRLV dsrlv 393819833afSPeter Tyser #define PTR_SRA dsra 394819833afSPeter Tyser #define PTR_SRAV dsrav 395819833afSPeter Tyser 396819833afSPeter Tyser #define PTR_SCALESHIFT 3 397819833afSPeter Tyser 398819833afSPeter Tyser #define PTR .dword 399819833afSPeter Tyser #define PTRSIZE 8 400819833afSPeter Tyser #define PTRLOG 3 401819833afSPeter Tyser #endif 402819833afSPeter Tyser 403819833afSPeter Tyser /* 404819833afSPeter Tyser * Some cp0 registers were extended to 64bit for MIPS III. 405819833afSPeter Tyser */ 406819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_ABI32) 407819833afSPeter Tyser #define MFC0 mfc0 408819833afSPeter Tyser #define MTC0 mtc0 409819833afSPeter Tyser #endif 410819833afSPeter Tyser #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 411819833afSPeter Tyser #define MFC0 dmfc0 412819833afSPeter Tyser #define MTC0 dmtc0 413819833afSPeter Tyser #endif 414819833afSPeter Tyser 415819833afSPeter Tyser #define SSNOP sll zero, zero, 1 416819833afSPeter Tyser 417819833afSPeter Tyser #ifdef CONFIG_SGI_IP28 418819833afSPeter Tyser /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 419819833afSPeter Tyser #include <asm/cacheops.h> 420cb0a6a1eSZhi-zhou Zhang #define R10KCBARRIER(addr) cache CACHE_BARRIER, addr; 421819833afSPeter Tyser #else 422819833afSPeter Tyser #define R10KCBARRIER(addr) 423819833afSPeter Tyser #endif 424819833afSPeter Tyser 425819833afSPeter Tyser #endif /* __ASM_ASM_H */ 426