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