Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 38482a77

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

3145 93fcfe39 aliguori
            qemu_log("       code=");
3146 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3147 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3148 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3149 91736d37 blueswir1
            }
3150 93fcfe39 aliguori
            qemu_log("\n");
3151 91736d37 blueswir1
        }
3152 91736d37 blueswir1
#endif
3153 91736d37 blueswir1
        count++;
3154 91736d37 blueswir1
    }
3155 91736d37 blueswir1
#endif
3156 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3157 91736d37 blueswir1
    if (env->tl >= env->maxtl) {
3158 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
3159 91736d37 blueswir1
                  " Error state", env->exception_index, env->tl, env->maxtl);
3160 91736d37 blueswir1
        return;
3161 91736d37 blueswir1
    }
3162 91736d37 blueswir1
#endif
3163 91736d37 blueswir1
    if (env->tl < env->maxtl - 1) {
3164 91736d37 blueswir1
        env->tl++;
3165 91736d37 blueswir1
    } else {
3166 91736d37 blueswir1
        env->pstate |= PS_RED;
3167 91736d37 blueswir1
        if (env->tl < env->maxtl)
3168 91736d37 blueswir1
            env->tl++;
3169 91736d37 blueswir1
    }
3170 91736d37 blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
3171 91736d37 blueswir1
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
3172 91736d37 blueswir1
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
3173 91736d37 blueswir1
        GET_CWP64(env);
3174 91736d37 blueswir1
    env->tsptr->tpc = env->pc;
3175 91736d37 blueswir1
    env->tsptr->tnpc = env->npc;
3176 91736d37 blueswir1
    env->tsptr->tt = intno;
3177 91736d37 blueswir1
    if (!(env->def->features & CPU_FEATURE_GL)) {
3178 91736d37 blueswir1
        switch (intno) {
3179 91736d37 blueswir1
        case TT_IVEC:
3180 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
3181 91736d37 blueswir1
            break;
3182 91736d37 blueswir1
        case TT_TFAULT:
3183 91736d37 blueswir1
        case TT_TMISS:
3184 91736d37 blueswir1
        case TT_DFAULT:
3185 91736d37 blueswir1
        case TT_DMISS:
3186 91736d37 blueswir1
        case TT_DPROT:
3187 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
3188 91736d37 blueswir1
            break;
3189 91736d37 blueswir1
        default:
3190 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
3191 91736d37 blueswir1
            break;
3192 91736d37 blueswir1
        }
3193 91736d37 blueswir1
    }
3194 91736d37 blueswir1
    if (intno == TT_CLRWIN)
3195 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
3196 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_SPILL)
3197 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
3198 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_FILL)
3199 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
3200 91736d37 blueswir1
    env->tbr &= ~0x7fffULL;
3201 91736d37 blueswir1
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
3202 91736d37 blueswir1
    env->pc = env->tbr;
3203 91736d37 blueswir1
    env->npc = env->pc + 4;
3204 91736d37 blueswir1
    env->exception_index = 0;
3205 ee5bbe38 bellard
}
3206 91736d37 blueswir1
#else
3207 91736d37 blueswir1
#ifdef DEBUG_PCALL
3208 91736d37 blueswir1
static const char * const excp_names[0x80] = {
3209 91736d37 blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
3210 91736d37 blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
3211 91736d37 blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
3212 91736d37 blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
3213 91736d37 blueswir1
    [TT_WIN_OVF] = "Window Overflow",
3214 91736d37 blueswir1
    [TT_WIN_UNF] = "Window Underflow",
3215 91736d37 blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
3216 91736d37 blueswir1
    [TT_FP_EXCP] = "FPU Exception",
3217 91736d37 blueswir1
    [TT_DFAULT] = "Data Access Fault",
3218 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3219 91736d37 blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
3220 91736d37 blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
3221 91736d37 blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
3222 91736d37 blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
3223 91736d37 blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
3224 91736d37 blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
3225 91736d37 blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
3226 91736d37 blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
3227 91736d37 blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
3228 91736d37 blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
3229 91736d37 blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
3230 91736d37 blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
3231 91736d37 blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
3232 91736d37 blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
3233 91736d37 blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
3234 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3235 91736d37 blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
3236 91736d37 blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
3237 91736d37 blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
3238 91736d37 blueswir1
    [TT_NCP_INSN] = "Coprocessor Disabled",
3239 91736d37 blueswir1
};
3240 91736d37 blueswir1
#endif
3241 ee5bbe38 bellard
3242 91736d37 blueswir1
void do_interrupt(CPUState *env)
3243 ee5bbe38 bellard
{
3244 91736d37 blueswir1
    int cwp, intno = env->exception_index;
3245 91736d37 blueswir1
3246 91736d37 blueswir1
#ifdef DEBUG_PCALL
3247 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
3248 91736d37 blueswir1
        static int count;
3249 91736d37 blueswir1
        const char *name;
3250 91736d37 blueswir1
3251 91736d37 blueswir1
        if (intno < 0 || intno >= 0x100)
3252 91736d37 blueswir1
            name = "Unknown";
3253 91736d37 blueswir1
        else if (intno >= 0x80)
3254 91736d37 blueswir1
            name = "Trap Instruction";
3255 91736d37 blueswir1
        else {
3256 91736d37 blueswir1
            name = excp_names[intno];
3257 91736d37 blueswir1
            if (!name)
3258 91736d37 blueswir1
                name = "Unknown";
3259 91736d37 blueswir1
        }
3260 91736d37 blueswir1
3261 93fcfe39 aliguori
        qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
3262 91736d37 blueswir1
                count, name, intno,
3263 91736d37 blueswir1
                env->pc,
3264 91736d37 blueswir1
                env->npc, env->regwptr[6]);
3265 93fcfe39 aliguori
        log_cpu_state(env, 0);
3266 91736d37 blueswir1
#if 0
3267 91736d37 blueswir1
        {
3268 91736d37 blueswir1
            int i;
3269 91736d37 blueswir1
            uint8_t *ptr;
3270 91736d37 blueswir1

3271 93fcfe39 aliguori
            qemu_log("       code=");
3272 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3273 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3274 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3275 91736d37 blueswir1
            }
3276 93fcfe39 aliguori
            qemu_log("\n");
3277 91736d37 blueswir1
        }
3278 91736d37 blueswir1
#endif
3279 91736d37 blueswir1
        count++;
3280 91736d37 blueswir1
    }
3281 91736d37 blueswir1
#endif
3282 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3283 91736d37 blueswir1
    if (env->psret == 0) {
3284 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
3285 91736d37 blueswir1
                  env->exception_index);
3286 91736d37 blueswir1
        return;
3287 91736d37 blueswir1
    }
3288 91736d37 blueswir1
#endif
3289 91736d37 blueswir1
    env->psret = 0;
3290 91736d37 blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
3291 91736d37 blueswir1
    cpu_set_cwp(env, cwp);
3292 91736d37 blueswir1
    env->regwptr[9] = env->pc;
3293 91736d37 blueswir1
    env->regwptr[10] = env->npc;
3294 91736d37 blueswir1
    env->psrps = env->psrs;
3295 91736d37 blueswir1
    env->psrs = 1;
3296 91736d37 blueswir1
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
3297 91736d37 blueswir1
    env->pc = env->tbr;
3298 91736d37 blueswir1
    env->npc = env->pc + 4;
3299 91736d37 blueswir1
    env->exception_index = 0;
3300 ee5bbe38 bellard
}
3301 91736d37 blueswir1
#endif
3302 ee5bbe38 bellard
3303 5fafdf24 ths
#if !defined(CONFIG_USER_ONLY)
3304 ee5bbe38 bellard
3305 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3306 d2889a3e blueswir1
                                void *retaddr);
3307 d2889a3e blueswir1
3308 ee5bbe38 bellard
#define MMUSUFFIX _mmu
3309 d2889a3e blueswir1
#define ALIGNED_ONLY
3310 ee5bbe38 bellard
3311 ee5bbe38 bellard
#define SHIFT 0
3312 ee5bbe38 bellard
#include "softmmu_template.h"
3313 ee5bbe38 bellard
3314 ee5bbe38 bellard
#define SHIFT 1
3315 ee5bbe38 bellard
#include "softmmu_template.h"
3316 ee5bbe38 bellard
3317 ee5bbe38 bellard
#define SHIFT 2
3318 ee5bbe38 bellard
#include "softmmu_template.h"
3319 ee5bbe38 bellard
3320 ee5bbe38 bellard
#define SHIFT 3
3321 ee5bbe38 bellard
#include "softmmu_template.h"
3322 ee5bbe38 bellard
3323 c2bc0e38 blueswir1
/* XXX: make it generic ? */
3324 c2bc0e38 blueswir1
static void cpu_restore_state2(void *retaddr)
3325 c2bc0e38 blueswir1
{
3326 c2bc0e38 blueswir1
    TranslationBlock *tb;
3327 c2bc0e38 blueswir1
    unsigned long pc;
3328 c2bc0e38 blueswir1
3329 c2bc0e38 blueswir1
    if (retaddr) {
3330 c2bc0e38 blueswir1
        /* now we have a real cpu fault */
3331 c2bc0e38 blueswir1
        pc = (unsigned long)retaddr;
3332 c2bc0e38 blueswir1
        tb = tb_find_pc(pc);
3333 c2bc0e38 blueswir1
        if (tb) {
3334 c2bc0e38 blueswir1
            /* the PC is inside the translated code. It means that we have
3335 c2bc0e38 blueswir1
               a virtual CPU fault */
3336 c2bc0e38 blueswir1
            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
3337 c2bc0e38 blueswir1
        }
3338 c2bc0e38 blueswir1
    }
3339 c2bc0e38 blueswir1
}
3340 c2bc0e38 blueswir1
3341 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3342 d2889a3e blueswir1
                                void *retaddr)
3343 d2889a3e blueswir1
{
3344 94554550 blueswir1
#ifdef DEBUG_UNALIGNED
3345 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
3346 c2bc0e38 blueswir1
           "\n", addr, env->pc);
3347 94554550 blueswir1
#endif
3348 c2bc0e38 blueswir1
    cpu_restore_state2(retaddr);
3349 94554550 blueswir1
    raise_exception(TT_UNALIGNED);
3350 d2889a3e blueswir1
}
3351 ee5bbe38 bellard
3352 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
3353 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
3354 ee5bbe38 bellard
   from generated code or from helper.c) */
3355 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
3356 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
3357 ee5bbe38 bellard
{
3358 ee5bbe38 bellard
    int ret;
3359 ee5bbe38 bellard
    CPUState *saved_env;
3360 ee5bbe38 bellard
3361 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
3362 ee5bbe38 bellard
       generated code */
3363 ee5bbe38 bellard
    saved_env = env;
3364 ee5bbe38 bellard
    env = cpu_single_env;
3365 ee5bbe38 bellard
3366 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
3367 ee5bbe38 bellard
    if (ret) {
3368 c2bc0e38 blueswir1
        cpu_restore_state2(retaddr);
3369 ee5bbe38 bellard
        cpu_loop_exit();
3370 ee5bbe38 bellard
    }
3371 ee5bbe38 bellard
    env = saved_env;
3372 ee5bbe38 bellard
}
3373 ee5bbe38 bellard
3374 ee5bbe38 bellard
#endif
3375 6c36d3fa blueswir1
3376 6c36d3fa blueswir1
#ifndef TARGET_SPARC64
3377 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3378 e18231a3 blueswir1
                          int is_asi, int size)
3379 6c36d3fa blueswir1
{
3380 6c36d3fa blueswir1
    CPUState *saved_env;
3381 6c36d3fa blueswir1
3382 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3383 6c36d3fa blueswir1
       generated code */
3384 6c36d3fa blueswir1
    saved_env = env;
3385 6c36d3fa blueswir1
    env = cpu_single_env;
3386 8543e2cf blueswir1
#ifdef DEBUG_UNASSIGNED
3387 8543e2cf blueswir1
    if (is_asi)
3388 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3389 77f193da blueswir1
               " asi 0x%02x from " TARGET_FMT_lx "\n",
3390 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3391 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, is_asi, env->pc);
3392 8543e2cf blueswir1
    else
3393 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3394 e18231a3 blueswir1
               " from " TARGET_FMT_lx "\n",
3395 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3396 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, env->pc);
3397 8543e2cf blueswir1
#endif
3398 6c36d3fa blueswir1
    if (env->mmuregs[3]) /* Fault status register */
3399 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
3400 6c36d3fa blueswir1
    if (is_asi)
3401 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 16;
3402 6c36d3fa blueswir1
    if (env->psrs)
3403 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 5;
3404 6c36d3fa blueswir1
    if (is_exec)
3405 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 6;
3406 6c36d3fa blueswir1
    if (is_write)
3407 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 7;
3408 6c36d3fa blueswir1
    env->mmuregs[3] |= (5 << 2) | 2;
3409 6c36d3fa blueswir1
    env->mmuregs[4] = addr; /* Fault address register */
3410 6c36d3fa blueswir1
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
3411 1b2e93c1 blueswir1
        if (is_exec)
3412 1b2e93c1 blueswir1
            raise_exception(TT_CODE_ACCESS);
3413 1b2e93c1 blueswir1
        else
3414 1b2e93c1 blueswir1
            raise_exception(TT_DATA_ACCESS);
3415 6c36d3fa blueswir1
    }
3416 6c36d3fa blueswir1
    env = saved_env;
3417 6c36d3fa blueswir1
}
3418 6c36d3fa blueswir1
#else
3419 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3420 e18231a3 blueswir1
                          int is_asi, int size)
3421 6c36d3fa blueswir1
{
3422 6c36d3fa blueswir1
#ifdef DEBUG_UNASSIGNED
3423 6c36d3fa blueswir1
    CPUState *saved_env;
3424 6c36d3fa blueswir1
3425 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3426 6c36d3fa blueswir1
       generated code */
3427 6c36d3fa blueswir1
    saved_env = env;
3428 6c36d3fa blueswir1
    env = cpu_single_env;
3429 77f193da blueswir1
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
3430 77f193da blueswir1
           "\n", addr, env->pc);
3431 6c36d3fa blueswir1
    env = saved_env;
3432 6c36d3fa blueswir1
#endif
3433 1b2e93c1 blueswir1
    if (is_exec)
3434 1b2e93c1 blueswir1
        raise_exception(TT_CODE_ACCESS);
3435 1b2e93c1 blueswir1
    else
3436 1b2e93c1 blueswir1
        raise_exception(TT_DATA_ACCESS);
3437 6c36d3fa blueswir1
}
3438 6c36d3fa blueswir1
#endif
3439 20c9f095 blueswir1
3440 f4b1a842 blueswir1
#ifdef TARGET_SPARC64
3441 f4b1a842 blueswir1
void helper_tick_set_count(void *opaque, uint64_t count)
3442 f4b1a842 blueswir1
{
3443 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3444 f4b1a842 blueswir1
    cpu_tick_set_count(opaque, count);
3445 f4b1a842 blueswir1
#endif
3446 f4b1a842 blueswir1
}
3447 f4b1a842 blueswir1
3448 f4b1a842 blueswir1
uint64_t helper_tick_get_count(void *opaque)
3449 f4b1a842 blueswir1
{
3450 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3451 f4b1a842 blueswir1
    return cpu_tick_get_count(opaque);
3452 f4b1a842 blueswir1
#else
3453 f4b1a842 blueswir1
    return 0;
3454 f4b1a842 blueswir1
#endif
3455 f4b1a842 blueswir1
}
3456 f4b1a842 blueswir1
3457 f4b1a842 blueswir1
void helper_tick_set_limit(void *opaque, uint64_t limit)
3458 f4b1a842 blueswir1
{
3459 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3460 f4b1a842 blueswir1
    cpu_tick_set_limit(opaque, limit);
3461 f4b1a842 blueswir1
#endif
3462 f4b1a842 blueswir1
}
3463 f4b1a842 blueswir1
#endif