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 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; \ 67 symbol: .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; \ 81 symbol: 82 83 /* 84 * FEXPORT - export definition of a function symbol 85 */ 86 #define FEXPORT(symbol) \ 87 .globl symbol; \ 88 .type symbol, @function; \ 89 symbol: 90 91 /* 92 * ABS - export absolute symbol 93 */ 94 #define ABS(symbol,value) \ 95 .globl symbol; \ 96 symbol = value 97 98 #define PANIC(msg) \ 99 .set push; \ 100 .set reorder; \ 101 PTR_LA a0, 8f; \ 102 jal panic; \ 103 9: 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; \ 124 8: .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; \ 135 1: .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; \ 184 9: 185 #define MOVZ(rd, rs, rt) \ 186 .set push; \ 187 .set reorder; \ 188 bnez rt, 9f; \ 189 move rd, rs; \ 190 .set pop; \ 191 9: 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; \ 200 9: 201 #define MOVZ(rd, rs, rt) \ 202 .set push; \ 203 .set noreorder; \ 204 beqzl rt, 9f; \ 205 move rd, rs; \ 206 .set pop; \ 207 9: 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