1 /* $NetBSD: asm.h,v 1.77 2025/01/06 10:46:43 martin 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 * 3. 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 */ 36 37 /* 38 * machAsmDefs.h -- 39 * 40 * Macros used when writing assembler programs. 41 * 42 * Copyright (C) 1989 Digital Equipment Corporation. 43 * Permission to use, copy, modify, and distribute this software and 44 * its documentation for any purpose and without fee is hereby granted, 45 * provided that the above copyright notice appears in all copies. 46 * Digital Equipment Corporation makes no representations about the 47 * suitability of this software for any purpose. It is provided "as is" 48 * without express or implied warranty. 49 * 50 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsmDefs.h, 51 * v 1.2 89/08/15 18:28:24 rab Exp SPRITE (DECWRL) 52 */ 53 54 #ifndef _MIPS_ASM_H 55 #define _MIPS_ASM_H 56 57 #include <sys/cdefs.h> /* for API selection */ 58 #include <mips/regdef.h> 59 60 #if defined(_KERNEL_OPT) 61 #include "opt_gprof.h" 62 #include "opt_multiprocessor.h" 63 #endif 64 65 #ifdef __ASSEMBLER__ 66 #define __BIT(n) (1 << (n)) 67 #define __BITS(hi,lo) ((~((~0)<<((hi)+1)))&((~0)<<(lo))) 68 69 #define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) 70 #define __SHIFTOUT(__x, __mask) (((__x) & (__mask)) / __LOWEST_SET_BIT(__mask)) 71 #define __SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask)) 72 #endif /* __ASSEMBLER__ */ 73 74 #ifndef GPROF 75 #define _MIPS_ASM_MCOUNT(x) 76 #else 77 /* 78 * Define -pg profile entry code. 79 * Must always be noreorder, must never use a macro instruction. 80 */ 81 #if defined(__mips_o32) /* Old 32-bit ABI */ 82 /* 83 * The old ABI version must also decrement two less words off the 84 * stack and the final addiu to t9 must always equal the size of this 85 * _MIPS_ASM_MCOUNT. 86 */ 87 #define _MIPS_ASM_MCOUNT(x) \ 88 .set push; \ 89 .set noreorder; \ 90 .set noat; \ 91 subu sp,16; \ 92 sw t9,12(sp); \ 93 move AT,ra; \ 94 lui t9,%hi(_mcount); \ 95 addiu t9,t9,%lo(_mcount); \ 96 jalr t9; \ 97 nop; \ 98 lw t9,4(sp); \ 99 addiu sp,8; \ 100 addiu t9,40; \ 101 .set pop; 102 #elif defined(__mips_o64) /* Old 64-bit ABI */ 103 # error yeahnah 104 #else /* New (n32/n64) ABI */ 105 /* 106 * The new ABI version just needs to put the return address in AT and 107 * call _mcount(). For the no abicalls case, skip the reloc dance. 108 */ 109 #ifdef __mips_abicalls 110 #if defined(__mips_n32) /* n32 */ 111 #define _MIPS_ASM_MCOUNT(x) \ 112 .set push; \ 113 .set noreorder; \ 114 .set noat; \ 115 subu sp,16; \ 116 sw t9,8(sp); \ 117 move AT,ra; \ 118 lui t9,%hi(_mcount); \ 119 addiu t9,t9,%lo(_mcount); \ 120 jalr t9; \ 121 nop; \ 122 lw t9,8(sp); \ 123 addiu sp,16; \ 124 .set pop; 125 #else /* n64 */ 126 #define _MIPS_ASM_MCOUNT(x) \ 127 .set push; \ 128 .set noreorder; \ 129 .set noat; \ 130 dsubu sp,16; \ 131 sd gp,0(sp); \ 132 sd t9,8(sp); \ 133 move AT,ra; \ 134 lui gp,%hi(%neg(%gp_rel(x))); \ 135 daddiu gp,%lo(%neg(%gp_rel(x))); \ 136 daddu gp,gp,t9; \ 137 ld t9,%call16(_mcount)(gp); \ 138 jalr t9; \ 139 nop; \ 140 ld gp,0(sp); \ 141 ld t9,8(sp); \ 142 daddiu sp,16; \ 143 .set pop; 144 #endif 145 #else /* !__mips_abicalls */ 146 #define _MIPS_ASM_MCOUNT(x) \ 147 .set push; \ 148 .set noreorder; \ 149 .set noat; \ 150 move AT,ra; \ 151 jal _mcount; \ 152 nop; \ 153 .set pop; 154 #endif /* !__mips_abicalls */ 155 #endif /* n32/n64 */ 156 #endif /* GPROF */ 157 158 #ifdef USE_AENT 159 #define AENT(x) \ 160 .aent x, 0 161 #else 162 #define AENT(x) 163 #endif 164 165 /* 166 * WEAK_ALIAS: create a weak alias. 167 */ 168 #define WEAK_ALIAS(alias,sym) \ 169 .weak alias; \ 170 alias = sym 171 /* 172 * STRONG_ALIAS: create a strong alias. 173 */ 174 #define STRONG_ALIAS(alias,sym) \ 175 .globl alias; \ 176 alias = sym 177 178 /* 179 * WARN_REFERENCES: create a warning if the specified symbol is referenced. 180 */ 181 #define WARN_REFERENCES(sym,msg) \ 182 .pushsection __CONCAT(.gnu.warning.,sym); \ 183 .ascii msg; \ 184 .popsection 185 186 /* 187 * STATIC_LEAF_NOPROFILE 188 * No profilable local leaf routine. 189 */ 190 #define STATIC_LEAF_NOPROFILE(x) \ 191 .ent _C_LABEL(x); \ 192 _C_LABEL(x): ; \ 193 .frame sp, 0, ra 194 195 /* 196 * LEAF_NOPROFILE 197 * No profilable leaf routine. 198 */ 199 #define LEAF_NOPROFILE(x) \ 200 .globl _C_LABEL(x); \ 201 STATIC_LEAF_NOPROFILE(x) 202 203 /* 204 * STATIC_LEAF 205 * Declare a local leaf function. 206 */ 207 #define STATIC_LEAF(x) \ 208 STATIC_LEAF_NOPROFILE(x); \ 209 _MIPS_ASM_MCOUNT(x) 210 211 /* 212 * LEAF 213 * A leaf routine does 214 * - call no other function, 215 * - never use any register that callee-saved (S0-S8), and 216 * - not use any local stack storage. 217 */ 218 #define LEAF(x) \ 219 LEAF_NOPROFILE(x); \ 220 _MIPS_ASM_MCOUNT(x) 221 222 /* 223 * STATIC_XLEAF 224 * declare alternate entry to a static leaf routine 225 */ 226 #define STATIC_XLEAF(x) \ 227 AENT (_C_LABEL(x)); \ 228 _C_LABEL(x): 229 230 /* 231 * XLEAF 232 * declare alternate entry to leaf routine 233 */ 234 #define XLEAF(x) \ 235 .globl _C_LABEL(x); \ 236 STATIC_XLEAF(x) 237 238 /* 239 * STATIC_NESTED_NOPROFILE 240 * No profilable local nested routine. 241 */ 242 #define STATIC_NESTED_NOPROFILE(x, fsize, retpc) \ 243 .ent _C_LABEL(x); \ 244 .type _C_LABEL(x), @function; \ 245 _C_LABEL(x): ; \ 246 .frame sp, fsize, retpc 247 248 /* 249 * NESTED_NOPROFILE 250 * No profilable nested routine. 251 */ 252 #define NESTED_NOPROFILE(x, fsize, retpc) \ 253 .globl _C_LABEL(x); \ 254 STATIC_NESTED_NOPROFILE(x, fsize, retpc) 255 256 /* 257 * NESTED 258 * A function calls other functions and needs 259 * therefore stack space to save/restore registers. 260 */ 261 #define NESTED(x, fsize, retpc) \ 262 NESTED_NOPROFILE(x, fsize, retpc); \ 263 _MIPS_ASM_MCOUNT(x) 264 265 /* 266 * STATIC_NESTED 267 * No profilable local nested routine. 268 */ 269 #define STATIC_NESTED(x, fsize, retpc) \ 270 STATIC_NESTED_NOPROFILE(x, fsize, retpc); \ 271 _MIPS_ASM_MCOUNT(x) 272 273 /* 274 * XNESTED 275 * declare alternate entry point to nested routine. 276 */ 277 #define XNESTED(x) \ 278 .globl _C_LABEL(x); \ 279 AENT (_C_LABEL(x)); \ 280 _C_LABEL(x): 281 282 /* 283 * END 284 * Mark end of a procedure. 285 */ 286 #define END(x) \ 287 .end _C_LABEL(x); \ 288 .size _C_LABEL(x), . - _C_LABEL(x) 289 290 /* 291 * IMPORT -- import external symbol 292 */ 293 #define IMPORT(sym, size) \ 294 .extern _C_LABEL(sym),size 295 296 /* 297 * EXPORT -- export definition of symbol 298 */ 299 #define EXPORT(x) \ 300 .globl _C_LABEL(x); \ 301 _C_LABEL(x): 302 303 /* 304 * EXPORT_OBJECT -- export definition of symbol of symbol 305 * type Object, visible to ksyms(4) address search. 306 */ 307 #define EXPORT_OBJECT(x) \ 308 EXPORT(x); \ 309 .type _C_LABEL(x), @object; 310 311 /* 312 * VECTOR 313 * exception vector entrypoint 314 * XXX: regmask should be used to generate .mask 315 */ 316 #define VECTOR(x, regmask) \ 317 .ent _C_LABEL(x); \ 318 EXPORT(x); \ 319 320 #define VECTOR_END(x) \ 321 EXPORT(__CONCAT(x,_end)); \ 322 END(x); \ 323 .org _C_LABEL(x) + 0x80 324 325 /* 326 * Macros to panic and printf from assembly language. 327 */ 328 #define PANIC(msg) \ 329 PTR_LA a0, 9f; \ 330 jal _C_LABEL(panic); \ 331 nop; \ 332 MSG(msg) 333 334 #define PRINTF(msg) \ 335 PTR_LA a0, 9f; \ 336 jal _C_LABEL(printf); \ 337 nop; \ 338 MSG(msg) 339 340 #define MSG(msg) \ 341 .rdata; \ 342 9: .asciz msg; \ 343 .text 344 345 #define ASMSTR(str) \ 346 .asciz str; \ 347 .align 3 348 349 #ifdef _NETBSD_REVISIONID 350 #define RCSID(x) .pushsection ".ident","MS",@progbits,1; \ 351 .asciz x; \ 352 .ascii "$"; .ascii "NetBSD: "; .ascii __FILE__; \ 353 .ascii " "; .ascii _NETBSD_REVISIONID; \ 354 .asciz " $"; \ 355 .popsection 356 #else 357 #define RCSID(x) .pushsection ".ident","MS",@progbits,1; \ 358 .asciz x; \ 359 .popsection 360 #endif 361 362 /* 363 * XXX retain dialects XXX 364 */ 365 #define ALEAF(x) XLEAF(x) 366 #define NLEAF(x) LEAF_NOPROFILE(x) 367 #define NON_LEAF(x, fsize, retpc) NESTED(x, fsize, retpc) 368 #define NNON_LEAF(x, fsize, retpc) NESTED_NOPROFILE(x, fsize, retpc) 369 370 #if defined(__mips_o32) 371 #define SZREG 4 372 #else 373 #define SZREG 8 374 #endif 375 376 #if defined(__mips_o32) || defined(__mips_o64) 377 #define ALSK 7 /* stack alignment */ 378 #define ALMASK -7 /* stack alignment */ 379 #define SZFPREG 4 380 #define FP_L lwc1 381 #define FP_S swc1 382 #else 383 #define ALSK 15 /* stack alignment */ 384 #define ALMASK -15 /* stack alignment */ 385 #define SZFPREG 8 386 #define FP_L ldc1 387 #define FP_S sdc1 388 #endif 389 390 /* 391 * standard callframe { 392 * register_t cf_args[4]; arg0 - arg3 (only on o32 and o64) 393 * register_t cf_pad[N]; o32/64 (N=0), n32 (N=1) n64 (N=1) 394 * register_t cf_gp; global pointer (only on n32 and n64) 395 * register_t cf_sp; frame pointer 396 * register_t cf_ra; return address 397 * }; 398 */ 399 #if defined(__mips_o32) || defined(__mips_o64) 400 #define CALLFRAME_SIZ (SZREG * (4 + 2)) 401 #define CALLFRAME_S0 0 402 #elif defined(__mips_n32) || defined(__mips_n64) 403 #define CALLFRAME_SIZ (SZREG * 4) 404 #define CALLFRAME_S0 (CALLFRAME_SIZ - 4 * SZREG) 405 #endif 406 #ifndef _KERNEL 407 #define CALLFRAME_GP (CALLFRAME_SIZ - 3 * SZREG) 408 #endif 409 #define CALLFRAME_SP (CALLFRAME_SIZ - 2 * SZREG) 410 #define CALLFRAME_RA (CALLFRAME_SIZ - 1 * SZREG) 411 412 /* 413 * While it would be nice to be compatible with the SGI 414 * REG_L and REG_S macros, because they do not take parameters, it 415 * is impossible to use them with the _MIPS_SIM_ABIX32 model. 416 * 417 * These macros hide the use of mips3 instructions from the 418 * assembler to prevent the assembler from generating 64-bit style 419 * ABI calls. 420 */ 421 #ifdef __mips_o32 422 #define PTR_ADD add 423 #define PTR_ADDI addi 424 #define PTR_ADDU addu 425 #define PTR_ADDIU addiu 426 #define PTR_SUB subu 427 #define PTR_SUBI subi 428 #define PTR_SUBU subu 429 #define PTR_SUBIU subu 430 #define PTR_L lw 431 #define PTR_LA la 432 #define PTR_S sw 433 #define PTR_SLL sll 434 #define PTR_SLLV sllv 435 #define PTR_SRL srl 436 #define PTR_SRLV srlv 437 #define PTR_SRA sra 438 #define PTR_SRAV srav 439 #define PTR_LL ll 440 #define PTR_SC sc 441 #define PTR_WORD .word 442 #define PTR_SCALESHIFT 2 443 #else /* _MIPS_SZPTR == 64 */ 444 #define PTR_ADD dadd 445 #define PTR_ADDI daddi 446 #define PTR_ADDU daddu 447 #define PTR_ADDIU daddiu 448 #define PTR_SUB dsubu 449 #define PTR_SUBI dsubi 450 #define PTR_SUBU dsubu 451 #define PTR_SUBIU dsubu 452 #ifdef __mips_n32 453 #define PTR_L lw 454 #define PTR_LL ll 455 #define PTR_SC sc 456 #define PTR_S sw 457 #define PTR_SCALESHIFT 2 458 #define PTR_WORD .word 459 #else 460 #define PTR_L ld 461 #define PTR_LL lld 462 #define PTR_SC scd 463 #define PTR_S sd 464 #define PTR_SCALESHIFT 3 465 #define PTR_WORD .dword 466 #endif 467 #define PTR_LA dla 468 #define PTR_SLL dsll 469 #define PTR_SLLV dsllv 470 #define PTR_SRL dsrl 471 #define PTR_SRLV dsrlv 472 #define PTR_SRA dsra 473 #define PTR_SRAV dsrav 474 #endif /* _MIPS_SZPTR == 64 */ 475 476 #if _MIPS_SZINT == 32 477 #define INT_ADD add 478 #define INT_ADDI addi 479 #define INT_ADDU addu 480 #define INT_ADDIU addiu 481 #define INT_SUB subu 482 #define INT_SUBI subi 483 #define INT_SUBU subu 484 #define INT_SUBIU subu 485 #define INT_L lw 486 #define INT_LA la 487 #define INT_S sw 488 #define INT_SLL sll 489 #define INT_SLLV sllv 490 #define INT_SRL srl 491 #define INT_SRLV srlv 492 #define INT_SRA sra 493 #define INT_SRAV srav 494 #define INT_LL ll 495 #define INT_SC sc 496 #define INT_WORD .word 497 #define INT_SCALESHIFT 2 498 #else 499 #define INT_ADD dadd 500 #define INT_ADDI daddi 501 #define INT_ADDU daddu 502 #define INT_ADDIU daddiu 503 #define INT_SUB dsubu 504 #define INT_SUBI dsubi 505 #define INT_SUBU dsubu 506 #define INT_SUBIU dsubu 507 #define INT_L ld 508 #define INT_LA dla 509 #define INT_S sd 510 #define INT_SLL dsll 511 #define INT_SLLV dsllv 512 #define INT_SRL dsrl 513 #define INT_SRLV dsrlv 514 #define INT_SRA dsra 515 #define INT_SRAV dsrav 516 #define INT_LL lld 517 #define INT_SC scd 518 #define INT_WORD .dword 519 #define INT_SCALESHIFT 3 520 #endif 521 522 #if _MIPS_SZLONG == 32 523 #define LONG_ADD add 524 #define LONG_ADDI addi 525 #define LONG_ADDU addu 526 #define LONG_ADDIU addiu 527 #define LONG_SUB subu 528 #define LONG_SUBI subi 529 #define LONG_SUBU subu 530 #define LONG_SUBIU subu 531 #define LONG_L lw 532 #define LONG_LA la 533 #define LONG_S sw 534 #define LONG_SLL sll 535 #define LONG_SLLV sllv 536 #define LONG_SRL srl 537 #define LONG_SRLV srlv 538 #define LONG_SRA sra 539 #define LONG_SRAV srav 540 #define LONG_LL ll 541 #define LONG_SC sc 542 #define LONG_WORD .word 543 #define LONG_SCALESHIFT 2 544 #else 545 #define LONG_ADD dadd 546 #define LONG_ADDI daddi 547 #define LONG_ADDU daddu 548 #define LONG_ADDIU daddiu 549 #define LONG_SUB dsubu 550 #define LONG_SUBI dsubi 551 #define LONG_SUBU dsubu 552 #define LONG_SUBIU dsubu 553 #define LONG_L ld 554 #define LONG_LA dla 555 #define LONG_S sd 556 #define LONG_SLL dsll 557 #define LONG_SLLV dsllv 558 #define LONG_SRL dsrl 559 #define LONG_SRLV dsrlv 560 #define LONG_SRA dsra 561 #define LONG_SRAV dsrav 562 #define LONG_LL lld 563 #define LONG_SC scd 564 #define LONG_WORD .dword 565 #define LONG_SCALESHIFT 3 566 #endif 567 568 #if SZREG == 4 569 #define REG_L lw 570 #define REG_S sw 571 #define REG_LI li 572 #define REG_ADDU addu 573 #define REG_SLL sll 574 #define REG_SLLV sllv 575 #define REG_SRL srl 576 #define REG_SRLV srlv 577 #define REG_SRA sra 578 #define REG_SRAV srav 579 #define REG_LL ll 580 #define REG_SC sc 581 #define REG_SCALESHIFT 2 582 #else 583 #define REG_L ld 584 #define REG_S sd 585 #define REG_LI dli 586 #define REG_ADDU daddu 587 #define REG_SLL dsll 588 #define REG_SLLV dsllv 589 #define REG_SRL dsrl 590 #define REG_SRLV dsrlv 591 #define REG_SRA dsra 592 #define REG_SRAV dsrav 593 #define REG_LL lld 594 #define REG_SC scd 595 #define REG_SCALESHIFT 3 596 #endif 597 598 #if (MIPS1 + MIPS2) > 0 599 #define NOP_L nop 600 #else 601 #define NOP_L /* nothing */ 602 #endif 603 604 /* compiler define */ 605 #if defined(MULTIPROCESSOR) && defined(__OCTEON__) 606 /* 607 * See common/lib/libc/arch/mips/atomic/membar_ops.S for notes on 608 * Octeon memory ordering guarantees and barriers. 609 * 610 * cnMIPS also has a quirk where the store buffer can get clogged and 611 * we need to apply a plunger to it _after_ releasing a lock or else 612 * other CPUs may spin for hundreds of thousands of cycles before they 613 * see the lock is released. So we also have the quirky SYNC_PLUNGER 614 * barrier as syncw. See the note in the SYNCW instruction description 615 * on p. 2168 of Cavium OCTEON III CN78XX Hardware Reference Manual, 616 * CN78XX-HM-0.99E, September 2014: 617 * 618 * Core A (writer) 619 * 620 * SW R1, DATA# change shared DATA value 621 * LI R1, 1 622 * SYNCW# (or SYNCWS) Perform DATA store before performing FLAG store 623 * SW R2, FLAG# say that the shared DATA value is valid 624 * SYNCW# (or SYNCWS) Force the FLAG store soon (CN78XX-specific) 625 * 626 * ... 627 * 628 * The second SYNCW instruction executed by core A is not 629 * necessary for correctness, but has very important performance 630 * effects on the CN78XX. Without it, the store to FLAG may 631 * linger in core A's write buffer before it becomes visible to 632 * any other cores. (If core A is not performing many stores, 633 * this may add hundreds of thousands of cycles to the flag 634 * release time since the CN78XX core nominally retains stores to 635 * attempt to merge them before sending the store on the CMI.) 636 * Applications should include this second SYNCW instruction after 637 * flag or lock release. 638 */ 639 #define LLSCSYNC /* nothing */ 640 #define BDSYNC sync 641 #define BDSYNC_ACQ nop 642 #define SYNC_ACQ /* nothing */ 643 #define SYNC_REL sync 4 644 #define BDSYNC_PLUNGER sync 4 645 #define SYNC_PLUNGER sync 4 646 #elif defined(MULTIPROCESSOR) && (__mips >= 3 || !defined(__mips_o32)) 647 #define LLSCSYNC /* nothing */ 648 #define BDSYNC sync 649 #define BDSYNC_ACQ sync 650 #define SYNC_ACQ sync 651 #define SYNC_REL sync 652 #define BDSYNC_PLUNGER nop 653 #define SYNC_PLUNGER /* nothing */ 654 #else 655 #define LLSCSYNC /* nothing */ 656 #define BDSYNC nop 657 #define BDSYNC_ACQ nop 658 #define SYNC_ACQ /* nothing */ 659 #define SYNC_REL /* nothing */ 660 #define BDSYNC_PLUNGER nop 661 #define SYNC_PLUNGER /* nothing */ 662 #endif 663 664 /* 665 * Store-before-load barrier. Do not use this unless you know what 666 * you're doing. 667 */ 668 #ifdef MULTIPROCESSOR 669 #define SYNC_DEKKER sync 670 #else 671 #define SYNC_DEKKER /* nothing */ 672 #endif 673 674 /* 675 * Store-before-store and load-before-load barriers. These could be 676 * made weaker than release (load/store-before-store) and acquire 677 * (load-before-load/store) barriers, and newer MIPS does have 678 * instruction encodings for finer-grained barriers like this, but I 679 * dunno how to appropriately conditionalize their use or get the 680 * assembler to be happy with them, so we'll use these definitions for 681 * now. 682 */ 683 #define SYNC_PRODUCER SYNC_REL 684 #define SYNC_CONSUMER SYNC_ACQ 685 686 /* CPU dependent hook for cp0 load delays */ 687 #if defined(MIPS1) || defined(MIPS2) || defined(MIPS3) 688 #define MFC0_HAZARD sll $0,$0,1 /* super scalar nop */ 689 #else 690 #define MFC0_HAZARD /* nothing */ 691 #endif 692 693 #if _MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \ 694 _MIPS_ISA == _MIPS_ISA_MIPS32 695 #define MFC0 mfc0 696 #define MTC0 mtc0 697 #endif 698 #if _MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \ 699 _MIPS_ISA == _MIPS_ISA_MIPS64 700 #define MFC0 dmfc0 701 #define MTC0 dmtc0 702 #endif 703 704 #if defined(__mips_o32) || defined(__mips_o64) 705 706 #ifdef __mips_abicalls 707 #define CPRESTORE(r) .cprestore r 708 #define CPLOAD(r) .cpload r 709 #else 710 #define CPRESTORE(r) /* not needed */ 711 #define CPLOAD(r) /* not needed */ 712 #endif 713 714 #define SETUP_GP \ 715 .set push; \ 716 .set noreorder; \ 717 .cpload t9; \ 718 .set pop 719 #define SETUP_GPX(r) \ 720 .set push; \ 721 .set noreorder; \ 722 move r,ra; /* save old ra */ \ 723 bal 7f; \ 724 nop; \ 725 7: .cpload ra; \ 726 move ra,r; \ 727 .set pop 728 #define SETUP_GPX_L(r,lbl) \ 729 .set push; \ 730 .set noreorder; \ 731 move r,ra; /* save old ra */ \ 732 bal lbl; \ 733 nop; \ 734 lbl: .cpload ra; \ 735 move ra,r; \ 736 .set pop 737 #define SAVE_GP(x) .cprestore x 738 739 #define SETUP_GP64(a,b) /* n32/n64 specific */ 740 #define SETUP_GP64_R(a,b) /* n32/n64 specific */ 741 #define SETUP_GPX64(a,b) /* n32/n64 specific */ 742 #define SETUP_GPX64_L(a,b,c) /* n32/n64 specific */ 743 #define RESTORE_GP64 /* n32/n64 specific */ 744 #define USE_ALT_CP(a) /* n32/n64 specific */ 745 #endif /* __mips_o32 || __mips_o64 */ 746 747 #if defined(__mips_o32) || defined(__mips_o64) 748 #define REG_PROLOGUE .set push 749 #define REG_EPILOGUE .set pop 750 #endif 751 #if defined(__mips_n32) || defined(__mips_n64) 752 #define REG_PROLOGUE .set push ; .set mips3 753 #define REG_EPILOGUE .set pop 754 #endif 755 756 #if defined(__mips_n32) || defined(__mips_n64) 757 #define SETUP_GP /* o32 specific */ 758 #define SETUP_GPX(r) /* o32 specific */ 759 #define SETUP_GPX_L(r,lbl) /* o32 specific */ 760 #define SAVE_GP(x) /* o32 specific */ 761 #define SETUP_GP64(a,b) .cpsetup t9, a, b 762 #define SETUP_GPX64(a,b) \ 763 .set push; \ 764 move b,ra; \ 765 .set noreorder; \ 766 bal 7f; \ 767 nop; \ 768 7: .set pop; \ 769 .cpsetup ra, a, 7b; \ 770 move ra,b 771 #define SETUP_GPX64_L(a,b,c) \ 772 .set push; \ 773 move b,ra; \ 774 .set noreorder; \ 775 bal c; \ 776 nop; \ 777 c: .set pop; \ 778 .cpsetup ra, a, c; \ 779 move ra,b 780 #define RESTORE_GP64 .cpreturn 781 #define USE_ALT_CP(a) .cplocal a 782 #endif /* __mips_n32 || __mips_n64 */ 783 784 /* 785 * The DYNAMIC_STATUS_MASK option adds an additional masking operation 786 * when updating the hardware interrupt mask in the status register. 787 * 788 * This is useful for platforms that need to at run-time mask 789 * interrupts based on motherboard configuration or to handle 790 * slowly clearing interrupts. 791 * 792 * XXX this is only currently implemented for mips3. 793 */ 794 #ifdef MIPS_DYNAMIC_STATUS_MASK 795 #define DYNAMIC_STATUS_MASK(sr,scratch) \ 796 lw scratch, mips_dynamic_status_mask; \ 797 and sr, sr, scratch 798 799 #define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1) \ 800 ori sr, (MIPS_INT_MASK | MIPS_SR_INT_IE); \ 801 DYNAMIC_STATUS_MASK(sr,scratch1) 802 #else 803 #define DYNAMIC_STATUS_MASK(sr,scratch) 804 #define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1) 805 #endif 806 807 /* See lock_stubs.S. */ 808 #define LOG2_MIPS_LOCK_RAS_SIZE 8 809 #define MIPS_LOCK_RAS_SIZE 256 /* 16 bytes left over */ 810 811 #define CPUVAR(off) _C_LABEL(cpu_info_store)+__CONCAT(CPU_INFO_,off) 812 813 #endif /* _MIPS_ASM_H */ 814