Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 2cade6a3

History | View | Annotate | Download (76.5 kB)

1 e8af50a3 bellard
#include "exec.h"
2 eed152bb blueswir1
#include "host-utils.h"
3 1a2fb1c0 blueswir1
#include "helper.h"
4 0828b448 blueswir1
#if !defined(CONFIG_USER_ONLY)
5 0828b448 blueswir1
#include "softmmu_exec.h"
6 0828b448 blueswir1
#endif /* !defined(CONFIG_USER_ONLY) */
7 e8af50a3 bellard
8 e80cfcfc bellard
//#define DEBUG_MMU
9 952a328f blueswir1
//#define DEBUG_MXCC
10 94554550 blueswir1
//#define DEBUG_UNALIGNED
11 6c36d3fa blueswir1
//#define DEBUG_UNASSIGNED
12 8543e2cf blueswir1
//#define DEBUG_ASI
13 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 83469015 bellard
    case 0x04: // Nucleus
1638 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
1639 83469015 bellard
    case 0x11: // As if user secondary
1640 83469015 bellard
    case 0x19: // As if user secondary LE
1641 83469015 bellard
    case 0x24: // Nucleus quad LDD 128 bit atomic
1642 83469015 bellard
    case 0x2c: // Nucleus quad LDD 128 bit atomic
1643 83469015 bellard
    case 0x4a: // UPA config
1644 81ad8ba2 blueswir1
    case 0x81: // Secondary
1645 83469015 bellard
    case 0x83: // Secondary no-fault
1646 83469015 bellard
    case 0x89: // Secondary LE
1647 83469015 bellard
    case 0x8b: // Secondary no-fault LE
1648 0f8a249a blueswir1
        // XXX
1649 0f8a249a blueswir1
        break;
1650 3475187d bellard
    case 0x45: // LSU
1651 0f8a249a blueswir1
        ret = env->lsu;
1652 0f8a249a blueswir1
        break;
1653 3475187d bellard
    case 0x50: // I-MMU regs
1654 0f8a249a blueswir1
        {
1655 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
1656 3475187d bellard
1657 0f8a249a blueswir1
            ret = env->immuregs[reg];
1658 0f8a249a blueswir1
            break;
1659 0f8a249a blueswir1
        }
1660 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer
1661 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer
1662 0f8a249a blueswir1
        // XXX
1663 0f8a249a blueswir1
        break;
1664 a5a52cf2 blueswir1
    case 0x55: // I-MMU data access
1665 a5a52cf2 blueswir1
        {
1666 a5a52cf2 blueswir1
            int reg = (addr >> 3) & 0x3f;
1667 a5a52cf2 blueswir1
1668 a5a52cf2 blueswir1
            ret = env->itlb_tte[reg];
1669 a5a52cf2 blueswir1
            break;
1670 a5a52cf2 blueswir1
        }
1671 83469015 bellard
    case 0x56: // I-MMU tag read
1672 0f8a249a blueswir1
        {
1673 0f8a249a blueswir1
            unsigned int i;
1674 0f8a249a blueswir1
1675 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
1676 0f8a249a blueswir1
                // Valid, ctx match, vaddr match
1677 a5a52cf2 blueswir1
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
1678 a5a52cf2 blueswir1
                    uint64_t mask;
1679 a5a52cf2 blueswir1
1680 a5a52cf2 blueswir1
                    switch ((env->itlb_tte[i] >> 61) & 3) {
1681 a5a52cf2 blueswir1
                    default:
1682 a5a52cf2 blueswir1
                    case 0x0:
1683 a5a52cf2 blueswir1
                        mask = 0xffffffffffffffff;
1684 a5a52cf2 blueswir1
                        break;
1685 a5a52cf2 blueswir1
                    case 0x1:
1686 a5a52cf2 blueswir1
                        mask = 0xffffffffffff0fff;
1687 a5a52cf2 blueswir1
                        break;
1688 a5a52cf2 blueswir1
                    case 0x2:
1689 a5a52cf2 blueswir1
                        mask = 0xfffffffffff80fff;
1690 a5a52cf2 blueswir1
                        break;
1691 a5a52cf2 blueswir1
                    case 0x3:
1692 a5a52cf2 blueswir1
                        mask = 0xffffffffffc00fff;
1693 a5a52cf2 blueswir1
                        break;
1694 a5a52cf2 blueswir1
                    }
1695 a5a52cf2 blueswir1
                    if ((env->itlb_tag[i] & mask) == (addr & mask)) {
1696 a5a52cf2 blueswir1
                        ret = env->itlb_tte[i];
1697 a5a52cf2 blueswir1
                        break;
1698 a5a52cf2 blueswir1
                    }
1699 0f8a249a blueswir1
                }
1700 0f8a249a blueswir1
            }
1701 0f8a249a blueswir1
            break;
1702 0f8a249a blueswir1
        }
1703 3475187d bellard
    case 0x58: // D-MMU regs
1704 0f8a249a blueswir1
        {
1705 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
1706 3475187d bellard
1707 0f8a249a blueswir1
            ret = env->dmmuregs[reg];
1708 0f8a249a blueswir1
            break;
1709 0f8a249a blueswir1
        }
1710 a5a52cf2 blueswir1
    case 0x5d: // D-MMU data access
1711 a5a52cf2 blueswir1
        {
1712 a5a52cf2 blueswir1
            int reg = (addr >> 3) & 0x3f;
1713 a5a52cf2 blueswir1
1714 a5a52cf2 blueswir1
            ret = env->dtlb_tte[reg];
1715 a5a52cf2 blueswir1
            break;
1716 a5a52cf2 blueswir1
        }
1717 83469015 bellard
    case 0x5e: // D-MMU tag read
1718 0f8a249a blueswir1
        {
1719 0f8a249a blueswir1
            unsigned int i;
1720 0f8a249a blueswir1
1721 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
1722 0f8a249a blueswir1
                // Valid, ctx match, vaddr match
1723 a5a52cf2 blueswir1
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
1724 a5a52cf2 blueswir1
                    uint64_t mask;
1725 a5a52cf2 blueswir1
1726 a5a52cf2 blueswir1
                    switch ((env->dtlb_tte[i] >> 61) & 3) {
1727 a5a52cf2 blueswir1
                    default:
1728 a5a52cf2 blueswir1
                    case 0x0:
1729 a5a52cf2 blueswir1
                        mask = 0xffffffffffffffff;
1730 a5a52cf2 blueswir1
                        break;
1731 a5a52cf2 blueswir1
                    case 0x1:
1732 a5a52cf2 blueswir1
                        mask = 0xffffffffffff0fff;
1733 a5a52cf2 blueswir1
                        break;
1734 a5a52cf2 blueswir1
                    case 0x2:
1735 a5a52cf2 blueswir1
                        mask = 0xfffffffffff80fff;
1736 a5a52cf2 blueswir1
                        break;
1737 a5a52cf2 blueswir1
                    case 0x3:
1738 a5a52cf2 blueswir1
                        mask = 0xffffffffffc00fff;
1739 a5a52cf2 blueswir1
                        break;
1740 a5a52cf2 blueswir1
                    }
1741 a5a52cf2 blueswir1
                    if ((env->dtlb_tag[i] & mask) == (addr & mask)) {
1742 a5a52cf2 blueswir1
                        ret = env->dtlb_tte[i];
1743 a5a52cf2 blueswir1
                        break;
1744 a5a52cf2 blueswir1
                    }
1745 0f8a249a blueswir1
                }
1746 0f8a249a blueswir1
            }
1747 0f8a249a blueswir1
            break;
1748 0f8a249a blueswir1
        }
1749 f7350b47 blueswir1
    case 0x46: // D-cache data
1750 f7350b47 blueswir1
    case 0x47: // D-cache tag access
1751 a5a52cf2 blueswir1
    case 0x4b: // E-cache error enable
1752 a5a52cf2 blueswir1
    case 0x4c: // E-cache asynchronous fault status
1753 a5a52cf2 blueswir1
    case 0x4d: // E-cache asynchronous fault address
1754 f7350b47 blueswir1
    case 0x4e: // E-cache tag data
1755 f7350b47 blueswir1
    case 0x66: // I-cache instruction access
1756 f7350b47 blueswir1
    case 0x67: // I-cache tag access
1757 f7350b47 blueswir1
    case 0x6e: // I-cache predecode
1758 f7350b47 blueswir1
    case 0x6f: // I-cache LRU etc.
1759 f7350b47 blueswir1
    case 0x76: // E-cache tag
1760 f7350b47 blueswir1
    case 0x7e: // E-cache tag
1761 f7350b47 blueswir1
        break;
1762 3475187d bellard
    case 0x59: // D-MMU 8k TSB pointer
1763 3475187d bellard
    case 0x5a: // D-MMU 64k TSB pointer
1764 3475187d bellard
    case 0x5b: // D-MMU data pointer
1765 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
1766 83469015 bellard
    case 0x49: // Interrupt data receive
1767 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
1768 0f8a249a blueswir1
        // XXX
1769 0f8a249a blueswir1
        break;
1770 3475187d bellard
    case 0x54: // I-MMU data in, WO
1771 3475187d bellard
    case 0x57: // I-MMU demap, WO
1772 3475187d bellard
    case 0x5c: // D-MMU data in, WO
1773 3475187d bellard
    case 0x5f: // D-MMU demap, WO
1774 83469015 bellard
    case 0x77: // Interrupt vector, WO
1775 3475187d bellard
    default:
1776 1a2fb1c0 blueswir1
        do_unassigned_access(addr, 0, 0, 1);
1777 0f8a249a blueswir1
        ret = 0;
1778 0f8a249a blueswir1
        break;
1779 3475187d bellard
    }
1780 81ad8ba2 blueswir1
1781 81ad8ba2 blueswir1
    /* Convert from little endian */
1782 81ad8ba2 blueswir1
    switch (asi) {
1783 81ad8ba2 blueswir1
    case 0x0c: // Nucleus Little Endian (LE)
1784 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1785 81ad8ba2 blueswir1
    case 0x19: // As if user secondary LE
1786 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1787 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1788 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1789 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1790 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1791 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1792 81ad8ba2 blueswir1
        switch(size) {
1793 81ad8ba2 blueswir1
        case 2:
1794 81ad8ba2 blueswir1
            ret = bswap16(ret);
1795 e32664fb blueswir1
            break;
1796 81ad8ba2 blueswir1
        case 4:
1797 81ad8ba2 blueswir1
            ret = bswap32(ret);
1798 e32664fb blueswir1
            break;
1799 81ad8ba2 blueswir1
        case 8:
1800 81ad8ba2 blueswir1
            ret = bswap64(ret);
1801 e32664fb blueswir1
            break;
1802 81ad8ba2 blueswir1
        default:
1803 81ad8ba2 blueswir1
            break;
1804 81ad8ba2 blueswir1
        }
1805 81ad8ba2 blueswir1
    default:
1806 81ad8ba2 blueswir1
        break;
1807 81ad8ba2 blueswir1
    }
1808 81ad8ba2 blueswir1
1809 81ad8ba2 blueswir1
    /* Convert to signed number */
1810 81ad8ba2 blueswir1
    if (sign) {
1811 81ad8ba2 blueswir1
        switch(size) {
1812 81ad8ba2 blueswir1
        case 1:
1813 81ad8ba2 blueswir1
            ret = (int8_t) ret;
1814 e32664fb blueswir1
            break;
1815 81ad8ba2 blueswir1
        case 2:
1816 81ad8ba2 blueswir1
            ret = (int16_t) ret;
1817 e32664fb blueswir1
            break;
1818 81ad8ba2 blueswir1
        case 4:
1819 81ad8ba2 blueswir1
            ret = (int32_t) ret;
1820 e32664fb blueswir1
            break;
1821 81ad8ba2 blueswir1
        default:
1822 81ad8ba2 blueswir1
            break;
1823 81ad8ba2 blueswir1
        }
1824 81ad8ba2 blueswir1
    }
1825 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1826 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
1827 1a2fb1c0 blueswir1
#endif
1828 1a2fb1c0 blueswir1
    return ret;
1829 3475187d bellard
}
1830 3475187d bellard
1831 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
1832 3475187d bellard
{
1833 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
1834 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
1835 1a2fb1c0 blueswir1
#endif
1836 6f27aba6 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1837 20b749f6 blueswir1
        || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV)))
1838 0f8a249a blueswir1
        raise_exception(TT_PRIV_ACT);
1839 3475187d bellard
1840 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1841 81ad8ba2 blueswir1
    /* Convert to little endian */
1842 81ad8ba2 blueswir1
    switch (asi) {
1843 81ad8ba2 blueswir1
    case 0x0c: // Nucleus Little Endian (LE)
1844 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1845 81ad8ba2 blueswir1
    case 0x19: // As if user secondary LE
1846 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1847 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1848 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1849 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1850 81ad8ba2 blueswir1
        switch(size) {
1851 81ad8ba2 blueswir1
        case 2:
1852 1a2fb1c0 blueswir1
            addr = bswap16(addr);
1853 e32664fb blueswir1
            break;
1854 81ad8ba2 blueswir1
        case 4:
1855 1a2fb1c0 blueswir1
            addr = bswap32(addr);
1856 e32664fb blueswir1
            break;
1857 81ad8ba2 blueswir1
        case 8:
1858 1a2fb1c0 blueswir1
            addr = bswap64(addr);
1859 e32664fb blueswir1
            break;
1860 81ad8ba2 blueswir1
        default:
1861 81ad8ba2 blueswir1
            break;
1862 81ad8ba2 blueswir1
        }
1863 81ad8ba2 blueswir1
    default:
1864 81ad8ba2 blueswir1
        break;
1865 81ad8ba2 blueswir1
    }
1866 81ad8ba2 blueswir1
1867 3475187d bellard
    switch(asi) {
1868 81ad8ba2 blueswir1
    case 0x10: // As if user primary
1869 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
1870 81ad8ba2 blueswir1
    case 0x80: // Primary
1871 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1872 81ad8ba2 blueswir1
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1873 6f27aba6 blueswir1
            if (env->hpstate & HS_PRIV) {
1874 6f27aba6 blueswir1
                switch(size) {
1875 6f27aba6 blueswir1
                case 1:
1876 1a2fb1c0 blueswir1
                    stb_hypv(addr, val);
1877 6f27aba6 blueswir1
                    break;
1878 6f27aba6 blueswir1
                case 2:
1879 a4e7dd52 blueswir1
                    stw_hypv(addr, val);
1880 6f27aba6 blueswir1
                    break;
1881 6f27aba6 blueswir1
                case 4:
1882 a4e7dd52 blueswir1
                    stl_hypv(addr, val);
1883 6f27aba6 blueswir1
                    break;
1884 6f27aba6 blueswir1
                case 8:
1885 6f27aba6 blueswir1
                default:
1886 a4e7dd52 blueswir1
                    stq_hypv(addr, val);
1887 6f27aba6 blueswir1
                    break;
1888 6f27aba6 blueswir1
                }
1889 6f27aba6 blueswir1
            } else {
1890 6f27aba6 blueswir1
                switch(size) {
1891 6f27aba6 blueswir1
                case 1:
1892 1a2fb1c0 blueswir1
                    stb_kernel(addr, val);
1893 6f27aba6 blueswir1
                    break;
1894 6f27aba6 blueswir1
                case 2:
1895 a4e7dd52 blueswir1
                    stw_kernel(addr, val);
1896 6f27aba6 blueswir1
                    break;
1897 6f27aba6 blueswir1
                case 4:
1898 a4e7dd52 blueswir1
                    stl_kernel(addr, val);
1899 6f27aba6 blueswir1
                    break;
1900 6f27aba6 blueswir1
                case 8:
1901 6f27aba6 blueswir1
                default:
1902 a4e7dd52 blueswir1
                    stq_kernel(addr, val);
1903 6f27aba6 blueswir1
                    break;
1904 6f27aba6 blueswir1
                }
1905 81ad8ba2 blueswir1
            }
1906 81ad8ba2 blueswir1
        } else {
1907 81ad8ba2 blueswir1
            switch(size) {
1908 81ad8ba2 blueswir1
            case 1:
1909 1a2fb1c0 blueswir1
                stb_user(addr, val);
1910 81ad8ba2 blueswir1
                break;
1911 81ad8ba2 blueswir1
            case 2:
1912 a4e7dd52 blueswir1
                stw_user(addr, val);
1913 81ad8ba2 blueswir1
                break;
1914 81ad8ba2 blueswir1
            case 4:
1915 a4e7dd52 blueswir1
                stl_user(addr, val);
1916 81ad8ba2 blueswir1
                break;
1917 81ad8ba2 blueswir1
            case 8:
1918 81ad8ba2 blueswir1
            default:
1919 a4e7dd52 blueswir1
                stq_user(addr, val);
1920 81ad8ba2 blueswir1
                break;
1921 81ad8ba2 blueswir1
            }
1922 81ad8ba2 blueswir1
        }
1923 81ad8ba2 blueswir1
        break;
1924 3475187d bellard
    case 0x14: // Bypass
1925 3475187d bellard
    case 0x15: // Bypass, non-cacheable
1926 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
1927 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
1928 0f8a249a blueswir1
        {
1929 02aab46a bellard
            switch(size) {
1930 02aab46a bellard
            case 1:
1931 1a2fb1c0 blueswir1
                stb_phys(addr, val);
1932 02aab46a bellard
                break;
1933 02aab46a bellard
            case 2:
1934 a4e7dd52 blueswir1
                stw_phys(addr, val);
1935 02aab46a bellard
                break;
1936 02aab46a bellard
            case 4:
1937 a4e7dd52 blueswir1
                stl_phys(addr, val);
1938 02aab46a bellard
                break;
1939 02aab46a bellard
            case 8:
1940 02aab46a bellard
            default:
1941 a4e7dd52 blueswir1
                stq_phys(addr, val);
1942 02aab46a bellard
                break;
1943 02aab46a bellard
            }
1944 0f8a249a blueswir1
        }
1945 0f8a249a blueswir1
        return;
1946 83469015 bellard
    case 0x04: // Nucleus
1947 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
1948 83469015 bellard
    case 0x11: // As if user secondary
1949 83469015 bellard
    case 0x19: // As if user secondary LE
1950 83469015 bellard
    case 0x24: // Nucleus quad LDD 128 bit atomic
1951 83469015 bellard
    case 0x2c: // Nucleus quad LDD 128 bit atomic
1952 83469015 bellard
    case 0x4a: // UPA config
1953 51996525 blueswir1
    case 0x81: // Secondary
1954 83469015 bellard
    case 0x89: // Secondary LE
1955 0f8a249a blueswir1
        // XXX
1956 0f8a249a blueswir1
        return;
1957 3475187d bellard
    case 0x45: // LSU
1958 0f8a249a blueswir1
        {
1959 0f8a249a blueswir1
            uint64_t oldreg;
1960 0f8a249a blueswir1
1961 0f8a249a blueswir1
            oldreg = env->lsu;
1962 1a2fb1c0 blueswir1
            env->lsu = val & (DMMU_E | IMMU_E);
1963 0f8a249a blueswir1
            // Mappings generated during D/I MMU disabled mode are
1964 0f8a249a blueswir1
            // invalid in normal mode
1965 0f8a249a blueswir1
            if (oldreg != env->lsu) {
1966 77f193da blueswir1
                DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
1967 77f193da blueswir1
                            oldreg, env->lsu);
1968 83469015 bellard
#ifdef DEBUG_MMU
1969 0f8a249a blueswir1
                dump_mmu(env);
1970 83469015 bellard
#endif
1971 0f8a249a blueswir1
                tlb_flush(env, 1);
1972 0f8a249a blueswir1
            }
1973 0f8a249a blueswir1
            return;
1974 0f8a249a blueswir1
        }
1975 3475187d bellard
    case 0x50: // I-MMU regs
1976 0f8a249a blueswir1
        {
1977 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
1978 0f8a249a blueswir1
            uint64_t oldreg;
1979 3b46e624 ths
1980 0f8a249a blueswir1
            oldreg = env->immuregs[reg];
1981 3475187d bellard
            switch(reg) {
1982 3475187d bellard
            case 0: // RO
1983 3475187d bellard
            case 4:
1984 3475187d bellard
                return;
1985 3475187d bellard
            case 1: // Not in I-MMU
1986 3475187d bellard
            case 2:
1987 3475187d bellard
            case 7:
1988 3475187d bellard
            case 8:
1989 3475187d bellard
                return;
1990 3475187d bellard
            case 3: // SFSR
1991 1a2fb1c0 blueswir1
                if ((val & 1) == 0)
1992 1a2fb1c0 blueswir1
                    val = 0; // Clear SFSR
1993 3475187d bellard
                break;
1994 3475187d bellard
            case 5: // TSB access
1995 3475187d bellard
            case 6: // Tag access
1996 3475187d bellard
            default:
1997 3475187d bellard
                break;
1998 3475187d bellard
            }
1999 1a2fb1c0 blueswir1
            env->immuregs[reg] = val;
2000 3475187d bellard
            if (oldreg != env->immuregs[reg]) {
2001 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08"
2002 77f193da blueswir1
                            PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
2003 3475187d bellard
            }
2004 952a328f blueswir1
#ifdef DEBUG_MMU
2005 0f8a249a blueswir1
            dump_mmu(env);
2006 3475187d bellard
#endif
2007 0f8a249a blueswir1
            return;
2008 0f8a249a blueswir1
        }
2009 3475187d bellard
    case 0x54: // I-MMU data in
2010 0f8a249a blueswir1
        {
2011 0f8a249a blueswir1
            unsigned int i;
2012 0f8a249a blueswir1
2013 0f8a249a blueswir1
            // Try finding an invalid entry
2014 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2015 0f8a249a blueswir1
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
2016 0f8a249a blueswir1
                    env->itlb_tag[i] = env->immuregs[6];
2017 1a2fb1c0 blueswir1
                    env->itlb_tte[i] = val;
2018 0f8a249a blueswir1
                    return;
2019 0f8a249a blueswir1
                }
2020 0f8a249a blueswir1
            }
2021 0f8a249a blueswir1
            // Try finding an unlocked entry
2022 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2023 0f8a249a blueswir1
                if ((env->itlb_tte[i] & 0x40) == 0) {
2024 0f8a249a blueswir1
                    env->itlb_tag[i] = env->immuregs[6];
2025 1a2fb1c0 blueswir1
                    env->itlb_tte[i] = val;
2026 0f8a249a blueswir1
                    return;
2027 0f8a249a blueswir1
                }
2028 0f8a249a blueswir1
            }
2029 0f8a249a blueswir1
            // error state?
2030 0f8a249a blueswir1
            return;
2031 0f8a249a blueswir1
        }
2032 3475187d bellard
    case 0x55: // I-MMU data access
2033 0f8a249a blueswir1
        {
2034 1a2fb1c0 blueswir1
            unsigned int i = (addr >> 3) & 0x3f;
2035 3475187d bellard
2036 0f8a249a blueswir1
            env->itlb_tag[i] = env->immuregs[6];
2037 1a2fb1c0 blueswir1
            env->itlb_tte[i] = val;
2038 0f8a249a blueswir1
            return;
2039 0f8a249a blueswir1
        }
2040 3475187d bellard
    case 0x57: // I-MMU demap
2041 0f8a249a blueswir1
        // XXX
2042 0f8a249a blueswir1
        return;
2043 3475187d bellard
    case 0x58: // D-MMU regs
2044 0f8a249a blueswir1
        {
2045 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
2046 0f8a249a blueswir1
            uint64_t oldreg;
2047 3b46e624 ths
2048 0f8a249a blueswir1
            oldreg = env->dmmuregs[reg];
2049 3475187d bellard
            switch(reg) {
2050 3475187d bellard
            case 0: // RO
2051 3475187d bellard
            case 4:
2052 3475187d bellard
                return;
2053 3475187d bellard
            case 3: // SFSR
2054 1a2fb1c0 blueswir1
                if ((val & 1) == 0) {
2055 1a2fb1c0 blueswir1
                    val = 0; // Clear SFSR, Fault address
2056 0f8a249a blueswir1
                    env->dmmuregs[4] = 0;
2057 0f8a249a blueswir1
                }
2058 1a2fb1c0 blueswir1
                env->dmmuregs[reg] = val;
2059 3475187d bellard
                break;
2060 3475187d bellard
            case 1: // Primary context
2061 3475187d bellard
            case 2: // Secondary context
2062 3475187d bellard
            case 5: // TSB access
2063 3475187d bellard
            case 6: // Tag access
2064 3475187d bellard
            case 7: // Virtual Watchpoint
2065 3475187d bellard
            case 8: // Physical Watchpoint
2066 3475187d bellard
            default:
2067 3475187d bellard
                break;
2068 3475187d bellard
            }
2069 1a2fb1c0 blueswir1
            env->dmmuregs[reg] = val;
2070 3475187d bellard
            if (oldreg != env->dmmuregs[reg]) {
2071 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08"
2072 77f193da blueswir1
                            PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
2073 3475187d bellard
            }
2074 952a328f blueswir1
#ifdef DEBUG_MMU
2075 0f8a249a blueswir1
            dump_mmu(env);
2076 3475187d bellard
#endif
2077 0f8a249a blueswir1
            return;
2078 0f8a249a blueswir1
        }
2079 3475187d bellard
    case 0x5c: // D-MMU data in
2080 0f8a249a blueswir1
        {
2081 0f8a249a blueswir1
            unsigned int i;
2082 0f8a249a blueswir1
2083 0f8a249a blueswir1
            // Try finding an invalid entry
2084 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2085 0f8a249a blueswir1
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
2086 0f8a249a blueswir1
                    env->dtlb_tag[i] = env->dmmuregs[6];
2087 1a2fb1c0 blueswir1
                    env->dtlb_tte[i] = val;
2088 0f8a249a blueswir1
                    return;
2089 0f8a249a blueswir1
                }
2090 0f8a249a blueswir1
            }
2091 0f8a249a blueswir1
            // Try finding an unlocked entry
2092 0f8a249a blueswir1
            for (i = 0; i < 64; i++) {
2093 0f8a249a blueswir1
                if ((env->dtlb_tte[i] & 0x40) == 0) {
2094 0f8a249a blueswir1
                    env->dtlb_tag[i] = env->dmmuregs[6];
2095 1a2fb1c0 blueswir1
                    env->dtlb_tte[i] = val;
2096 0f8a249a blueswir1
                    return;
2097 0f8a249a blueswir1
                }
2098 0f8a249a blueswir1
            }
2099 0f8a249a blueswir1
            // error state?
2100 0f8a249a blueswir1
            return;
2101 0f8a249a blueswir1
        }
2102 3475187d bellard
    case 0x5d: // D-MMU data access
2103 0f8a249a blueswir1
        {
2104 1a2fb1c0 blueswir1
            unsigned int i = (addr >> 3) & 0x3f;
2105 3475187d bellard
2106 0f8a249a blueswir1
            env->dtlb_tag[i] = env->dmmuregs[6];
2107 1a2fb1c0 blueswir1
            env->dtlb_tte[i] = val;
2108 0f8a249a blueswir1
            return;
2109 0f8a249a blueswir1
        }
2110 3475187d bellard
    case 0x5f: // D-MMU demap
2111 83469015 bellard
    case 0x49: // Interrupt data receive
2112 0f8a249a blueswir1
        // XXX
2113 0f8a249a blueswir1
        return;
2114 f7350b47 blueswir1
    case 0x46: // D-cache data
2115 f7350b47 blueswir1
    case 0x47: // D-cache tag access
2116 a5a52cf2 blueswir1
    case 0x4b: // E-cache error enable
2117 a5a52cf2 blueswir1
    case 0x4c: // E-cache asynchronous fault status
2118 a5a52cf2 blueswir1
    case 0x4d: // E-cache asynchronous fault address
2119 f7350b47 blueswir1
    case 0x4e: // E-cache tag data
2120 f7350b47 blueswir1
    case 0x66: // I-cache instruction access
2121 f7350b47 blueswir1
    case 0x67: // I-cache tag access
2122 f7350b47 blueswir1
    case 0x6e: // I-cache predecode
2123 f7350b47 blueswir1
    case 0x6f: // I-cache LRU etc.
2124 f7350b47 blueswir1
    case 0x76: // E-cache tag
2125 f7350b47 blueswir1
    case 0x7e: // E-cache tag
2126 f7350b47 blueswir1
        return;
2127 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer, RO
2128 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer, RO
2129 3475187d bellard
    case 0x56: // I-MMU tag read, RO
2130 3475187d bellard
    case 0x59: // D-MMU 8k TSB pointer, RO
2131 3475187d bellard
    case 0x5a: // D-MMU 64k TSB pointer, RO
2132 3475187d bellard
    case 0x5b: // D-MMU data pointer, RO
2133 3475187d bellard
    case 0x5e: // D-MMU tag read, RO
2134 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
2135 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
2136 83469015 bellard
    case 0x82: // Primary no-fault, RO
2137 83469015 bellard
    case 0x83: // Secondary no-fault, RO
2138 83469015 bellard
    case 0x8a: // Primary no-fault LE, RO
2139 83469015 bellard
    case 0x8b: // Secondary no-fault LE, RO
2140 3475187d bellard
    default:
2141 1a2fb1c0 blueswir1
        do_unassigned_access(addr, 1, 0, 1);
2142 0f8a249a blueswir1
        return;
2143 3475187d bellard
    }
2144 3475187d bellard
}
2145 81ad8ba2 blueswir1
#endif /* CONFIG_USER_ONLY */
2146 3391c818 blueswir1
2147 1a2fb1c0 blueswir1
void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2148 3391c818 blueswir1
{
2149 3391c818 blueswir1
    unsigned int i;
2150 1a2fb1c0 blueswir1
    target_ulong val;
2151 3391c818 blueswir1
2152 c2bc0e38 blueswir1
    helper_check_align(addr, 3);
2153 3391c818 blueswir1
    switch (asi) {
2154 3391c818 blueswir1
    case 0xf0: // Block load primary
2155 3391c818 blueswir1
    case 0xf1: // Block load secondary
2156 3391c818 blueswir1
    case 0xf8: // Block load primary LE
2157 3391c818 blueswir1
    case 0xf9: // Block load secondary LE
2158 51996525 blueswir1
        if (rd & 7) {
2159 51996525 blueswir1
            raise_exception(TT_ILL_INSN);
2160 51996525 blueswir1
            return;
2161 51996525 blueswir1
        }
2162 c2bc0e38 blueswir1
        helper_check_align(addr, 0x3f);
2163 51996525 blueswir1
        for (i = 0; i < 16; i++) {
2164 77f193da blueswir1
            *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4,
2165 77f193da blueswir1
                                                         0);
2166 1a2fb1c0 blueswir1
            addr += 4;
2167 3391c818 blueswir1
        }
2168 3391c818 blueswir1
2169 3391c818 blueswir1
        return;
2170 3391c818 blueswir1
    default:
2171 3391c818 blueswir1
        break;
2172 3391c818 blueswir1
    }
2173 3391c818 blueswir1
2174 1a2fb1c0 blueswir1
    val = helper_ld_asi(addr, asi, size, 0);
2175 3391c818 blueswir1
    switch(size) {
2176 3391c818 blueswir1
    default:
2177 3391c818 blueswir1
    case 4:
2178 1a2fb1c0 blueswir1
        *((uint32_t *)&FT0) = val;
2179 3391c818 blueswir1
        break;
2180 3391c818 blueswir1
    case 8:
2181 1a2fb1c0 blueswir1
        *((int64_t *)&DT0) = val;
2182 3391c818 blueswir1
        break;
2183 1f587329 blueswir1
    case 16:
2184 1f587329 blueswir1
        // XXX
2185 1f587329 blueswir1
        break;
2186 3391c818 blueswir1
    }
2187 3391c818 blueswir1
}
2188 3391c818 blueswir1
2189 1a2fb1c0 blueswir1
void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
2190 3391c818 blueswir1
{
2191 3391c818 blueswir1
    unsigned int i;
2192 1a2fb1c0 blueswir1
    target_ulong val = 0;
2193 3391c818 blueswir1
2194 c2bc0e38 blueswir1
    helper_check_align(addr, 3);
2195 3391c818 blueswir1
    switch (asi) {
2196 3391c818 blueswir1
    case 0xf0: // Block store primary
2197 3391c818 blueswir1
    case 0xf1: // Block store secondary
2198 3391c818 blueswir1
    case 0xf8: // Block store primary LE
2199 3391c818 blueswir1
    case 0xf9: // Block store secondary LE
2200 51996525 blueswir1
        if (rd & 7) {
2201 51996525 blueswir1
            raise_exception(TT_ILL_INSN);
2202 51996525 blueswir1
            return;
2203 51996525 blueswir1
        }
2204 c2bc0e38 blueswir1
        helper_check_align(addr, 0x3f);
2205 51996525 blueswir1
        for (i = 0; i < 16; i++) {
2206 1a2fb1c0 blueswir1
            val = *(uint32_t *)&env->fpr[rd++];
2207 1a2fb1c0 blueswir1
            helper_st_asi(addr, val, asi & 0x8f, 4);
2208 1a2fb1c0 blueswir1
            addr += 4;
2209 3391c818 blueswir1
        }
2210 3391c818 blueswir1
2211 3391c818 blueswir1
        return;
2212 3391c818 blueswir1
    default:
2213 3391c818 blueswir1
        break;
2214 3391c818 blueswir1
    }
2215 3391c818 blueswir1
2216 3391c818 blueswir1
    switch(size) {
2217 3391c818 blueswir1
    default:
2218 3391c818 blueswir1
    case 4:
2219 1a2fb1c0 blueswir1
        val = *((uint32_t *)&FT0);
2220 3391c818 blueswir1
        break;
2221 3391c818 blueswir1
    case 8:
2222 1a2fb1c0 blueswir1
        val = *((int64_t *)&DT0);
2223 3391c818 blueswir1
        break;
2224 1f587329 blueswir1
    case 16:
2225 1f587329 blueswir1
        // XXX
2226 1f587329 blueswir1
        break;
2227 3391c818 blueswir1
    }
2228 1a2fb1c0 blueswir1
    helper_st_asi(addr, val, asi, size);
2229 1a2fb1c0 blueswir1
}
2230 1a2fb1c0 blueswir1
2231 1a2fb1c0 blueswir1
target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
2232 1a2fb1c0 blueswir1
                            target_ulong val2, uint32_t asi)
2233 1a2fb1c0 blueswir1
{
2234 1a2fb1c0 blueswir1
    target_ulong ret;
2235 1a2fb1c0 blueswir1
2236 1a2fb1c0 blueswir1
    val1 &= 0xffffffffUL;
2237 1a2fb1c0 blueswir1
    ret = helper_ld_asi(addr, asi, 4, 0);
2238 1a2fb1c0 blueswir1
    ret &= 0xffffffffUL;
2239 1a2fb1c0 blueswir1
    if (val1 == ret)
2240 1a2fb1c0 blueswir1
        helper_st_asi(addr, val2 & 0xffffffffUL, asi, 4);
2241 1a2fb1c0 blueswir1
    return ret;
2242 3391c818 blueswir1
}
2243 3391c818 blueswir1
2244 1a2fb1c0 blueswir1
target_ulong helper_casx_asi(target_ulong addr, target_ulong val1,
2245 1a2fb1c0 blueswir1
                             target_ulong val2, uint32_t asi)
2246 1a2fb1c0 blueswir1
{
2247 1a2fb1c0 blueswir1
    target_ulong ret;
2248 1a2fb1c0 blueswir1
2249 1a2fb1c0 blueswir1
    ret = helper_ld_asi(addr, asi, 8, 0);
2250 1a2fb1c0 blueswir1
    if (val1 == ret)
2251 1a2fb1c0 blueswir1
        helper_st_asi(addr, val2, asi, 8);
2252 1a2fb1c0 blueswir1
    return ret;
2253 1a2fb1c0 blueswir1
}
2254 81ad8ba2 blueswir1
#endif /* TARGET_SPARC64 */
2255 3475187d bellard
2256 3475187d bellard
#ifndef TARGET_SPARC64
2257 1a2fb1c0 blueswir1
void helper_rett(void)
2258 e8af50a3 bellard
{
2259 af7bf89b bellard
    unsigned int cwp;
2260 af7bf89b bellard
2261 d4218d99 blueswir1
    if (env->psret == 1)
2262 d4218d99 blueswir1
        raise_exception(TT_ILL_INSN);
2263 d4218d99 blueswir1
2264 e8af50a3 bellard
    env->psret = 1;
2265 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1) ;
2266 e8af50a3 bellard
    if (env->wim & (1 << cwp)) {
2267 e8af50a3 bellard
        raise_exception(TT_WIN_UNF);
2268 e8af50a3 bellard
    }
2269 e8af50a3 bellard
    set_cwp(cwp);
2270 e8af50a3 bellard
    env->psrs = env->psrps;
2271 e8af50a3 bellard
}
2272 3475187d bellard
#endif
2273 e8af50a3 bellard
2274 3b89f26c blueswir1
target_ulong helper_udiv(target_ulong a, target_ulong b)
2275 3b89f26c blueswir1
{
2276 3b89f26c blueswir1
    uint64_t x0;
2277 3b89f26c blueswir1
    uint32_t x1;
2278 3b89f26c blueswir1
2279 3b89f26c blueswir1
    x0 = a | ((uint64_t) (env->y) << 32);
2280 3b89f26c blueswir1
    x1 = b;
2281 3b89f26c blueswir1
2282 3b89f26c blueswir1
    if (x1 == 0) {
2283 3b89f26c blueswir1
        raise_exception(TT_DIV_ZERO);
2284 3b89f26c blueswir1
    }
2285 3b89f26c blueswir1
2286 3b89f26c blueswir1
    x0 = x0 / x1;
2287 3b89f26c blueswir1
    if (x0 > 0xffffffff) {
2288 3b89f26c blueswir1
        env->cc_src2 = 1;
2289 3b89f26c blueswir1
        return 0xffffffff;
2290 3b89f26c blueswir1
    } else {
2291 3b89f26c blueswir1
        env->cc_src2 = 0;
2292 3b89f26c blueswir1
        return x0;
2293 3b89f26c blueswir1
    }
2294 3b89f26c blueswir1
}
2295 3b89f26c blueswir1
2296 3b89f26c blueswir1
target_ulong helper_sdiv(target_ulong a, target_ulong b)
2297 3b89f26c blueswir1
{
2298 3b89f26c blueswir1
    int64_t x0;
2299 3b89f26c blueswir1
    int32_t x1;
2300 3b89f26c blueswir1
2301 3b89f26c blueswir1
    x0 = a | ((int64_t) (env->y) << 32);
2302 3b89f26c blueswir1
    x1 = b;
2303 3b89f26c blueswir1
2304 3b89f26c blueswir1
    if (x1 == 0) {
2305 3b89f26c blueswir1
        raise_exception(TT_DIV_ZERO);
2306 3b89f26c blueswir1
    }
2307 3b89f26c blueswir1
2308 3b89f26c blueswir1
    x0 = x0 / x1;
2309 3b89f26c blueswir1
    if ((int32_t) x0 != x0) {
2310 3b89f26c blueswir1
        env->cc_src2 = 1;
2311 3b89f26c blueswir1
        return x0 < 0? 0x80000000: 0x7fffffff;
2312 3b89f26c blueswir1
    } else {
2313 3b89f26c blueswir1
        env->cc_src2 = 0;
2314 3b89f26c blueswir1
        return x0;
2315 3b89f26c blueswir1
    }
2316 3b89f26c blueswir1
}
2317 3b89f26c blueswir1
2318 1a2fb1c0 blueswir1
uint64_t helper_pack64(target_ulong high, target_ulong low)
2319 1a2fb1c0 blueswir1
{
2320 1a2fb1c0 blueswir1
    return ((uint64_t)high << 32) | (uint64_t)(low & 0xffffffff);
2321 1a2fb1c0 blueswir1
}
2322 1a2fb1c0 blueswir1
2323 7fa76c0b blueswir1
void helper_stdf(target_ulong addr, int mem_idx)
2324 7fa76c0b blueswir1
{
2325 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2326 7fa76c0b blueswir1
#if !defined(CONFIG_USER_ONLY)
2327 7fa76c0b blueswir1
    switch (mem_idx) {
2328 7fa76c0b blueswir1
    case 0:
2329 c2bc0e38 blueswir1
        stfq_user(addr, DT0);
2330 7fa76c0b blueswir1
        break;
2331 7fa76c0b blueswir1
    case 1:
2332 c2bc0e38 blueswir1
        stfq_kernel(addr, DT0);
2333 7fa76c0b blueswir1
        break;
2334 7fa76c0b blueswir1
#ifdef TARGET_SPARC64
2335 7fa76c0b blueswir1
    case 2:
2336 c2bc0e38 blueswir1
        stfq_hypv(addr, DT0);
2337 7fa76c0b blueswir1
        break;
2338 7fa76c0b blueswir1
#endif
2339 7fa76c0b blueswir1
    default:
2340 7fa76c0b blueswir1
        break;
2341 7fa76c0b blueswir1
    }
2342 7fa76c0b blueswir1
#else
2343 2cade6a3 blueswir1
    address_mask(env, &addr);
2344 c2bc0e38 blueswir1
    stfq_raw(addr, DT0);
2345 7fa76c0b blueswir1
#endif
2346 7fa76c0b blueswir1
}
2347 7fa76c0b blueswir1
2348 7fa76c0b blueswir1
void helper_lddf(target_ulong addr, int mem_idx)
2349 7fa76c0b blueswir1
{
2350 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2351 7fa76c0b blueswir1
#if !defined(CONFIG_USER_ONLY)
2352 7fa76c0b blueswir1
    switch (mem_idx) {
2353 7fa76c0b blueswir1
    case 0:
2354 c2bc0e38 blueswir1
        DT0 = ldfq_user(addr);
2355 7fa76c0b blueswir1
        break;
2356 7fa76c0b blueswir1
    case 1:
2357 c2bc0e38 blueswir1
        DT0 = ldfq_kernel(addr);
2358 7fa76c0b blueswir1
        break;
2359 7fa76c0b blueswir1
#ifdef TARGET_SPARC64
2360 7fa76c0b blueswir1
    case 2:
2361 c2bc0e38 blueswir1
        DT0 = ldfq_hypv(addr);
2362 7fa76c0b blueswir1
        break;
2363 7fa76c0b blueswir1
#endif
2364 7fa76c0b blueswir1
    default:
2365 7fa76c0b blueswir1
        break;
2366 7fa76c0b blueswir1
    }
2367 7fa76c0b blueswir1
#else
2368 2cade6a3 blueswir1
    address_mask(env, &addr);
2369 c2bc0e38 blueswir1
    DT0 = ldfq_raw(addr);
2370 7fa76c0b blueswir1
#endif
2371 7fa76c0b blueswir1
}
2372 7fa76c0b blueswir1
2373 64a88d5d blueswir1
void helper_ldqf(target_ulong addr, int mem_idx)
2374 7fa76c0b blueswir1
{
2375 7fa76c0b blueswir1
    // XXX add 128 bit load
2376 7fa76c0b blueswir1
    CPU_QuadU u;
2377 7fa76c0b blueswir1
2378 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2379 64a88d5d blueswir1
#if !defined(CONFIG_USER_ONLY)
2380 64a88d5d blueswir1
    switch (mem_idx) {
2381 64a88d5d blueswir1
    case 0:
2382 c2bc0e38 blueswir1
        u.ll.upper = ldq_user(addr);
2383 c2bc0e38 blueswir1
        u.ll.lower = ldq_user(addr + 8);
2384 64a88d5d blueswir1
        QT0 = u.q;
2385 64a88d5d blueswir1
        break;
2386 64a88d5d blueswir1
    case 1:
2387 c2bc0e38 blueswir1
        u.ll.upper = ldq_kernel(addr);
2388 c2bc0e38 blueswir1
        u.ll.lower = ldq_kernel(addr + 8);
2389 64a88d5d blueswir1
        QT0 = u.q;
2390 64a88d5d blueswir1
        break;
2391 64a88d5d blueswir1
#ifdef TARGET_SPARC64
2392 64a88d5d blueswir1
    case 2:
2393 c2bc0e38 blueswir1
        u.ll.upper = ldq_hypv(addr);
2394 c2bc0e38 blueswir1
        u.ll.lower = ldq_hypv(addr + 8);
2395 64a88d5d blueswir1
        QT0 = u.q;
2396 64a88d5d blueswir1
        break;
2397 64a88d5d blueswir1
#endif
2398 64a88d5d blueswir1
    default:
2399 64a88d5d blueswir1
        break;
2400 64a88d5d blueswir1
    }
2401 64a88d5d blueswir1
#else
2402 2cade6a3 blueswir1
    address_mask(env, &addr);
2403 c2bc0e38 blueswir1
    u.ll.upper = ldq_raw(addr);
2404 c2bc0e38 blueswir1
    u.ll.lower = ldq_raw((addr + 8) & 0xffffffffULL);
2405 7fa76c0b blueswir1
    QT0 = u.q;
2406 64a88d5d blueswir1
#endif
2407 7fa76c0b blueswir1
}
2408 7fa76c0b blueswir1
2409 64a88d5d blueswir1
void helper_stqf(target_ulong addr, int mem_idx)
2410 7fa76c0b blueswir1
{
2411 7fa76c0b blueswir1
    // XXX add 128 bit store
2412 7fa76c0b blueswir1
    CPU_QuadU u;
2413 7fa76c0b blueswir1
2414 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2415 64a88d5d blueswir1
#if !defined(CONFIG_USER_ONLY)
2416 64a88d5d blueswir1
    switch (mem_idx) {
2417 64a88d5d blueswir1
    case 0:
2418 64a88d5d blueswir1
        u.q = QT0;
2419 c2bc0e38 blueswir1
        stq_user(addr, u.ll.upper);
2420 c2bc0e38 blueswir1
        stq_user(addr + 8, u.ll.lower);
2421 64a88d5d blueswir1
        break;
2422 64a88d5d blueswir1
    case 1:
2423 64a88d5d blueswir1
        u.q = QT0;
2424 c2bc0e38 blueswir1
        stq_kernel(addr, u.ll.upper);
2425 c2bc0e38 blueswir1
        stq_kernel(addr + 8, u.ll.lower);
2426 64a88d5d blueswir1
        break;
2427 64a88d5d blueswir1
#ifdef TARGET_SPARC64
2428 64a88d5d blueswir1
    case 2:
2429 64a88d5d blueswir1
        u.q = QT0;
2430 c2bc0e38 blueswir1
        stq_hypv(addr, u.ll.upper);
2431 c2bc0e38 blueswir1
        stq_hypv(addr + 8, u.ll.lower);
2432 64a88d5d blueswir1
        break;
2433 64a88d5d blueswir1
#endif
2434 64a88d5d blueswir1
    default:
2435 64a88d5d blueswir1
        break;
2436 64a88d5d blueswir1
    }
2437 64a88d5d blueswir1
#else
2438 7fa76c0b blueswir1
    u.q = QT0;
2439 2cade6a3 blueswir1
    address_mask(env, &addr);
2440 c2bc0e38 blueswir1
    stq_raw(addr, u.ll.upper);
2441 c2bc0e38 blueswir1
    stq_raw((addr + 8) & 0xffffffffULL, u.ll.lower);
2442 7fa76c0b blueswir1
#endif
2443 64a88d5d blueswir1
}
2444 7fa76c0b blueswir1
2445 8d5f07fa bellard
void helper_ldfsr(void)
2446 e8af50a3 bellard
{
2447 7a0e1f41 bellard
    int rnd_mode;
2448 bb5529bb blueswir1
2449 bb5529bb blueswir1
    PUT_FSR32(env, *((uint32_t *) &FT0));
2450 e8af50a3 bellard
    switch (env->fsr & FSR_RD_MASK) {
2451 e8af50a3 bellard
    case FSR_RD_NEAREST:
2452 7a0e1f41 bellard
        rnd_mode = float_round_nearest_even;
2453 0f8a249a blueswir1
        break;
2454 ed910241 bellard
    default:
2455 e8af50a3 bellard
    case FSR_RD_ZERO:
2456 7a0e1f41 bellard
        rnd_mode = float_round_to_zero;
2457 0f8a249a blueswir1
        break;
2458 e8af50a3 bellard
    case FSR_RD_POS:
2459 7a0e1f41 bellard
        rnd_mode = float_round_up;
2460 0f8a249a blueswir1
        break;
2461 e8af50a3 bellard
    case FSR_RD_NEG:
2462 7a0e1f41 bellard
        rnd_mode = float_round_down;
2463 0f8a249a blueswir1
        break;
2464 e8af50a3 bellard
    }
2465 7a0e1f41 bellard
    set_float_rounding_mode(rnd_mode, &env->fp_status);
2466 e8af50a3 bellard
}
2467 e80cfcfc bellard
2468 bb5529bb blueswir1
void helper_stfsr(void)
2469 bb5529bb blueswir1
{
2470 bb5529bb blueswir1
    *((uint32_t *) &FT0) = GET_FSR32(env);
2471 bb5529bb blueswir1
}
2472 bb5529bb blueswir1
2473 bb5529bb blueswir1
void helper_debug(void)
2474 e80cfcfc bellard
{
2475 e80cfcfc bellard
    env->exception_index = EXCP_DEBUG;
2476 e80cfcfc bellard
    cpu_loop_exit();
2477 e80cfcfc bellard
}
2478 af7bf89b bellard
2479 3475187d bellard
#ifndef TARGET_SPARC64
2480 72a9747b blueswir1
/* XXX: use another pointer for %iN registers to avoid slow wrapping
2481 72a9747b blueswir1
   handling ? */
2482 72a9747b blueswir1
void helper_save(void)
2483 72a9747b blueswir1
{
2484 72a9747b blueswir1
    uint32_t cwp;
2485 72a9747b blueswir1
2486 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2487 72a9747b blueswir1
    if (env->wim & (1 << cwp)) {
2488 72a9747b blueswir1
        raise_exception(TT_WIN_OVF);
2489 72a9747b blueswir1
    }
2490 72a9747b blueswir1
    set_cwp(cwp);
2491 72a9747b blueswir1
}
2492 72a9747b blueswir1
2493 72a9747b blueswir1
void helper_restore(void)
2494 72a9747b blueswir1
{
2495 72a9747b blueswir1
    uint32_t cwp;
2496 72a9747b blueswir1
2497 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1);
2498 72a9747b blueswir1
    if (env->wim & (1 << cwp)) {
2499 72a9747b blueswir1
        raise_exception(TT_WIN_UNF);
2500 72a9747b blueswir1
    }
2501 72a9747b blueswir1
    set_cwp(cwp);
2502 72a9747b blueswir1
}
2503 72a9747b blueswir1
2504 1a2fb1c0 blueswir1
void helper_wrpsr(target_ulong new_psr)
2505 af7bf89b bellard
{
2506 1a14026e blueswir1
    if ((new_psr & PSR_CWP) >= env->nwindows)
2507 d4218d99 blueswir1
        raise_exception(TT_ILL_INSN);
2508 d4218d99 blueswir1
    else
2509 1a2fb1c0 blueswir1
        PUT_PSR(env, new_psr);
2510 af7bf89b bellard
}
2511 af7bf89b bellard
2512 1a2fb1c0 blueswir1
target_ulong helper_rdpsr(void)
2513 af7bf89b bellard
{
2514 1a2fb1c0 blueswir1
    return GET_PSR(env);
2515 af7bf89b bellard
}
2516 3475187d bellard
2517 3475187d bellard
#else
2518 72a9747b blueswir1
/* XXX: use another pointer for %iN registers to avoid slow wrapping
2519 72a9747b blueswir1
   handling ? */
2520 72a9747b blueswir1
void helper_save(void)
2521 72a9747b blueswir1
{
2522 72a9747b blueswir1
    uint32_t cwp;
2523 72a9747b blueswir1
2524 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2525 72a9747b blueswir1
    if (env->cansave == 0) {
2526 72a9747b blueswir1
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
2527 72a9747b blueswir1
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2528 72a9747b blueswir1
                                    ((env->wstate & 0x7) << 2)));
2529 72a9747b blueswir1
    } else {
2530 72a9747b blueswir1
        if (env->cleanwin - env->canrestore == 0) {
2531 72a9747b blueswir1
            // XXX Clean windows without trap
2532 72a9747b blueswir1
            raise_exception(TT_CLRWIN);
2533 72a9747b blueswir1
        } else {
2534 72a9747b blueswir1
            env->cansave--;
2535 72a9747b blueswir1
            env->canrestore++;
2536 72a9747b blueswir1
            set_cwp(cwp);
2537 72a9747b blueswir1
        }
2538 72a9747b blueswir1
    }
2539 72a9747b blueswir1
}
2540 72a9747b blueswir1
2541 72a9747b blueswir1
void helper_restore(void)
2542 72a9747b blueswir1
{
2543 72a9747b blueswir1
    uint32_t cwp;
2544 72a9747b blueswir1
2545 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1);
2546 72a9747b blueswir1
    if (env->canrestore == 0) {
2547 72a9747b blueswir1
        raise_exception(TT_FILL | (env->otherwin != 0 ?
2548 72a9747b blueswir1
                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2549 72a9747b blueswir1
                                   ((env->wstate & 0x7) << 2)));
2550 72a9747b blueswir1
    } else {
2551 72a9747b blueswir1
        env->cansave++;
2552 72a9747b blueswir1
        env->canrestore--;
2553 72a9747b blueswir1
        set_cwp(cwp);
2554 72a9747b blueswir1
    }
2555 72a9747b blueswir1
}
2556 72a9747b blueswir1
2557 72a9747b blueswir1
void helper_flushw(void)
2558 72a9747b blueswir1
{
2559 1a14026e blueswir1
    if (env->cansave != env->nwindows - 2) {
2560 72a9747b blueswir1
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
2561 72a9747b blueswir1
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2562 72a9747b blueswir1
                                    ((env->wstate & 0x7) << 2)));
2563 72a9747b blueswir1
    }
2564 72a9747b blueswir1
}
2565 72a9747b blueswir1
2566 72a9747b blueswir1
void helper_saved(void)
2567 72a9747b blueswir1
{
2568 72a9747b blueswir1
    env->cansave++;
2569 72a9747b blueswir1
    if (env->otherwin == 0)
2570 72a9747b blueswir1
        env->canrestore--;
2571 72a9747b blueswir1
    else
2572 72a9747b blueswir1
        env->otherwin--;
2573 72a9747b blueswir1
}
2574 72a9747b blueswir1
2575 72a9747b blueswir1
void helper_restored(void)
2576 72a9747b blueswir1
{
2577 72a9747b blueswir1
    env->canrestore++;
2578 1a14026e blueswir1
    if (env->cleanwin < env->nwindows - 1)
2579 72a9747b blueswir1
        env->cleanwin++;
2580 72a9747b blueswir1
    if (env->otherwin == 0)
2581 72a9747b blueswir1
        env->cansave--;
2582 72a9747b blueswir1
    else
2583 72a9747b blueswir1
        env->otherwin--;
2584 72a9747b blueswir1
}
2585 72a9747b blueswir1
2586 d35527d9 blueswir1
target_ulong helper_rdccr(void)
2587 d35527d9 blueswir1
{
2588 d35527d9 blueswir1
    return GET_CCR(env);
2589 d35527d9 blueswir1
}
2590 d35527d9 blueswir1
2591 d35527d9 blueswir1
void helper_wrccr(target_ulong new_ccr)
2592 d35527d9 blueswir1
{
2593 d35527d9 blueswir1
    PUT_CCR(env, new_ccr);
2594 d35527d9 blueswir1
}
2595 d35527d9 blueswir1
2596 d35527d9 blueswir1
// CWP handling is reversed in V9, but we still use the V8 register
2597 d35527d9 blueswir1
// order.
2598 d35527d9 blueswir1
target_ulong helper_rdcwp(void)
2599 d35527d9 blueswir1
{
2600 d35527d9 blueswir1
    return GET_CWP64(env);
2601 d35527d9 blueswir1
}
2602 d35527d9 blueswir1
2603 d35527d9 blueswir1
void helper_wrcwp(target_ulong new_cwp)
2604 d35527d9 blueswir1
{
2605 d35527d9 blueswir1
    PUT_CWP64(env, new_cwp);
2606 d35527d9 blueswir1
}
2607 3475187d bellard
2608 1f5063fb blueswir1
// This function uses non-native bit order
2609 1f5063fb blueswir1
#define GET_FIELD(X, FROM, TO)                                  \
2610 1f5063fb blueswir1
    ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
2611 1f5063fb blueswir1
2612 1f5063fb blueswir1
// This function uses the order in the manuals, i.e. bit 0 is 2^0
2613 1f5063fb blueswir1
#define GET_FIELD_SP(X, FROM, TO)               \
2614 1f5063fb blueswir1
    GET_FIELD(X, 63 - (TO), 63 - (FROM))
2615 1f5063fb blueswir1
2616 1f5063fb blueswir1
target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
2617 1f5063fb blueswir1
{
2618 1f5063fb blueswir1
    return (GET_FIELD_SP(pixel_addr, 60, 63) << (17 + 2 * cubesize)) |
2619 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 39, 39 + cubesize - 1) << (17 + cubesize)) |
2620 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 17 + cubesize - 1, 17) << 17) |
2621 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 56, 59) << 13) |
2622 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 35, 38) << 9) |
2623 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 13, 16) << 5) |
2624 1f5063fb blueswir1
        (((pixel_addr >> 55) & 1) << 4) |
2625 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 33, 34) << 2) |
2626 1f5063fb blueswir1
        GET_FIELD_SP(pixel_addr, 11, 12);
2627 1f5063fb blueswir1
}
2628 1f5063fb blueswir1
2629 1f5063fb blueswir1
target_ulong helper_alignaddr(target_ulong addr, target_ulong offset)
2630 1f5063fb blueswir1
{
2631 1f5063fb blueswir1
    uint64_t tmp;
2632 1f5063fb blueswir1
2633 1f5063fb blueswir1
    tmp = addr + offset;
2634 1f5063fb blueswir1
    env->gsr &= ~7ULL;
2635 1f5063fb blueswir1
    env->gsr |= tmp & 7ULL;
2636 1f5063fb blueswir1
    return tmp & ~7ULL;
2637 1f5063fb blueswir1
}
2638 1f5063fb blueswir1
2639 1a2fb1c0 blueswir1
target_ulong helper_popc(target_ulong val)
2640 3475187d bellard
{
2641 1a2fb1c0 blueswir1
    return ctpop64(val);
2642 3475187d bellard
}
2643 83469015 bellard
2644 83469015 bellard
static inline uint64_t *get_gregset(uint64_t pstate)
2645 83469015 bellard
{
2646 83469015 bellard
    switch (pstate) {
2647 83469015 bellard
    default:
2648 83469015 bellard
    case 0:
2649 0f8a249a blueswir1
        return env->bgregs;
2650 83469015 bellard
    case PS_AG:
2651 0f8a249a blueswir1
        return env->agregs;
2652 83469015 bellard
    case PS_MG:
2653 0f8a249a blueswir1
        return env->mgregs;
2654 83469015 bellard
    case PS_IG:
2655 0f8a249a blueswir1
        return env->igregs;
2656 83469015 bellard
    }
2657 83469015 bellard
}
2658 83469015 bellard
2659 f2bc7e7f blueswir1
void change_pstate(uint64_t new_pstate)
2660 83469015 bellard
{
2661 8f1f22f6 blueswir1
    uint64_t pstate_regs, new_pstate_regs;
2662 83469015 bellard
    uint64_t *src, *dst;
2663 83469015 bellard
2664 83469015 bellard
    pstate_regs = env->pstate & 0xc01;
2665 83469015 bellard
    new_pstate_regs = new_pstate & 0xc01;
2666 83469015 bellard
    if (new_pstate_regs != pstate_regs) {
2667 0f8a249a blueswir1
        // Switch global register bank
2668 0f8a249a blueswir1
        src = get_gregset(new_pstate_regs);
2669 0f8a249a blueswir1
        dst = get_gregset(pstate_regs);
2670 0f8a249a blueswir1
        memcpy32(dst, env->gregs);
2671 0f8a249a blueswir1
        memcpy32(env->gregs, src);
2672 83469015 bellard
    }
2673 83469015 bellard
    env->pstate = new_pstate;
2674 83469015 bellard
}
2675 83469015 bellard
2676 1a2fb1c0 blueswir1
void helper_wrpstate(target_ulong new_state)
2677 8f1f22f6 blueswir1
{
2678 1a2fb1c0 blueswir1
    change_pstate(new_state & 0xf3f);
2679 8f1f22f6 blueswir1
}
2680 8f1f22f6 blueswir1
2681 1a2fb1c0 blueswir1
void helper_done(void)
2682 83469015 bellard
{
2683 83469015 bellard
    env->tl--;
2684 375ee38b blueswir1
    env->tsptr = &env->ts[env->tl];
2685 375ee38b blueswir1
    env->pc = env->tsptr->tpc;
2686 375ee38b blueswir1
    env->npc = env->tsptr->tnpc + 4;
2687 375ee38b blueswir1
    PUT_CCR(env, env->tsptr->tstate >> 32);
2688 375ee38b blueswir1
    env->asi = (env->tsptr->tstate >> 24) & 0xff;
2689 375ee38b blueswir1
    change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
2690 375ee38b blueswir1
    PUT_CWP64(env, env->tsptr->tstate & 0xff);
2691 83469015 bellard
}
2692 83469015 bellard
2693 1a2fb1c0 blueswir1
void helper_retry(void)
2694 83469015 bellard
{
2695 83469015 bellard
    env->tl--;
2696 375ee38b blueswir1
    env->tsptr = &env->ts[env->tl];
2697 375ee38b blueswir1
    env->pc = env->tsptr->tpc;
2698 375ee38b blueswir1
    env->npc = env->tsptr->tnpc;
2699 375ee38b blueswir1
    PUT_CCR(env, env->tsptr->tstate >> 32);
2700 375ee38b blueswir1
    env->asi = (env->tsptr->tstate >> 24) & 0xff;
2701 375ee38b blueswir1
    change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
2702 375ee38b blueswir1
    PUT_CWP64(env, env->tsptr->tstate & 0xff);
2703 83469015 bellard
}
2704 3475187d bellard
#endif
2705 ee5bbe38 bellard
2706 f2bc7e7f blueswir1
void cpu_set_cwp(CPUState *env1, int new_cwp)
2707 ee5bbe38 bellard
{
2708 ee5bbe38 bellard
    /* put the modified wrap registers at their proper location */
2709 9fac3a3a blueswir1
    if (env1->cwp == env1->nwindows - 1)
2710 9fac3a3a blueswir1
        memcpy32(env1->regbase, env1->regbase + env1->nwindows * 16);
2711 f2bc7e7f blueswir1
    env1->cwp = new_cwp;
2712 ee5bbe38 bellard
    /* put the wrap registers at their temporary location */
2713 9fac3a3a blueswir1
    if (new_cwp == env1->nwindows - 1)
2714 9fac3a3a blueswir1
        memcpy32(env1->regbase + env1->nwindows * 16, env1->regbase);
2715 f2bc7e7f blueswir1
    env1->regwptr = env1->regbase + (new_cwp * 16);
2716 ee5bbe38 bellard
}
2717 ee5bbe38 bellard
2718 f2bc7e7f blueswir1
void set_cwp(int new_cwp)
2719 ee5bbe38 bellard
{
2720 f2bc7e7f blueswir1
    cpu_set_cwp(env, new_cwp);
2721 ee5bbe38 bellard
}
2722 ee5bbe38 bellard
2723 f2bc7e7f blueswir1
void helper_flush(target_ulong addr)
2724 ee5bbe38 bellard
{
2725 f2bc7e7f blueswir1
    addr &= ~7;
2726 f2bc7e7f blueswir1
    tb_invalidate_page_range(addr, addr + 8);
2727 ee5bbe38 bellard
}
2728 ee5bbe38 bellard
2729 5fafdf24 ths
#if !defined(CONFIG_USER_ONLY)
2730 ee5bbe38 bellard
2731 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
2732 d2889a3e blueswir1
                                void *retaddr);
2733 d2889a3e blueswir1
2734 ee5bbe38 bellard
#define MMUSUFFIX _mmu
2735 d2889a3e blueswir1
#define ALIGNED_ONLY
2736 ee5bbe38 bellard
2737 ee5bbe38 bellard
#define SHIFT 0
2738 ee5bbe38 bellard
#include "softmmu_template.h"
2739 ee5bbe38 bellard
2740 ee5bbe38 bellard
#define SHIFT 1
2741 ee5bbe38 bellard
#include "softmmu_template.h"
2742 ee5bbe38 bellard
2743 ee5bbe38 bellard
#define SHIFT 2
2744 ee5bbe38 bellard
#include "softmmu_template.h"
2745 ee5bbe38 bellard
2746 ee5bbe38 bellard
#define SHIFT 3
2747 ee5bbe38 bellard
#include "softmmu_template.h"
2748 ee5bbe38 bellard
2749 c2bc0e38 blueswir1
/* XXX: make it generic ? */
2750 c2bc0e38 blueswir1
static void cpu_restore_state2(void *retaddr)
2751 c2bc0e38 blueswir1
{
2752 c2bc0e38 blueswir1
    TranslationBlock *tb;
2753 c2bc0e38 blueswir1
    unsigned long pc;
2754 c2bc0e38 blueswir1
2755 c2bc0e38 blueswir1
    if (retaddr) {
2756 c2bc0e38 blueswir1
        /* now we have a real cpu fault */
2757 c2bc0e38 blueswir1
        pc = (unsigned long)retaddr;
2758 c2bc0e38 blueswir1
        tb = tb_find_pc(pc);
2759 c2bc0e38 blueswir1
        if (tb) {
2760 c2bc0e38 blueswir1
            /* the PC is inside the translated code. It means that we have
2761 c2bc0e38 blueswir1
               a virtual CPU fault */
2762 c2bc0e38 blueswir1
            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
2763 c2bc0e38 blueswir1
        }
2764 c2bc0e38 blueswir1
    }
2765 c2bc0e38 blueswir1
}
2766 c2bc0e38 blueswir1
2767 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
2768 d2889a3e blueswir1
                                void *retaddr)
2769 d2889a3e blueswir1
{
2770 94554550 blueswir1
#ifdef DEBUG_UNALIGNED
2771 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
2772 c2bc0e38 blueswir1
           "\n", addr, env->pc);
2773 94554550 blueswir1
#endif
2774 c2bc0e38 blueswir1
    cpu_restore_state2(retaddr);
2775 94554550 blueswir1
    raise_exception(TT_UNALIGNED);
2776 d2889a3e blueswir1
}
2777 ee5bbe38 bellard
2778 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
2779 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
2780 ee5bbe38 bellard
   from generated code or from helper.c) */
2781 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
2782 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
2783 ee5bbe38 bellard
{
2784 ee5bbe38 bellard
    int ret;
2785 ee5bbe38 bellard
    CPUState *saved_env;
2786 ee5bbe38 bellard
2787 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
2788 ee5bbe38 bellard
       generated code */
2789 ee5bbe38 bellard
    saved_env = env;
2790 ee5bbe38 bellard
    env = cpu_single_env;
2791 ee5bbe38 bellard
2792 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
2793 ee5bbe38 bellard
    if (ret) {
2794 c2bc0e38 blueswir1
        cpu_restore_state2(retaddr);
2795 ee5bbe38 bellard
        cpu_loop_exit();
2796 ee5bbe38 bellard
    }
2797 ee5bbe38 bellard
    env = saved_env;
2798 ee5bbe38 bellard
}
2799 ee5bbe38 bellard
2800 ee5bbe38 bellard
#endif
2801 6c36d3fa blueswir1
2802 6c36d3fa blueswir1
#ifndef TARGET_SPARC64
2803 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
2804 6c36d3fa blueswir1
                          int is_asi)
2805 6c36d3fa blueswir1
{
2806 6c36d3fa blueswir1
    CPUState *saved_env;
2807 6c36d3fa blueswir1
2808 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
2809 6c36d3fa blueswir1
       generated code */
2810 6c36d3fa blueswir1
    saved_env = env;
2811 6c36d3fa blueswir1
    env = cpu_single_env;
2812 8543e2cf blueswir1
#ifdef DEBUG_UNASSIGNED
2813 8543e2cf blueswir1
    if (is_asi)
2814 77f193da blueswir1
        printf("Unassigned mem %s access to " TARGET_FMT_plx
2815 77f193da blueswir1
               " asi 0x%02x from " TARGET_FMT_lx "\n",
2816 8543e2cf blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", addr, is_asi,
2817 8543e2cf blueswir1
               env->pc);
2818 8543e2cf blueswir1
    else
2819 8543e2cf blueswir1
        printf("Unassigned mem %s access to " TARGET_FMT_plx " from "
2820 8543e2cf blueswir1
               TARGET_FMT_lx "\n",
2821 8543e2cf blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", addr, env->pc);
2822 8543e2cf blueswir1
#endif
2823 6c36d3fa blueswir1
    if (env->mmuregs[3]) /* Fault status register */
2824 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
2825 6c36d3fa blueswir1
    if (is_asi)
2826 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 16;
2827 6c36d3fa blueswir1
    if (env->psrs)
2828 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 5;
2829 6c36d3fa blueswir1
    if (is_exec)
2830 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 6;
2831 6c36d3fa blueswir1
    if (is_write)
2832 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 7;
2833 6c36d3fa blueswir1
    env->mmuregs[3] |= (5 << 2) | 2;
2834 6c36d3fa blueswir1
    env->mmuregs[4] = addr; /* Fault address register */
2835 6c36d3fa blueswir1
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
2836 1b2e93c1 blueswir1
        if (is_exec)
2837 1b2e93c1 blueswir1
            raise_exception(TT_CODE_ACCESS);
2838 1b2e93c1 blueswir1
        else
2839 1b2e93c1 blueswir1
            raise_exception(TT_DATA_ACCESS);
2840 6c36d3fa blueswir1
    }
2841 6c36d3fa blueswir1
    env = saved_env;
2842 6c36d3fa blueswir1
}
2843 6c36d3fa blueswir1
#else
2844 5dcb6b91 blueswir1
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
2845 6c36d3fa blueswir1
                          int is_asi)
2846 6c36d3fa blueswir1
{
2847 6c36d3fa blueswir1
#ifdef DEBUG_UNASSIGNED
2848 6c36d3fa blueswir1
    CPUState *saved_env;
2849 6c36d3fa blueswir1
2850 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
2851 6c36d3fa blueswir1
       generated code */
2852 6c36d3fa blueswir1
    saved_env = env;
2853 6c36d3fa blueswir1
    env = cpu_single_env;
2854 77f193da blueswir1
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
2855 77f193da blueswir1
           "\n", addr, env->pc);
2856 6c36d3fa blueswir1
    env = saved_env;
2857 6c36d3fa blueswir1
#endif
2858 1b2e93c1 blueswir1
    if (is_exec)
2859 1b2e93c1 blueswir1
        raise_exception(TT_CODE_ACCESS);
2860 1b2e93c1 blueswir1
    else
2861 1b2e93c1 blueswir1
        raise_exception(TT_DATA_ACCESS);
2862 6c36d3fa blueswir1
}
2863 6c36d3fa blueswir1
#endif