locore.h revision 1.3.2.3 1 1.3.2.3 yamt /* $NetBSD: locore.h,v 1.3.2.3 2010/08/11 22:52:47 yamt Exp $ */
2 1.3.2.2 yamt
3 1.3.2.2 yamt /*
4 1.3.2.2 yamt * Copyright (c) 1996-2002 Eduardo Horvath
5 1.3.2.2 yamt * All rights reserved.
6 1.3.2.2 yamt *
7 1.3.2.2 yamt * Redistribution and use in source and binary forms, with or without
8 1.3.2.2 yamt * modification, are permitted provided that the following conditions
9 1.3.2.2 yamt * are met:
10 1.3.2.2 yamt * 1. Redistributions of source code must retain the above copyright
11 1.3.2.2 yamt * notice, this list of conditions and the following disclaimer.
12 1.3.2.2 yamt *
13 1.3.2.2 yamt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
14 1.3.2.2 yamt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 1.3.2.2 yamt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 1.3.2.2 yamt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
17 1.3.2.2 yamt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 1.3.2.2 yamt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 1.3.2.2 yamt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 1.3.2.2 yamt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 1.3.2.2 yamt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 1.3.2.2 yamt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 1.3.2.2 yamt * SUCH DAMAGE.
24 1.3.2.2 yamt *
25 1.3.2.2 yamt */
26 1.3.2.2 yamt
27 1.3.2.2 yamt #undef CURLWP
28 1.3.2.2 yamt #undef CPCB
29 1.3.2.2 yamt #undef FPLWP
30 1.3.2.2 yamt
31 1.3.2.2 yamt #define CURLWP (CPUINFO_VA + CI_CURLWP)
32 1.3.2.2 yamt #define CPCB (CPUINFO_VA + CI_CPCB)
33 1.3.2.2 yamt #define FPLWP (CPUINFO_VA + CI_FPLWP)
34 1.3.2.2 yamt
35 1.3.2.2 yamt /*
36 1.3.2.2 yamt * Here are some defines to try to maintain consistency but still
37 1.3.2.2 yamt * support 32-and 64-bit compilers.
38 1.3.2.2 yamt */
39 1.3.2.2 yamt #ifdef _LP64
40 1.3.2.2 yamt /* reg that points to base of data/text segment */
41 1.3.2.2 yamt #define BASEREG %g4
42 1.3.2.2 yamt /* first constants for storage allocation */
43 1.3.2.2 yamt #define LNGSZ 8
44 1.3.2.2 yamt #define LNGSHFT 3
45 1.3.2.2 yamt #define PTRSZ 8
46 1.3.2.2 yamt #define PTRSHFT 3
47 1.3.2.2 yamt #define POINTER .xword
48 1.3.2.2 yamt #define ULONG .xword
49 1.3.2.2 yamt /* Now instructions to load/store pointers & long ints */
50 1.3.2.2 yamt #define LDLNG ldx
51 1.3.2.2 yamt #define LDULNG ldx
52 1.3.2.2 yamt #define STLNG stx
53 1.3.2.2 yamt #define STULNG stx
54 1.3.2.2 yamt #define LDPTR ldx
55 1.3.2.2 yamt #define LDPTRA ldxa
56 1.3.2.2 yamt #define STPTR stx
57 1.3.2.2 yamt #define STPTRA stxa
58 1.3.2.2 yamt #define CASPTR casxa
59 1.3.2.2 yamt /* Now something to calculate the stack bias */
60 1.3.2.2 yamt #define STKB BIAS
61 1.3.2.2 yamt #define CCCR %xcc
62 1.3.2.2 yamt #else
63 1.3.2.2 yamt #define BASEREG %g0
64 1.3.2.2 yamt #define LNGSZ 4
65 1.3.2.2 yamt #define LNGSHFT 2
66 1.3.2.2 yamt #define PTRSZ 4
67 1.3.2.2 yamt #define PTRSHFT 2
68 1.3.2.2 yamt #define POINTER .word
69 1.3.2.2 yamt #define ULONG .word
70 1.3.2.2 yamt /* Instructions to load/store pointers & long ints */
71 1.3.2.2 yamt #define LDLNG ldsw
72 1.3.2.2 yamt #define LDULNG lduw
73 1.3.2.2 yamt #define STLNG stw
74 1.3.2.2 yamt #define STULNG stw
75 1.3.2.2 yamt #define LDPTR lduw
76 1.3.2.2 yamt #define LDPTRA lduwa
77 1.3.2.2 yamt #define STPTR stw
78 1.3.2.2 yamt #define STPTRA stwa
79 1.3.2.2 yamt #define CASPTR casa
80 1.3.2.2 yamt #define STKB 0
81 1.3.2.2 yamt #define CCCR %icc
82 1.3.2.2 yamt #endif
83 1.3.2.2 yamt
84 1.3.2.2 yamt /* Give this real authority: reset the machine */
85 1.3.2.2 yamt #define NOTREACHED sir
86 1.3.2.2 yamt
87 1.3.2.2 yamt /* if < 32, copy by bytes, memcpy, kcopy, ... */
88 1.3.2.2 yamt #define BCOPY_SMALL 32
89 1.3.2.2 yamt
90 1.3.2.2 yamt /* use as needed to align things on longword boundaries */
91 1.3.2.2 yamt #define _ALIGN .align 8
92 1.3.2.2 yamt #define ICACHE_ALIGN .align 32
93 1.3.2.3 yamt
94 1.3.2.3 yamt /* A few convenient abbreviations for trapframe fields. */
95 1.3.2.3 yamt #define TF_G TF_GLOBAL
96 1.3.2.3 yamt #define TF_O TF_OUT
97 1.3.2.3 yamt #define TF_L TF_LOCAL
98 1.3.2.3 yamt #define TF_I TF_IN
99 1.3.2.3 yamt
100 1.3.2.3 yamt /* Let us use same syntax as C code */
101 1.3.2.3 yamt #define Debugger() ta 1; nop
102 1.3.2.3 yamt
103 1.3.2.3 yamt
104 1.3.2.3 yamt /*
105 1.3.2.3 yamt * This macro will clear out a cache line before an explicit
106 1.3.2.3 yamt * access to that location. It's mostly used to make certain
107 1.3.2.3 yamt * loads bypassing the D$ do not get stale D$ data.
108 1.3.2.3 yamt *
109 1.3.2.3 yamt * It uses a register with the address to clear and a temporary
110 1.3.2.3 yamt * which is destroyed.
111 1.3.2.3 yamt */
112 1.3.2.3 yamt #ifdef DCACHE_BUG
113 1.3.2.3 yamt #define DLFLUSH(a,t) \
114 1.3.2.3 yamt andn a, 0x3f, t; \
115 1.3.2.3 yamt stxa %g0, [ t ] ASI_DCACHE_TAG; \
116 1.3.2.3 yamt membar #Sync
117 1.3.2.3 yamt /* The following can be used if the pointer is 32-byte aligned */
118 1.3.2.3 yamt #define DLFLUSH2(t) \
119 1.3.2.3 yamt stxa %g0, [ t ] ASI_DCACHE_TAG; \
120 1.3.2.3 yamt membar #Sync
121 1.3.2.3 yamt #else
122 1.3.2.3 yamt #define DLFLUSH(a,t)
123 1.3.2.3 yamt #define DLFLUSH2(t)
124 1.3.2.3 yamt #endif
125 1.3.2.3 yamt
126 1.3.2.3 yamt
127 1.3.2.3 yamt /*
128 1.3.2.3 yamt * Combine 2 regs -- used to convert 64-bit ILP32
129 1.3.2.3 yamt * values to LP64.
130 1.3.2.3 yamt */
131 1.3.2.3 yamt #define COMBINE(r1, r2, d) \
132 1.3.2.3 yamt clruw r2; \
133 1.3.2.3 yamt sllx r1, 32, d; \
134 1.3.2.3 yamt or d, r2, d
135 1.3.2.3 yamt
136 1.3.2.3 yamt /*
137 1.3.2.3 yamt * Split 64-bit value in 1 reg into high and low halves.
138 1.3.2.3 yamt * Used for ILP32 return values.
139 1.3.2.3 yamt */
140 1.3.2.3 yamt #define SPLIT(r0, r1) \
141 1.3.2.3 yamt srl r0, 0, r1; \
142 1.3.2.3 yamt srlx r0, 32, r0
143 1.3.2.3 yamt
144 1.3.2.3 yamt
145 1.3.2.3 yamt /*
146 1.3.2.3 yamt * A handy macro for maintaining instrumentation counters.
147 1.3.2.3 yamt * Note that this clobbers %o0, %o1 and %o2. Normal usage is
148 1.3.2.3 yamt * something like:
149 1.3.2.3 yamt * foointr:
150 1.3.2.3 yamt * TRAP_SETUP(...) ! makes %o registers safe
151 1.3.2.3 yamt * INCR(_C_LABEL(cnt)+V_FOO) ! count a foo
152 1.3.2.3 yamt */
153 1.3.2.3 yamt #define INCR(what) \
154 1.3.2.3 yamt sethi %hi(what), %o0; \
155 1.3.2.3 yamt or %o0, %lo(what), %o0; \
156 1.3.2.3 yamt 99: \
157 1.3.2.3 yamt lduw [%o0], %o1; \
158 1.3.2.3 yamt add %o1, 1, %o2; \
159 1.3.2.3 yamt casa [%o0] ASI_P, %o1, %o2; \
160 1.3.2.3 yamt cmp %o1, %o2; \
161 1.3.2.3 yamt bne,pn %icc, 99b; \
162 1.3.2.3 yamt nop
163 1.3.2.3 yamt
164 1.3.2.3 yamt /*
165 1.3.2.3 yamt * A couple of handy macros to save and restore globals to/from
166 1.3.2.3 yamt * locals. Since udivrem uses several globals, and it's called
167 1.3.2.3 yamt * from vsprintf, we need to do this before and after doing a printf.
168 1.3.2.3 yamt */
169 1.3.2.3 yamt #define GLOBTOLOC \
170 1.3.2.3 yamt mov %g1, %l1; \
171 1.3.2.3 yamt mov %g2, %l2; \
172 1.3.2.3 yamt mov %g3, %l3; \
173 1.3.2.3 yamt mov %g4, %l4; \
174 1.3.2.3 yamt mov %g5, %l5; \
175 1.3.2.3 yamt mov %g6, %l6; \
176 1.3.2.3 yamt mov %g7, %l7
177 1.3.2.3 yamt
178 1.3.2.3 yamt #define LOCTOGLOB \
179 1.3.2.3 yamt mov %l1, %g1; \
180 1.3.2.3 yamt mov %l2, %g2; \
181 1.3.2.3 yamt mov %l3, %g3; \
182 1.3.2.3 yamt mov %l4, %g4; \
183 1.3.2.3 yamt mov %l5, %g5; \
184 1.3.2.3 yamt mov %l6, %g6; \
185 1.3.2.3 yamt mov %l7, %g7
186 1.3.2.3 yamt
187 1.3.2.3 yamt /* Load strings address into register; NOTE: hidden local label 99 */
188 1.3.2.3 yamt #define LOAD_ASCIZ(reg, s) \
189 1.3.2.3 yamt set 99f, reg ; \
190 1.3.2.3 yamt .data ; \
191 1.3.2.3 yamt 99: .asciz s ; \
192 1.3.2.3 yamt _ALIGN ; \
193 1.3.2.3 yamt .text
194 1.3.2.3 yamt
195 1.3.2.3 yamt /*
196 1.3.2.3 yamt * Handy stack conversion macros.
197 1.3.2.3 yamt * They correctly switch to requested stack type
198 1.3.2.3 yamt * regardless of the current stack.
199 1.3.2.3 yamt */
200 1.3.2.3 yamt
201 1.3.2.3 yamt #define TO_STACK64(size) \
202 1.3.2.3 yamt save %sp, size, %sp; \
203 1.3.2.3 yamt add %sp, -BIAS, %o0; /* Convert to 64-bits */ \
204 1.3.2.3 yamt andcc %sp, 1, %g0; /* 64-bit stack? */ \
205 1.3.2.3 yamt movz %icc, %o0, %sp
206 1.3.2.3 yamt
207 1.3.2.3 yamt #define TO_STACK32(size) \
208 1.3.2.3 yamt save %sp, size, %sp; \
209 1.3.2.3 yamt add %sp, +BIAS, %o0; /* Convert to 32-bits */ \
210 1.3.2.3 yamt andcc %sp, 1, %g0; /* 64-bit stack? */ \
211 1.3.2.3 yamt movnz %icc, %o0, %sp
212 1.3.2.3 yamt
213 1.3.2.3 yamt #ifdef _LP64
214 1.3.2.3 yamt #define STACKFRAME(size) TO_STACK64(size)
215 1.3.2.3 yamt #else
216 1.3.2.3 yamt #define STACKFRAME(size) TO_STACK32(size)
217 1.3.2.3 yamt #endif
218 1.3.2.3 yamt
219 1.3.2.3 yamt /*
220 1.3.2.3 yamt * Primitives
221 1.3.2.3 yamt */
222 1.3.2.3 yamt #ifdef ENTRY
223 1.3.2.3 yamt #undef ENTRY
224 1.3.2.3 yamt #endif
225 1.3.2.3 yamt
226 1.3.2.3 yamt #ifdef GPROF
227 1.3.2.3 yamt .globl _mcount
228 1.3.2.3 yamt #define ENTRY(x) \
229 1.3.2.3 yamt .globl _C_LABEL(x); .proc 1; .type _C_LABEL(x),@function; \
230 1.3.2.3 yamt _C_LABEL(x): ; \
231 1.3.2.3 yamt .data; \
232 1.3.2.3 yamt .align 8; \
233 1.3.2.3 yamt 0: .uaword 0; .uaword 0; \
234 1.3.2.3 yamt .text; \
235 1.3.2.3 yamt save %sp, -CC64FSZ, %sp; \
236 1.3.2.3 yamt sethi %hi(0b), %o0; \
237 1.3.2.3 yamt call _mcount; \
238 1.3.2.3 yamt or %o0, %lo(0b), %o0; \
239 1.3.2.3 yamt restore
240 1.3.2.3 yamt #else
241 1.3.2.3 yamt #define ENTRY(x) .globl _C_LABEL(x); .proc 1; \
242 1.3.2.3 yamt .type _C_LABEL(x),@function; _C_LABEL(x):
243 1.3.2.3 yamt #endif
244 1.3.2.3 yamt #define ALTENTRY(x) .globl _C_LABEL(x); _C_LABEL(x):
245 1.3.2.3 yamt
246 1.3.2.3 yamt
247