1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle 4 * Copyright (C) 1999 by Silicon Graphics, Inc. 5 * Copyright (C) 2001 MIPS Technologies, Inc. 6 * Copyright (C) 2002 Maciej W. Rozycki 7 * 8 * Some useful macros for MIPS assembler code 9 * 10 * Some of the routines below contain useless nops that will be optimized 11 * away by gas in -O mode. These nops are however required to fill delay 12 * slots in noreorder mode. 13 */ 14 #ifndef __ASM_ASM_H 15 #define __ASM_ASM_H 16 17 #include <asm/sgidefs.h> 18 19 #ifndef CAT 20 #ifdef __STDC__ 21 #define __CAT(str1, str2) str1##str2 22 #else 23 #define __CAT(str1, str2) str1/**/str2 24 #endif 25 #define CAT(str1, str2) __CAT(str1, str2) 26 #endif 27 28 /* 29 * PIC specific declarations 30 * Not used for the kernel but here seems to be the right place. 31 */ 32 #ifdef __PIC__ 33 #define CPRESTORE(register) \ 34 .cprestore register 35 #define CPADD(register) \ 36 .cpadd register 37 #define CPLOAD(register) \ 38 .cpload register 39 #else 40 #define CPRESTORE(register) 41 #define CPADD(register) 42 #define CPLOAD(register) 43 #endif 44 45 #define ENTRY(symbol) \ 46 .globl symbol; \ 47 .type symbol, @function; \ 48 .ent symbol, 0; \ 49 symbol: 50 51 /* 52 * LEAF - declare leaf routine 53 */ 54 #define LEAF(symbol) \ 55 .globl symbol; \ 56 .align 2; \ 57 .type symbol, @function; \ 58 .ent symbol, 0; \ 59 .section .text.symbol, "x"; \ 60 symbol: .frame sp, 0, ra 61 62 /* 63 * NESTED - declare nested routine entry point 64 */ 65 #define NESTED(symbol, framesize, rpc) \ 66 .globl symbol; \ 67 .align 2; \ 68 .type symbol, @function; \ 69 .ent symbol, 0; \ 70 .section .text.symbol, "x"; \ 71 symbol: .frame sp, framesize, rpc 72 73 /* 74 * END - mark end of function 75 */ 76 #define END(function) \ 77 .end function; \ 78 .size function, .-function 79 80 /* 81 * EXPORT - export definition of symbol 82 */ 83 #define EXPORT(symbol) \ 84 .globl symbol; \ 85 symbol: 86 87 /* 88 * FEXPORT - export definition of a function symbol 89 */ 90 #define FEXPORT(symbol) \ 91 .globl symbol; \ 92 .type symbol, @function; \ 93 symbol: 94 95 /* 96 * ABS - export absolute symbol 97 */ 98 #define ABS(symbol,value) \ 99 .globl symbol; \ 100 symbol = value 101 102 #define 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 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 PRINT(string) 124 #endif 125 126 #define TEXT(msg) \ 127 .pushsection .data; \ 128 8: .asciiz msg; \ 129 .popsection; 130 131 /* 132 * Build text tables 133 */ 134 #define TTABLE(string) \ 135 .pushsection .text; \ 136 .word 1f; \ 137 .popsection \ 138 .pushsection .data; \ 139 1: .asciiz string; \ 140 .popsection 141 142 /* 143 * MIPS IV pref instruction. 144 * Use with .set noreorder only! 145 * 146 * MIPS IV implementations are free to treat this as a nop. The R5000 147 * is one of them. So we should have an option not to use this instruction. 148 */ 149 #ifdef CONFIG_CPU_HAS_PREFETCH 150 151 #define PREF(hint, addr) \ 152 .set push; \ 153 .set arch=r5000; \ 154 pref hint, addr; \ 155 .set pop 156 157 #define PREFE(hint, addr) \ 158 .set push; \ 159 .set mips0; \ 160 .set eva; \ 161 prefe hint, addr; \ 162 .set pop 163 164 #define PREFX(hint, addr) \ 165 .set push; \ 166 .set arch=r5000; \ 167 prefx hint, addr; \ 168 .set pop 169 170 #else /* !CONFIG_CPU_HAS_PREFETCH */ 171 172 #define PREF(hint, addr) 173 #define PREFE(hint, addr) 174 #define PREFX(hint, addr) 175 176 #endif /* !CONFIG_CPU_HAS_PREFETCH */ 177 178 /* 179 * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. 180 */ 181 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) 182 #define MOVN(rd, rs, rt) \ 183 .set push; \ 184 .set reorder; \ 185 beqz rt, 9f; \ 186 move rd, rs; \ 187 .set pop; \ 188 9: 189 #define MOVZ(rd, rs, rt) \ 190 .set push; \ 191 .set reorder; \ 192 bnez rt, 9f; \ 193 move rd, rs; \ 194 .set pop; \ 195 9: 196 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ 197 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) 198 #define MOVN(rd, rs, rt) \ 199 .set push; \ 200 .set noreorder; \ 201 bnezl rt, 9f; \ 202 move rd, rs; \ 203 .set pop; \ 204 9: 205 #define MOVZ(rd, rs, rt) \ 206 .set push; \ 207 .set noreorder; \ 208 beqzl rt, 9f; \ 209 move rd, rs; \ 210 .set pop; \ 211 9: 212 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ 213 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ 214 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 215 #define MOVN(rd, rs, rt) \ 216 movn rd, rs, rt 217 #define MOVZ(rd, rs, rt) \ 218 movz rd, rs, rt 219 #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ 220 221 /* 222 * Stack alignment 223 */ 224 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 225 #define ALSZ 7 226 #define ALMASK ~7 227 #endif 228 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 229 #define ALSZ 15 230 #define ALMASK ~15 231 #endif 232 233 /* 234 * Macros to handle different pointer/register sizes for 32/64-bit code 235 */ 236 237 /* 238 * Size of a register 239 */ 240 #ifdef __mips64 241 #define SZREG 8 242 #else 243 #define SZREG 4 244 #endif 245 246 /* 247 * Use the following macros in assemblercode to load/store registers, 248 * pointers etc. 249 */ 250 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 251 #define REG_S sw 252 #define REG_L lw 253 #define REG_SUBU subu 254 #define REG_ADDU addu 255 #endif 256 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 257 #define REG_S sd 258 #define REG_L ld 259 #define REG_SUBU dsubu 260 #define REG_ADDU daddu 261 #endif 262 263 /* 264 * How to add/sub/load/store/shift C int variables. 265 */ 266 #if (_MIPS_SZINT == 32) 267 #define INT_ADD add 268 #define INT_ADDU addu 269 #define INT_ADDI addi 270 #define INT_ADDIU addiu 271 #define INT_SUB sub 272 #define INT_SUBU subu 273 #define INT_L lw 274 #define INT_S sw 275 #define INT_SLL sll 276 #define INT_SLLV sllv 277 #define INT_SRL srl 278 #define INT_SRLV srlv 279 #define INT_SRA sra 280 #define INT_SRAV srav 281 #endif 282 283 #if (_MIPS_SZINT == 64) 284 #define INT_ADD dadd 285 #define INT_ADDU daddu 286 #define INT_ADDI daddi 287 #define INT_ADDIU daddiu 288 #define INT_SUB dsub 289 #define INT_SUBU dsubu 290 #define INT_L ld 291 #define INT_S sd 292 #define INT_SLL dsll 293 #define INT_SLLV dsllv 294 #define INT_SRL dsrl 295 #define INT_SRLV dsrlv 296 #define INT_SRA dsra 297 #define INT_SRAV dsrav 298 #endif 299 300 /* 301 * How to add/sub/load/store/shift C long variables. 302 */ 303 #if (_MIPS_SZLONG == 32) 304 #define LONG_ADD add 305 #define LONG_ADDU addu 306 #define LONG_ADDI addi 307 #define LONG_ADDIU addiu 308 #define LONG_SUB sub 309 #define LONG_SUBU subu 310 #define LONG_L lw 311 #define LONG_S sw 312 #define LONG_SP swp 313 #define LONG_SLL sll 314 #define LONG_SLLV sllv 315 #define LONG_SRL srl 316 #define LONG_SRLV srlv 317 #define LONG_SRA sra 318 #define LONG_SRAV srav 319 320 #define LONG .word 321 #define LONGSIZE 4 322 #define LONGMASK 3 323 #define LONGLOG 2 324 #endif 325 326 #if (_MIPS_SZLONG == 64) 327 #define LONG_ADD dadd 328 #define LONG_ADDU daddu 329 #define LONG_ADDI daddi 330 #define LONG_ADDIU daddiu 331 #define LONG_SUB dsub 332 #define LONG_SUBU dsubu 333 #define LONG_L ld 334 #define LONG_S sd 335 #define LONG_SP sdp 336 #define LONG_SLL dsll 337 #define LONG_SLLV dsllv 338 #define LONG_SRL dsrl 339 #define LONG_SRLV dsrlv 340 #define LONG_SRA dsra 341 #define LONG_SRAV dsrav 342 343 #define LONG .dword 344 #define LONGSIZE 8 345 #define LONGMASK 7 346 #define LONGLOG 3 347 #endif 348 349 /* 350 * How to add/sub/load/store/shift pointers. 351 */ 352 #if (_MIPS_SZPTR == 32) 353 #define PTR_ADD add 354 #define PTR_ADDU addu 355 #define PTR_ADDI addi 356 #define PTR_ADDIU addiu 357 #define PTR_SUB sub 358 #define PTR_SUBU subu 359 #define PTR_L lw 360 #define PTR_S sw 361 #define PTR_LA la 362 #define PTR_LI li 363 #define PTR_SLL sll 364 #define PTR_SLLV sllv 365 #define PTR_SRL srl 366 #define PTR_SRLV srlv 367 #define PTR_SRA sra 368 #define PTR_SRAV srav 369 370 #define PTR_SCALESHIFT 2 371 372 #define PTR .word 373 #define PTRSIZE 4 374 #define PTRLOG 2 375 #endif 376 377 #if (_MIPS_SZPTR == 64) 378 #define PTR_ADD dadd 379 #define PTR_ADDU daddu 380 #define PTR_ADDI daddi 381 #define PTR_ADDIU daddiu 382 #define PTR_SUB dsub 383 #define PTR_SUBU dsubu 384 #define PTR_L ld 385 #define PTR_S sd 386 #define PTR_LA dla 387 #define PTR_LI dli 388 #define PTR_SLL dsll 389 #define PTR_SLLV dsllv 390 #define PTR_SRL dsrl 391 #define PTR_SRLV dsrlv 392 #define PTR_SRA dsra 393 #define PTR_SRAV dsrav 394 395 #define PTR_SCALESHIFT 3 396 397 #define PTR .dword 398 #define PTRSIZE 8 399 #define PTRLOG 3 400 #endif 401 402 /* 403 * Some cp0 registers were extended to 64bit for MIPS III. 404 */ 405 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 406 #define MFC0 mfc0 407 #define MTC0 mtc0 408 #endif 409 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 410 #define MFC0 dmfc0 411 #define MTC0 dmtc0 412 #endif 413 414 #define SSNOP sll zero, zero, 1 415 416 #ifdef CONFIG_SGI_IP28 417 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ 418 #include <asm/cacheops.h> 419 #define R10KCBARRIER(addr) cache CACHE_BARRIER, addr; 420 #else 421 #define R10KCBARRIER(addr) 422 #endif 423 424 #endif /* __ASM_ASM_H */ 425