Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 1121f879

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

2753 91736d37 blueswir1
            fprintf(logfile, "       code=");
2754 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
2755 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
2756 91736d37 blueswir1
                fprintf(logfile, " %02x", ldub(ptr + i));
2757 91736d37 blueswir1
            }
2758 91736d37 blueswir1
            fprintf(logfile, "\n");
2759 91736d37 blueswir1
        }
2760 91736d37 blueswir1
#endif
2761 91736d37 blueswir1
        count++;
2762 91736d37 blueswir1
    }
2763 91736d37 blueswir1
#endif
2764 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
2765 91736d37 blueswir1
    if (env->tl >= env->maxtl) {
2766 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
2767 91736d37 blueswir1
                  " Error state", env->exception_index, env->tl, env->maxtl);
2768 91736d37 blueswir1
        return;
2769 91736d37 blueswir1
    }
2770 91736d37 blueswir1
#endif
2771 91736d37 blueswir1
    if (env->tl < env->maxtl - 1) {
2772 91736d37 blueswir1
        env->tl++;
2773 91736d37 blueswir1
    } else {
2774 91736d37 blueswir1
        env->pstate |= PS_RED;
2775 91736d37 blueswir1
        if (env->tl < env->maxtl)
2776 91736d37 blueswir1
            env->tl++;
2777 91736d37 blueswir1
    }
2778 91736d37 blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
2779 91736d37 blueswir1
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
2780 91736d37 blueswir1
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
2781 91736d37 blueswir1
        GET_CWP64(env);
2782 91736d37 blueswir1
    env->tsptr->tpc = env->pc;
2783 91736d37 blueswir1
    env->tsptr->tnpc = env->npc;
2784 91736d37 blueswir1
    env->tsptr->tt = intno;
2785 91736d37 blueswir1
    if (!(env->def->features & CPU_FEATURE_GL)) {
2786 91736d37 blueswir1
        switch (intno) {
2787 91736d37 blueswir1
        case TT_IVEC:
2788 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
2789 91736d37 blueswir1
            break;
2790 91736d37 blueswir1
        case TT_TFAULT:
2791 91736d37 blueswir1
        case TT_TMISS:
2792 91736d37 blueswir1
        case TT_DFAULT:
2793 91736d37 blueswir1
        case TT_DMISS:
2794 91736d37 blueswir1
        case TT_DPROT:
2795 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
2796 91736d37 blueswir1
            break;
2797 91736d37 blueswir1
        default:
2798 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
2799 91736d37 blueswir1
            break;
2800 91736d37 blueswir1
        }
2801 91736d37 blueswir1
    }
2802 91736d37 blueswir1
    if (intno == TT_CLRWIN)
2803 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
2804 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_SPILL)
2805 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
2806 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_FILL)
2807 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
2808 91736d37 blueswir1
    env->tbr &= ~0x7fffULL;
2809 91736d37 blueswir1
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
2810 91736d37 blueswir1
    env->pc = env->tbr;
2811 91736d37 blueswir1
    env->npc = env->pc + 4;
2812 91736d37 blueswir1
    env->exception_index = 0;
2813 ee5bbe38 bellard
}
2814 91736d37 blueswir1
#else
2815 91736d37 blueswir1
#ifdef DEBUG_PCALL
2816 91736d37 blueswir1
static const char * const excp_names[0x80] = {
2817 91736d37 blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
2818 91736d37 blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
2819 91736d37 blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
2820 91736d37 blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
2821 91736d37 blueswir1
    [TT_WIN_OVF] = "Window Overflow",
2822 91736d37 blueswir1
    [TT_WIN_UNF] = "Window Underflow",
2823 91736d37 blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
2824 91736d37 blueswir1
    [TT_FP_EXCP] = "FPU Exception",
2825 91736d37 blueswir1
    [TT_DFAULT] = "Data Access Fault",
2826 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
2827 91736d37 blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
2828 91736d37 blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
2829 91736d37 blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
2830 91736d37 blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
2831 91736d37 blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
2832 91736d37 blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
2833 91736d37 blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
2834 91736d37 blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
2835 91736d37 blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
2836 91736d37 blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
2837 91736d37 blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
2838 91736d37 blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
2839 91736d37 blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
2840 91736d37 blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
2841 91736d37 blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
2842 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
2843 91736d37 blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
2844 91736d37 blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
2845 91736d37 blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
2846 91736d37 blueswir1
    [TT_NCP_INSN] = "Coprocessor Disabled",
2847 91736d37 blueswir1
};
2848 91736d37 blueswir1
#endif
2849 ee5bbe38 bellard
2850 91736d37 blueswir1
void do_interrupt(CPUState *env)
2851 ee5bbe38 bellard
{
2852 91736d37 blueswir1
    int cwp, intno = env->exception_index;
2853 91736d37 blueswir1
2854 91736d37 blueswir1
#ifdef DEBUG_PCALL
2855 91736d37 blueswir1
    if (loglevel & CPU_LOG_INT) {
2856 91736d37 blueswir1
        static int count;
2857 91736d37 blueswir1
        const char *name;
2858 91736d37 blueswir1
2859 91736d37 blueswir1
        if (intno < 0 || intno >= 0x100)
2860 91736d37 blueswir1
            name = "Unknown";
2861 91736d37 blueswir1
        else if (intno >= 0x80)
2862 91736d37 blueswir1
            name = "Trap Instruction";
2863 91736d37 blueswir1
        else {
2864 91736d37 blueswir1
            name = excp_names[intno];
2865 91736d37 blueswir1
            if (!name)
2866 91736d37 blueswir1
                name = "Unknown";
2867 91736d37 blueswir1
        }
2868 91736d37 blueswir1
2869 91736d37 blueswir1
        fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
2870 91736d37 blueswir1
                count, name, intno,
2871 91736d37 blueswir1
                env->pc,
2872 91736d37 blueswir1
                env->npc, env->regwptr[6]);
2873 91736d37 blueswir1
        cpu_dump_state(env, logfile, fprintf, 0);
2874 91736d37 blueswir1
#if 0
2875 91736d37 blueswir1
        {
2876 91736d37 blueswir1
            int i;
2877 91736d37 blueswir1
            uint8_t *ptr;
2878 91736d37 blueswir1

2879 91736d37 blueswir1
            fprintf(logfile, "       code=");
2880 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
2881 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
2882 91736d37 blueswir1
                fprintf(logfile, " %02x", ldub(ptr + i));
2883 91736d37 blueswir1
            }
2884 91736d37 blueswir1
            fprintf(logfile, "\n");
2885 91736d37 blueswir1
        }
2886 91736d37 blueswir1
#endif
2887 91736d37 blueswir1
        count++;
2888 91736d37 blueswir1
    }
2889 91736d37 blueswir1
#endif
2890 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
2891 91736d37 blueswir1
    if (env->psret == 0) {
2892 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
2893 91736d37 blueswir1
                  env->exception_index);
2894 91736d37 blueswir1
        return;
2895 91736d37 blueswir1
    }
2896 91736d37 blueswir1
#endif
2897 91736d37 blueswir1
    env->psret = 0;
2898 91736d37 blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2899 91736d37 blueswir1
    cpu_set_cwp(env, cwp);
2900 91736d37 blueswir1
    env->regwptr[9] = env->pc;
2901 91736d37 blueswir1
    env->regwptr[10] = env->npc;
2902 91736d37 blueswir1
    env->psrps = env->psrs;
2903 91736d37 blueswir1
    env->psrs = 1;
2904 91736d37 blueswir1
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
2905 91736d37 blueswir1
    env->pc = env->tbr;
2906 91736d37 blueswir1
    env->npc = env->pc + 4;
2907 91736d37 blueswir1
    env->exception_index = 0;
2908 ee5bbe38 bellard
}
2909 91736d37 blueswir1
#endif
2910 ee5bbe38 bellard
2911 5fafdf24 ths
#if !defined(CONFIG_USER_ONLY)
2912 ee5bbe38 bellard
2913 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
2914 d2889a3e blueswir1
                                void *retaddr);
2915 d2889a3e blueswir1
2916 ee5bbe38 bellard
#define MMUSUFFIX _mmu
2917 d2889a3e blueswir1
#define ALIGNED_ONLY
2918 ee5bbe38 bellard
2919 ee5bbe38 bellard
#define SHIFT 0
2920 ee5bbe38 bellard
#include "softmmu_template.h"
2921 ee5bbe38 bellard
2922 ee5bbe38 bellard
#define SHIFT 1
2923 ee5bbe38 bellard
#include "softmmu_template.h"
2924 ee5bbe38 bellard
2925 ee5bbe38 bellard
#define SHIFT 2
2926 ee5bbe38 bellard
#include "softmmu_template.h"
2927 ee5bbe38 bellard
2928 ee5bbe38 bellard
#define SHIFT 3
2929 ee5bbe38 bellard
#include "softmmu_template.h"
2930 ee5bbe38 bellard
2931 c2bc0e38 blueswir1
/* XXX: make it generic ? */
2932 c2bc0e38 blueswir1
static void cpu_restore_state2(void *retaddr)
2933 c2bc0e38 blueswir1
{
2934 c2bc0e38 blueswir1
    TranslationBlock *tb;
2935 c2bc0e38 blueswir1
    unsigned long pc;
2936 c2bc0e38 blueswir1
2937 c2bc0e38 blueswir1
    if (retaddr) {
2938 c2bc0e38 blueswir1
        /* now we have a real cpu fault */
2939 c2bc0e38 blueswir1
        pc = (unsigned long)retaddr;
2940 c2bc0e38 blueswir1
        tb = tb_find_pc(pc);
2941 c2bc0e38 blueswir1
        if (tb) {
2942 c2bc0e38 blueswir1
            /* the PC is inside the translated code. It means that we have
2943 c2bc0e38 blueswir1
               a virtual CPU fault */
2944 c2bc0e38 blueswir1
            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
2945 c2bc0e38 blueswir1
        }
2946 c2bc0e38 blueswir1
    }
2947 c2bc0e38 blueswir1
}
2948 c2bc0e38 blueswir1
2949 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
2950 d2889a3e blueswir1
                                void *retaddr)
2951 d2889a3e blueswir1
{
2952 94554550 blueswir1
#ifdef DEBUG_UNALIGNED
2953 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
2954 c2bc0e38 blueswir1
           "\n", addr, env->pc);
2955 94554550 blueswir1
#endif
2956 c2bc0e38 blueswir1
    cpu_restore_state2(retaddr);
2957 94554550 blueswir1
    raise_exception(TT_UNALIGNED);
2958 d2889a3e blueswir1
}
2959 ee5bbe38 bellard
2960 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
2961 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
2962 ee5bbe38 bellard
   from generated code or from helper.c) */
2963 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
2964 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
2965 ee5bbe38 bellard
{
2966 ee5bbe38 bellard
    int ret;
2967 ee5bbe38 bellard
    CPUState *saved_env;
2968 ee5bbe38 bellard
2969 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
2970 ee5bbe38 bellard
       generated code */
2971 ee5bbe38 bellard
    saved_env = env;
2972 ee5bbe38 bellard
    env = cpu_single_env;
2973 ee5bbe38 bellard
2974 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
2975 ee5bbe38 bellard
    if (ret) {
2976 c2bc0e38 blueswir1
        cpu_restore_state2(retaddr);
2977 ee5bbe38 bellard
        cpu_loop_exit();
2978 ee5bbe38 bellard
    }
2979 ee5bbe38 bellard
    env = saved_env;
2980 ee5bbe38 bellard
}
2981 ee5bbe38 bellard
2982 ee5bbe38 bellard
#endif
2983 6c36d3fa blueswir1
2984 6c36d3fa blueswir1
#ifndef TARGET_SPARC64
2985 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
2986 6c36d3fa blueswir1
                          int is_asi)
2987 6c36d3fa blueswir1
{
2988 6c36d3fa blueswir1
    CPUState *saved_env;
2989 6c36d3fa blueswir1
2990 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
2991 6c36d3fa blueswir1
       generated code */
2992 6c36d3fa blueswir1
    saved_env = env;
2993 6c36d3fa blueswir1
    env = cpu_single_env;
2994 8543e2cf blueswir1
#ifdef DEBUG_UNASSIGNED
2995 8543e2cf blueswir1
    if (is_asi)
2996 77f193da blueswir1
        printf("Unassigned mem %s access to " TARGET_FMT_plx
2997 77f193da blueswir1
               " asi 0x%02x from " TARGET_FMT_lx "\n",
2998 8543e2cf blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", addr, is_asi,
2999 8543e2cf blueswir1
               env->pc);
3000 8543e2cf blueswir1
    else
3001 8543e2cf blueswir1
        printf("Unassigned mem %s access to " TARGET_FMT_plx " from "
3002 8543e2cf blueswir1
               TARGET_FMT_lx "\n",
3003 8543e2cf blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", addr, env->pc);
3004 8543e2cf blueswir1
#endif
3005 6c36d3fa blueswir1
    if (env->mmuregs[3]) /* Fault status register */
3006 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
3007 6c36d3fa blueswir1
    if (is_asi)
3008 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 16;
3009 6c36d3fa blueswir1
    if (env->psrs)
3010 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 5;
3011 6c36d3fa blueswir1
    if (is_exec)
3012 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 6;
3013 6c36d3fa blueswir1
    if (is_write)
3014 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 7;
3015 6c36d3fa blueswir1
    env->mmuregs[3] |= (5 << 2) | 2;
3016 6c36d3fa blueswir1
    env->mmuregs[4] = addr; /* Fault address register */
3017 6c36d3fa blueswir1
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
3018 1b2e93c1 blueswir1
        if (is_exec)
3019 1b2e93c1 blueswir1
            raise_exception(TT_CODE_ACCESS);
3020 1b2e93c1 blueswir1
        else
3021 1b2e93c1 blueswir1
            raise_exception(TT_DATA_ACCESS);
3022 6c36d3fa blueswir1
    }
3023 6c36d3fa blueswir1
    env = saved_env;
3024 6c36d3fa blueswir1
}
3025 6c36d3fa blueswir1
#else
3026 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3027 6c36d3fa blueswir1
                          int is_asi)
3028 6c36d3fa blueswir1
{
3029 6c36d3fa blueswir1
#ifdef DEBUG_UNASSIGNED
3030 6c36d3fa blueswir1
    CPUState *saved_env;
3031 6c36d3fa blueswir1
3032 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3033 6c36d3fa blueswir1
       generated code */
3034 6c36d3fa blueswir1
    saved_env = env;
3035 6c36d3fa blueswir1
    env = cpu_single_env;
3036 77f193da blueswir1
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
3037 77f193da blueswir1
           "\n", addr, env->pc);
3038 6c36d3fa blueswir1
    env = saved_env;
3039 6c36d3fa blueswir1
#endif
3040 1b2e93c1 blueswir1
    if (is_exec)
3041 1b2e93c1 blueswir1
        raise_exception(TT_CODE_ACCESS);
3042 1b2e93c1 blueswir1
    else
3043 1b2e93c1 blueswir1
        raise_exception(TT_DATA_ACCESS);
3044 6c36d3fa blueswir1
}
3045 6c36d3fa blueswir1
#endif