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 #define LONG_INS ins 226 #define LONG_EXT ext 227 228 #ifdef __ASSEMBLY__ 229 #define LONG .word 230 #endif 231 #define LONGSIZE 4 232 #define LONGMASK 3 233 #define LONGLOG 2 234 #endif 235 236 #if (_MIPS_SZLONG == 64) 237 #define LONG_ADD dadd 238 #define LONG_ADDU daddu 239 #define LONG_ADDI daddi 240 #define LONG_ADDIU daddiu 241 #define LONG_SUB dsub 242 #define LONG_SUBU dsubu 243 #define LONG_L ld 244 #define LONG_LL lld 245 #define LONG_SC scd 246 #define LONG_S sd 247 #define LONG_SP sdp 248 #define LONG_SLL dsll 249 #define LONG_SLLV dsllv 250 #define LONG_SRL dsrl 251 #define LONG_SRLV dsrlv 252 #define LONG_SRA dsra 253 #define LONG_SRAV dsrav 254 #define LONG_INS dins 255 #define LONG_EXT dext 256 257 #ifdef __ASSEMBLY__ 258 #define LONG .dword 259 #endif 260 #define LONGSIZE 8 261 #define LONGMASK 7 262 #define LONGLOG 3 263 #endif 264 265 /* 266 * How to add/sub/load/store/shift pointers. 267 */ 268 #if (_MIPS_SZPTR == 32) 269 #define PTR_ADD add 270 #define PTR_ADDU addu 271 #define PTR_ADDI addi 272 #define PTR_ADDIU addiu 273 #define PTR_SUB sub 274 #define PTR_SUBU subu 275 #define PTR_L lw 276 #define PTR_S sw 277 #define PTR_LA la 278 #define PTR_LI li 279 #define PTR_SLL sll 280 #define PTR_SLLV sllv 281 #define PTR_SRL srl 282 #define PTR_SRLV srlv 283 #define PTR_SRA sra 284 #define PTR_SRAV srav 285 286 #define PTR_SCALESHIFT 2 287 288 #define PTR_WD .word 289 #define PTRSIZE 4 290 #define PTRLOG 2 291 #endif 292 293 #if (_MIPS_SZPTR == 64) 294 #define PTR_ADD dadd 295 #define PTR_ADDU daddu 296 #define PTR_ADDI daddi 297 #define PTR_ADDIU daddiu 298 #define PTR_SUB dsub 299 #define PTR_SUBU dsubu 300 #define PTR_L ld 301 #define PTR_S sd 302 #define PTR_LA dla 303 #define PTR_LI dli 304 #define PTR_SLL dsll 305 #define PTR_SLLV dsllv 306 #define PTR_SRL dsrl 307 #define PTR_SRLV dsrlv 308 #define PTR_SRA dsra 309 #define PTR_SRAV dsrav 310 311 #define PTR_SCALESHIFT 3 312 313 #define PTR_WD .dword 314 #define PTRSIZE 8 315 #define PTRLOG 3 316 #endif 317 318 /* 319 * Some cp0 registers were extended to 64bit for MIPS III. 320 */ 321 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 322 #define MFC0 mfc0 323 #define MTC0 mtc0 324 #endif 325 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 326 #define MFC0 dmfc0 327 #define MTC0 dmtc0 328 #endif 329 330 #define SSNOP sll zero, zero, 1 331 332 /* 333 * Using a branch-likely instruction to check the result of an sc instruction 334 * works around a bug present in R10000 CPUs prior to revision 3.0 that could 335 * cause ll-sc sequences to execute non-atomically. 336 */ 337 #ifdef CONFIG_WAR_R10000_LLSC 338 # define SC_BEQZ beqzl 339 #elif MIPS_ISA_REV >= 6 340 # define SC_BEQZ beqzc 341 #else 342 # define SC_BEQZ beqz 343 #endif 344 345 #ifdef CONFIG_SGI_IP28 346 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 347 #include <asm/cacheops.h> 348 #define R10KCBARRIER(addr) cache Cache_Barrier, addr; 349 #else 350 #define R10KCBARRIER(addr) 351 #endif 352 353 #endif /* __ASM_ASM_H */ 354