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