1 /* Copyright (C) 1997, 1998, 2002, 2003 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 Contributed by Ralf Baechle <ralf@gnu.org>. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19 #ifndef _SYS_ASM_H 20 #define _SYS_ASM_H 21 22 #include <sgidefs.h> 23 24 #ifndef CAT 25 # ifdef __STDC__ 26 # define __CAT(str1,str2) str1##str2 27 # else 28 # define __CAT(str1,str2) str1/**/str2 29 # endif 30 # define CAT(str1,str2) __CAT(str1,str2) 31 #endif 32 33 /* 34 * Macros to handle different pointer/register sizes for 32/64-bit code 35 * 36 * 64 bit address space isn't used yet, so we may use the R3000 32 bit 37 * defines for now. 38 */ 39 #if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32) 40 # define PTR .word 41 # define PTRSIZE 4 42 # define PTRLOG 2 43 #elif (_MIPS_SIM == _MIPS_SIM_ABI64) 44 # define PTR .dword 45 # define PTRSIZE 8 46 # define PTRLOG 3 47 #endif 48 49 /* 50 * PIC specific declarations 51 */ 52 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 53 # ifdef __PIC__ 54 # define CPRESTORE(register) \ 55 .cprestore register 56 # define CPLOAD(register) \ 57 .cpload register 58 # else 59 # define CPRESTORE(register) 60 # define CPLOAD(register) 61 # endif 62 63 # define CPADD(register) \ 64 .cpadd register 65 66 /* 67 * Set gp when at 1st instruction 68 */ 69 # define SETUP_GP \ 70 .set noreorder; \ 71 .cpload $25; \ 72 .set reorder 73 /* Set gp when not at 1st instruction */ 74 # define SETUP_GPX(r) \ 75 .set noreorder; \ 76 move r, $31; /* Save old ra. */ \ 77 bal 10f; /* Find addr of cpload. */ \ 78 nop; \ 79 10: \ 80 .cpload $31; \ 81 move $31, r; \ 82 .set reorder 83 # define SETUP_GPX_L(r, l) \ 84 .set noreorder; \ 85 move r, $31; /* Save old ra. */ \ 86 bal l; /* Find addr of cpload. */ \ 87 nop; \ 88 l: \ 89 .cpload $31; \ 90 move $31, r; \ 91 .set reorder 92 # define SAVE_GP(x) \ 93 .cprestore x /* Save gp trigger t9/jalr conversion. */ 94 # define SETUP_GP64(a, b) 95 # define SETUP_GPX64(a, b) 96 # define SETUP_GPX64_L(cp_reg, ra_save, l) 97 # define RESTORE_GP64 98 # define USE_ALT_CP(a) 99 # define L(label) $L ## label 100 #else /* (_MIPS_SIM == _MIPS_SIM_ABI64) || (_MIPS_SIM == _MIPS_SIM_NABI32) */ 101 /* 102 * For callee-saved gp calling convention: 103 */ 104 # define SETUP_GP 105 # define SETUP_GPX(r) 106 # define SETUP_GPX_L(r, l) 107 # define SAVE_GP(x) 108 109 # define SETUP_GP64(gpoffset, proc) \ 110 .cpsetup $25, gpoffset, proc 111 # define SETUP_GPX64(cp_reg, ra_save) \ 112 move ra_save, $31; /* Save old ra. */ \ 113 .set noreorder; \ 114 bal 10f; /* Find addr of .cpsetup. */ \ 115 nop; \ 116 10: \ 117 .set reorder; \ 118 .cpsetup $31, cp_reg, 10b; \ 119 move $31, ra_save 120 # define SETUP_GPX64_L(cp_reg, ra_save, l) \ 121 move ra_save, $31; /* Save old ra. */ \ 122 .set noreorder; \ 123 bal l; /* Find addr of .cpsetup. */ \ 124 nop; \ 125 l: \ 126 .set reorder; \ 127 .cpsetup $31, cp_reg, l; \ 128 move $31, ra_save 129 # define RESTORE_GP64 \ 130 .cpreturn 131 /* Use alternate register for context pointer. */ 132 # define USE_ALT_CP(reg) \ 133 .cplocal reg 134 # define L(label) .L ## label 135 #endif /* _MIPS_SIM != _MIPS_SIM_ABI32 */ 136 137 /* 138 * Stack Frame Definitions 139 */ 140 #if (_MIPS_SIM == _MIPS_SIM_ABI32) 141 # define NARGSAVE 4 /* Space for 4 argument registers must be allocated. */ 142 #endif 143 #if (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32) 144 # define NARGSAVE 0 /* No caller responsibilities. */ 145 #endif 146 147 148 /* 149 * LEAF - declare leaf routine 150 */ 151 #define LEAF(symbol) \ 152 .globl symbol; \ 153 .align 2; \ 154 .type symbol,@function; \ 155 .ent symbol,0; \ 156 symbol: .frame sp,0,ra 157 158 /* 159 * NESTED - declare nested routine entry point 160 */ 161 #define NESTED(symbol, framesize, rpc) \ 162 .globl symbol; \ 163 .align 2; \ 164 .type symbol,@function; \ 165 .ent symbol,0; \ 166 symbol: .frame sp, framesize, rpc 167 168 /* 169 * END - mark end of function 170 */ 171 #ifndef END 172 # define END(function) \ 173 .end function; \ 174 .size function,.-function 175 #endif 176 177 /* 178 * EXPORT - export definition of symbol 179 */ 180 #define EXPORT(symbol) \ 181 .globl symbol; \ 182 symbol: 183 184 /* 185 * ABS - export absolute symbol 186 */ 187 #define ABS(symbol,value) \ 188 .globl symbol; \ 189 symbol = value 190 191 #define PANIC(msg) \ 192 .set push; \ 193 .set reorder; \ 194 la a0,8f; \ 195 jal panic; \ 196 9: b 9b; \ 197 .set pop; \ 198 TEXT(msg) 199 200 /* 201 * Print formated string 202 */ 203 #define PRINT(string) \ 204 .set push; \ 205 .set reorder; \ 206 la a0,8f; \ 207 jal printk; \ 208 .set pop; \ 209 TEXT(string) 210 211 #define TEXT(msg) \ 212 .data; \ 213 8: .asciiz msg; \ 214 .previous; 215 216 /* 217 * Build text tables 218 */ 219 #define TTABLE(string) \ 220 .text; \ 221 .word 1f; \ 222 .previous; \ 223 .data; \ 224 1: .asciz string; \ 225 .previous 226 227 /* 228 * MIPS IV pref instruction. 229 * Use with .set noreorder only! 230 * 231 * MIPS IV implementations are free to treat this as a nop. The R5000 232 * is one of them. So we should have an option not to use this instruction. 233 */ 234 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ 235 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 236 # define PREF(hint,addr) \ 237 pref hint,addr 238 # define PREFX(hint,addr) \ 239 prefx hint,addr 240 #else 241 # define PREF 242 # define PREFX 243 #endif 244 245 /* 246 * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. 247 */ 248 #if _MIPS_ISA == _MIPS_ISA_MIPS1 249 # define MOVN(rd,rs,rt) \ 250 .set push; \ 251 .set reorder; \ 252 beqz rt,9f; \ 253 move rd,rs; \ 254 .set pop; \ 255 9: 256 # define MOVZ(rd,rs,rt) \ 257 .set push; \ 258 .set reorder; \ 259 bnez rt,9f; \ 260 move rd,rt; \ 261 .set pop; \ 262 9: 263 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ 264 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) 265 # define MOVN(rd,rs,rt) \ 266 .set push; \ 267 .set noreorder; \ 268 bnezl rt,9f; \ 269 move rd,rs; \ 270 .set pop; \ 271 9: 272 # define MOVZ(rd,rs,rt) \ 273 .set push; \ 274 .set noreorder; \ 275 beqzl rt,9f; \ 276 movz rd,rs; \ 277 .set pop; \ 278 9: 279 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ 280 #if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ 281 (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 282 # define MOVN(rd,rs,rt) \ 283 movn rd,rs,rt 284 # define MOVZ(rd,rs,rt) \ 285 movz rd,rs,rt 286 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */ 287 288 /* 289 * Stack alignment 290 */ 291 #if (_MIPS_SIM == _MIPS_SIM_ABI64) || (_MIPS_SIM == _MIPS_SIM_NABI32) 292 # define ALSZ 15 293 # define ALMASK ~15 294 #else 295 # define ALSZ 7 296 # define ALMASK ~7 297 #endif 298 299 /* 300 * Size of a register 301 */ 302 #if (_MIPS_SIM == _MIPS_SIM_ABI64) || (_MIPS_SIM == _MIPS_SIM_NABI32) 303 # define SZREG 8 304 #else 305 # define SZREG 4 306 #endif 307 308 /* 309 * Use the following macros in assemblercode to load/store registers, 310 * pointers etc. 311 */ 312 #if (SZREG == 4) 313 # define REG_S sw 314 # define REG_L lw 315 #else 316 # define REG_S sd 317 # define REG_L ld 318 #endif 319 320 /* 321 * How to add/sub/load/store/shift C int variables. 322 */ 323 #if (_MIPS_SZINT == 32) 324 # define INT_ADD add 325 # define INT_ADDI addi 326 # define INT_ADDU addu 327 # define INT_ADDIU addiu 328 # define INT_SUB add 329 # define INT_SUBI subi 330 # define INT_SUBU subu 331 # define INT_SUBIU subu 332 # define INT_L lw 333 # define INT_S sw 334 #endif 335 336 #if (_MIPS_SZINT == 64) 337 # define INT_ADD dadd 338 # define INT_ADDI daddi 339 # define INT_ADDU daddu 340 # define INT_ADDIU daddiu 341 # define INT_SUB dadd 342 # define INT_SUBI dsubi 343 # define INT_SUBU dsubu 344 # define INT_SUBIU dsubu 345 # define INT_L ld 346 # define INT_S sd 347 #endif 348 349 /* 350 * How to add/sub/load/store/shift C long variables. 351 */ 352 #if (_MIPS_SZLONG == 32) 353 # define LONG_ADD add 354 # define LONG_ADDI addi 355 # define LONG_ADDU addu 356 # define LONG_ADDIU addiu 357 # define LONG_SUB add 358 # define LONG_SUBI subi 359 # define LONG_SUBU subu 360 # define LONG_SUBIU subu 361 # define LONG_L lw 362 # define LONG_S sw 363 # define LONG_SLL sll 364 # define LONG_SLLV sllv 365 # define LONG_SRL srl 366 # define LONG_SRLV srlv 367 # define LONG_SRA sra 368 # define LONG_SRAV srav 369 #endif 370 371 #if (_MIPS_SZLONG == 64) 372 # define LONG_ADD dadd 373 # define LONG_ADDI daddi 374 # define LONG_ADDU daddu 375 # define LONG_ADDIU daddiu 376 # define LONG_SUB dadd 377 # define LONG_SUBI dsubi 378 # define LONG_SUBU dsubu 379 # define LONG_SUBIU dsubu 380 # define LONG_L ld 381 # define LONG_S sd 382 # define LONG_SLL dsll 383 # define LONG_SLLV dsllv 384 # define LONG_SRL dsrl 385 # define LONG_SRLV dsrlv 386 # define LONG_SRA dsra 387 # define LONG_SRAV dsrav 388 #endif 389 390 /* 391 * How to add/sub/load/store/shift pointers. 392 */ 393 #if (_MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32) 394 # define PTR_ADD add 395 # define PTR_ADDI addi 396 # define PTR_ADDU addu 397 # define PTR_ADDIU addiu 398 # define PTR_SUB add 399 # define PTR_SUBI subi 400 # define PTR_SUBU subu 401 # define PTR_SUBIU subu 402 # define PTR_L lw 403 # define PTR_LA la 404 # define PTR_S sw 405 # define PTR_SLL sll 406 # define PTR_SLLV sllv 407 # define PTR_SRL srl 408 # define PTR_SRLV srlv 409 # define PTR_SRA sra 410 # define PTR_SRAV srav 411 412 # define PTR_SCALESHIFT 2 413 #endif 414 415 #if _MIPS_SIM == _MIPS_SIM_NABI32 416 # define PTR_ADD add 417 # define PTR_ADDI addi 418 # define PTR_ADDU add /* no u */ 419 # define PTR_ADDIU addi /* no u */ 420 # define PTR_SUB add 421 # define PTR_SUBI subi 422 # define PTR_SUBU sub /* no u */ 423 # define PTR_SUBIU sub /* no u */ 424 # define PTR_L lw 425 # define PTR_LA la 426 # define PTR_S sw 427 # define PTR_SLL sll 428 # define PTR_SLLV sllv 429 # define PTR_SRL srl 430 # define PTR_SRLV srlv 431 # define PTR_SRA sra 432 # define PTR_SRAV srav 433 434 # define PTR_SCALESHIFT 2 435 #endif 436 437 #if (_MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 64 /* o64??? */) \ 438 || _MIPS_SIM == _MIPS_SIM_ABI64 439 # define PTR_ADD dadd 440 # define PTR_ADDI daddi 441 # define PTR_ADDU daddu 442 # define PTR_ADDIU daddiu 443 # define PTR_SUB dadd 444 # define PTR_SUBI dsubi 445 # define PTR_SUBU dsubu 446 # define PTR_SUBIU dsubu 447 # define PTR_L ld 448 # define PTR_LA dla 449 # define PTR_S sd 450 # define PTR_SLL dsll 451 # define PTR_SLLV dsllv 452 # define PTR_SRL dsrl 453 # define PTR_SRLV dsrlv 454 # define PTR_SRA dsra 455 # define PTR_SRAV dsrav 456 457 # define PTR_SCALESHIFT 3 458 #endif 459 460 /* 461 * Some cp0 registers were extended to 64bit for MIPS III. 462 */ 463 #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ 464 (_MIPS_ISA == _MIPS_ISA_MIPS32) 465 # define MFC0 mfc0 466 # define MTC0 mtc0 467 #endif 468 #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ 469 (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) 470 # define MFC0 dmfc0 471 # define MTC0 dmtc0 472 #endif 473 474 /* The MIPS archtectures do not have a uniform memory model. Particular 475 platforms may provide additional guarantees - for instance, the R4000 476 LL and SC instructions implicitly perform a SYNC, and the 4K promises 477 strong ordering. 478 479 However, in the absence of those guarantees, we must assume weak ordering 480 and SYNC explicitly where necessary. 481 482 Some obsolete MIPS processors may not support the SYNC instruction. This 483 applies to "true" MIPS I processors; most of the processors which compile 484 using MIPS I implement parts of MIPS II. */ 485 486 #ifndef MIPS_SYNC 487 # define MIPS_SYNC sync 488 #endif 489 490 #endif /* sys/asm.h */ 491