Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 7ab463cb

History | View | Annotate | Download (91.2 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 3475187d bellard
#ifdef TARGET_SPARC64
750 714547bb blueswir1
GEN_FCMPS(fcmps_fcc1, float32, 22, 0);
751 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
752 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
753 417454b0 blueswir1
754 714547bb blueswir1
GEN_FCMPS(fcmps_fcc2, float32, 24, 0);
755 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
756 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
757 417454b0 blueswir1
758 714547bb blueswir1
GEN_FCMPS(fcmps_fcc3, float32, 26, 0);
759 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
760 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
761 417454b0 blueswir1
762 714547bb blueswir1
GEN_FCMPS(fcmpes_fcc1, float32, 22, 1);
763 417454b0 blueswir1
GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
764 64a88d5d blueswir1
GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
765 3475187d bellard
766 714547bb blueswir1
GEN_FCMPS(fcmpes_fcc2, float32, 24, 1);
767 417454b0 blueswir1
GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
768 64a88d5d blueswir1
GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
769 3475187d bellard
770 714547bb blueswir1
GEN_FCMPS(fcmpes_fcc3, float32, 26, 1);
771 417454b0 blueswir1
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
772 4e14008f blueswir1
GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
773 4e14008f blueswir1
#endif
774 714547bb blueswir1
#undef GEN_FCMPS
775 3475187d bellard
776 77f193da blueswir1
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \
777 77f193da blueswir1
    defined(DEBUG_MXCC)
778 952a328f blueswir1
static void dump_mxcc(CPUState *env)
779 952a328f blueswir1
{
780 952a328f blueswir1
    printf("mxccdata: %016llx %016llx %016llx %016llx\n",
781 77f193da blueswir1
           env->mxccdata[0], env->mxccdata[1],
782 77f193da blueswir1
           env->mxccdata[2], env->mxccdata[3]);
783 952a328f blueswir1
    printf("mxccregs: %016llx %016llx %016llx %016llx\n"
784 952a328f blueswir1
           "          %016llx %016llx %016llx %016llx\n",
785 77f193da blueswir1
           env->mxccregs[0], env->mxccregs[1],
786 77f193da blueswir1
           env->mxccregs[2], env->mxccregs[3],
787 77f193da blueswir1
           env->mxccregs[4], env->mxccregs[5],
788 77f193da blueswir1
           env->mxccregs[6], env->mxccregs[7]);
789 952a328f blueswir1
}
790 952a328f blueswir1
#endif
791 952a328f blueswir1
792 1a2fb1c0 blueswir1
#if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)) \
793 1a2fb1c0 blueswir1
    && defined(DEBUG_ASI)
794 1a2fb1c0 blueswir1
static void dump_asi(const char *txt, target_ulong addr, int asi, int size,
795 1a2fb1c0 blueswir1
                     uint64_t r1)
796 8543e2cf blueswir1
{
797 8543e2cf blueswir1
    switch (size)
798 8543e2cf blueswir1
    {
799 8543e2cf blueswir1
    case 1:
800 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt,
801 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xff);
802 8543e2cf blueswir1
        break;
803 8543e2cf blueswir1
    case 2:
804 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt,
805 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xffff);
806 8543e2cf blueswir1
        break;
807 8543e2cf blueswir1
    case 4:
808 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt,
809 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xffffffff);
810 8543e2cf blueswir1
        break;
811 8543e2cf blueswir1
    case 8:
812 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt,
813 1a2fb1c0 blueswir1
                    addr, asi, r1);
814 8543e2cf blueswir1
        break;
815 8543e2cf blueswir1
    }
816 8543e2cf blueswir1
}
817 8543e2cf blueswir1
#endif
818 8543e2cf blueswir1
819 1a2fb1c0 blueswir1
#ifndef TARGET_SPARC64
820 1a2fb1c0 blueswir1
#ifndef CONFIG_USER_ONLY
821 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
822 e8af50a3 bellard
{
823 1a2fb1c0 blueswir1
    uint64_t ret = 0;
824 8543e2cf blueswir1
#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
825 1a2fb1c0 blueswir1
    uint32_t last_addr = addr;
826 952a328f blueswir1
#endif
827 e80cfcfc bellard
828 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
829 e80cfcfc bellard
    switch (asi) {
830 6c36d3fa blueswir1
    case 2: /* SuperSparc MXCC registers */
831 1a2fb1c0 blueswir1
        switch (addr) {
832 952a328f blueswir1
        case 0x01c00a00: /* MXCC control register */
833 1a2fb1c0 blueswir1
            if (size == 8)
834 1a2fb1c0 blueswir1
                ret = env->mxccregs[3];
835 1a2fb1c0 blueswir1
            else
836 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
837 77f193da blueswir1
                             size);
838 952a328f blueswir1
            break;
839 952a328f blueswir1
        case 0x01c00a04: /* MXCC control register */
840 952a328f blueswir1
            if (size == 4)
841 952a328f blueswir1
                ret = env->mxccregs[3];
842 952a328f blueswir1
            else
843 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
844 77f193da blueswir1
                             size);
845 952a328f blueswir1
            break;
846 295db113 blueswir1
        case 0x01c00c00: /* Module reset register */
847 295db113 blueswir1
            if (size == 8) {
848 1a2fb1c0 blueswir1
                ret = env->mxccregs[5];
849 295db113 blueswir1
                // should we do something here?
850 295db113 blueswir1
            } else
851 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
852 77f193da blueswir1
                             size);
853 295db113 blueswir1
            break;
854 952a328f blueswir1
        case 0x01c00f00: /* MBus port address register */
855 1a2fb1c0 blueswir1
            if (size == 8)
856 1a2fb1c0 blueswir1
                ret = env->mxccregs[7];
857 1a2fb1c0 blueswir1
            else
858 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
859 77f193da blueswir1
                             size);
860 952a328f blueswir1
            break;
861 952a328f blueswir1
        default:
862 77f193da blueswir1
            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
863 77f193da blueswir1
                         size);
864 952a328f blueswir1
            break;
865 952a328f blueswir1
        }
866 77f193da blueswir1
        DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
867 9827e450 blueswir1
                     "addr = %08x -> ret = %" PRIx64 ","
868 1a2fb1c0 blueswir1
                     "addr = %08x\n", asi, size, sign, last_addr, ret, addr);
869 952a328f blueswir1
#ifdef DEBUG_MXCC
870 952a328f blueswir1
        dump_mxcc(env);
871 952a328f blueswir1
#endif
872 6c36d3fa blueswir1
        break;
873 e8af50a3 bellard
    case 3: /* MMU probe */
874 0f8a249a blueswir1
        {
875 0f8a249a blueswir1
            int mmulev;
876 0f8a249a blueswir1
877 1a2fb1c0 blueswir1
            mmulev = (addr >> 8) & 15;
878 0f8a249a blueswir1
            if (mmulev > 4)
879 0f8a249a blueswir1
                ret = 0;
880 1a2fb1c0 blueswir1
            else
881 1a2fb1c0 blueswir1
                ret = mmu_probe(env, addr, mmulev);
882 1a2fb1c0 blueswir1
            DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n",
883 1a2fb1c0 blueswir1
                        addr, mmulev, ret);
884 0f8a249a blueswir1
        }
885 0f8a249a blueswir1
        break;
886 e8af50a3 bellard
    case 4: /* read MMU regs */
887 0f8a249a blueswir1
        {
888 1a2fb1c0 blueswir1
            int reg = (addr >> 8) & 0x1f;
889 3b46e624 ths
890 0f8a249a blueswir1
            ret = env->mmuregs[reg];
891 0f8a249a blueswir1
            if (reg == 3) /* Fault status cleared on read */
892 3dd9a152 blueswir1
                env->mmuregs[3] = 0;
893 3dd9a152 blueswir1
            else if (reg == 0x13) /* Fault status read */
894 3dd9a152 blueswir1
                ret = env->mmuregs[3];
895 3dd9a152 blueswir1
            else if (reg == 0x14) /* Fault address read */
896 3dd9a152 blueswir1
                ret = env->mmuregs[4];
897 1a2fb1c0 blueswir1
            DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
898 0f8a249a blueswir1
        }
899 0f8a249a blueswir1
        break;
900 045380be blueswir1
    case 5: // Turbosparc ITLB Diagnostic
901 045380be blueswir1
    case 6: // Turbosparc DTLB Diagnostic
902 045380be blueswir1
    case 7: // Turbosparc IOTLB Diagnostic
903 045380be blueswir1
        break;
904 6c36d3fa blueswir1
    case 9: /* Supervisor code access */
905 6c36d3fa blueswir1
        switch(size) {
906 6c36d3fa blueswir1
        case 1:
907 1a2fb1c0 blueswir1
            ret = ldub_code(addr);
908 6c36d3fa blueswir1
            break;
909 6c36d3fa blueswir1
        case 2:
910 a4e7dd52 blueswir1
            ret = lduw_code(addr);
911 6c36d3fa blueswir1
            break;
912 6c36d3fa blueswir1
        default:
913 6c36d3fa blueswir1
        case 4:
914 a4e7dd52 blueswir1
            ret = ldl_code(addr);
915 6c36d3fa blueswir1
            break;
916 6c36d3fa blueswir1
        case 8:
917 a4e7dd52 blueswir1
            ret = ldq_code(addr);
918 6c36d3fa blueswir1
            break;
919 6c36d3fa blueswir1
        }
920 6c36d3fa blueswir1
        break;
921 81ad8ba2 blueswir1
    case 0xa: /* User data access */
922 81ad8ba2 blueswir1
        switch(size) {
923 81ad8ba2 blueswir1
        case 1:
924 1a2fb1c0 blueswir1
            ret = ldub_user(addr);
925 81ad8ba2 blueswir1
            break;
926 81ad8ba2 blueswir1
        case 2:
927 a4e7dd52 blueswir1
            ret = lduw_user(addr);
928 81ad8ba2 blueswir1
            break;
929 81ad8ba2 blueswir1
        default:
930 81ad8ba2 blueswir1
        case 4:
931 a4e7dd52 blueswir1
            ret = ldl_user(addr);
932 81ad8ba2 blueswir1
            break;
933 81ad8ba2 blueswir1
        case 8:
934 a4e7dd52 blueswir1
            ret = ldq_user(addr);
935 81ad8ba2 blueswir1
            break;
936 81ad8ba2 blueswir1
        }
937 81ad8ba2 blueswir1
        break;
938 81ad8ba2 blueswir1
    case 0xb: /* Supervisor data access */
939 81ad8ba2 blueswir1
        switch(size) {
940 81ad8ba2 blueswir1
        case 1:
941 1a2fb1c0 blueswir1
            ret = ldub_kernel(addr);
942 81ad8ba2 blueswir1
            break;
943 81ad8ba2 blueswir1
        case 2:
944 a4e7dd52 blueswir1
            ret = lduw_kernel(addr);
945 81ad8ba2 blueswir1
            break;
946 81ad8ba2 blueswir1
        default:
947 81ad8ba2 blueswir1
        case 4:
948 a4e7dd52 blueswir1
            ret = ldl_kernel(addr);
949 81ad8ba2 blueswir1
            break;
950 81ad8ba2 blueswir1
        case 8:
951 a4e7dd52 blueswir1
            ret = ldq_kernel(addr);
952 81ad8ba2 blueswir1
            break;
953 81ad8ba2 blueswir1
        }
954 81ad8ba2 blueswir1
        break;
955 6c36d3fa blueswir1
    case 0xc: /* I-cache tag */
956 6c36d3fa blueswir1
    case 0xd: /* I-cache data */
957 6c36d3fa blueswir1
    case 0xe: /* D-cache tag */
958 6c36d3fa blueswir1
    case 0xf: /* D-cache data */
959 6c36d3fa blueswir1
        break;
960 6c36d3fa blueswir1
    case 0x20: /* MMU passthrough */
961 02aab46a bellard
        switch(size) {
962 02aab46a bellard
        case 1:
963 1a2fb1c0 blueswir1
            ret = ldub_phys(addr);
964 02aab46a bellard
            break;
965 02aab46a bellard
        case 2:
966 a4e7dd52 blueswir1
            ret = lduw_phys(addr);
967 02aab46a bellard
            break;
968 02aab46a bellard
        default:
969 02aab46a bellard
        case 4:
970 a4e7dd52 blueswir1
            ret = ldl_phys(addr);
971 02aab46a bellard
            break;
972 9e61bde5 bellard
        case 8:
973 a4e7dd52 blueswir1
            ret = ldq_phys(addr);
974 0f8a249a blueswir1
            break;
975 02aab46a bellard
        }
976 0f8a249a blueswir1
        break;
977 7d85892b blueswir1
    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
978 5dcb6b91 blueswir1
        switch(size) {
979 5dcb6b91 blueswir1
        case 1:
980 1a2fb1c0 blueswir1
            ret = ldub_phys((target_phys_addr_t)addr
981 5dcb6b91 blueswir1
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
982 5dcb6b91 blueswir1
            break;
983 5dcb6b91 blueswir1
        case 2:
984 a4e7dd52 blueswir1
            ret = lduw_phys((target_phys_addr_t)addr
985 5dcb6b91 blueswir1
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
986 5dcb6b91 blueswir1
            break;
987 5dcb6b91 blueswir1
        default:
988 5dcb6b91 blueswir1
        case 4:
989 a4e7dd52 blueswir1
            ret = ldl_phys((target_phys_addr_t)addr
990 5dcb6b91 blueswir1
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
991 5dcb6b91 blueswir1
            break;
992 5dcb6b91 blueswir1
        case 8:
993 a4e7dd52 blueswir1
            ret = ldq_phys((target_phys_addr_t)addr
994 5dcb6b91 blueswir1
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
995 0f8a249a blueswir1
            break;
996 5dcb6b91 blueswir1
        }
997 0f8a249a blueswir1
        break;
998 045380be blueswir1
    case 0x30: // Turbosparc secondary cache diagnostic
999 045380be blueswir1
    case 0x31: // Turbosparc RAM snoop
1000 045380be blueswir1
    case 0x32: // Turbosparc page table descriptor diagnostic
1001 666c87aa blueswir1
    case 0x39: /* data cache diagnostic register */
1002 666c87aa blueswir1
        ret = 0;
1003 666c87aa blueswir1
        break;
1004 4017190e blueswir1
    case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
1005 4017190e blueswir1
        {
1006 4017190e blueswir1
            int reg = (addr >> 8) & 3;
1007 4017190e blueswir1
1008 4017190e blueswir1
            switch(reg) {
1009 4017190e blueswir1
            case 0: /* Breakpoint Value (Addr) */
1010 4017190e blueswir1
                ret = env->mmubpregs[reg];
1011 4017190e blueswir1
                break;
1012 4017190e blueswir1
            case 1: /* Breakpoint Mask */
1013 4017190e blueswir1
                ret = env->mmubpregs[reg];
1014 4017190e blueswir1
                break;
1015 4017190e blueswir1
            case 2: /* Breakpoint Control */
1016 4017190e blueswir1
                ret = env->mmubpregs[reg];
1017 4017190e blueswir1
                break;
1018 4017190e blueswir1
            case 3: /* Breakpoint Status */
1019 4017190e blueswir1
                ret = env->mmubpregs[reg];
1020 4017190e blueswir1
                env->mmubpregs[reg] = 0ULL;
1021 4017190e blueswir1
                break;
1022 4017190e blueswir1
            }
1023 4017190e blueswir1
            DPRINTF_MMU("read breakpoint reg[%d] 0x%016llx\n", reg, ret);
1024 4017190e blueswir1
        }
1025 4017190e blueswir1
        break;
1026 045380be blueswir1
    case 8: /* User code access, XXX */
1027 e8af50a3 bellard
    default:
1028 e18231a3 blueswir1
        do_unassigned_access(addr, 0, 0, asi, size);
1029 0f8a249a blueswir1
        ret = 0;
1030 0f8a249a blueswir1
        break;
1031 e8af50a3 bellard
    }
1032 81ad8ba2 blueswir1
    if (sign) {
1033 81ad8ba2 blueswir1
        switch(size) {
1034 81ad8ba2 blueswir1
        case 1:
1035 1a2fb1c0 blueswir1
            ret = (int8_t) ret;
1036 e32664fb blueswir1
            break;
1037 81ad8ba2 blueswir1
        case 2:
1038 1a2fb1c0 blueswir1
            ret = (int16_t) ret;
1039 1a2fb1c0 blueswir1
            break;
1040 1a2fb1c0 blueswir1
        case 4:
1041 1a2fb1c0 blueswir1
            ret = (int32_t) ret;
1042 e32664fb blueswir1
            break;
1043 81ad8ba2 blueswir1
        default:
1044 81ad8ba2 blueswir1
            break;
1045 81ad8ba2 blueswir1
        }
1046 81ad8ba2 blueswir1
    }
1047 8543e2cf blueswir1
#ifdef DEBUG_ASI
1048 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
1049 8543e2cf blueswir1
#endif
1050 1a2fb1c0 blueswir1
    return ret;
1051 e8af50a3 bellard
}
1052 e8af50a3 bellard
1053 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
1054 e8af50a3 bellard
{
1055 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1056 e8af50a3 bellard
    switch(asi) {
1057 6c36d3fa blueswir1
    case 2: /* SuperSparc MXCC registers */
1058 1a2fb1c0 blueswir1
        switch (addr) {
1059 952a328f blueswir1
        case 0x01c00000: /* MXCC stream data register 0 */
1060 952a328f blueswir1
            if (size == 8)
1061 1a2fb1c0 blueswir1
                env->mxccdata[0] = val;
1062 952a328f blueswir1
            else
1063 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1064 77f193da blueswir1
                             size);
1065 952a328f blueswir1
            break;
1066 952a328f blueswir1
        case 0x01c00008: /* MXCC stream data register 1 */
1067 952a328f blueswir1
            if (size == 8)
1068 1a2fb1c0 blueswir1
                env->mxccdata[1] = val;
1069 952a328f blueswir1
            else
1070 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1071 77f193da blueswir1
                             size);
1072 952a328f blueswir1
            break;
1073 952a328f blueswir1
        case 0x01c00010: /* MXCC stream data register 2 */
1074 952a328f blueswir1
            if (size == 8)
1075 1a2fb1c0 blueswir1
                env->mxccdata[2] = val;
1076 952a328f blueswir1
            else
1077 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1078 77f193da blueswir1
                             size);
1079 952a328f blueswir1
            break;
1080 952a328f blueswir1
        case 0x01c00018: /* MXCC stream data register 3 */
1081 952a328f blueswir1
            if (size == 8)
1082 1a2fb1c0 blueswir1
                env->mxccdata[3] = val;
1083 952a328f blueswir1
            else
1084 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1085 77f193da blueswir1
                             size);
1086 952a328f blueswir1
            break;
1087 952a328f blueswir1
        case 0x01c00100: /* MXCC stream source */
1088 952a328f blueswir1
            if (size == 8)
1089 1a2fb1c0 blueswir1
                env->mxccregs[0] = val;
1090 952a328f blueswir1
            else
1091 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1092 77f193da blueswir1
                             size);
1093 77f193da blueswir1
            env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1094 77f193da blueswir1
                                        0);
1095 77f193da blueswir1
            env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1096 77f193da blueswir1
                                        8);
1097 77f193da blueswir1
            env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1098 77f193da blueswir1
                                        16);
1099 77f193da blueswir1
            env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1100 77f193da blueswir1
                                        24);
1101 952a328f blueswir1
            break;
1102 952a328f blueswir1
        case 0x01c00200: /* MXCC stream destination */
1103 952a328f blueswir1
            if (size == 8)
1104 1a2fb1c0 blueswir1
                env->mxccregs[1] = val;
1105 952a328f blueswir1
            else
1106 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1107 77f193da blueswir1
                             size);
1108 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0,
1109 77f193da blueswir1
                     env->mxccdata[0]);
1110 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8,
1111 77f193da blueswir1
                     env->mxccdata[1]);
1112 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16,
1113 77f193da blueswir1
                     env->mxccdata[2]);
1114 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24,
1115 77f193da blueswir1
                     env->mxccdata[3]);
1116 952a328f blueswir1
            break;
1117 952a328f blueswir1
        case 0x01c00a00: /* MXCC control register */
1118 952a328f blueswir1
            if (size == 8)
1119 1a2fb1c0 blueswir1
                env->mxccregs[3] = val;
1120 952a328f blueswir1
            else
1121 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1122 77f193da blueswir1
                             size);
1123 952a328f blueswir1
            break;
1124 952a328f blueswir1
        case 0x01c00a04: /* MXCC control register */
1125 952a328f blueswir1
            if (size == 4)
1126 9f4576f0 blueswir1
                env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL)
1127 77f193da blueswir1
                    | val;
1128 952a328f blueswir1
            else
1129 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1130 77f193da blueswir1
                             size);
1131 952a328f blueswir1
            break;
1132 952a328f blueswir1
        case 0x01c00e00: /* MXCC error register  */
1133 bbf7d96b blueswir1
            // writing a 1 bit clears the error
1134 952a328f blueswir1
            if (size == 8)
1135 1a2fb1c0 blueswir1
                env->mxccregs[6] &= ~val;
1136 952a328f blueswir1
            else
1137 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1138 77f193da blueswir1
                             size);
1139 952a328f blueswir1
            break;
1140 952a328f blueswir1
        case 0x01c00f00: /* MBus port address register */
1141 952a328f blueswir1
            if (size == 8)
1142 1a2fb1c0 blueswir1
                env->mxccregs[7] = val;
1143 952a328f blueswir1
            else
1144 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1145 77f193da blueswir1
                             size);
1146 952a328f blueswir1
            break;
1147 952a328f blueswir1
        default:
1148 77f193da blueswir1
            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
1149 77f193da blueswir1
                         size);
1150 952a328f blueswir1
            break;
1151 952a328f blueswir1
        }
1152 9827e450 blueswir1
        DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
1153 9827e450 blueswir1
                     asi, size, addr, val);
1154 952a328f blueswir1
#ifdef DEBUG_MXCC
1155 952a328f blueswir1
        dump_mxcc(env);
1156 952a328f blueswir1
#endif
1157 6c36d3fa blueswir1
        break;
1158 e8af50a3 bellard
    case 3: /* MMU flush */
1159 0f8a249a blueswir1
        {
1160 0f8a249a blueswir1
            int mmulev;
1161 e80cfcfc bellard
1162 1a2fb1c0 blueswir1
            mmulev = (addr >> 8) & 15;
1163 952a328f blueswir1
            DPRINTF_MMU("mmu flush level %d\n", mmulev);
1164 0f8a249a blueswir1
            switch (mmulev) {
1165 0f8a249a blueswir1
            case 0: // flush page
1166 1a2fb1c0 blueswir1
                tlb_flush_page(env, addr & 0xfffff000);
1167 0f8a249a blueswir1
                break;
1168 0f8a249a blueswir1
            case 1: // flush segment (256k)
1169 0f8a249a blueswir1
            case 2: // flush region (16M)
1170 0f8a249a blueswir1
            case 3: // flush context (4G)
1171 0f8a249a blueswir1
            case 4: // flush entire
1172 0f8a249a blueswir1
                tlb_flush(env, 1);
1173 0f8a249a blueswir1
                break;
1174 0f8a249a blueswir1
            default:
1175 0f8a249a blueswir1
                break;
1176 0f8a249a blueswir1
            }
1177 55754d9e bellard
#ifdef DEBUG_MMU
1178 0f8a249a blueswir1
            dump_mmu(env);
1179 55754d9e bellard
#endif
1180 0f8a249a blueswir1
        }
1181 8543e2cf blueswir1
        break;
1182 e8af50a3 bellard
    case 4: /* write MMU regs */
1183 0f8a249a blueswir1
        {
1184 1a2fb1c0 blueswir1
            int reg = (addr >> 8) & 0x1f;
1185 0f8a249a blueswir1
            uint32_t oldreg;
1186 3b46e624 ths
1187 0f8a249a blueswir1
            oldreg = env->mmuregs[reg];
1188 55754d9e bellard
            switch(reg) {
1189 3deaeab7 blueswir1
            case 0: // Control Register
1190 3dd9a152 blueswir1
                env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
1191 1a2fb1c0 blueswir1
                                    (val & 0x00ffffff);
1192 0f8a249a blueswir1
                // Mappings generated during no-fault mode or MMU
1193 0f8a249a blueswir1
                // disabled mode are invalid in normal mode
1194 5578ceab blueswir1
                if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
1195 5578ceab blueswir1
                    (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm)))
1196 55754d9e bellard
                    tlb_flush(env, 1);
1197 55754d9e bellard
                break;
1198 3deaeab7 blueswir1
            case 1: // Context Table Pointer Register
1199 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_ctpr_mask;
1200 3deaeab7 blueswir1
                break;
1201 3deaeab7 blueswir1
            case 2: // Context Register
1202 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_cxr_mask;
1203 55754d9e bellard
                if (oldreg != env->mmuregs[reg]) {
1204 55754d9e bellard
                    /* we flush when the MMU context changes because
1205 55754d9e bellard
                       QEMU has no MMU context support */
1206 55754d9e bellard
                    tlb_flush(env, 1);
1207 55754d9e bellard
                }
1208 55754d9e bellard
                break;
1209 3deaeab7 blueswir1
            case 3: // Synchronous Fault Status Register with Clear
1210 3deaeab7 blueswir1
            case 4: // Synchronous Fault Address Register
1211 3deaeab7 blueswir1
                break;
1212 3deaeab7 blueswir1
            case 0x10: // TLB Replacement Control Register
1213 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_trcr_mask;
1214 55754d9e bellard
                break;
1215 3deaeab7 blueswir1
            case 0x13: // Synchronous Fault Status Register with Read and Clear
1216 5578ceab blueswir1
                env->mmuregs[3] = val & env->def->mmu_sfsr_mask;
1217 3dd9a152 blueswir1
                break;
1218 3deaeab7 blueswir1
            case 0x14: // Synchronous Fault Address Register
1219 1a2fb1c0 blueswir1
                env->mmuregs[4] = val;
1220 3dd9a152 blueswir1
                break;
1221 55754d9e bellard
            default:
1222 1a2fb1c0 blueswir1
                env->mmuregs[reg] = val;
1223 55754d9e bellard
                break;
1224 55754d9e bellard
            }
1225 55754d9e bellard
            if (oldreg != env->mmuregs[reg]) {
1226 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
1227 77f193da blueswir1
                            reg, oldreg, env->mmuregs[reg]);
1228 55754d9e bellard
            }
1229 952a328f blueswir1
#ifdef DEBUG_MMU
1230 0f8a249a blueswir1
            dump_mmu(env);
1231 55754d9e bellard
#endif
1232 0f8a249a blueswir1
        }
1233 8543e2cf blueswir1
        break;
1234 045380be blueswir1
    case 5: // Turbosparc ITLB Diagnostic
1235 045380be blueswir1
    case 6: // Turbosparc DTLB Diagnostic
1236 045380be blueswir1
    case 7: // Turbosparc IOTLB Diagnostic
1237 045380be blueswir1
        break;
1238 81ad8ba2 blueswir1
    case 0xa: /* User data access */
1239 81ad8ba2 blueswir1
        switch(size) {
1240 81ad8ba2 blueswir1
        case 1:
1241 1a2fb1c0 blueswir1
            stb_user(addr, val);
1242 81ad8ba2 blueswir1
            break;
1243 81ad8ba2 blueswir1
        case 2:
1244 a4e7dd52 blueswir1
            stw_user(addr, val);
1245 81ad8ba2 blueswir1
            break;
1246 81ad8ba2 blueswir1
        default:
1247 81ad8ba2 blueswir1
        case 4:
1248 a4e7dd52 blueswir1
            stl_user(addr, val);
1249 81ad8ba2 blueswir1
            break;
1250 81ad8ba2 blueswir1
        case 8:
1251 a4e7dd52 blueswir1
            stq_user(addr, val);
1252 81ad8ba2 blueswir1
            break;
1253 81ad8ba2 blueswir1
        }
1254 81ad8ba2 blueswir1
        break;
1255 81ad8ba2 blueswir1
    case 0xb: /* Supervisor data access */
1256 81ad8ba2 blueswir1
        switch(size) {
1257 81ad8ba2 blueswir1
        case 1:
1258 1a2fb1c0 blueswir1
            stb_kernel(addr, val);
1259 81ad8ba2 blueswir1
            break;
1260 81ad8ba2 blueswir1
        case 2:
1261 a4e7dd52 blueswir1
            stw_kernel(addr, val);
1262 81ad8ba2 blueswir1
            break;
1263 81ad8ba2 blueswir1
        default:
1264 81ad8ba2 blueswir1
        case 4:
1265 a4e7dd52 blueswir1
            stl_kernel(addr, val);
1266 81ad8ba2 blueswir1
            break;
1267 81ad8ba2 blueswir1
        case 8:
1268 a4e7dd52 blueswir1
            stq_kernel(addr, val);
1269 81ad8ba2 blueswir1
            break;
1270 81ad8ba2 blueswir1
        }
1271 81ad8ba2 blueswir1
        break;
1272 6c36d3fa blueswir1
    case 0xc: /* I-cache tag */
1273 6c36d3fa blueswir1
    case 0xd: /* I-cache data */
1274 6c36d3fa blueswir1
    case 0xe: /* D-cache tag */
1275 6c36d3fa blueswir1
    case 0xf: /* D-cache data */
1276 6c36d3fa blueswir1
    case 0x10: /* I/D-cache flush page */
1277 6c36d3fa blueswir1
    case 0x11: /* I/D-cache flush segment */
1278 6c36d3fa blueswir1
    case 0x12: /* I/D-cache flush region */
1279 6c36d3fa blueswir1
    case 0x13: /* I/D-cache flush context */
1280 6c36d3fa blueswir1
    case 0x14: /* I/D-cache flush user */
1281 6c36d3fa blueswir1
        break;
1282 e80cfcfc bellard
    case 0x17: /* Block copy, sta access */
1283 0f8a249a blueswir1
        {
1284 1a2fb1c0 blueswir1
            // val = src
1285 1a2fb1c0 blueswir1
            // addr = dst
1286 0f8a249a blueswir1
            // copy 32 bytes
1287 6c36d3fa blueswir1
            unsigned int i;
1288 1a2fb1c0 blueswir1
            uint32_t src = val & ~3, dst = addr & ~3, temp;
1289 3b46e624 ths
1290 6c36d3fa blueswir1
            for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
1291 6c36d3fa blueswir1
                temp = ldl_kernel(src);
1292 6c36d3fa blueswir1
                stl_kernel(dst, temp);
1293 6c36d3fa blueswir1
            }
1294 0f8a249a blueswir1
        }
1295 8543e2cf blueswir1
        break;
1296 e80cfcfc bellard
    case 0x1f: /* Block fill, stda access */
1297 0f8a249a blueswir1
        {
1298 1a2fb1c0 blueswir1
            // addr = dst
1299 1a2fb1c0 blueswir1
            // fill 32 bytes with val
1300 6c36d3fa blueswir1
            unsigned int i;
1301 1a2fb1c0 blueswir1
            uint32_t dst = addr & 7;
1302 6c36d3fa blueswir1
1303 6c36d3fa blueswir1
            for (i = 0; i < 32; i += 8, dst += 8)
1304 6c36d3fa blueswir1
                stq_kernel(dst, val);
1305 0f8a249a blueswir1
        }
1306 8543e2cf blueswir1
        break;
1307 6c36d3fa blueswir1
    case 0x20: /* MMU passthrough */
1308 0f8a249a blueswir1
        {
1309 02aab46a bellard
            switch(size) {
1310 02aab46a bellard
            case 1:
1311 1a2fb1c0 blueswir1
                stb_phys(addr, val);
1312 02aab46a bellard
                break;
1313 02aab46a bellard
            case 2:
1314 a4e7dd52 blueswir1
                stw_phys(addr, val);
1315 02aab46a bellard
                break;
1316 02aab46a bellard
            case 4:
1317 02aab46a bellard
            default:
1318 a4e7dd52 blueswir1
                stl_phys(addr, val);
1319 02aab46a bellard
                break;
1320 9e61bde5 bellard
            case 8:
1321 a4e7dd52 blueswir1
                stq_phys(addr, val);
1322 9e61bde5 bellard
                break;
1323 02aab46a bellard
            }
1324 0f8a249a blueswir1
        }
1325 8543e2cf blueswir1
        break;
1326 045380be blueswir1
    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1327 0f8a249a blueswir1
        {
1328 5dcb6b91 blueswir1
            switch(size) {
1329 5dcb6b91 blueswir1
            case 1:
1330 1a2fb1c0 blueswir1
                stb_phys((target_phys_addr_t)addr
1331 1a2fb1c0 blueswir1
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1332 5dcb6b91 blueswir1
                break;
1333 5dcb6b91 blueswir1
            case 2:
1334 a4e7dd52 blueswir1
                stw_phys((target_phys_addr_t)addr
1335 1a2fb1c0 blueswir1
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1336 5dcb6b91 blueswir1
                break;
1337 5dcb6b91 blueswir1
            case 4:
1338 5dcb6b91 blueswir1
            default:
1339 a4e7dd52 blueswir1
                stl_phys((target_phys_addr_t)addr
1340 1a2fb1c0 blueswir1
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1341 5dcb6b91 blueswir1
                break;
1342 5dcb6b91 blueswir1
            case 8:
1343 a4e7dd52 blueswir1
                stq_phys((target_phys_addr_t)addr
1344 1a2fb1c0 blueswir1
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1345 5dcb6b91 blueswir1
                break;
1346 5dcb6b91 blueswir1
            }
1347 0f8a249a blueswir1
        }
1348 8543e2cf blueswir1
        break;
1349 045380be blueswir1
    case 0x30: // store buffer tags or Turbosparc secondary cache diagnostic
1350 045380be blueswir1
    case 0x31: // store buffer data, Ross RT620 I-cache flush or
1351 045380be blueswir1
               // Turbosparc snoop RAM
1352 77f193da blueswir1
    case 0x32: // store buffer control or Turbosparc page table
1353 77f193da blueswir1
               // descriptor diagnostic
1354 6c36d3fa blueswir1
    case 0x36: /* I-cache flash clear */
1355 6c36d3fa blueswir1
    case 0x37: /* D-cache flash clear */
1356 666c87aa blueswir1
    case 0x4c: /* breakpoint action */
1357 6c36d3fa blueswir1
        break;
1358 4017190e blueswir1
    case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
1359 4017190e blueswir1
        {
1360 4017190e blueswir1
            int reg = (addr >> 8) & 3;
1361 4017190e blueswir1
1362 4017190e blueswir1
            switch(reg) {
1363 4017190e blueswir1
            case 0: /* Breakpoint Value (Addr) */
1364 4017190e blueswir1
                env->mmubpregs[reg] = (val & 0xfffffffffULL);
1365 4017190e blueswir1
                break;
1366 4017190e blueswir1
            case 1: /* Breakpoint Mask */
1367 4017190e blueswir1
                env->mmubpregs[reg] = (val & 0xfffffffffULL);
1368 4017190e blueswir1
                break;
1369 4017190e blueswir1
            case 2: /* Breakpoint Control */
1370 4017190e blueswir1
                env->mmubpregs[reg] = (val & 0x7fULL);
1371 4017190e blueswir1
                break;
1372 4017190e blueswir1
            case 3: /* Breakpoint Status */
1373 4017190e blueswir1
                env->mmubpregs[reg] = (val & 0xfULL);
1374 4017190e blueswir1
                break;
1375 4017190e blueswir1
            }
1376 4017190e blueswir1
            DPRINTF_MMU("write breakpoint reg[%d] 0x%016llx\n", reg,
1377 4017190e blueswir1
                        env->mmuregs[reg]);
1378 4017190e blueswir1
        }
1379 4017190e blueswir1
        break;
1380 045380be blueswir1
    case 8: /* User code access, XXX */
1381 6c36d3fa blueswir1
    case 9: /* Supervisor code access, XXX */
1382 e8af50a3 bellard
    default:
1383 e18231a3 blueswir1
        do_unassigned_access(addr, 1, 0, asi, size);
1384 8543e2cf blueswir1
        break;
1385 e8af50a3 bellard
    }
1386 8543e2cf blueswir1
#ifdef DEBUG_ASI
1387 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
1388 8543e2cf blueswir1
#endif
1389 e8af50a3 bellard
}
1390 e8af50a3 bellard
1391 81ad8ba2 blueswir1
#endif /* CONFIG_USER_ONLY */
1392 81ad8ba2 blueswir1
#else /* TARGET_SPARC64 */
1393 81ad8ba2 blueswir1
1394 81ad8ba2 blueswir1
#ifdef CONFIG_USER_ONLY
1395 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1396 81ad8ba2 blueswir1
{
1397 81ad8ba2 blueswir1
    uint64_t ret = 0;
1398 1a2fb1c0 blueswir1
#if defined(DEBUG_ASI)
1399 1a2fb1c0 blueswir1
    target_ulong last_addr = addr;
1400 1a2fb1c0 blueswir1
#endif
1401 81ad8ba2 blueswir1
1402 81ad8ba2 blueswir1
    if (asi < 0x80)
1403 81ad8ba2 blueswir1
        raise_exception(TT_PRIV_ACT);
1404 81ad8ba2 blueswir1
1405 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1406 2cade6a3 blueswir1
    address_mask(env, &addr);
1407 c2bc0e38 blueswir1
1408 81ad8ba2 blueswir1
    switch (asi) {
1409 81ad8ba2 blueswir1
    case 0x82: // Primary no-fault
1410 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1411 e83ce550 blueswir1
        if (page_check_range(addr, size, PAGE_READ) == -1) {
1412 e83ce550 blueswir1
#ifdef DEBUG_ASI
1413 e83ce550 blueswir1
            dump_asi("read ", last_addr, asi, size, ret);
1414 e83ce550 blueswir1
#endif
1415 e83ce550 blueswir1
            return 0;
1416 e83ce550 blueswir1
        }
1417 e83ce550 blueswir1
        // Fall through
1418 e83ce550 blueswir1
    case 0x80: // Primary
1419 e83ce550 blueswir1
    case 0x88: // Primary LE
1420 81ad8ba2 blueswir1
        {
1421 81ad8ba2 blueswir1
            switch(size) {
1422 81ad8ba2 blueswir1
            case 1:
1423 1a2fb1c0 blueswir1
                ret = ldub_raw(addr);
1424 81ad8ba2 blueswir1
                break;
1425 81ad8ba2 blueswir1
            case 2:
1426 a4e7dd52 blueswir1
                ret = lduw_raw(addr);
1427 81ad8ba2 blueswir1
                break;
1428 81ad8ba2 blueswir1
            case 4:
1429 a4e7dd52 blueswir1
                ret = ldl_raw(addr);
1430 81ad8ba2 blueswir1
                break;
1431 81ad8ba2 blueswir1
            default:
1432 81ad8ba2 blueswir1
            case 8:
1433 a4e7dd52 blueswir1
                ret = ldq_raw(addr);
1434 81ad8ba2 blueswir1
                break;
1435 81ad8ba2 blueswir1
            }
1436 81ad8ba2 blueswir1
        }
1437 81ad8ba2 blueswir1
        break;
1438 81ad8ba2 blueswir1
    case 0x83: // Secondary no-fault
1439 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1440 e83ce550 blueswir1
        if (page_check_range(addr, size, PAGE_READ) == -1) {
1441 e83ce550 blueswir1
#ifdef DEBUG_ASI
1442 e83ce550 blueswir1
            dump_asi("read ", last_addr, asi, size, ret);
1443 e83ce550 blueswir1
#endif
1444 e83ce550 blueswir1
            return 0;
1445 e83ce550 blueswir1
        }
1446 e83ce550 blueswir1
        // Fall through
1447 e83ce550 blueswir1
    case 0x81: // Secondary
1448 e83ce550 blueswir1
    case 0x89: // Secondary LE
1449 81ad8ba2 blueswir1
        // XXX
1450 81ad8ba2 blueswir1
        break;
1451 81ad8ba2 blueswir1
    default:
1452 81ad8ba2 blueswir1
        break;
1453 81ad8ba2 blueswir1
    }
1454 81ad8ba2 blueswir1
1455 81ad8ba2 blueswir1
    /* Convert from little endian */
1456 81ad8ba2 blueswir1
    switch (asi) {
1457 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1458 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1459 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1460 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1461 81ad8ba2 blueswir1
        switch(size) {
1462 81ad8ba2 blueswir1
        case 2:
1463 81ad8ba2 blueswir1
            ret = bswap16(ret);
1464 e32664fb blueswir1
            break;
1465 81ad8ba2 blueswir1
        case 4:
1466 81ad8ba2 blueswir1
            ret = bswap32(ret);
1467 e32664fb blueswir1
            break;
1468 81ad8ba2 blueswir1
        case 8:
1469 81ad8ba2 blueswir1
            ret = bswap64(ret);
1470 e32664fb blueswir1
            break;
1471 81ad8ba2 blueswir1
        default:
1472 81ad8ba2 blueswir1
            break;
1473 81ad8ba2 blueswir1
        }
1474 81ad8ba2 blueswir1
    default:
1475 81ad8ba2 blueswir1
        break;
1476 81ad8ba2 blueswir1
    }
1477 81ad8ba2 blueswir1
1478 81ad8ba2 blueswir1
    /* Convert to signed number */
1479 81ad8ba2 blueswir1
    if (sign) {
1480 81ad8ba2 blueswir1
        switch(size) {
1481 81ad8ba2 blueswir1
        case 1:
1482 81ad8ba2 blueswir1
            ret = (int8_t) ret;
1483 e32664fb blueswir1
            break;
1484 81ad8ba2 blueswir1
        case 2:
1485 81ad8ba2 blueswir1
            ret = (int16_t) ret;
1486 e32664fb blueswir1
            break;
1487 81ad8ba2 blueswir1
        case 4:
1488 81ad8ba2 blueswir1
            ret = (int32_t) ret;
1489 e32664fb blueswir1
            break;
1490 81ad8ba2 blueswir1
        default:
1491 81ad8ba2 blueswir1
            break;
1492 81ad8ba2 blueswir1
        }
1493 81ad8ba2 blueswir1
    }
1494 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1495 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
1496 1a2fb1c0 blueswir1
#endif
1497 1a2fb1c0 blueswir1
    return ret;
1498 81ad8ba2 blueswir1
}
1499 81ad8ba2 blueswir1
1500 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
1501 81ad8ba2 blueswir1
{
1502 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1503 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
1504 1a2fb1c0 blueswir1
#endif
1505 81ad8ba2 blueswir1
    if (asi < 0x80)
1506 81ad8ba2 blueswir1
        raise_exception(TT_PRIV_ACT);
1507 81ad8ba2 blueswir1
1508 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1509 2cade6a3 blueswir1
    address_mask(env, &addr);
1510 c2bc0e38 blueswir1
1511 81ad8ba2 blueswir1
    /* Convert to little endian */
1512 81ad8ba2 blueswir1
    switch (asi) {
1513 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1514 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1515 81ad8ba2 blueswir1
        switch(size) {
1516 81ad8ba2 blueswir1
        case 2:
1517 1a2fb1c0 blueswir1
            addr = bswap16(addr);
1518 e32664fb blueswir1
            break;
1519 81ad8ba2 blueswir1
        case 4:
1520 1a2fb1c0 blueswir1
            addr = bswap32(addr);
1521 e32664fb blueswir1
            break;
1522 81ad8ba2 blueswir1
        case 8:
1523 1a2fb1c0 blueswir1
            addr = bswap64(addr);
1524 e32664fb blueswir1
            break;
1525 81ad8ba2 blueswir1
        default:
1526 81ad8ba2 blueswir1
            break;
1527 81ad8ba2 blueswir1
        }
1528 81ad8ba2 blueswir1
    default:
1529 81ad8ba2 blueswir1
        break;
1530 81ad8ba2 blueswir1
    }
1531 81ad8ba2 blueswir1
1532 81ad8ba2 blueswir1
    switch(asi) {
1533 81ad8ba2 blueswir1
    case 0x80: // Primary
1534 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1535 81ad8ba2 blueswir1
        {
1536 81ad8ba2 blueswir1
            switch(size) {
1537 81ad8ba2 blueswir1
            case 1:
1538 1a2fb1c0 blueswir1
                stb_raw(addr, val);
1539 81ad8ba2 blueswir1
                break;
1540 81ad8ba2 blueswir1
            case 2:
1541 a4e7dd52 blueswir1
                stw_raw(addr, val);
1542 81ad8ba2 blueswir1
                break;
1543 81ad8ba2 blueswir1
            case 4:
1544 a4e7dd52 blueswir1
                stl_raw(addr, val);
1545 81ad8ba2 blueswir1
                break;
1546 81ad8ba2 blueswir1
            case 8:
1547 81ad8ba2 blueswir1
            default:
1548 a4e7dd52 blueswir1
                stq_raw(addr, val);
1549 81ad8ba2 blueswir1
                break;
1550 81ad8ba2 blueswir1
            }
1551 81ad8ba2 blueswir1
        }
1552 81ad8ba2 blueswir1
        break;
1553 81ad8ba2 blueswir1
    case 0x81: // Secondary
1554 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1555 81ad8ba2 blueswir1
        // XXX
1556 81ad8ba2 blueswir1
        return;
1557 81ad8ba2 blueswir1
1558 81ad8ba2 blueswir1
    case 0x82: // Primary no-fault, RO
1559 81ad8ba2 blueswir1
    case 0x83: // Secondary no-fault, RO
1560 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE, RO
1561 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE, RO
1562 81ad8ba2 blueswir1
    default:
1563 e18231a3 blueswir1
        do_unassigned_access(addr, 1, 0, 1, size);
1564 81ad8ba2 blueswir1
        return;
1565 81ad8ba2 blueswir1
    }
1566 81ad8ba2 blueswir1
}
1567 81ad8ba2 blueswir1
1568 81ad8ba2 blueswir1
#else /* CONFIG_USER_ONLY */
1569 3475187d bellard
1570 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1571 3475187d bellard
{
1572 83469015 bellard
    uint64_t ret = 0;
1573 1a2fb1c0 blueswir1
#if defined(DEBUG_ASI)
1574 1a2fb1c0 blueswir1
    target_ulong last_addr = addr;
1575 1a2fb1c0 blueswir1
#endif
1576 3475187d bellard
1577 6f27aba6 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1578 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
1579 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
1580 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
1581 0f8a249a blueswir1
        raise_exception(TT_PRIV_ACT);
1582 3475187d bellard
1583 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1584 3475187d bellard
    switch (asi) {
1585 e83ce550 blueswir1
    case 0x82: // Primary no-fault
1586 e83ce550 blueswir1
    case 0x8a: // Primary no-fault LE
1587 e83ce550 blueswir1
        if (cpu_get_phys_page_debug(env, addr) == -1ULL) {
1588 e83ce550 blueswir1
#ifdef DEBUG_ASI
1589 e83ce550 blueswir1
            dump_asi("read ", last_addr, asi, size, ret);
1590 e83ce550 blueswir1
#endif
1591 e83ce550 blueswir1
            return 0;
1592 e83ce550 blueswir1
        }
1593 e83ce550 blueswir1
        // Fall through
1594 81ad8ba2 blueswir1
    case 0x10: // As if user primary
1595 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1596 81ad8ba2 blueswir1
    case 0x80: // Primary
1597 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1598 c99657d3 blueswir1
    case 0xe2: // UA2007 Primary block init
1599 c99657d3 blueswir1
    case 0xe3: // UA2007 Secondary block init
1600 81ad8ba2 blueswir1
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1601 5578ceab blueswir1
            if ((env->def->features & CPU_FEATURE_HYPV)
1602 5578ceab blueswir1
                && env->hpstate & HS_PRIV) {
1603 6f27aba6 blueswir1
                switch(size) {
1604 6f27aba6 blueswir1
                case 1:
1605 1a2fb1c0 blueswir1
                    ret = ldub_hypv(addr);
1606 6f27aba6 blueswir1
                    break;
1607 6f27aba6 blueswir1
                case 2:
1608 a4e7dd52 blueswir1
                    ret = lduw_hypv(addr);
1609 6f27aba6 blueswir1
                    break;
1610 6f27aba6 blueswir1
                case 4:
1611 a4e7dd52 blueswir1
                    ret = ldl_hypv(addr);
1612 6f27aba6 blueswir1
                    break;
1613 6f27aba6 blueswir1
                default:
1614 6f27aba6 blueswir1
                case 8:
1615 a4e7dd52 blueswir1
                    ret = ldq_hypv(addr);
1616 6f27aba6 blueswir1
                    break;
1617 6f27aba6 blueswir1
                }
1618 6f27aba6 blueswir1
            } else {
1619 6f27aba6 blueswir1
                switch(size) {
1620 6f27aba6 blueswir1
                case 1:
1621 1a2fb1c0 blueswir1
                    ret = ldub_kernel(addr);
1622 6f27aba6 blueswir1
                    break;
1623 6f27aba6 blueswir1
                case 2:
1624 a4e7dd52 blueswir1
                    ret = lduw_kernel(addr);
1625 6f27aba6 blueswir1
                    break;
1626 6f27aba6 blueswir1
                case 4:
1627 a4e7dd52 blueswir1
                    ret = ldl_kernel(addr);
1628 6f27aba6 blueswir1
                    break;
1629 6f27aba6 blueswir1
                default:
1630 6f27aba6 blueswir1
                case 8:
1631 a4e7dd52 blueswir1
                    ret = ldq_kernel(addr);
1632 6f27aba6 blueswir1
                    break;
1633 6f27aba6 blueswir1
                }
1634 81ad8ba2 blueswir1
            }
1635 81ad8ba2 blueswir1
        } else {
1636 81ad8ba2 blueswir1
            switch(size) {
1637 81ad8ba2 blueswir1
            case 1:
1638 1a2fb1c0 blueswir1
                ret = ldub_user(addr);
1639 81ad8ba2 blueswir1
                break;
1640 81ad8ba2 blueswir1
            case 2:
1641 a4e7dd52 blueswir1
                ret = lduw_user(addr);
1642 81ad8ba2 blueswir1
                break;
1643 81ad8ba2 blueswir1
            case 4:
1644 a4e7dd52 blueswir1
                ret = ldl_user(addr);
1645 81ad8ba2 blueswir1
                break;
1646 81ad8ba2 blueswir1
            default:
1647 81ad8ba2 blueswir1
            case 8:
1648 a4e7dd52 blueswir1
                ret = ldq_user(addr);
1649 81ad8ba2 blueswir1
                break;
1650 81ad8ba2 blueswir1
            }
1651 81ad8ba2 blueswir1
        }
1652 81ad8ba2 blueswir1
        break;
1653 3475187d bellard
    case 0x14: // Bypass
1654 3475187d bellard
    case 0x15: // Bypass, non-cacheable
1655 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1656 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1657 0f8a249a blueswir1
        {
1658 02aab46a bellard
            switch(size) {
1659 02aab46a bellard
            case 1:
1660 1a2fb1c0 blueswir1
                ret = ldub_phys(addr);
1661 02aab46a bellard
                break;
1662 02aab46a bellard
            case 2:
1663 a4e7dd52 blueswir1
                ret = lduw_phys(addr);
1664 02aab46a bellard
                break;
1665 02aab46a bellard
            case 4:
1666 a4e7dd52 blueswir1
                ret = ldl_phys(addr);
1667 02aab46a bellard
                break;
1668 02aab46a bellard
            default:
1669 02aab46a bellard
            case 8:
1670 a4e7dd52 blueswir1
                ret = ldq_phys(addr);
1671 02aab46a bellard
                break;
1672 02aab46a bellard
            }
1673 0f8a249a blueswir1
            break;
1674 0f8a249a blueswir1
        }
1675 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
1676 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
1677 db166940 blueswir1
        //  Only ldda allowed
1678 db166940 blueswir1
        raise_exception(TT_ILL_INSN);
1679 db166940 blueswir1
        return 0;
1680 e83ce550 blueswir1
    case 0x83: // Secondary no-fault
1681 e83ce550 blueswir1
    case 0x8b: // Secondary no-fault LE
1682 e83ce550 blueswir1
        if (cpu_get_phys_page_debug(env, addr) == -1ULL) {
1683 e83ce550 blueswir1
#ifdef DEBUG_ASI
1684 e83ce550 blueswir1
            dump_asi("read ", last_addr, asi, size, ret);
1685 e83ce550 blueswir1
#endif
1686 e83ce550 blueswir1
            return 0;
1687 e83ce550 blueswir1
        }
1688 e83ce550 blueswir1
        // Fall through
1689 83469015 bellard
    case 0x04: // Nucleus
1690 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
1691 83469015 bellard
    case 0x11: // As if user secondary
1692 83469015 bellard
    case 0x19: // As if user secondary LE
1693 83469015 bellard
    case 0x4a: // UPA config
1694 81ad8ba2 blueswir1
    case 0x81: // Secondary
1695 83469015 bellard
    case 0x89: // Secondary LE
1696 0f8a249a blueswir1
        // XXX
1697 0f8a249a blueswir1
        break;
1698 3475187d bellard
    case 0x45: // LSU
1699 0f8a249a blueswir1
        ret = env->lsu;
1700 0f8a249a blueswir1
        break;
1701 3475187d bellard
    case 0x50: // I-MMU regs
1702 0f8a249a blueswir1
        {
1703 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
1704 3475187d bellard
1705 697a77e6 Igor Kovalenko
            if (reg == 0) {
1706 697a77e6 Igor Kovalenko
                // I-TSB Tag Target register
1707 697a77e6 Igor Kovalenko
                ret = ultrasparc_tag_target(env->immuregs[6]);
1708 697a77e6 Igor Kovalenko
            } else {
1709 697a77e6 Igor Kovalenko
                ret = env->immuregs[reg];
1710 697a77e6 Igor Kovalenko
            }
1711 697a77e6 Igor Kovalenko
1712 0f8a249a blueswir1
            break;
1713 0f8a249a blueswir1
        }
1714 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer
1715 697a77e6 Igor Kovalenko
        {
1716 697a77e6 Igor Kovalenko
            // env->immuregs[5] holds I-MMU TSB register value
1717 697a77e6 Igor Kovalenko
            // env->immuregs[6] holds I-MMU Tag Access register value
1718 697a77e6 Igor Kovalenko
            ret = ultrasparc_tsb_pointer(env->immuregs[5], env->immuregs[6],
1719 697a77e6 Igor Kovalenko
                                         8*1024);
1720 697a77e6 Igor Kovalenko
            break;
1721 697a77e6 Igor Kovalenko
        }
1722 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer
1723 697a77e6 Igor Kovalenko
        {
1724 697a77e6 Igor Kovalenko
            // env->immuregs[5] holds I-MMU TSB register value
1725 697a77e6 Igor Kovalenko
            // env->immuregs[6] holds I-MMU Tag Access register value
1726 697a77e6 Igor Kovalenko
            ret = ultrasparc_tsb_pointer(env->immuregs[5], env->immuregs[6],
1727 697a77e6 Igor Kovalenko
                                         64*1024);
1728 697a77e6 Igor Kovalenko
            break;
1729 697a77e6 Igor Kovalenko
        }
1730 a5a52cf2 blueswir1
    case 0x55: // I-MMU data access
1731 a5a52cf2 blueswir1
        {
1732 a5a52cf2 blueswir1
            int reg = (addr >> 3) & 0x3f;
1733 a5a52cf2 blueswir1
1734 a5a52cf2 blueswir1
            ret = env->itlb_tte[reg];
1735 a5a52cf2 blueswir1
            break;
1736 a5a52cf2 blueswir1
        }
1737 83469015 bellard
    case 0x56: // I-MMU tag read
1738 0f8a249a blueswir1
        {
1739 43e9e742 blueswir1
            int reg = (addr >> 3) & 0x3f;
1740 0f8a249a blueswir1
1741 43e9e742 blueswir1
            ret = env->itlb_tag[reg];
1742 0f8a249a blueswir1
            break;
1743 0f8a249a blueswir1
        }
1744 3475187d bellard
    case 0x58: // D-MMU regs
1745 0f8a249a blueswir1
        {
1746 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
1747 3475187d bellard
1748 697a77e6 Igor Kovalenko
            if (reg == 0) {
1749 697a77e6 Igor Kovalenko
                // D-TSB Tag Target register
1750 697a77e6 Igor Kovalenko
                ret = ultrasparc_tag_target(env->dmmuregs[6]);
1751 697a77e6 Igor Kovalenko
            } else {
1752 697a77e6 Igor Kovalenko
                ret = env->dmmuregs[reg];
1753 697a77e6 Igor Kovalenko
            }
1754 697a77e6 Igor Kovalenko
            break;
1755 697a77e6 Igor Kovalenko
        }
1756 697a77e6 Igor Kovalenko
    case 0x59: // D-MMU 8k TSB pointer
1757 697a77e6 Igor Kovalenko
        {
1758 697a77e6 Igor Kovalenko
            // env->dmmuregs[5] holds D-MMU TSB register value
1759 697a77e6 Igor Kovalenko
            // env->dmmuregs[6] holds D-MMU Tag Access register value
1760 697a77e6 Igor Kovalenko
            ret = ultrasparc_tsb_pointer(env->dmmuregs[5], env->dmmuregs[6],
1761 697a77e6 Igor Kovalenko
                                         8*1024);
1762 697a77e6 Igor Kovalenko
            break;
1763 697a77e6 Igor Kovalenko
        }
1764 697a77e6 Igor Kovalenko
    case 0x5a: // D-MMU 64k TSB pointer
1765 697a77e6 Igor Kovalenko
        {
1766 697a77e6 Igor Kovalenko
            // env->dmmuregs[5] holds D-MMU TSB register value
1767 697a77e6 Igor Kovalenko
            // env->dmmuregs[6] holds D-MMU Tag Access register value
1768 697a77e6 Igor Kovalenko
            ret = ultrasparc_tsb_pointer(env->dmmuregs[5], env->dmmuregs[6],
1769 697a77e6 Igor Kovalenko
                                         64*1024);
1770 0f8a249a blueswir1
            break;
1771 0f8a249a blueswir1
        }
1772 a5a52cf2 blueswir1
    case 0x5d: // D-MMU data access
1773 a5a52cf2 blueswir1
        {
1774 a5a52cf2 blueswir1
            int reg = (addr >> 3) & 0x3f;
1775 a5a52cf2 blueswir1
1776 a5a52cf2 blueswir1
            ret = env->dtlb_tte[reg];
1777 a5a52cf2 blueswir1
            break;
1778 a5a52cf2 blueswir1
        }
1779 83469015 bellard
    case 0x5e: // D-MMU tag read
1780 0f8a249a blueswir1
        {
1781 43e9e742 blueswir1
            int reg = (addr >> 3) & 0x3f;
1782 0f8a249a blueswir1
1783 43e9e742 blueswir1
            ret = env->dtlb_tag[reg];
1784 0f8a249a blueswir1
            break;
1785 0f8a249a blueswir1
        }
1786 f7350b47 blueswir1
    case 0x46: // D-cache data
1787 f7350b47 blueswir1
    case 0x47: // D-cache tag access
1788 a5a52cf2 blueswir1
    case 0x4b: // E-cache error enable
1789 a5a52cf2 blueswir1
    case 0x4c: // E-cache asynchronous fault status
1790 a5a52cf2 blueswir1
    case 0x4d: // E-cache asynchronous fault address
1791 f7350b47 blueswir1
    case 0x4e: // E-cache tag data
1792 f7350b47 blueswir1
    case 0x66: // I-cache instruction access
1793 f7350b47 blueswir1
    case 0x67: // I-cache tag access
1794 f7350b47 blueswir1
    case 0x6e: // I-cache predecode
1795 f7350b47 blueswir1
    case 0x6f: // I-cache LRU etc.
1796 f7350b47 blueswir1
    case 0x76: // E-cache tag
1797 f7350b47 blueswir1
    case 0x7e: // E-cache tag
1798 f7350b47 blueswir1
        break;
1799 3475187d bellard
    case 0x5b: // D-MMU data pointer
1800 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
1801 83469015 bellard
    case 0x49: // Interrupt data receive
1802 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
1803 0f8a249a blueswir1
        // XXX
1804 0f8a249a blueswir1
        break;
1805 3475187d bellard
    case 0x54: // I-MMU data in, WO
1806 3475187d bellard
    case 0x57: // I-MMU demap, WO
1807 3475187d bellard
    case 0x5c: // D-MMU data in, WO
1808 3475187d bellard
    case 0x5f: // D-MMU demap, WO
1809 83469015 bellard
    case 0x77: // Interrupt vector, WO
1810 3475187d bellard
    default:
1811 e18231a3 blueswir1
        do_unassigned_access(addr, 0, 0, 1, size);
1812 0f8a249a blueswir1
        ret = 0;
1813 0f8a249a blueswir1
        break;
1814 3475187d bellard
    }
1815 81ad8ba2 blueswir1
1816 81ad8ba2 blueswir1
    /* Convert from little endian */
1817 81ad8ba2 blueswir1
    switch (asi) {
1818 81ad8ba2 blueswir1
    case 0x0c: // Nucleus Little Endian (LE)
1819 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1820 81ad8ba2 blueswir1
    case 0x19: // As if user secondary LE
1821 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1822 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1823 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1824 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1825 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1826 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1827 81ad8ba2 blueswir1
        switch(size) {
1828 81ad8ba2 blueswir1
        case 2:
1829 81ad8ba2 blueswir1
            ret = bswap16(ret);
1830 e32664fb blueswir1
            break;
1831 81ad8ba2 blueswir1
        case 4:
1832 81ad8ba2 blueswir1
            ret = bswap32(ret);
1833 e32664fb blueswir1
            break;
1834 81ad8ba2 blueswir1
        case 8:
1835 81ad8ba2 blueswir1
            ret = bswap64(ret);
1836 e32664fb blueswir1
            break;
1837 81ad8ba2 blueswir1
        default:
1838 81ad8ba2 blueswir1
            break;
1839 81ad8ba2 blueswir1
        }
1840 81ad8ba2 blueswir1
    default:
1841 81ad8ba2 blueswir1
        break;
1842 81ad8ba2 blueswir1
    }
1843 81ad8ba2 blueswir1
1844 81ad8ba2 blueswir1
    /* Convert to signed number */
1845 81ad8ba2 blueswir1
    if (sign) {
1846 81ad8ba2 blueswir1
        switch(size) {
1847 81ad8ba2 blueswir1
        case 1:
1848 81ad8ba2 blueswir1
            ret = (int8_t) ret;
1849 e32664fb blueswir1
            break;
1850 81ad8ba2 blueswir1
        case 2:
1851 81ad8ba2 blueswir1
            ret = (int16_t) ret;
1852 e32664fb blueswir1
            break;
1853 81ad8ba2 blueswir1
        case 4:
1854 81ad8ba2 blueswir1
            ret = (int32_t) ret;
1855 e32664fb blueswir1
            break;
1856 81ad8ba2 blueswir1
        default:
1857 81ad8ba2 blueswir1
            break;
1858 81ad8ba2 blueswir1
        }
1859 81ad8ba2 blueswir1
    }
1860 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1861 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
1862 1a2fb1c0 blueswir1
#endif
1863 1a2fb1c0 blueswir1
    return ret;
1864 3475187d bellard
}
1865 3475187d bellard
1866 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
1867 3475187d bellard
{
1868 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1869 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
1870 1a2fb1c0 blueswir1
#endif
1871 6f27aba6 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1872 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
1873 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
1874 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
1875 0f8a249a blueswir1
        raise_exception(TT_PRIV_ACT);
1876 3475187d bellard
1877 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1878 81ad8ba2 blueswir1
    /* Convert to little endian */
1879 81ad8ba2 blueswir1
    switch (asi) {
1880 81ad8ba2 blueswir1
    case 0x0c: // Nucleus Little Endian (LE)
1881 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1882 81ad8ba2 blueswir1
    case 0x19: // As if user secondary LE
1883 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1884 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1885 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1886 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1887 81ad8ba2 blueswir1
        switch(size) {
1888 81ad8ba2 blueswir1
        case 2:
1889 1a2fb1c0 blueswir1
            addr = bswap16(addr);
1890 e32664fb blueswir1
            break;
1891 81ad8ba2 blueswir1
        case 4:
1892 1a2fb1c0 blueswir1
            addr = bswap32(addr);
1893 e32664fb blueswir1
            break;
1894 81ad8ba2 blueswir1
        case 8:
1895 1a2fb1c0 blueswir1
            addr = bswap64(addr);
1896 e32664fb blueswir1
            break;
1897 81ad8ba2 blueswir1
        default:
1898 81ad8ba2 blueswir1
            break;
1899 81ad8ba2 blueswir1
        }
1900 81ad8ba2 blueswir1
    default:
1901 81ad8ba2 blueswir1
        break;
1902 81ad8ba2 blueswir1
    }
1903 81ad8ba2 blueswir1
1904 3475187d bellard
    switch(asi) {
1905 81ad8ba2 blueswir1
    case 0x10: // As if user primary
1906 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1907 81ad8ba2 blueswir1
    case 0x80: // Primary
1908 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1909 c99657d3 blueswir1
    case 0xe2: // UA2007 Primary block init
1910 c99657d3 blueswir1
    case 0xe3: // UA2007 Secondary block init
1911 81ad8ba2 blueswir1
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1912 5578ceab blueswir1
            if ((env->def->features & CPU_FEATURE_HYPV)
1913 5578ceab blueswir1
                && env->hpstate & HS_PRIV) {
1914 6f27aba6 blueswir1
                switch(size) {
1915 6f27aba6 blueswir1
                case 1:
1916 1a2fb1c0 blueswir1
                    stb_hypv(addr, val);
1917 6f27aba6 blueswir1
                    break;
1918 6f27aba6 blueswir1
                case 2:
1919 a4e7dd52 blueswir1
                    stw_hypv(addr, val);
1920 6f27aba6 blueswir1
                    break;
1921 6f27aba6 blueswir1
                case 4:
1922 a4e7dd52 blueswir1
                    stl_hypv(addr, val);
1923 6f27aba6 blueswir1
                    break;
1924 6f27aba6 blueswir1
                case 8:
1925 6f27aba6 blueswir1
                default:
1926 a4e7dd52 blueswir1
                    stq_hypv(addr, val);
1927 6f27aba6 blueswir1
                    break;
1928 6f27aba6 blueswir1
                }
1929 6f27aba6 blueswir1
            } else {
1930 6f27aba6 blueswir1
                switch(size) {
1931 6f27aba6 blueswir1
                case 1:
1932 1a2fb1c0 blueswir1
                    stb_kernel(addr, val);
1933 6f27aba6 blueswir1
                    break;
1934 6f27aba6 blueswir1
                case 2:
1935 a4e7dd52 blueswir1
                    stw_kernel(addr, val);
1936 6f27aba6 blueswir1
                    break;
1937 6f27aba6 blueswir1
                case 4:
1938 a4e7dd52 blueswir1
                    stl_kernel(addr, val);
1939 6f27aba6 blueswir1
                    break;
1940 6f27aba6 blueswir1
                case 8:
1941 6f27aba6 blueswir1
                default:
1942 a4e7dd52 blueswir1
                    stq_kernel(addr, val);
1943 6f27aba6 blueswir1
                    break;
1944 6f27aba6 blueswir1
                }
1945 81ad8ba2 blueswir1
            }
1946 81ad8ba2 blueswir1
        } else {
1947 81ad8ba2 blueswir1
            switch(size) {
1948 81ad8ba2 blueswir1
            case 1:
1949 1a2fb1c0 blueswir1
                stb_user(addr, val);
1950 81ad8ba2 blueswir1
                break;
1951 81ad8ba2 blueswir1
            case 2:
1952 a4e7dd52 blueswir1
                stw_user(addr, val);
1953 81ad8ba2 blueswir1
                break;
1954 81ad8ba2 blueswir1
            case 4:
1955 a4e7dd52 blueswir1
                stl_user(addr, val);
1956 81ad8ba2 blueswir1
                break;
1957 81ad8ba2 blueswir1
            case 8:
1958 81ad8ba2 blueswir1
            default:
1959 a4e7dd52 blueswir1
                stq_user(addr, val);
1960 81ad8ba2 blueswir1
                break;
1961 81ad8ba2 blueswir1
            }
1962 81ad8ba2 blueswir1
        }
1963 81ad8ba2 blueswir1
        break;
1964 3475187d bellard
    case 0x14: // Bypass
1965 3475187d bellard
    case 0x15: // Bypass, non-cacheable
1966 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1967 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1968 0f8a249a blueswir1
        {
1969 02aab46a bellard
            switch(size) {
1970 02aab46a bellard
            case 1:
1971 1a2fb1c0 blueswir1
                stb_phys(addr, val);
1972 02aab46a bellard
                break;
1973 02aab46a bellard
            case 2:
1974 a4e7dd52 blueswir1
                stw_phys(addr, val);
1975 02aab46a bellard
                break;
1976 02aab46a bellard
            case 4:
1977 a4e7dd52 blueswir1
                stl_phys(addr, val);
1978 02aab46a bellard
                break;
1979 02aab46a bellard
            case 8:
1980 02aab46a bellard
            default:
1981 a4e7dd52 blueswir1
                stq_phys(addr, val);
1982 02aab46a bellard
                break;
1983 02aab46a bellard
            }
1984 0f8a249a blueswir1
        }
1985 0f8a249a blueswir1
        return;
1986 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
1987 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
1988 db166940 blueswir1
        //  Only ldda allowed
1989 db166940 blueswir1
        raise_exception(TT_ILL_INSN);
1990 db166940 blueswir1
        return;
1991 83469015 bellard
    case 0x04: // Nucleus
1992 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
1993 83469015 bellard
    case 0x11: // As if user secondary
1994 83469015 bellard
    case 0x19: // As if user secondary LE
1995 83469015 bellard
    case 0x4a: // UPA config
1996 51996525 blueswir1
    case 0x81: // Secondary
1997 83469015 bellard
    case 0x89: // Secondary LE
1998 0f8a249a blueswir1
        // XXX
1999 0f8a249a blueswir1
        return;
2000 3475187d bellard
    case 0x45: // LSU
2001 0f8a249a blueswir1
        {
2002 0f8a249a blueswir1
            uint64_t oldreg;
2003 0f8a249a blueswir1
2004 0f8a249a blueswir1
            oldreg = env->lsu;
2005 1a2fb1c0 blueswir1
            env->lsu = val & (DMMU_E | IMMU_E);
2006 0f8a249a blueswir1
            // Mappings generated during D/I MMU disabled mode are
2007 0f8a249a blueswir1
            // invalid in normal mode
2008 0f8a249a blueswir1
            if (oldreg != env->lsu) {
2009 77f193da blueswir1
                DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
2010 77f193da blueswir1
                            oldreg, env->lsu);
2011 83469015 bellard
#ifdef DEBUG_MMU
2012 0f8a249a blueswir1
                dump_mmu(env);
2013 83469015 bellard
#endif
2014 0f8a249a blueswir1
                tlb_flush(env, 1);
2015 0f8a249a blueswir1
            }
2016 0f8a249a blueswir1
            return;
2017 0f8a249a blueswir1
        }
2018 3475187d bellard
    case 0x50: // I-MMU regs
2019 0f8a249a blueswir1
        {
2020 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
2021 0f8a249a blueswir1
            uint64_t oldreg;
2022 3b46e624 ths
2023 0f8a249a blueswir1
            oldreg = env->immuregs[reg];
2024 3475187d bellard
            switch(reg) {
2025 3475187d bellard
            case 0: // RO
2026 3475187d bellard
            case 4:
2027 3475187d bellard
                return;
2028 3475187d bellard
            case 1: // Not in I-MMU
2029 3475187d bellard
            case 2:
2030 3475187d bellard
            case 7:
2031 3475187d bellard
            case 8:
2032 3475187d bellard
                return;
2033 3475187d bellard
            case 3: // SFSR
2034 1a2fb1c0 blueswir1
                if ((val & 1) == 0)
2035 1a2fb1c0 blueswir1
                    val = 0; // Clear SFSR
2036 3475187d bellard
                break;
2037 3475187d bellard
            case 5: // TSB access
2038 3475187d bellard
            case 6: // Tag access
2039 3475187d bellard
            default:
2040 3475187d bellard
                break;
2041 3475187d bellard
            }
2042 1a2fb1c0 blueswir1
            env->immuregs[reg] = val;
2043 3475187d bellard
            if (oldreg != env->immuregs[reg]) {
2044 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08"
2045 77f193da blueswir1
                            PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
2046 3475187d bellard
            }
2047 952a328f blueswir1
#ifdef DEBUG_MMU
2048 0f8a249a blueswir1
            dump_mmu(env);
2049 3475187d bellard
#endif
2050 0f8a249a blueswir1
            return;
2051 0f8a249a blueswir1
        }
2052 3475187d bellard
    case 0x54: // I-MMU data in
2053 0f8a249a blueswir1
        {
2054 0f8a249a blueswir1
            unsigned int i;
2055 0f8a249a blueswir1
2056 0f8a249a blueswir1
            // Try finding an invalid entry
2057 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2058 0f8a249a blueswir1
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
2059 0f8a249a blueswir1
                    env->itlb_tag[i] = env->immuregs[6];
2060 1a2fb1c0 blueswir1
                    env->itlb_tte[i] = val;
2061 0f8a249a blueswir1
                    return;
2062 0f8a249a blueswir1
                }
2063 0f8a249a blueswir1
            }
2064 0f8a249a blueswir1
            // Try finding an unlocked entry
2065 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2066 0f8a249a blueswir1
                if ((env->itlb_tte[i] & 0x40) == 0) {
2067 0f8a249a blueswir1
                    env->itlb_tag[i] = env->immuregs[6];
2068 1a2fb1c0 blueswir1
                    env->itlb_tte[i] = val;
2069 0f8a249a blueswir1
                    return;
2070 0f8a249a blueswir1
                }
2071 0f8a249a blueswir1
            }
2072 0f8a249a blueswir1
            // error state?
2073 0f8a249a blueswir1
            return;
2074 0f8a249a blueswir1
        }
2075 3475187d bellard
    case 0x55: // I-MMU data access
2076 0f8a249a blueswir1
        {
2077 cc6747f4 blueswir1
            // TODO: auto demap
2078 cc6747f4 blueswir1
2079 1a2fb1c0 blueswir1
            unsigned int i = (addr >> 3) & 0x3f;
2080 3475187d bellard
2081 0f8a249a blueswir1
            env->itlb_tag[i] = env->immuregs[6];
2082 1a2fb1c0 blueswir1
            env->itlb_tte[i] = val;
2083 0f8a249a blueswir1
            return;
2084 0f8a249a blueswir1
        }
2085 3475187d bellard
    case 0x57: // I-MMU demap
2086 cc6747f4 blueswir1
        {
2087 cc6747f4 blueswir1
            unsigned int i;
2088 cc6747f4 blueswir1
2089 cc6747f4 blueswir1
            for (i = 0; i < 64; i++) {
2090 cc6747f4 blueswir1
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
2091 cc6747f4 blueswir1
                    target_ulong mask = 0xffffffffffffe000ULL;
2092 cc6747f4 blueswir1
2093 cc6747f4 blueswir1
                    mask <<= 3 * ((env->itlb_tte[i] >> 61) & 3);
2094 cc6747f4 blueswir1
                    if ((val & mask) == (env->itlb_tag[i] & mask)) {
2095 cc6747f4 blueswir1
                        env->itlb_tag[i] = 0;
2096 cc6747f4 blueswir1
                        env->itlb_tte[i] = 0;
2097 cc6747f4 blueswir1
                    }
2098 cc6747f4 blueswir1
                    return;
2099 cc6747f4 blueswir1
                }
2100 cc6747f4 blueswir1
            }
2101 cc6747f4 blueswir1
        }
2102 0f8a249a blueswir1
        return;
2103 3475187d bellard
    case 0x58: // D-MMU regs
2104 0f8a249a blueswir1
        {
2105 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
2106 0f8a249a blueswir1
            uint64_t oldreg;
2107 3b46e624 ths
2108 0f8a249a blueswir1
            oldreg = env->dmmuregs[reg];
2109 3475187d bellard
            switch(reg) {
2110 3475187d bellard
            case 0: // RO
2111 3475187d bellard
            case 4:
2112 3475187d bellard
                return;
2113 3475187d bellard
            case 3: // SFSR
2114 1a2fb1c0 blueswir1
                if ((val & 1) == 0) {
2115 1a2fb1c0 blueswir1
                    val = 0; // Clear SFSR, Fault address
2116 0f8a249a blueswir1
                    env->dmmuregs[4] = 0;
2117 0f8a249a blueswir1
                }
2118 1a2fb1c0 blueswir1
                env->dmmuregs[reg] = val;
2119 3475187d bellard
                break;
2120 3475187d bellard
            case 1: // Primary context
2121 3475187d bellard
            case 2: // Secondary context
2122 3475187d bellard
            case 5: // TSB access
2123 3475187d bellard
            case 6: // Tag access
2124 3475187d bellard
            case 7: // Virtual Watchpoint
2125 3475187d bellard
            case 8: // Physical Watchpoint
2126 3475187d bellard
            default:
2127 3475187d bellard
                break;
2128 3475187d bellard
            }
2129 1a2fb1c0 blueswir1
            env->dmmuregs[reg] = val;
2130 3475187d bellard
            if (oldreg != env->dmmuregs[reg]) {
2131 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08"
2132 77f193da blueswir1
                            PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
2133 3475187d bellard
            }
2134 952a328f blueswir1
#ifdef DEBUG_MMU
2135 0f8a249a blueswir1
            dump_mmu(env);
2136 3475187d bellard
#endif
2137 0f8a249a blueswir1
            return;
2138 0f8a249a blueswir1
        }
2139 3475187d bellard
    case 0x5c: // D-MMU data in
2140 0f8a249a blueswir1
        {
2141 0f8a249a blueswir1
            unsigned int i;
2142 0f8a249a blueswir1
2143 0f8a249a blueswir1
            // Try finding an invalid entry
2144 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2145 0f8a249a blueswir1
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
2146 0f8a249a blueswir1
                    env->dtlb_tag[i] = env->dmmuregs[6];
2147 1a2fb1c0 blueswir1
                    env->dtlb_tte[i] = val;
2148 0f8a249a blueswir1
                    return;
2149 0f8a249a blueswir1
                }
2150 0f8a249a blueswir1
            }
2151 0f8a249a blueswir1
            // Try finding an unlocked entry
2152 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2153 0f8a249a blueswir1
                if ((env->dtlb_tte[i] & 0x40) == 0) {
2154 0f8a249a blueswir1
                    env->dtlb_tag[i] = env->dmmuregs[6];
2155 1a2fb1c0 blueswir1
                    env->dtlb_tte[i] = val;
2156 0f8a249a blueswir1
                    return;
2157 0f8a249a blueswir1
                }
2158 0f8a249a blueswir1
            }
2159 0f8a249a blueswir1
            // error state?
2160 0f8a249a blueswir1
            return;
2161 0f8a249a blueswir1
        }
2162 3475187d bellard
    case 0x5d: // D-MMU data access
2163 0f8a249a blueswir1
        {
2164 1a2fb1c0 blueswir1
            unsigned int i = (addr >> 3) & 0x3f;
2165 3475187d bellard
2166 0f8a249a blueswir1
            env->dtlb_tag[i] = env->dmmuregs[6];
2167 1a2fb1c0 blueswir1
            env->dtlb_tte[i] = val;
2168 0f8a249a blueswir1
            return;
2169 0f8a249a blueswir1
        }
2170 3475187d bellard
    case 0x5f: // D-MMU demap
2171 cc6747f4 blueswir1
        {
2172 cc6747f4 blueswir1
            unsigned int i;
2173 cc6747f4 blueswir1
2174 cc6747f4 blueswir1
            for (i = 0; i < 64; i++) {
2175 cc6747f4 blueswir1
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
2176 cc6747f4 blueswir1
                    target_ulong mask = 0xffffffffffffe000ULL;
2177 cc6747f4 blueswir1
2178 cc6747f4 blueswir1
                    mask <<= 3 * ((env->dtlb_tte[i] >> 61) & 3);
2179 cc6747f4 blueswir1
                    if ((val & mask) == (env->dtlb_tag[i] & mask)) {
2180 cc6747f4 blueswir1
                        env->dtlb_tag[i] = 0;
2181 cc6747f4 blueswir1
                        env->dtlb_tte[i] = 0;
2182 cc6747f4 blueswir1
                    }
2183 cc6747f4 blueswir1
                    return;
2184 cc6747f4 blueswir1
                }
2185 cc6747f4 blueswir1
            }
2186 cc6747f4 blueswir1
        }
2187 cc6747f4 blueswir1
        return;
2188 83469015 bellard
    case 0x49: // Interrupt data receive
2189 0f8a249a blueswir1
        // XXX
2190 0f8a249a blueswir1
        return;
2191 f7350b47 blueswir1
    case 0x46: // D-cache data
2192 f7350b47 blueswir1
    case 0x47: // D-cache tag access
2193 a5a52cf2 blueswir1
    case 0x4b: // E-cache error enable
2194 a5a52cf2 blueswir1
    case 0x4c: // E-cache asynchronous fault status
2195 a5a52cf2 blueswir1
    case 0x4d: // E-cache asynchronous fault address
2196 f7350b47 blueswir1
    case 0x4e: // E-cache tag data
2197 f7350b47 blueswir1
    case 0x66: // I-cache instruction access
2198 f7350b47 blueswir1
    case 0x67: // I-cache tag access
2199 f7350b47 blueswir1
    case 0x6e: // I-cache predecode
2200 f7350b47 blueswir1
    case 0x6f: // I-cache LRU etc.
2201 f7350b47 blueswir1
    case 0x76: // E-cache tag
2202 f7350b47 blueswir1
    case 0x7e: // E-cache tag
2203 f7350b47 blueswir1
        return;
2204 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer, RO
2205 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer, RO
2206 3475187d bellard
    case 0x56: // I-MMU tag read, RO
2207 3475187d bellard
    case 0x59: // D-MMU 8k TSB pointer, RO
2208 3475187d bellard
    case 0x5a: // D-MMU 64k TSB pointer, RO
2209 3475187d bellard
    case 0x5b: // D-MMU data pointer, RO
2210 3475187d bellard
    case 0x5e: // D-MMU tag read, RO
2211 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
2212 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
2213 83469015 bellard
    case 0x82: // Primary no-fault, RO
2214 83469015 bellard
    case 0x83: // Secondary no-fault, RO
2215 83469015 bellard
    case 0x8a: // Primary no-fault LE, RO
2216 83469015 bellard
    case 0x8b: // Secondary no-fault LE, RO
2217 3475187d bellard
    default:
2218 e18231a3 blueswir1
        do_unassigned_access(addr, 1, 0, 1, size);
2219 0f8a249a blueswir1
        return;
2220 3475187d bellard
    }
2221 3475187d bellard
}
2222 81ad8ba2 blueswir1
#endif /* CONFIG_USER_ONLY */
2223 3391c818 blueswir1
2224 db166940 blueswir1
void helper_ldda_asi(target_ulong addr, int asi, int rd)
2225 db166940 blueswir1
{
2226 db166940 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2227 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
2228 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
2229 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
2230 db166940 blueswir1
        raise_exception(TT_PRIV_ACT);
2231 db166940 blueswir1
2232 db166940 blueswir1
    switch (asi) {
2233 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
2234 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
2235 db166940 blueswir1
        helper_check_align(addr, 0xf);
2236 db166940 blueswir1
        if (rd == 0) {
2237 db166940 blueswir1
            env->gregs[1] = ldq_kernel(addr + 8);
2238 db166940 blueswir1
            if (asi == 0x2c)
2239 db166940 blueswir1
                bswap64s(&env->gregs[1]);
2240 db166940 blueswir1
        } else if (rd < 8) {
2241 db166940 blueswir1
            env->gregs[rd] = ldq_kernel(addr);
2242 db166940 blueswir1
            env->gregs[rd + 1] = ldq_kernel(addr + 8);
2243 db166940 blueswir1
            if (asi == 0x2c) {
2244 db166940 blueswir1
                bswap64s(&env->gregs[rd]);
2245 db166940 blueswir1
                bswap64s(&env->gregs[rd + 1]);
2246 db166940 blueswir1
            }
2247 db166940 blueswir1
        } else {
2248 db166940 blueswir1
            env->regwptr[rd] = ldq_kernel(addr);
2249 db166940 blueswir1
            env->regwptr[rd + 1] = ldq_kernel(addr + 8);
2250 db166940 blueswir1
            if (asi == 0x2c) {
2251 db166940 blueswir1
                bswap64s(&env->regwptr[rd]);
2252 db166940 blueswir1
                bswap64s(&env->regwptr[rd + 1]);
2253 db166940 blueswir1
            }
2254 db166940 blueswir1
        }
2255 db166940 blueswir1
        break;
2256 db166940 blueswir1
    default:
2257 db166940 blueswir1
        helper_check_align(addr, 0x3);
2258 db166940 blueswir1
        if (rd == 0)
2259 db166940 blueswir1
            env->gregs[1] = helper_ld_asi(addr + 4, asi, 4, 0);
2260 db166940 blueswir1
        else if (rd < 8) {
2261 db166940 blueswir1
            env->gregs[rd] = helper_ld_asi(addr, asi, 4, 0);
2262 db166940 blueswir1
            env->gregs[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2263 db166940 blueswir1
        } else {
2264 db166940 blueswir1
            env->regwptr[rd] = helper_ld_asi(addr, asi, 4, 0);
2265 db166940 blueswir1
            env->regwptr[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2266 db166940 blueswir1
        }
2267 db166940 blueswir1
        break;
2268 db166940 blueswir1
    }
2269 db166940 blueswir1
}
2270 db166940 blueswir1
2271 1a2fb1c0 blueswir1
void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2272 3391c818 blueswir1
{
2273 3391c818 blueswir1
    unsigned int i;
2274 1a2fb1c0 blueswir1
    target_ulong val;
2275 3391c818 blueswir1
2276 c2bc0e38 blueswir1
    helper_check_align(addr, 3);
2277 3391c818 blueswir1
    switch (asi) {
2278 3391c818 blueswir1
    case 0xf0: // Block load primary
2279 3391c818 blueswir1
    case 0xf1: // Block load secondary
2280 3391c818 blueswir1
    case 0xf8: // Block load primary LE
2281 3391c818 blueswir1
    case 0xf9: // Block load secondary LE
2282 51996525 blueswir1
        if (rd & 7) {
2283 51996525 blueswir1
            raise_exception(TT_ILL_INSN);
2284 51996525 blueswir1
            return;
2285 51996525 blueswir1
        }
2286 c2bc0e38 blueswir1
        helper_check_align(addr, 0x3f);
2287 51996525 blueswir1
        for (i = 0; i < 16; i++) {
2288 77f193da blueswir1
            *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4,
2289 77f193da blueswir1
                                                         0);
2290 1a2fb1c0 blueswir1
            addr += 4;
2291 3391c818 blueswir1
        }
2292 3391c818 blueswir1
2293 3391c818 blueswir1
        return;
2294 3391c818 blueswir1
    default:
2295 3391c818 blueswir1
        break;
2296 3391c818 blueswir1
    }
2297 3391c818 blueswir1
2298 1a2fb1c0 blueswir1
    val = helper_ld_asi(addr, asi, size, 0);
2299 3391c818 blueswir1
    switch(size) {
2300 3391c818 blueswir1
    default:
2301 3391c818 blueswir1
    case 4:
2302 714547bb blueswir1
        *((uint32_t *)&env->fpr[rd]) = val;
2303 3391c818 blueswir1
        break;
2304 3391c818 blueswir1
    case 8:
2305 1a2fb1c0 blueswir1
        *((int64_t *)&DT0) = val;
2306 3391c818 blueswir1
        break;
2307 1f587329 blueswir1
    case 16:
2308 1f587329 blueswir1
        // XXX
2309 1f587329 blueswir1
        break;
2310 3391c818 blueswir1
    }
2311 3391c818 blueswir1
}
2312 3391c818 blueswir1
2313 1a2fb1c0 blueswir1
void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
2314 3391c818 blueswir1
{
2315 3391c818 blueswir1
    unsigned int i;
2316 1a2fb1c0 blueswir1
    target_ulong val = 0;
2317 3391c818 blueswir1
2318 c2bc0e38 blueswir1
    helper_check_align(addr, 3);
2319 3391c818 blueswir1
    switch (asi) {
2320 c99657d3 blueswir1
    case 0xe0: // UA2007 Block commit store primary (cache flush)
2321 c99657d3 blueswir1
    case 0xe1: // UA2007 Block commit store secondary (cache flush)
2322 3391c818 blueswir1
    case 0xf0: // Block store primary
2323 3391c818 blueswir1
    case 0xf1: // Block store secondary
2324 3391c818 blueswir1
    case 0xf8: // Block store primary LE
2325 3391c818 blueswir1
    case 0xf9: // Block store secondary LE
2326 51996525 blueswir1
        if (rd & 7) {
2327 51996525 blueswir1
            raise_exception(TT_ILL_INSN);
2328 51996525 blueswir1
            return;
2329 51996525 blueswir1
        }
2330 c2bc0e38 blueswir1
        helper_check_align(addr, 0x3f);
2331 51996525 blueswir1
        for (i = 0; i < 16; i++) {
2332 1a2fb1c0 blueswir1
            val = *(uint32_t *)&env->fpr[rd++];
2333 1a2fb1c0 blueswir1
            helper_st_asi(addr, val, asi & 0x8f, 4);
2334 1a2fb1c0 blueswir1
            addr += 4;
2335 3391c818 blueswir1
        }
2336 3391c818 blueswir1
2337 3391c818 blueswir1
        return;
2338 3391c818 blueswir1
    default:
2339 3391c818 blueswir1
        break;
2340 3391c818 blueswir1
    }
2341 3391c818 blueswir1
2342 3391c818 blueswir1
    switch(size) {
2343 3391c818 blueswir1
    default:
2344 3391c818 blueswir1
    case 4:
2345 714547bb blueswir1
        val = *((uint32_t *)&env->fpr[rd]);
2346 3391c818 blueswir1
        break;
2347 3391c818 blueswir1
    case 8:
2348 1a2fb1c0 blueswir1
        val = *((int64_t *)&DT0);
2349 3391c818 blueswir1
        break;
2350 1f587329 blueswir1
    case 16:
2351 1f587329 blueswir1
        // XXX
2352 1f587329 blueswir1
        break;
2353 3391c818 blueswir1
    }
2354 1a2fb1c0 blueswir1
    helper_st_asi(addr, val, asi, size);
2355 1a2fb1c0 blueswir1
}
2356 1a2fb1c0 blueswir1
2357 1a2fb1c0 blueswir1
target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
2358 1a2fb1c0 blueswir1
                            target_ulong val2, uint32_t asi)
2359 1a2fb1c0 blueswir1
{
2360 1a2fb1c0 blueswir1
    target_ulong ret;
2361 1a2fb1c0 blueswir1
2362 1121f879 blueswir1
    val2 &= 0xffffffffUL;
2363 1a2fb1c0 blueswir1
    ret = helper_ld_asi(addr, asi, 4, 0);
2364 1a2fb1c0 blueswir1
    ret &= 0xffffffffUL;
2365 1121f879 blueswir1
    if (val2 == ret)
2366 1121f879 blueswir1
        helper_st_asi(addr, val1 & 0xffffffffUL, asi, 4);
2367 1a2fb1c0 blueswir1
    return ret;
2368 3391c818 blueswir1
}
2369 3391c818 blueswir1
2370 1a2fb1c0 blueswir1
target_ulong helper_casx_asi(target_ulong addr, target_ulong val1,
2371 1a2fb1c0 blueswir1
                             target_ulong val2, uint32_t asi)
2372 1a2fb1c0 blueswir1
{
2373 1a2fb1c0 blueswir1
    target_ulong ret;
2374 1a2fb1c0 blueswir1
2375 1a2fb1c0 blueswir1
    ret = helper_ld_asi(addr, asi, 8, 0);
2376 1121f879 blueswir1
    if (val2 == ret)
2377 1121f879 blueswir1
        helper_st_asi(addr, val1, asi, 8);
2378 1a2fb1c0 blueswir1
    return ret;
2379 1a2fb1c0 blueswir1
}
2380 81ad8ba2 blueswir1
#endif /* TARGET_SPARC64 */
2381 3475187d bellard
2382 3475187d bellard
#ifndef TARGET_SPARC64
2383 1a2fb1c0 blueswir1
void helper_rett(void)
2384 e8af50a3 bellard
{
2385 af7bf89b bellard
    unsigned int cwp;
2386 af7bf89b bellard
2387 d4218d99 blueswir1
    if (env->psret == 1)
2388 d4218d99 blueswir1
        raise_exception(TT_ILL_INSN);
2389 d4218d99 blueswir1
2390 e8af50a3 bellard
    env->psret = 1;
2391 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1) ;
2392 e8af50a3 bellard
    if (env->wim & (1 << cwp)) {
2393 e8af50a3 bellard
        raise_exception(TT_WIN_UNF);
2394 e8af50a3 bellard
    }
2395 e8af50a3 bellard
    set_cwp(cwp);
2396 e8af50a3 bellard
    env->psrs = env->psrps;
2397 e8af50a3 bellard
}
2398 3475187d bellard
#endif
2399 e8af50a3 bellard
2400 3b89f26c blueswir1
target_ulong helper_udiv(target_ulong a, target_ulong b)
2401 3b89f26c blueswir1
{
2402 3b89f26c blueswir1
    uint64_t x0;
2403 3b89f26c blueswir1
    uint32_t x1;
2404 3b89f26c blueswir1
2405 7621a90d blueswir1
    x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
2406 3b89f26c blueswir1
    x1 = b;
2407 3b89f26c blueswir1
2408 3b89f26c blueswir1
    if (x1 == 0) {
2409 3b89f26c blueswir1
        raise_exception(TT_DIV_ZERO);
2410 3b89f26c blueswir1
    }
2411 3b89f26c blueswir1
2412 3b89f26c blueswir1
    x0 = x0 / x1;
2413 3b89f26c blueswir1
    if (x0 > 0xffffffff) {
2414 3b89f26c blueswir1
        env->cc_src2 = 1;
2415 3b89f26c blueswir1
        return 0xffffffff;
2416 3b89f26c blueswir1
    } else {
2417 3b89f26c blueswir1
        env->cc_src2 = 0;
2418 3b89f26c blueswir1
        return x0;
2419 3b89f26c blueswir1
    }
2420 3b89f26c blueswir1
}
2421 3b89f26c blueswir1
2422 3b89f26c blueswir1
target_ulong helper_sdiv(target_ulong a, target_ulong b)
2423 3b89f26c blueswir1
{
2424 3b89f26c blueswir1
    int64_t x0;
2425 3b89f26c blueswir1
    int32_t x1;
2426 3b89f26c blueswir1
2427 7621a90d blueswir1
    x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
2428 3b89f26c blueswir1
    x1 = b;
2429 3b89f26c blueswir1
2430 3b89f26c blueswir1
    if (x1 == 0) {
2431 3b89f26c blueswir1
        raise_exception(TT_DIV_ZERO);
2432 3b89f26c blueswir1
    }
2433 3b89f26c blueswir1
2434 3b89f26c blueswir1
    x0 = x0 / x1;
2435 3b89f26c blueswir1
    if ((int32_t) x0 != x0) {
2436 3b89f26c blueswir1
        env->cc_src2 = 1;
2437 3b89f26c blueswir1
        return x0 < 0? 0x80000000: 0x7fffffff;
2438 3b89f26c blueswir1
    } else {
2439 3b89f26c blueswir1
        env->cc_src2 = 0;
2440 3b89f26c blueswir1
        return x0;
2441 3b89f26c blueswir1
    }
2442 3b89f26c blueswir1
}
2443 3b89f26c blueswir1
2444 7fa76c0b blueswir1
void helper_stdf(target_ulong addr, int mem_idx)
2445 7fa76c0b blueswir1
{
2446 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2447 7fa76c0b blueswir1
#if !defined(CONFIG_USER_ONLY)
2448 7fa76c0b blueswir1
    switch (mem_idx) {
2449 7fa76c0b blueswir1
    case 0:
2450 c2bc0e38 blueswir1
        stfq_user(addr, DT0);
2451 7fa76c0b blueswir1
        break;
2452 7fa76c0b blueswir1
    case 1:
2453 c2bc0e38 blueswir1
        stfq_kernel(addr, DT0);
2454 7fa76c0b blueswir1
        break;
2455 7fa76c0b blueswir1
#ifdef TARGET_SPARC64
2456 7fa76c0b blueswir1
    case 2:
2457 c2bc0e38 blueswir1
        stfq_hypv(addr, DT0);
2458 7fa76c0b blueswir1
        break;
2459 7fa76c0b blueswir1
#endif
2460 7fa76c0b blueswir1
    default:
2461 7fa76c0b blueswir1
        break;
2462 7fa76c0b blueswir1
    }
2463 7fa76c0b blueswir1
#else
2464 2cade6a3 blueswir1
    address_mask(env, &addr);
2465 c2bc0e38 blueswir1
    stfq_raw(addr, DT0);
2466 7fa76c0b blueswir1
#endif
2467 7fa76c0b blueswir1
}
2468 7fa76c0b blueswir1
2469 7fa76c0b blueswir1
void helper_lddf(target_ulong addr, int mem_idx)
2470 7fa76c0b blueswir1
{
2471 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2472 7fa76c0b blueswir1
#if !defined(CONFIG_USER_ONLY)
2473 7fa76c0b blueswir1
    switch (mem_idx) {
2474 7fa76c0b blueswir1
    case 0:
2475 c2bc0e38 blueswir1
        DT0 = ldfq_user(addr);
2476 7fa76c0b blueswir1
        break;
2477 7fa76c0b blueswir1
    case 1:
2478 c2bc0e38 blueswir1
        DT0 = ldfq_kernel(addr);
2479 7fa76c0b blueswir1
        break;
2480 7fa76c0b blueswir1
#ifdef TARGET_SPARC64
2481 7fa76c0b blueswir1
    case 2:
2482 c2bc0e38 blueswir1
        DT0 = ldfq_hypv(addr);
2483 7fa76c0b blueswir1
        break;
2484 7fa76c0b blueswir1
#endif
2485 7fa76c0b blueswir1
    default:
2486 7fa76c0b blueswir1
        break;
2487 7fa76c0b blueswir1
    }
2488 7fa76c0b blueswir1
#else
2489 2cade6a3 blueswir1
    address_mask(env, &addr);
2490 c2bc0e38 blueswir1
    DT0 = ldfq_raw(addr);
2491 7fa76c0b blueswir1
#endif
2492 7fa76c0b blueswir1
}
2493 7fa76c0b blueswir1
2494 64a88d5d blueswir1
void helper_ldqf(target_ulong addr, int mem_idx)
2495 7fa76c0b blueswir1
{
2496 7fa76c0b blueswir1
    // XXX add 128 bit load
2497 7fa76c0b blueswir1
    CPU_QuadU u;
2498 7fa76c0b blueswir1
2499 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2500 64a88d5d blueswir1
#if !defined(CONFIG_USER_ONLY)
2501 64a88d5d blueswir1
    switch (mem_idx) {
2502 64a88d5d blueswir1
    case 0:
2503 c2bc0e38 blueswir1
        u.ll.upper = ldq_user(addr);
2504 c2bc0e38 blueswir1
        u.ll.lower = ldq_user(addr + 8);
2505 64a88d5d blueswir1
        QT0 = u.q;
2506 64a88d5d blueswir1
        break;
2507 64a88d5d blueswir1
    case 1:
2508 c2bc0e38 blueswir1
        u.ll.upper = ldq_kernel(addr);
2509 c2bc0e38 blueswir1
        u.ll.lower = ldq_kernel(addr + 8);
2510 64a88d5d blueswir1
        QT0 = u.q;
2511 64a88d5d blueswir1
        break;
2512 64a88d5d blueswir1
#ifdef TARGET_SPARC64
2513 64a88d5d blueswir1
    case 2:
2514 c2bc0e38 blueswir1
        u.ll.upper = ldq_hypv(addr);
2515 c2bc0e38 blueswir1
        u.ll.lower = ldq_hypv(addr + 8);
2516 64a88d5d blueswir1
        QT0 = u.q;
2517 64a88d5d blueswir1
        break;
2518 64a88d5d blueswir1
#endif
2519 64a88d5d blueswir1
    default:
2520 64a88d5d blueswir1
        break;
2521 64a88d5d blueswir1
    }
2522 64a88d5d blueswir1
#else
2523 2cade6a3 blueswir1
    address_mask(env, &addr);
2524 c2bc0e38 blueswir1
    u.ll.upper = ldq_raw(addr);
2525 c2bc0e38 blueswir1
    u.ll.lower = ldq_raw((addr + 8) & 0xffffffffULL);
2526 7fa76c0b blueswir1
    QT0 = u.q;
2527 64a88d5d blueswir1
#endif
2528 7fa76c0b blueswir1
}
2529 7fa76c0b blueswir1
2530 64a88d5d blueswir1
void helper_stqf(target_ulong addr, int mem_idx)
2531 7fa76c0b blueswir1
{
2532 7fa76c0b blueswir1
    // XXX add 128 bit store
2533 7fa76c0b blueswir1
    CPU_QuadU u;
2534 7fa76c0b blueswir1
2535 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2536 64a88d5d blueswir1
#if !defined(CONFIG_USER_ONLY)
2537 64a88d5d blueswir1
    switch (mem_idx) {
2538 64a88d5d blueswir1
    case 0:
2539 64a88d5d blueswir1
        u.q = QT0;
2540 c2bc0e38 blueswir1
        stq_user(addr, u.ll.upper);
2541 c2bc0e38 blueswir1
        stq_user(addr + 8, u.ll.lower);
2542 64a88d5d blueswir1
        break;
2543 64a88d5d blueswir1
    case 1:
2544 64a88d5d blueswir1
        u.q = QT0;
2545 c2bc0e38 blueswir1
        stq_kernel(addr, u.ll.upper);
2546 c2bc0e38 blueswir1
        stq_kernel(addr + 8, u.ll.lower);
2547 64a88d5d blueswir1
        break;
2548 64a88d5d blueswir1
#ifdef TARGET_SPARC64
2549 64a88d5d blueswir1
    case 2:
2550 64a88d5d blueswir1
        u.q = QT0;
2551 c2bc0e38 blueswir1
        stq_hypv(addr, u.ll.upper);
2552 c2bc0e38 blueswir1
        stq_hypv(addr + 8, u.ll.lower);
2553 64a88d5d blueswir1
        break;
2554 64a88d5d blueswir1
#endif
2555 64a88d5d blueswir1
    default:
2556 64a88d5d blueswir1
        break;
2557 64a88d5d blueswir1
    }
2558 64a88d5d blueswir1
#else
2559 7fa76c0b blueswir1
    u.q = QT0;
2560 2cade6a3 blueswir1
    address_mask(env, &addr);
2561 c2bc0e38 blueswir1
    stq_raw(addr, u.ll.upper);
2562 c2bc0e38 blueswir1
    stq_raw((addr + 8) & 0xffffffffULL, u.ll.lower);
2563 7fa76c0b blueswir1
#endif
2564 64a88d5d blueswir1
}
2565 7fa76c0b blueswir1
2566 3a3b925d blueswir1
static inline void set_fsr(void)
2567 e8af50a3 bellard
{
2568 7a0e1f41 bellard
    int rnd_mode;
2569 bb5529bb blueswir1
2570 e8af50a3 bellard
    switch (env->fsr & FSR_RD_MASK) {
2571 e8af50a3 bellard
    case FSR_RD_NEAREST:
2572 7a0e1f41 bellard
        rnd_mode = float_round_nearest_even;
2573 0f8a249a blueswir1
        break;
2574 ed910241 bellard
    default:
2575 e8af50a3 bellard
    case FSR_RD_ZERO:
2576 7a0e1f41 bellard
        rnd_mode = float_round_to_zero;
2577 0f8a249a blueswir1
        break;
2578 e8af50a3 bellard
    case FSR_RD_POS:
2579 7a0e1f41 bellard
        rnd_mode = float_round_up;
2580 0f8a249a blueswir1
        break;
2581 e8af50a3 bellard
    case FSR_RD_NEG:
2582 7a0e1f41 bellard
        rnd_mode = float_round_down;
2583 0f8a249a blueswir1
        break;
2584 e8af50a3 bellard
    }
2585 7a0e1f41 bellard
    set_float_rounding_mode(rnd_mode, &env->fp_status);
2586 e8af50a3 bellard
}
2587 e80cfcfc bellard
2588 3a3b925d blueswir1
void helper_ldfsr(uint32_t new_fsr)
2589 bb5529bb blueswir1
{
2590 3a3b925d blueswir1
    env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK);
2591 3a3b925d blueswir1
    set_fsr();
2592 bb5529bb blueswir1
}
2593 bb5529bb blueswir1
2594 3a3b925d blueswir1
#ifdef TARGET_SPARC64
2595 3a3b925d blueswir1
void helper_ldxfsr(uint64_t new_fsr)
2596 3a3b925d blueswir1
{
2597 3a3b925d blueswir1
    env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK);
2598 3a3b925d blueswir1
    set_fsr();
2599 3a3b925d blueswir1
}
2600 3a3b925d blueswir1
#endif
2601 3a3b925d blueswir1
2602 bb5529bb blueswir1
void helper_debug(void)
2603 e80cfcfc bellard
{
2604 e80cfcfc bellard
    env->exception_index = EXCP_DEBUG;
2605 e80cfcfc bellard
    cpu_loop_exit();
2606 e80cfcfc bellard
}
2607 af7bf89b bellard
2608 3475187d bellard
#ifndef TARGET_SPARC64
2609 72a9747b blueswir1
/* XXX: use another pointer for %iN registers to avoid slow wrapping
2610 72a9747b blueswir1
   handling ? */
2611 72a9747b blueswir1
void helper_save(void)
2612 72a9747b blueswir1
{
2613 72a9747b blueswir1
    uint32_t cwp;
2614 72a9747b blueswir1
2615 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2616 72a9747b blueswir1
    if (env->wim & (1 << cwp)) {
2617 72a9747b blueswir1
        raise_exception(TT_WIN_OVF);
2618 72a9747b blueswir1
    }
2619 72a9747b blueswir1
    set_cwp(cwp);
2620 72a9747b blueswir1
}
2621 72a9747b blueswir1
2622 72a9747b blueswir1
void helper_restore(void)
2623 72a9747b blueswir1
{
2624 72a9747b blueswir1
    uint32_t cwp;
2625 72a9747b blueswir1
2626 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1);
2627 72a9747b blueswir1
    if (env->wim & (1 << cwp)) {
2628 72a9747b blueswir1
        raise_exception(TT_WIN_UNF);
2629 72a9747b blueswir1
    }
2630 72a9747b blueswir1
    set_cwp(cwp);
2631 72a9747b blueswir1
}
2632 72a9747b blueswir1
2633 1a2fb1c0 blueswir1
void helper_wrpsr(target_ulong new_psr)
2634 af7bf89b bellard
{
2635 1a14026e blueswir1
    if ((new_psr & PSR_CWP) >= env->nwindows)
2636 d4218d99 blueswir1
        raise_exception(TT_ILL_INSN);
2637 d4218d99 blueswir1
    else
2638 1a2fb1c0 blueswir1
        PUT_PSR(env, new_psr);
2639 af7bf89b bellard
}
2640 af7bf89b bellard
2641 1a2fb1c0 blueswir1
target_ulong helper_rdpsr(void)
2642 af7bf89b bellard
{
2643 1a2fb1c0 blueswir1
    return GET_PSR(env);
2644 af7bf89b bellard
}
2645 3475187d bellard
2646 3475187d bellard
#else
2647 72a9747b blueswir1
/* XXX: use another pointer for %iN registers to avoid slow wrapping
2648 72a9747b blueswir1
   handling ? */
2649 72a9747b blueswir1
void helper_save(void)
2650 72a9747b blueswir1
{
2651 72a9747b blueswir1
    uint32_t cwp;
2652 72a9747b blueswir1
2653 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2654 72a9747b blueswir1
    if (env->cansave == 0) {
2655 72a9747b blueswir1
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
2656 72a9747b blueswir1
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2657 72a9747b blueswir1
                                    ((env->wstate & 0x7) << 2)));
2658 72a9747b blueswir1
    } else {
2659 72a9747b blueswir1
        if (env->cleanwin - env->canrestore == 0) {
2660 72a9747b blueswir1
            // XXX Clean windows without trap
2661 72a9747b blueswir1
            raise_exception(TT_CLRWIN);
2662 72a9747b blueswir1
        } else {
2663 72a9747b blueswir1
            env->cansave--;
2664 72a9747b blueswir1
            env->canrestore++;
2665 72a9747b blueswir1
            set_cwp(cwp);
2666 72a9747b blueswir1
        }
2667 72a9747b blueswir1
    }
2668 72a9747b blueswir1
}
2669 72a9747b blueswir1
2670 72a9747b blueswir1
void helper_restore(void)
2671 72a9747b blueswir1
{
2672 72a9747b blueswir1
    uint32_t cwp;
2673 72a9747b blueswir1
2674 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1);
2675 72a9747b blueswir1
    if (env->canrestore == 0) {
2676 72a9747b blueswir1
        raise_exception(TT_FILL | (env->otherwin != 0 ?
2677 72a9747b blueswir1
                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2678 72a9747b blueswir1
                                   ((env->wstate & 0x7) << 2)));
2679 72a9747b blueswir1
    } else {
2680 72a9747b blueswir1
        env->cansave++;
2681 72a9747b blueswir1
        env->canrestore--;
2682 72a9747b blueswir1
        set_cwp(cwp);
2683 72a9747b blueswir1
    }
2684 72a9747b blueswir1
}
2685 72a9747b blueswir1
2686 72a9747b blueswir1
void helper_flushw(void)
2687 72a9747b blueswir1
{
2688 1a14026e blueswir1
    if (env->cansave != env->nwindows - 2) {
2689 72a9747b blueswir1
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
2690 72a9747b blueswir1
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2691 72a9747b blueswir1
                                    ((env->wstate & 0x7) << 2)));
2692 72a9747b blueswir1
    }
2693 72a9747b blueswir1
}
2694 72a9747b blueswir1
2695 72a9747b blueswir1
void helper_saved(void)
2696 72a9747b blueswir1
{
2697 72a9747b blueswir1
    env->cansave++;
2698 72a9747b blueswir1
    if (env->otherwin == 0)
2699 72a9747b blueswir1
        env->canrestore--;
2700 72a9747b blueswir1
    else
2701 72a9747b blueswir1
        env->otherwin--;
2702 72a9747b blueswir1
}
2703 72a9747b blueswir1
2704 72a9747b blueswir1
void helper_restored(void)
2705 72a9747b blueswir1
{
2706 72a9747b blueswir1
    env->canrestore++;
2707 1a14026e blueswir1
    if (env->cleanwin < env->nwindows - 1)
2708 72a9747b blueswir1
        env->cleanwin++;
2709 72a9747b blueswir1
    if (env->otherwin == 0)
2710 72a9747b blueswir1
        env->cansave--;
2711 72a9747b blueswir1
    else
2712 72a9747b blueswir1
        env->otherwin--;
2713 72a9747b blueswir1
}
2714 72a9747b blueswir1
2715 d35527d9 blueswir1
target_ulong helper_rdccr(void)
2716 d35527d9 blueswir1
{
2717 d35527d9 blueswir1
    return GET_CCR(env);
2718 d35527d9 blueswir1
}
2719 d35527d9 blueswir1
2720 d35527d9 blueswir1
void helper_wrccr(target_ulong new_ccr)
2721 d35527d9 blueswir1
{
2722 d35527d9 blueswir1
    PUT_CCR(env, new_ccr);
2723 d35527d9 blueswir1
}
2724 d35527d9 blueswir1
2725 d35527d9 blueswir1
// CWP handling is reversed in V9, but we still use the V8 register
2726 d35527d9 blueswir1
// order.
2727 d35527d9 blueswir1
target_ulong helper_rdcwp(void)
2728 d35527d9 blueswir1
{
2729 d35527d9 blueswir1
    return GET_CWP64(env);
2730 d35527d9 blueswir1
}
2731 d35527d9 blueswir1
2732 d35527d9 blueswir1
void helper_wrcwp(target_ulong new_cwp)
2733 d35527d9 blueswir1
{
2734 d35527d9 blueswir1
    PUT_CWP64(env, new_cwp);
2735 d35527d9 blueswir1
}
2736 3475187d bellard
2737 1f5063fb blueswir1
// This function uses non-native bit order
2738 1f5063fb blueswir1
#define GET_FIELD(X, FROM, TO)                                  \
2739 1f5063fb blueswir1
    ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
2740 1f5063fb blueswir1
2741 1f5063fb blueswir1
// This function uses the order in the manuals, i.e. bit 0 is 2^0
2742 1f5063fb blueswir1
#define GET_FIELD_SP(X, FROM, TO)               \
2743 1f5063fb blueswir1
    GET_FIELD(X, 63 - (TO), 63 - (FROM))
2744 1f5063fb blueswir1
2745 1f5063fb blueswir1
target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
2746 1f5063fb blueswir1
{
2747 1f5063fb blueswir1
    return (GET_FIELD_SP(pixel_addr, 60, 63) << (17 + 2 * cubesize)) |
2748 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 39, 39 + cubesize - 1) << (17 + cubesize)) |
2749 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 17 + cubesize - 1, 17) << 17) |
2750 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 56, 59) << 13) |
2751 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 35, 38) << 9) |
2752 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 13, 16) << 5) |
2753 1f5063fb blueswir1
        (((pixel_addr >> 55) & 1) << 4) |
2754 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 33, 34) << 2) |
2755 1f5063fb blueswir1
        GET_FIELD_SP(pixel_addr, 11, 12);
2756 1f5063fb blueswir1
}
2757 1f5063fb blueswir1
2758 1f5063fb blueswir1
target_ulong helper_alignaddr(target_ulong addr, target_ulong offset)
2759 1f5063fb blueswir1
{
2760 1f5063fb blueswir1
    uint64_t tmp;
2761 1f5063fb blueswir1
2762 1f5063fb blueswir1
    tmp = addr + offset;
2763 1f5063fb blueswir1
    env->gsr &= ~7ULL;
2764 1f5063fb blueswir1
    env->gsr |= tmp & 7ULL;
2765 1f5063fb blueswir1
    return tmp & ~7ULL;
2766 1f5063fb blueswir1
}
2767 1f5063fb blueswir1
2768 1a2fb1c0 blueswir1
target_ulong helper_popc(target_ulong val)
2769 3475187d bellard
{
2770 1a2fb1c0 blueswir1
    return ctpop64(val);
2771 3475187d bellard
}
2772 83469015 bellard
2773 83469015 bellard
static inline uint64_t *get_gregset(uint64_t pstate)
2774 83469015 bellard
{
2775 83469015 bellard
    switch (pstate) {
2776 83469015 bellard
    default:
2777 83469015 bellard
    case 0:
2778 0f8a249a blueswir1
        return env->bgregs;
2779 83469015 bellard
    case PS_AG:
2780 0f8a249a blueswir1
        return env->agregs;
2781 83469015 bellard
    case PS_MG:
2782 0f8a249a blueswir1
        return env->mgregs;
2783 83469015 bellard
    case PS_IG:
2784 0f8a249a blueswir1
        return env->igregs;
2785 83469015 bellard
    }
2786 83469015 bellard
}
2787 83469015 bellard
2788 91736d37 blueswir1
static inline void change_pstate(uint64_t new_pstate)
2789 83469015 bellard
{
2790 8f1f22f6 blueswir1
    uint64_t pstate_regs, new_pstate_regs;
2791 83469015 bellard
    uint64_t *src, *dst;
2792 83469015 bellard
2793 83469015 bellard
    pstate_regs = env->pstate & 0xc01;
2794 83469015 bellard
    new_pstate_regs = new_pstate & 0xc01;
2795 83469015 bellard
    if (new_pstate_regs != pstate_regs) {
2796 0f8a249a blueswir1
        // Switch global register bank
2797 0f8a249a blueswir1
        src = get_gregset(new_pstate_regs);
2798 0f8a249a blueswir1
        dst = get_gregset(pstate_regs);
2799 0f8a249a blueswir1
        memcpy32(dst, env->gregs);
2800 0f8a249a blueswir1
        memcpy32(env->gregs, src);
2801 83469015 bellard
    }
2802 83469015 bellard
    env->pstate = new_pstate;
2803 83469015 bellard
}
2804 83469015 bellard
2805 1a2fb1c0 blueswir1
void helper_wrpstate(target_ulong new_state)
2806 8f1f22f6 blueswir1
{
2807 5578ceab blueswir1
    if (!(env->def->features & CPU_FEATURE_GL))
2808 fb79ceb9 blueswir1
        change_pstate(new_state & 0xf3f);
2809 8f1f22f6 blueswir1
}
2810 8f1f22f6 blueswir1
2811 1a2fb1c0 blueswir1
void helper_done(void)
2812 83469015 bellard
{
2813 375ee38b blueswir1
    env->pc = env->tsptr->tpc;
2814 375ee38b blueswir1
    env->npc = env->tsptr->tnpc + 4;
2815 375ee38b blueswir1
    PUT_CCR(env, env->tsptr->tstate >> 32);
2816 375ee38b blueswir1
    env->asi = (env->tsptr->tstate >> 24) & 0xff;
2817 375ee38b blueswir1
    change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
2818 375ee38b blueswir1
    PUT_CWP64(env, env->tsptr->tstate & 0xff);
2819 e6bf7d70 blueswir1
    env->tl--;
2820 c19148bd blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
2821 83469015 bellard
}
2822 83469015 bellard
2823 1a2fb1c0 blueswir1
void helper_retry(void)
2824 83469015 bellard
{
2825 375ee38b blueswir1
    env->pc = env->tsptr->tpc;
2826 375ee38b blueswir1
    env->npc = env->tsptr->tnpc;
2827 375ee38b blueswir1
    PUT_CCR(env, env->tsptr->tstate >> 32);
2828 375ee38b blueswir1
    env->asi = (env->tsptr->tstate >> 24) & 0xff;
2829 375ee38b blueswir1
    change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
2830 375ee38b blueswir1
    PUT_CWP64(env, env->tsptr->tstate & 0xff);
2831 e6bf7d70 blueswir1
    env->tl--;
2832 c19148bd blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
2833 83469015 bellard
}
2834 9d926598 blueswir1
2835 9d926598 blueswir1
void helper_set_softint(uint64_t value)
2836 9d926598 blueswir1
{
2837 9d926598 blueswir1
    env->softint |= (uint32_t)value;
2838 9d926598 blueswir1
}
2839 9d926598 blueswir1
2840 9d926598 blueswir1
void helper_clear_softint(uint64_t value)
2841 9d926598 blueswir1
{
2842 9d926598 blueswir1
    env->softint &= (uint32_t)~value;
2843 9d926598 blueswir1
}
2844 9d926598 blueswir1
2845 9d926598 blueswir1
void helper_write_softint(uint64_t value)
2846 9d926598 blueswir1
{
2847 9d926598 blueswir1
    env->softint = (uint32_t)value;
2848 9d926598 blueswir1
}
2849 3475187d bellard
#endif
2850 ee5bbe38 bellard
2851 91736d37 blueswir1
void helper_flush(target_ulong addr)
2852 ee5bbe38 bellard
{
2853 91736d37 blueswir1
    addr &= ~7;
2854 91736d37 blueswir1
    tb_invalidate_page_range(addr, addr + 8);
2855 ee5bbe38 bellard
}
2856 ee5bbe38 bellard
2857 91736d37 blueswir1
#ifdef TARGET_SPARC64
2858 91736d37 blueswir1
#ifdef DEBUG_PCALL
2859 91736d37 blueswir1
static const char * const excp_names[0x80] = {
2860 91736d37 blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
2861 91736d37 blueswir1
    [TT_TMISS] = "Instruction Access MMU Miss",
2862 91736d37 blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
2863 91736d37 blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
2864 91736d37 blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
2865 91736d37 blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
2866 91736d37 blueswir1
    [TT_FP_EXCP] = "FPU Exception",
2867 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
2868 91736d37 blueswir1
    [TT_CLRWIN] = "Clean Windows",
2869 91736d37 blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
2870 91736d37 blueswir1
    [TT_DFAULT] = "Data Access Fault",
2871 91736d37 blueswir1
    [TT_DMISS] = "Data Access MMU Miss",
2872 91736d37 blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
2873 91736d37 blueswir1
    [TT_DPROT] = "Data Protection Error",
2874 91736d37 blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
2875 91736d37 blueswir1
    [TT_PRIV_ACT] = "Privileged Action",
2876 91736d37 blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
2877 91736d37 blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
2878 91736d37 blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
2879 91736d37 blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
2880 91736d37 blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
2881 91736d37 blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
2882 91736d37 blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
2883 91736d37 blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
2884 91736d37 blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
2885 91736d37 blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
2886 91736d37 blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
2887 91736d37 blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
2888 91736d37 blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
2889 91736d37 blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
2890 91736d37 blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
2891 91736d37 blueswir1
};
2892 91736d37 blueswir1
#endif
2893 91736d37 blueswir1
2894 91736d37 blueswir1
void do_interrupt(CPUState *env)
2895 91736d37 blueswir1
{
2896 91736d37 blueswir1
    int intno = env->exception_index;
2897 91736d37 blueswir1
2898 91736d37 blueswir1
#ifdef DEBUG_PCALL
2899 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
2900 91736d37 blueswir1
        static int count;
2901 91736d37 blueswir1
        const char *name;
2902 91736d37 blueswir1
2903 91736d37 blueswir1
        if (intno < 0 || intno >= 0x180)
2904 91736d37 blueswir1
            name = "Unknown";
2905 91736d37 blueswir1
        else if (intno >= 0x100)
2906 91736d37 blueswir1
            name = "Trap Instruction";
2907 91736d37 blueswir1
        else if (intno >= 0xc0)
2908 91736d37 blueswir1
            name = "Window Fill";
2909 91736d37 blueswir1
        else if (intno >= 0x80)
2910 91736d37 blueswir1
            name = "Window Spill";
2911 91736d37 blueswir1
        else {
2912 91736d37 blueswir1
            name = excp_names[intno];
2913 91736d37 blueswir1
            if (!name)
2914 91736d37 blueswir1
                name = "Unknown";
2915 91736d37 blueswir1
        }
2916 91736d37 blueswir1
2917 93fcfe39 aliguori
        qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
2918 91736d37 blueswir1
                " SP=%016" PRIx64 "\n",
2919 91736d37 blueswir1
                count, name, intno,
2920 91736d37 blueswir1
                env->pc,
2921 91736d37 blueswir1
                env->npc, env->regwptr[6]);
2922 93fcfe39 aliguori
        log_cpu_state(env, 0);
2923 91736d37 blueswir1
#if 0
2924 91736d37 blueswir1
        {
2925 91736d37 blueswir1
            int i;
2926 91736d37 blueswir1
            uint8_t *ptr;
2927 91736d37 blueswir1

2928 93fcfe39 aliguori
            qemu_log("       code=");
2929 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
2930 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
2931 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
2932 91736d37 blueswir1
            }
2933 93fcfe39 aliguori
            qemu_log("\n");
2934 91736d37 blueswir1
        }
2935 91736d37 blueswir1
#endif
2936 91736d37 blueswir1
        count++;
2937 91736d37 blueswir1
    }
2938 91736d37 blueswir1
#endif
2939 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
2940 91736d37 blueswir1
    if (env->tl >= env->maxtl) {
2941 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
2942 91736d37 blueswir1
                  " Error state", env->exception_index, env->tl, env->maxtl);
2943 91736d37 blueswir1
        return;
2944 91736d37 blueswir1
    }
2945 91736d37 blueswir1
#endif
2946 91736d37 blueswir1
    if (env->tl < env->maxtl - 1) {
2947 91736d37 blueswir1
        env->tl++;
2948 91736d37 blueswir1
    } else {
2949 91736d37 blueswir1
        env->pstate |= PS_RED;
2950 91736d37 blueswir1
        if (env->tl < env->maxtl)
2951 91736d37 blueswir1
            env->tl++;
2952 91736d37 blueswir1
    }
2953 91736d37 blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
2954 91736d37 blueswir1
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
2955 91736d37 blueswir1
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
2956 91736d37 blueswir1
        GET_CWP64(env);
2957 91736d37 blueswir1
    env->tsptr->tpc = env->pc;
2958 91736d37 blueswir1
    env->tsptr->tnpc = env->npc;
2959 91736d37 blueswir1
    env->tsptr->tt = intno;
2960 91736d37 blueswir1
    if (!(env->def->features & CPU_FEATURE_GL)) {
2961 91736d37 blueswir1
        switch (intno) {
2962 91736d37 blueswir1
        case TT_IVEC:
2963 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
2964 91736d37 blueswir1
            break;
2965 91736d37 blueswir1
        case TT_TFAULT:
2966 91736d37 blueswir1
        case TT_TMISS:
2967 91736d37 blueswir1
        case TT_DFAULT:
2968 91736d37 blueswir1
        case TT_DMISS:
2969 91736d37 blueswir1
        case TT_DPROT:
2970 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
2971 91736d37 blueswir1
            break;
2972 91736d37 blueswir1
        default:
2973 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
2974 91736d37 blueswir1
            break;
2975 91736d37 blueswir1
        }
2976 91736d37 blueswir1
    }
2977 91736d37 blueswir1
    if (intno == TT_CLRWIN)
2978 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
2979 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_SPILL)
2980 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
2981 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_FILL)
2982 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
2983 91736d37 blueswir1
    env->tbr &= ~0x7fffULL;
2984 91736d37 blueswir1
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
2985 91736d37 blueswir1
    env->pc = env->tbr;
2986 91736d37 blueswir1
    env->npc = env->pc + 4;
2987 91736d37 blueswir1
    env->exception_index = 0;
2988 ee5bbe38 bellard
}
2989 91736d37 blueswir1
#else
2990 91736d37 blueswir1
#ifdef DEBUG_PCALL
2991 91736d37 blueswir1
static const char * const excp_names[0x80] = {
2992 91736d37 blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
2993 91736d37 blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
2994 91736d37 blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
2995 91736d37 blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
2996 91736d37 blueswir1
    [TT_WIN_OVF] = "Window Overflow",
2997 91736d37 blueswir1
    [TT_WIN_UNF] = "Window Underflow",
2998 91736d37 blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
2999 91736d37 blueswir1
    [TT_FP_EXCP] = "FPU Exception",
3000 91736d37 blueswir1
    [TT_DFAULT] = "Data Access Fault",
3001 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3002 91736d37 blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
3003 91736d37 blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
3004 91736d37 blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
3005 91736d37 blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
3006 91736d37 blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
3007 91736d37 blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
3008 91736d37 blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
3009 91736d37 blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
3010 91736d37 blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
3011 91736d37 blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
3012 91736d37 blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
3013 91736d37 blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
3014 91736d37 blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
3015 91736d37 blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
3016 91736d37 blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
3017 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3018 91736d37 blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
3019 91736d37 blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
3020 91736d37 blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
3021 91736d37 blueswir1
    [TT_NCP_INSN] = "Coprocessor Disabled",
3022 91736d37 blueswir1
};
3023 91736d37 blueswir1
#endif
3024 ee5bbe38 bellard
3025 91736d37 blueswir1
void do_interrupt(CPUState *env)
3026 ee5bbe38 bellard
{
3027 91736d37 blueswir1
    int cwp, intno = env->exception_index;
3028 91736d37 blueswir1
3029 91736d37 blueswir1
#ifdef DEBUG_PCALL
3030 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
3031 91736d37 blueswir1
        static int count;
3032 91736d37 blueswir1
        const char *name;
3033 91736d37 blueswir1
3034 91736d37 blueswir1
        if (intno < 0 || intno >= 0x100)
3035 91736d37 blueswir1
            name = "Unknown";
3036 91736d37 blueswir1
        else if (intno >= 0x80)
3037 91736d37 blueswir1
            name = "Trap Instruction";
3038 91736d37 blueswir1
        else {
3039 91736d37 blueswir1
            name = excp_names[intno];
3040 91736d37 blueswir1
            if (!name)
3041 91736d37 blueswir1
                name = "Unknown";
3042 91736d37 blueswir1
        }
3043 91736d37 blueswir1
3044 93fcfe39 aliguori
        qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
3045 91736d37 blueswir1
                count, name, intno,
3046 91736d37 blueswir1
                env->pc,
3047 91736d37 blueswir1
                env->npc, env->regwptr[6]);
3048 93fcfe39 aliguori
        log_cpu_state(env, 0);
3049 91736d37 blueswir1
#if 0
3050 91736d37 blueswir1
        {
3051 91736d37 blueswir1
            int i;
3052 91736d37 blueswir1
            uint8_t *ptr;
3053 91736d37 blueswir1

3054 93fcfe39 aliguori
            qemu_log("       code=");
3055 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3056 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3057 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3058 91736d37 blueswir1
            }
3059 93fcfe39 aliguori
            qemu_log("\n");
3060 91736d37 blueswir1
        }
3061 91736d37 blueswir1
#endif
3062 91736d37 blueswir1
        count++;
3063 91736d37 blueswir1
    }
3064 91736d37 blueswir1
#endif
3065 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3066 91736d37 blueswir1
    if (env->psret == 0) {
3067 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
3068 91736d37 blueswir1
                  env->exception_index);
3069 91736d37 blueswir1
        return;
3070 91736d37 blueswir1
    }
3071 91736d37 blueswir1
#endif
3072 91736d37 blueswir1
    env->psret = 0;
3073 91736d37 blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
3074 91736d37 blueswir1
    cpu_set_cwp(env, cwp);
3075 91736d37 blueswir1
    env->regwptr[9] = env->pc;
3076 91736d37 blueswir1
    env->regwptr[10] = env->npc;
3077 91736d37 blueswir1
    env->psrps = env->psrs;
3078 91736d37 blueswir1
    env->psrs = 1;
3079 91736d37 blueswir1
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
3080 91736d37 blueswir1
    env->pc = env->tbr;
3081 91736d37 blueswir1
    env->npc = env->pc + 4;
3082 91736d37 blueswir1
    env->exception_index = 0;
3083 ee5bbe38 bellard
}
3084 91736d37 blueswir1
#endif
3085 ee5bbe38 bellard
3086 5fafdf24 ths
#if !defined(CONFIG_USER_ONLY)
3087 ee5bbe38 bellard
3088 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3089 d2889a3e blueswir1
                                void *retaddr);
3090 d2889a3e blueswir1
3091 ee5bbe38 bellard
#define MMUSUFFIX _mmu
3092 d2889a3e blueswir1
#define ALIGNED_ONLY
3093 ee5bbe38 bellard
3094 ee5bbe38 bellard
#define SHIFT 0
3095 ee5bbe38 bellard
#include "softmmu_template.h"
3096 ee5bbe38 bellard
3097 ee5bbe38 bellard
#define SHIFT 1
3098 ee5bbe38 bellard
#include "softmmu_template.h"
3099 ee5bbe38 bellard
3100 ee5bbe38 bellard
#define SHIFT 2
3101 ee5bbe38 bellard
#include "softmmu_template.h"
3102 ee5bbe38 bellard
3103 ee5bbe38 bellard
#define SHIFT 3
3104 ee5bbe38 bellard
#include "softmmu_template.h"
3105 ee5bbe38 bellard
3106 c2bc0e38 blueswir1
/* XXX: make it generic ? */
3107 c2bc0e38 blueswir1
static void cpu_restore_state2(void *retaddr)
3108 c2bc0e38 blueswir1
{
3109 c2bc0e38 blueswir1
    TranslationBlock *tb;
3110 c2bc0e38 blueswir1
    unsigned long pc;
3111 c2bc0e38 blueswir1
3112 c2bc0e38 blueswir1
    if (retaddr) {
3113 c2bc0e38 blueswir1
        /* now we have a real cpu fault */
3114 c2bc0e38 blueswir1
        pc = (unsigned long)retaddr;
3115 c2bc0e38 blueswir1
        tb = tb_find_pc(pc);
3116 c2bc0e38 blueswir1
        if (tb) {
3117 c2bc0e38 blueswir1
            /* the PC is inside the translated code. It means that we have
3118 c2bc0e38 blueswir1
               a virtual CPU fault */
3119 c2bc0e38 blueswir1
            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
3120 c2bc0e38 blueswir1
        }
3121 c2bc0e38 blueswir1
    }
3122 c2bc0e38 blueswir1
}
3123 c2bc0e38 blueswir1
3124 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3125 d2889a3e blueswir1
                                void *retaddr)
3126 d2889a3e blueswir1
{
3127 94554550 blueswir1
#ifdef DEBUG_UNALIGNED
3128 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
3129 c2bc0e38 blueswir1
           "\n", addr, env->pc);
3130 94554550 blueswir1
#endif
3131 c2bc0e38 blueswir1
    cpu_restore_state2(retaddr);
3132 94554550 blueswir1
    raise_exception(TT_UNALIGNED);
3133 d2889a3e blueswir1
}
3134 ee5bbe38 bellard
3135 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
3136 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
3137 ee5bbe38 bellard
   from generated code or from helper.c) */
3138 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
3139 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
3140 ee5bbe38 bellard
{
3141 ee5bbe38 bellard
    int ret;
3142 ee5bbe38 bellard
    CPUState *saved_env;
3143 ee5bbe38 bellard
3144 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
3145 ee5bbe38 bellard
       generated code */
3146 ee5bbe38 bellard
    saved_env = env;
3147 ee5bbe38 bellard
    env = cpu_single_env;
3148 ee5bbe38 bellard
3149 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
3150 ee5bbe38 bellard
    if (ret) {
3151 c2bc0e38 blueswir1
        cpu_restore_state2(retaddr);
3152 ee5bbe38 bellard
        cpu_loop_exit();
3153 ee5bbe38 bellard
    }
3154 ee5bbe38 bellard
    env = saved_env;
3155 ee5bbe38 bellard
}
3156 ee5bbe38 bellard
3157 ee5bbe38 bellard
#endif
3158 6c36d3fa blueswir1
3159 6c36d3fa blueswir1
#ifndef TARGET_SPARC64
3160 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3161 e18231a3 blueswir1
                          int is_asi, int size)
3162 6c36d3fa blueswir1
{
3163 6c36d3fa blueswir1
    CPUState *saved_env;
3164 6c36d3fa blueswir1
3165 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3166 6c36d3fa blueswir1
       generated code */
3167 6c36d3fa blueswir1
    saved_env = env;
3168 6c36d3fa blueswir1
    env = cpu_single_env;
3169 8543e2cf blueswir1
#ifdef DEBUG_UNASSIGNED
3170 8543e2cf blueswir1
    if (is_asi)
3171 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3172 77f193da blueswir1
               " asi 0x%02x from " TARGET_FMT_lx "\n",
3173 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3174 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, is_asi, env->pc);
3175 8543e2cf blueswir1
    else
3176 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3177 e18231a3 blueswir1
               " from " TARGET_FMT_lx "\n",
3178 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3179 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, env->pc);
3180 8543e2cf blueswir1
#endif
3181 6c36d3fa blueswir1
    if (env->mmuregs[3]) /* Fault status register */
3182 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
3183 6c36d3fa blueswir1
    if (is_asi)
3184 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 16;
3185 6c36d3fa blueswir1
    if (env->psrs)
3186 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 5;
3187 6c36d3fa blueswir1
    if (is_exec)
3188 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 6;
3189 6c36d3fa blueswir1
    if (is_write)
3190 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 7;
3191 6c36d3fa blueswir1
    env->mmuregs[3] |= (5 << 2) | 2;
3192 6c36d3fa blueswir1
    env->mmuregs[4] = addr; /* Fault address register */
3193 6c36d3fa blueswir1
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
3194 1b2e93c1 blueswir1
        if (is_exec)
3195 1b2e93c1 blueswir1
            raise_exception(TT_CODE_ACCESS);
3196 1b2e93c1 blueswir1
        else
3197 1b2e93c1 blueswir1
            raise_exception(TT_DATA_ACCESS);
3198 6c36d3fa blueswir1
    }
3199 6c36d3fa blueswir1
    env = saved_env;
3200 6c36d3fa blueswir1
}
3201 6c36d3fa blueswir1
#else
3202 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3203 e18231a3 blueswir1
                          int is_asi, int size)
3204 6c36d3fa blueswir1
{
3205 6c36d3fa blueswir1
#ifdef DEBUG_UNASSIGNED
3206 6c36d3fa blueswir1
    CPUState *saved_env;
3207 6c36d3fa blueswir1
3208 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3209 6c36d3fa blueswir1
       generated code */
3210 6c36d3fa blueswir1
    saved_env = env;
3211 6c36d3fa blueswir1
    env = cpu_single_env;
3212 77f193da blueswir1
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
3213 77f193da blueswir1
           "\n", addr, env->pc);
3214 6c36d3fa blueswir1
    env = saved_env;
3215 6c36d3fa blueswir1
#endif
3216 1b2e93c1 blueswir1
    if (is_exec)
3217 1b2e93c1 blueswir1
        raise_exception(TT_CODE_ACCESS);
3218 1b2e93c1 blueswir1
    else
3219 1b2e93c1 blueswir1
        raise_exception(TT_DATA_ACCESS);
3220 6c36d3fa blueswir1
}
3221 6c36d3fa blueswir1
#endif
3222 20c9f095 blueswir1
3223 f4b1a842 blueswir1
#ifdef TARGET_SPARC64
3224 f4b1a842 blueswir1
void helper_tick_set_count(void *opaque, uint64_t count)
3225 f4b1a842 blueswir1
{
3226 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3227 f4b1a842 blueswir1
    cpu_tick_set_count(opaque, count);
3228 f4b1a842 blueswir1
#endif
3229 f4b1a842 blueswir1
}
3230 f4b1a842 blueswir1
3231 f4b1a842 blueswir1
uint64_t helper_tick_get_count(void *opaque)
3232 f4b1a842 blueswir1
{
3233 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3234 f4b1a842 blueswir1
    return cpu_tick_get_count(opaque);
3235 f4b1a842 blueswir1
#else
3236 f4b1a842 blueswir1
    return 0;
3237 f4b1a842 blueswir1
#endif
3238 f4b1a842 blueswir1
}
3239 f4b1a842 blueswir1
3240 f4b1a842 blueswir1
void helper_tick_set_limit(void *opaque, uint64_t limit)
3241 f4b1a842 blueswir1
{
3242 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3243 f4b1a842 blueswir1
    cpu_tick_set_limit(opaque, limit);
3244 f4b1a842 blueswir1
#endif
3245 f4b1a842 blueswir1
}
3246 f4b1a842 blueswir1
#endif