Convert subx
[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 static uint32_t compute_all_addx(void)
864 {
865     uint32_t ret;
866
867     ret = get_NZ_icc(CC_DST);
868     ret |= get_C_add_icc(CC_DST - CC_SRC2, CC_SRC);
869     ret |= get_C_add_icc(CC_DST, CC_SRC);
870     ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
871     return ret;
872 }
873
874 static uint32_t compute_C_addx(void)
875 {
876     uint32_t ret;
877
878     ret = get_C_add_icc(CC_DST - CC_SRC2, CC_SRC);
879     ret |= get_C_add_icc(CC_DST, CC_SRC);
880     return ret;
881 }
882
883 #ifdef TARGET_SPARC64
884 static uint32_t compute_all_addx_xcc(void)
885 {
886     uint32_t ret;
887
888     ret = get_NZ_xcc(CC_DST);
889     ret |= get_C_add_xcc(CC_DST - CC_SRC2, CC_SRC);
890     ret |= get_C_add_xcc(CC_DST, CC_SRC);
891     ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2);
892     return ret;
893 }
894
895 static uint32_t compute_C_addx_xcc(void)
896 {
897     uint32_t ret;
898
899     ret = get_C_add_xcc(CC_DST - CC_SRC2, CC_SRC);
900     ret |= get_C_add_xcc(CC_DST, CC_SRC);
901     return ret;
902 }
903 #endif
904
905 static inline uint32_t get_C_sub_icc(target_ulong src1, target_ulong src2)
906 {
907     uint32_t ret = 0;
908
909     if ((src1 & 0xffffffffULL) < (src2 & 0xffffffffULL))
910         ret |= PSR_CARRY;
911     return ret;
912 }
913
914 static inline uint32_t get_V_sub_icc(target_ulong dst, target_ulong src1,
915                                      target_ulong src2)
916 {
917     uint32_t ret = 0;
918
919     if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 31))
920         ret |= PSR_OVF;
921     return ret;
922 }
923
924 static uint32_t compute_all_sub(void)
925 {
926     uint32_t ret;
927
928     ret = get_NZ_icc(CC_DST);
929     ret |= get_C_sub_icc(CC_SRC, CC_SRC2);
930     ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
931     return ret;
932 }
933
934 static uint32_t compute_C_sub(void)
935 {
936     return get_C_sub_icc(CC_SRC, CC_SRC2);
937 }
938
939 #ifdef TARGET_SPARC64
940 static inline uint32_t get_C_sub_xcc(target_ulong src1, target_ulong src2)
941 {
942     uint32_t ret = 0;
943
944     if (src1 < src2)
945         ret |= PSR_CARRY;
946     return ret;
947 }
948
949 static inline uint32_t get_V_sub_xcc(target_ulong dst, target_ulong src1,
950                                      target_ulong src2)
951 {
952     uint32_t ret = 0;
953
954     if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 63))
955         ret |= PSR_OVF;
956     return ret;
957 }
958
959 static uint32_t compute_all_sub_xcc(void)
960 {
961     uint32_t ret;
962
963     ret = get_NZ_xcc(CC_DST);
964     ret |= get_C_sub_xcc(CC_SRC, CC_SRC2);
965     ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2);
966     return ret;
967 }
968
969 static uint32_t compute_C_sub_xcc(void)
970 {
971     return get_C_sub_xcc(CC_SRC, CC_SRC2);
972 }
973 #endif
974
975 static uint32_t compute_all_subx(void)
976 {
977     uint32_t ret;
978
979     ret = get_NZ_icc(CC_DST);
980     ret |= get_C_sub_icc(CC_DST - CC_SRC2, CC_SRC);
981     ret |= get_C_sub_icc(CC_DST, CC_SRC2);
982     ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
983     return ret;
984 }
985
986 static uint32_t compute_C_subx(void)
987 {
988     uint32_t ret;
989
990     ret = get_C_sub_icc(CC_DST - CC_SRC2, CC_SRC);
991     ret |= get_C_sub_icc(CC_DST, CC_SRC2);
992     return ret;
993 }
994
995 #ifdef TARGET_SPARC64
996 static uint32_t compute_all_subx_xcc(void)
997 {
998     uint32_t ret;
999
1000     ret = get_NZ_xcc(CC_DST);
1001     ret |= get_C_sub_xcc(CC_DST - CC_SRC2, CC_SRC);
1002     ret |= get_C_sub_xcc(CC_DST, CC_SRC2);
1003     ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2);
1004     return ret;
1005 }
1006
1007 static uint32_t compute_C_subx_xcc(void)
1008 {
1009     uint32_t ret;
1010
1011     ret = get_C_sub_xcc(CC_DST - CC_SRC2, CC_SRC);
1012     ret |= get_C_sub_xcc(CC_DST, CC_SRC2);
1013     return ret;
1014 }
1015 #endif
1016
1017 static uint32_t compute_all_logic(void)
1018 {
1019     return get_NZ_icc(CC_DST);
1020 }
1021
1022 static uint32_t compute_C_logic(void)
1023 {
1024     return 0;
1025 }
1026
1027 #ifdef TARGET_SPARC64
1028 static uint32_t compute_all_logic_xcc(void)
1029 {
1030     return get_NZ_xcc(CC_DST);
1031 }
1032 #endif
1033
1034 typedef struct CCTable {
1035     uint32_t (*compute_all)(void); /* return all the flags */
1036     uint32_t (*compute_c)(void);  /* return the C flag */
1037 } CCTable;
1038
1039 static const CCTable icc_table[CC_OP_NB] = {
1040     /* CC_OP_DYNAMIC should never happen */
1041     [CC_OP_FLAGS] = { compute_all_flags, compute_C_flags },
1042     [CC_OP_ADD] = { compute_all_add, compute_C_add },
1043     [CC_OP_ADDX] = { compute_all_addx, compute_C_addx },
1044     [CC_OP_SUB] = { compute_all_sub, compute_C_sub },
1045     [CC_OP_SUBX] = { compute_all_subx, compute_C_subx },
1046     [CC_OP_LOGIC] = { compute_all_logic, compute_C_logic },
1047 };
1048
1049 #ifdef TARGET_SPARC64
1050 static const CCTable xcc_table[CC_OP_NB] = {
1051     /* CC_OP_DYNAMIC should never happen */
1052     [CC_OP_FLAGS] = { compute_all_flags_xcc, compute_C_flags_xcc },
1053     [CC_OP_ADD] = { compute_all_add_xcc, compute_C_add_xcc },
1054     [CC_OP_ADDX] = { compute_all_addx_xcc, compute_C_addx_xcc },
1055     [CC_OP_SUB] = { compute_all_sub_xcc, compute_C_sub_xcc },
1056     [CC_OP_SUBX] = { compute_all_subx_xcc, compute_C_subx_xcc },
1057     [CC_OP_LOGIC] = { compute_all_logic_xcc, compute_C_logic },
1058 };
1059 #endif
1060
1061 void helper_compute_psr(void)
1062 {
1063     uint32_t new_psr;
1064
1065     new_psr = icc_table[CC_OP].compute_all();
1066     env->psr = new_psr;
1067 #ifdef TARGET_SPARC64
1068     new_psr = xcc_table[CC_OP].compute_all();
1069     env->xcc = new_psr;
1070 #endif
1071     CC_OP = CC_OP_FLAGS;
1072 }
1073
1074 uint32_t helper_compute_C_icc(void)
1075 {
1076     uint32_t ret;
1077
1078     ret = icc_table[CC_OP].compute_c() >> PSR_CARRY_SHIFT;
1079     return ret;
1080 }
1081
1082 #ifdef TARGET_SPARC64
1083 GEN_FCMPS(fcmps_fcc1, float32, 22, 0);
1084 GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
1085 GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
1086
1087 GEN_FCMPS(fcmps_fcc2, float32, 24, 0);
1088 GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
1089 GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
1090
1091 GEN_FCMPS(fcmps_fcc3, float32, 26, 0);
1092 GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
1093 GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
1094
1095 GEN_FCMPS(fcmpes_fcc1, float32, 22, 1);
1096 GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
1097 GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
1098
1099 GEN_FCMPS(fcmpes_fcc2, float32, 24, 1);
1100 GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
1101 GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
1102
1103 GEN_FCMPS(fcmpes_fcc3, float32, 26, 1);
1104 GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
1105 GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
1106 #endif
1107 #undef GEN_FCMPS
1108
1109 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \
1110     defined(DEBUG_MXCC)
1111 static void dump_mxcc(CPUState *env)
1112 {
1113     printf("mxccdata: %016llx %016llx %016llx %016llx\n",
1114            env->mxccdata[0], env->mxccdata[1],
1115            env->mxccdata[2], env->mxccdata[3]);
1116     printf("mxccregs: %016llx %016llx %016llx %016llx\n"
1117            "          %016llx %016llx %016llx %016llx\n",
1118            env->mxccregs[0], env->mxccregs[1],
1119            env->mxccregs[2], env->mxccregs[3],
1120            env->mxccregs[4], env->mxccregs[5],
1121            env->mxccregs[6], env->mxccregs[7]);
1122 }
1123 #endif
1124
1125 #if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)) \
1126     && defined(DEBUG_ASI)
1127 static void dump_asi(const char *txt, target_ulong addr, int asi, int size,
1128                      uint64_t r1)
1129 {
1130     switch (size)
1131     {
1132     case 1:
1133         DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt,
1134                     addr, asi, r1 & 0xff);
1135         break;
1136     case 2:
1137         DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt,
1138                     addr, asi, r1 & 0xffff);
1139         break;
1140     case 4:
1141         DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt,
1142                     addr, asi, r1 & 0xffffffff);
1143         break;
1144     case 8:
1145         DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt,
1146                     addr, asi, r1);
1147         break;
1148     }
1149 }
1150 #endif
1151
1152 #ifndef TARGET_SPARC64
1153 #ifndef CONFIG_USER_ONLY
1154 uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1155 {
1156     uint64_t ret = 0;
1157 #if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
1158     uint32_t last_addr = addr;
1159 #endif
1160
1161     helper_check_align(addr, size - 1);
1162     switch (asi) {
1163     case 2: /* SuperSparc MXCC registers */
1164         switch (addr) {
1165         case 0x01c00a00: /* MXCC control register */
1166             if (size == 8)
1167                 ret = env->mxccregs[3];
1168             else
1169                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1170                              size);
1171             break;
1172         case 0x01c00a04: /* MXCC control register */
1173             if (size == 4)
1174                 ret = env->mxccregs[3];
1175             else
1176                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1177                              size);
1178             break;
1179         case 0x01c00c00: /* Module reset register */
1180             if (size == 8) {
1181                 ret = env->mxccregs[5];
1182                 // should we do something here?
1183             } else
1184                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1185                              size);
1186             break;
1187         case 0x01c00f00: /* MBus port address register */
1188             if (size == 8)
1189                 ret = env->mxccregs[7];
1190             else
1191                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1192                              size);
1193             break;
1194         default:
1195             DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
1196                          size);
1197             break;
1198         }
1199         DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
1200                      "addr = %08x -> ret = %" PRIx64 ","
1201                      "addr = %08x\n", asi, size, sign, last_addr, ret, addr);
1202 #ifdef DEBUG_MXCC
1203         dump_mxcc(env);
1204 #endif
1205         break;
1206     case 3: /* MMU probe */
1207         {
1208             int mmulev;
1209
1210             mmulev = (addr >> 8) & 15;
1211             if (mmulev > 4)
1212                 ret = 0;
1213             else
1214                 ret = mmu_probe(env, addr, mmulev);
1215             DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n",
1216                         addr, mmulev, ret);
1217         }
1218         break;
1219     case 4: /* read MMU regs */
1220         {
1221             int reg = (addr >> 8) & 0x1f;
1222
1223             ret = env->mmuregs[reg];
1224             if (reg == 3) /* Fault status cleared on read */
1225                 env->mmuregs[3] = 0;
1226             else if (reg == 0x13) /* Fault status read */
1227                 ret = env->mmuregs[3];
1228             else if (reg == 0x14) /* Fault address read */
1229                 ret = env->mmuregs[4];
1230             DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
1231         }
1232         break;
1233     case 5: // Turbosparc ITLB Diagnostic
1234     case 6: // Turbosparc DTLB Diagnostic
1235     case 7: // Turbosparc IOTLB Diagnostic
1236         break;
1237     case 9: /* Supervisor code access */
1238         switch(size) {
1239         case 1:
1240             ret = ldub_code(addr);
1241             break;
1242         case 2:
1243             ret = lduw_code(addr);
1244             break;
1245         default:
1246         case 4:
1247             ret = ldl_code(addr);
1248             break;
1249         case 8:
1250             ret = ldq_code(addr);
1251             break;
1252         }
1253         break;
1254     case 0xa: /* User data access */
1255         switch(size) {
1256         case 1:
1257             ret = ldub_user(addr);
1258             break;
1259         case 2:
1260             ret = lduw_user(addr);
1261             break;
1262         default:
1263         case 4:
1264             ret = ldl_user(addr);
1265             break;
1266         case 8:
1267             ret = ldq_user(addr);
1268             break;
1269         }
1270         break;
1271     case 0xb: /* Supervisor data access */
1272         switch(size) {
1273         case 1:
1274             ret = ldub_kernel(addr);
1275             break;
1276         case 2:
1277             ret = lduw_kernel(addr);
1278             break;
1279         default:
1280         case 4:
1281             ret = ldl_kernel(addr);
1282             break;
1283         case 8:
1284             ret = ldq_kernel(addr);
1285             break;
1286         }
1287         break;
1288     case 0xc: /* I-cache tag */
1289     case 0xd: /* I-cache data */
1290     case 0xe: /* D-cache tag */
1291     case 0xf: /* D-cache data */
1292         break;
1293     case 0x20: /* MMU passthrough */
1294         switch(size) {
1295         case 1:
1296             ret = ldub_phys(addr);
1297             break;
1298         case 2:
1299             ret = lduw_phys(addr);
1300             break;
1301         default:
1302         case 4:
1303             ret = ldl_phys(addr);
1304             break;
1305         case 8:
1306             ret = ldq_phys(addr);
1307             break;
1308         }
1309         break;
1310     case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1311         switch(size) {
1312         case 1:
1313             ret = ldub_phys((target_phys_addr_t)addr
1314                             | ((target_phys_addr_t)(asi & 0xf) << 32));
1315             break;
1316         case 2:
1317             ret = lduw_phys((target_phys_addr_t)addr
1318                             | ((target_phys_addr_t)(asi & 0xf) << 32));
1319             break;
1320         default:
1321         case 4:
1322             ret = ldl_phys((target_phys_addr_t)addr
1323                            | ((target_phys_addr_t)(asi & 0xf) << 32));
1324             break;
1325         case 8:
1326             ret = ldq_phys((target_phys_addr_t)addr
1327                            | ((target_phys_addr_t)(asi & 0xf) << 32));
1328             break;
1329         }
1330         break;
1331     case 0x30: // Turbosparc secondary cache diagnostic
1332     case 0x31: // Turbosparc RAM snoop
1333     case 0x32: // Turbosparc page table descriptor diagnostic
1334     case 0x39: /* data cache diagnostic register */
1335         ret = 0;
1336         break;
1337     case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
1338         {
1339             int reg = (addr >> 8) & 3;
1340
1341             switch(reg) {
1342             case 0: /* Breakpoint Value (Addr) */
1343                 ret = env->mmubpregs[reg];
1344                 break;
1345             case 1: /* Breakpoint Mask */
1346                 ret = env->mmubpregs[reg];
1347                 break;
1348             case 2: /* Breakpoint Control */
1349                 ret = env->mmubpregs[reg];
1350                 break;
1351             case 3: /* Breakpoint Status */
1352                 ret = env->mmubpregs[reg];
1353                 env->mmubpregs[reg] = 0ULL;
1354                 break;
1355             }
1356             DPRINTF_MMU("read breakpoint reg[%d] 0x%016llx\n", reg, ret);
1357         }
1358         break;
1359     case 8: /* User code access, XXX */
1360     default:
1361         do_unassigned_access(addr, 0, 0, asi, size);
1362         ret = 0;
1363         break;
1364     }
1365     if (sign) {
1366         switch(size) {
1367         case 1:
1368             ret = (int8_t) ret;
1369             break;
1370         case 2:
1371             ret = (int16_t) ret;
1372             break;
1373         case 4:
1374             ret = (int32_t) ret;
1375             break;
1376         default:
1377             break;
1378         }
1379     }
1380 #ifdef DEBUG_ASI
1381     dump_asi("read ", last_addr, asi, size, ret);
1382 #endif
1383     return ret;
1384 }
1385
1386 void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
1387 {
1388     helper_check_align(addr, size - 1);
1389     switch(asi) {
1390     case 2: /* SuperSparc MXCC registers */
1391         switch (addr) {
1392         case 0x01c00000: /* MXCC stream data register 0 */
1393             if (size == 8)
1394                 env->mxccdata[0] = val;
1395             else
1396                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1397                              size);
1398             break;
1399         case 0x01c00008: /* MXCC stream data register 1 */
1400             if (size == 8)
1401                 env->mxccdata[1] = val;
1402             else
1403                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1404                              size);
1405             break;
1406         case 0x01c00010: /* MXCC stream data register 2 */
1407             if (size == 8)
1408                 env->mxccdata[2] = val;
1409             else
1410                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1411                              size);
1412             break;
1413         case 0x01c00018: /* MXCC stream data register 3 */
1414             if (size == 8)
1415                 env->mxccdata[3] = val;
1416             else
1417                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1418                              size);
1419             break;
1420         case 0x01c00100: /* MXCC stream source */
1421             if (size == 8)
1422                 env->mxccregs[0] = val;
1423             else
1424                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1425                              size);
1426             env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1427                                         0);
1428             env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1429                                         8);
1430             env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1431                                         16);
1432             env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1433                                         24);
1434             break;
1435         case 0x01c00200: /* MXCC stream destination */
1436             if (size == 8)
1437                 env->mxccregs[1] = val;
1438             else
1439                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1440                              size);
1441             stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0,
1442                      env->mxccdata[0]);
1443             stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8,
1444                      env->mxccdata[1]);
1445             stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16,
1446                      env->mxccdata[2]);
1447             stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24,
1448                      env->mxccdata[3]);
1449             break;
1450         case 0x01c00a00: /* MXCC control register */
1451             if (size == 8)
1452                 env->mxccregs[3] = val;
1453             else
1454                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1455                              size);
1456             break;
1457         case 0x01c00a04: /* MXCC control register */
1458             if (size == 4)
1459                 env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL)
1460                     | val;
1461             else
1462                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1463                              size);
1464             break;
1465         case 0x01c00e00: /* MXCC error register  */
1466             // writing a 1 bit clears the error
1467             if (size == 8)
1468                 env->mxccregs[6] &= ~val;
1469             else
1470                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1471                              size);
1472             break;
1473         case 0x01c00f00: /* MBus port address register */
1474             if (size == 8)
1475                 env->mxccregs[7] = val;
1476             else
1477                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1478                              size);
1479             break;
1480         default:
1481             DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
1482                          size);
1483             break;
1484         }
1485         DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
1486                      asi, size, addr, val);
1487 #ifdef DEBUG_MXCC
1488         dump_mxcc(env);
1489 #endif
1490         break;
1491     case 3: /* MMU flush */
1492         {
1493             int mmulev;
1494
1495             mmulev = (addr >> 8) & 15;
1496             DPRINTF_MMU("mmu flush level %d\n", mmulev);
1497             switch (mmulev) {
1498             case 0: // flush page
1499                 tlb_flush_page(env, addr & 0xfffff000);
1500                 break;
1501             case 1: // flush segment (256k)
1502             case 2: // flush region (16M)
1503             case 3: // flush context (4G)
1504             case 4: // flush entire
1505                 tlb_flush(env, 1);
1506                 break;
1507             default:
1508                 break;
1509             }
1510 #ifdef DEBUG_MMU
1511             dump_mmu(env);
1512 #endif
1513         }
1514         break;
1515     case 4: /* write MMU regs */
1516         {
1517             int reg = (addr >> 8) & 0x1f;
1518             uint32_t oldreg;
1519
1520             oldreg = env->mmuregs[reg];
1521             switch(reg) {
1522             case 0: // Control Register
1523                 env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
1524                                     (val & 0x00ffffff);
1525                 // Mappings generated during no-fault mode or MMU
1526                 // disabled mode are invalid in normal mode
1527                 if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
1528                     (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm)))
1529                     tlb_flush(env, 1);
1530                 break;
1531             case 1: // Context Table Pointer Register
1532                 env->mmuregs[reg] = val & env->def->mmu_ctpr_mask;
1533                 break;
1534             case 2: // Context Register
1535                 env->mmuregs[reg] = val & env->def->mmu_cxr_mask;
1536                 if (oldreg != env->mmuregs[reg]) {
1537                     /* we flush when the MMU context changes because
1538                        QEMU has no MMU context support */
1539                     tlb_flush(env, 1);
1540                 }
1541                 break;
1542             case 3: // Synchronous Fault Status Register with Clear
1543             case 4: // Synchronous Fault Address Register
1544                 break;
1545             case 0x10: // TLB Replacement Control Register
1546                 env->mmuregs[reg] = val & env->def->mmu_trcr_mask;
1547                 break;
1548             case 0x13: // Synchronous Fault Status Register with Read and Clear
1549                 env->mmuregs[3] = val & env->def->mmu_sfsr_mask;
1550                 break;
1551             case 0x14: // Synchronous Fault Address Register
1552                 env->mmuregs[4] = val;
1553                 break;
1554             default:
1555                 env->mmuregs[reg] = val;
1556                 break;
1557             }
1558             if (oldreg != env->mmuregs[reg]) {
1559                 DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
1560                             reg, oldreg, env->mmuregs[reg]);
1561             }
1562 #ifdef DEBUG_MMU
1563             dump_mmu(env);
1564 #endif
1565         }
1566         break;
1567     case 5: // Turbosparc ITLB Diagnostic
1568     case 6: // Turbosparc DTLB Diagnostic
1569     case 7: // Turbosparc IOTLB Diagnostic
1570         break;
1571     case 0xa: /* User data access */
1572         switch(size) {
1573         case 1:
1574             stb_user(addr, val);
1575             break;
1576         case 2:
1577             stw_user(addr, val);
1578             break;
1579         default:
1580         case 4:
1581             stl_user(addr, val);
1582             break;
1583         case 8:
1584             stq_user(addr, val);
1585             break;
1586         }
1587         break;
1588     case 0xb: /* Supervisor data access */
1589         switch(size) {
1590         case 1:
1591             stb_kernel(addr, val);
1592             break;
1593         case 2:
1594             stw_kernel(addr, val);
1595             break;
1596         default:
1597         case 4:
1598             stl_kernel(addr, val);
1599             break;
1600         case 8:
1601             stq_kernel(addr, val);
1602             break;
1603         }
1604         break;
1605     case 0xc: /* I-cache tag */
1606     case 0xd: /* I-cache data */
1607     case 0xe: /* D-cache tag */
1608     case 0xf: /* D-cache data */
1609     case 0x10: /* I/D-cache flush page */
1610     case 0x11: /* I/D-cache flush segment */
1611     case 0x12: /* I/D-cache flush region */
1612     case 0x13: /* I/D-cache flush context */
1613     case 0x14: /* I/D-cache flush user */
1614         break;
1615     case 0x17: /* Block copy, sta access */
1616         {
1617             // val = src
1618             // addr = dst
1619             // copy 32 bytes
1620             unsigned int i;
1621             uint32_t src = val & ~3, dst = addr & ~3, temp;
1622
1623             for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
1624                 temp = ldl_kernel(src);
1625                 stl_kernel(dst, temp);
1626             }
1627         }
1628         break;
1629     case 0x1f: /* Block fill, stda access */
1630         {
1631             // addr = dst
1632             // fill 32 bytes with val
1633             unsigned int i;
1634             uint32_t dst = addr & 7;
1635
1636             for (i = 0; i < 32; i += 8, dst += 8)
1637                 stq_kernel(dst, val);
1638         }
1639         break;
1640     case 0x20: /* MMU passthrough */
1641         {
1642             switch(size) {
1643             case 1:
1644                 stb_phys(addr, val);
1645                 break;
1646             case 2:
1647                 stw_phys(addr, val);
1648                 break;
1649             case 4:
1650             default:
1651                 stl_phys(addr, val);
1652                 break;
1653             case 8:
1654                 stq_phys(addr, val);
1655                 break;
1656             }
1657         }
1658         break;
1659     case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1660         {
1661             switch(size) {
1662             case 1:
1663                 stb_phys((target_phys_addr_t)addr
1664                          | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1665                 break;
1666             case 2:
1667                 stw_phys((target_phys_addr_t)addr
1668                          | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1669                 break;
1670             case 4:
1671             default:
1672                 stl_phys((target_phys_addr_t)addr
1673                          | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1674                 break;
1675             case 8:
1676                 stq_phys((target_phys_addr_t)addr
1677                          | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1678                 break;
1679             }
1680         }
1681         break;
1682     case 0x30: // store buffer tags or Turbosparc secondary cache diagnostic
1683     case 0x31: // store buffer data, Ross RT620 I-cache flush or
1684                // Turbosparc snoop RAM
1685     case 0x32: // store buffer control or Turbosparc page table
1686                // descriptor diagnostic
1687     case 0x36: /* I-cache flash clear */
1688     case 0x37: /* D-cache flash clear */
1689     case 0x4c: /* breakpoint action */
1690         break;
1691     case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
1692         {
1693             int reg = (addr >> 8) & 3;
1694
1695             switch(reg) {
1696             case 0: /* Breakpoint Value (Addr) */
1697                 env->mmubpregs[reg] = (val & 0xfffffffffULL);
1698                 break;
1699             case 1: /* Breakpoint Mask */
1700                 env->mmubpregs[reg] = (val & 0xfffffffffULL);
1701                 break;
1702             case 2: /* Breakpoint Control */
1703                 env->mmubpregs[reg] = (val & 0x7fULL);
1704                 break;
1705             case 3: /* Breakpoint Status */
1706                 env->mmubpregs[reg] = (val & 0xfULL);
1707                 break;
1708             }
1709             DPRINTF_MMU("write breakpoint reg[%d] 0x%016llx\n", reg,
1710                         env->mmuregs[reg]);
1711         }
1712         break;
1713     case 8: /* User code access, XXX */
1714     case 9: /* Supervisor code access, XXX */
1715     default:
1716         do_unassigned_access(addr, 1, 0, asi, size);
1717         break;
1718     }
1719 #ifdef DEBUG_ASI
1720     dump_asi("write", addr, asi, size, val);
1721 #endif
1722 }
1723
1724 #endif /* CONFIG_USER_ONLY */
1725 #else /* TARGET_SPARC64 */
1726
1727 #ifdef CONFIG_USER_ONLY
1728 uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1729 {
1730     uint64_t ret = 0;
1731 #if defined(DEBUG_ASI)
1732     target_ulong last_addr = addr;
1733 #endif
1734
1735     if (asi < 0x80)
1736         raise_exception(TT_PRIV_ACT);
1737
1738     helper_check_align(addr, size - 1);
1739     address_mask(env, &addr);
1740
1741     switch (asi) {
1742     case 0x82: // Primary no-fault
1743     case 0x8a: // Primary no-fault LE
1744         if (page_check_range(addr, size, PAGE_READ) == -1) {
1745 #ifdef DEBUG_ASI
1746             dump_asi("read ", last_addr, asi, size, ret);
1747 #endif
1748             return 0;
1749         }
1750         // Fall through
1751     case 0x80: // Primary
1752     case 0x88: // Primary LE
1753         {
1754             switch(size) {
1755             case 1:
1756                 ret = ldub_raw(addr);
1757                 break;
1758             case 2:
1759                 ret = lduw_raw(addr);
1760                 break;
1761             case 4:
1762                 ret = ldl_raw(addr);
1763                 break;
1764             default:
1765             case 8:
1766                 ret = ldq_raw(addr);
1767                 break;
1768             }
1769         }
1770         break;
1771     case 0x83: // Secondary no-fault
1772     case 0x8b: // Secondary no-fault LE
1773         if (page_check_range(addr, size, PAGE_READ) == -1) {
1774 #ifdef DEBUG_ASI
1775             dump_asi("read ", last_addr, asi, size, ret);
1776 #endif
1777             return 0;
1778         }
1779         // Fall through
1780     case 0x81: // Secondary
1781     case 0x89: // Secondary LE
1782         // XXX
1783         break;
1784     default:
1785         break;
1786     }
1787
1788     /* Convert from little endian */
1789     switch (asi) {
1790     case 0x88: // Primary LE
1791     case 0x89: // Secondary LE
1792     case 0x8a: // Primary no-fault LE
1793     case 0x8b: // Secondary no-fault LE
1794         switch(size) {
1795         case 2:
1796             ret = bswap16(ret);
1797             break;
1798         case 4:
1799             ret = bswap32(ret);
1800             break;
1801         case 8:
1802             ret = bswap64(ret);
1803             break;
1804         default:
1805             break;
1806         }
1807     default:
1808         break;
1809     }
1810
1811     /* Convert to signed number */
1812     if (sign) {
1813         switch(size) {
1814         case 1:
1815             ret = (int8_t) ret;
1816             break;
1817         case 2:
1818             ret = (int16_t) ret;
1819             break;
1820         case 4:
1821             ret = (int32_t) ret;
1822             break;
1823         default:
1824             break;
1825         }
1826     }
1827 #ifdef DEBUG_ASI
1828     dump_asi("read ", last_addr, asi, size, ret);
1829 #endif
1830     return ret;
1831 }
1832
1833 void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
1834 {
1835 #ifdef DEBUG_ASI
1836     dump_asi("write", addr, asi, size, val);
1837 #endif
1838     if (asi < 0x80)
1839         raise_exception(TT_PRIV_ACT);
1840
1841     helper_check_align(addr, size - 1);
1842     address_mask(env, &addr);
1843
1844     /* Convert to little endian */
1845     switch (asi) {
1846     case 0x88: // Primary LE
1847     case 0x89: // Secondary LE
1848         switch(size) {
1849         case 2:
1850             addr = bswap16(addr);
1851             break;
1852         case 4:
1853             addr = bswap32(addr);
1854             break;
1855         case 8:
1856             addr = bswap64(addr);
1857             break;
1858         default:
1859             break;
1860         }
1861     default:
1862         break;
1863     }
1864
1865     switch(asi) {
1866     case 0x80: // Primary
1867     case 0x88: // Primary LE
1868         {
1869             switch(size) {
1870             case 1:
1871                 stb_raw(addr, val);
1872                 break;
1873             case 2:
1874                 stw_raw(addr, val);
1875                 break;
1876             case 4:
1877                 stl_raw(addr, val);
1878                 break;
1879             case 8:
1880             default:
1881                 stq_raw(addr, val);
1882                 break;
1883             }
1884         }
1885         break;
1886     case 0x81: // Secondary
1887     case 0x89: // Secondary LE
1888         // XXX
1889         return;
1890
1891     case 0x82: // Primary no-fault, RO
1892     case 0x83: // Secondary no-fault, RO
1893     case 0x8a: // Primary no-fault LE, RO
1894     case 0x8b: // Secondary no-fault LE, RO
1895     default:
1896         do_unassigned_access(addr, 1, 0, 1, size);
1897         return;
1898     }
1899 }
1900
1901 #else /* CONFIG_USER_ONLY */
1902
1903 uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1904 {
1905     uint64_t ret = 0;
1906 #if defined(DEBUG_ASI)
1907     target_ulong last_addr = addr;
1908 #endif
1909
1910     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1911         || ((env->def->features & CPU_FEATURE_HYPV)
1912             && asi >= 0x30 && asi < 0x80
1913             && !(env->hpstate & HS_PRIV)))
1914         raise_exception(TT_PRIV_ACT);
1915
1916     helper_check_align(addr, size - 1);
1917     switch (asi) {
1918     case 0x82: // Primary no-fault
1919     case 0x8a: // Primary no-fault LE
1920         if (cpu_get_phys_page_debug(env, addr) == -1ULL) {
1921 #ifdef DEBUG_ASI
1922             dump_asi("read ", last_addr, asi, size, ret);
1923 #endif
1924             return 0;
1925         }
1926         // Fall through
1927     case 0x10: // As if user primary
1928     case 0x18: // As if user primary LE
1929     case 0x80: // Primary
1930     case 0x88: // Primary LE
1931     case 0xe2: // UA2007 Primary block init
1932     case 0xe3: // UA2007 Secondary block init
1933         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1934             if ((env->def->features & CPU_FEATURE_HYPV)
1935                 && env->hpstate & HS_PRIV) {
1936                 switch(size) {
1937                 case 1:
1938                     ret = ldub_hypv(addr);
1939                     break;
1940                 case 2:
1941                     ret = lduw_hypv(addr);
1942                     break;
1943                 case 4:
1944                     ret = ldl_hypv(addr);
1945                     break;
1946                 default:
1947                 case 8:
1948                     ret = ldq_hypv(addr);
1949                     break;
1950                 }
1951             } else {
1952                 switch(size) {
1953                 case 1:
1954                     ret = ldub_kernel(addr);
1955                     break;
1956                 case 2:
1957                     ret = lduw_kernel(addr);
1958                     break;
1959                 case 4:
1960                     ret = ldl_kernel(addr);
1961                     break;
1962                 default:
1963                 case 8:
1964                     ret = ldq_kernel(addr);
1965                     break;
1966                 }
1967             }
1968         } else {
1969             switch(size) {
1970             case 1:
1971                 ret = ldub_user(addr);
1972                 break;
1973             case 2:
1974                 ret = lduw_user(addr);
1975                 break;
1976             case 4:
1977                 ret = ldl_user(addr);
1978                 break;
1979             default:
1980             case 8:
1981                 ret = ldq_user(addr);
1982                 break;
1983             }
1984         }
1985         break;
1986     case 0x14: // Bypass
1987     case 0x15: // Bypass, non-cacheable
1988     case 0x1c: // Bypass LE
1989     case 0x1d: // Bypass, non-cacheable LE
1990         {
1991             switch(size) {
1992             case 1:
1993                 ret = ldub_phys(addr);
1994                 break;
1995             case 2:
1996                 ret = lduw_phys(addr);
1997                 break;
1998             case 4:
1999                 ret = ldl_phys(addr);
2000                 break;
2001             default:
2002             case 8:
2003                 ret = ldq_phys(addr);
2004                 break;
2005             }
2006             break;
2007         }
2008     case 0x24: // Nucleus quad LDD 128 bit atomic
2009     case 0x2c: // Nucleus quad LDD 128 bit atomic LE
2010         //  Only ldda allowed
2011         raise_exception(TT_ILL_INSN);
2012         return 0;
2013     case 0x83: // Secondary no-fault
2014     case 0x8b: // Secondary no-fault LE
2015         if (cpu_get_phys_page_debug(env, addr) == -1ULL) {
2016 #ifdef DEBUG_ASI
2017             dump_asi("read ", last_addr, asi, size, ret);
2018 #endif
2019             return 0;
2020         }
2021         // Fall through
2022     case 0x04: // Nucleus
2023     case 0x0c: // Nucleus Little Endian (LE)
2024     case 0x11: // As if user secondary
2025     case 0x19: // As if user secondary LE
2026     case 0x4a: // UPA config
2027     case 0x81: // Secondary
2028     case 0x89: // Secondary LE
2029         // XXX
2030         break;
2031     case 0x45: // LSU
2032         ret = env->lsu;
2033         break;
2034     case 0x50: // I-MMU regs
2035         {
2036             int reg = (addr >> 3) & 0xf;
2037
2038             if (reg == 0) {
2039                 // I-TSB Tag Target register
2040                 ret = ultrasparc_tag_target(env->immuregs[6]);
2041             } else {
2042                 ret = env->immuregs[reg];
2043             }
2044
2045             break;
2046         }
2047     case 0x51: // I-MMU 8k TSB pointer
2048         {
2049             // env->immuregs[5] holds I-MMU TSB register value
2050             // env->immuregs[6] holds I-MMU Tag Access register value
2051             ret = ultrasparc_tsb_pointer(env->immuregs[5], env->immuregs[6],
2052                                          8*1024);
2053             break;
2054         }
2055     case 0x52: // I-MMU 64k TSB pointer
2056         {
2057             // env->immuregs[5] holds I-MMU TSB register value
2058             // env->immuregs[6] holds I-MMU Tag Access register value
2059             ret = ultrasparc_tsb_pointer(env->immuregs[5], env->immuregs[6],
2060                                          64*1024);
2061             break;
2062         }
2063     case 0x55: // I-MMU data access
2064         {
2065             int reg = (addr >> 3) & 0x3f;
2066
2067             ret = env->itlb_tte[reg];
2068             break;
2069         }
2070     case 0x56: // I-MMU tag read
2071         {
2072             int reg = (addr >> 3) & 0x3f;
2073
2074             ret = env->itlb_tag[reg];
2075             break;
2076         }
2077     case 0x58: // D-MMU regs
2078         {
2079             int reg = (addr >> 3) & 0xf;
2080
2081             if (reg == 0) {
2082                 // D-TSB Tag Target register
2083                 ret = ultrasparc_tag_target(env->dmmuregs[6]);
2084             } else {
2085                 ret = env->dmmuregs[reg];
2086             }
2087             break;
2088         }
2089     case 0x59: // D-MMU 8k TSB pointer
2090         {
2091             // env->dmmuregs[5] holds D-MMU TSB register value
2092             // env->dmmuregs[6] holds D-MMU Tag Access register value
2093             ret = ultrasparc_tsb_pointer(env->dmmuregs[5], env->dmmuregs[6],
2094                                          8*1024);
2095             break;
2096         }
2097     case 0x5a: // D-MMU 64k TSB pointer
2098         {
2099             // env->dmmuregs[5] holds D-MMU TSB register value
2100             // env->dmmuregs[6] holds D-MMU Tag Access register value
2101             ret = ultrasparc_tsb_pointer(env->dmmuregs[5], env->dmmuregs[6],
2102                                          64*1024);
2103             break;
2104         }
2105     case 0x5d: // D-MMU data access
2106         {
2107             int reg = (addr >> 3) & 0x3f;
2108
2109             ret = env->dtlb_tte[reg];
2110             break;
2111         }
2112     case 0x5e: // D-MMU tag read
2113         {
2114             int reg = (addr >> 3) & 0x3f;
2115
2116             ret = env->dtlb_tag[reg];
2117             break;
2118         }
2119     case 0x46: // D-cache data
2120     case 0x47: // D-cache tag access
2121     case 0x4b: // E-cache error enable
2122     case 0x4c: // E-cache asynchronous fault status
2123     case 0x4d: // E-cache asynchronous fault address
2124     case 0x4e: // E-cache tag data
2125     case 0x66: // I-cache instruction access
2126     case 0x67: // I-cache tag access
2127     case 0x6e: // I-cache predecode
2128     case 0x6f: // I-cache LRU etc.
2129     case 0x76: // E-cache tag
2130     case 0x7e: // E-cache tag
2131         break;
2132     case 0x5b: // D-MMU data pointer
2133     case 0x48: // Interrupt dispatch, RO
2134     case 0x49: // Interrupt data receive
2135     case 0x7f: // Incoming interrupt vector, RO
2136         // XXX
2137         break;
2138     case 0x54: // I-MMU data in, WO
2139     case 0x57: // I-MMU demap, WO
2140     case 0x5c: // D-MMU data in, WO
2141     case 0x5f: // D-MMU demap, WO
2142     case 0x77: // Interrupt vector, WO
2143     default:
2144         do_unassigned_access(addr, 0, 0, 1, size);
2145         ret = 0;
2146         break;
2147     }
2148
2149     /* Convert from little endian */
2150     switch (asi) {
2151     case 0x0c: // Nucleus Little Endian (LE)
2152     case 0x18: // As if user primary LE
2153     case 0x19: // As if user secondary LE
2154     case 0x1c: // Bypass LE
2155     case 0x1d: // Bypass, non-cacheable LE
2156     case 0x88: // Primary LE
2157     case 0x89: // Secondary LE
2158     case 0x8a: // Primary no-fault LE
2159     case 0x8b: // Secondary no-fault LE
2160         switch(size) {
2161         case 2:
2162             ret = bswap16(ret);
2163             break;
2164         case 4:
2165             ret = bswap32(ret);
2166             break;
2167         case 8:
2168             ret = bswap64(ret);
2169             break;
2170         default:
2171             break;
2172         }
2173     default:
2174         break;
2175     }
2176
2177     /* Convert to signed number */
2178     if (sign) {
2179         switch(size) {
2180         case 1:
2181             ret = (int8_t) ret;
2182             break;
2183         case 2:
2184             ret = (int16_t) ret;
2185             break;
2186         case 4:
2187             ret = (int32_t) ret;
2188             break;
2189         default:
2190             break;
2191         }
2192     }
2193 #ifdef DEBUG_ASI
2194     dump_asi("read ", last_addr, asi, size, ret);
2195 #endif
2196     return ret;
2197 }
2198
2199 void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
2200 {
2201 #ifdef DEBUG_ASI
2202     dump_asi("write", addr, asi, size, val);
2203 #endif
2204     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2205         || ((env->def->features & CPU_FEATURE_HYPV)
2206             && asi >= 0x30 && asi < 0x80
2207             && !(env->hpstate & HS_PRIV)))
2208         raise_exception(TT_PRIV_ACT);
2209
2210     helper_check_align(addr, size - 1);
2211     /* Convert to little endian */
2212     switch (asi) {
2213     case 0x0c: // Nucleus Little Endian (LE)
2214     case 0x18: // As if user primary LE
2215     case 0x19: // As if user secondary LE
2216     case 0x1c: // Bypass LE
2217     case 0x1d: // Bypass, non-cacheable LE
2218     case 0x88: // Primary LE
2219     case 0x89: // Secondary LE
2220         switch(size) {
2221         case 2:
2222             addr = bswap16(addr);
2223             break;
2224         case 4:
2225             addr = bswap32(addr);
2226             break;
2227         case 8:
2228             addr = bswap64(addr);
2229             break;
2230         default:
2231             break;
2232         }
2233     default:
2234         break;
2235     }
2236
2237     switch(asi) {
2238     case 0x10: // As if user primary
2239     case 0x18: // As if user primary LE
2240     case 0x80: // Primary
2241     case 0x88: // Primary LE
2242     case 0xe2: // UA2007 Primary block init
2243     case 0xe3: // UA2007 Secondary block init
2244         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
2245             if ((env->def->features & CPU_FEATURE_HYPV)
2246                 && env->hpstate & HS_PRIV) {
2247                 switch(size) {
2248                 case 1:
2249                     stb_hypv(addr, val);
2250                     break;
2251                 case 2:
2252                     stw_hypv(addr, val);
2253                     break;
2254                 case 4:
2255                     stl_hypv(addr, val);
2256                     break;
2257                 case 8:
2258                 default:
2259                     stq_hypv(addr, val);
2260                     break;
2261                 }
2262             } else {
2263                 switch(size) {
2264                 case 1:
2265                     stb_kernel(addr, val);
2266                     break;
2267                 case 2:
2268                     stw_kernel(addr, val);
2269                     break;
2270                 case 4:
2271                     stl_kernel(addr, val);
2272                     break;
2273                 case 8:
2274                 default:
2275                     stq_kernel(addr, val);
2276                     break;
2277                 }
2278             }
2279         } else {
2280             switch(size) {
2281             case 1:
2282                 stb_user(addr, val);
2283                 break;
2284             case 2:
2285                 stw_user(addr, val);
2286                 break;
2287             case 4:
2288                 stl_user(addr, val);
2289                 break;
2290             case 8:
2291             default:
2292                 stq_user(addr, val);
2293                 break;
2294             }
2295         }
2296         break;
2297     case 0x14: // Bypass
2298     case 0x15: // Bypass, non-cacheable
2299     case 0x1c: // Bypass LE
2300     case 0x1d: // Bypass, non-cacheable LE
2301         {
2302             switch(size) {
2303             case 1:
2304                 stb_phys(addr, val);
2305                 break;
2306             case 2:
2307                 stw_phys(addr, val);
2308                 break;
2309             case 4:
2310                 stl_phys(addr, val);
2311                 break;
2312             case 8:
2313             default:
2314                 stq_phys(addr, val);
2315                 break;
2316             }
2317         }
2318         return;
2319     case 0x24: // Nucleus quad LDD 128 bit atomic
2320     case 0x2c: // Nucleus quad LDD 128 bit atomic LE
2321         //  Only ldda allowed
2322         raise_exception(TT_ILL_INSN);
2323         return;
2324     case 0x04: // Nucleus
2325     case 0x0c: // Nucleus Little Endian (LE)
2326     case 0x11: // As if user secondary
2327     case 0x19: // As if user secondary LE
2328     case 0x4a: // UPA config
2329     case 0x81: // Secondary
2330     case 0x89: // Secondary LE
2331         // XXX
2332         return;
2333     case 0x45: // LSU
2334         {
2335             uint64_t oldreg;
2336
2337             oldreg = env->lsu;
2338             env->lsu = val & (DMMU_E | IMMU_E);
2339             // Mappings generated during D/I MMU disabled mode are
2340             // invalid in normal mode
2341             if (oldreg != env->lsu) {
2342                 DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
2343                             oldreg, env->lsu);
2344 #ifdef DEBUG_MMU
2345                 dump_mmu(env);
2346 #endif
2347                 tlb_flush(env, 1);
2348             }
2349             return;
2350         }
2351     case 0x50: // I-MMU regs
2352         {
2353             int reg = (addr >> 3) & 0xf;
2354             uint64_t oldreg;
2355
2356             oldreg = env->immuregs[reg];
2357             switch(reg) {
2358             case 0: // RO
2359             case 4:
2360                 return;
2361             case 1: // Not in I-MMU
2362             case 2:
2363             case 7:
2364             case 8:
2365                 return;
2366             case 3: // SFSR
2367                 if ((val & 1) == 0)
2368                     val = 0; // Clear SFSR
2369                 break;
2370             case 5: // TSB access
2371             case 6: // Tag access
2372             default:
2373                 break;
2374             }
2375             env->immuregs[reg] = val;
2376             if (oldreg != env->immuregs[reg]) {
2377                 DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08"
2378                             PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
2379             }
2380 #ifdef DEBUG_MMU
2381             dump_mmu(env);
2382 #endif
2383             return;
2384         }
2385     case 0x54: // I-MMU data in
2386         {
2387             unsigned int i;
2388
2389             // Try finding an invalid entry
2390             for (i = 0; i < 64; i++) {
2391                 if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
2392                     env->itlb_tag[i] = env->immuregs[6];
2393                     env->itlb_tte[i] = val;
2394                     return;
2395                 }
2396             }
2397             // Try finding an unlocked entry
2398             for (i = 0; i < 64; i++) {
2399                 if ((env->itlb_tte[i] & 0x40) == 0) {
2400                     env->itlb_tag[i] = env->immuregs[6];
2401                     env->itlb_tte[i] = val;
2402                     return;
2403                 }
2404             }
2405             // error state?
2406             return;
2407         }
2408     case 0x55: // I-MMU data access
2409         {
2410             // TODO: auto demap
2411
2412             unsigned int i = (addr >> 3) & 0x3f;
2413
2414             env->itlb_tag[i] = env->immuregs[6];
2415             env->itlb_tte[i] = val;
2416             return;
2417         }
2418     case 0x57: // I-MMU demap
2419         {
2420             unsigned int i;
2421
2422             for (i = 0; i < 64; i++) {
2423                 if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
2424                     target_ulong mask = 0xffffffffffffe000ULL;
2425
2426                     mask <<= 3 * ((env->itlb_tte[i] >> 61) & 3);
2427                     if ((val & mask) == (env->itlb_tag[i] & mask)) {
2428                         env->itlb_tag[i] = 0;
2429                         env->itlb_tte[i] = 0;
2430                     }
2431                     return;
2432                 }
2433             }
2434         }
2435         return;
2436     case 0x58: // D-MMU regs
2437         {
2438             int reg = (addr >> 3) & 0xf;
2439             uint64_t oldreg;
2440
2441             oldreg = env->dmmuregs[reg];
2442             switch(reg) {
2443             case 0: // RO
2444             case 4:
2445                 return;
2446             case 3: // SFSR
2447                 if ((val & 1) == 0) {
2448                     val = 0; // Clear SFSR, Fault address
2449                     env->dmmuregs[4] = 0;
2450                 }
2451                 env->dmmuregs[reg] = val;
2452                 break;
2453             case 1: // Primary context
2454             case 2: // Secondary context
2455             case 5: // TSB access
2456             case 6: // Tag access
2457             case 7: // Virtual Watchpoint
2458             case 8: // Physical Watchpoint
2459             default:
2460                 break;
2461             }
2462             env->dmmuregs[reg] = val;
2463             if (oldreg != env->dmmuregs[reg]) {
2464                 DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08"
2465                             PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
2466             }
2467 #ifdef DEBUG_MMU
2468             dump_mmu(env);
2469 #endif
2470             return;
2471         }
2472     case 0x5c: // D-MMU data in
2473         {
2474             unsigned int i;
2475
2476             // Try finding an invalid entry
2477             for (i = 0; i < 64; i++) {
2478                 if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
2479                     env->dtlb_tag[i] = env->dmmuregs[6];
2480                     env->dtlb_tte[i] = val;
2481                     return;
2482                 }
2483             }
2484             // Try finding an unlocked entry
2485             for (i = 0; i < 64; i++) {
2486                 if ((env->dtlb_tte[i] & 0x40) == 0) {
2487                     env->dtlb_tag[i] = env->dmmuregs[6];
2488                     env->dtlb_tte[i] = val;
2489                     return;
2490                 }
2491             }
2492             // error state?
2493             return;
2494         }
2495     case 0x5d: // D-MMU data access
2496         {
2497             unsigned int i = (addr >> 3) & 0x3f;
2498
2499             env->dtlb_tag[i] = env->dmmuregs[6];
2500             env->dtlb_tte[i] = val;
2501             return;
2502         }
2503     case 0x5f: // D-MMU demap
2504         {
2505             unsigned int i;
2506
2507             for (i = 0; i < 64; i++) {
2508                 if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
2509                     target_ulong mask = 0xffffffffffffe000ULL;
2510
2511                     mask <<= 3 * ((env->dtlb_tte[i] >> 61) & 3);
2512                     if ((val & mask) == (env->dtlb_tag[i] & mask)) {
2513                         env->dtlb_tag[i] = 0;
2514                         env->dtlb_tte[i] = 0;
2515                     }
2516                     return;
2517                 }
2518             }
2519         }
2520         return;
2521     case 0x49: // Interrupt data receive
2522         // XXX
2523         return;
2524     case 0x46: // D-cache data
2525     case 0x47: // D-cache tag access
2526     case 0x4b: // E-cache error enable
2527     case 0x4c: // E-cache asynchronous fault status
2528     case 0x4d: // E-cache asynchronous fault address
2529     case 0x4e: // E-cache tag data
2530     case 0x66: // I-cache instruction access
2531     case 0x67: // I-cache tag access
2532     case 0x6e: // I-cache predecode
2533     case 0x6f: // I-cache LRU etc.
2534     case 0x76: // E-cache tag
2535     case 0x7e: // E-cache tag
2536         return;
2537     case 0x51: // I-MMU 8k TSB pointer, RO
2538     case 0x52: // I-MMU 64k TSB pointer, RO
2539     case 0x56: // I-MMU tag read, RO
2540     case 0x59: // D-MMU 8k TSB pointer, RO
2541     case 0x5a: // D-MMU 64k TSB pointer, RO
2542     case 0x5b: // D-MMU data pointer, RO
2543     case 0x5e: // D-MMU tag read, RO
2544     case 0x48: // Interrupt dispatch, RO
2545     case 0x7f: // Incoming interrupt vector, RO
2546     case 0x82: // Primary no-fault, RO
2547     case 0x83: // Secondary no-fault, RO
2548     case 0x8a: // Primary no-fault LE, RO
2549     case 0x8b: // Secondary no-fault LE, RO
2550     default:
2551         do_unassigned_access(addr, 1, 0, 1, size);
2552         return;
2553     }
2554 }
2555 #endif /* CONFIG_USER_ONLY */
2556
2557 void helper_ldda_asi(target_ulong addr, int asi, int rd)
2558 {
2559     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2560         || ((env->def->features & CPU_FEATURE_HYPV)
2561             && asi >= 0x30 && asi < 0x80
2562             && !(env->hpstate & HS_PRIV)))
2563         raise_exception(TT_PRIV_ACT);
2564
2565     switch (asi) {
2566     case 0x24: // Nucleus quad LDD 128 bit atomic
2567     case 0x2c: // Nucleus quad LDD 128 bit atomic LE
2568         helper_check_align(addr, 0xf);
2569         if (rd == 0) {
2570             env->gregs[1] = ldq_kernel(addr + 8);
2571             if (asi == 0x2c)
2572                 bswap64s(&env->gregs[1]);
2573         } else if (rd < 8) {
2574             env->gregs[rd] = ldq_kernel(addr);
2575             env->gregs[rd + 1] = ldq_kernel(addr + 8);
2576             if (asi == 0x2c) {
2577                 bswap64s(&env->gregs[rd]);
2578                 bswap64s(&env->gregs[rd + 1]);
2579             }
2580         } else {
2581             env->regwptr[rd] = ldq_kernel(addr);
2582             env->regwptr[rd + 1] = ldq_kernel(addr + 8);
2583             if (asi == 0x2c) {
2584                 bswap64s(&env->regwptr[rd]);
2585                 bswap64s(&env->regwptr[rd + 1]);
2586             }
2587         }
2588         break;
2589     default:
2590         helper_check_align(addr, 0x3);
2591         if (rd == 0)
2592             env->gregs[1] = helper_ld_asi(addr + 4, asi, 4, 0);
2593         else if (rd < 8) {
2594             env->gregs[rd] = helper_ld_asi(addr, asi, 4, 0);
2595             env->gregs[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2596         } else {
2597             env->regwptr[rd] = helper_ld_asi(addr, asi, 4, 0);
2598             env->regwptr[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2599         }
2600         break;
2601     }
2602 }
2603
2604 void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2605 {
2606     unsigned int i;
2607     target_ulong val;
2608
2609     helper_check_align(addr, 3);
2610     switch (asi) {
2611     case 0xf0: // Block load primary
2612     case 0xf1: // Block load secondary
2613     case 0xf8: // Block load primary LE
2614     case 0xf9: // Block load secondary LE
2615         if (rd & 7) {
2616             raise_exception(TT_ILL_INSN);
2617             return;
2618         }
2619         helper_check_align(addr, 0x3f);
2620         for (i = 0; i < 16; i++) {
2621             *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4,
2622                                                          0);
2623             addr += 4;
2624         }
2625
2626         return;
2627     default:
2628         break;
2629     }
2630
2631     val = helper_ld_asi(addr, asi, size, 0);
2632     switch(size) {
2633     default:
2634     case 4:
2635         *((uint32_t *)&env->fpr[rd]) = val;
2636         break;
2637     case 8:
2638         *((int64_t *)&DT0) = val;
2639         break;
2640     case 16:
2641         // XXX
2642         break;
2643     }
2644 }
2645
2646 void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
2647 {
2648     unsigned int i;
2649     target_ulong val = 0;
2650
2651     helper_check_align(addr, 3);
2652     switch (asi) {
2653     case 0xe0: // UA2007 Block commit store primary (cache flush)
2654     case 0xe1: // UA2007 Block commit store secondary (cache flush)
2655     case 0xf0: // Block store primary
2656     case 0xf1: // Block store secondary
2657     case 0xf8: // Block store primary LE
2658     case 0xf9: // Block store secondary LE
2659         if (rd & 7) {
2660             raise_exception(TT_ILL_INSN);
2661             return;
2662         }
2663         helper_check_align(addr, 0x3f);
2664         for (i = 0; i < 16; i++) {
2665             val = *(uint32_t *)&env->fpr[rd++];
2666             helper_st_asi(addr, val, asi & 0x8f, 4);
2667             addr += 4;
2668         }
2669
2670         return;
2671     default:
2672         break;
2673     }
2674
2675     switch(size) {
2676     default:
2677     case 4:
2678         val = *((uint32_t *)&env->fpr[rd]);
2679         break;
2680     case 8:
2681         val = *((int64_t *)&DT0);
2682         break;
2683     case 16:
2684         // XXX
2685         break;
2686     }
2687     helper_st_asi(addr, val, asi, size);
2688 }
2689
2690 target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
2691                             target_ulong val2, uint32_t asi)
2692 {
2693     target_ulong ret;
2694
2695     val2 &= 0xffffffffUL;
2696     ret = helper_ld_asi(addr, asi, 4, 0);
2697     ret &= 0xffffffffUL;
2698     if (val2 == ret)
2699         helper_st_asi(addr, val1 & 0xffffffffUL, asi, 4);
2700     return ret;
2701 }
2702
2703 target_ulong helper_casx_asi(target_ulong addr, target_ulong val1,
2704                              target_ulong val2, uint32_t asi)
2705 {
2706     target_ulong ret;
2707
2708     ret = helper_ld_asi(addr, asi, 8, 0);
2709     if (val2 == ret)
2710         helper_st_asi(addr, val1, asi, 8);
2711     return ret;
2712 }
2713 #endif /* TARGET_SPARC64 */
2714
2715 #ifndef TARGET_SPARC64
2716 void helper_rett(void)
2717 {
2718     unsigned int cwp;
2719
2720     if (env->psret == 1)
2721         raise_exception(TT_ILL_INSN);
2722
2723     env->psret = 1;
2724     cwp = cpu_cwp_inc(env, env->cwp + 1) ;
2725     if (env->wim & (1 << cwp)) {
2726         raise_exception(TT_WIN_UNF);
2727     }
2728     set_cwp(cwp);
2729     env->psrs = env->psrps;
2730 }
2731 #endif
2732
2733 target_ulong helper_udiv(target_ulong a, target_ulong b)
2734 {
2735     uint64_t x0;
2736     uint32_t x1;
2737
2738     x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
2739     x1 = b;
2740
2741     if (x1 == 0) {
2742         raise_exception(TT_DIV_ZERO);
2743     }
2744
2745     x0 = x0 / x1;
2746     if (x0 > 0xffffffff) {
2747         env->cc_src2 = 1;
2748         return 0xffffffff;
2749     } else {
2750         env->cc_src2 = 0;
2751         return x0;
2752     }
2753 }
2754
2755 target_ulong helper_sdiv(target_ulong a, target_ulong b)
2756 {
2757     int64_t x0;
2758     int32_t x1;
2759
2760     x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
2761     x1 = b;
2762
2763     if (x1 == 0) {
2764         raise_exception(TT_DIV_ZERO);
2765     }
2766
2767     x0 = x0 / x1;
2768     if ((int32_t) x0 != x0) {
2769         env->cc_src2 = 1;
2770         return x0 < 0? 0x80000000: 0x7fffffff;
2771     } else {
2772         env->cc_src2 = 0;
2773         return x0;
2774     }
2775 }
2776
2777 void helper_stdf(target_ulong addr, int mem_idx)
2778 {
2779     helper_check_align(addr, 7);
2780 #if !defined(CONFIG_USER_ONLY)
2781     switch (mem_idx) {
2782     case 0:
2783         stfq_user(addr, DT0);
2784         break;
2785     case 1:
2786         stfq_kernel(addr, DT0);
2787         break;
2788 #ifdef TARGET_SPARC64
2789     case 2:
2790         stfq_hypv(addr, DT0);
2791         break;
2792 #endif
2793     default:
2794         break;
2795     }
2796 #else
2797     address_mask(env, &addr);
2798     stfq_raw(addr, DT0);
2799 #endif
2800 }
2801
2802 void helper_lddf(target_ulong addr, int mem_idx)
2803 {
2804     helper_check_align(addr, 7);
2805 #if !defined(CONFIG_USER_ONLY)
2806     switch (mem_idx) {
2807     case 0:
2808         DT0 = ldfq_user(addr);
2809         break;
2810     case 1:
2811         DT0 = ldfq_kernel(addr);
2812         break;
2813 #ifdef TARGET_SPARC64
2814     case 2:
2815         DT0 = ldfq_hypv(addr);
2816         break;
2817 #endif
2818     default:
2819         break;
2820     }
2821 #else
2822     address_mask(env, &addr);
2823     DT0 = ldfq_raw(addr);
2824 #endif
2825 }
2826
2827 void helper_ldqf(target_ulong addr, int mem_idx)
2828 {
2829     // XXX add 128 bit load
2830     CPU_QuadU u;
2831
2832     helper_check_align(addr, 7);
2833 #if !defined(CONFIG_USER_ONLY)
2834     switch (mem_idx) {
2835     case 0:
2836         u.ll.upper = ldq_user(addr);
2837         u.ll.lower = ldq_user(addr + 8);
2838         QT0 = u.q;
2839         break;
2840     case 1:
2841         u.ll.upper = ldq_kernel(addr);
2842         u.ll.lower = ldq_kernel(addr + 8);
2843         QT0 = u.q;
2844         break;
2845 #ifdef TARGET_SPARC64
2846     case 2:
2847         u.ll.upper = ldq_hypv(addr);
2848         u.ll.lower = ldq_hypv(addr + 8);
2849         QT0 = u.q;
2850         break;
2851 #endif
2852     default:
2853         break;
2854     }
2855 #else
2856     address_mask(env, &addr);
2857     u.ll.upper = ldq_raw(addr);
2858     u.ll.lower = ldq_raw((addr + 8) & 0xffffffffULL);
2859     QT0 = u.q;
2860 #endif
2861 }
2862
2863 void helper_stqf(target_ulong addr, int mem_idx)
2864 {
2865     // XXX add 128 bit store
2866     CPU_QuadU u;
2867
2868     helper_check_align(addr, 7);
2869 #if !defined(CONFIG_USER_ONLY)
2870     switch (mem_idx) {
2871     case 0:
2872         u.q = QT0;
2873         stq_user(addr, u.ll.upper);
2874         stq_user(addr + 8, u.ll.lower);
2875         break;
2876     case 1:
2877         u.q = QT0;
2878         stq_kernel(addr, u.ll.upper);
2879         stq_kernel(addr + 8, u.ll.lower);
2880         break;
2881 #ifdef TARGET_SPARC64
2882     case 2:
2883         u.q = QT0;
2884         stq_hypv(addr, u.ll.upper);
2885         stq_hypv(addr + 8, u.ll.lower);
2886         break;
2887 #endif
2888     default:
2889         break;
2890     }
2891 #else
2892     u.q = QT0;
2893     address_mask(env, &addr);
2894     stq_raw(addr, u.ll.upper);
2895     stq_raw((addr + 8) & 0xffffffffULL, u.ll.lower);
2896 #endif
2897 }
2898
2899 static inline void set_fsr(void)
2900 {
2901     int rnd_mode;
2902
2903     switch (env->fsr & FSR_RD_MASK) {
2904     case FSR_RD_NEAREST:
2905         rnd_mode = float_round_nearest_even;
2906         break;
2907     default:
2908     case FSR_RD_ZERO:
2909         rnd_mode = float_round_to_zero;
2910         break;
2911     case FSR_RD_POS:
2912         rnd_mode = float_round_up;
2913         break;
2914     case FSR_RD_NEG:
2915         rnd_mode = float_round_down;
2916         break;
2917     }
2918     set_float_rounding_mode(rnd_mode, &env->fp_status);
2919 }
2920
2921 void helper_ldfsr(uint32_t new_fsr)
2922 {
2923     env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK);
2924     set_fsr();
2925 }
2926
2927 #ifdef TARGET_SPARC64
2928 void helper_ldxfsr(uint64_t new_fsr)
2929 {
2930     env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK);
2931     set_fsr();
2932 }
2933 #endif
2934
2935 void helper_debug(void)
2936 {
2937     env->exception_index = EXCP_DEBUG;
2938     cpu_loop_exit();
2939 }
2940
2941 #ifndef TARGET_SPARC64
2942 /* XXX: use another pointer for %iN registers to avoid slow wrapping
2943    handling ? */
2944 void helper_save(void)
2945 {
2946     uint32_t cwp;
2947
2948     cwp = cpu_cwp_dec(env, env->cwp - 1);
2949     if (env->wim & (1 << cwp)) {
2950         raise_exception(TT_WIN_OVF);
2951     }
2952     set_cwp(cwp);
2953 }
2954
2955 void helper_restore(void)
2956 {
2957     uint32_t cwp;
2958
2959     cwp = cpu_cwp_inc(env, env->cwp + 1);
2960     if (env->wim & (1 << cwp)) {
2961         raise_exception(TT_WIN_UNF);
2962     }
2963     set_cwp(cwp);
2964 }
2965
2966 void helper_wrpsr(target_ulong new_psr)
2967 {
2968     if ((new_psr & PSR_CWP) >= env->nwindows)
2969         raise_exception(TT_ILL_INSN);
2970     else
2971         PUT_PSR(env, new_psr);
2972 }
2973
2974 target_ulong helper_rdpsr(void)
2975 {
2976     return GET_PSR(env);
2977 }
2978
2979 #else
2980 /* XXX: use another pointer for %iN registers to avoid slow wrapping
2981    handling ? */
2982 void helper_save(void)
2983 {
2984     uint32_t cwp;
2985
2986     cwp = cpu_cwp_dec(env, env->cwp - 1);
2987     if (env->cansave == 0) {
2988         raise_exception(TT_SPILL | (env->otherwin != 0 ?
2989                                     (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2990                                     ((env->wstate & 0x7) << 2)));
2991     } else {
2992         if (env->cleanwin - env->canrestore == 0) {
2993             // XXX Clean windows without trap
2994             raise_exception(TT_CLRWIN);
2995         } else {
2996             env->cansave--;
2997             env->canrestore++;
2998             set_cwp(cwp);
2999         }
3000     }
3001 }
3002
3003 void helper_restore(void)
3004 {
3005     uint32_t cwp;
3006
3007     cwp = cpu_cwp_inc(env, env->cwp + 1);
3008     if (env->canrestore == 0) {
3009         raise_exception(TT_FILL | (env->otherwin != 0 ?
3010                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
3011                                    ((env->wstate & 0x7) << 2)));
3012     } else {
3013         env->cansave++;
3014         env->canrestore--;
3015         set_cwp(cwp);
3016     }
3017 }
3018
3019 void helper_flushw(void)
3020 {
3021     if (env->cansave != env->nwindows - 2) {
3022         raise_exception(TT_SPILL | (env->otherwin != 0 ?
3023                                     (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
3024                                     ((env->wstate & 0x7) << 2)));
3025     }
3026 }
3027
3028 void helper_saved(void)
3029 {
3030     env->cansave++;
3031     if (env->otherwin == 0)
3032         env->canrestore--;
3033     else
3034         env->otherwin--;
3035 }
3036
3037 void helper_restored(void)
3038 {
3039     env->canrestore++;
3040     if (env->cleanwin < env->nwindows - 1)
3041         env->cleanwin++;
3042     if (env->otherwin == 0)
3043         env->cansave--;
3044     else
3045         env->otherwin--;
3046 }
3047
3048 target_ulong helper_rdccr(void)
3049 {
3050     return GET_CCR(env);
3051 }
3052
3053 void helper_wrccr(target_ulong new_ccr)
3054 {
3055     PUT_CCR(env, new_ccr);
3056 }
3057
3058 // CWP handling is reversed in V9, but we still use the V8 register
3059 // order.
3060 target_ulong helper_rdcwp(void)
3061 {
3062     return GET_CWP64(env);
3063 }
3064
3065 void helper_wrcwp(target_ulong new_cwp)
3066 {
3067     PUT_CWP64(env, new_cwp);
3068 }
3069
3070 // This function uses non-native bit order
3071 #define GET_FIELD(X, FROM, TO)                                  \
3072     ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
3073
3074 // This function uses the order in the manuals, i.e. bit 0 is 2^0
3075 #define GET_FIELD_SP(X, FROM, TO)               \
3076     GET_FIELD(X, 63 - (TO), 63 - (FROM))
3077
3078 target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
3079 {
3080     return (GET_FIELD_SP(pixel_addr, 60, 63) << (17 + 2 * cubesize)) |
3081         (GET_FIELD_SP(pixel_addr, 39, 39 + cubesize - 1) << (17 + cubesize)) |
3082         (GET_FIELD_SP(pixel_addr, 17 + cubesize - 1, 17) << 17) |
3083         (GET_FIELD_SP(pixel_addr, 56, 59) << 13) |
3084         (GET_FIELD_SP(pixel_addr, 35, 38) << 9) |
3085         (GET_FIELD_SP(pixel_addr, 13, 16) << 5) |
3086         (((pixel_addr >> 55) & 1) << 4) |
3087         (GET_FIELD_SP(pixel_addr, 33, 34) << 2) |
3088         GET_FIELD_SP(pixel_addr, 11, 12);
3089 }
3090
3091 target_ulong helper_alignaddr(target_ulong addr, target_ulong offset)
3092 {
3093     uint64_t tmp;
3094
3095     tmp = addr + offset;
3096     env->gsr &= ~7ULL;
3097     env->gsr |= tmp & 7ULL;
3098     return tmp & ~7ULL;
3099 }
3100
3101 target_ulong helper_popc(target_ulong val)
3102 {
3103     return ctpop64(val);
3104 }
3105
3106 static inline uint64_t *get_gregset(uint64_t pstate)
3107 {
3108     switch (pstate) {
3109     default:
3110     case 0:
3111         return env->bgregs;
3112     case PS_AG:
3113         return env->agregs;
3114     case PS_MG:
3115         return env->mgregs;
3116     case PS_IG:
3117         return env->igregs;
3118     }
3119 }
3120
3121 static inline void change_pstate(uint64_t new_pstate)
3122 {
3123     uint64_t pstate_regs, new_pstate_regs;
3124     uint64_t *src, *dst;
3125
3126     pstate_regs = env->pstate & 0xc01;
3127     new_pstate_regs = new_pstate & 0xc01;
3128     if (new_pstate_regs != pstate_regs) {
3129         // Switch global register bank
3130         src = get_gregset(new_pstate_regs);
3131         dst = get_gregset(pstate_regs);
3132         memcpy32(dst, env->gregs);
3133         memcpy32(env->gregs, src);
3134     }
3135     env->pstate = new_pstate;
3136 }
3137
3138 void helper_wrpstate(target_ulong new_state)
3139 {
3140     if (!(env->def->features & CPU_FEATURE_GL))
3141         change_pstate(new_state & 0xf3f);
3142 }
3143
3144 void helper_done(void)
3145 {
3146     env->pc = env->tsptr->tpc;
3147     env->npc = env->tsptr->tnpc + 4;
3148     PUT_CCR(env, env->tsptr->tstate >> 32);
3149     env->asi = (env->tsptr->tstate >> 24) & 0xff;
3150     change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
3151     PUT_CWP64(env, env->tsptr->tstate & 0xff);
3152     env->tl--;
3153     env->tsptr = &env->ts[env->tl & MAXTL_MASK];
3154 }
3155
3156 void helper_retry(void)
3157 {
3158     env->pc = env->tsptr->tpc;
3159     env->npc = env->tsptr->tnpc;
3160     PUT_CCR(env, env->tsptr->tstate >> 32);
3161     env->asi = (env->tsptr->tstate >> 24) & 0xff;
3162     change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
3163     PUT_CWP64(env, env->tsptr->tstate & 0xff);
3164     env->tl--;
3165     env->tsptr = &env->ts[env->tl & MAXTL_MASK];
3166 }
3167
3168 void helper_set_softint(uint64_t value)
3169 {
3170     env->softint |= (uint32_t)value;
3171 }
3172
3173 void helper_clear_softint(uint64_t value)
3174 {
3175     env->softint &= (uint32_t)~value;
3176 }
3177
3178 void helper_write_softint(uint64_t value)
3179 {
3180     env->softint = (uint32_t)value;
3181 }
3182 #endif
3183
3184 void helper_flush(target_ulong addr)
3185 {
3186     addr &= ~7;
3187     tb_invalidate_page_range(addr, addr + 8);
3188 }
3189
3190 #ifdef TARGET_SPARC64
3191 #ifdef DEBUG_PCALL
3192 static const char * const excp_names[0x80] = {
3193     [TT_TFAULT] = "Instruction Access Fault",
3194     [TT_TMISS] = "Instruction Access MMU Miss",
3195     [TT_CODE_ACCESS] = "Instruction Access Error",
3196     [TT_ILL_INSN] = "Illegal Instruction",
3197     [TT_PRIV_INSN] = "Privileged Instruction",
3198     [TT_NFPU_INSN] = "FPU Disabled",
3199     [TT_FP_EXCP] = "FPU Exception",
3200     [TT_TOVF] = "Tag Overflow",
3201     [TT_CLRWIN] = "Clean Windows",
3202     [TT_DIV_ZERO] = "Division By Zero",
3203     [TT_DFAULT] = "Data Access Fault",
3204     [TT_DMISS] = "Data Access MMU Miss",
3205     [TT_DATA_ACCESS] = "Data Access Error",
3206     [TT_DPROT] = "Data Protection Error",
3207     [TT_UNALIGNED] = "Unaligned Memory Access",
3208     [TT_PRIV_ACT] = "Privileged Action",
3209     [TT_EXTINT | 0x1] = "External Interrupt 1",
3210     [TT_EXTINT | 0x2] = "External Interrupt 2",
3211     [TT_EXTINT | 0x3] = "External Interrupt 3",
3212     [TT_EXTINT | 0x4] = "External Interrupt 4",
3213     [TT_EXTINT | 0x5] = "External Interrupt 5",
3214     [TT_EXTINT | 0x6] = "External Interrupt 6",
3215     [TT_EXTINT | 0x7] = "External Interrupt 7",
3216     [TT_EXTINT | 0x8] = "External Interrupt 8",
3217     [TT_EXTINT | 0x9] = "External Interrupt 9",
3218     [TT_EXTINT | 0xa] = "External Interrupt 10",
3219     [TT_EXTINT | 0xb] = "External Interrupt 11",
3220     [TT_EXTINT | 0xc] = "External Interrupt 12",
3221     [TT_EXTINT | 0xd] = "External Interrupt 13",
3222     [TT_EXTINT | 0xe] = "External Interrupt 14",
3223     [TT_EXTINT | 0xf] = "External Interrupt 15",
3224 };
3225 #endif
3226
3227 void do_interrupt(CPUState *env)
3228 {
3229     int intno = env->exception_index;
3230
3231 #ifdef DEBUG_PCALL
3232     if (qemu_loglevel_mask(CPU_LOG_INT)) {
3233         static int count;
3234         const char *name;
3235
3236         if (intno < 0 || intno >= 0x180)
3237             name = "Unknown";
3238         else if (intno >= 0x100)
3239             name = "Trap Instruction";
3240         else if (intno >= 0xc0)
3241             name = "Window Fill";
3242         else if (intno >= 0x80)
3243             name = "Window Spill";
3244         else {
3245             name = excp_names[intno];
3246             if (!name)
3247                 name = "Unknown";
3248         }
3249
3250         qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
3251                 " SP=%016" PRIx64 "\n",
3252                 count, name, intno,
3253                 env->pc,
3254                 env->npc, env->regwptr[6]);
3255         log_cpu_state(env, 0);
3256 #if 0
3257         {
3258             int i;
3259             uint8_t *ptr;
3260
3261             qemu_log("       code=");
3262             ptr = (uint8_t *)env->pc;
3263             for(i = 0; i < 16; i++) {
3264                 qemu_log(" %02x", ldub(ptr + i));
3265             }
3266             qemu_log("\n");
3267         }
3268 #endif
3269         count++;
3270     }
3271 #endif
3272 #if !defined(CONFIG_USER_ONLY)
3273     if (env->tl >= env->maxtl) {
3274         cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
3275                   " Error state", env->exception_index, env->tl, env->maxtl);
3276         return;
3277     }
3278 #endif
3279     if (env->tl < env->maxtl - 1) {
3280         env->tl++;
3281     } else {
3282         env->pstate |= PS_RED;
3283         if (env->tl < env->maxtl)
3284             env->tl++;
3285     }
3286     env->tsptr = &env->ts[env->tl & MAXTL_MASK];
3287     env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
3288         ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
3289         GET_CWP64(env);
3290     env->tsptr->tpc = env->pc;
3291     env->tsptr->tnpc = env->npc;
3292     env->tsptr->tt = intno;
3293     if (!(env->def->features & CPU_FEATURE_GL)) {
3294         switch (intno) {
3295         case TT_IVEC:
3296             change_pstate(PS_PEF | PS_PRIV | PS_IG);
3297             break;
3298         case TT_TFAULT:
3299         case TT_TMISS:
3300         case TT_DFAULT:
3301         case TT_DMISS:
3302         case TT_DPROT:
3303             change_pstate(PS_PEF | PS_PRIV | PS_MG);
3304             break;
3305         default:
3306             change_pstate(PS_PEF | PS_PRIV | PS_AG);
3307             break;
3308         }
3309     }
3310     if (intno == TT_CLRWIN)
3311         cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
3312     else if ((intno & 0x1c0) == TT_SPILL)
3313         cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
3314     else if ((intno & 0x1c0) == TT_FILL)
3315         cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
3316     env->tbr &= ~0x7fffULL;
3317     env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
3318     env->pc = env->tbr;
3319     env->npc = env->pc + 4;
3320     env->exception_index = 0;
3321 }
3322 #else
3323 #ifdef DEBUG_PCALL
3324 static const char * const excp_names[0x80] = {
3325     [TT_TFAULT] = "Instruction Access Fault",
3326     [TT_ILL_INSN] = "Illegal Instruction",
3327     [TT_PRIV_INSN] = "Privileged Instruction",
3328     [TT_NFPU_INSN] = "FPU Disabled",
3329     [TT_WIN_OVF] = "Window Overflow",
3330     [TT_WIN_UNF] = "Window Underflow",
3331     [TT_UNALIGNED] = "Unaligned Memory Access",
3332     [TT_FP_EXCP] = "FPU Exception",
3333     [TT_DFAULT] = "Data Access Fault",
3334     [TT_TOVF] = "Tag Overflow",
3335     [TT_EXTINT | 0x1] = "External Interrupt 1",
3336     [TT_EXTINT | 0x2] = "External Interrupt 2",
3337     [TT_EXTINT | 0x3] = "External Interrupt 3",
3338     [TT_EXTINT | 0x4] = "External Interrupt 4",
3339     [TT_EXTINT | 0x5] = "External Interrupt 5",
3340     [TT_EXTINT | 0x6] = "External Interrupt 6",
3341     [TT_EXTINT | 0x7] = "External Interrupt 7",
3342     [TT_EXTINT | 0x8] = "External Interrupt 8",
3343     [TT_EXTINT | 0x9] = "External Interrupt 9",
3344     [TT_EXTINT | 0xa] = "External Interrupt 10",
3345     [TT_EXTINT | 0xb] = "External Interrupt 11",
3346     [TT_EXTINT | 0xc] = "External Interrupt 12",
3347     [TT_EXTINT | 0xd] = "External Interrupt 13",
3348     [TT_EXTINT | 0xe] = "External Interrupt 14",
3349     [TT_EXTINT | 0xf] = "External Interrupt 15",
3350     [TT_TOVF] = "Tag Overflow",
3351     [TT_CODE_ACCESS] = "Instruction Access Error",
3352     [TT_DATA_ACCESS] = "Data Access Error",
3353     [TT_DIV_ZERO] = "Division By Zero",
3354     [TT_NCP_INSN] = "Coprocessor Disabled",
3355 };
3356 #endif
3357
3358 void do_interrupt(CPUState *env)
3359 {
3360     int cwp, intno = env->exception_index;
3361
3362 #ifdef DEBUG_PCALL
3363     if (qemu_loglevel_mask(CPU_LOG_INT)) {
3364         static int count;
3365         const char *name;
3366
3367         if (intno < 0 || intno >= 0x100)
3368             name = "Unknown";
3369         else if (intno >= 0x80)
3370             name = "Trap Instruction";
3371         else {
3372             name = excp_names[intno];
3373             if (!name)
3374                 name = "Unknown";
3375         }
3376
3377         qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
3378                 count, name, intno,
3379                 env->pc,
3380                 env->npc, env->regwptr[6]);
3381         log_cpu_state(env, 0);
3382 #if 0
3383         {
3384             int i;
3385             uint8_t *ptr;
3386
3387             qemu_log("       code=");
3388             ptr = (uint8_t *)env->pc;
3389             for(i = 0; i < 16; i++) {
3390                 qemu_log(" %02x", ldub(ptr + i));
3391             }
3392             qemu_log("\n");
3393         }
3394 #endif
3395         count++;
3396     }
3397 #endif
3398 #if !defined(CONFIG_USER_ONLY)
3399     if (env->psret == 0) {
3400         cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
3401                   env->exception_index);
3402         return;
3403     }
3404 #endif
3405     env->psret = 0;
3406     cwp = cpu_cwp_dec(env, env->cwp - 1);
3407     cpu_set_cwp(env, cwp);
3408     env->regwptr[9] = env->pc;
3409     env->regwptr[10] = env->npc;
3410     env->psrps = env->psrs;
3411     env->psrs = 1;
3412     env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
3413     env->pc = env->tbr;
3414     env->npc = env->pc + 4;
3415     env->exception_index = 0;
3416 }
3417 #endif
3418
3419 #if !defined(CONFIG_USER_ONLY)
3420
3421 static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3422                                 void *retaddr);
3423
3424 #define MMUSUFFIX _mmu
3425 #define ALIGNED_ONLY
3426
3427 #define SHIFT 0
3428 #include "softmmu_template.h"
3429
3430 #define SHIFT 1
3431 #include "softmmu_template.h"
3432
3433 #define SHIFT 2
3434 #include "softmmu_template.h"
3435
3436 #define SHIFT 3
3437 #include "softmmu_template.h"
3438
3439 /* XXX: make it generic ? */
3440 static void cpu_restore_state2(void *retaddr)
3441 {
3442     TranslationBlock *tb;
3443     unsigned long pc;
3444
3445     if (retaddr) {
3446         /* now we have a real cpu fault */
3447         pc = (unsigned long)retaddr;
3448         tb = tb_find_pc(pc);
3449         if (tb) {
3450             /* the PC is inside the translated code. It means that we have
3451                a virtual CPU fault */
3452             cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
3453         }
3454     }
3455 }
3456
3457 static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3458                                 void *retaddr)
3459 {
3460 #ifdef DEBUG_UNALIGNED
3461     printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
3462            "\n", addr, env->pc);
3463 #endif
3464     cpu_restore_state2(retaddr);
3465     raise_exception(TT_UNALIGNED);
3466 }
3467
3468 /* try to fill the TLB and return an exception if error. If retaddr is
3469    NULL, it means that the function was called in C code (i.e. not
3470    from generated code or from helper.c) */
3471 /* XXX: fix it to restore all registers */
3472 void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
3473 {
3474     int ret;
3475     CPUState *saved_env;
3476
3477     /* XXX: hack to restore env in all cases, even if not called from
3478        generated code */
3479     saved_env = env;
3480     env = cpu_single_env;
3481
3482     ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
3483     if (ret) {
3484         cpu_restore_state2(retaddr);
3485         cpu_loop_exit();
3486     }
3487     env = saved_env;
3488 }
3489
3490 #endif
3491
3492 #ifndef TARGET_SPARC64
3493 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3494                           int is_asi, int size)
3495 {
3496     CPUState *saved_env;
3497
3498     /* XXX: hack to restore env in all cases, even if not called from
3499        generated code */
3500     saved_env = env;
3501     env = cpu_single_env;
3502 #ifdef DEBUG_UNASSIGNED
3503     if (is_asi)
3504         printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3505                " asi 0x%02x from " TARGET_FMT_lx "\n",
3506                is_exec ? "exec" : is_write ? "write" : "read", size,
3507                size == 1 ? "" : "s", addr, is_asi, env->pc);
3508     else
3509         printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3510                " from " TARGET_FMT_lx "\n",
3511                is_exec ? "exec" : is_write ? "write" : "read", size,
3512                size == 1 ? "" : "s", addr, env->pc);
3513 #endif
3514     if (env->mmuregs[3]) /* Fault status register */
3515         env->mmuregs[3] = 1; /* overflow (not read before another fault) */
3516     if (is_asi)
3517         env->mmuregs[3] |= 1 << 16;
3518     if (env->psrs)
3519         env->mmuregs[3] |= 1 << 5;
3520     if (is_exec)
3521         env->mmuregs[3] |= 1 << 6;
3522     if (is_write)
3523         env->mmuregs[3] |= 1 << 7;
3524     env->mmuregs[3] |= (5 << 2) | 2;
3525     env->mmuregs[4] = addr; /* Fault address register */
3526     if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
3527         if (is_exec)
3528             raise_exception(TT_CODE_ACCESS);
3529         else
3530             raise_exception(TT_DATA_ACCESS);
3531     }
3532     env = saved_env;
3533 }
3534 #else
3535 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3536                           int is_asi, int size)
3537 {
3538 #ifdef DEBUG_UNASSIGNED
3539     CPUState *saved_env;
3540
3541     /* XXX: hack to restore env in all cases, even if not called from
3542        generated code */
3543     saved_env = env;
3544     env = cpu_single_env;
3545     printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
3546            "\n", addr, env->pc);
3547     env = saved_env;
3548 #endif
3549     if (is_exec)
3550         raise_exception(TT_CODE_ACCESS);
3551     else
3552         raise_exception(TT_DATA_ACCESS);
3553 }
3554 #endif
3555
3556 #ifdef TARGET_SPARC64
3557 void helper_tick_set_count(void *opaque, uint64_t count)
3558 {
3559 #if !defined(CONFIG_USER_ONLY)
3560     cpu_tick_set_count(opaque, count);
3561 #endif
3562 }
3563
3564 uint64_t helper_tick_get_count(void *opaque)
3565 {
3566 #if !defined(CONFIG_USER_ONLY)
3567     return cpu_tick_get_count(opaque);
3568 #else
3569     return 0;
3570 #endif
3571 }
3572
3573 void helper_tick_set_limit(void *opaque, uint64_t limit)
3574 {
3575 #if !defined(CONFIG_USER_ONLY)
3576     cpu_tick_set_limit(opaque, limit);
3577 #endif
3578 }
3579 #endif