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 * MIPS IV pref instruction. 117 * Use with .set noreorder only! 118 * 119 * MIPS IV implementations are free to treat this as a nop. The R5000 120 * is one of them. So we should have an option not to use this instruction. 121 */ 122 #ifdef CONFIG_CPU_HAS_PREFETCH 123 124 #define PREF(hint,addr) \ 125 .set push; \ 126 .set arch=r5000; \ 127 pref hint, addr; \ 128 .set pop 129 130 #define PREFE(hint, addr) \ 131 .set push; \ 132 .set mips0; \ 133 .set eva; \ 134 prefe hint, addr; \ 135 .set pop 136 137 #define PREFX(hint,addr) \ 138 .set push; \ 139 .set arch=r5000; \ 140 prefx hint, addr; \ 141 .set pop 142 143 #else /* !CONFIG_CPU_HAS_PREFETCH */ 144 145 #define PREF(hint, addr) 146 #define PREFE(hint, addr) 147 #define PREFX(hint, addr) 148 149 #endif /* !CONFIG_CPU_HAS_PREFETCH */ 150 151 /* 152 * Stack alignment 153 */ 154 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 155 #define ALSZ 7 156 #define ALMASK ~7 157 #endif 158 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 159 #define ALSZ 15 160 #define ALMASK ~15 161 #endif 162 163 /* 164 * Macros to handle different pointer/register sizes for 32/64-bit code 165 */ 166 167 /* 168 * Size of a register 169 */ 170 #ifdef __mips64 171 #define SZREG 8 172 #else 173 #define SZREG 4 174 #endif 175 176 /* 177 * Use the following macros in assemblercode to load/store registers, 178 * pointers etc. 179 */ 180 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 181 #define REG_S sw 182 #define REG_L lw 183 #define REG_SUBU subu 184 #define REG_ADDU addu 185 #endif 186 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 187 #define REG_S sd 188 #define REG_L ld 189 #define REG_SUBU dsubu 190 #define REG_ADDU daddu 191 #endif 192 193 /* 194 * How to add/sub/load/store/shift C int variables. 195 */ 196 #if (_MIPS_SZINT == 32) 197 #define INT_ADD add 198 #define INT_ADDU addu 199 #define INT_ADDI addi 200 #define INT_ADDIU addiu 201 #define INT_SUB sub 202 #define INT_SUBU subu 203 #define INT_L lw 204 #define INT_S sw 205 #define INT_SLL sll 206 #define INT_SLLV sllv 207 #define INT_SRL srl 208 #define INT_SRLV srlv 209 #define INT_SRA sra 210 #define INT_SRAV srav 211 #endif 212 213 #if (_MIPS_SZINT == 64) 214 #define INT_ADD dadd 215 #define INT_ADDU daddu 216 #define INT_ADDI daddi 217 #define INT_ADDIU daddiu 218 #define INT_SUB dsub 219 #define INT_SUBU dsubu 220 #define INT_L ld 221 #define INT_S sd 222 #define INT_SLL dsll 223 #define INT_SLLV dsllv 224 #define INT_SRL dsrl 225 #define INT_SRLV dsrlv 226 #define INT_SRA dsra 227 #define INT_SRAV dsrav 228 #endif 229 230 /* 231 * How to add/sub/load/store/shift C long variables. 232 */ 233 #if (_MIPS_SZLONG == 32) 234 #define LONG_ADD add 235 #define LONG_ADDU addu 236 #define LONG_ADDI addi 237 #define LONG_ADDIU addiu 238 #define LONG_SUB sub 239 #define LONG_SUBU subu 240 #define LONG_L lw 241 #define LONG_S sw 242 #define LONG_SP swp 243 #define LONG_SLL sll 244 #define LONG_SLLV sllv 245 #define LONG_SRL srl 246 #define LONG_SRLV srlv 247 #define LONG_SRA sra 248 #define LONG_SRAV srav 249 250 #define LONG .word 251 #define LONGSIZE 4 252 #define LONGMASK 3 253 #define LONGLOG 2 254 #endif 255 256 #if (_MIPS_SZLONG == 64) 257 #define LONG_ADD dadd 258 #define LONG_ADDU daddu 259 #define LONG_ADDI daddi 260 #define LONG_ADDIU daddiu 261 #define LONG_SUB dsub 262 #define LONG_SUBU dsubu 263 #define LONG_L ld 264 #define LONG_S sd 265 #define LONG_SP sdp 266 #define LONG_SLL dsll 267 #define LONG_SLLV dsllv 268 #define LONG_SRL dsrl 269 #define LONG_SRLV dsrlv 270 #define LONG_SRA dsra 271 #define LONG_SRAV dsrav 272 273 #define LONG .dword 274 #define LONGSIZE 8 275 #define LONGMASK 7 276 #define LONGLOG 3 277 #endif 278 279 /* 280 * How to add/sub/load/store/shift pointers. 281 */ 282 #if (_MIPS_SZPTR == 32) 283 #define PTR_ADD add 284 #define PTR_ADDU addu 285 #define PTR_ADDI addi 286 #define PTR_ADDIU addiu 287 #define PTR_SUB sub 288 #define PTR_SUBU subu 289 #define PTR_L lw 290 #define PTR_S sw 291 #define PTR_LA la 292 #define PTR_LI li 293 #define PTR_SLL sll 294 #define PTR_SLLV sllv 295 #define PTR_SRL srl 296 #define PTR_SRLV srlv 297 #define PTR_SRA sra 298 #define PTR_SRAV srav 299 300 #define PTR_SCALESHIFT 2 301 302 #define PTR .word 303 #define PTRSIZE 4 304 #define PTRLOG 2 305 #endif 306 307 #if (_MIPS_SZPTR == 64) 308 #define PTR_ADD dadd 309 #define PTR_ADDU daddu 310 #define PTR_ADDI daddi 311 #define PTR_ADDIU daddiu 312 #define PTR_SUB dsub 313 #define PTR_SUBU dsubu 314 #define PTR_L ld 315 #define PTR_S sd 316 #define PTR_LA dla 317 #define PTR_LI dli 318 #define PTR_SLL dsll 319 #define PTR_SLLV dsllv 320 #define PTR_SRL dsrl 321 #define PTR_SRLV dsrlv 322 #define PTR_SRA dsra 323 #define PTR_SRAV dsrav 324 325 #define PTR_SCALESHIFT 3 326 327 #define PTR .dword 328 #define PTRSIZE 8 329 #define PTRLOG 3 330 #endif 331 332 /* 333 * Some cp0 registers were extended to 64bit for MIPS III. 334 */ 335 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 336 #define MFC0 mfc0 337 #define MTC0 mtc0 338 #endif 339 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 340 #define MFC0 dmfc0 341 #define MTC0 dmtc0 342 #endif 343 344 #define SSNOP sll zero, zero, 1 345 346 #ifdef CONFIG_SGI_IP28 347 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 348 #include <asm/cacheops.h> 349 #define R10KCBARRIER(addr) cache Cache_Barrier, addr; 350 #else 351 #define R10KCBARRIER(addr) 352 #endif 353 354 #endif /* __ASM_ASM_H */ 355