Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 6c78ea32

History | View | Annotate | Download (100.5 kB)

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

3363 93fcfe39 aliguori
            qemu_log("       code=");
3364 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3365 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3366 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3367 91736d37 blueswir1
            }
3368 93fcfe39 aliguori
            qemu_log("\n");
3369 91736d37 blueswir1
        }
3370 91736d37 blueswir1
#endif
3371 91736d37 blueswir1
        count++;
3372 91736d37 blueswir1
    }
3373 91736d37 blueswir1
#endif
3374 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3375 91736d37 blueswir1
    if (env->tl >= env->maxtl) {
3376 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
3377 91736d37 blueswir1
                  " Error state", env->exception_index, env->tl, env->maxtl);
3378 91736d37 blueswir1
        return;
3379 91736d37 blueswir1
    }
3380 91736d37 blueswir1
#endif
3381 91736d37 blueswir1
    if (env->tl < env->maxtl - 1) {
3382 91736d37 blueswir1
        env->tl++;
3383 91736d37 blueswir1
    } else {
3384 91736d37 blueswir1
        env->pstate |= PS_RED;
3385 91736d37 blueswir1
        if (env->tl < env->maxtl)
3386 91736d37 blueswir1
            env->tl++;
3387 91736d37 blueswir1
    }
3388 91736d37 blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
3389 91736d37 blueswir1
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
3390 91736d37 blueswir1
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
3391 91736d37 blueswir1
        GET_CWP64(env);
3392 91736d37 blueswir1
    env->tsptr->tpc = env->pc;
3393 91736d37 blueswir1
    env->tsptr->tnpc = env->npc;
3394 91736d37 blueswir1
    env->tsptr->tt = intno;
3395 91736d37 blueswir1
    if (!(env->def->features & CPU_FEATURE_GL)) {
3396 91736d37 blueswir1
        switch (intno) {
3397 91736d37 blueswir1
        case TT_IVEC:
3398 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
3399 91736d37 blueswir1
            break;
3400 91736d37 blueswir1
        case TT_TFAULT:
3401 91736d37 blueswir1
        case TT_TMISS:
3402 91736d37 blueswir1
        case TT_DFAULT:
3403 91736d37 blueswir1
        case TT_DMISS:
3404 91736d37 blueswir1
        case TT_DPROT:
3405 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
3406 91736d37 blueswir1
            break;
3407 91736d37 blueswir1
        default:
3408 91736d37 blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
3409 91736d37 blueswir1
            break;
3410 91736d37 blueswir1
        }
3411 91736d37 blueswir1
    }
3412 91736d37 blueswir1
    if (intno == TT_CLRWIN)
3413 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
3414 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_SPILL)
3415 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
3416 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_FILL)
3417 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
3418 91736d37 blueswir1
    env->tbr &= ~0x7fffULL;
3419 91736d37 blueswir1
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
3420 91736d37 blueswir1
    env->pc = env->tbr;
3421 91736d37 blueswir1
    env->npc = env->pc + 4;
3422 91736d37 blueswir1
    env->exception_index = 0;
3423 ee5bbe38 bellard
}
3424 91736d37 blueswir1
#else
3425 91736d37 blueswir1
#ifdef DEBUG_PCALL
3426 91736d37 blueswir1
static const char * const excp_names[0x80] = {
3427 91736d37 blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
3428 91736d37 blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
3429 91736d37 blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
3430 91736d37 blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
3431 91736d37 blueswir1
    [TT_WIN_OVF] = "Window Overflow",
3432 91736d37 blueswir1
    [TT_WIN_UNF] = "Window Underflow",
3433 91736d37 blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
3434 91736d37 blueswir1
    [TT_FP_EXCP] = "FPU Exception",
3435 91736d37 blueswir1
    [TT_DFAULT] = "Data Access Fault",
3436 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3437 91736d37 blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
3438 91736d37 blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
3439 91736d37 blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
3440 91736d37 blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
3441 91736d37 blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
3442 91736d37 blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
3443 91736d37 blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
3444 91736d37 blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
3445 91736d37 blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
3446 91736d37 blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
3447 91736d37 blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
3448 91736d37 blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
3449 91736d37 blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
3450 91736d37 blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
3451 91736d37 blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
3452 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3453 91736d37 blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
3454 91736d37 blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
3455 91736d37 blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
3456 91736d37 blueswir1
    [TT_NCP_INSN] = "Coprocessor Disabled",
3457 91736d37 blueswir1
};
3458 91736d37 blueswir1
#endif
3459 ee5bbe38 bellard
3460 91736d37 blueswir1
void do_interrupt(CPUState *env)
3461 ee5bbe38 bellard
{
3462 91736d37 blueswir1
    int cwp, intno = env->exception_index;
3463 91736d37 blueswir1
3464 91736d37 blueswir1
#ifdef DEBUG_PCALL
3465 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
3466 91736d37 blueswir1
        static int count;
3467 91736d37 blueswir1
        const char *name;
3468 91736d37 blueswir1
3469 91736d37 blueswir1
        if (intno < 0 || intno >= 0x100)
3470 91736d37 blueswir1
            name = "Unknown";
3471 91736d37 blueswir1
        else if (intno >= 0x80)
3472 91736d37 blueswir1
            name = "Trap Instruction";
3473 91736d37 blueswir1
        else {
3474 91736d37 blueswir1
            name = excp_names[intno];
3475 91736d37 blueswir1
            if (!name)
3476 91736d37 blueswir1
                name = "Unknown";
3477 91736d37 blueswir1
        }
3478 91736d37 blueswir1
3479 93fcfe39 aliguori
        qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
3480 91736d37 blueswir1
                count, name, intno,
3481 91736d37 blueswir1
                env->pc,
3482 91736d37 blueswir1
                env->npc, env->regwptr[6]);
3483 93fcfe39 aliguori
        log_cpu_state(env, 0);
3484 91736d37 blueswir1
#if 0
3485 91736d37 blueswir1
        {
3486 91736d37 blueswir1
            int i;
3487 91736d37 blueswir1
            uint8_t *ptr;
3488 91736d37 blueswir1

3489 93fcfe39 aliguori
            qemu_log("       code=");
3490 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3491 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3492 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3493 91736d37 blueswir1
            }
3494 93fcfe39 aliguori
            qemu_log("\n");
3495 91736d37 blueswir1
        }
3496 91736d37 blueswir1
#endif
3497 91736d37 blueswir1
        count++;
3498 91736d37 blueswir1
    }
3499 91736d37 blueswir1
#endif
3500 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3501 91736d37 blueswir1
    if (env->psret == 0) {
3502 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
3503 91736d37 blueswir1
                  env->exception_index);
3504 91736d37 blueswir1
        return;
3505 91736d37 blueswir1
    }
3506 91736d37 blueswir1
#endif
3507 91736d37 blueswir1
    env->psret = 0;
3508 91736d37 blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
3509 91736d37 blueswir1
    cpu_set_cwp(env, cwp);
3510 91736d37 blueswir1
    env->regwptr[9] = env->pc;
3511 91736d37 blueswir1
    env->regwptr[10] = env->npc;
3512 91736d37 blueswir1
    env->psrps = env->psrs;
3513 91736d37 blueswir1
    env->psrs = 1;
3514 91736d37 blueswir1
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
3515 91736d37 blueswir1
    env->pc = env->tbr;
3516 91736d37 blueswir1
    env->npc = env->pc + 4;
3517 91736d37 blueswir1
    env->exception_index = 0;
3518 ee5bbe38 bellard
}
3519 91736d37 blueswir1
#endif
3520 ee5bbe38 bellard
3521 5fafdf24 ths
#if !defined(CONFIG_USER_ONLY)
3522 ee5bbe38 bellard
3523 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3524 d2889a3e blueswir1
                                void *retaddr);
3525 d2889a3e blueswir1
3526 ee5bbe38 bellard
#define MMUSUFFIX _mmu
3527 d2889a3e blueswir1
#define ALIGNED_ONLY
3528 ee5bbe38 bellard
3529 ee5bbe38 bellard
#define SHIFT 0
3530 ee5bbe38 bellard
#include "softmmu_template.h"
3531 ee5bbe38 bellard
3532 ee5bbe38 bellard
#define SHIFT 1
3533 ee5bbe38 bellard
#include "softmmu_template.h"
3534 ee5bbe38 bellard
3535 ee5bbe38 bellard
#define SHIFT 2
3536 ee5bbe38 bellard
#include "softmmu_template.h"
3537 ee5bbe38 bellard
3538 ee5bbe38 bellard
#define SHIFT 3
3539 ee5bbe38 bellard
#include "softmmu_template.h"
3540 ee5bbe38 bellard
3541 c2bc0e38 blueswir1
/* XXX: make it generic ? */
3542 c2bc0e38 blueswir1
static void cpu_restore_state2(void *retaddr)
3543 c2bc0e38 blueswir1
{
3544 c2bc0e38 blueswir1
    TranslationBlock *tb;
3545 c2bc0e38 blueswir1
    unsigned long pc;
3546 c2bc0e38 blueswir1
3547 c2bc0e38 blueswir1
    if (retaddr) {
3548 c2bc0e38 blueswir1
        /* now we have a real cpu fault */
3549 c2bc0e38 blueswir1
        pc = (unsigned long)retaddr;
3550 c2bc0e38 blueswir1
        tb = tb_find_pc(pc);
3551 c2bc0e38 blueswir1
        if (tb) {
3552 c2bc0e38 blueswir1
            /* the PC is inside the translated code. It means that we have
3553 c2bc0e38 blueswir1
               a virtual CPU fault */
3554 c2bc0e38 blueswir1
            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
3555 c2bc0e38 blueswir1
        }
3556 c2bc0e38 blueswir1
    }
3557 c2bc0e38 blueswir1
}
3558 c2bc0e38 blueswir1
3559 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3560 d2889a3e blueswir1
                                void *retaddr)
3561 d2889a3e blueswir1
{
3562 94554550 blueswir1
#ifdef DEBUG_UNALIGNED
3563 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
3564 c2bc0e38 blueswir1
           "\n", addr, env->pc);
3565 94554550 blueswir1
#endif
3566 c2bc0e38 blueswir1
    cpu_restore_state2(retaddr);
3567 94554550 blueswir1
    raise_exception(TT_UNALIGNED);
3568 d2889a3e blueswir1
}
3569 ee5bbe38 bellard
3570 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
3571 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
3572 ee5bbe38 bellard
   from generated code or from helper.c) */
3573 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
3574 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
3575 ee5bbe38 bellard
{
3576 ee5bbe38 bellard
    int ret;
3577 ee5bbe38 bellard
    CPUState *saved_env;
3578 ee5bbe38 bellard
3579 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
3580 ee5bbe38 bellard
       generated code */
3581 ee5bbe38 bellard
    saved_env = env;
3582 ee5bbe38 bellard
    env = cpu_single_env;
3583 ee5bbe38 bellard
3584 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
3585 ee5bbe38 bellard
    if (ret) {
3586 c2bc0e38 blueswir1
        cpu_restore_state2(retaddr);
3587 ee5bbe38 bellard
        cpu_loop_exit();
3588 ee5bbe38 bellard
    }
3589 ee5bbe38 bellard
    env = saved_env;
3590 ee5bbe38 bellard
}
3591 ee5bbe38 bellard
3592 ee5bbe38 bellard
#endif
3593 6c36d3fa blueswir1
3594 6c36d3fa blueswir1
#ifndef TARGET_SPARC64
3595 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3596 e18231a3 blueswir1
                          int is_asi, int size)
3597 6c36d3fa blueswir1
{
3598 6c36d3fa blueswir1
    CPUState *saved_env;
3599 6c36d3fa blueswir1
3600 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3601 6c36d3fa blueswir1
       generated code */
3602 6c36d3fa blueswir1
    saved_env = env;
3603 6c36d3fa blueswir1
    env = cpu_single_env;
3604 8543e2cf blueswir1
#ifdef DEBUG_UNASSIGNED
3605 8543e2cf blueswir1
    if (is_asi)
3606 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3607 77f193da blueswir1
               " asi 0x%02x from " TARGET_FMT_lx "\n",
3608 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3609 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, is_asi, env->pc);
3610 8543e2cf blueswir1
    else
3611 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3612 e18231a3 blueswir1
               " from " TARGET_FMT_lx "\n",
3613 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3614 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, env->pc);
3615 8543e2cf blueswir1
#endif
3616 6c36d3fa blueswir1
    if (env->mmuregs[3]) /* Fault status register */
3617 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
3618 6c36d3fa blueswir1
    if (is_asi)
3619 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 16;
3620 6c36d3fa blueswir1
    if (env->psrs)
3621 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 5;
3622 6c36d3fa blueswir1
    if (is_exec)
3623 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 6;
3624 6c36d3fa blueswir1
    if (is_write)
3625 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 7;
3626 6c36d3fa blueswir1
    env->mmuregs[3] |= (5 << 2) | 2;
3627 6c36d3fa blueswir1
    env->mmuregs[4] = addr; /* Fault address register */
3628 6c36d3fa blueswir1
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
3629 1b2e93c1 blueswir1
        if (is_exec)
3630 1b2e93c1 blueswir1
            raise_exception(TT_CODE_ACCESS);
3631 1b2e93c1 blueswir1
        else
3632 1b2e93c1 blueswir1
            raise_exception(TT_DATA_ACCESS);
3633 6c36d3fa blueswir1
    }
3634 6c36d3fa blueswir1
    env = saved_env;
3635 6c36d3fa blueswir1
}
3636 6c36d3fa blueswir1
#else
3637 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3638 e18231a3 blueswir1
                          int is_asi, int size)
3639 6c36d3fa blueswir1
{
3640 6c36d3fa blueswir1
#ifdef DEBUG_UNASSIGNED
3641 6c36d3fa blueswir1
    CPUState *saved_env;
3642 6c36d3fa blueswir1
3643 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3644 6c36d3fa blueswir1
       generated code */
3645 6c36d3fa blueswir1
    saved_env = env;
3646 6c36d3fa blueswir1
    env = cpu_single_env;
3647 77f193da blueswir1
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
3648 77f193da blueswir1
           "\n", addr, env->pc);
3649 6c36d3fa blueswir1
    env = saved_env;
3650 6c36d3fa blueswir1
#endif
3651 1b2e93c1 blueswir1
    if (is_exec)
3652 1b2e93c1 blueswir1
        raise_exception(TT_CODE_ACCESS);
3653 1b2e93c1 blueswir1
    else
3654 1b2e93c1 blueswir1
        raise_exception(TT_DATA_ACCESS);
3655 6c36d3fa blueswir1
}
3656 6c36d3fa blueswir1
#endif
3657 20c9f095 blueswir1
3658 f4b1a842 blueswir1
#ifdef TARGET_SPARC64
3659 f4b1a842 blueswir1
void helper_tick_set_count(void *opaque, uint64_t count)
3660 f4b1a842 blueswir1
{
3661 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3662 f4b1a842 blueswir1
    cpu_tick_set_count(opaque, count);
3663 f4b1a842 blueswir1
#endif
3664 f4b1a842 blueswir1
}
3665 f4b1a842 blueswir1
3666 f4b1a842 blueswir1
uint64_t helper_tick_get_count(void *opaque)
3667 f4b1a842 blueswir1
{
3668 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3669 f4b1a842 blueswir1
    return cpu_tick_get_count(opaque);
3670 f4b1a842 blueswir1
#else
3671 f4b1a842 blueswir1
    return 0;
3672 f4b1a842 blueswir1
#endif
3673 f4b1a842 blueswir1
}
3674 f4b1a842 blueswir1
3675 f4b1a842 blueswir1
void helper_tick_set_limit(void *opaque, uint64_t limit)
3676 f4b1a842 blueswir1
{
3677 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3678 f4b1a842 blueswir1
    cpu_tick_set_limit(opaque, limit);
3679 f4b1a842 blueswir1
#endif
3680 f4b1a842 blueswir1
}
3681 f4b1a842 blueswir1
#endif