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