1 /* $NetBSD: locore.h,v 1.6 2013/03/16 23:04:22 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1996-2002 Eduardo Horvath 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 */ 26 27 #undef CURLWP 28 #undef CPCB 29 #undef FPLWP 30 31 #define CURLWP (CPUINFO_VA + CI_CURLWP) 32 #define CPCB (CPUINFO_VA + CI_CPCB) 33 #define FPLWP (CPUINFO_VA + CI_FPLWP) 34 35 /* A few convenient abbreviations for trapframe fields. */ 36 #define TF_G TF_GLOBAL 37 #define TF_O TF_OUT 38 #define TF_L TF_LOCAL 39 #define TF_I TF_IN 40 41 /* Let us use same syntax as C code */ 42 #define Debugger() ta 1; nop 43 44 45 /* 46 * This macro will clear out a cache line before an explicit 47 * access to that location. It's mostly used to make certain 48 * loads bypassing the D$ do not get stale D$ data. 49 * 50 * It uses a register with the address to clear and a temporary 51 * which is destroyed. 52 */ 53 #ifdef DCACHE_BUG 54 #define DLFLUSH(a,t) \ 55 andn a, 0x3f, t; \ 56 stxa %g0, [ t ] ASI_DCACHE_TAG; \ 57 membar #Sync 58 /* The following can be used if the pointer is 32-byte aligned */ 59 #define DLFLUSH2(t) \ 60 stxa %g0, [ t ] ASI_DCACHE_TAG; \ 61 membar #Sync 62 #else 63 #define DLFLUSH(a,t) 64 #define DLFLUSH2(t) 65 #endif 66 67 68 /* 69 * Combine 2 regs -- used to convert 64-bit ILP32 70 * values to LP64. 71 */ 72 #define COMBINE(r1, r2, d) \ 73 clruw r2; \ 74 sllx r1, 32, d; \ 75 or d, r2, d 76 77 /* 78 * Split 64-bit value in 1 reg into high and low halves. 79 * Used for ILP32 return values. 80 */ 81 #define SPLIT(r0, r1) \ 82 srl r0, 0, r1; \ 83 srlx r0, 32, r0 84 85 86 /* 87 * A handy macro for maintaining instrumentation counters. 88 * Note that this clobbers %o0, %o1 and %o2. Normal usage is 89 * something like: 90 * foointr: 91 * TRAP_SETUP(...) ! makes %o registers safe 92 * INCR(_C_LABEL(cnt)+V_FOO) ! count a foo 93 */ 94 #define INCR(what) \ 95 sethi %hi(what), %o0; \ 96 or %o0, %lo(what), %o0; \ 97 99: \ 98 lduw [%o0], %o1; \ 99 add %o1, 1, %o2; \ 100 casa [%o0] ASI_P, %o1, %o2; \ 101 cmp %o1, %o2; \ 102 bne,pn %icc, 99b; \ 103 nop 104 105 /* 106 * A couple of handy macros to save and restore globals to/from 107 * locals. Since udivrem uses several globals, and it's called 108 * from vsprintf, we need to do this before and after doing a printf. 109 */ 110 #define GLOBTOLOC \ 111 mov %g1, %l1; \ 112 mov %g2, %l2; \ 113 mov %g3, %l3; \ 114 mov %g4, %l4; \ 115 mov %g5, %l5; \ 116 mov %g6, %l6; \ 117 mov %g7, %l7 118 119 #define LOCTOGLOB \ 120 mov %l1, %g1; \ 121 mov %l2, %g2; \ 122 mov %l3, %g3; \ 123 mov %l4, %g4; \ 124 mov %l5, %g5; \ 125 mov %l6, %g6; \ 126 mov %l7, %g7 127 128 /* Load strings address into register; NOTE: hidden local label 99 */ 129 #define LOAD_ASCIZ(reg, s) \ 130 set 99f, reg ; \ 131 .data ; \ 132 99: .asciz s ; \ 133 _ALIGN ; \ 134 .text 135 136 /* 137 * Handy stack conversion macros. 138 * They correctly switch to requested stack type 139 * regardless of the current stack. 140 */ 141 142 #define TO_STACK64(size) \ 143 save %sp, size, %sp; \ 144 add %sp, -BIAS, %o0; /* Convert to 64-bits */ \ 145 andcc %sp, 1, %g0; /* 64-bit stack? */ \ 146 movz %icc, %o0, %sp 147 148 #define TO_STACK32(size) \ 149 save %sp, size, %sp; \ 150 add %sp, +BIAS, %o0; /* Convert to 32-bits */ \ 151 andcc %sp, 1, %g0; /* 64-bit stack? */ \ 152 movnz %icc, %o0, %sp 153 154 #ifdef _LP64 155 #define STACKFRAME(size) TO_STACK64(size) 156 #else 157 #define STACKFRAME(size) TO_STACK32(size) 158 #endif 159 160 /* 161 * Primitives 162 */ 163 #ifdef ENTRY 164 #undef ENTRY 165 #endif 166 167 #ifdef GPROF 168 .globl _mcount 169 #define ENTRY(x) \ 170 .globl _C_LABEL(x); .proc 1; .type _C_LABEL(x),@function; \ 171 _C_LABEL(x): ; \ 172 .data; \ 173 .align 8; \ 174 0: .uaword 0; .uaword 0; \ 175 .text; \ 176 save %sp, -CC64FSZ, %sp; \ 177 sethi %hi(0b), %o0; \ 178 call _mcount; \ 179 or %o0, %lo(0b), %o0; \ 180 restore 181 #else 182 #define ENTRY(x) .globl _C_LABEL(x); .proc 1; \ 183 .type _C_LABEL(x),@function; _C_LABEL(x): 184 #endif 185 #define ALTENTRY(x) .globl _C_LABEL(x); _C_LABEL(x): 186 187 188