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