asm.h revision 178172
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 178172 2008-04-13 07:27:37Z 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#ifndef NO_REG_DEFS 60#include <machine/regdef.h> 61#endif 62#include <machine/endian.h> 63 64#undef __FBSDID 65#if !defined(lint) && !defined(STRIP_FBSDID) 66#define __FBSDID(s) .ident s 67#else 68#define __FBSDID(s) /* nothing */ 69#endif 70 71/* 72 * Define -pg profile entry code. 73 * Must always be noreorder, must never use a macro instruction 74 * Final addiu to t9 must always equal the size of this _KERN_MCOUNT 75 */ 76#define _KERN_MCOUNT \ 77 .set push; \ 78 .set noreorder; \ 79 .set noat; \ 80 subu sp,sp,16; \ 81 sw t9,12(sp); \ 82 move AT,ra; \ 83 lui t9,%hi(_mcount); \ 84 addiu t9,t9,%lo(_mcount); \ 85 jalr t9; \ 86 nop; \ 87 lw t9,4(sp); \ 88 addiu sp,sp,8; \ 89 addiu t9,t9,40; \ 90 .set pop; 91 92#ifdef GPROF 93#define MCOUNT _KERN_MCOUNT 94#else 95#define MCOUNT 96#endif 97 98#define _C_LABEL(x) x 99 100/* 101 * Endian-independent assembly-code aliases for unaligned memory accesses. 102 */ 103#if BYTE_ORDER == LITTLE_ENDIAN 104#define LWLO lwl 105#define LWHI lwr 106#define SWLO swl 107#define SWHI swr 108#endif 109 110#if BYTE_ORDER == BIG_ENDIAN 111#define LWLO lwr 112#define LWHI lwl 113#define SWLO swr 114#define SWHI swl 115#endif 116 117#ifdef USE_AENT 118#define AENT(x) \ 119 .aent x, 0 120#else 121#define AENT(x) 122#endif 123 124/* 125 * WARN_REFERENCES: create a warning if the specified symbol is referenced 126 */ 127#define WARN_REFERENCES(_sym,_msg) \ 128 .section .gnu.warning. ## _sym ; .ascii _msg ; .text 129 130/* 131 * These are temp registers whose names can be used in either the old 132 * or new ABI, although they map to different physical registers. In 133 * the old ABI, they map to t4-t7, and in the new ABI, they map to a4-a7. 134 * 135 * Because they overlap with the last 4 arg regs in the new ABI, ta0-ta3 136 * should be used only when we need more than t0-t3. 137 */ 138#if defined(__mips_n32) || defined(__mips_n64) 139#define ta0 $8 140#define ta1 $9 141#define ta2 $10 142#define ta3 $11 143#else 144#define ta0 $12 145#define ta1 $13 146#define ta2 $14 147#define ta3 $15 148#endif /* __mips_n32 || __mips_n64 */ 149 150#ifdef __ELF__ 151# define _C_LABEL(x) x 152#else 153# define _C_LABEL(x) _ ## x 154#endif 155 156/* 157 * WEAK_ALIAS: create a weak alias. 158 */ 159#define WEAK_ALIAS(alias,sym) \ 160 .weak alias; \ 161 alias = sym 162 163/* 164 * STRONG_ALIAS: create a strong alias. 165 */ 166#define STRONG_ALIAS(alias,sym) \ 167 .globl alias; \ 168 alias = sym 169 170#define GLOBAL(sym) \ 171 .globl sym; sym: 172 173#define ENTRY(sym) \ 174 .text; .globl sym; .ent sym; sym: 175 176#define ASM_ENTRY(sym) \ 177 .text; .globl sym; .type sym,@function; sym: 178 179/* 180 * LEAF 181 * A leaf routine does 182 * - call no other function, 183 * - never use any register that callee-saved (S0-S8), and 184 * - not use any local stack storage. 185 */ 186#define LEAF(x) \ 187 .globl _C_LABEL(x); \ 188 .ent _C_LABEL(x), 0; \ 189_C_LABEL(x): ; \ 190 .frame sp, 0, ra; \ 191 MCOUNT 192 193/* 194 * LEAF_NOPROFILE 195 * No profilable leaf routine. 196 */ 197#define LEAF_NOPROFILE(x) \ 198 .globl _C_LABEL(x); \ 199 .ent _C_LABEL(x), 0; \ 200_C_LABEL(x): ; \ 201 .frame sp, 0, ra 202 203/* 204 * XLEAF 205 * declare alternate entry to leaf routine 206 */ 207#define XLEAF(x) \ 208 .globl _C_LABEL(x); \ 209 AENT (_C_LABEL(x)); \ 210_C_LABEL(x): 211 212/* 213 * NESTED 214 * A function calls other functions and needs 215 * therefore stack space to save/restore registers. 216 */ 217#define NESTED(x, fsize, retpc) \ 218 .globl _C_LABEL(x); \ 219 .ent _C_LABEL(x), 0; \ 220_C_LABEL(x): ; \ 221 .frame sp, fsize, retpc; \ 222 MCOUNT 223 224/* 225 * NESTED_NOPROFILE(x) 226 * No profilable nested routine. 227 */ 228#define NESTED_NOPROFILE(x, fsize, retpc) \ 229 .globl _C_LABEL(x); \ 230 .ent _C_LABEL(x), 0; \ 231_C_LABEL(x): ; \ 232 .frame sp, fsize, retpc 233 234/* 235 * XNESTED 236 * declare alternate entry point to nested routine. 237 */ 238#define XNESTED(x) \ 239 .globl _C_LABEL(x); \ 240 AENT (_C_LABEL(x)); \ 241_C_LABEL(x): 242 243/* 244 * END 245 * Mark end of a procedure. 246 */ 247#define END(x) \ 248 .end _C_LABEL(x) 249 250/* 251 * IMPORT -- import external symbol 252 */ 253#define IMPORT(sym, size) \ 254 .extern _C_LABEL(sym),size 255 256/* 257 * EXPORT -- export definition of symbol 258 */ 259#define EXPORT(x) \ 260 .globl _C_LABEL(x); \ 261_C_LABEL(x): 262 263/* 264 * VECTOR 265 * exception vector entrypoint 266 * XXX: regmask should be used to generate .mask 267 */ 268#define VECTOR(x, regmask) \ 269 .ent _C_LABEL(x),0; \ 270 EXPORT(x); \ 271 272#define VECTOR_END(x) \ 273 EXPORT(x ## End); \ 274 END(x) 275 276#define KSEG0TEXT_START 277#define KSEG0TEXT_END 278#define KSEG0TEXT .text 279 280/* 281 * Macros to panic and printf from assembly language. 282 */ 283#define PANIC(msg) \ 284 la a0, 9f; \ 285 jal _C_LABEL(panic); \ 286 nop; \ 287 MSG(msg) 288 289#define PANIC_KSEG0(msg, reg) PANIC(msg) 290 291#define PRINTF(msg) \ 292 la a0, 9f; \ 293 jal _C_LABEL(printf); \ 294 nop; \ 295 MSG(msg) 296 297#define MSG(msg) \ 298 .rdata; \ 2999: .asciiz msg; \ 300 .text 301 302#define ASMSTR(str) \ 303 .asciiz str; \ 304 .align 3 305 306/* 307 * Call ast if required 308 */ 309#define DO_AST \ 31044: \ 311 la s0, _C_LABEL(disableintr) ;\ 312 jalr s0 ;\ 313 nop ;\ 314 GET_CPU_PCPU(s1) ;\ 315 lw s3, PC_CURPCB(s1) ;\ 316 lw s1, PC_CURTHREAD(s1) ;\ 317 lw s2, TD_FLAGS(s1) ;\ 318 li s0, TDF_ASTPENDING | TDF_NEEDRESCHED;\ 319 and s2, s0 ;\ 320 la s0, _C_LABEL(enableintr) ;\ 321 jalr s0 ;\ 322 nop ;\ 323 beq s2, zero, 4f ;\ 324 nop ;\ 325 la s0, _C_LABEL(ast) ;\ 326 jalr s0 ;\ 327 addu a0, s3, U_PCB_REGS ;\ 328 j 44b ;\ 329 nop ;\ 3304: 331 332 333/* 334 * XXX retain dialects XXX 335 */ 336#define ALEAF(x) XLEAF(x) 337#define NLEAF(x) LEAF_NOPROFILE(x) 338#define NON_LEAF(x, fsize, retpc) NESTED(x, fsize, retpc) 339#define NNON_LEAF(x, fsize, retpc) NESTED_NOPROFILE(x, fsize, retpc) 340 341/* 342 * standard callframe { 343 * register_t cf_args[4]; arg0 - arg3 344 * register_t cf_sp; frame pointer 345 * register_t cf_ra; return address 346 * }; 347 */ 348#define CALLFRAME_SIZ (4 * (4 + 2)) 349#define CALLFRAME_SP (4 * 4) 350#define CALLFRAME_RA (4 * 5) 351#define START_FRAME CALLFRAME_SIZ 352 353/* 354 * While it would be nice to be compatible with the SGI 355 * REG_L and REG_S macros, because they do not take parameters, it 356 * is impossible to use them with the _MIPS_SIM_ABIX32 model. 357 * 358 * These macros hide the use of mips3 instructions from the 359 * assembler to prevent the assembler from generating 64-bit style 360 * ABI calls. 361 */ 362 363#if !defined(_MIPS_BSD_API) || _MIPS_BSD_API == _MIPS_BSD_API_LP32 364#define REG_L lw 365#define REG_S sw 366#define REG_LI li 367#define REG_PROLOGUE .set push 368#define REG_EPILOGUE .set pop 369#define SZREG 4 370#else 371#define REG_L ld 372#define REG_S sd 373#define REG_LI dli 374#define REG_PROLOGUE .set push ; .set mips3 375#define REG_EPILOGUE .set pop 376#define SZREG 8 377#endif /* _MIPS_BSD_API */ 378 379#define mfc0_macro(data, spr) \ 380 __asm __volatile ("mfc0 %0, $%1" \ 381 : "=r" (data) /* outputs */ \ 382 : "i" (spr)); /* inputs */ 383 384#define mtc0_macro(data, spr) \ 385 __asm __volatile ("mtc0 %0, $%1" \ 386 : /* outputs */ \ 387 : "r" (data), "i" (spr)); /* inputs */ 388 389#define cfc0_macro(data, spr) \ 390 __asm __volatile ("cfc0 %0, $%1" \ 391 : "=r" (data) /* outputs */ \ 392 : "i" (spr)); /* inputs */ 393 394#define ctc0_macro(data, spr) \ 395 __asm __volatile ("ctc0 %0, $%1" \ 396 : /* outputs */ \ 397 : "r" (data), "i" (spr)); /* inputs */ 398 399 400#define lbu_macro(data, addr) \ 401 __asm __volatile ("lbu %0, 0x0(%1)" \ 402 : "=r" (data) /* outputs */ \ 403 : "r" (addr)); /* inputs */ 404 405#define lb_macro(data, addr) \ 406 __asm __volatile ("lb %0, 0x0(%1)" \ 407 : "=r" (data) /* outputs */ \ 408 : "r" (addr)); /* inputs */ 409 410#define lwl_macro(data, addr) \ 411 __asm __volatile ("lwl %0, 0x0(%1)" \ 412 : "=r" (data) /* outputs */ \ 413 : "r" (addr)); /* inputs */ 414 415#define lwr_macro(data, addr) \ 416 __asm __volatile ("lwr %0, 0x0(%1)" \ 417 : "=r" (data) /* outputs */ \ 418 : "r" (addr)); /* inputs */ 419 420#define ldl_macro(data, addr) \ 421 __asm __volatile ("ldl %0, 0x0(%1)" \ 422 : "=r" (data) /* outputs */ \ 423 : "r" (addr)); /* inputs */ 424 425#define ldr_macro(data, addr) \ 426 __asm __volatile ("ldr %0, 0x0(%1)" \ 427 : "=r" (data) /* outputs */ \ 428 : "r" (addr)); /* inputs */ 429 430#define sb_macro(data, addr) \ 431 __asm __volatile ("sb %0, 0x0(%1)" \ 432 : /* outputs */ \ 433 : "r" (data), "r" (addr)); /* inputs */ 434 435#define swl_macro(data, addr) \ 436 __asm __volatile ("swl %0, 0x0(%1)" \ 437 : /* outputs */ \ 438 : "r" (data), "r" (addr)); /* inputs */ 439 440#define swr_macro(data, addr) \ 441 __asm __volatile ("swr %0, 0x0(%1)" \ 442 : /* outputs */ \ 443 : "r" (data), "r" (addr)); /* inputs */ 444 445#define sdl_macro(data, addr) \ 446 __asm __volatile ("sdl %0, 0x0(%1)" \ 447 : /* outputs */ \ 448 : "r" (data), "r" (addr)); /* inputs */ 449 450#define sdr_macro(data, addr) \ 451 __asm __volatile ("sdr %0, 0x0(%1)" \ 452 : /* outputs */ \ 453 : "r" (data), "r" (addr)); /* inputs */ 454 455#define mfgr_macro(data, gr) \ 456 __asm __volatile ("move %0, $%1" \ 457 : "=r" (data) /* outputs */ \ 458 : "i" (gr)); /* inputs */ 459 460#define dmfc0_macro(data, spr) \ 461 __asm __volatile ("dmfc0 %0, $%1" \ 462 : "=r" (data) /* outputs */ \ 463 : "i" (spr)); /* inputs */ 464 465#define dmtc0_macro(data, spr, sel) \ 466 __asm __volatile ("dmtc0 %0, $%1, %2" \ 467 : /* no outputs */ \ 468 : "r" (data), "i" (spr), "i" (sel)); /* inputs */ 469 470/* 471 * The DYNAMIC_STATUS_MASK option adds an additional masking operation 472 * when updating the hardware interrupt mask in the status register. 473 * 474 * This is useful for platforms that need to at run-time mask 475 * interrupts based on motherboard configuration or to handle 476 * slowly clearing interrupts. 477 * 478 * XXX this is only currently implemented for mips3. 479 */ 480#ifdef MIPS_DYNAMIC_STATUS_MASK 481#define DYNAMIC_STATUS_MASK(sr,scratch) \ 482 lw scratch, mips_dynamic_status_mask; \ 483 and sr, sr, scratch 484 485#define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1) \ 486 ori sr, (MIPS_INT_MASK | MIPS_SR_INT_IE); \ 487 DYNAMIC_STATUS_MASK(sr,scratch1) 488#else 489#define DYNAMIC_STATUS_MASK(sr,scratch) 490#define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1) 491#endif 492 493#ifdef SMP 494 /* 495 * FREEBSD_DEVELOPERS_FIXME 496 * In multiprocessor case, store/retrieve the pcpu structure 497 * address for current CPU in scratch register for fast access. 498 */ 499#error "Write GET_CPU_PCPU for SMP" 500#else 501#define GET_CPU_PCPU(reg) \ 502 lw reg, _C_LABEL(pcpup); 503#endif 504 505/* 506 * Description of the setjmp buffer 507 * 508 * word 0 magic number (dependant on creator) 509 * 1 RA 510 * 2 S0 511 * 3 S1 512 * 4 S2 513 * 5 S3 514 * 6 S4 515 * 7 S5 516 * 8 S6 517 * 9 S7 518 * 10 SP 519 * 11 S8 520 * 12 signal mask (dependant on magic) 521 * 13 (con't) 522 * 14 (con't) 523 * 15 (con't) 524 * 525 * The magic number number identifies the jmp_buf and 526 * how the buffer was created as well as providing 527 * a sanity check 528 * 529 */ 530 531#define _JB_MAGIC__SETJMP 0xBADFACED 532#define _JB_MAGIC_SETJMP 0xFACEDBAD 533 534/* Valid for all jmp_buf's */ 535 536#define _JB_MAGIC 0 537#define _JB_REG_RA 1 538#define _JB_REG_S0 2 539#define _JB_REG_S1 3 540#define _JB_REG_S2 4 541#define _JB_REG_S3 5 542#define _JB_REG_S4 6 543#define _JB_REG_S5 7 544#define _JB_REG_S6 8 545#define _JB_REG_S7 9 546#define _JB_REG_SP 10 547#define _JB_REG_S8 11 548 549/* Only valid with the _JB_MAGIC_SETJMP magic */ 550 551#define _JB_SIGMASK 12 552 553#endif /* !_MACHINE_ASM_H_ */ 554