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