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