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