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