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