Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ f97572e5

History | View | Annotate | Download (76.9 kB)

1 e8af50a3 bellard
#include "exec.h"
2 eed152bb blueswir1
#include "host-utils.h"
3 1a2fb1c0 blueswir1
#include "helper.h"
4 0828b448 blueswir1
#if !defined(CONFIG_USER_ONLY)
5 0828b448 blueswir1
#include "softmmu_exec.h"
6 0828b448 blueswir1
#endif /* !defined(CONFIG_USER_ONLY) */
7 e8af50a3 bellard
8 e80cfcfc bellard
//#define DEBUG_MMU
9 952a328f blueswir1
//#define DEBUG_MXCC
10 94554550 blueswir1
//#define DEBUG_UNALIGNED
11 6c36d3fa blueswir1
//#define DEBUG_UNASSIGNED
12 8543e2cf blueswir1
//#define DEBUG_ASI
13 e80cfcfc bellard
14 952a328f blueswir1
#ifdef DEBUG_MMU
15 952a328f blueswir1
#define DPRINTF_MMU(fmt, args...) \
16 952a328f blueswir1
do { printf("MMU: " fmt , ##args); } while (0)
17 952a328f blueswir1
#else
18 22548760 blueswir1
#define DPRINTF_MMU(fmt, args...) do {} while (0)
19 952a328f blueswir1
#endif
20 952a328f blueswir1
21 952a328f blueswir1
#ifdef DEBUG_MXCC
22 952a328f blueswir1
#define DPRINTF_MXCC(fmt, args...) \
23 952a328f blueswir1
do { printf("MXCC: " fmt , ##args); } while (0)
24 952a328f blueswir1
#else
25 22548760 blueswir1
#define DPRINTF_MXCC(fmt, args...) do {} while (0)
26 952a328f blueswir1
#endif
27 952a328f blueswir1
28 8543e2cf blueswir1
#ifdef DEBUG_ASI
29 8543e2cf blueswir1
#define DPRINTF_ASI(fmt, args...) \
30 8543e2cf blueswir1
do { printf("ASI: " fmt , ##args); } while (0)
31 8543e2cf blueswir1
#else
32 22548760 blueswir1
#define DPRINTF_ASI(fmt, args...) do {} while (0)
33 8543e2cf blueswir1
#endif
34 8543e2cf blueswir1
35 2cade6a3 blueswir1
#ifdef TARGET_SPARC64
36 2cade6a3 blueswir1
#ifndef TARGET_ABI32
37 2cade6a3 blueswir1
#define AM_CHECK(env1) ((env1)->pstate & PS_AM)
38 c2bc0e38 blueswir1
#else
39 2cade6a3 blueswir1
#define AM_CHECK(env1) (1)
40 2cade6a3 blueswir1
#endif
41 c2bc0e38 blueswir1
#endif
42 c2bc0e38 blueswir1
43 2cade6a3 blueswir1
static inline void address_mask(CPUState *env1, target_ulong *addr)
44 2cade6a3 blueswir1
{
45 2cade6a3 blueswir1
#ifdef TARGET_SPARC64
46 2cade6a3 blueswir1
    if (AM_CHECK(env1))
47 2cade6a3 blueswir1
        *addr &= 0xffffffffULL;
48 2cade6a3 blueswir1
#endif
49 2cade6a3 blueswir1
}
50 2cade6a3 blueswir1
51 9d893301 bellard
void raise_exception(int tt)
52 9d893301 bellard
{
53 9d893301 bellard
    env->exception_index = tt;
54 9d893301 bellard
    cpu_loop_exit();
55 3b46e624 ths
}
56 9d893301 bellard
57 1a2fb1c0 blueswir1
void helper_trap(target_ulong nb_trap)
58 417454b0 blueswir1
{
59 1a2fb1c0 blueswir1
    env->exception_index = TT_TRAP + (nb_trap & 0x7f);
60 1a2fb1c0 blueswir1
    cpu_loop_exit();
61 1a2fb1c0 blueswir1
}
62 1a2fb1c0 blueswir1
63 1a2fb1c0 blueswir1
void helper_trapcc(target_ulong nb_trap, target_ulong do_trap)
64 1a2fb1c0 blueswir1
{
65 1a2fb1c0 blueswir1
    if (do_trap) {
66 1a2fb1c0 blueswir1
        env->exception_index = TT_TRAP + (nb_trap & 0x7f);
67 1a2fb1c0 blueswir1
        cpu_loop_exit();
68 1a2fb1c0 blueswir1
    }
69 1a2fb1c0 blueswir1
}
70 1a2fb1c0 blueswir1
71 2b29924f blueswir1
void helper_check_align(target_ulong addr, uint32_t align)
72 2b29924f blueswir1
{
73 c2bc0e38 blueswir1
    if (addr & align) {
74 c2bc0e38 blueswir1
#ifdef DEBUG_UNALIGNED
75 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
76 c2bc0e38 blueswir1
           "\n", addr, env->pc);
77 c2bc0e38 blueswir1
#endif
78 2b29924f blueswir1
        raise_exception(TT_UNALIGNED);
79 c2bc0e38 blueswir1
    }
80 2b29924f blueswir1
}
81 2b29924f blueswir1
82 44e7757c blueswir1
#define F_HELPER(name, p) void helper_f##name##p(void)
83 44e7757c blueswir1
84 44e7757c blueswir1
#define F_BINOP(name)                                           \
85 44e7757c blueswir1
    F_HELPER(name, s)                                           \
86 44e7757c blueswir1
    {                                                           \
87 44e7757c blueswir1
        FT0 = float32_ ## name (FT0, FT1, &env->fp_status);     \
88 44e7757c blueswir1
    }                                                           \
89 44e7757c blueswir1
    F_HELPER(name, d)                                           \
90 44e7757c blueswir1
    {                                                           \
91 44e7757c blueswir1
        DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
92 4e14008f blueswir1
    }                                                           \
93 4e14008f blueswir1
    F_HELPER(name, q)                                           \
94 4e14008f blueswir1
    {                                                           \
95 4e14008f blueswir1
        QT0 = float128_ ## name (QT0, QT1, &env->fp_status);    \
96 44e7757c blueswir1
    }
97 44e7757c blueswir1
98 44e7757c blueswir1
F_BINOP(add);
99 44e7757c blueswir1
F_BINOP(sub);
100 44e7757c blueswir1
F_BINOP(mul);
101 44e7757c blueswir1
F_BINOP(div);
102 44e7757c blueswir1
#undef F_BINOP
103 44e7757c blueswir1
104 44e7757c blueswir1
void helper_fsmuld(void)
105 1a2fb1c0 blueswir1
{
106 44e7757c blueswir1
    DT0 = float64_mul(float32_to_float64(FT0, &env->fp_status),
107 44e7757c blueswir1
                      float32_to_float64(FT1, &env->fp_status),
108 44e7757c blueswir1
                      &env->fp_status);
109 44e7757c blueswir1
}
110 1a2fb1c0 blueswir1
111 4e14008f blueswir1
void helper_fdmulq(void)
112 4e14008f blueswir1
{
113 4e14008f blueswir1
    QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
114 4e14008f blueswir1
                       float64_to_float128(DT1, &env->fp_status),
115 4e14008f blueswir1
                       &env->fp_status);
116 4e14008f blueswir1
}
117 4e14008f blueswir1
118 44e7757c blueswir1
F_HELPER(neg, s)
119 44e7757c blueswir1
{
120 44e7757c blueswir1
    FT0 = float32_chs(FT1);
121 417454b0 blueswir1
}
122 417454b0 blueswir1
123 44e7757c blueswir1
#ifdef TARGET_SPARC64
124 44e7757c blueswir1
F_HELPER(neg, d)
125 7e8c2b6c blueswir1
{
126 44e7757c blueswir1
    DT0 = float64_chs(DT1);
127 7e8c2b6c blueswir1
}
128 4e14008f blueswir1
129 4e14008f blueswir1
F_HELPER(neg, q)
130 4e14008f blueswir1
{
131 4e14008f blueswir1
    QT0 = float128_chs(QT1);
132 4e14008f blueswir1
}
133 4e14008f blueswir1
#endif
134 44e7757c blueswir1
135 44e7757c blueswir1
/* Integer to float conversion.  */
136 44e7757c blueswir1
F_HELPER(ito, s)
137 a0c4cb4a bellard
{
138 ec230928 ths
    FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
139 a0c4cb4a bellard
}
140 a0c4cb4a bellard
141 44e7757c blueswir1
F_HELPER(ito, d)
142 a0c4cb4a bellard
{
143 ec230928 ths
    DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
144 a0c4cb4a bellard
}
145 9c2b428e blueswir1
146 4e14008f blueswir1
F_HELPER(ito, q)
147 4e14008f blueswir1
{
148 4e14008f blueswir1
    QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
149 4e14008f blueswir1
}
150 4e14008f blueswir1
151 1e64e78d blueswir1
#ifdef TARGET_SPARC64
152 44e7757c blueswir1
F_HELPER(xto, s)
153 1e64e78d blueswir1
{
154 1e64e78d blueswir1
    FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
155 1e64e78d blueswir1
}
156 1e64e78d blueswir1
157 44e7757c blueswir1
F_HELPER(xto, d)
158 1e64e78d blueswir1
{
159 1e64e78d blueswir1
    DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
160 1e64e78d blueswir1
}
161 64a88d5d blueswir1
162 4e14008f blueswir1
F_HELPER(xto, q)
163 4e14008f blueswir1
{
164 4e14008f blueswir1
    QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
165 4e14008f blueswir1
}
166 4e14008f blueswir1
#endif
167 44e7757c blueswir1
#undef F_HELPER
168 44e7757c blueswir1
169 44e7757c blueswir1
/* floating point conversion */
170 44e7757c blueswir1
void helper_fdtos(void)
171 44e7757c blueswir1
{
172 44e7757c blueswir1
    FT0 = float64_to_float32(DT1, &env->fp_status);
173 44e7757c blueswir1
}
174 44e7757c blueswir1
175 44e7757c blueswir1
void helper_fstod(void)
176 44e7757c blueswir1
{
177 44e7757c blueswir1
    DT0 = float32_to_float64(FT1, &env->fp_status);
178 44e7757c blueswir1
}
179 9c2b428e blueswir1
180 4e14008f blueswir1
void helper_fqtos(void)
181 4e14008f blueswir1
{
182 4e14008f blueswir1
    FT0 = float128_to_float32(QT1, &env->fp_status);
183 4e14008f blueswir1
}
184 4e14008f blueswir1
185 4e14008f blueswir1
void helper_fstoq(void)
186 4e14008f blueswir1
{
187 4e14008f blueswir1
    QT0 = float32_to_float128(FT1, &env->fp_status);
188 4e14008f blueswir1
}
189 4e14008f blueswir1
190 4e14008f blueswir1
void helper_fqtod(void)
191 4e14008f blueswir1
{
192 4e14008f blueswir1
    DT0 = float128_to_float64(QT1, &env->fp_status);
193 4e14008f blueswir1
}
194 4e14008f blueswir1
195 4e14008f blueswir1
void helper_fdtoq(void)
196 4e14008f blueswir1
{
197 4e14008f blueswir1
    QT0 = float64_to_float128(DT1, &env->fp_status);
198 4e14008f blueswir1
}
199 4e14008f blueswir1
200 44e7757c blueswir1
/* Float to integer conversion.  */
201 44e7757c blueswir1
void helper_fstoi(void)
202 44e7757c blueswir1
{
203 44e7757c blueswir1
    *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status);
204 44e7757c blueswir1
}
205 44e7757c blueswir1
206 44e7757c blueswir1
void helper_fdtoi(void)
207 44e7757c blueswir1
{
208 44e7757c blueswir1
    *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
209 44e7757c blueswir1
}
210 44e7757c blueswir1
211 4e14008f blueswir1
void helper_fqtoi(void)
212 4e14008f blueswir1
{
213 4e14008f blueswir1
    *((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status);
214 4e14008f blueswir1
}
215 4e14008f blueswir1
216 44e7757c blueswir1
#ifdef TARGET_SPARC64
217 44e7757c blueswir1
void helper_fstox(void)
218 44e7757c blueswir1
{
219 44e7757c blueswir1
    *((int64_t *)&DT0) = float32_to_int64_round_to_zero(FT1, &env->fp_status);
220 44e7757c blueswir1
}
221 44e7757c blueswir1
222 44e7757c blueswir1
void helper_fdtox(void)
223 44e7757c blueswir1
{
224 44e7757c blueswir1
    *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
225 44e7757c blueswir1
}
226 44e7757c blueswir1
227 4e14008f blueswir1
void helper_fqtox(void)
228 4e14008f blueswir1
{
229 4e14008f blueswir1
    *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
230 4e14008f blueswir1
}
231 4e14008f blueswir1
232 44e7757c blueswir1
void helper_faligndata(void)
233 44e7757c blueswir1
{
234 44e7757c blueswir1
    uint64_t tmp;
235 44e7757c blueswir1
236 44e7757c blueswir1
    tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
237 06057e6f blueswir1
    /* on many architectures a shift of 64 does nothing */
238 06057e6f blueswir1
    if ((env->gsr & 7) != 0) {
239 06057e6f blueswir1
        tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
240 06057e6f blueswir1
    }
241 44e7757c blueswir1
    *((uint64_t *)&DT0) = tmp;
242 44e7757c blueswir1
}
243 44e7757c blueswir1
244 44e7757c blueswir1
void helper_movl_FT0_0(void)
245 44e7757c blueswir1
{
246 44e7757c blueswir1
    *((uint32_t *)&FT0) = 0;
247 44e7757c blueswir1
}
248 44e7757c blueswir1
249 44e7757c blueswir1
void helper_movl_DT0_0(void)
250 44e7757c blueswir1
{
251 44e7757c blueswir1
    *((uint64_t *)&DT0) = 0;
252 44e7757c blueswir1
}
253 44e7757c blueswir1
254 44e7757c blueswir1
void helper_movl_FT0_1(void)
255 44e7757c blueswir1
{
256 44e7757c blueswir1
    *((uint32_t *)&FT0) = 0xffffffff;
257 44e7757c blueswir1
}
258 44e7757c blueswir1
259 44e7757c blueswir1
void helper_movl_DT0_1(void)
260 44e7757c blueswir1
{
261 44e7757c blueswir1
    *((uint64_t *)&DT0) = 0xffffffffffffffffULL;
262 44e7757c blueswir1
}
263 44e7757c blueswir1
264 44e7757c blueswir1
void helper_fnot(void)
265 44e7757c blueswir1
{
266 44e7757c blueswir1
    *(uint64_t *)&DT0 = ~*(uint64_t *)&DT1;
267 44e7757c blueswir1
}
268 44e7757c blueswir1
269 44e7757c blueswir1
void helper_fnots(void)
270 44e7757c blueswir1
{
271 44e7757c blueswir1
    *(uint32_t *)&FT0 = ~*(uint32_t *)&FT1;
272 44e7757c blueswir1
}
273 44e7757c blueswir1
274 44e7757c blueswir1
void helper_fnor(void)
275 44e7757c blueswir1
{
276 44e7757c blueswir1
    *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 | *(uint64_t *)&DT1);
277 44e7757c blueswir1
}
278 44e7757c blueswir1
279 44e7757c blueswir1
void helper_fnors(void)
280 44e7757c blueswir1
{
281 44e7757c blueswir1
    *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 | *(uint32_t *)&FT1);
282 44e7757c blueswir1
}
283 44e7757c blueswir1
284 44e7757c blueswir1
void helper_for(void)
285 44e7757c blueswir1
{
286 44e7757c blueswir1
    *(uint64_t *)&DT0 |= *(uint64_t *)&DT1;
287 44e7757c blueswir1
}
288 44e7757c blueswir1
289 44e7757c blueswir1
void helper_fors(void)
290 44e7757c blueswir1
{
291 44e7757c blueswir1
    *(uint32_t *)&FT0 |= *(uint32_t *)&FT1;
292 44e7757c blueswir1
}
293 44e7757c blueswir1
294 44e7757c blueswir1
void helper_fxor(void)
295 44e7757c blueswir1
{
296 44e7757c blueswir1
    *(uint64_t *)&DT0 ^= *(uint64_t *)&DT1;
297 44e7757c blueswir1
}
298 44e7757c blueswir1
299 44e7757c blueswir1
void helper_fxors(void)
300 44e7757c blueswir1
{
301 44e7757c blueswir1
    *(uint32_t *)&FT0 ^= *(uint32_t *)&FT1;
302 44e7757c blueswir1
}
303 44e7757c blueswir1
304 44e7757c blueswir1
void helper_fand(void)
305 44e7757c blueswir1
{
306 44e7757c blueswir1
    *(uint64_t *)&DT0 &= *(uint64_t *)&DT1;
307 44e7757c blueswir1
}
308 44e7757c blueswir1
309 44e7757c blueswir1
void helper_fands(void)
310 44e7757c blueswir1
{
311 44e7757c blueswir1
    *(uint32_t *)&FT0 &= *(uint32_t *)&FT1;
312 44e7757c blueswir1
}
313 44e7757c blueswir1
314 44e7757c blueswir1
void helper_fornot(void)
315 44e7757c blueswir1
{
316 44e7757c blueswir1
    *(uint64_t *)&DT0 = *(uint64_t *)&DT0 | ~*(uint64_t *)&DT1;
317 44e7757c blueswir1
}
318 44e7757c blueswir1
319 44e7757c blueswir1
void helper_fornots(void)
320 44e7757c blueswir1
{
321 44e7757c blueswir1
    *(uint32_t *)&FT0 = *(uint32_t *)&FT0 | ~*(uint32_t *)&FT1;
322 44e7757c blueswir1
}
323 44e7757c blueswir1
324 44e7757c blueswir1
void helper_fandnot(void)
325 44e7757c blueswir1
{
326 44e7757c blueswir1
    *(uint64_t *)&DT0 = *(uint64_t *)&DT0 & ~*(uint64_t *)&DT1;
327 44e7757c blueswir1
}
328 44e7757c blueswir1
329 44e7757c blueswir1
void helper_fandnots(void)
330 44e7757c blueswir1
{
331 44e7757c blueswir1
    *(uint32_t *)&FT0 = *(uint32_t *)&FT0 & ~*(uint32_t *)&FT1;
332 44e7757c blueswir1
}
333 44e7757c blueswir1
334 44e7757c blueswir1
void helper_fnand(void)
335 44e7757c blueswir1
{
336 44e7757c blueswir1
    *(uint64_t *)&DT0 = ~(*(uint64_t *)&DT0 & *(uint64_t *)&DT1);
337 44e7757c blueswir1
}
338 44e7757c blueswir1
339 44e7757c blueswir1
void helper_fnands(void)
340 44e7757c blueswir1
{
341 44e7757c blueswir1
    *(uint32_t *)&FT0 = ~(*(uint32_t *)&FT0 & *(uint32_t *)&FT1);
342 44e7757c blueswir1
}
343 44e7757c blueswir1
344 44e7757c blueswir1
void helper_fxnor(void)
345 44e7757c blueswir1
{
346 44e7757c blueswir1
    *(uint64_t *)&DT0 ^= ~*(uint64_t *)&DT1;
347 44e7757c blueswir1
}
348 44e7757c blueswir1
349 44e7757c blueswir1
void helper_fxnors(void)
350 44e7757c blueswir1
{
351 44e7757c blueswir1
    *(uint32_t *)&FT0 ^= ~*(uint32_t *)&FT1;
352 44e7757c blueswir1
}
353 44e7757c blueswir1
354 44e7757c blueswir1
#ifdef WORDS_BIGENDIAN
355 44e7757c blueswir1
#define VIS_B64(n) b[7 - (n)]
356 44e7757c blueswir1
#define VIS_W64(n) w[3 - (n)]
357 44e7757c blueswir1
#define VIS_SW64(n) sw[3 - (n)]
358 44e7757c blueswir1
#define VIS_L64(n) l[1 - (n)]
359 44e7757c blueswir1
#define VIS_B32(n) b[3 - (n)]
360 44e7757c blueswir1
#define VIS_W32(n) w[1 - (n)]
361 44e7757c blueswir1
#else
362 44e7757c blueswir1
#define VIS_B64(n) b[n]
363 44e7757c blueswir1
#define VIS_W64(n) w[n]
364 44e7757c blueswir1
#define VIS_SW64(n) sw[n]
365 44e7757c blueswir1
#define VIS_L64(n) l[n]
366 44e7757c blueswir1
#define VIS_B32(n) b[n]
367 44e7757c blueswir1
#define VIS_W32(n) w[n]
368 44e7757c blueswir1
#endif
369 44e7757c blueswir1
370 44e7757c blueswir1
typedef union {
371 44e7757c blueswir1
    uint8_t b[8];
372 44e7757c blueswir1
    uint16_t w[4];
373 44e7757c blueswir1
    int16_t sw[4];
374 44e7757c blueswir1
    uint32_t l[2];
375 44e7757c blueswir1
    float64 d;
376 44e7757c blueswir1
} vis64;
377 44e7757c blueswir1
378 44e7757c blueswir1
typedef union {
379 44e7757c blueswir1
    uint8_t b[4];
380 44e7757c blueswir1
    uint16_t w[2];
381 44e7757c blueswir1
    uint32_t l;
382 44e7757c blueswir1
    float32 f;
383 44e7757c blueswir1
} vis32;
384 44e7757c blueswir1
385 44e7757c blueswir1
void helper_fpmerge(void)
386 44e7757c blueswir1
{
387 44e7757c blueswir1
    vis64 s, d;
388 44e7757c blueswir1
389 44e7757c blueswir1
    s.d = DT0;
390 44e7757c blueswir1
    d.d = DT1;
391 44e7757c blueswir1
392 44e7757c blueswir1
    // Reverse calculation order to handle overlap
393 44e7757c blueswir1
    d.VIS_B64(7) = s.VIS_B64(3);
394 44e7757c blueswir1
    d.VIS_B64(6) = d.VIS_B64(3);
395 44e7757c blueswir1
    d.VIS_B64(5) = s.VIS_B64(2);
396 44e7757c blueswir1
    d.VIS_B64(4) = d.VIS_B64(2);
397 44e7757c blueswir1
    d.VIS_B64(3) = s.VIS_B64(1);
398 44e7757c blueswir1
    d.VIS_B64(2) = d.VIS_B64(1);
399 44e7757c blueswir1
    d.VIS_B64(1) = s.VIS_B64(0);
400 44e7757c blueswir1
    //d.VIS_B64(0) = d.VIS_B64(0);
401 44e7757c blueswir1
402 44e7757c blueswir1
    DT0 = d.d;
403 44e7757c blueswir1
}
404 44e7757c blueswir1
405 44e7757c blueswir1
void helper_fmul8x16(void)
406 44e7757c blueswir1
{
407 44e7757c blueswir1
    vis64 s, d;
408 44e7757c blueswir1
    uint32_t tmp;
409 44e7757c blueswir1
410 44e7757c blueswir1
    s.d = DT0;
411 44e7757c blueswir1
    d.d = DT1;
412 44e7757c blueswir1
413 44e7757c blueswir1
#define PMUL(r)                                                 \
414 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r);       \
415 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                    \
416 44e7757c blueswir1
        tmp += 0x100;                                           \
417 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
418 44e7757c blueswir1
419 44e7757c blueswir1
    PMUL(0);
420 44e7757c blueswir1
    PMUL(1);
421 44e7757c blueswir1
    PMUL(2);
422 44e7757c blueswir1
    PMUL(3);
423 44e7757c blueswir1
#undef PMUL
424 44e7757c blueswir1
425 44e7757c blueswir1
    DT0 = d.d;
426 44e7757c blueswir1
}
427 44e7757c blueswir1
428 44e7757c blueswir1
void helper_fmul8x16al(void)
429 44e7757c blueswir1
{
430 44e7757c blueswir1
    vis64 s, d;
431 44e7757c blueswir1
    uint32_t tmp;
432 44e7757c blueswir1
433 44e7757c blueswir1
    s.d = DT0;
434 44e7757c blueswir1
    d.d = DT1;
435 44e7757c blueswir1
436 44e7757c blueswir1
#define PMUL(r)                                                 \
437 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r);       \
438 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                    \
439 44e7757c blueswir1
        tmp += 0x100;                                           \
440 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
441 44e7757c blueswir1
442 44e7757c blueswir1
    PMUL(0);
443 44e7757c blueswir1
    PMUL(1);
444 44e7757c blueswir1
    PMUL(2);
445 44e7757c blueswir1
    PMUL(3);
446 44e7757c blueswir1
#undef PMUL
447 44e7757c blueswir1
448 44e7757c blueswir1
    DT0 = d.d;
449 44e7757c blueswir1
}
450 44e7757c blueswir1
451 44e7757c blueswir1
void helper_fmul8x16au(void)
452 44e7757c blueswir1
{
453 44e7757c blueswir1
    vis64 s, d;
454 44e7757c blueswir1
    uint32_t tmp;
455 44e7757c blueswir1
456 44e7757c blueswir1
    s.d = DT0;
457 44e7757c blueswir1
    d.d = DT1;
458 44e7757c blueswir1
459 44e7757c blueswir1
#define PMUL(r)                                                 \
460 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r);       \
461 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                    \
462 44e7757c blueswir1
        tmp += 0x100;                                           \
463 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
464 44e7757c blueswir1
465 44e7757c blueswir1
    PMUL(0);
466 44e7757c blueswir1
    PMUL(1);
467 44e7757c blueswir1
    PMUL(2);
468 44e7757c blueswir1
    PMUL(3);
469 44e7757c blueswir1
#undef PMUL
470 44e7757c blueswir1
471 44e7757c blueswir1
    DT0 = d.d;
472 44e7757c blueswir1
}
473 44e7757c blueswir1
474 44e7757c blueswir1
void helper_fmul8sux16(void)
475 44e7757c blueswir1
{
476 44e7757c blueswir1
    vis64 s, d;
477 44e7757c blueswir1
    uint32_t tmp;
478 44e7757c blueswir1
479 44e7757c blueswir1
    s.d = DT0;
480 44e7757c blueswir1
    d.d = DT1;
481 44e7757c blueswir1
482 44e7757c blueswir1
#define PMUL(r)                                                         \
483 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
484 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                            \
485 44e7757c blueswir1
        tmp += 0x100;                                                   \
486 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
487 44e7757c blueswir1
488 44e7757c blueswir1
    PMUL(0);
489 44e7757c blueswir1
    PMUL(1);
490 44e7757c blueswir1
    PMUL(2);
491 44e7757c blueswir1
    PMUL(3);
492 44e7757c blueswir1
#undef PMUL
493 44e7757c blueswir1
494 44e7757c blueswir1
    DT0 = d.d;
495 44e7757c blueswir1
}
496 44e7757c blueswir1
497 44e7757c blueswir1
void helper_fmul8ulx16(void)
498 44e7757c blueswir1
{
499 44e7757c blueswir1
    vis64 s, d;
500 44e7757c blueswir1
    uint32_t tmp;
501 44e7757c blueswir1
502 44e7757c blueswir1
    s.d = DT0;
503 44e7757c blueswir1
    d.d = DT1;
504 44e7757c blueswir1
505 44e7757c blueswir1
#define PMUL(r)                                                         \
506 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
507 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                            \
508 44e7757c blueswir1
        tmp += 0x100;                                                   \
509 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
510 44e7757c blueswir1
511 44e7757c blueswir1
    PMUL(0);
512 44e7757c blueswir1
    PMUL(1);
513 44e7757c blueswir1
    PMUL(2);
514 44e7757c blueswir1
    PMUL(3);
515 44e7757c blueswir1
#undef PMUL
516 44e7757c blueswir1
517 44e7757c blueswir1
    DT0 = d.d;
518 44e7757c blueswir1
}
519 44e7757c blueswir1
520 44e7757c blueswir1
void helper_fmuld8sux16(void)
521 44e7757c blueswir1
{
522 44e7757c blueswir1
    vis64 s, d;
523 44e7757c blueswir1
    uint32_t tmp;
524 44e7757c blueswir1
525 44e7757c blueswir1
    s.d = DT0;
526 44e7757c blueswir1
    d.d = DT1;
527 44e7757c blueswir1
528 44e7757c blueswir1
#define PMUL(r)                                                         \
529 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
530 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                            \
531 44e7757c blueswir1
        tmp += 0x100;                                                   \
532 44e7757c blueswir1
    d.VIS_L64(r) = tmp;
533 44e7757c blueswir1
534 44e7757c blueswir1
    // Reverse calculation order to handle overlap
535 44e7757c blueswir1
    PMUL(1);
536 44e7757c blueswir1
    PMUL(0);
537 44e7757c blueswir1
#undef PMUL
538 44e7757c blueswir1
539 44e7757c blueswir1
    DT0 = d.d;
540 44e7757c blueswir1
}
541 44e7757c blueswir1
542 44e7757c blueswir1
void helper_fmuld8ulx16(void)
543 44e7757c blueswir1
{
544 44e7757c blueswir1
    vis64 s, d;
545 44e7757c blueswir1
    uint32_t tmp;
546 44e7757c blueswir1
547 44e7757c blueswir1
    s.d = DT0;
548 44e7757c blueswir1
    d.d = DT1;
549 44e7757c blueswir1
550 44e7757c blueswir1
#define PMUL(r)                                                         \
551 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
552 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                            \
553 44e7757c blueswir1
        tmp += 0x100;                                                   \
554 44e7757c blueswir1
    d.VIS_L64(r) = tmp;
555 44e7757c blueswir1
556 44e7757c blueswir1
    // Reverse calculation order to handle overlap
557 44e7757c blueswir1
    PMUL(1);
558 44e7757c blueswir1
    PMUL(0);
559 44e7757c blueswir1
#undef PMUL
560 44e7757c blueswir1
561 44e7757c blueswir1
    DT0 = d.d;
562 44e7757c blueswir1
}
563 44e7757c blueswir1
564 44e7757c blueswir1
void helper_fexpand(void)
565 44e7757c blueswir1
{
566 44e7757c blueswir1
    vis32 s;
567 44e7757c blueswir1
    vis64 d;
568 44e7757c blueswir1
569 44e7757c blueswir1
    s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
570 44e7757c blueswir1
    d.d = DT1;
571 44e7757c blueswir1
    d.VIS_L64(0) = s.VIS_W32(0) << 4;
572 44e7757c blueswir1
    d.VIS_L64(1) = s.VIS_W32(1) << 4;
573 44e7757c blueswir1
    d.VIS_L64(2) = s.VIS_W32(2) << 4;
574 44e7757c blueswir1
    d.VIS_L64(3) = s.VIS_W32(3) << 4;
575 44e7757c blueswir1
576 44e7757c blueswir1
    DT0 = d.d;
577 44e7757c blueswir1
}
578 44e7757c blueswir1
579 44e7757c blueswir1
#define VIS_HELPER(name, F)                             \
580 44e7757c blueswir1
    void name##16(void)                                 \
581 44e7757c blueswir1
    {                                                   \
582 44e7757c blueswir1
        vis64 s, d;                                     \
583 44e7757c blueswir1
                                                        \
584 44e7757c blueswir1
        s.d = DT0;                                      \
585 44e7757c blueswir1
        d.d = DT1;                                      \
586 44e7757c blueswir1
                                                        \
587 44e7757c blueswir1
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0));   \
588 44e7757c blueswir1
        d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1));   \
589 44e7757c blueswir1
        d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2));   \
590 44e7757c blueswir1
        d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3));   \
591 44e7757c blueswir1
                                                        \
592 44e7757c blueswir1
        DT0 = d.d;                                      \
593 44e7757c blueswir1
    }                                                   \
594 44e7757c blueswir1
                                                        \
595 44e7757c blueswir1
    void name##16s(void)                                \
596 44e7757c blueswir1
    {                                                   \
597 44e7757c blueswir1
        vis32 s, d;                                     \
598 44e7757c blueswir1
                                                        \
599 44e7757c blueswir1
        s.f = FT0;                                      \
600 44e7757c blueswir1
        d.f = FT1;                                      \
601 44e7757c blueswir1
                                                        \
602 44e7757c blueswir1
        d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0));   \
603 44e7757c blueswir1
        d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1));   \
604 44e7757c blueswir1
                                                        \
605 44e7757c blueswir1
        FT0 = d.f;                                      \
606 44e7757c blueswir1
    }                                                   \
607 44e7757c blueswir1
                                                        \
608 44e7757c blueswir1
    void name##32(void)                                 \
609 44e7757c blueswir1
    {                                                   \
610 44e7757c blueswir1
        vis64 s, d;                                     \
611 44e7757c blueswir1
                                                        \
612 44e7757c blueswir1
        s.d = DT0;                                      \
613 44e7757c blueswir1
        d.d = DT1;                                      \
614 44e7757c blueswir1
                                                        \
615 44e7757c blueswir1
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0));   \
616 44e7757c blueswir1
        d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1));   \
617 44e7757c blueswir1
                                                        \
618 44e7757c blueswir1
        DT0 = d.d;                                      \
619 44e7757c blueswir1
    }                                                   \
620 44e7757c blueswir1
                                                        \
621 44e7757c blueswir1
    void name##32s(void)                                \
622 44e7757c blueswir1
    {                                                   \
623 44e7757c blueswir1
        vis32 s, d;                                     \
624 44e7757c blueswir1
                                                        \
625 44e7757c blueswir1
        s.f = FT0;                                      \
626 44e7757c blueswir1
        d.f = FT1;                                      \
627 44e7757c blueswir1
                                                        \
628 44e7757c blueswir1
        d.l = F(d.l, s.l);                              \
629 44e7757c blueswir1
                                                        \
630 44e7757c blueswir1
        FT0 = d.f;                                      \
631 44e7757c blueswir1
    }
632 44e7757c blueswir1
633 44e7757c blueswir1
#define FADD(a, b) ((a) + (b))
634 44e7757c blueswir1
#define FSUB(a, b) ((a) - (b))
635 44e7757c blueswir1
VIS_HELPER(helper_fpadd, FADD)
636 44e7757c blueswir1
VIS_HELPER(helper_fpsub, FSUB)
637 44e7757c blueswir1
638 44e7757c blueswir1
#define VIS_CMPHELPER(name, F)                                        \
639 44e7757c blueswir1
    void name##16(void)                                           \
640 44e7757c blueswir1
    {                                                             \
641 44e7757c blueswir1
        vis64 s, d;                                               \
642 44e7757c blueswir1
                                                                  \
643 44e7757c blueswir1
        s.d = DT0;                                                \
644 44e7757c blueswir1
        d.d = DT1;                                                \
645 44e7757c blueswir1
                                                                  \
646 44e7757c blueswir1
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0;       \
647 44e7757c blueswir1
        d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0;      \
648 44e7757c blueswir1
        d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0;      \
649 44e7757c blueswir1
        d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0;      \
650 44e7757c blueswir1
                                                                  \
651 44e7757c blueswir1
        DT0 = d.d;                                                \
652 44e7757c blueswir1
    }                                                             \
653 44e7757c blueswir1
                                                                  \
654 44e7757c blueswir1
    void name##32(void)                                           \
655 44e7757c blueswir1
    {                                                             \
656 44e7757c blueswir1
        vis64 s, d;                                               \
657 44e7757c blueswir1
                                                                  \
658 44e7757c blueswir1
        s.d = DT0;                                                \
659 44e7757c blueswir1
        d.d = DT1;                                                \
660 44e7757c blueswir1
                                                                  \
661 44e7757c blueswir1
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0;       \
662 44e7757c blueswir1
        d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0;      \
663 44e7757c blueswir1
                                                                  \
664 44e7757c blueswir1
        DT0 = d.d;                                                \
665 44e7757c blueswir1
    }
666 44e7757c blueswir1
667 44e7757c blueswir1
#define FCMPGT(a, b) ((a) > (b))
668 44e7757c blueswir1
#define FCMPEQ(a, b) ((a) == (b))
669 44e7757c blueswir1
#define FCMPLE(a, b) ((a) <= (b))
670 44e7757c blueswir1
#define FCMPNE(a, b) ((a) != (b))
671 44e7757c blueswir1
672 44e7757c blueswir1
VIS_CMPHELPER(helper_fcmpgt, FCMPGT)
673 44e7757c blueswir1
VIS_CMPHELPER(helper_fcmpeq, FCMPEQ)
674 44e7757c blueswir1
VIS_CMPHELPER(helper_fcmple, FCMPLE)
675 44e7757c blueswir1
VIS_CMPHELPER(helper_fcmpne, FCMPNE)
676 44e7757c blueswir1
#endif
677 44e7757c blueswir1
678 44e7757c blueswir1
void helper_check_ieee_exceptions(void)
679 44e7757c blueswir1
{
680 44e7757c blueswir1
    target_ulong status;
681 44e7757c blueswir1
682 44e7757c blueswir1
    status = get_float_exception_flags(&env->fp_status);
683 44e7757c blueswir1
    if (status) {
684 44e7757c blueswir1
        /* Copy IEEE 754 flags into FSR */
685 44e7757c blueswir1
        if (status & float_flag_invalid)
686 44e7757c blueswir1
            env->fsr |= FSR_NVC;
687 44e7757c blueswir1
        if (status & float_flag_overflow)
688 44e7757c blueswir1
            env->fsr |= FSR_OFC;
689 44e7757c blueswir1
        if (status & float_flag_underflow)
690 44e7757c blueswir1
            env->fsr |= FSR_UFC;
691 44e7757c blueswir1
        if (status & float_flag_divbyzero)
692 44e7757c blueswir1
            env->fsr |= FSR_DZC;
693 44e7757c blueswir1
        if (status & float_flag_inexact)
694 44e7757c blueswir1
            env->fsr |= FSR_NXC;
695 44e7757c blueswir1
696 44e7757c blueswir1
        if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) {
697 44e7757c blueswir1
            /* Unmasked exception, generate a trap */
698 44e7757c blueswir1
            env->fsr |= FSR_FTT_IEEE_EXCP;
699 44e7757c blueswir1
            raise_exception(TT_FP_EXCP);
700 44e7757c blueswir1
        } else {
701 44e7757c blueswir1
            /* Accumulate exceptions */
702 44e7757c blueswir1
            env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
703 44e7757c blueswir1
        }
704 44e7757c blueswir1
    }
705 44e7757c blueswir1
}
706 44e7757c blueswir1
707 44e7757c blueswir1
void helper_clear_float_exceptions(void)
708 44e7757c blueswir1
{
709 44e7757c blueswir1
    set_float_exception_flags(0, &env->fp_status);
710 44e7757c blueswir1
}
711 44e7757c blueswir1
712 7e8c2b6c blueswir1
void helper_fabss(void)
713 e8af50a3 bellard
{
714 7a0e1f41 bellard
    FT0 = float32_abs(FT1);
715 e8af50a3 bellard
}
716 e8af50a3 bellard
717 3475187d bellard
#ifdef TARGET_SPARC64
718 7e8c2b6c blueswir1
void helper_fabsd(void)
719 3475187d bellard
{
720 3475187d bellard
    DT0 = float64_abs(DT1);
721 3475187d bellard
}
722 4e14008f blueswir1
723 4e14008f blueswir1
void helper_fabsq(void)
724 4e14008f blueswir1
{
725 4e14008f blueswir1
    QT0 = float128_abs(QT1);
726 4e14008f blueswir1
}
727 4e14008f blueswir1
#endif
728 3475187d bellard
729 7e8c2b6c blueswir1
void helper_fsqrts(void)
730 e8af50a3 bellard
{
731 7a0e1f41 bellard
    FT0 = float32_sqrt(FT1, &env->fp_status);
732 e8af50a3 bellard
}
733 e8af50a3 bellard
734 7e8c2b6c blueswir1
void helper_fsqrtd(void)
735 e8af50a3 bellard
{
736 7a0e1f41 bellard
    DT0 = float64_sqrt(DT1, &env->fp_status);
737 e8af50a3 bellard
}
738 e8af50a3 bellard
739 4e14008f blueswir1
void helper_fsqrtq(void)
740 4e14008f blueswir1
{
741 4e14008f blueswir1
    QT0 = float128_sqrt(QT1, &env->fp_status);
742 4e14008f blueswir1
}
743 4e14008f blueswir1
744 417454b0 blueswir1
#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP)                      \
745 7e8c2b6c blueswir1
    void glue(helper_, name) (void)                                     \
746 65ce8c2f bellard
    {                                                                   \
747 1a2fb1c0 blueswir1
        target_ulong new_fsr;                                           \
748 1a2fb1c0 blueswir1
                                                                        \
749 65ce8c2f bellard
        env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                     \
750 65ce8c2f bellard
        switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) {   \
751 65ce8c2f bellard
        case float_relation_unordered:                                  \
752 1a2fb1c0 blueswir1
            new_fsr = (FSR_FCC1 | FSR_FCC0) << FS;                      \
753 417454b0 blueswir1
            if ((env->fsr & FSR_NVM) || TRAP) {                         \
754 1a2fb1c0 blueswir1
                env->fsr |= new_fsr;                                    \
755 417454b0 blueswir1
                env->fsr |= FSR_NVC;                                    \
756 417454b0 blueswir1
                env->fsr |= FSR_FTT_IEEE_EXCP;                          \
757 65ce8c2f bellard
                raise_exception(TT_FP_EXCP);                            \
758 65ce8c2f bellard
            } else {                                                    \
759 65ce8c2f bellard
                env->fsr |= FSR_NVA;                                    \
760 65ce8c2f bellard
            }                                                           \
761 65ce8c2f bellard
            break;                                                      \
762 65ce8c2f bellard
        case float_relation_less:                                       \
763 1a2fb1c0 blueswir1
            new_fsr = FSR_FCC0 << FS;                                   \
764 65ce8c2f bellard
            break;                                                      \
765 65ce8c2f bellard
        case float_relation_greater:                                    \
766 1a2fb1c0 blueswir1
            new_fsr = FSR_FCC1 << FS;                                   \
767 65ce8c2f bellard
            break;                                                      \
768 65ce8c2f bellard
        default:                                                        \
769 1a2fb1c0 blueswir1
            new_fsr = 0;                                                \
770 65ce8c2f bellard
            break;                                                      \
771 65ce8c2f bellard
        }                                                               \
772 1a2fb1c0 blueswir1
        env->fsr |= new_fsr;                                            \
773 e8af50a3 bellard
    }
774 e8af50a3 bellard
775 417454b0 blueswir1
GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0);
776 417454b0 blueswir1
GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0);
777 417454b0 blueswir1
778 417454b0 blueswir1
GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1);
779 417454b0 blueswir1
GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1);
780 3475187d bellard
781 4e14008f blueswir1
GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
782 4e14008f blueswir1
GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
783 4e14008f blueswir1
784 3475187d bellard
#ifdef TARGET_SPARC64
785 417454b0 blueswir1
GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0);
786 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
787 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
788 417454b0 blueswir1
789 417454b0 blueswir1
GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0);
790 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
791 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
792 417454b0 blueswir1
793 417454b0 blueswir1
GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0);
794 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
795 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
796 417454b0 blueswir1
797 417454b0 blueswir1
GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1);
798 417454b0 blueswir1
GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
799 64a88d5d blueswir1
GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
800 3475187d bellard
801 417454b0 blueswir1
GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1);
802 417454b0 blueswir1
GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
803 64a88d5d blueswir1
GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
804 3475187d bellard
805 417454b0 blueswir1
GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
806 417454b0 blueswir1
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
807 4e14008f blueswir1
GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
808 4e14008f blueswir1
#endif
809 3475187d bellard
810 77f193da blueswir1
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \
811 77f193da blueswir1
    defined(DEBUG_MXCC)
812 952a328f blueswir1
static void dump_mxcc(CPUState *env)
813 952a328f blueswir1
{
814 952a328f blueswir1
    printf("mxccdata: %016llx %016llx %016llx %016llx\n",
815 77f193da blueswir1
           env->mxccdata[0], env->mxccdata[1],
816 77f193da blueswir1
           env->mxccdata[2], env->mxccdata[3]);
817 952a328f blueswir1
    printf("mxccregs: %016llx %016llx %016llx %016llx\n"
818 952a328f blueswir1
           "          %016llx %016llx %016llx %016llx\n",
819 77f193da blueswir1
           env->mxccregs[0], env->mxccregs[1],
820 77f193da blueswir1
           env->mxccregs[2], env->mxccregs[3],
821 77f193da blueswir1
           env->mxccregs[4], env->mxccregs[5],
822 77f193da blueswir1
           env->mxccregs[6], env->mxccregs[7]);
823 952a328f blueswir1
}
824 952a328f blueswir1
#endif
825 952a328f blueswir1
826 1a2fb1c0 blueswir1
#if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)) \
827 1a2fb1c0 blueswir1
    && defined(DEBUG_ASI)
828 1a2fb1c0 blueswir1
static void dump_asi(const char *txt, target_ulong addr, int asi, int size,
829 1a2fb1c0 blueswir1
                     uint64_t r1)
830 8543e2cf blueswir1
{
831 8543e2cf blueswir1
    switch (size)
832 8543e2cf blueswir1
    {
833 8543e2cf blueswir1
    case 1:
834 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt,
835 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xff);
836 8543e2cf blueswir1
        break;
837 8543e2cf blueswir1
    case 2:
838 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt,
839 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xffff);
840 8543e2cf blueswir1
        break;
841 8543e2cf blueswir1
    case 4:
842 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt,
843 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xffffffff);
844 8543e2cf blueswir1
        break;
845 8543e2cf blueswir1
    case 8:
846 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt,
847 1a2fb1c0 blueswir1
                    addr, asi, r1);
848 8543e2cf blueswir1
        break;
849 8543e2cf blueswir1
    }
850 8543e2cf blueswir1
}
851 8543e2cf blueswir1
#endif
852 8543e2cf blueswir1
853 1a2fb1c0 blueswir1
#ifndef TARGET_SPARC64
854 1a2fb1c0 blueswir1
#ifndef CONFIG_USER_ONLY
855 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
856 e8af50a3 bellard
{
857 1a2fb1c0 blueswir1
    uint64_t ret = 0;
858 8543e2cf blueswir1
#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
859 1a2fb1c0 blueswir1
    uint32_t last_addr = addr;
860 952a328f blueswir1
#endif
861 e80cfcfc bellard
862 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
863 e80cfcfc bellard
    switch (asi) {
864 6c36d3fa blueswir1
    case 2: /* SuperSparc MXCC registers */
865 1a2fb1c0 blueswir1
        switch (addr) {
866 952a328f blueswir1
        case 0x01c00a00: /* MXCC control register */
867 1a2fb1c0 blueswir1
            if (size == 8)
868 1a2fb1c0 blueswir1
                ret = env->mxccregs[3];
869 1a2fb1c0 blueswir1
            else
870 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
871 77f193da blueswir1
                             size);
872 952a328f blueswir1
            break;
873 952a328f blueswir1
        case 0x01c00a04: /* MXCC control register */
874 952a328f blueswir1
            if (size == 4)
875 952a328f blueswir1
                ret = env->mxccregs[3];
876 952a328f blueswir1
            else
877 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
878 77f193da blueswir1
                             size);
879 952a328f blueswir1
            break;
880 295db113 blueswir1
        case 0x01c00c00: /* Module reset register */
881 295db113 blueswir1
            if (size == 8) {
882 1a2fb1c0 blueswir1
                ret = env->mxccregs[5];
883 295db113 blueswir1
                // should we do something here?
884 295db113 blueswir1
            } else
885 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
886 77f193da blueswir1
                             size);
887 295db113 blueswir1
            break;
888 952a328f blueswir1
        case 0x01c00f00: /* MBus port address register */
889 1a2fb1c0 blueswir1
            if (size == 8)
890 1a2fb1c0 blueswir1
                ret = env->mxccregs[7];
891 1a2fb1c0 blueswir1
            else
892 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
893 77f193da blueswir1
                             size);
894 952a328f blueswir1
            break;
895 952a328f blueswir1
        default:
896 77f193da blueswir1
            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
897 77f193da blueswir1
                         size);
898 952a328f blueswir1
            break;
899 952a328f blueswir1
        }
900 77f193da blueswir1
        DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
901 77f193da blueswir1
                     "addr = %08x -> ret = %08x,"
902 1a2fb1c0 blueswir1
                     "addr = %08x\n", asi, size, sign, last_addr, ret, addr);
903 952a328f blueswir1
#ifdef DEBUG_MXCC
904 952a328f blueswir1
        dump_mxcc(env);
905 952a328f blueswir1
#endif
906 6c36d3fa blueswir1
        break;
907 e8af50a3 bellard
    case 3: /* MMU probe */
908 0f8a249a blueswir1
        {
909 0f8a249a blueswir1
            int mmulev;
910 0f8a249a blueswir1
911 1a2fb1c0 blueswir1
            mmulev = (addr >> 8) & 15;
912 0f8a249a blueswir1
            if (mmulev > 4)
913 0f8a249a blueswir1
                ret = 0;
914 1a2fb1c0 blueswir1
            else
915 1a2fb1c0 blueswir1
                ret = mmu_probe(env, addr, mmulev);
916 1a2fb1c0 blueswir1
            DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n",
917 1a2fb1c0 blueswir1
                        addr, mmulev, ret);
918 0f8a249a blueswir1
        }
919 0f8a249a blueswir1
        break;
920 e8af50a3 bellard
    case 4: /* read MMU regs */
921 0f8a249a blueswir1
        {
922 1a2fb1c0 blueswir1
            int reg = (addr >> 8) & 0x1f;
923 3b46e624 ths
924 0f8a249a blueswir1
            ret = env->mmuregs[reg];
925 0f8a249a blueswir1
            if (reg == 3) /* Fault status cleared on read */
926 3dd9a152 blueswir1
                env->mmuregs[3] = 0;
927 3dd9a152 blueswir1
            else if (reg == 0x13) /* Fault status read */
928 3dd9a152 blueswir1
                ret = env->mmuregs[3];
929 3dd9a152 blueswir1
            else if (reg == 0x14) /* Fault address read */
930 3dd9a152 blueswir1
                ret = env->mmuregs[4];
931 1a2fb1c0 blueswir1
            DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
932 0f8a249a blueswir1
        }
933 0f8a249a blueswir1
        break;
934 045380be blueswir1
    case 5: // Turbosparc ITLB Diagnostic
935 045380be blueswir1
    case 6: // Turbosparc DTLB Diagnostic
936 045380be blueswir1
    case 7: // Turbosparc IOTLB Diagnostic
937 045380be blueswir1
        break;
938 6c36d3fa blueswir1
    case 9: /* Supervisor code access */
939 6c36d3fa blueswir1
        switch(size) {
940 6c36d3fa blueswir1
        case 1:
941 1a2fb1c0 blueswir1
            ret = ldub_code(addr);
942 6c36d3fa blueswir1
            break;
943 6c36d3fa blueswir1
        case 2:
944 a4e7dd52 blueswir1
            ret = lduw_code(addr);
945 6c36d3fa blueswir1
            break;
946 6c36d3fa blueswir1
        default:
947 6c36d3fa blueswir1
        case 4:
948 a4e7dd52 blueswir1
            ret = ldl_code(addr);
949 6c36d3fa blueswir1
            break;
950 6c36d3fa blueswir1
        case 8:
951 a4e7dd52 blueswir1
            ret = ldq_code(addr);
952 6c36d3fa blueswir1
            break;
953 6c36d3fa blueswir1
        }
954 6c36d3fa blueswir1
        break;
955 81ad8ba2 blueswir1
    case 0xa: /* User data access */
956 81ad8ba2 blueswir1
        switch(size) {
957 81ad8ba2 blueswir1
        case 1:
958 1a2fb1c0 blueswir1
            ret = ldub_user(addr);
959 81ad8ba2 blueswir1
            break;
960 81ad8ba2 blueswir1
        case 2:
961 a4e7dd52 blueswir1
            ret = lduw_user(addr);
962 81ad8ba2 blueswir1
            break;
963 81ad8ba2 blueswir1
        default:
964 81ad8ba2 blueswir1
        case 4:
965 a4e7dd52 blueswir1
            ret = ldl_user(addr);
966 81ad8ba2 blueswir1
            break;
967 81ad8ba2 blueswir1
        case 8:
968 a4e7dd52 blueswir1
            ret = ldq_user(addr);
969 81ad8ba2 blueswir1
            break;
970 81ad8ba2 blueswir1
        }
971 81ad8ba2 blueswir1
        break;
972 81ad8ba2 blueswir1
    case 0xb: /* Supervisor data access */
973 81ad8ba2 blueswir1
        switch(size) {
974 81ad8ba2 blueswir1
        case 1:
975 1a2fb1c0 blueswir1
            ret = ldub_kernel(addr);
976 81ad8ba2 blueswir1
            break;
977 81ad8ba2 blueswir1
        case 2:
978 a4e7dd52 blueswir1
            ret = lduw_kernel(addr);
979 81ad8ba2 blueswir1
            break;
980 81ad8ba2 blueswir1
        default:
981 81ad8ba2 blueswir1
        case 4:
982 a4e7dd52 blueswir1
            ret = ldl_kernel(addr);
983 81ad8ba2 blueswir1
            break;
984 81ad8ba2 blueswir1
        case 8:
985 a4e7dd52 blueswir1
            ret = ldq_kernel(addr);
986 81ad8ba2 blueswir1
            break;
987 81ad8ba2 blueswir1
        }
988 81ad8ba2 blueswir1
        break;
989 6c36d3fa blueswir1
    case 0xc: /* I-cache tag */
990 6c36d3fa blueswir1
    case 0xd: /* I-cache data */
991 6c36d3fa blueswir1
    case 0xe: /* D-cache tag */
992 6c36d3fa blueswir1
    case 0xf: /* D-cache data */
993 6c36d3fa blueswir1
        break;
994 6c36d3fa blueswir1
    case 0x20: /* MMU passthrough */
995 02aab46a bellard
        switch(size) {
996 02aab46a bellard
        case 1:
997 1a2fb1c0 blueswir1
            ret = ldub_phys(addr);
998 02aab46a bellard
            break;
999 02aab46a bellard
        case 2:
1000 a4e7dd52 blueswir1
            ret = lduw_phys(addr);
1001 02aab46a bellard
            break;
1002 02aab46a bellard
        default:
1003 02aab46a bellard
        case 4:
1004 a4e7dd52 blueswir1
            ret = ldl_phys(addr);
1005 02aab46a bellard
            break;
1006 9e61bde5 bellard
        case 8:
1007 a4e7dd52 blueswir1
            ret = ldq_phys(addr);
1008 0f8a249a blueswir1
            break;
1009 02aab46a bellard
        }
1010 0f8a249a blueswir1
        break;
1011 7d85892b blueswir1
    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1012 5dcb6b91 blueswir1
        switch(size) {
1013 5dcb6b91 blueswir1
        case 1:
1014 1a2fb1c0 blueswir1
            ret = ldub_phys((target_phys_addr_t)addr
1015 5dcb6b91 blueswir1
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
1016 5dcb6b91 blueswir1
            break;
1017 5dcb6b91 blueswir1
        case 2:
1018 a4e7dd52 blueswir1
            ret = lduw_phys((target_phys_addr_t)addr
1019 5dcb6b91 blueswir1
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
1020 5dcb6b91 blueswir1
            break;
1021 5dcb6b91 blueswir1
        default:
1022 5dcb6b91 blueswir1
        case 4:
1023 a4e7dd52 blueswir1
            ret = ldl_phys((target_phys_addr_t)addr
1024 5dcb6b91 blueswir1
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
1025 5dcb6b91 blueswir1
            break;
1026 5dcb6b91 blueswir1
        case 8:
1027 a4e7dd52 blueswir1
            ret = ldq_phys((target_phys_addr_t)addr
1028 5dcb6b91 blueswir1
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
1029 0f8a249a blueswir1
            break;
1030 5dcb6b91 blueswir1
        }
1031 0f8a249a blueswir1
        break;
1032 045380be blueswir1
    case 0x30: // Turbosparc secondary cache diagnostic
1033 045380be blueswir1
    case 0x31: // Turbosparc RAM snoop
1034 045380be blueswir1
    case 0x32: // Turbosparc page table descriptor diagnostic
1035 666c87aa blueswir1
    case 0x39: /* data cache diagnostic register */
1036 666c87aa blueswir1
        ret = 0;
1037 666c87aa blueswir1
        break;
1038 045380be blueswir1
    case 8: /* User code access, XXX */
1039 e8af50a3 bellard
    default:
1040 1a2fb1c0 blueswir1
        do_unassigned_access(addr, 0, 0, asi);
1041 0f8a249a blueswir1
        ret = 0;
1042 0f8a249a blueswir1
        break;
1043 e8af50a3 bellard
    }
1044 81ad8ba2 blueswir1
    if (sign) {
1045 81ad8ba2 blueswir1
        switch(size) {
1046 81ad8ba2 blueswir1
        case 1:
1047 1a2fb1c0 blueswir1
            ret = (int8_t) ret;
1048 e32664fb blueswir1
            break;
1049 81ad8ba2 blueswir1
        case 2:
1050 1a2fb1c0 blueswir1
            ret = (int16_t) ret;
1051 1a2fb1c0 blueswir1
            break;
1052 1a2fb1c0 blueswir1
        case 4:
1053 1a2fb1c0 blueswir1
            ret = (int32_t) ret;
1054 e32664fb blueswir1
            break;
1055 81ad8ba2 blueswir1
        default:
1056 81ad8ba2 blueswir1
            break;
1057 81ad8ba2 blueswir1
        }
1058 81ad8ba2 blueswir1
    }
1059 8543e2cf blueswir1
#ifdef DEBUG_ASI
1060 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
1061 8543e2cf blueswir1
#endif
1062 1a2fb1c0 blueswir1
    return ret;
1063 e8af50a3 bellard
}
1064 e8af50a3 bellard
1065 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
1066 e8af50a3 bellard
{
1067 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1068 e8af50a3 bellard
    switch(asi) {
1069 6c36d3fa blueswir1
    case 2: /* SuperSparc MXCC registers */
1070 1a2fb1c0 blueswir1
        switch (addr) {
1071 952a328f blueswir1
        case 0x01c00000: /* MXCC stream data register 0 */
1072 952a328f blueswir1
            if (size == 8)
1073 1a2fb1c0 blueswir1
                env->mxccdata[0] = val;
1074 952a328f blueswir1
            else
1075 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1076 77f193da blueswir1
                             size);
1077 952a328f blueswir1
            break;
1078 952a328f blueswir1
        case 0x01c00008: /* MXCC stream data register 1 */
1079 952a328f blueswir1
            if (size == 8)
1080 1a2fb1c0 blueswir1
                env->mxccdata[1] = val;
1081 952a328f blueswir1
            else
1082 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1083 77f193da blueswir1
                             size);
1084 952a328f blueswir1
            break;
1085 952a328f blueswir1
        case 0x01c00010: /* MXCC stream data register 2 */
1086 952a328f blueswir1
            if (size == 8)
1087 1a2fb1c0 blueswir1
                env->mxccdata[2] = val;
1088 952a328f blueswir1
            else
1089 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1090 77f193da blueswir1
                             size);
1091 952a328f blueswir1
            break;
1092 952a328f blueswir1
        case 0x01c00018: /* MXCC stream data register 3 */
1093 952a328f blueswir1
            if (size == 8)
1094 1a2fb1c0 blueswir1
                env->mxccdata[3] = val;
1095 952a328f blueswir1
            else
1096 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1097 77f193da blueswir1
                             size);
1098 952a328f blueswir1
            break;
1099 952a328f blueswir1
        case 0x01c00100: /* MXCC stream source */
1100 952a328f blueswir1
            if (size == 8)
1101 1a2fb1c0 blueswir1
                env->mxccregs[0] = val;
1102 952a328f blueswir1
            else
1103 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1104 77f193da blueswir1
                             size);
1105 77f193da blueswir1
            env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1106 77f193da blueswir1
                                        0);
1107 77f193da blueswir1
            env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1108 77f193da blueswir1
                                        8);
1109 77f193da blueswir1
            env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1110 77f193da blueswir1
                                        16);
1111 77f193da blueswir1
            env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1112 77f193da blueswir1
                                        24);
1113 952a328f blueswir1
            break;
1114 952a328f blueswir1
        case 0x01c00200: /* MXCC stream destination */
1115 952a328f blueswir1
            if (size == 8)
1116 1a2fb1c0 blueswir1
                env->mxccregs[1] = val;
1117 952a328f blueswir1
            else
1118 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1119 77f193da blueswir1
                             size);
1120 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0,
1121 77f193da blueswir1
                     env->mxccdata[0]);
1122 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8,
1123 77f193da blueswir1
                     env->mxccdata[1]);
1124 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16,
1125 77f193da blueswir1
                     env->mxccdata[2]);
1126 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24,
1127 77f193da blueswir1
                     env->mxccdata[3]);
1128 952a328f blueswir1
            break;
1129 952a328f blueswir1
        case 0x01c00a00: /* MXCC control register */
1130 952a328f blueswir1
            if (size == 8)
1131 1a2fb1c0 blueswir1
                env->mxccregs[3] = val;
1132 952a328f blueswir1
            else
1133 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1134 77f193da blueswir1
                             size);
1135 952a328f blueswir1
            break;
1136 952a328f blueswir1
        case 0x01c00a04: /* MXCC control register */
1137 952a328f blueswir1
            if (size == 4)
1138 77f193da blueswir1
                env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000ULL)
1139 77f193da blueswir1
                    | val;
1140 952a328f blueswir1
            else
1141 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1142 77f193da blueswir1
                             size);
1143 952a328f blueswir1
            break;
1144 952a328f blueswir1
        case 0x01c00e00: /* MXCC error register  */
1145 bbf7d96b blueswir1
            // writing a 1 bit clears the error
1146 952a328f blueswir1
            if (size == 8)
1147 1a2fb1c0 blueswir1
                env->mxccregs[6] &= ~val;
1148 952a328f blueswir1
            else
1149 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1150 77f193da blueswir1
                             size);
1151 952a328f blueswir1
            break;
1152 952a328f blueswir1
        case 0x01c00f00: /* MBus port address register */
1153 952a328f blueswir1
            if (size == 8)
1154 1a2fb1c0 blueswir1
                env->mxccregs[7] = val;
1155 952a328f blueswir1
            else
1156 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1157 77f193da blueswir1
                             size);
1158 952a328f blueswir1
            break;
1159 952a328f blueswir1
        default:
1160 77f193da blueswir1
            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
1161 77f193da blueswir1
                         size);
1162 952a328f blueswir1
            break;
1163 952a328f blueswir1
        }
1164 77f193da blueswir1
        DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %08x\n", asi,
1165 77f193da blueswir1
                     size, addr, val);
1166 952a328f blueswir1
#ifdef DEBUG_MXCC
1167 952a328f blueswir1
        dump_mxcc(env);
1168 952a328f blueswir1
#endif
1169 6c36d3fa blueswir1
        break;
1170 e8af50a3 bellard
    case 3: /* MMU flush */
1171 0f8a249a blueswir1
        {
1172 0f8a249a blueswir1
            int mmulev;
1173 e80cfcfc bellard
1174 1a2fb1c0 blueswir1
            mmulev = (addr >> 8) & 15;
1175 952a328f blueswir1
            DPRINTF_MMU("mmu flush level %d\n", mmulev);
1176 0f8a249a blueswir1
            switch (mmulev) {
1177 0f8a249a blueswir1
            case 0: // flush page
1178 1a2fb1c0 blueswir1
                tlb_flush_page(env, addr & 0xfffff000);
1179 0f8a249a blueswir1
                break;
1180 0f8a249a blueswir1
            case 1: // flush segment (256k)
1181 0f8a249a blueswir1
            case 2: // flush region (16M)
1182 0f8a249a blueswir1
            case 3: // flush context (4G)
1183 0f8a249a blueswir1
            case 4: // flush entire
1184 0f8a249a blueswir1
                tlb_flush(env, 1);
1185 0f8a249a blueswir1
                break;
1186 0f8a249a blueswir1
            default:
1187 0f8a249a blueswir1
                break;
1188 0f8a249a blueswir1
            }
1189 55754d9e bellard
#ifdef DEBUG_MMU
1190 0f8a249a blueswir1
            dump_mmu(env);
1191 55754d9e bellard
#endif
1192 0f8a249a blueswir1
        }
1193 8543e2cf blueswir1
        break;
1194 e8af50a3 bellard
    case 4: /* write MMU regs */
1195 0f8a249a blueswir1
        {
1196 1a2fb1c0 blueswir1
            int reg = (addr >> 8) & 0x1f;
1197 0f8a249a blueswir1
            uint32_t oldreg;
1198 3b46e624 ths
1199 0f8a249a blueswir1
            oldreg = env->mmuregs[reg];
1200 55754d9e bellard
            switch(reg) {
1201 3deaeab7 blueswir1
            case 0: // Control Register
1202 3dd9a152 blueswir1
                env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
1203 1a2fb1c0 blueswir1
                                    (val & 0x00ffffff);
1204 0f8a249a blueswir1
                // Mappings generated during no-fault mode or MMU
1205 0f8a249a blueswir1
                // disabled mode are invalid in normal mode
1206 5578ceab blueswir1
                if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
1207 5578ceab blueswir1
                    (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm)))
1208 55754d9e bellard
                    tlb_flush(env, 1);
1209 55754d9e bellard
                break;
1210 3deaeab7 blueswir1
            case 1: // Context Table Pointer Register
1211 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_ctpr_mask;
1212 3deaeab7 blueswir1
                break;
1213 3deaeab7 blueswir1
            case 2: // Context Register
1214 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_cxr_mask;
1215 55754d9e bellard
                if (oldreg != env->mmuregs[reg]) {
1216 55754d9e bellard
                    /* we flush when the MMU context changes because
1217 55754d9e bellard
                       QEMU has no MMU context support */
1218 55754d9e bellard
                    tlb_flush(env, 1);
1219 55754d9e bellard
                }
1220 55754d9e bellard
                break;
1221 3deaeab7 blueswir1
            case 3: // Synchronous Fault Status Register with Clear
1222 3deaeab7 blueswir1
            case 4: // Synchronous Fault Address Register
1223 3deaeab7 blueswir1
                break;
1224 3deaeab7 blueswir1
            case 0x10: // TLB Replacement Control Register
1225 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_trcr_mask;
1226 55754d9e bellard
                break;
1227 3deaeab7 blueswir1
            case 0x13: // Synchronous Fault Status Register with Read and Clear
1228 5578ceab blueswir1
                env->mmuregs[3] = val & env->def->mmu_sfsr_mask;
1229 3dd9a152 blueswir1
                break;
1230 3deaeab7 blueswir1
            case 0x14: // Synchronous Fault Address Register
1231 1a2fb1c0 blueswir1
                env->mmuregs[4] = val;
1232 3dd9a152 blueswir1
                break;
1233 55754d9e bellard
            default:
1234 1a2fb1c0 blueswir1
                env->mmuregs[reg] = val;
1235 55754d9e bellard
                break;
1236 55754d9e bellard
            }
1237 55754d9e bellard
            if (oldreg != env->mmuregs[reg]) {
1238 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
1239 77f193da blueswir1
                            reg, oldreg, env->mmuregs[reg]);
1240 55754d9e bellard
            }
1241 952a328f blueswir1
#ifdef DEBUG_MMU
1242 0f8a249a blueswir1
            dump_mmu(env);
1243 55754d9e bellard
#endif
1244 0f8a249a blueswir1
        }
1245 8543e2cf blueswir1
        break;
1246 045380be blueswir1
    case 5: // Turbosparc ITLB Diagnostic
1247 045380be blueswir1
    case 6: // Turbosparc DTLB Diagnostic
1248 045380be blueswir1
    case 7: // Turbosparc IOTLB Diagnostic
1249 045380be blueswir1
        break;
1250 81ad8ba2 blueswir1
    case 0xa: /* User data access */
1251 81ad8ba2 blueswir1
        switch(size) {
1252 81ad8ba2 blueswir1
        case 1:
1253 1a2fb1c0 blueswir1
            stb_user(addr, val);
1254 81ad8ba2 blueswir1
            break;
1255 81ad8ba2 blueswir1
        case 2:
1256 a4e7dd52 blueswir1
            stw_user(addr, val);
1257 81ad8ba2 blueswir1
            break;
1258 81ad8ba2 blueswir1
        default:
1259 81ad8ba2 blueswir1
        case 4:
1260 a4e7dd52 blueswir1
            stl_user(addr, val);
1261 81ad8ba2 blueswir1
            break;
1262 81ad8ba2 blueswir1
        case 8:
1263 a4e7dd52 blueswir1
            stq_user(addr, val);
1264 81ad8ba2 blueswir1
            break;
1265 81ad8ba2 blueswir1
        }
1266 81ad8ba2 blueswir1
        break;
1267 81ad8ba2 blueswir1
    case 0xb: /* Supervisor data access */
1268 81ad8ba2 blueswir1
        switch(size) {
1269 81ad8ba2 blueswir1
        case 1:
1270 1a2fb1c0 blueswir1
            stb_kernel(addr, val);
1271 81ad8ba2 blueswir1
            break;
1272 81ad8ba2 blueswir1
        case 2:
1273 a4e7dd52 blueswir1
            stw_kernel(addr, val);
1274 81ad8ba2 blueswir1
            break;
1275 81ad8ba2 blueswir1
        default:
1276 81ad8ba2 blueswir1
        case 4:
1277 a4e7dd52 blueswir1
            stl_kernel(addr, val);
1278 81ad8ba2 blueswir1
            break;
1279 81ad8ba2 blueswir1
        case 8:
1280 a4e7dd52 blueswir1
            stq_kernel(addr, val);
1281 81ad8ba2 blueswir1
            break;
1282 81ad8ba2 blueswir1
        }
1283 81ad8ba2 blueswir1
        break;
1284 6c36d3fa blueswir1
    case 0xc: /* I-cache tag */
1285 6c36d3fa blueswir1
    case 0xd: /* I-cache data */
1286 6c36d3fa blueswir1
    case 0xe: /* D-cache tag */
1287 6c36d3fa blueswir1
    case 0xf: /* D-cache data */
1288 6c36d3fa blueswir1
    case 0x10: /* I/D-cache flush page */
1289 6c36d3fa blueswir1
    case 0x11: /* I/D-cache flush segment */
1290 6c36d3fa blueswir1
    case 0x12: /* I/D-cache flush region */
1291 6c36d3fa blueswir1
    case 0x13: /* I/D-cache flush context */
1292 6c36d3fa blueswir1
    case 0x14: /* I/D-cache flush user */
1293 6c36d3fa blueswir1
        break;
1294 e80cfcfc bellard
    case 0x17: /* Block copy, sta access */
1295 0f8a249a blueswir1
        {
1296 1a2fb1c0 blueswir1
            // val = src
1297 1a2fb1c0 blueswir1
            // addr = dst
1298 0f8a249a blueswir1
            // copy 32 bytes
1299 6c36d3fa blueswir1
            unsigned int i;
1300 1a2fb1c0 blueswir1
            uint32_t src = val & ~3, dst = addr & ~3, temp;
1301 3b46e624 ths
1302 6c36d3fa blueswir1
            for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
1303 6c36d3fa blueswir1
                temp = ldl_kernel(src);
1304 6c36d3fa blueswir1
                stl_kernel(dst, temp);
1305 6c36d3fa blueswir1
            }
1306 0f8a249a blueswir1
        }
1307 8543e2cf blueswir1
        break;
1308 e80cfcfc bellard
    case 0x1f: /* Block fill, stda access */
1309 0f8a249a blueswir1
        {
1310 1a2fb1c0 blueswir1
            // addr = dst
1311 1a2fb1c0 blueswir1
            // fill 32 bytes with val
1312 6c36d3fa blueswir1
            unsigned int i;
1313 1a2fb1c0 blueswir1
            uint32_t dst = addr & 7;
1314 6c36d3fa blueswir1
1315 6c36d3fa blueswir1
            for (i = 0; i < 32; i += 8, dst += 8)
1316 6c36d3fa blueswir1
                stq_kernel(dst, val);
1317 0f8a249a blueswir1
        }
1318 8543e2cf blueswir1
        break;
1319 6c36d3fa blueswir1
    case 0x20: /* MMU passthrough */
1320 0f8a249a blueswir1
        {
1321 02aab46a bellard
            switch(size) {
1322 02aab46a bellard
            case 1:
1323 1a2fb1c0 blueswir1
                stb_phys(addr, val);
1324 02aab46a bellard
                break;
1325 02aab46a bellard
            case 2:
1326 a4e7dd52 blueswir1
                stw_phys(addr, val);
1327 02aab46a bellard
                break;
1328 02aab46a bellard
            case 4:
1329 02aab46a bellard
            default:
1330 a4e7dd52 blueswir1
                stl_phys(addr, val);
1331 02aab46a bellard
                break;
1332 9e61bde5 bellard
            case 8:
1333 a4e7dd52 blueswir1
                stq_phys(addr, val);
1334 9e61bde5 bellard
                break;
1335 02aab46a bellard
            }
1336 0f8a249a blueswir1
        }
1337 8543e2cf blueswir1
        break;
1338 045380be blueswir1
    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1339 0f8a249a blueswir1
        {
1340 5dcb6b91 blueswir1
            switch(size) {
1341 5dcb6b91 blueswir1
            case 1:
1342 1a2fb1c0 blueswir1
                stb_phys((target_phys_addr_t)addr
1343 1a2fb1c0 blueswir1
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1344 5dcb6b91 blueswir1
                break;
1345 5dcb6b91 blueswir1
            case 2:
1346 a4e7dd52 blueswir1
                stw_phys((target_phys_addr_t)addr
1347 1a2fb1c0 blueswir1
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1348 5dcb6b91 blueswir1
                break;
1349 5dcb6b91 blueswir1
            case 4:
1350 5dcb6b91 blueswir1
            default:
1351 a4e7dd52 blueswir1
                stl_phys((target_phys_addr_t)addr
1352 1a2fb1c0 blueswir1
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1353 5dcb6b91 blueswir1
                break;
1354 5dcb6b91 blueswir1
            case 8:
1355 a4e7dd52 blueswir1
                stq_phys((target_phys_addr_t)addr
1356 1a2fb1c0 blueswir1
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1357 5dcb6b91 blueswir1
                break;
1358 5dcb6b91 blueswir1
            }
1359 0f8a249a blueswir1
        }
1360 8543e2cf blueswir1
        break;
1361 045380be blueswir1
    case 0x30: // store buffer tags or Turbosparc secondary cache diagnostic
1362 045380be blueswir1
    case 0x31: // store buffer data, Ross RT620 I-cache flush or
1363 045380be blueswir1
               // Turbosparc snoop RAM
1364 77f193da blueswir1
    case 0x32: // store buffer control or Turbosparc page table
1365 77f193da blueswir1
               // descriptor diagnostic
1366 6c36d3fa blueswir1
    case 0x36: /* I-cache flash clear */
1367 6c36d3fa blueswir1
    case 0x37: /* D-cache flash clear */
1368 666c87aa blueswir1
    case 0x38: /* breakpoint diagnostics */
1369 666c87aa blueswir1
    case 0x4c: /* breakpoint action */
1370 6c36d3fa blueswir1
        break;
1371 045380be blueswir1
    case 8: /* User code access, XXX */
1372 6c36d3fa blueswir1
    case 9: /* Supervisor code access, XXX */
1373 e8af50a3 bellard
    default:
1374 1a2fb1c0 blueswir1
        do_unassigned_access(addr, 1, 0, asi);
1375 8543e2cf blueswir1
        break;
1376 e8af50a3 bellard
    }
1377 8543e2cf blueswir1
#ifdef DEBUG_ASI
1378 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
1379 8543e2cf blueswir1
#endif
1380 e8af50a3 bellard
}
1381 e8af50a3 bellard
1382 81ad8ba2 blueswir1
#endif /* CONFIG_USER_ONLY */
1383 81ad8ba2 blueswir1
#else /* TARGET_SPARC64 */
1384 81ad8ba2 blueswir1
1385 81ad8ba2 blueswir1
#ifdef CONFIG_USER_ONLY
1386 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1387 81ad8ba2 blueswir1
{
1388 81ad8ba2 blueswir1
    uint64_t ret = 0;
1389 1a2fb1c0 blueswir1
#if defined(DEBUG_ASI)
1390 1a2fb1c0 blueswir1
    target_ulong last_addr = addr;
1391 1a2fb1c0 blueswir1
#endif
1392 81ad8ba2 blueswir1
1393 81ad8ba2 blueswir1
    if (asi < 0x80)
1394 81ad8ba2 blueswir1
        raise_exception(TT_PRIV_ACT);
1395 81ad8ba2 blueswir1
1396 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1397 2cade6a3 blueswir1
    address_mask(env, &addr);
1398 c2bc0e38 blueswir1
1399 81ad8ba2 blueswir1
    switch (asi) {
1400 81ad8ba2 blueswir1
    case 0x80: // Primary
1401 81ad8ba2 blueswir1
    case 0x82: // Primary no-fault
1402 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1403 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1404 81ad8ba2 blueswir1
        {
1405 81ad8ba2 blueswir1
            switch(size) {
1406 81ad8ba2 blueswir1
            case 1:
1407 1a2fb1c0 blueswir1
                ret = ldub_raw(addr);
1408 81ad8ba2 blueswir1
                break;
1409 81ad8ba2 blueswir1
            case 2:
1410 a4e7dd52 blueswir1
                ret = lduw_raw(addr);
1411 81ad8ba2 blueswir1
                break;
1412 81ad8ba2 blueswir1
            case 4:
1413 a4e7dd52 blueswir1
                ret = ldl_raw(addr);
1414 81ad8ba2 blueswir1
                break;
1415 81ad8ba2 blueswir1
            default:
1416 81ad8ba2 blueswir1
            case 8:
1417 a4e7dd52 blueswir1
                ret = ldq_raw(addr);
1418 81ad8ba2 blueswir1
                break;
1419 81ad8ba2 blueswir1
            }
1420 81ad8ba2 blueswir1
        }
1421 81ad8ba2 blueswir1
        break;
1422 81ad8ba2 blueswir1
    case 0x81: // Secondary
1423 81ad8ba2 blueswir1
    case 0x83: // Secondary no-fault
1424 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1425 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1426 81ad8ba2 blueswir1
        // XXX
1427 81ad8ba2 blueswir1
        break;
1428 81ad8ba2 blueswir1
    default:
1429 81ad8ba2 blueswir1
        break;
1430 81ad8ba2 blueswir1
    }
1431 81ad8ba2 blueswir1
1432 81ad8ba2 blueswir1
    /* Convert from little endian */
1433 81ad8ba2 blueswir1
    switch (asi) {
1434 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1435 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1436 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1437 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1438 81ad8ba2 blueswir1
        switch(size) {
1439 81ad8ba2 blueswir1
        case 2:
1440 81ad8ba2 blueswir1
            ret = bswap16(ret);
1441 e32664fb blueswir1
            break;
1442 81ad8ba2 blueswir1
        case 4:
1443 81ad8ba2 blueswir1
            ret = bswap32(ret);
1444 e32664fb blueswir1
            break;
1445 81ad8ba2 blueswir1
        case 8:
1446 81ad8ba2 blueswir1
            ret = bswap64(ret);
1447 e32664fb blueswir1
            break;
1448 81ad8ba2 blueswir1
        default:
1449 81ad8ba2 blueswir1
            break;
1450 81ad8ba2 blueswir1
        }
1451 81ad8ba2 blueswir1
    default:
1452 81ad8ba2 blueswir1
        break;
1453 81ad8ba2 blueswir1
    }
1454 81ad8ba2 blueswir1
1455 81ad8ba2 blueswir1
    /* Convert to signed number */
1456 81ad8ba2 blueswir1
    if (sign) {
1457 81ad8ba2 blueswir1
        switch(size) {
1458 81ad8ba2 blueswir1
        case 1:
1459 81ad8ba2 blueswir1
            ret = (int8_t) ret;
1460 e32664fb blueswir1
            break;
1461 81ad8ba2 blueswir1
        case 2:
1462 81ad8ba2 blueswir1
            ret = (int16_t) ret;
1463 e32664fb blueswir1
            break;
1464 81ad8ba2 blueswir1
        case 4:
1465 81ad8ba2 blueswir1
            ret = (int32_t) ret;
1466 e32664fb blueswir1
            break;
1467 81ad8ba2 blueswir1
        default:
1468 81ad8ba2 blueswir1
            break;
1469 81ad8ba2 blueswir1
        }
1470 81ad8ba2 blueswir1
    }
1471 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1472 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
1473 1a2fb1c0 blueswir1
#endif
1474 1a2fb1c0 blueswir1
    return ret;
1475 81ad8ba2 blueswir1
}
1476 81ad8ba2 blueswir1
1477 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
1478 81ad8ba2 blueswir1
{
1479 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1480 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
1481 1a2fb1c0 blueswir1
#endif
1482 81ad8ba2 blueswir1
    if (asi < 0x80)
1483 81ad8ba2 blueswir1
        raise_exception(TT_PRIV_ACT);
1484 81ad8ba2 blueswir1
1485 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1486 2cade6a3 blueswir1
    address_mask(env, &addr);
1487 c2bc0e38 blueswir1
1488 81ad8ba2 blueswir1
    /* Convert to little endian */
1489 81ad8ba2 blueswir1
    switch (asi) {
1490 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1491 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1492 81ad8ba2 blueswir1
        switch(size) {
1493 81ad8ba2 blueswir1
        case 2:
1494 1a2fb1c0 blueswir1
            addr = bswap16(addr);
1495 e32664fb blueswir1
            break;
1496 81ad8ba2 blueswir1
        case 4:
1497 1a2fb1c0 blueswir1
            addr = bswap32(addr);
1498 e32664fb blueswir1
            break;
1499 81ad8ba2 blueswir1
        case 8:
1500 1a2fb1c0 blueswir1
            addr = bswap64(addr);
1501 e32664fb blueswir1
            break;
1502 81ad8ba2 blueswir1
        default:
1503 81ad8ba2 blueswir1
            break;
1504 81ad8ba2 blueswir1
        }
1505 81ad8ba2 blueswir1
    default:
1506 81ad8ba2 blueswir1
        break;
1507 81ad8ba2 blueswir1
    }
1508 81ad8ba2 blueswir1
1509 81ad8ba2 blueswir1
    switch(asi) {
1510 81ad8ba2 blueswir1
    case 0x80: // Primary
1511 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1512 81ad8ba2 blueswir1
        {
1513 81ad8ba2 blueswir1
            switch(size) {
1514 81ad8ba2 blueswir1
            case 1:
1515 1a2fb1c0 blueswir1
                stb_raw(addr, val);
1516 81ad8ba2 blueswir1
                break;
1517 81ad8ba2 blueswir1
            case 2:
1518 a4e7dd52 blueswir1
                stw_raw(addr, val);
1519 81ad8ba2 blueswir1
                break;
1520 81ad8ba2 blueswir1
            case 4:
1521 a4e7dd52 blueswir1
                stl_raw(addr, val);
1522 81ad8ba2 blueswir1
                break;
1523 81ad8ba2 blueswir1
            case 8:
1524 81ad8ba2 blueswir1
            default:
1525 a4e7dd52 blueswir1
                stq_raw(addr, val);
1526 81ad8ba2 blueswir1
                break;
1527 81ad8ba2 blueswir1
            }
1528 81ad8ba2 blueswir1
        }
1529 81ad8ba2 blueswir1
        break;
1530 81ad8ba2 blueswir1
    case 0x81: // Secondary
1531 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1532 81ad8ba2 blueswir1
        // XXX
1533 81ad8ba2 blueswir1
        return;
1534 81ad8ba2 blueswir1
1535 81ad8ba2 blueswir1
    case 0x82: // Primary no-fault, RO
1536 81ad8ba2 blueswir1
    case 0x83: // Secondary no-fault, RO
1537 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE, RO
1538 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE, RO
1539 81ad8ba2 blueswir1
    default:
1540 1a2fb1c0 blueswir1
        do_unassigned_access(addr, 1, 0, 1);
1541 81ad8ba2 blueswir1
        return;
1542 81ad8ba2 blueswir1
    }
1543 81ad8ba2 blueswir1
}
1544 81ad8ba2 blueswir1
1545 81ad8ba2 blueswir1
#else /* CONFIG_USER_ONLY */
1546 3475187d bellard
1547 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1548 3475187d bellard
{
1549 83469015 bellard
    uint64_t ret = 0;
1550 1a2fb1c0 blueswir1
#if defined(DEBUG_ASI)
1551 1a2fb1c0 blueswir1
    target_ulong last_addr = addr;
1552 1a2fb1c0 blueswir1
#endif
1553 3475187d bellard
1554 6f27aba6 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1555 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
1556 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
1557 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
1558 0f8a249a blueswir1
        raise_exception(TT_PRIV_ACT);
1559 3475187d bellard
1560 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1561 3475187d bellard
    switch (asi) {
1562 81ad8ba2 blueswir1
    case 0x10: // As if user primary
1563 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1564 81ad8ba2 blueswir1
    case 0x80: // Primary
1565 81ad8ba2 blueswir1
    case 0x82: // Primary no-fault
1566 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1567 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1568 81ad8ba2 blueswir1
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1569 5578ceab blueswir1
            if ((env->def->features & CPU_FEATURE_HYPV)
1570 5578ceab blueswir1
                && env->hpstate & HS_PRIV) {
1571 6f27aba6 blueswir1
                switch(size) {
1572 6f27aba6 blueswir1
                case 1:
1573 1a2fb1c0 blueswir1
                    ret = ldub_hypv(addr);
1574 6f27aba6 blueswir1
                    break;
1575 6f27aba6 blueswir1
                case 2:
1576 a4e7dd52 blueswir1
                    ret = lduw_hypv(addr);
1577 6f27aba6 blueswir1
                    break;
1578 6f27aba6 blueswir1
                case 4:
1579 a4e7dd52 blueswir1
                    ret = ldl_hypv(addr);
1580 6f27aba6 blueswir1
                    break;
1581 6f27aba6 blueswir1
                default:
1582 6f27aba6 blueswir1
                case 8:
1583 a4e7dd52 blueswir1
                    ret = ldq_hypv(addr);
1584 6f27aba6 blueswir1
                    break;
1585 6f27aba6 blueswir1
                }
1586 6f27aba6 blueswir1
            } else {
1587 6f27aba6 blueswir1
                switch(size) {
1588 6f27aba6 blueswir1
                case 1:
1589 1a2fb1c0 blueswir1
                    ret = ldub_kernel(addr);
1590 6f27aba6 blueswir1
                    break;
1591 6f27aba6 blueswir1
                case 2:
1592 a4e7dd52 blueswir1
                    ret = lduw_kernel(addr);
1593 6f27aba6 blueswir1
                    break;
1594 6f27aba6 blueswir1
                case 4:
1595 a4e7dd52 blueswir1
                    ret = ldl_kernel(addr);
1596 6f27aba6 blueswir1
                    break;
1597 6f27aba6 blueswir1
                default:
1598 6f27aba6 blueswir1
                case 8:
1599 a4e7dd52 blueswir1
                    ret = ldq_kernel(addr);
1600 6f27aba6 blueswir1
                    break;
1601 6f27aba6 blueswir1
                }
1602 81ad8ba2 blueswir1
            }
1603 81ad8ba2 blueswir1
        } else {
1604 81ad8ba2 blueswir1
            switch(size) {
1605 81ad8ba2 blueswir1
            case 1:
1606 1a2fb1c0 blueswir1
                ret = ldub_user(addr);
1607 81ad8ba2 blueswir1
                break;
1608 81ad8ba2 blueswir1
            case 2:
1609 a4e7dd52 blueswir1
                ret = lduw_user(addr);
1610 81ad8ba2 blueswir1
                break;
1611 81ad8ba2 blueswir1
            case 4:
1612 a4e7dd52 blueswir1
                ret = ldl_user(addr);
1613 81ad8ba2 blueswir1
                break;
1614 81ad8ba2 blueswir1
            default:
1615 81ad8ba2 blueswir1
            case 8:
1616 a4e7dd52 blueswir1
                ret = ldq_user(addr);
1617 81ad8ba2 blueswir1
                break;
1618 81ad8ba2 blueswir1
            }
1619 81ad8ba2 blueswir1
        }
1620 81ad8ba2 blueswir1
        break;
1621 3475187d bellard
    case 0x14: // Bypass
1622 3475187d bellard
    case 0x15: // Bypass, non-cacheable
1623 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1624 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1625 0f8a249a blueswir1
        {
1626 02aab46a bellard
            switch(size) {
1627 02aab46a bellard
            case 1:
1628 1a2fb1c0 blueswir1
                ret = ldub_phys(addr);
1629 02aab46a bellard
                break;
1630 02aab46a bellard
            case 2:
1631 a4e7dd52 blueswir1
                ret = lduw_phys(addr);
1632 02aab46a bellard
                break;
1633 02aab46a bellard
            case 4:
1634 a4e7dd52 blueswir1
                ret = ldl_phys(addr);
1635 02aab46a bellard
                break;
1636 02aab46a bellard
            default:
1637 02aab46a bellard
            case 8:
1638 a4e7dd52 blueswir1
                ret = ldq_phys(addr);
1639 02aab46a bellard
                break;
1640 02aab46a bellard
            }
1641 0f8a249a blueswir1
            break;
1642 0f8a249a blueswir1
        }
1643 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
1644 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
1645 db166940 blueswir1
        //  Only ldda allowed
1646 db166940 blueswir1
        raise_exception(TT_ILL_INSN);
1647 db166940 blueswir1
        return 0;
1648 83469015 bellard
    case 0x04: // Nucleus
1649 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
1650 83469015 bellard
    case 0x11: // As if user secondary
1651 83469015 bellard
    case 0x19: // As if user secondary LE
1652 83469015 bellard
    case 0x4a: // UPA config
1653 81ad8ba2 blueswir1
    case 0x81: // Secondary
1654 83469015 bellard
    case 0x83: // Secondary no-fault
1655 83469015 bellard
    case 0x89: // Secondary LE
1656 83469015 bellard
    case 0x8b: // Secondary no-fault LE
1657 0f8a249a blueswir1
        // XXX
1658 0f8a249a blueswir1
        break;
1659 3475187d bellard
    case 0x45: // LSU
1660 0f8a249a blueswir1
        ret = env->lsu;
1661 0f8a249a blueswir1
        break;
1662 3475187d bellard
    case 0x50: // I-MMU regs
1663 0f8a249a blueswir1
        {
1664 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
1665 3475187d bellard
1666 0f8a249a blueswir1
            ret = env->immuregs[reg];
1667 0f8a249a blueswir1
            break;
1668 0f8a249a blueswir1
        }
1669 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer
1670 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer
1671 0f8a249a blueswir1
        // XXX
1672 0f8a249a blueswir1
        break;
1673 a5a52cf2 blueswir1
    case 0x55: // I-MMU data access
1674 a5a52cf2 blueswir1
        {
1675 a5a52cf2 blueswir1
            int reg = (addr >> 3) & 0x3f;
1676 a5a52cf2 blueswir1
1677 a5a52cf2 blueswir1
            ret = env->itlb_tte[reg];
1678 a5a52cf2 blueswir1
            break;
1679 a5a52cf2 blueswir1
        }
1680 83469015 bellard
    case 0x56: // I-MMU tag read
1681 0f8a249a blueswir1
        {
1682 43e9e742 blueswir1
            int reg = (addr >> 3) & 0x3f;
1683 0f8a249a blueswir1
1684 43e9e742 blueswir1
            ret = env->itlb_tag[reg];
1685 0f8a249a blueswir1
            break;
1686 0f8a249a blueswir1
        }
1687 3475187d bellard
    case 0x58: // D-MMU regs
1688 0f8a249a blueswir1
        {
1689 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
1690 3475187d bellard
1691 0f8a249a blueswir1
            ret = env->dmmuregs[reg];
1692 0f8a249a blueswir1
            break;
1693 0f8a249a blueswir1
        }
1694 a5a52cf2 blueswir1
    case 0x5d: // D-MMU data access
1695 a5a52cf2 blueswir1
        {
1696 a5a52cf2 blueswir1
            int reg = (addr >> 3) & 0x3f;
1697 a5a52cf2 blueswir1
1698 a5a52cf2 blueswir1
            ret = env->dtlb_tte[reg];
1699 a5a52cf2 blueswir1
            break;
1700 a5a52cf2 blueswir1
        }
1701 83469015 bellard
    case 0x5e: // D-MMU tag read
1702 0f8a249a blueswir1
        {
1703 43e9e742 blueswir1
            int reg = (addr >> 3) & 0x3f;
1704 0f8a249a blueswir1
1705 43e9e742 blueswir1
            ret = env->dtlb_tag[reg];
1706 0f8a249a blueswir1
            break;
1707 0f8a249a blueswir1
        }
1708 f7350b47 blueswir1
    case 0x46: // D-cache data
1709 f7350b47 blueswir1
    case 0x47: // D-cache tag access
1710 a5a52cf2 blueswir1
    case 0x4b: // E-cache error enable
1711 a5a52cf2 blueswir1
    case 0x4c: // E-cache asynchronous fault status
1712 a5a52cf2 blueswir1
    case 0x4d: // E-cache asynchronous fault address
1713 f7350b47 blueswir1
    case 0x4e: // E-cache tag data
1714 f7350b47 blueswir1
    case 0x66: // I-cache instruction access
1715 f7350b47 blueswir1
    case 0x67: // I-cache tag access
1716 f7350b47 blueswir1
    case 0x6e: // I-cache predecode
1717 f7350b47 blueswir1
    case 0x6f: // I-cache LRU etc.
1718 f7350b47 blueswir1
    case 0x76: // E-cache tag
1719 f7350b47 blueswir1
    case 0x7e: // E-cache tag
1720 f7350b47 blueswir1
        break;
1721 3475187d bellard
    case 0x59: // D-MMU 8k TSB pointer
1722 3475187d bellard
    case 0x5a: // D-MMU 64k TSB pointer
1723 3475187d bellard
    case 0x5b: // D-MMU data pointer
1724 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
1725 83469015 bellard
    case 0x49: // Interrupt data receive
1726 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
1727 0f8a249a blueswir1
        // XXX
1728 0f8a249a blueswir1
        break;
1729 3475187d bellard
    case 0x54: // I-MMU data in, WO
1730 3475187d bellard
    case 0x57: // I-MMU demap, WO
1731 3475187d bellard
    case 0x5c: // D-MMU data in, WO
1732 3475187d bellard
    case 0x5f: // D-MMU demap, WO
1733 83469015 bellard
    case 0x77: // Interrupt vector, WO
1734 3475187d bellard
    default:
1735 1a2fb1c0 blueswir1
        do_unassigned_access(addr, 0, 0, 1);
1736 0f8a249a blueswir1
        ret = 0;
1737 0f8a249a blueswir1
        break;
1738 3475187d bellard
    }
1739 81ad8ba2 blueswir1
1740 81ad8ba2 blueswir1
    /* Convert from little endian */
1741 81ad8ba2 blueswir1
    switch (asi) {
1742 81ad8ba2 blueswir1
    case 0x0c: // Nucleus Little Endian (LE)
1743 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1744 81ad8ba2 blueswir1
    case 0x19: // As if user secondary LE
1745 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1746 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1747 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1748 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1749 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1750 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1751 81ad8ba2 blueswir1
        switch(size) {
1752 81ad8ba2 blueswir1
        case 2:
1753 81ad8ba2 blueswir1
            ret = bswap16(ret);
1754 e32664fb blueswir1
            break;
1755 81ad8ba2 blueswir1
        case 4:
1756 81ad8ba2 blueswir1
            ret = bswap32(ret);
1757 e32664fb blueswir1
            break;
1758 81ad8ba2 blueswir1
        case 8:
1759 81ad8ba2 blueswir1
            ret = bswap64(ret);
1760 e32664fb blueswir1
            break;
1761 81ad8ba2 blueswir1
        default:
1762 81ad8ba2 blueswir1
            break;
1763 81ad8ba2 blueswir1
        }
1764 81ad8ba2 blueswir1
    default:
1765 81ad8ba2 blueswir1
        break;
1766 81ad8ba2 blueswir1
    }
1767 81ad8ba2 blueswir1
1768 81ad8ba2 blueswir1
    /* Convert to signed number */
1769 81ad8ba2 blueswir1
    if (sign) {
1770 81ad8ba2 blueswir1
        switch(size) {
1771 81ad8ba2 blueswir1
        case 1:
1772 81ad8ba2 blueswir1
            ret = (int8_t) ret;
1773 e32664fb blueswir1
            break;
1774 81ad8ba2 blueswir1
        case 2:
1775 81ad8ba2 blueswir1
            ret = (int16_t) ret;
1776 e32664fb blueswir1
            break;
1777 81ad8ba2 blueswir1
        case 4:
1778 81ad8ba2 blueswir1
            ret = (int32_t) ret;
1779 e32664fb blueswir1
            break;
1780 81ad8ba2 blueswir1
        default:
1781 81ad8ba2 blueswir1
            break;
1782 81ad8ba2 blueswir1
        }
1783 81ad8ba2 blueswir1
    }
1784 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1785 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
1786 1a2fb1c0 blueswir1
#endif
1787 1a2fb1c0 blueswir1
    return ret;
1788 3475187d bellard
}
1789 3475187d bellard
1790 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
1791 3475187d bellard
{
1792 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1793 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
1794 1a2fb1c0 blueswir1
#endif
1795 6f27aba6 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1796 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
1797 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
1798 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
1799 0f8a249a blueswir1
        raise_exception(TT_PRIV_ACT);
1800 3475187d bellard
1801 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1802 81ad8ba2 blueswir1
    /* Convert to little endian */
1803 81ad8ba2 blueswir1
    switch (asi) {
1804 81ad8ba2 blueswir1
    case 0x0c: // Nucleus Little Endian (LE)
1805 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1806 81ad8ba2 blueswir1
    case 0x19: // As if user secondary LE
1807 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1808 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1809 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1810 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1811 81ad8ba2 blueswir1
        switch(size) {
1812 81ad8ba2 blueswir1
        case 2:
1813 1a2fb1c0 blueswir1
            addr = bswap16(addr);
1814 e32664fb blueswir1
            break;
1815 81ad8ba2 blueswir1
        case 4:
1816 1a2fb1c0 blueswir1
            addr = bswap32(addr);
1817 e32664fb blueswir1
            break;
1818 81ad8ba2 blueswir1
        case 8:
1819 1a2fb1c0 blueswir1
            addr = bswap64(addr);
1820 e32664fb blueswir1
            break;
1821 81ad8ba2 blueswir1
        default:
1822 81ad8ba2 blueswir1
            break;
1823 81ad8ba2 blueswir1
        }
1824 81ad8ba2 blueswir1
    default:
1825 81ad8ba2 blueswir1
        break;
1826 81ad8ba2 blueswir1
    }
1827 81ad8ba2 blueswir1
1828 3475187d bellard
    switch(asi) {
1829 81ad8ba2 blueswir1
    case 0x10: // As if user primary
1830 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1831 81ad8ba2 blueswir1
    case 0x80: // Primary
1832 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1833 81ad8ba2 blueswir1
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1834 5578ceab blueswir1
            if ((env->def->features & CPU_FEATURE_HYPV)
1835 5578ceab blueswir1
                && env->hpstate & HS_PRIV) {
1836 6f27aba6 blueswir1
                switch(size) {
1837 6f27aba6 blueswir1
                case 1:
1838 1a2fb1c0 blueswir1
                    stb_hypv(addr, val);
1839 6f27aba6 blueswir1
                    break;
1840 6f27aba6 blueswir1
                case 2:
1841 a4e7dd52 blueswir1
                    stw_hypv(addr, val);
1842 6f27aba6 blueswir1
                    break;
1843 6f27aba6 blueswir1
                case 4:
1844 a4e7dd52 blueswir1
                    stl_hypv(addr, val);
1845 6f27aba6 blueswir1
                    break;
1846 6f27aba6 blueswir1
                case 8:
1847 6f27aba6 blueswir1
                default:
1848 a4e7dd52 blueswir1
                    stq_hypv(addr, val);
1849 6f27aba6 blueswir1
                    break;
1850 6f27aba6 blueswir1
                }
1851 6f27aba6 blueswir1
            } else {
1852 6f27aba6 blueswir1
                switch(size) {
1853 6f27aba6 blueswir1
                case 1:
1854 1a2fb1c0 blueswir1
                    stb_kernel(addr, val);
1855 6f27aba6 blueswir1
                    break;
1856 6f27aba6 blueswir1
                case 2:
1857 a4e7dd52 blueswir1
                    stw_kernel(addr, val);
1858 6f27aba6 blueswir1
                    break;
1859 6f27aba6 blueswir1
                case 4:
1860 a4e7dd52 blueswir1
                    stl_kernel(addr, val);
1861 6f27aba6 blueswir1
                    break;
1862 6f27aba6 blueswir1
                case 8:
1863 6f27aba6 blueswir1
                default:
1864 a4e7dd52 blueswir1
                    stq_kernel(addr, val);
1865 6f27aba6 blueswir1
                    break;
1866 6f27aba6 blueswir1
                }
1867 81ad8ba2 blueswir1
            }
1868 81ad8ba2 blueswir1
        } else {
1869 81ad8ba2 blueswir1
            switch(size) {
1870 81ad8ba2 blueswir1
            case 1:
1871 1a2fb1c0 blueswir1
                stb_user(addr, val);
1872 81ad8ba2 blueswir1
                break;
1873 81ad8ba2 blueswir1
            case 2:
1874 a4e7dd52 blueswir1
                stw_user(addr, val);
1875 81ad8ba2 blueswir1
                break;
1876 81ad8ba2 blueswir1
            case 4:
1877 a4e7dd52 blueswir1
                stl_user(addr, val);
1878 81ad8ba2 blueswir1
                break;
1879 81ad8ba2 blueswir1
            case 8:
1880 81ad8ba2 blueswir1
            default:
1881 a4e7dd52 blueswir1
                stq_user(addr, val);
1882 81ad8ba2 blueswir1
                break;
1883 81ad8ba2 blueswir1
            }
1884 81ad8ba2 blueswir1
        }
1885 81ad8ba2 blueswir1
        break;
1886 3475187d bellard
    case 0x14: // Bypass
1887 3475187d bellard
    case 0x15: // Bypass, non-cacheable
1888 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1889 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1890 0f8a249a blueswir1
        {
1891 02aab46a bellard
            switch(size) {
1892 02aab46a bellard
            case 1:
1893 1a2fb1c0 blueswir1
                stb_phys(addr, val);
1894 02aab46a bellard
                break;
1895 02aab46a bellard
            case 2:
1896 a4e7dd52 blueswir1
                stw_phys(addr, val);
1897 02aab46a bellard
                break;
1898 02aab46a bellard
            case 4:
1899 a4e7dd52 blueswir1
                stl_phys(addr, val);
1900 02aab46a bellard
                break;
1901 02aab46a bellard
            case 8:
1902 02aab46a bellard
            default:
1903 a4e7dd52 blueswir1
                stq_phys(addr, val);
1904 02aab46a bellard
                break;
1905 02aab46a bellard
            }
1906 0f8a249a blueswir1
        }
1907 0f8a249a blueswir1
        return;
1908 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
1909 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
1910 db166940 blueswir1
        //  Only ldda allowed
1911 db166940 blueswir1
        raise_exception(TT_ILL_INSN);
1912 db166940 blueswir1
        return;
1913 83469015 bellard
    case 0x04: // Nucleus
1914 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
1915 83469015 bellard
    case 0x11: // As if user secondary
1916 83469015 bellard
    case 0x19: // As if user secondary LE
1917 83469015 bellard
    case 0x4a: // UPA config
1918 51996525 blueswir1
    case 0x81: // Secondary
1919 83469015 bellard
    case 0x89: // Secondary LE
1920 0f8a249a blueswir1
        // XXX
1921 0f8a249a blueswir1
        return;
1922 3475187d bellard
    case 0x45: // LSU
1923 0f8a249a blueswir1
        {
1924 0f8a249a blueswir1
            uint64_t oldreg;
1925 0f8a249a blueswir1
1926 0f8a249a blueswir1
            oldreg = env->lsu;
1927 1a2fb1c0 blueswir1
            env->lsu = val & (DMMU_E | IMMU_E);
1928 0f8a249a blueswir1
            // Mappings generated during D/I MMU disabled mode are
1929 0f8a249a blueswir1
            // invalid in normal mode
1930 0f8a249a blueswir1
            if (oldreg != env->lsu) {
1931 77f193da blueswir1
                DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
1932 77f193da blueswir1
                            oldreg, env->lsu);
1933 83469015 bellard
#ifdef DEBUG_MMU
1934 0f8a249a blueswir1
                dump_mmu(env);
1935 83469015 bellard
#endif
1936 0f8a249a blueswir1
                tlb_flush(env, 1);
1937 0f8a249a blueswir1
            }
1938 0f8a249a blueswir1
            return;
1939 0f8a249a blueswir1
        }
1940 3475187d bellard
    case 0x50: // I-MMU regs
1941 0f8a249a blueswir1
        {
1942 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
1943 0f8a249a blueswir1
            uint64_t oldreg;
1944 3b46e624 ths
1945 0f8a249a blueswir1
            oldreg = env->immuregs[reg];
1946 3475187d bellard
            switch(reg) {
1947 3475187d bellard
            case 0: // RO
1948 3475187d bellard
            case 4:
1949 3475187d bellard
                return;
1950 3475187d bellard
            case 1: // Not in I-MMU
1951 3475187d bellard
            case 2:
1952 3475187d bellard
            case 7:
1953 3475187d bellard
            case 8:
1954 3475187d bellard
                return;
1955 3475187d bellard
            case 3: // SFSR
1956 1a2fb1c0 blueswir1
                if ((val & 1) == 0)
1957 1a2fb1c0 blueswir1
                    val = 0; // Clear SFSR
1958 3475187d bellard
                break;
1959 3475187d bellard
            case 5: // TSB access
1960 3475187d bellard
            case 6: // Tag access
1961 3475187d bellard
            default:
1962 3475187d bellard
                break;
1963 3475187d bellard
            }
1964 1a2fb1c0 blueswir1
            env->immuregs[reg] = val;
1965 3475187d bellard
            if (oldreg != env->immuregs[reg]) {
1966 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08"
1967 77f193da blueswir1
                            PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
1968 3475187d bellard
            }
1969 952a328f blueswir1
#ifdef DEBUG_MMU
1970 0f8a249a blueswir1
            dump_mmu(env);
1971 3475187d bellard
#endif
1972 0f8a249a blueswir1
            return;
1973 0f8a249a blueswir1
        }
1974 3475187d bellard
    case 0x54: // I-MMU data in
1975 0f8a249a blueswir1
        {
1976 0f8a249a blueswir1
            unsigned int i;
1977 0f8a249a blueswir1
1978 0f8a249a blueswir1
            // Try finding an invalid entry
1979 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
1980 0f8a249a blueswir1
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
1981 0f8a249a blueswir1
                    env->itlb_tag[i] = env->immuregs[6];
1982 1a2fb1c0 blueswir1
                    env->itlb_tte[i] = val;
1983 0f8a249a blueswir1
                    return;
1984 0f8a249a blueswir1
                }
1985 0f8a249a blueswir1
            }
1986 0f8a249a blueswir1
            // Try finding an unlocked entry
1987 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
1988 0f8a249a blueswir1
                if ((env->itlb_tte[i] & 0x40) == 0) {
1989 0f8a249a blueswir1
                    env->itlb_tag[i] = env->immuregs[6];
1990 1a2fb1c0 blueswir1
                    env->itlb_tte[i] = val;
1991 0f8a249a blueswir1
                    return;
1992 0f8a249a blueswir1
                }
1993 0f8a249a blueswir1
            }
1994 0f8a249a blueswir1
            // error state?
1995 0f8a249a blueswir1
            return;
1996 0f8a249a blueswir1
        }
1997 3475187d bellard
    case 0x55: // I-MMU data access
1998 0f8a249a blueswir1
        {
1999 1a2fb1c0 blueswir1
            unsigned int i = (addr >> 3) & 0x3f;
2000 3475187d bellard
2001 0f8a249a blueswir1
            env->itlb_tag[i] = env->immuregs[6];
2002 1a2fb1c0 blueswir1
            env->itlb_tte[i] = val;
2003 0f8a249a blueswir1
            return;
2004 0f8a249a blueswir1
        }
2005 3475187d bellard
    case 0x57: // I-MMU demap
2006 0f8a249a blueswir1
        // XXX
2007 0f8a249a blueswir1
        return;
2008 3475187d bellard
    case 0x58: // D-MMU regs
2009 0f8a249a blueswir1
        {
2010 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
2011 0f8a249a blueswir1
            uint64_t oldreg;
2012 3b46e624 ths
2013 0f8a249a blueswir1
            oldreg = env->dmmuregs[reg];
2014 3475187d bellard
            switch(reg) {
2015 3475187d bellard
            case 0: // RO
2016 3475187d bellard
            case 4:
2017 3475187d bellard
                return;
2018 3475187d bellard
            case 3: // SFSR
2019 1a2fb1c0 blueswir1
                if ((val & 1) == 0) {
2020 1a2fb1c0 blueswir1
                    val = 0; // Clear SFSR, Fault address
2021 0f8a249a blueswir1
                    env->dmmuregs[4] = 0;
2022 0f8a249a blueswir1
                }
2023 1a2fb1c0 blueswir1
                env->dmmuregs[reg] = val;
2024 3475187d bellard
                break;
2025 3475187d bellard
            case 1: // Primary context
2026 3475187d bellard
            case 2: // Secondary context
2027 3475187d bellard
            case 5: // TSB access
2028 3475187d bellard
            case 6: // Tag access
2029 3475187d bellard
            case 7: // Virtual Watchpoint
2030 3475187d bellard
            case 8: // Physical Watchpoint
2031 3475187d bellard
            default:
2032 3475187d bellard
                break;
2033 3475187d bellard
            }
2034 1a2fb1c0 blueswir1
            env->dmmuregs[reg] = val;
2035 3475187d bellard
            if (oldreg != env->dmmuregs[reg]) {
2036 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08"
2037 77f193da blueswir1
                            PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
2038 3475187d bellard
            }
2039 952a328f blueswir1
#ifdef DEBUG_MMU
2040 0f8a249a blueswir1
            dump_mmu(env);
2041 3475187d bellard
#endif
2042 0f8a249a blueswir1
            return;
2043 0f8a249a blueswir1
        }
2044 3475187d bellard
    case 0x5c: // D-MMU data in
2045 0f8a249a blueswir1
        {
2046 0f8a249a blueswir1
            unsigned int i;
2047 0f8a249a blueswir1
2048 0f8a249a blueswir1
            // Try finding an invalid entry
2049 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2050 0f8a249a blueswir1
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
2051 0f8a249a blueswir1
                    env->dtlb_tag[i] = env->dmmuregs[6];
2052 1a2fb1c0 blueswir1
                    env->dtlb_tte[i] = val;
2053 0f8a249a blueswir1
                    return;
2054 0f8a249a blueswir1
                }
2055 0f8a249a blueswir1
            }
2056 0f8a249a blueswir1
            // Try finding an unlocked entry
2057 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2058 0f8a249a blueswir1
                if ((env->dtlb_tte[i] & 0x40) == 0) {
2059 0f8a249a blueswir1
                    env->dtlb_tag[i] = env->dmmuregs[6];
2060 1a2fb1c0 blueswir1
                    env->dtlb_tte[i] = val;
2061 0f8a249a blueswir1
                    return;
2062 0f8a249a blueswir1
                }
2063 0f8a249a blueswir1
            }
2064 0f8a249a blueswir1
            // error state?
2065 0f8a249a blueswir1
            return;
2066 0f8a249a blueswir1
        }
2067 3475187d bellard
    case 0x5d: // D-MMU data access
2068 0f8a249a blueswir1
        {
2069 1a2fb1c0 blueswir1
            unsigned int i = (addr >> 3) & 0x3f;
2070 3475187d bellard
2071 0f8a249a blueswir1
            env->dtlb_tag[i] = env->dmmuregs[6];
2072 1a2fb1c0 blueswir1
            env->dtlb_tte[i] = val;
2073 0f8a249a blueswir1
            return;
2074 0f8a249a blueswir1
        }
2075 3475187d bellard
    case 0x5f: // D-MMU demap
2076 83469015 bellard
    case 0x49: // Interrupt data receive
2077 0f8a249a blueswir1
        // XXX
2078 0f8a249a blueswir1
        return;
2079 f7350b47 blueswir1
    case 0x46: // D-cache data
2080 f7350b47 blueswir1
    case 0x47: // D-cache tag access
2081 a5a52cf2 blueswir1
    case 0x4b: // E-cache error enable
2082 a5a52cf2 blueswir1
    case 0x4c: // E-cache asynchronous fault status
2083 a5a52cf2 blueswir1
    case 0x4d: // E-cache asynchronous fault address
2084 f7350b47 blueswir1
    case 0x4e: // E-cache tag data
2085 f7350b47 blueswir1
    case 0x66: // I-cache instruction access
2086 f7350b47 blueswir1
    case 0x67: // I-cache tag access
2087 f7350b47 blueswir1
    case 0x6e: // I-cache predecode
2088 f7350b47 blueswir1
    case 0x6f: // I-cache LRU etc.
2089 f7350b47 blueswir1
    case 0x76: // E-cache tag
2090 f7350b47 blueswir1
    case 0x7e: // E-cache tag
2091 f7350b47 blueswir1
        return;
2092 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer, RO
2093 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer, RO
2094 3475187d bellard
    case 0x56: // I-MMU tag read, RO
2095 3475187d bellard
    case 0x59: // D-MMU 8k TSB pointer, RO
2096 3475187d bellard
    case 0x5a: // D-MMU 64k TSB pointer, RO
2097 3475187d bellard
    case 0x5b: // D-MMU data pointer, RO
2098 3475187d bellard
    case 0x5e: // D-MMU tag read, RO
2099 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
2100 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
2101 83469015 bellard
    case 0x82: // Primary no-fault, RO
2102 83469015 bellard
    case 0x83: // Secondary no-fault, RO
2103 83469015 bellard
    case 0x8a: // Primary no-fault LE, RO
2104 83469015 bellard
    case 0x8b: // Secondary no-fault LE, RO
2105 3475187d bellard
    default:
2106 1a2fb1c0 blueswir1
        do_unassigned_access(addr, 1, 0, 1);
2107 0f8a249a blueswir1
        return;
2108 3475187d bellard
    }
2109 3475187d bellard
}
2110 81ad8ba2 blueswir1
#endif /* CONFIG_USER_ONLY */
2111 3391c818 blueswir1
2112 db166940 blueswir1
void helper_ldda_asi(target_ulong addr, int asi, int rd)
2113 db166940 blueswir1
{
2114 db166940 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2115 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
2116 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
2117 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
2118 db166940 blueswir1
        raise_exception(TT_PRIV_ACT);
2119 db166940 blueswir1
2120 db166940 blueswir1
    switch (asi) {
2121 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
2122 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
2123 db166940 blueswir1
        helper_check_align(addr, 0xf);
2124 db166940 blueswir1
        if (rd == 0) {
2125 db166940 blueswir1
            env->gregs[1] = ldq_kernel(addr + 8);
2126 db166940 blueswir1
            if (asi == 0x2c)
2127 db166940 blueswir1
                bswap64s(&env->gregs[1]);
2128 db166940 blueswir1
        } else if (rd < 8) {
2129 db166940 blueswir1
            env->gregs[rd] = ldq_kernel(addr);
2130 db166940 blueswir1
            env->gregs[rd + 1] = ldq_kernel(addr + 8);
2131 db166940 blueswir1
            if (asi == 0x2c) {
2132 db166940 blueswir1
                bswap64s(&env->gregs[rd]);
2133 db166940 blueswir1
                bswap64s(&env->gregs[rd + 1]);
2134 db166940 blueswir1
            }
2135 db166940 blueswir1
        } else {
2136 db166940 blueswir1
            env->regwptr[rd] = ldq_kernel(addr);
2137 db166940 blueswir1
            env->regwptr[rd + 1] = ldq_kernel(addr + 8);
2138 db166940 blueswir1
            if (asi == 0x2c) {
2139 db166940 blueswir1
                bswap64s(&env->regwptr[rd]);
2140 db166940 blueswir1
                bswap64s(&env->regwptr[rd + 1]);
2141 db166940 blueswir1
            }
2142 db166940 blueswir1
        }
2143 db166940 blueswir1
        break;
2144 db166940 blueswir1
    default:
2145 db166940 blueswir1
        helper_check_align(addr, 0x3);
2146 db166940 blueswir1
        if (rd == 0)
2147 db166940 blueswir1
            env->gregs[1] = helper_ld_asi(addr + 4, asi, 4, 0);
2148 db166940 blueswir1
        else if (rd < 8) {
2149 db166940 blueswir1
            env->gregs[rd] = helper_ld_asi(addr, asi, 4, 0);
2150 db166940 blueswir1
            env->gregs[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2151 db166940 blueswir1
        } else {
2152 db166940 blueswir1
            env->regwptr[rd] = helper_ld_asi(addr, asi, 4, 0);
2153 db166940 blueswir1
            env->regwptr[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2154 db166940 blueswir1
        }
2155 db166940 blueswir1
        break;
2156 db166940 blueswir1
    }
2157 db166940 blueswir1
}
2158 db166940 blueswir1
2159 1a2fb1c0 blueswir1
void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2160 3391c818 blueswir1
{
2161 3391c818 blueswir1
    unsigned int i;
2162 1a2fb1c0 blueswir1
    target_ulong val;
2163 3391c818 blueswir1
2164 c2bc0e38 blueswir1
    helper_check_align(addr, 3);
2165 3391c818 blueswir1
    switch (asi) {
2166 3391c818 blueswir1
    case 0xf0: // Block load primary
2167 3391c818 blueswir1
    case 0xf1: // Block load secondary
2168 3391c818 blueswir1
    case 0xf8: // Block load primary LE
2169 3391c818 blueswir1
    case 0xf9: // Block load secondary LE
2170 51996525 blueswir1
        if (rd & 7) {
2171 51996525 blueswir1
            raise_exception(TT_ILL_INSN);
2172 51996525 blueswir1
            return;
2173 51996525 blueswir1
        }
2174 c2bc0e38 blueswir1
        helper_check_align(addr, 0x3f);
2175 51996525 blueswir1
        for (i = 0; i < 16; i++) {
2176 77f193da blueswir1
            *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4,
2177 77f193da blueswir1
                                                         0);
2178 1a2fb1c0 blueswir1
            addr += 4;
2179 3391c818 blueswir1
        }
2180 3391c818 blueswir1
2181 3391c818 blueswir1
        return;
2182 3391c818 blueswir1
    default:
2183 3391c818 blueswir1
        break;
2184 3391c818 blueswir1
    }
2185 3391c818 blueswir1
2186 1a2fb1c0 blueswir1
    val = helper_ld_asi(addr, asi, size, 0);
2187 3391c818 blueswir1
    switch(size) {
2188 3391c818 blueswir1
    default:
2189 3391c818 blueswir1
    case 4:
2190 1a2fb1c0 blueswir1
        *((uint32_t *)&FT0) = val;
2191 3391c818 blueswir1
        break;
2192 3391c818 blueswir1
    case 8:
2193 1a2fb1c0 blueswir1
        *((int64_t *)&DT0) = val;
2194 3391c818 blueswir1
        break;
2195 1f587329 blueswir1
    case 16:
2196 1f587329 blueswir1
        // XXX
2197 1f587329 blueswir1
        break;
2198 3391c818 blueswir1
    }
2199 3391c818 blueswir1
}
2200 3391c818 blueswir1
2201 1a2fb1c0 blueswir1
void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
2202 3391c818 blueswir1
{
2203 3391c818 blueswir1
    unsigned int i;
2204 1a2fb1c0 blueswir1
    target_ulong val = 0;
2205 3391c818 blueswir1
2206 c2bc0e38 blueswir1
    helper_check_align(addr, 3);
2207 3391c818 blueswir1
    switch (asi) {
2208 3391c818 blueswir1
    case 0xf0: // Block store primary
2209 3391c818 blueswir1
    case 0xf1: // Block store secondary
2210 3391c818 blueswir1
    case 0xf8: // Block store primary LE
2211 3391c818 blueswir1
    case 0xf9: // Block store secondary LE
2212 51996525 blueswir1
        if (rd & 7) {
2213 51996525 blueswir1
            raise_exception(TT_ILL_INSN);
2214 51996525 blueswir1
            return;
2215 51996525 blueswir1
        }
2216 c2bc0e38 blueswir1
        helper_check_align(addr, 0x3f);
2217 51996525 blueswir1
        for (i = 0; i < 16; i++) {
2218 1a2fb1c0 blueswir1
            val = *(uint32_t *)&env->fpr[rd++];
2219 1a2fb1c0 blueswir1
            helper_st_asi(addr, val, asi & 0x8f, 4);
2220 1a2fb1c0 blueswir1
            addr += 4;
2221 3391c818 blueswir1
        }
2222 3391c818 blueswir1
2223 3391c818 blueswir1
        return;
2224 3391c818 blueswir1
    default:
2225 3391c818 blueswir1
        break;
2226 3391c818 blueswir1
    }
2227 3391c818 blueswir1
2228 3391c818 blueswir1
    switch(size) {
2229 3391c818 blueswir1
    default:
2230 3391c818 blueswir1
    case 4:
2231 1a2fb1c0 blueswir1
        val = *((uint32_t *)&FT0);
2232 3391c818 blueswir1
        break;
2233 3391c818 blueswir1
    case 8:
2234 1a2fb1c0 blueswir1
        val = *((int64_t *)&DT0);
2235 3391c818 blueswir1
        break;
2236 1f587329 blueswir1
    case 16:
2237 1f587329 blueswir1
        // XXX
2238 1f587329 blueswir1
        break;
2239 3391c818 blueswir1
    }
2240 1a2fb1c0 blueswir1
    helper_st_asi(addr, val, asi, size);
2241 1a2fb1c0 blueswir1
}
2242 1a2fb1c0 blueswir1
2243 1a2fb1c0 blueswir1
target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
2244 1a2fb1c0 blueswir1
                            target_ulong val2, uint32_t asi)
2245 1a2fb1c0 blueswir1
{
2246 1a2fb1c0 blueswir1
    target_ulong ret;
2247 1a2fb1c0 blueswir1
2248 1a2fb1c0 blueswir1
    val1 &= 0xffffffffUL;
2249 1a2fb1c0 blueswir1
    ret = helper_ld_asi(addr, asi, 4, 0);
2250 1a2fb1c0 blueswir1
    ret &= 0xffffffffUL;
2251 1a2fb1c0 blueswir1
    if (val1 == ret)
2252 1a2fb1c0 blueswir1
        helper_st_asi(addr, val2 & 0xffffffffUL, asi, 4);
2253 1a2fb1c0 blueswir1
    return ret;
2254 3391c818 blueswir1
}
2255 3391c818 blueswir1
2256 1a2fb1c0 blueswir1
target_ulong helper_casx_asi(target_ulong addr, target_ulong val1,
2257 1a2fb1c0 blueswir1
                             target_ulong val2, uint32_t asi)
2258 1a2fb1c0 blueswir1
{
2259 1a2fb1c0 blueswir1
    target_ulong ret;
2260 1a2fb1c0 blueswir1
2261 1a2fb1c0 blueswir1
    ret = helper_ld_asi(addr, asi, 8, 0);
2262 1a2fb1c0 blueswir1
    if (val1 == ret)
2263 1a2fb1c0 blueswir1
        helper_st_asi(addr, val2, asi, 8);
2264 1a2fb1c0 blueswir1
    return ret;
2265 1a2fb1c0 blueswir1
}
2266 81ad8ba2 blueswir1
#endif /* TARGET_SPARC64 */
2267 3475187d bellard
2268 3475187d bellard
#ifndef TARGET_SPARC64
2269 1a2fb1c0 blueswir1
void helper_rett(void)
2270 e8af50a3 bellard
{
2271 af7bf89b bellard
    unsigned int cwp;
2272 af7bf89b bellard
2273 d4218d99 blueswir1
    if (env->psret == 1)
2274 d4218d99 blueswir1
        raise_exception(TT_ILL_INSN);
2275 d4218d99 blueswir1
2276 e8af50a3 bellard
    env->psret = 1;
2277 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1) ;
2278 e8af50a3 bellard
    if (env->wim & (1 << cwp)) {
2279 e8af50a3 bellard
        raise_exception(TT_WIN_UNF);
2280 e8af50a3 bellard
    }
2281 e8af50a3 bellard
    set_cwp(cwp);
2282 e8af50a3 bellard
    env->psrs = env->psrps;
2283 e8af50a3 bellard
}
2284 3475187d bellard
#endif
2285 e8af50a3 bellard
2286 3b89f26c blueswir1
target_ulong helper_udiv(target_ulong a, target_ulong b)
2287 3b89f26c blueswir1
{
2288 3b89f26c blueswir1
    uint64_t x0;
2289 3b89f26c blueswir1
    uint32_t x1;
2290 3b89f26c blueswir1
2291 3b89f26c blueswir1
    x0 = a | ((uint64_t) (env->y) << 32);
2292 3b89f26c blueswir1
    x1 = b;
2293 3b89f26c blueswir1
2294 3b89f26c blueswir1
    if (x1 == 0) {
2295 3b89f26c blueswir1
        raise_exception(TT_DIV_ZERO);
2296 3b89f26c blueswir1
    }
2297 3b89f26c blueswir1
2298 3b89f26c blueswir1
    x0 = x0 / x1;
2299 3b89f26c blueswir1
    if (x0 > 0xffffffff) {
2300 3b89f26c blueswir1
        env->cc_src2 = 1;
2301 3b89f26c blueswir1
        return 0xffffffff;
2302 3b89f26c blueswir1
    } else {
2303 3b89f26c blueswir1
        env->cc_src2 = 0;
2304 3b89f26c blueswir1
        return x0;
2305 3b89f26c blueswir1
    }
2306 3b89f26c blueswir1
}
2307 3b89f26c blueswir1
2308 3b89f26c blueswir1
target_ulong helper_sdiv(target_ulong a, target_ulong b)
2309 3b89f26c blueswir1
{
2310 3b89f26c blueswir1
    int64_t x0;
2311 3b89f26c blueswir1
    int32_t x1;
2312 3b89f26c blueswir1
2313 3b89f26c blueswir1
    x0 = a | ((int64_t) (env->y) << 32);
2314 3b89f26c blueswir1
    x1 = b;
2315 3b89f26c blueswir1
2316 3b89f26c blueswir1
    if (x1 == 0) {
2317 3b89f26c blueswir1
        raise_exception(TT_DIV_ZERO);
2318 3b89f26c blueswir1
    }
2319 3b89f26c blueswir1
2320 3b89f26c blueswir1
    x0 = x0 / x1;
2321 3b89f26c blueswir1
    if ((int32_t) x0 != x0) {
2322 3b89f26c blueswir1
        env->cc_src2 = 1;
2323 3b89f26c blueswir1
        return x0 < 0? 0x80000000: 0x7fffffff;
2324 3b89f26c blueswir1
    } else {
2325 3b89f26c blueswir1
        env->cc_src2 = 0;
2326 3b89f26c blueswir1
        return x0;
2327 3b89f26c blueswir1
    }
2328 3b89f26c blueswir1
}
2329 3b89f26c blueswir1
2330 1a2fb1c0 blueswir1
uint64_t helper_pack64(target_ulong high, target_ulong low)
2331 1a2fb1c0 blueswir1
{
2332 1a2fb1c0 blueswir1
    return ((uint64_t)high << 32) | (uint64_t)(low & 0xffffffff);
2333 1a2fb1c0 blueswir1
}
2334 1a2fb1c0 blueswir1
2335 7fa76c0b blueswir1
void helper_stdf(target_ulong addr, int mem_idx)
2336 7fa76c0b blueswir1
{
2337 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2338 7fa76c0b blueswir1
#if !defined(CONFIG_USER_ONLY)
2339 7fa76c0b blueswir1
    switch (mem_idx) {
2340 7fa76c0b blueswir1
    case 0:
2341 c2bc0e38 blueswir1
        stfq_user(addr, DT0);
2342 7fa76c0b blueswir1
        break;
2343 7fa76c0b blueswir1
    case 1:
2344 c2bc0e38 blueswir1
        stfq_kernel(addr, DT0);
2345 7fa76c0b blueswir1
        break;
2346 7fa76c0b blueswir1
#ifdef TARGET_SPARC64
2347 7fa76c0b blueswir1
    case 2:
2348 c2bc0e38 blueswir1
        stfq_hypv(addr, DT0);
2349 7fa76c0b blueswir1
        break;
2350 7fa76c0b blueswir1
#endif
2351 7fa76c0b blueswir1
    default:
2352 7fa76c0b blueswir1
        break;
2353 7fa76c0b blueswir1
    }
2354 7fa76c0b blueswir1
#else
2355 2cade6a3 blueswir1
    address_mask(env, &addr);
2356 c2bc0e38 blueswir1
    stfq_raw(addr, DT0);
2357 7fa76c0b blueswir1
#endif
2358 7fa76c0b blueswir1
}
2359 7fa76c0b blueswir1
2360 7fa76c0b blueswir1
void helper_lddf(target_ulong addr, int mem_idx)
2361 7fa76c0b blueswir1
{
2362 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2363 7fa76c0b blueswir1
#if !defined(CONFIG_USER_ONLY)
2364 7fa76c0b blueswir1
    switch (mem_idx) {
2365 7fa76c0b blueswir1
    case 0:
2366 c2bc0e38 blueswir1
        DT0 = ldfq_user(addr);
2367 7fa76c0b blueswir1
        break;
2368 7fa76c0b blueswir1
    case 1:
2369 c2bc0e38 blueswir1
        DT0 = ldfq_kernel(addr);
2370 7fa76c0b blueswir1
        break;
2371 7fa76c0b blueswir1
#ifdef TARGET_SPARC64
2372 7fa76c0b blueswir1
    case 2:
2373 c2bc0e38 blueswir1
        DT0 = ldfq_hypv(addr);
2374 7fa76c0b blueswir1
        break;
2375 7fa76c0b blueswir1
#endif
2376 7fa76c0b blueswir1
    default:
2377 7fa76c0b blueswir1
        break;
2378 7fa76c0b blueswir1
    }
2379 7fa76c0b blueswir1
#else
2380 2cade6a3 blueswir1
    address_mask(env, &addr);
2381 c2bc0e38 blueswir1
    DT0 = ldfq_raw(addr);
2382 7fa76c0b blueswir1
#endif
2383 7fa76c0b blueswir1
}
2384 7fa76c0b blueswir1
2385 64a88d5d blueswir1
void helper_ldqf(target_ulong addr, int mem_idx)
2386 7fa76c0b blueswir1
{
2387 7fa76c0b blueswir1
    // XXX add 128 bit load
2388 7fa76c0b blueswir1
    CPU_QuadU u;
2389 7fa76c0b blueswir1
2390 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2391 64a88d5d blueswir1
#if !defined(CONFIG_USER_ONLY)
2392 64a88d5d blueswir1
    switch (mem_idx) {
2393 64a88d5d blueswir1
    case 0:
2394 c2bc0e38 blueswir1
        u.ll.upper = ldq_user(addr);
2395 c2bc0e38 blueswir1
        u.ll.lower = ldq_user(addr + 8);
2396 64a88d5d blueswir1
        QT0 = u.q;
2397 64a88d5d blueswir1
        break;
2398 64a88d5d blueswir1
    case 1:
2399 c2bc0e38 blueswir1
        u.ll.upper = ldq_kernel(addr);
2400 c2bc0e38 blueswir1
        u.ll.lower = ldq_kernel(addr + 8);
2401 64a88d5d blueswir1
        QT0 = u.q;
2402 64a88d5d blueswir1
        break;
2403 64a88d5d blueswir1
#ifdef TARGET_SPARC64
2404 64a88d5d blueswir1
    case 2:
2405 c2bc0e38 blueswir1
        u.ll.upper = ldq_hypv(addr);
2406 c2bc0e38 blueswir1
        u.ll.lower = ldq_hypv(addr + 8);
2407 64a88d5d blueswir1
        QT0 = u.q;
2408 64a88d5d blueswir1
        break;
2409 64a88d5d blueswir1
#endif
2410 64a88d5d blueswir1
    default:
2411 64a88d5d blueswir1
        break;
2412 64a88d5d blueswir1
    }
2413 64a88d5d blueswir1
#else
2414 2cade6a3 blueswir1
    address_mask(env, &addr);
2415 c2bc0e38 blueswir1
    u.ll.upper = ldq_raw(addr);
2416 c2bc0e38 blueswir1
    u.ll.lower = ldq_raw((addr + 8) & 0xffffffffULL);
2417 7fa76c0b blueswir1
    QT0 = u.q;
2418 64a88d5d blueswir1
#endif
2419 7fa76c0b blueswir1
}
2420 7fa76c0b blueswir1
2421 64a88d5d blueswir1
void helper_stqf(target_ulong addr, int mem_idx)
2422 7fa76c0b blueswir1
{
2423 7fa76c0b blueswir1
    // XXX add 128 bit store
2424 7fa76c0b blueswir1
    CPU_QuadU u;
2425 7fa76c0b blueswir1
2426 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2427 64a88d5d blueswir1
#if !defined(CONFIG_USER_ONLY)
2428 64a88d5d blueswir1
    switch (mem_idx) {
2429 64a88d5d blueswir1
    case 0:
2430 64a88d5d blueswir1
        u.q = QT0;
2431 c2bc0e38 blueswir1
        stq_user(addr, u.ll.upper);
2432 c2bc0e38 blueswir1
        stq_user(addr + 8, u.ll.lower);
2433 64a88d5d blueswir1
        break;
2434 64a88d5d blueswir1
    case 1:
2435 64a88d5d blueswir1
        u.q = QT0;
2436 c2bc0e38 blueswir1
        stq_kernel(addr, u.ll.upper);
2437 c2bc0e38 blueswir1
        stq_kernel(addr + 8, u.ll.lower);
2438 64a88d5d blueswir1
        break;
2439 64a88d5d blueswir1
#ifdef TARGET_SPARC64
2440 64a88d5d blueswir1
    case 2:
2441 64a88d5d blueswir1
        u.q = QT0;
2442 c2bc0e38 blueswir1
        stq_hypv(addr, u.ll.upper);
2443 c2bc0e38 blueswir1
        stq_hypv(addr + 8, u.ll.lower);
2444 64a88d5d blueswir1
        break;
2445 64a88d5d blueswir1
#endif
2446 64a88d5d blueswir1
    default:
2447 64a88d5d blueswir1
        break;
2448 64a88d5d blueswir1
    }
2449 64a88d5d blueswir1
#else
2450 7fa76c0b blueswir1
    u.q = QT0;
2451 2cade6a3 blueswir1
    address_mask(env, &addr);
2452 c2bc0e38 blueswir1
    stq_raw(addr, u.ll.upper);
2453 c2bc0e38 blueswir1
    stq_raw((addr + 8) & 0xffffffffULL, u.ll.lower);
2454 7fa76c0b blueswir1
#endif
2455 64a88d5d blueswir1
}
2456 7fa76c0b blueswir1
2457 8d5f07fa bellard
void helper_ldfsr(void)
2458 e8af50a3 bellard
{
2459 7a0e1f41 bellard
    int rnd_mode;
2460 bb5529bb blueswir1
2461 bb5529bb blueswir1
    PUT_FSR32(env, *((uint32_t *) &FT0));
2462 e8af50a3 bellard
    switch (env->fsr & FSR_RD_MASK) {
2463 e8af50a3 bellard
    case FSR_RD_NEAREST:
2464 7a0e1f41 bellard
        rnd_mode = float_round_nearest_even;
2465 0f8a249a blueswir1
        break;
2466 ed910241 bellard
    default:
2467 e8af50a3 bellard
    case FSR_RD_ZERO:
2468 7a0e1f41 bellard
        rnd_mode = float_round_to_zero;
2469 0f8a249a blueswir1
        break;
2470 e8af50a3 bellard
    case FSR_RD_POS:
2471 7a0e1f41 bellard
        rnd_mode = float_round_up;
2472 0f8a249a blueswir1
        break;
2473 e8af50a3 bellard
    case FSR_RD_NEG:
2474 7a0e1f41 bellard
        rnd_mode = float_round_down;
2475 0f8a249a blueswir1
        break;
2476 e8af50a3 bellard
    }
2477 7a0e1f41 bellard
    set_float_rounding_mode(rnd_mode, &env->fp_status);
2478 e8af50a3 bellard
}
2479 e80cfcfc bellard
2480 bb5529bb blueswir1
void helper_stfsr(void)
2481 bb5529bb blueswir1
{
2482 bb5529bb blueswir1
    *((uint32_t *) &FT0) = GET_FSR32(env);
2483 bb5529bb blueswir1
}
2484 bb5529bb blueswir1
2485 bb5529bb blueswir1
void helper_debug(void)
2486 e80cfcfc bellard
{
2487 e80cfcfc bellard
    env->exception_index = EXCP_DEBUG;
2488 e80cfcfc bellard
    cpu_loop_exit();
2489 e80cfcfc bellard
}
2490 af7bf89b bellard
2491 3475187d bellard
#ifndef TARGET_SPARC64
2492 72a9747b blueswir1
/* XXX: use another pointer for %iN registers to avoid slow wrapping
2493 72a9747b blueswir1
   handling ? */
2494 72a9747b blueswir1
void helper_save(void)
2495 72a9747b blueswir1
{
2496 72a9747b blueswir1
    uint32_t cwp;
2497 72a9747b blueswir1
2498 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2499 72a9747b blueswir1
    if (env->wim & (1 << cwp)) {
2500 72a9747b blueswir1
        raise_exception(TT_WIN_OVF);
2501 72a9747b blueswir1
    }
2502 72a9747b blueswir1
    set_cwp(cwp);
2503 72a9747b blueswir1
}
2504 72a9747b blueswir1
2505 72a9747b blueswir1
void helper_restore(void)
2506 72a9747b blueswir1
{
2507 72a9747b blueswir1
    uint32_t cwp;
2508 72a9747b blueswir1
2509 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1);
2510 72a9747b blueswir1
    if (env->wim & (1 << cwp)) {
2511 72a9747b blueswir1
        raise_exception(TT_WIN_UNF);
2512 72a9747b blueswir1
    }
2513 72a9747b blueswir1
    set_cwp(cwp);
2514 72a9747b blueswir1
}
2515 72a9747b blueswir1
2516 1a2fb1c0 blueswir1
void helper_wrpsr(target_ulong new_psr)
2517 af7bf89b bellard
{
2518 1a14026e blueswir1
    if ((new_psr & PSR_CWP) >= env->nwindows)
2519 d4218d99 blueswir1
        raise_exception(TT_ILL_INSN);
2520 d4218d99 blueswir1
    else
2521 1a2fb1c0 blueswir1
        PUT_PSR(env, new_psr);
2522 af7bf89b bellard
}
2523 af7bf89b bellard
2524 1a2fb1c0 blueswir1
target_ulong helper_rdpsr(void)
2525 af7bf89b bellard
{
2526 1a2fb1c0 blueswir1
    return GET_PSR(env);
2527 af7bf89b bellard
}
2528 3475187d bellard
2529 3475187d bellard
#else
2530 72a9747b blueswir1
/* XXX: use another pointer for %iN registers to avoid slow wrapping
2531 72a9747b blueswir1
   handling ? */
2532 72a9747b blueswir1
void helper_save(void)
2533 72a9747b blueswir1
{
2534 72a9747b blueswir1
    uint32_t cwp;
2535 72a9747b blueswir1
2536 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2537 72a9747b blueswir1
    if (env->cansave == 0) {
2538 72a9747b blueswir1
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
2539 72a9747b blueswir1
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2540 72a9747b blueswir1
                                    ((env->wstate & 0x7) << 2)));
2541 72a9747b blueswir1
    } else {
2542 72a9747b blueswir1
        if (env->cleanwin - env->canrestore == 0) {
2543 72a9747b blueswir1
            // XXX Clean windows without trap
2544 72a9747b blueswir1
            raise_exception(TT_CLRWIN);
2545 72a9747b blueswir1
        } else {
2546 72a9747b blueswir1
            env->cansave--;
2547 72a9747b blueswir1
            env->canrestore++;
2548 72a9747b blueswir1
            set_cwp(cwp);
2549 72a9747b blueswir1
        }
2550 72a9747b blueswir1
    }
2551 72a9747b blueswir1
}
2552 72a9747b blueswir1
2553 72a9747b blueswir1
void helper_restore(void)
2554 72a9747b blueswir1
{
2555 72a9747b blueswir1
    uint32_t cwp;
2556 72a9747b blueswir1
2557 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1);
2558 72a9747b blueswir1
    if (env->canrestore == 0) {
2559 72a9747b blueswir1
        raise_exception(TT_FILL | (env->otherwin != 0 ?
2560 72a9747b blueswir1
                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2561 72a9747b blueswir1
                                   ((env->wstate & 0x7) << 2)));
2562 72a9747b blueswir1
    } else {
2563 72a9747b blueswir1
        env->cansave++;
2564 72a9747b blueswir1
        env->canrestore--;
2565 72a9747b blueswir1
        set_cwp(cwp);
2566 72a9747b blueswir1
    }
2567 72a9747b blueswir1
}
2568 72a9747b blueswir1
2569 72a9747b blueswir1
void helper_flushw(void)
2570 72a9747b blueswir1
{
2571 1a14026e blueswir1
    if (env->cansave != env->nwindows - 2) {
2572 72a9747b blueswir1
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
2573 72a9747b blueswir1
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2574 72a9747b blueswir1
                                    ((env->wstate & 0x7) << 2)));
2575 72a9747b blueswir1
    }
2576 72a9747b blueswir1
}
2577 72a9747b blueswir1
2578 72a9747b blueswir1
void helper_saved(void)
2579 72a9747b blueswir1
{
2580 72a9747b blueswir1
    env->cansave++;
2581 72a9747b blueswir1
    if (env->otherwin == 0)
2582 72a9747b blueswir1
        env->canrestore--;
2583 72a9747b blueswir1
    else
2584 72a9747b blueswir1
        env->otherwin--;
2585 72a9747b blueswir1
}
2586 72a9747b blueswir1
2587 72a9747b blueswir1
void helper_restored(void)
2588 72a9747b blueswir1
{
2589 72a9747b blueswir1
    env->canrestore++;
2590 1a14026e blueswir1
    if (env->cleanwin < env->nwindows - 1)
2591 72a9747b blueswir1
        env->cleanwin++;
2592 72a9747b blueswir1
    if (env->otherwin == 0)
2593 72a9747b blueswir1
        env->cansave--;
2594 72a9747b blueswir1
    else
2595 72a9747b blueswir1
        env->otherwin--;
2596 72a9747b blueswir1
}
2597 72a9747b blueswir1
2598 d35527d9 blueswir1
target_ulong helper_rdccr(void)
2599 d35527d9 blueswir1
{
2600 d35527d9 blueswir1
    return GET_CCR(env);
2601 d35527d9 blueswir1
}
2602 d35527d9 blueswir1
2603 d35527d9 blueswir1
void helper_wrccr(target_ulong new_ccr)
2604 d35527d9 blueswir1
{
2605 d35527d9 blueswir1
    PUT_CCR(env, new_ccr);
2606 d35527d9 blueswir1
}
2607 d35527d9 blueswir1
2608 d35527d9 blueswir1
// CWP handling is reversed in V9, but we still use the V8 register
2609 d35527d9 blueswir1
// order.
2610 d35527d9 blueswir1
target_ulong helper_rdcwp(void)
2611 d35527d9 blueswir1
{
2612 d35527d9 blueswir1
    return GET_CWP64(env);
2613 d35527d9 blueswir1
}
2614 d35527d9 blueswir1
2615 d35527d9 blueswir1
void helper_wrcwp(target_ulong new_cwp)
2616 d35527d9 blueswir1
{
2617 d35527d9 blueswir1
    PUT_CWP64(env, new_cwp);
2618 d35527d9 blueswir1
}
2619 3475187d bellard
2620 1f5063fb blueswir1
// This function uses non-native bit order
2621 1f5063fb blueswir1
#define GET_FIELD(X, FROM, TO)                                  \
2622 1f5063fb blueswir1
    ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
2623 1f5063fb blueswir1
2624 1f5063fb blueswir1
// This function uses the order in the manuals, i.e. bit 0 is 2^0
2625 1f5063fb blueswir1
#define GET_FIELD_SP(X, FROM, TO)               \
2626 1f5063fb blueswir1
    GET_FIELD(X, 63 - (TO), 63 - (FROM))
2627 1f5063fb blueswir1
2628 1f5063fb blueswir1
target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
2629 1f5063fb blueswir1
{
2630 1f5063fb blueswir1
    return (GET_FIELD_SP(pixel_addr, 60, 63) << (17 + 2 * cubesize)) |
2631 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 39, 39 + cubesize - 1) << (17 + cubesize)) |
2632 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 17 + cubesize - 1, 17) << 17) |
2633 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 56, 59) << 13) |
2634 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 35, 38) << 9) |
2635 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 13, 16) << 5) |
2636 1f5063fb blueswir1
        (((pixel_addr >> 55) & 1) << 4) |
2637 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 33, 34) << 2) |
2638 1f5063fb blueswir1
        GET_FIELD_SP(pixel_addr, 11, 12);
2639 1f5063fb blueswir1
}
2640 1f5063fb blueswir1
2641 1f5063fb blueswir1
target_ulong helper_alignaddr(target_ulong addr, target_ulong offset)
2642 1f5063fb blueswir1
{
2643 1f5063fb blueswir1
    uint64_t tmp;
2644 1f5063fb blueswir1
2645 1f5063fb blueswir1
    tmp = addr + offset;
2646 1f5063fb blueswir1
    env->gsr &= ~7ULL;
2647 1f5063fb blueswir1
    env->gsr |= tmp & 7ULL;
2648 1f5063fb blueswir1
    return tmp & ~7ULL;
2649 1f5063fb blueswir1
}
2650 1f5063fb blueswir1
2651 1a2fb1c0 blueswir1
target_ulong helper_popc(target_ulong val)
2652 3475187d bellard
{
2653 1a2fb1c0 blueswir1
    return ctpop64(val);
2654 3475187d bellard
}
2655 83469015 bellard
2656 83469015 bellard
static inline uint64_t *get_gregset(uint64_t pstate)
2657 83469015 bellard
{
2658 83469015 bellard
    switch (pstate) {
2659 83469015 bellard
    default:
2660 83469015 bellard
    case 0:
2661 0f8a249a blueswir1
        return env->bgregs;
2662 83469015 bellard
    case PS_AG:
2663 0f8a249a blueswir1
        return env->agregs;
2664 83469015 bellard
    case PS_MG:
2665 0f8a249a blueswir1
        return env->mgregs;
2666 83469015 bellard
    case PS_IG:
2667 0f8a249a blueswir1
        return env->igregs;
2668 83469015 bellard
    }
2669 83469015 bellard
}
2670 83469015 bellard
2671 f2bc7e7f blueswir1
void change_pstate(uint64_t new_pstate)
2672 83469015 bellard
{
2673 8f1f22f6 blueswir1
    uint64_t pstate_regs, new_pstate_regs;
2674 83469015 bellard
    uint64_t *src, *dst;
2675 83469015 bellard
2676 83469015 bellard
    pstate_regs = env->pstate & 0xc01;
2677 83469015 bellard
    new_pstate_regs = new_pstate & 0xc01;
2678 83469015 bellard
    if (new_pstate_regs != pstate_regs) {
2679 0f8a249a blueswir1
        // Switch global register bank
2680 0f8a249a blueswir1
        src = get_gregset(new_pstate_regs);
2681 0f8a249a blueswir1
        dst = get_gregset(pstate_regs);
2682 0f8a249a blueswir1
        memcpy32(dst, env->gregs);
2683 0f8a249a blueswir1
        memcpy32(env->gregs, src);
2684 83469015 bellard
    }
2685 83469015 bellard
    env->pstate = new_pstate;
2686 83469015 bellard
}
2687 83469015 bellard
2688 1a2fb1c0 blueswir1
void helper_wrpstate(target_ulong new_state)
2689 8f1f22f6 blueswir1
{
2690 5578ceab blueswir1
    if (!(env->def->features & CPU_FEATURE_GL))
2691 fb79ceb9 blueswir1
        change_pstate(new_state & 0xf3f);
2692 8f1f22f6 blueswir1
}
2693 8f1f22f6 blueswir1
2694 1a2fb1c0 blueswir1
void helper_done(void)
2695 83469015 bellard
{
2696 375ee38b blueswir1
    env->pc = env->tsptr->tpc;
2697 375ee38b blueswir1
    env->npc = env->tsptr->tnpc + 4;
2698 375ee38b blueswir1
    PUT_CCR(env, env->tsptr->tstate >> 32);
2699 375ee38b blueswir1
    env->asi = (env->tsptr->tstate >> 24) & 0xff;
2700 375ee38b blueswir1
    change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
2701 375ee38b blueswir1
    PUT_CWP64(env, env->tsptr->tstate & 0xff);
2702 e6bf7d70 blueswir1
    env->tl--;
2703 c19148bd blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
2704 83469015 bellard
}
2705 83469015 bellard
2706 1a2fb1c0 blueswir1
void helper_retry(void)
2707 83469015 bellard
{
2708 375ee38b blueswir1
    env->pc = env->tsptr->tpc;
2709 375ee38b blueswir1
    env->npc = env->tsptr->tnpc;
2710 375ee38b blueswir1
    PUT_CCR(env, env->tsptr->tstate >> 32);
2711 375ee38b blueswir1
    env->asi = (env->tsptr->tstate >> 24) & 0xff;
2712 375ee38b blueswir1
    change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
2713 375ee38b blueswir1
    PUT_CWP64(env, env->tsptr->tstate & 0xff);
2714 e6bf7d70 blueswir1
    env->tl--;
2715 c19148bd blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
2716 83469015 bellard
}
2717 3475187d bellard
#endif
2718 ee5bbe38 bellard
2719 f2bc7e7f blueswir1
void cpu_set_cwp(CPUState *env1, int new_cwp)
2720 ee5bbe38 bellard
{
2721 ee5bbe38 bellard
    /* put the modified wrap registers at their proper location */
2722 9fac3a3a blueswir1
    if (env1->cwp == env1->nwindows - 1)
2723 9fac3a3a blueswir1
        memcpy32(env1->regbase, env1->regbase + env1->nwindows * 16);
2724 f2bc7e7f blueswir1
    env1->cwp = new_cwp;
2725 ee5bbe38 bellard
    /* put the wrap registers at their temporary location */
2726 9fac3a3a blueswir1
    if (new_cwp == env1->nwindows - 1)
2727 9fac3a3a blueswir1
        memcpy32(env1->regbase + env1->nwindows * 16, env1->regbase);
2728 f2bc7e7f blueswir1
    env1->regwptr = env1->regbase + (new_cwp * 16);
2729 ee5bbe38 bellard
}
2730 ee5bbe38 bellard
2731 f2bc7e7f blueswir1
void set_cwp(int new_cwp)
2732 ee5bbe38 bellard
{
2733 f2bc7e7f blueswir1
    cpu_set_cwp(env, new_cwp);
2734 ee5bbe38 bellard
}
2735 ee5bbe38 bellard
2736 f2bc7e7f blueswir1
void helper_flush(target_ulong addr)
2737 ee5bbe38 bellard
{
2738 f2bc7e7f blueswir1
    addr &= ~7;
2739 f2bc7e7f blueswir1
    tb_invalidate_page_range(addr, addr + 8);
2740 ee5bbe38 bellard
}
2741 ee5bbe38 bellard
2742 5fafdf24 ths
#if !defined(CONFIG_USER_ONLY)
2743 ee5bbe38 bellard
2744 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
2745 d2889a3e blueswir1
                                void *retaddr);
2746 d2889a3e blueswir1
2747 ee5bbe38 bellard
#define MMUSUFFIX _mmu
2748 d2889a3e blueswir1
#define ALIGNED_ONLY
2749 ee5bbe38 bellard
2750 ee5bbe38 bellard
#define SHIFT 0
2751 ee5bbe38 bellard
#include "softmmu_template.h"
2752 ee5bbe38 bellard
2753 ee5bbe38 bellard
#define SHIFT 1
2754 ee5bbe38 bellard
#include "softmmu_template.h"
2755 ee5bbe38 bellard
2756 ee5bbe38 bellard
#define SHIFT 2
2757 ee5bbe38 bellard
#include "softmmu_template.h"
2758 ee5bbe38 bellard
2759 ee5bbe38 bellard
#define SHIFT 3
2760 ee5bbe38 bellard
#include "softmmu_template.h"
2761 ee5bbe38 bellard
2762 c2bc0e38 blueswir1
/* XXX: make it generic ? */
2763 c2bc0e38 blueswir1
static void cpu_restore_state2(void *retaddr)
2764 c2bc0e38 blueswir1
{
2765 c2bc0e38 blueswir1
    TranslationBlock *tb;
2766 c2bc0e38 blueswir1
    unsigned long pc;
2767 c2bc0e38 blueswir1
2768 c2bc0e38 blueswir1
    if (retaddr) {
2769 c2bc0e38 blueswir1
        /* now we have a real cpu fault */
2770 c2bc0e38 blueswir1
        pc = (unsigned long)retaddr;
2771 c2bc0e38 blueswir1
        tb = tb_find_pc(pc);
2772 c2bc0e38 blueswir1
        if (tb) {
2773 c2bc0e38 blueswir1
            /* the PC is inside the translated code. It means that we have
2774 c2bc0e38 blueswir1
               a virtual CPU fault */
2775 c2bc0e38 blueswir1
            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
2776 c2bc0e38 blueswir1
        }
2777 c2bc0e38 blueswir1
    }
2778 c2bc0e38 blueswir1
}
2779 c2bc0e38 blueswir1
2780 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
2781 d2889a3e blueswir1
                                void *retaddr)
2782 d2889a3e blueswir1
{
2783 94554550 blueswir1
#ifdef DEBUG_UNALIGNED
2784 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
2785 c2bc0e38 blueswir1
           "\n", addr, env->pc);
2786 94554550 blueswir1
#endif
2787 c2bc0e38 blueswir1
    cpu_restore_state2(retaddr);
2788 94554550 blueswir1
    raise_exception(TT_UNALIGNED);
2789 d2889a3e blueswir1
}
2790 ee5bbe38 bellard
2791 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
2792 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
2793 ee5bbe38 bellard
   from generated code or from helper.c) */
2794 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
2795 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
2796 ee5bbe38 bellard
{
2797 ee5bbe38 bellard
    int ret;
2798 ee5bbe38 bellard
    CPUState *saved_env;
2799 ee5bbe38 bellard
2800 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
2801 ee5bbe38 bellard
       generated code */
2802 ee5bbe38 bellard
    saved_env = env;
2803 ee5bbe38 bellard
    env = cpu_single_env;
2804 ee5bbe38 bellard
2805 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
2806 ee5bbe38 bellard
    if (ret) {
2807 c2bc0e38 blueswir1
        cpu_restore_state2(retaddr);
2808 ee5bbe38 bellard
        cpu_loop_exit();
2809 ee5bbe38 bellard
    }
2810 ee5bbe38 bellard
    env = saved_env;
2811 ee5bbe38 bellard
}
2812 ee5bbe38 bellard
2813 ee5bbe38 bellard
#endif
2814 6c36d3fa blueswir1
2815 6c36d3fa blueswir1
#ifndef TARGET_SPARC64
2816 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
2817 6c36d3fa blueswir1
                          int is_asi)
2818 6c36d3fa blueswir1
{
2819 6c36d3fa blueswir1
    CPUState *saved_env;
2820 6c36d3fa blueswir1
2821 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
2822 6c36d3fa blueswir1
       generated code */
2823 6c36d3fa blueswir1
    saved_env = env;
2824 6c36d3fa blueswir1
    env = cpu_single_env;
2825 8543e2cf blueswir1
#ifdef DEBUG_UNASSIGNED
2826 8543e2cf blueswir1
    if (is_asi)
2827 77f193da blueswir1
        printf("Unassigned mem %s access to " TARGET_FMT_plx
2828 77f193da blueswir1
               " asi 0x%02x from " TARGET_FMT_lx "\n",
2829 8543e2cf blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", addr, is_asi,
2830 8543e2cf blueswir1
               env->pc);
2831 8543e2cf blueswir1
    else
2832 8543e2cf blueswir1
        printf("Unassigned mem %s access to " TARGET_FMT_plx " from "
2833 8543e2cf blueswir1
               TARGET_FMT_lx "\n",
2834 8543e2cf blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", addr, env->pc);
2835 8543e2cf blueswir1
#endif
2836 6c36d3fa blueswir1
    if (env->mmuregs[3]) /* Fault status register */
2837 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
2838 6c36d3fa blueswir1
    if (is_asi)
2839 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 16;
2840 6c36d3fa blueswir1
    if (env->psrs)
2841 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 5;
2842 6c36d3fa blueswir1
    if (is_exec)
2843 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 6;
2844 6c36d3fa blueswir1
    if (is_write)
2845 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 7;
2846 6c36d3fa blueswir1
    env->mmuregs[3] |= (5 << 2) | 2;
2847 6c36d3fa blueswir1
    env->mmuregs[4] = addr; /* Fault address register */
2848 6c36d3fa blueswir1
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
2849 1b2e93c1 blueswir1
        if (is_exec)
2850 1b2e93c1 blueswir1
            raise_exception(TT_CODE_ACCESS);
2851 1b2e93c1 blueswir1
        else
2852 1b2e93c1 blueswir1
            raise_exception(TT_DATA_ACCESS);
2853 6c36d3fa blueswir1
    }
2854 6c36d3fa blueswir1
    env = saved_env;
2855 6c36d3fa blueswir1
}
2856 6c36d3fa blueswir1
#else
2857 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
2858 6c36d3fa blueswir1
                          int is_asi)
2859 6c36d3fa blueswir1
{
2860 6c36d3fa blueswir1
#ifdef DEBUG_UNASSIGNED
2861 6c36d3fa blueswir1
    CPUState *saved_env;
2862 6c36d3fa blueswir1
2863 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
2864 6c36d3fa blueswir1
       generated code */
2865 6c36d3fa blueswir1
    saved_env = env;
2866 6c36d3fa blueswir1
    env = cpu_single_env;
2867 77f193da blueswir1
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
2868 77f193da blueswir1
           "\n", addr, env->pc);
2869 6c36d3fa blueswir1
    env = saved_env;
2870 6c36d3fa blueswir1
#endif
2871 1b2e93c1 blueswir1
    if (is_exec)
2872 1b2e93c1 blueswir1
        raise_exception(TT_CODE_ACCESS);
2873 1b2e93c1 blueswir1
    else
2874 1b2e93c1 blueswir1
        raise_exception(TT_DATA_ACCESS);
2875 6c36d3fa blueswir1
}
2876 6c36d3fa blueswir1
#endif