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 .section .text.symbol, "x"; \ 63 symbol: .frame sp, 0, ra 64 65 /* 66 * NESTED - declare nested routine entry point 67 */ 68 #define NESTED(symbol, framesize, rpc) \ 69 .globl symbol; \ 70 .align 2; \ 71 .type symbol, @function; \ 72 .ent symbol, 0; \ 73 .section .text.symbol, "x"; \ 74 symbol: .frame sp, framesize, rpc 75 76 /* 77 * END - mark end of function 78 */ 79 #define END(function) \ 80 .end function; \ 81 .size function, .-function 82 83 /* 84 * EXPORT - export definition of symbol 85 */ 86 #define EXPORT(symbol) \ 87 .globl symbol; \ 88 symbol: 89 90 /* 91 * FEXPORT - export definition of a function symbol 92 */ 93 #define FEXPORT(symbol) \ 94 .globl symbol; \ 95 .type symbol, @function; \ 96 symbol: 97 98 /* 99 * ABS - export absolute symbol 100 */ 101 #define ABS(symbol,value) \ 102 .globl symbol; \ 103 symbol = value 104 105 #define PANIC(msg) \ 106 .set push; \ 107 .set reorder; \ 108 PTR_LA a0, 8f; \ 109 jal panic; \ 110 9: b 9b; \ 111 .set pop; \ 112 TEXT(msg) 113 114 /* 115 * Print formatted string 116 */ 117 #ifdef CONFIG_PRINTK 118 #define PRINT(string) \ 119 .set push; \ 120 .set reorder; \ 121 PTR_LA a0, 8f; \ 122 jal printk; \ 123 .set pop; \ 124 TEXT(string) 125 #else 126 #define PRINT(string) 127 #endif 128 129 #define TEXT(msg) \ 130 .pushsection .data; \ 131 8: .asciiz msg; \ 132 .popsection; 133 134 /* 135 * Build text tables 136 */ 137 #define TTABLE(string) \ 138 .pushsection .text; \ 139 .word 1f; \ 140 .popsection \ 141 .pushsection .data; \ 142 1: .asciiz string; \ 143 .popsection 144 145 /* 146 * MIPS IV pref instruction. 147 * Use with .set noreorder only! 148 * 149 * MIPS IV implementations are free to treat this as a nop. The R5000 150 * is one of them. So we should have an option not to use this instruction. 151 */ 152 #ifdef CONFIG_CPU_HAS_PREFETCH 153 154 #define PREF(hint,addr) \ 155 .set push; \ 156 .set mips4; \ 157 pref hint, addr; \ 158 .set pop 159 160 #define PREFX(hint,addr) \ 161 .set push; \ 162 .set mips4; \ 163 prefx hint, addr; \ 164 .set pop 165 166 #else /* !CONFIG_CPU_HAS_PREFETCH */ 167 168 #define PREF(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_SLL sll 308 #define LONG_SLLV sllv 309 #define LONG_SRL srl 310 #define LONG_SRLV srlv 311 #define LONG_SRA sra 312 #define LONG_SRAV srav 313 314 #define LONG .word 315 #define LONGSIZE 4 316 #define LONGMASK 3 317 #define LONGLOG 2 318 #endif 319 320 #if (_MIPS_SZLONG == 64) 321 #define LONG_ADD dadd 322 #define LONG_ADDU daddu 323 #define LONG_ADDI daddi 324 #define LONG_ADDIU daddiu 325 #define LONG_SUB dsub 326 #define LONG_SUBU dsubu 327 #define LONG_L ld 328 #define LONG_S sd 329 #define LONG_SLL dsll 330 #define LONG_SLLV dsllv 331 #define LONG_SRL dsrl 332 #define LONG_SRLV dsrlv 333 #define LONG_SRA dsra 334 #define LONG_SRAV dsrav 335 336 #define LONG .dword 337 #define LONGSIZE 8 338 #define LONGMASK 7 339 #define LONGLOG 3 340 #endif 341 342 /* 343 * How to add/sub/load/store/shift pointers. 344 */ 345 #if (_MIPS_SZPTR == 32) 346 #define PTR_ADD add 347 #define PTR_ADDU addu 348 #define PTR_ADDI addi 349 #define PTR_ADDIU addiu 350 #define PTR_SUB sub 351 #define PTR_SUBU subu 352 #define PTR_L lw 353 #define PTR_S sw 354 #define PTR_LA la 355 #define PTR_LI li 356 #define PTR_SLL sll 357 #define PTR_SLLV sllv 358 #define PTR_SRL srl 359 #define PTR_SRLV srlv 360 #define PTR_SRA sra 361 #define PTR_SRAV srav 362 363 #define PTR_SCALESHIFT 2 364 365 #define PTR .word 366 #define PTRSIZE 4 367 #define PTRLOG 2 368 #endif 369 370 #if (_MIPS_SZPTR == 64) 371 #define PTR_ADD dadd 372 #define PTR_ADDU daddu 373 #define PTR_ADDI daddi 374 #define PTR_ADDIU daddiu 375 #define PTR_SUB dsub 376 #define PTR_SUBU dsubu 377 #define PTR_L ld 378 #define PTR_S sd 379 #define PTR_LA dla 380 #define PTR_LI dli 381 #define PTR_SLL dsll 382 #define PTR_SLLV dsllv 383 #define PTR_SRL dsrl 384 #define PTR_SRLV dsrlv 385 #define PTR_SRA dsra 386 #define PTR_SRAV dsrav 387 388 #define PTR_SCALESHIFT 3 389 390 #define PTR .dword 391 #define PTRSIZE 8 392 #define PTRLOG 3 393 #endif 394 395 /* 396 * Some cp0 registers were extended to 64bit for MIPS III. 397 */ 398 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 399 #define MFC0 mfc0 400 #define MTC0 mtc0 401 #endif 402 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 403 #define MFC0 dmfc0 404 #define MTC0 dmtc0 405 #endif 406 407 #define SSNOP sll zero, zero, 1 408 409 #ifdef CONFIG_SGI_IP28 410 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 411 #include <asm/cacheops.h> 412 #define R10KCBARRIER(addr) cache CACHE_BARRIER, addr; 413 #else 414 #define R10KCBARRIER(addr) 415 #endif 416 417 #endif /* __ASM_ASM_H */ 418