Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ f7350b47

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