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