Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ db166940

History | View | Annotate | Download (78.2 kB)

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