1 /* $NetBSD: asm.h,v 1.29 2000/12/14 21:29:51 jeffs Exp $ */ 2 3 /* 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Ralph Campbell. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)machAsmDefs.h 8.1 (Berkeley) 6/10/93 37 * JNPR: asm.h,v 1.10 2007/08/09 11:23:32 katta 38 */ 39 40 /* 41 * machAsmDefs.h -- 42 * 43 * Macros used when writing assembler programs. 44 * 45 * Copyright (C) 1989 Digital Equipment Corporation. 46 * Permission to use, copy, modify, and distribute this software and 47 * its documentation for any purpose and without fee is hereby granted, 48 * provided that the above copyright notice appears in all copies. 49 * Digital Equipment Corporation makes no representations about the 50 * suitability of this software for any purpose. It is provided "as is" 51 * without express or implied warranty. 52 * 53 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsmDefs.h, 54 * v 1.2 89/08/15 18:28:24 rab Exp SPRITE (DECWRL) 55 */ 56 57 #ifndef _MACHINE_ASM_H_ 58 #define _MACHINE_ASM_H_ 59 60 #include <machine/abi.h> 61 #include <machine/regdef.h> 62 #include <machine/endian.h> 63 #include <machine/cdefs.h> 64 65 #undef __FBSDID 66 #if !defined(lint) && !defined(STRIP_FBSDID) 67 #define __FBSDID(s) .ident s 68 #else 69 #define __FBSDID(s) /* nothing */ 70 #endif 71 72 /* 73 * Define -pg profile entry code. 74 * Must always be noreorder, must never use a macro instruction 75 * Final addiu to t9 must always equal the size of this _KERN_MCOUNT 76 */ 77 #define _KERN_MCOUNT \ 78 .set push; \ 79 .set noreorder; \ 80 .set noat; \ 81 subu sp,sp,16; \ 82 sw t9,12(sp); \ 83 move AT,ra; \ 84 lui t9,%hi(_mcount); \ 85 addiu t9,t9,%lo(_mcount); \ 86 jalr t9; \ 87 nop; \ 88 lw t9,4(sp); \ 89 addiu sp,sp,8; \ 90 addiu t9,t9,40; \ 91 .set pop; 92 93 #ifdef GPROF 94 #define MCOUNT _KERN_MCOUNT 95 #else 96 #define MCOUNT 97 #endif 98 99 #define _C_LABEL(x) x 100 101 #ifdef USE_AENT 102 #define AENT(x) \ 103 .aent x, 0 104 #else 105 #define AENT(x) 106 #endif 107 108 /* 109 * WARN_REFERENCES: create a warning if the specified symbol is referenced 110 */ 111 #define WARN_REFERENCES(_sym,_msg) \ 112 .section .gnu.warning. ## _sym ; .ascii _msg ; .text 113 114 #ifdef __ELF__ 115 # define _C_LABEL(x) x 116 #else 117 # define _C_LABEL(x) _ ## x 118 #endif 119 120 /* 121 * WEAK_ALIAS: create a weak alias. 122 */ 123 #define WEAK_ALIAS(alias,sym) \ 124 .weak alias; \ 125 alias = sym 126 127 /* 128 * STRONG_ALIAS: create a strong alias. 129 */ 130 #define STRONG_ALIAS(alias,sym) \ 131 .globl alias; \ 132 alias = sym 133 134 #define GLOBAL(sym) \ 135 .globl sym; sym: 136 137 #define ENTRY(sym) \ 138 .text; .globl sym; .ent sym; sym: 139 140 #define ASM_ENTRY(sym) \ 141 .text; .globl sym; .type sym,@function; sym: 142 143 /* 144 * LEAF 145 * A leaf routine does 146 * - call no other function, 147 * - never use any register that callee-saved (S0-S8), and 148 * - not use any local stack storage. 149 */ 150 #define LEAF(x) \ 151 .globl _C_LABEL(x); \ 152 .ent _C_LABEL(x), 0; \ 153 _C_LABEL(x): ; \ 154 .frame sp, 0, ra; \ 155 MCOUNT 156 157 /* 158 * LEAF_NOPROFILE 159 * No profilable leaf routine. 160 */ 161 #define LEAF_NOPROFILE(x) \ 162 .globl _C_LABEL(x); \ 163 .ent _C_LABEL(x), 0; \ 164 _C_LABEL(x): ; \ 165 .frame sp, 0, ra 166 167 /* 168 * XLEAF 169 * declare alternate entry to leaf routine 170 */ 171 #define XLEAF(x) \ 172 .globl _C_LABEL(x); \ 173 AENT (_C_LABEL(x)); \ 174 _C_LABEL(x): 175 176 /* 177 * NESTED 178 * A function calls other functions and needs 179 * therefore stack space to save/restore registers. 180 */ 181 #define NESTED(x, fsize, retpc) \ 182 .globl _C_LABEL(x); \ 183 .ent _C_LABEL(x), 0; \ 184 _C_LABEL(x): ; \ 185 .frame sp, fsize, retpc; \ 186 MCOUNT 187 188 /* 189 * NESTED_NOPROFILE(x) 190 * No profilable nested routine. 191 */ 192 #define NESTED_NOPROFILE(x, fsize, retpc) \ 193 .globl _C_LABEL(x); \ 194 .ent _C_LABEL(x), 0; \ 195 _C_LABEL(x): ; \ 196 .frame sp, fsize, retpc 197 198 /* 199 * XNESTED 200 * declare alternate entry point to nested routine. 201 */ 202 #define XNESTED(x) \ 203 .globl _C_LABEL(x); \ 204 AENT (_C_LABEL(x)); \ 205 _C_LABEL(x): 206 207 /* 208 * END 209 * Mark end of a procedure. 210 */ 211 #define END(x) \ 212 .end _C_LABEL(x) 213 214 /* 215 * IMPORT -- import external symbol 216 */ 217 #define IMPORT(sym, size) \ 218 .extern _C_LABEL(sym),size 219 220 /* 221 * EXPORT -- export definition of symbol 222 */ 223 #define EXPORT(x) \ 224 .globl _C_LABEL(x); \ 225 _C_LABEL(x): 226 227 /* 228 * VECTOR 229 * exception vector entrypoint 230 * XXX: regmask should be used to generate .mask 231 */ 232 #define VECTOR(x, regmask) \ 233 .ent _C_LABEL(x),0; \ 234 EXPORT(x); \ 235 236 #define VECTOR_END(x) \ 237 EXPORT(x ## End); \ 238 END(x) 239 240 /* 241 * Macros to panic and printf from assembly language. 242 */ 243 #define PANIC(msg) \ 244 PTR_LA a0, 9f; \ 245 jal _C_LABEL(panic); \ 246 nop; \ 247 MSG(msg) 248 249 #define PANIC_KSEG0(msg, reg) PANIC(msg) 250 251 #define PRINTF(msg) \ 252 PTR_LA a0, 9f; \ 253 jal _C_LABEL(printf); \ 254 nop; \ 255 MSG(msg) 256 257 #define MSG(msg) \ 258 .rdata; \ 259 9: .asciiz msg; \ 260 .text 261 262 #define ASMSTR(str) \ 263 .asciiz str; \ 264 .align 3 265 266 #if defined(__mips_o32) || defined(__mips_o64) 267 #define ALSK 7 /* stack alignment */ 268 #define ALMASK -7 /* stack alignment */ 269 #define SZFPREG 4 270 #define FP_L lwc1 271 #define FP_S swc1 272 #else 273 #define ALSK 15 /* stack alignment */ 274 #define ALMASK -15 /* stack alignment */ 275 #define SZFPREG 8 276 #define FP_L ldc1 277 #define FP_S sdc1 278 #endif 279 280 /* 281 * Endian-independent assembly-code aliases for unaligned memory accesses. 282 */ 283 #if _BYTE_ORDER == _LITTLE_ENDIAN 284 # define LWHI lwr 285 # define LWLO lwl 286 # define SWHI swr 287 # define SWLO swl 288 # if SZREG == 4 289 # define REG_LHI lwr 290 # define REG_LLO lwl 291 # define REG_SHI swr 292 # define REG_SLO swl 293 # else 294 # define REG_LHI ldr 295 # define REG_LLO ldl 296 # define REG_SHI sdr 297 # define REG_SLO sdl 298 # endif 299 #endif 300 301 #if _BYTE_ORDER == _BIG_ENDIAN 302 # define LWHI lwl 303 # define LWLO lwr 304 # define SWHI swl 305 # define SWLO swr 306 # if SZREG == 4 307 # define REG_LHI lwl 308 # define REG_LLO lwr 309 # define REG_SHI swl 310 # define REG_SLO swr 311 # else 312 # define REG_LHI ldl 313 # define REG_LLO ldr 314 # define REG_SHI sdl 315 # define REG_SLO sdr 316 # endif 317 #endif 318 319 /* 320 * While it would be nice to be compatible with the SGI 321 * REG_L and REG_S macros, because they do not take parameters, it 322 * is impossible to use them with the _MIPS_SIM_ABIX32 model. 323 * 324 * These macros hide the use of mips3 instructions from the 325 * assembler to prevent the assembler from generating 64-bit style 326 * ABI calls. 327 */ 328 #if _MIPS_SZPTR == 32 329 #define PTR_ADD add 330 #define PTR_ADDI addi 331 #define PTR_ADDU addu 332 #define PTR_ADDIU addiu 333 #define PTR_SUB add 334 #define PTR_SUBI subi 335 #define PTR_SUBU subu 336 #define PTR_SUBIU subu 337 #define PTR_L lw 338 #define PTR_LA la 339 #define PTR_LI li 340 #define PTR_S sw 341 #define PTR_SLL sll 342 #define PTR_SLLV sllv 343 #define PTR_SRL srl 344 #define PTR_SRLV srlv 345 #define PTR_SRA sra 346 #define PTR_SRAV srav 347 #define PTR_LL ll 348 #define PTR_SC sc 349 #define PTR_WORD .word 350 #define PTR_SCALESHIFT 2 351 #else /* _MIPS_SZPTR == 64 */ 352 #define PTR_ADD dadd 353 #define PTR_ADDI daddi 354 #define PTR_ADDU daddu 355 #define PTR_ADDIU daddiu 356 #define PTR_SUB dadd 357 #define PTR_SUBI dsubi 358 #define PTR_SUBU dsubu 359 #define PTR_SUBIU dsubu 360 #define PTR_L ld 361 #define PTR_LA dla 362 #define PTR_LI dli 363 #define PTR_S sd 364 #define PTR_SLL dsll 365 #define PTR_SLLV dsllv 366 #define PTR_SRL dsrl 367 #define PTR_SRLV dsrlv 368 #define PTR_SRA dsra 369 #define PTR_SRAV dsrav 370 #define PTR_LL lld 371 #define PTR_SC scd 372 #define PTR_WORD .dword 373 #define PTR_SCALESHIFT 3 374 #endif /* _MIPS_SZPTR == 64 */ 375 376 #if _MIPS_SZINT == 32 377 #define INT_ADD add 378 #define INT_ADDI addi 379 #define INT_ADDU addu 380 #define INT_ADDIU addiu 381 #define INT_SUB add 382 #define INT_SUBI subi 383 #define INT_SUBU subu 384 #define INT_SUBIU subu 385 #define INT_L lw 386 #define INT_LA la 387 #define INT_S sw 388 #define INT_SLL sll 389 #define INT_SLLV sllv 390 #define INT_SRL srl 391 #define INT_SRLV srlv 392 #define INT_SRA sra 393 #define INT_SRAV srav 394 #define INT_LL ll 395 #define INT_SC sc 396 #define INT_WORD .word 397 #define INT_SCALESHIFT 2 398 #else 399 #define INT_ADD dadd 400 #define INT_ADDI daddi 401 #define INT_ADDU daddu 402 #define INT_ADDIU daddiu 403 #define INT_SUB dadd 404 #define INT_SUBI dsubi 405 #define INT_SUBU dsubu 406 #define INT_SUBIU dsubu 407 #define INT_L ld 408 #define INT_LA dla 409 #define INT_S sd 410 #define INT_SLL dsll 411 #define INT_SLLV dsllv 412 #define INT_SRL dsrl 413 #define INT_SRLV dsrlv 414 #define INT_SRA dsra 415 #define INT_SRAV dsrav 416 #define INT_LL lld 417 #define INT_SC scd 418 #define INT_WORD .dword 419 #define INT_SCALESHIFT 3 420 #endif 421 422 #if _MIPS_SZLONG == 32 423 #define LONG_ADD add 424 #define LONG_ADDI addi 425 #define LONG_ADDU addu 426 #define LONG_ADDIU addiu 427 #define LONG_SUB add 428 #define LONG_SUBI subi 429 #define LONG_SUBU subu 430 #define LONG_SUBIU subu 431 #define LONG_L lw 432 #define LONG_LA la 433 #define LONG_S sw 434 #define LONG_SLL sll 435 #define LONG_SLLV sllv 436 #define LONG_SRL srl 437 #define LONG_SRLV srlv 438 #define LONG_SRA sra 439 #define LONG_SRAV srav 440 #define LONG_LL ll 441 #define LONG_SC sc 442 #define LONG_WORD .word 443 #define LONG_SCALESHIFT 2 444 #else 445 #define LONG_ADD dadd 446 #define LONG_ADDI daddi 447 #define LONG_ADDU daddu 448 #define LONG_ADDIU daddiu 449 #define LONG_SUB dadd 450 #define LONG_SUBI dsubi 451 #define LONG_SUBU dsubu 452 #define LONG_SUBIU dsubu 453 #define LONG_L ld 454 #define LONG_LA dla 455 #define LONG_S sd 456 #define LONG_SLL dsll 457 #define LONG_SLLV dsllv 458 #define LONG_SRL dsrl 459 #define LONG_SRLV dsrlv 460 #define LONG_SRA dsra 461 #define LONG_SRAV dsrav 462 #define LONG_LL lld 463 #define LONG_SC scd 464 #define LONG_WORD .dword 465 #define LONG_SCALESHIFT 3 466 #endif 467 468 #if SZREG == 4 469 #define REG_L lw 470 #define REG_S sw 471 #define REG_LI li 472 #define REG_ADDU addu 473 #define REG_SLL sll 474 #define REG_SLLV sllv 475 #define REG_SRL srl 476 #define REG_SRLV srlv 477 #define REG_SRA sra 478 #define REG_SRAV srav 479 #define REG_LL ll 480 #define REG_SC sc 481 #define REG_SCALESHIFT 2 482 #else 483 #define REG_L ld 484 #define REG_S sd 485 #define REG_LI dli 486 #define REG_ADDU daddu 487 #define REG_SLL dsll 488 #define REG_SLLV dsllv 489 #define REG_SRL dsrl 490 #define REG_SRLV dsrlv 491 #define REG_SRA dsra 492 #define REG_SRAV dsrav 493 #define REG_LL lld 494 #define REG_SC scd 495 #define REG_SCALESHIFT 3 496 #endif 497 498 #if _MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \ 499 _MIPS_ISA == _MIPS_ISA_MIPS32 500 #define MFC0 mfc0 501 #define MTC0 mtc0 502 #endif 503 #if _MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \ 504 _MIPS_ISA == _MIPS_ISA_MIPS64 505 #define MFC0 dmfc0 506 #define MTC0 dmtc0 507 #endif 508 509 #if defined(__mips_o32) || defined(__mips_o64) 510 511 #ifdef __ABICALLS__ 512 #define CPRESTORE(r) .cprestore r 513 #define CPLOAD(r) .cpload r 514 #else 515 #define CPRESTORE(r) /* not needed */ 516 #define CPLOAD(r) /* not needed */ 517 #endif 518 519 #define SETUP_GP \ 520 .set push; \ 521 .set noreorder; \ 522 .cpload t9; \ 523 .set pop 524 #define SETUP_GPX(r) \ 525 .set push; \ 526 .set noreorder; \ 527 move r,ra; /* save old ra */ \ 528 bal 7f; \ 529 nop; \ 530 7: .cpload ra; \ 531 move ra,r; \ 532 .set pop 533 #define SETUP_GPX_L(r,lbl) \ 534 .set push; \ 535 .set noreorder; \ 536 move r,ra; /* save old ra */ \ 537 bal lbl; \ 538 nop; \ 539 lbl: .cpload ra; \ 540 move ra,r; \ 541 .set pop 542 #define SAVE_GP(x) .cprestore x 543 544 #define SETUP_GP64(a,b) /* n32/n64 specific */ 545 #define SETUP_GP64_R(a,b) /* n32/n64 specific */ 546 #define SETUP_GPX64(a,b) /* n32/n64 specific */ 547 #define SETUP_GPX64_L(a,b,c) /* n32/n64 specific */ 548 #define RESTORE_GP64 /* n32/n64 specific */ 549 #define USE_ALT_CP(a) /* n32/n64 specific */ 550 #endif /* __mips_o32 || __mips_o64 */ 551 552 #if defined(__mips_o32) || defined(__mips_o64) 553 #define REG_PROLOGUE .set push 554 #define REG_EPILOGUE .set pop 555 #endif 556 #if defined(__mips_n32) || defined(__mips_n64) 557 #define REG_PROLOGUE .set push ; .set mips3 558 #define REG_EPILOGUE .set pop 559 #endif 560 561 #if defined(__mips_n32) || defined(__mips_n64) 562 #define SETUP_GP /* o32 specific */ 563 #define SETUP_GPX(r) /* o32 specific */ 564 #define SETUP_GPX_L(r,lbl) /* o32 specific */ 565 #define SAVE_GP(x) /* o32 specific */ 566 #define SETUP_GP64(a,b) .cpsetup $25, a, b 567 #define SETUP_GPX64(a,b) \ 568 .set push; \ 569 move b,ra; \ 570 .set noreorder; \ 571 bal 7f; \ 572 nop; \ 573 7: .set pop; \ 574 .cpsetup ra, a, 7b; \ 575 move ra,b 576 #define SETUP_GPX64_L(a,b,c) \ 577 .set push; \ 578 move b,ra; \ 579 .set noreorder; \ 580 bal c; \ 581 nop; \ 582 c: .set pop; \ 583 .cpsetup ra, a, c; \ 584 move ra,b 585 #define RESTORE_GP64 .cpreturn 586 #define USE_ALT_CP(a) .cplocal a 587 #endif /* __mips_n32 || __mips_n64 */ 588 589 #define GET_CPU_PCPU(reg) \ 590 PTR_L reg, _C_LABEL(pcpup); 591 592 /* 593 * Description of the setjmp buffer 594 * 595 * word 0 magic number (dependant on creator) 596 * 1 RA 597 * 2 S0 598 * 3 S1 599 * 4 S2 600 * 5 S3 601 * 6 S4 602 * 7 S5 603 * 8 S6 604 * 9 S7 605 * 10 SP 606 * 11 S8 607 * 12 GP (dependent on ABI) 608 * 13 signal mask (dependant on magic) 609 * 14 (con't) 610 * 15 (con't) 611 * 16 (con't) 612 * 613 * The magic number number identifies the jmp_buf and 614 * how the buffer was created as well as providing 615 * a sanity check 616 * 617 */ 618 619 #define _JB_MAGIC__SETJMP 0xBADFACED 620 #define _JB_MAGIC_SETJMP 0xFACEDBAD 621 622 /* Valid for all jmp_buf's */ 623 624 #define _JB_MAGIC 0 625 #define _JB_REG_RA 1 626 #define _JB_REG_S0 2 627 #define _JB_REG_S1 3 628 #define _JB_REG_S2 4 629 #define _JB_REG_S3 5 630 #define _JB_REG_S4 6 631 #define _JB_REG_S5 7 632 #define _JB_REG_S6 8 633 #define _JB_REG_S7 9 634 #define _JB_REG_SP 10 635 #define _JB_REG_S8 11 636 #if defined(__mips_n32) || defined(__mips_n64) 637 #define _JB_REG_GP 12 638 #endif 639 640 /* Only valid with the _JB_MAGIC_SETJMP magic */ 641 642 #define _JB_SIGMASK 13 643 #define __JB_SIGMASK_REMAINDER 14 /* sigmask_t is 128-bits */ 644 645 #define _JB_FPREG_F20 15 646 #define _JB_FPREG_F21 16 647 #define _JB_FPREG_F22 17 648 #define _JB_FPREG_F23 18 649 #define _JB_FPREG_F24 19 650 #define _JB_FPREG_F25 20 651 #define _JB_FPREG_F26 21 652 #define _JB_FPREG_F27 22 653 #define _JB_FPREG_F28 23 654 #define _JB_FPREG_F29 24 655 #define _JB_FPREG_F30 25 656 #define _JB_FPREG_F31 26 657 #define _JB_FPREG_FCSR 27 658 659 /* 660 * Various macros for dealing with TLB hazards 661 * (a) why so many? 662 * (b) when to use? 663 * (c) why not used everywhere? 664 */ 665 /* 666 * Assume that w alaways need nops to escape CP0 hazard 667 * TODO: Make hazard delays configurable. Stuck with 5 cycles on the moment 668 * For more info on CP0 hazards see Chapter 7 (p.99) of "MIPS32 Architecture 669 * For Programmers Volume III: The MIPS32 Privileged Resource Architecture" 670 */ 671 #if defined(CPU_NLM) 672 #define HAZARD_DELAY sll $0,3 673 #define ITLBNOPFIX sll $0,3 674 #elif defined(CPU_RMI) 675 #define HAZARD_DELAY 676 #define ITLBNOPFIX 677 #elif defined(CPU_MIPS74K) 678 #define HAZARD_DELAY sll $0,$0,3 679 #define ITLBNOPFIX sll $0,$0,3 680 #else 681 #define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;sll $0,$0,3; 682 #define HAZARD_DELAY nop;nop;nop;nop;sll $0,$0,3; 683 #endif 684 685 #endif /* !_MACHINE_ASM_H_ */ 686