asm.h revision 330897
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 * 4. 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 * $FreeBSD: stable/11/sys/mips/include/asm.h 330897 2018-03-14 03:19:51Z eadler $ 39 */ 40 41/* 42 * machAsmDefs.h -- 43 * 44 * Macros used when writing assembler programs. 45 * 46 * Copyright (C) 1989 Digital Equipment Corporation. 47 * Permission to use, copy, modify, and distribute this software and 48 * its documentation for any purpose and without fee is hereby granted, 49 * provided that the above copyright notice appears in all copies. 50 * Digital Equipment Corporation makes no representations about the 51 * suitability of this software for any purpose. It is provided "as is" 52 * without express or implied warranty. 53 * 54 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsmDefs.h, 55 * v 1.2 89/08/15 18:28:24 rab Exp SPRITE (DECWRL) 56 */ 57 58#ifndef _MACHINE_ASM_H_ 59#define _MACHINE_ASM_H_ 60 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; \ 2599: .asciiz msg; \ 260 .text 261 262#define ASMSTR(str) \ 263 .asciiz str; \ 264 .align 3 265 266#if defined(__mips_o32) 267#define SZREG 4 268#else 269#define SZREG 8 270#endif 271 272#if defined(__mips_o32) || defined(__mips_o64) 273#define ALSK 7 /* stack alignment */ 274#define ALMASK -7 /* stack alignment */ 275#define SZFPREG 4 276#define FP_L lwc1 277#define FP_S swc1 278#else 279#define ALSK 15 /* stack alignment */ 280#define ALMASK -15 /* stack alignment */ 281#define SZFPREG 8 282#define FP_L ldc1 283#define FP_S sdc1 284#endif 285 286/* 287 * standard callframe { 288 * register_t cf_pad[N]; o32/64 (N=0), n32 (N=1) n64 (N=1) 289 * register_t cf_args[4]; arg0 - arg3 (only on o32 and o64) 290 * register_t cf_gp; global pointer (only on n32 and n64) 291 * register_t cf_sp; frame pointer 292 * register_t cf_ra; return address 293 * }; 294 */ 295#if defined(__mips_o32) || defined(__mips_o64) 296#define CALLFRAME_SIZ (SZREG * (4 + 2)) 297#define CALLFRAME_S0 0 298#elif defined(__mips_n32) || defined(__mips_n64) 299#define CALLFRAME_SIZ (SZREG * 4) 300#define CALLFRAME_S0 (CALLFRAME_SIZ - 4 * SZREG) 301#endif 302#ifndef _KERNEL 303#define CALLFRAME_GP (CALLFRAME_SIZ - 3 * SZREG) 304#endif 305#define CALLFRAME_SP (CALLFRAME_SIZ - 2 * SZREG) 306#define CALLFRAME_RA (CALLFRAME_SIZ - 1 * SZREG) 307 308/* 309 * Endian-independent assembly-code aliases for unaligned memory accesses. 310 */ 311#if _BYTE_ORDER == _LITTLE_ENDIAN 312# define LWHI lwr 313# define LWLO lwl 314# define SWHI swr 315# define SWLO swl 316# if SZREG == 4 317# define REG_LHI lwr 318# define REG_LLO lwl 319# define REG_SHI swr 320# define REG_SLO swl 321# else 322# define REG_LHI ldr 323# define REG_LLO ldl 324# define REG_SHI sdr 325# define REG_SLO sdl 326# endif 327#endif 328 329#if _BYTE_ORDER == _BIG_ENDIAN 330# define LWHI lwl 331# define LWLO lwr 332# define SWHI swl 333# define SWLO swr 334# if SZREG == 4 335# define REG_LHI lwl 336# define REG_LLO lwr 337# define REG_SHI swl 338# define REG_SLO swr 339# else 340# define REG_LHI ldl 341# define REG_LLO ldr 342# define REG_SHI sdl 343# define REG_SLO sdr 344# endif 345#endif 346 347/* 348 * While it would be nice to be compatible with the SGI 349 * REG_L and REG_S macros, because they do not take parameters, it 350 * is impossible to use them with the _MIPS_SIM_ABIX32 model. 351 * 352 * These macros hide the use of mips3 instructions from the 353 * assembler to prevent the assembler from generating 64-bit style 354 * ABI calls. 355 */ 356#if _MIPS_SZPTR == 32 357#define PTR_ADD add 358#define PTR_ADDI addi 359#define PTR_ADDU addu 360#define PTR_ADDIU addiu 361#define PTR_SUB add 362#define PTR_SUBI subi 363#define PTR_SUBU subu 364#define PTR_SUBIU subu 365#define PTR_L lw 366#define PTR_LA la 367#define PTR_LI li 368#define PTR_S sw 369#define PTR_SLL sll 370#define PTR_SLLV sllv 371#define PTR_SRL srl 372#define PTR_SRLV srlv 373#define PTR_SRA sra 374#define PTR_SRAV srav 375#define PTR_LL ll 376#define PTR_SC sc 377#define PTR_WORD .word 378#define PTR_SCALESHIFT 2 379#else /* _MIPS_SZPTR == 64 */ 380#define PTR_ADD dadd 381#define PTR_ADDI daddi 382#define PTR_ADDU daddu 383#define PTR_ADDIU daddiu 384#define PTR_SUB dadd 385#define PTR_SUBI dsubi 386#define PTR_SUBU dsubu 387#define PTR_SUBIU dsubu 388#define PTR_L ld 389#define PTR_LA dla 390#define PTR_LI dli 391#define PTR_S sd 392#define PTR_SLL dsll 393#define PTR_SLLV dsllv 394#define PTR_SRL dsrl 395#define PTR_SRLV dsrlv 396#define PTR_SRA dsra 397#define PTR_SRAV dsrav 398#define PTR_LL lld 399#define PTR_SC scd 400#define PTR_WORD .dword 401#define PTR_SCALESHIFT 3 402#endif /* _MIPS_SZPTR == 64 */ 403 404#if _MIPS_SZINT == 32 405#define INT_ADD add 406#define INT_ADDI addi 407#define INT_ADDU addu 408#define INT_ADDIU addiu 409#define INT_SUB add 410#define INT_SUBI subi 411#define INT_SUBU subu 412#define INT_SUBIU subu 413#define INT_L lw 414#define INT_LA la 415#define INT_S sw 416#define INT_SLL sll 417#define INT_SLLV sllv 418#define INT_SRL srl 419#define INT_SRLV srlv 420#define INT_SRA sra 421#define INT_SRAV srav 422#define INT_LL ll 423#define INT_SC sc 424#define INT_WORD .word 425#define INT_SCALESHIFT 2 426#else 427#define INT_ADD dadd 428#define INT_ADDI daddi 429#define INT_ADDU daddu 430#define INT_ADDIU daddiu 431#define INT_SUB dadd 432#define INT_SUBI dsubi 433#define INT_SUBU dsubu 434#define INT_SUBIU dsubu 435#define INT_L ld 436#define INT_LA dla 437#define INT_S sd 438#define INT_SLL dsll 439#define INT_SLLV dsllv 440#define INT_SRL dsrl 441#define INT_SRLV dsrlv 442#define INT_SRA dsra 443#define INT_SRAV dsrav 444#define INT_LL lld 445#define INT_SC scd 446#define INT_WORD .dword 447#define INT_SCALESHIFT 3 448#endif 449 450#if _MIPS_SZLONG == 32 451#define LONG_ADD add 452#define LONG_ADDI addi 453#define LONG_ADDU addu 454#define LONG_ADDIU addiu 455#define LONG_SUB add 456#define LONG_SUBI subi 457#define LONG_SUBU subu 458#define LONG_SUBIU subu 459#define LONG_L lw 460#define LONG_LA la 461#define LONG_S sw 462#define LONG_SLL sll 463#define LONG_SLLV sllv 464#define LONG_SRL srl 465#define LONG_SRLV srlv 466#define LONG_SRA sra 467#define LONG_SRAV srav 468#define LONG_LL ll 469#define LONG_SC sc 470#define LONG_WORD .word 471#define LONG_SCALESHIFT 2 472#else 473#define LONG_ADD dadd 474#define LONG_ADDI daddi 475#define LONG_ADDU daddu 476#define LONG_ADDIU daddiu 477#define LONG_SUB dadd 478#define LONG_SUBI dsubi 479#define LONG_SUBU dsubu 480#define LONG_SUBIU dsubu 481#define LONG_L ld 482#define LONG_LA dla 483#define LONG_S sd 484#define LONG_SLL dsll 485#define LONG_SLLV dsllv 486#define LONG_SRL dsrl 487#define LONG_SRLV dsrlv 488#define LONG_SRA dsra 489#define LONG_SRAV dsrav 490#define LONG_LL lld 491#define LONG_SC scd 492#define LONG_WORD .dword 493#define LONG_SCALESHIFT 3 494#endif 495 496#if SZREG == 4 497#define REG_L lw 498#define REG_S sw 499#define REG_LI li 500#define REG_ADDU addu 501#define REG_SLL sll 502#define REG_SLLV sllv 503#define REG_SRL srl 504#define REG_SRLV srlv 505#define REG_SRA sra 506#define REG_SRAV srav 507#define REG_LL ll 508#define REG_SC sc 509#define REG_SCALESHIFT 2 510#else 511#define REG_L ld 512#define REG_S sd 513#define REG_LI dli 514#define REG_ADDU daddu 515#define REG_SLL dsll 516#define REG_SLLV dsllv 517#define REG_SRL dsrl 518#define REG_SRLV dsrlv 519#define REG_SRA dsra 520#define REG_SRAV dsrav 521#define REG_LL lld 522#define REG_SC scd 523#define REG_SCALESHIFT 3 524#endif 525 526#if _MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \ 527 _MIPS_ISA == _MIPS_ISA_MIPS32 528#define MFC0 mfc0 529#define MTC0 mtc0 530#endif 531#if _MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \ 532 _MIPS_ISA == _MIPS_ISA_MIPS64 533#define MFC0 dmfc0 534#define MTC0 dmtc0 535#endif 536 537#if defined(__mips_o32) || defined(__mips_o64) 538 539#ifdef __ABICALLS__ 540#define CPRESTORE(r) .cprestore r 541#define CPLOAD(r) .cpload r 542#else 543#define CPRESTORE(r) /* not needed */ 544#define CPLOAD(r) /* not needed */ 545#endif 546 547#define SETUP_GP \ 548 .set push; \ 549 .set noreorder; \ 550 .cpload t9; \ 551 .set pop 552#define SETUP_GPX(r) \ 553 .set push; \ 554 .set noreorder; \ 555 move r,ra; /* save old ra */ \ 556 bal 7f; \ 557 nop; \ 558 7: .cpload ra; \ 559 move ra,r; \ 560 .set pop 561#define SETUP_GPX_L(r,lbl) \ 562 .set push; \ 563 .set noreorder; \ 564 move r,ra; /* save old ra */ \ 565 bal lbl; \ 566 nop; \ 567 lbl: .cpload ra; \ 568 move ra,r; \ 569 .set pop 570#define SAVE_GP(x) .cprestore x 571 572#define SETUP_GP64(a,b) /* n32/n64 specific */ 573#define SETUP_GP64_R(a,b) /* n32/n64 specific */ 574#define SETUP_GPX64(a,b) /* n32/n64 specific */ 575#define SETUP_GPX64_L(a,b,c) /* n32/n64 specific */ 576#define RESTORE_GP64 /* n32/n64 specific */ 577#define USE_ALT_CP(a) /* n32/n64 specific */ 578#endif /* __mips_o32 || __mips_o64 */ 579 580#if defined(__mips_o32) || defined(__mips_o64) 581#define REG_PROLOGUE .set push 582#define REG_EPILOGUE .set pop 583#endif 584#if defined(__mips_n32) || defined(__mips_n64) 585#define REG_PROLOGUE .set push ; .set mips3 586#define REG_EPILOGUE .set pop 587#endif 588 589#if defined(__mips_n32) || defined(__mips_n64) 590#define SETUP_GP /* o32 specific */ 591#define SETUP_GPX(r) /* o32 specific */ 592#define SETUP_GPX_L(r,lbl) /* o32 specific */ 593#define SAVE_GP(x) /* o32 specific */ 594#define SETUP_GP64(a,b) .cpsetup $25, a, b 595#define SETUP_GPX64(a,b) \ 596 .set push; \ 597 move b,ra; \ 598 .set noreorder; \ 599 bal 7f; \ 600 nop; \ 601 7: .set pop; \ 602 .cpsetup ra, a, 7b; \ 603 move ra,b 604#define SETUP_GPX64_L(a,b,c) \ 605 .set push; \ 606 move b,ra; \ 607 .set noreorder; \ 608 bal c; \ 609 nop; \ 610 c: .set pop; \ 611 .cpsetup ra, a, c; \ 612 move ra,b 613#define RESTORE_GP64 .cpreturn 614#define USE_ALT_CP(a) .cplocal a 615#endif /* __mips_n32 || __mips_n64 */ 616 617#define GET_CPU_PCPU(reg) \ 618 PTR_L reg, _C_LABEL(pcpup); 619 620/* 621 * Description of the setjmp buffer 622 * 623 * word 0 magic number (dependant on creator) 624 * 1 RA 625 * 2 S0 626 * 3 S1 627 * 4 S2 628 * 5 S3 629 * 6 S4 630 * 7 S5 631 * 8 S6 632 * 9 S7 633 * 10 SP 634 * 11 S8 635 * 12 GP (dependent on ABI) 636 * 13 signal mask (dependant on magic) 637 * 14 (con't) 638 * 15 (con't) 639 * 16 (con't) 640 * 641 * The magic number number identifies the jmp_buf and 642 * how the buffer was created as well as providing 643 * a sanity check 644 * 645 */ 646 647#define _JB_MAGIC__SETJMP 0xBADFACED 648#define _JB_MAGIC_SETJMP 0xFACEDBAD 649 650/* Valid for all jmp_buf's */ 651 652#define _JB_MAGIC 0 653#define _JB_REG_RA 1 654#define _JB_REG_S0 2 655#define _JB_REG_S1 3 656#define _JB_REG_S2 4 657#define _JB_REG_S3 5 658#define _JB_REG_S4 6 659#define _JB_REG_S5 7 660#define _JB_REG_S6 8 661#define _JB_REG_S7 9 662#define _JB_REG_SP 10 663#define _JB_REG_S8 11 664#if defined(__mips_n32) || defined(__mips_n64) 665#define _JB_REG_GP 12 666#endif 667 668/* Only valid with the _JB_MAGIC_SETJMP magic */ 669 670#define _JB_SIGMASK 13 671#define __JB_SIGMASK_REMAINDER 14 /* sigmask_t is 128-bits */ 672 673#define _JB_FPREG_F20 15 674#define _JB_FPREG_F21 16 675#define _JB_FPREG_F22 17 676#define _JB_FPREG_F23 18 677#define _JB_FPREG_F24 19 678#define _JB_FPREG_F25 20 679#define _JB_FPREG_F26 21 680#define _JB_FPREG_F27 22 681#define _JB_FPREG_F28 23 682#define _JB_FPREG_F29 24 683#define _JB_FPREG_F30 25 684#define _JB_FPREG_F31 26 685#define _JB_FPREG_FCSR 27 686 687/* 688 * Various macros for dealing with TLB hazards 689 * (a) why so many? 690 * (b) when to use? 691 * (c) why not used everywhere? 692 */ 693/* 694 * Assume that w alaways need nops to escape CP0 hazard 695 * TODO: Make hazard delays configurable. Stuck with 5 cycles on the moment 696 * For more info on CP0 hazards see Chapter 7 (p.99) of "MIPS32 Architecture 697 * For Programmers Volume III: The MIPS32 Privileged Resource Architecture" 698 */ 699#if defined(CPU_NLM) 700#define HAZARD_DELAY sll $0,3 701#define ITLBNOPFIX sll $0,3 702#elif defined(CPU_RMI) 703#define HAZARD_DELAY 704#define ITLBNOPFIX 705#elif defined(CPU_MIPS74K) 706#define HAZARD_DELAY sll $0,$0,3 707#define ITLBNOPFIX sll $0,$0,3 708#else 709#define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;sll $0,$0,3; 710#define HAZARD_DELAY nop;nop;nop;nop;sll $0,$0,3; 711#endif 712 713#endif /* !_MACHINE_ASM_H_ */ 714