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 .cfi_startproc; \ 59 .insn 60 61 /* 62 * NESTED - declare nested routine entry point 63 */ 64 #define NESTED(symbol, framesize, rpc) \ 65 .globl symbol; \ 66 .align 2; \ 67 .type symbol, @function; \ 68 .ent symbol, 0; \ 69 symbol: .frame sp, framesize, rpc; \ 70 .cfi_startproc; \ 71 .insn 72 73 /* 74 * END - mark end of function 75 */ 76 #define END(function) \ 77 .cfi_endproc; \ 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: .insn 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 arch=r5000; \ 155 pref hint, addr; \ 156 .set pop 157 158 #define PREFE(hint, addr) \ 159 .set push; \ 160 .set mips0; \ 161 .set eva; \ 162 prefe hint, addr; \ 163 .set pop 164 165 #define PREFX(hint,addr) \ 166 .set push; \ 167 .set arch=r5000; \ 168 prefx hint, addr; \ 169 .set pop 170 171 #else /* !CONFIG_CPU_HAS_PREFETCH */ 172 173 #define PREF(hint, addr) 174 #define PREFE(hint, addr) 175 #define PREFX(hint, addr) 176 177 #endif /* !CONFIG_CPU_HAS_PREFETCH */ 178 179 /* 180 * Stack alignment 181 */ 182 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 183 #define ALSZ 7 184 #define ALMASK ~7 185 #endif 186 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 187 #define ALSZ 15 188 #define ALMASK ~15 189 #endif 190 191 /* 192 * Macros to handle different pointer/register sizes for 32/64-bit code 193 */ 194 195 /* 196 * Size of a register 197 */ 198 #ifdef __mips64 199 #define SZREG 8 200 #else 201 #define SZREG 4 202 #endif 203 204 /* 205 * Use the following macros in assemblercode to load/store registers, 206 * pointers etc. 207 */ 208 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 209 #define REG_S sw 210 #define REG_L lw 211 #define REG_SUBU subu 212 #define REG_ADDU addu 213 #endif 214 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 215 #define REG_S sd 216 #define REG_L ld 217 #define REG_SUBU dsubu 218 #define REG_ADDU daddu 219 #endif 220 221 /* 222 * How to add/sub/load/store/shift C int variables. 223 */ 224 #if (_MIPS_SZINT == 32) 225 #define INT_ADD add 226 #define INT_ADDU addu 227 #define INT_ADDI addi 228 #define INT_ADDIU addiu 229 #define INT_SUB sub 230 #define INT_SUBU subu 231 #define INT_L lw 232 #define INT_S sw 233 #define INT_SLL sll 234 #define INT_SLLV sllv 235 #define INT_SRL srl 236 #define INT_SRLV srlv 237 #define INT_SRA sra 238 #define INT_SRAV srav 239 #endif 240 241 #if (_MIPS_SZINT == 64) 242 #define INT_ADD dadd 243 #define INT_ADDU daddu 244 #define INT_ADDI daddi 245 #define INT_ADDIU daddiu 246 #define INT_SUB dsub 247 #define INT_SUBU dsubu 248 #define INT_L ld 249 #define INT_S sd 250 #define INT_SLL dsll 251 #define INT_SLLV dsllv 252 #define INT_SRL dsrl 253 #define INT_SRLV dsrlv 254 #define INT_SRA dsra 255 #define INT_SRAV dsrav 256 #endif 257 258 /* 259 * How to add/sub/load/store/shift C long variables. 260 */ 261 #if (_MIPS_SZLONG == 32) 262 #define LONG_ADD add 263 #define LONG_ADDU addu 264 #define LONG_ADDI addi 265 #define LONG_ADDIU addiu 266 #define LONG_SUB sub 267 #define LONG_SUBU subu 268 #define LONG_L lw 269 #define LONG_S sw 270 #define LONG_SP swp 271 #define LONG_SLL sll 272 #define LONG_SLLV sllv 273 #define LONG_SRL srl 274 #define LONG_SRLV srlv 275 #define LONG_SRA sra 276 #define LONG_SRAV srav 277 278 #define LONG .word 279 #define LONGSIZE 4 280 #define LONGMASK 3 281 #define LONGLOG 2 282 #endif 283 284 #if (_MIPS_SZLONG == 64) 285 #define LONG_ADD dadd 286 #define LONG_ADDU daddu 287 #define LONG_ADDI daddi 288 #define LONG_ADDIU daddiu 289 #define LONG_SUB dsub 290 #define LONG_SUBU dsubu 291 #define LONG_L ld 292 #define LONG_S sd 293 #define LONG_SP sdp 294 #define LONG_SLL dsll 295 #define LONG_SLLV dsllv 296 #define LONG_SRL dsrl 297 #define LONG_SRLV dsrlv 298 #define LONG_SRA dsra 299 #define LONG_SRAV dsrav 300 301 #define LONG .dword 302 #define LONGSIZE 8 303 #define LONGMASK 7 304 #define LONGLOG 3 305 #endif 306 307 /* 308 * How to add/sub/load/store/shift pointers. 309 */ 310 #if (_MIPS_SZPTR == 32) 311 #define PTR_ADD add 312 #define PTR_ADDU addu 313 #define PTR_ADDI addi 314 #define PTR_ADDIU addiu 315 #define PTR_SUB sub 316 #define PTR_SUBU subu 317 #define PTR_L lw 318 #define PTR_S sw 319 #define PTR_LA la 320 #define PTR_LI li 321 #define PTR_SLL sll 322 #define PTR_SLLV sllv 323 #define PTR_SRL srl 324 #define PTR_SRLV srlv 325 #define PTR_SRA sra 326 #define PTR_SRAV srav 327 328 #define PTR_SCALESHIFT 2 329 330 #define PTR .word 331 #define PTRSIZE 4 332 #define PTRLOG 2 333 #endif 334 335 #if (_MIPS_SZPTR == 64) 336 #define PTR_ADD dadd 337 #define PTR_ADDU daddu 338 #define PTR_ADDI daddi 339 #define PTR_ADDIU daddiu 340 #define PTR_SUB dsub 341 #define PTR_SUBU dsubu 342 #define PTR_L ld 343 #define PTR_S sd 344 #define PTR_LA dla 345 #define PTR_LI dli 346 #define PTR_SLL dsll 347 #define PTR_SLLV dsllv 348 #define PTR_SRL dsrl 349 #define PTR_SRLV dsrlv 350 #define PTR_SRA dsra 351 #define PTR_SRAV dsrav 352 353 #define PTR_SCALESHIFT 3 354 355 #define PTR .dword 356 #define PTRSIZE 8 357 #define PTRLOG 3 358 #endif 359 360 /* 361 * Some cp0 registers were extended to 64bit for MIPS III. 362 */ 363 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 364 #define MFC0 mfc0 365 #define MTC0 mtc0 366 #endif 367 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 368 #define MFC0 dmfc0 369 #define MTC0 dmtc0 370 #endif 371 372 #define SSNOP sll zero, zero, 1 373 374 #ifdef CONFIG_SGI_IP28 375 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 376 #include <asm/cacheops.h> 377 #define R10KCBARRIER(addr) cache Cache_Barrier, addr; 378 #else 379 #define R10KCBARRIER(addr) 380 #endif 381 382 #endif /* __ASM_ASM_H */ 383