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