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