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