Nicer debug output for exceptions
[qemu] / target-sparc / op_helper.c
1 #include "exec.h"
2 #include "host-utils.h"
3
4 //#define DEBUG_PCALL
5 //#define DEBUG_MMU
6 //#define DEBUG_MXCC
7 //#define DEBUG_UNALIGNED
8 //#define DEBUG_UNASSIGNED
9 //#define DEBUG_ASI
10
11 #ifdef DEBUG_MMU
12 #define DPRINTF_MMU(fmt, args...) \
13 do { printf("MMU: " fmt , ##args); } while (0)
14 #else
15 #define DPRINTF_MMU(fmt, args...)
16 #endif
17
18 #ifdef DEBUG_MXCC
19 #define DPRINTF_MXCC(fmt, args...) \
20 do { printf("MXCC: " fmt , ##args); } while (0)
21 #else
22 #define DPRINTF_MXCC(fmt, args...)
23 #endif
24
25 #ifdef DEBUG_ASI
26 #define DPRINTF_ASI(fmt, args...) \
27 do { printf("ASI: " fmt , ##args); } while (0)
28 #else
29 #define DPRINTF_ASI(fmt, args...)
30 #endif
31
32 void raise_exception(int tt)
33 {
34     env->exception_index = tt;
35     cpu_loop_exit();
36 }
37
38 void check_ieee_exceptions()
39 {
40      T0 = get_float_exception_flags(&env->fp_status);
41      if (T0)
42      {
43         /* Copy IEEE 754 flags into FSR */
44         if (T0 & float_flag_invalid)
45             env->fsr |= FSR_NVC;
46         if (T0 & float_flag_overflow)
47             env->fsr |= FSR_OFC;
48         if (T0 & float_flag_underflow)
49             env->fsr |= FSR_UFC;
50         if (T0 & float_flag_divbyzero)
51             env->fsr |= FSR_DZC;
52         if (T0 & float_flag_inexact)
53             env->fsr |= FSR_NXC;
54
55         if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23))
56         {
57             /* Unmasked exception, generate a trap */
58             env->fsr |= FSR_FTT_IEEE_EXCP;
59             raise_exception(TT_FP_EXCP);
60         }
61         else
62         {
63             /* Accumulate exceptions */
64             env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
65         }
66      }
67 }
68
69 #ifdef USE_INT_TO_FLOAT_HELPERS
70 void do_fitos(void)
71 {
72     set_float_exception_flags(0, &env->fp_status);
73     FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
74     check_ieee_exceptions();
75 }
76
77 void do_fitod(void)
78 {
79     DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
80 }
81
82 #if defined(CONFIG_USER_ONLY)
83 void do_fitoq(void)
84 {
85     QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
86 }
87 #endif
88
89 #ifdef TARGET_SPARC64
90 void do_fxtos(void)
91 {
92     set_float_exception_flags(0, &env->fp_status);
93     FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
94     check_ieee_exceptions();
95 }
96
97 void do_fxtod(void)
98 {
99     set_float_exception_flags(0, &env->fp_status);
100     DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
101     check_ieee_exceptions();
102 }
103
104 #if defined(CONFIG_USER_ONLY)
105 void do_fxtoq(void)
106 {
107     set_float_exception_flags(0, &env->fp_status);
108     QT0 = int64_to_float128(*((int32_t *)&DT1), &env->fp_status);
109     check_ieee_exceptions();
110 }
111 #endif
112 #endif
113 #endif
114
115 void do_fabss(void)
116 {
117     FT0 = float32_abs(FT1);
118 }
119
120 #ifdef TARGET_SPARC64
121 void do_fabsd(void)
122 {
123     DT0 = float64_abs(DT1);
124 }
125
126 #if defined(CONFIG_USER_ONLY)
127 void do_fabsq(void)
128 {
129     QT0 = float128_abs(QT1);
130 }
131 #endif
132 #endif
133
134 void do_fsqrts(void)
135 {
136     set_float_exception_flags(0, &env->fp_status);
137     FT0 = float32_sqrt(FT1, &env->fp_status);
138     check_ieee_exceptions();
139 }
140
141 void do_fsqrtd(void)
142 {
143     set_float_exception_flags(0, &env->fp_status);
144     DT0 = float64_sqrt(DT1, &env->fp_status);
145     check_ieee_exceptions();
146 }
147
148 #if defined(CONFIG_USER_ONLY)
149 void do_fsqrtq(void)
150 {
151     set_float_exception_flags(0, &env->fp_status);
152     QT0 = float128_sqrt(QT1, &env->fp_status);
153     check_ieee_exceptions();
154 }
155 #endif
156
157 #define GEN_FCMP(name, size, reg1, reg2, FS, TRAP)                      \
158     void glue(do_, name) (void)                                         \
159     {                                                                   \
160         env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                     \
161         switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) {   \
162         case float_relation_unordered:                                  \
163             T0 = (FSR_FCC1 | FSR_FCC0) << FS;                           \
164             if ((env->fsr & FSR_NVM) || TRAP) {                         \
165                 env->fsr |= T0;                                         \
166                 env->fsr |= FSR_NVC;                                    \
167                 env->fsr |= FSR_FTT_IEEE_EXCP;                          \
168                 raise_exception(TT_FP_EXCP);                            \
169             } else {                                                    \
170                 env->fsr |= FSR_NVA;                                    \
171             }                                                           \
172             break;                                                      \
173         case float_relation_less:                                       \
174             T0 = FSR_FCC0 << FS;                                        \
175             break;                                                      \
176         case float_relation_greater:                                    \
177             T0 = FSR_FCC1 << FS;                                        \
178             break;                                                      \
179         default:                                                        \
180             T0 = 0;                                                     \
181             break;                                                      \
182         }                                                               \
183         env->fsr |= T0;                                                 \
184     }
185
186 GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0);
187 GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0);
188
189 GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1);
190 GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1);
191
192 #ifdef CONFIG_USER_ONLY
193 GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
194 GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
195 #endif
196
197 #ifdef TARGET_SPARC64
198 GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0);
199 GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
200
201 GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0);
202 GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
203
204 GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0);
205 GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
206
207 GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1);
208 GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
209
210 GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1);
211 GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
212
213 GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
214 GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
215 #ifdef CONFIG_USER_ONLY
216 GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
217 GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
218 GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
219 GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
220 GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
221 GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
222 #endif
223 #endif
224
225 #ifndef TARGET_SPARC64
226 #ifndef CONFIG_USER_ONLY
227
228 #ifdef DEBUG_MXCC
229 static void dump_mxcc(CPUState *env)
230 {
231     printf("mxccdata: %016llx %016llx %016llx %016llx\n",
232         env->mxccdata[0], env->mxccdata[1], env->mxccdata[2], env->mxccdata[3]);
233     printf("mxccregs: %016llx %016llx %016llx %016llx\n"
234            "          %016llx %016llx %016llx %016llx\n",
235         env->mxccregs[0], env->mxccregs[1], env->mxccregs[2], env->mxccregs[3],
236         env->mxccregs[4], env->mxccregs[5], env->mxccregs[6], env->mxccregs[7]);
237 }
238 #endif
239
240 #ifdef DEBUG_ASI
241 static void dump_asi(const char * txt, uint32_t addr, int asi, int size,
242                      uint32_t r1, uint32_t r2)
243 {
244     switch (size)
245     {
246     case 1:
247         DPRINTF_ASI("%s %08x asi 0x%02x = %02x\n", txt, addr, asi, r1 & 0xff);
248         break;
249     case 2:
250         DPRINTF_ASI("%s %08x asi 0x%02x = %04x\n", txt, addr, asi, r1 & 0xffff);
251         break;
252     case 4:
253         DPRINTF_ASI("%s %08x asi 0x%02x = %08x\n", txt, addr, asi, r1);
254         break;
255     case 8:
256         DPRINTF_ASI("%s %08x asi 0x%02x = %016llx\n", txt, addr, asi,
257                     r2 | ((uint64_t)r1 << 32));
258         break;
259     }
260 }
261 #endif
262
263 void helper_ld_asi(int asi, int size, int sign)
264 {
265     uint32_t ret = 0;
266     uint64_t tmp;
267 #if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
268     uint32_t last_T0 = T0;
269 #endif
270
271     switch (asi) {
272     case 2: /* SuperSparc MXCC registers */
273         switch (T0) {
274         case 0x01c00a00: /* MXCC control register */
275             if (size == 8) {
276                 ret = env->mxccregs[3] >> 32;
277                 T0 = env->mxccregs[3];
278             } else
279                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
280             break;
281         case 0x01c00a04: /* MXCC control register */
282             if (size == 4)
283                 ret = env->mxccregs[3];
284             else
285                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
286             break;
287         case 0x01c00c00: /* Module reset register */
288             if (size == 8) {
289                 ret = env->mxccregs[5] >> 32;
290                 T0 = env->mxccregs[5];
291                 // should we do something here?
292             } else
293                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
294             break;
295         case 0x01c00f00: /* MBus port address register */
296             if (size == 8) {
297                 ret = env->mxccregs[7] >> 32;
298                 T0 = env->mxccregs[7];
299             } else
300                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
301             break;
302         default:
303             DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
304             break;
305         }
306         DPRINTF_MXCC("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x,"
307                      "T0 = %08x\n", asi, size, sign, last_T0, ret, T0);
308 #ifdef DEBUG_MXCC
309         dump_mxcc(env);
310 #endif
311         break;
312     case 3: /* MMU probe */
313         {
314             int mmulev;
315
316             mmulev = (T0 >> 8) & 15;
317             if (mmulev > 4)
318                 ret = 0;
319             else {
320                 ret = mmu_probe(env, T0, mmulev);
321                 //bswap32s(&ret);
322             }
323             DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
324         }
325         break;
326     case 4: /* read MMU regs */
327         {
328             int reg = (T0 >> 8) & 0x1f;
329
330             ret = env->mmuregs[reg];
331             if (reg == 3) /* Fault status cleared on read */
332                 env->mmuregs[3] = 0;
333             else if (reg == 0x13) /* Fault status read */
334                 ret = env->mmuregs[3];
335             else if (reg == 0x14) /* Fault address read */
336                 ret = env->mmuregs[4];
337             DPRINTF_MMU("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
338         }
339         break;
340     case 9: /* Supervisor code access */
341         switch(size) {
342         case 1:
343             ret = ldub_code(T0);
344             break;
345         case 2:
346             ret = lduw_code(T0 & ~1);
347             break;
348         default:
349         case 4:
350             ret = ldl_code(T0 & ~3);
351             break;
352         case 8:
353             tmp = ldq_code(T0 & ~7);
354             ret = tmp >> 32;
355             T0 = tmp;
356             break;
357         }
358         break;
359     case 0xa: /* User data access */
360         switch(size) {
361         case 1:
362             ret = ldub_user(T0);
363             break;
364         case 2:
365             ret = lduw_user(T0 & ~1);
366             break;
367         default:
368         case 4:
369             ret = ldl_user(T0 & ~3);
370             break;
371         case 8:
372             tmp = ldq_user(T0 & ~7);
373             ret = tmp >> 32;
374             T0 = tmp;
375             break;
376         }
377         break;
378     case 0xb: /* Supervisor data access */
379         switch(size) {
380         case 1:
381             ret = ldub_kernel(T0);
382             break;
383         case 2:
384             ret = lduw_kernel(T0 & ~1);
385             break;
386         default:
387         case 4:
388             ret = ldl_kernel(T0 & ~3);
389             break;
390         case 8:
391             tmp = ldq_kernel(T0 & ~7);
392             ret = tmp >> 32;
393             T0 = tmp;
394             break;
395         }
396         break;
397     case 0xc: /* I-cache tag */
398     case 0xd: /* I-cache data */
399     case 0xe: /* D-cache tag */
400     case 0xf: /* D-cache data */
401         break;
402     case 0x20: /* MMU passthrough */
403         switch(size) {
404         case 1:
405             ret = ldub_phys(T0);
406             break;
407         case 2:
408             ret = lduw_phys(T0 & ~1);
409             break;
410         default:
411         case 4:
412             ret = ldl_phys(T0 & ~3);
413             break;
414         case 8:
415             tmp = ldq_phys(T0 & ~7);
416             ret = tmp >> 32;
417             T0 = tmp;
418             break;
419         }
420         break;
421     case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
422         switch(size) {
423         case 1:
424             ret = ldub_phys((target_phys_addr_t)T0
425                             | ((target_phys_addr_t)(asi & 0xf) << 32));
426             break;
427         case 2:
428             ret = lduw_phys((target_phys_addr_t)(T0 & ~1)
429                             | ((target_phys_addr_t)(asi & 0xf) << 32));
430             break;
431         default:
432         case 4:
433             ret = ldl_phys((target_phys_addr_t)(T0 & ~3)
434                            | ((target_phys_addr_t)(asi & 0xf) << 32));
435             break;
436         case 8:
437             tmp = ldq_phys((target_phys_addr_t)(T0 & ~7)
438                            | ((target_phys_addr_t)(asi & 0xf) << 32));
439             ret = tmp >> 32;
440             T0 = tmp;
441             break;
442         }
443         break;
444     case 0x39: /* data cache diagnostic register */
445         ret = 0;
446         break;
447     default:
448         do_unassigned_access(T0, 0, 0, asi);
449         ret = 0;
450         break;
451     }
452     if (sign) {
453         switch(size) {
454         case 1:
455             T1 = (int8_t) ret;
456             break;
457         case 2:
458             T1 = (int16_t) ret;
459             break;
460         default:
461             T1 = ret;
462             break;
463         }
464     }
465     else
466         T1 = ret;
467 #ifdef DEBUG_ASI
468     dump_asi("read ", last_T0, asi, size, T1, T0);
469 #endif
470 }
471
472 void helper_st_asi(int asi, int size)
473 {
474     switch(asi) {
475     case 2: /* SuperSparc MXCC registers */
476         switch (T0) {
477         case 0x01c00000: /* MXCC stream data register 0 */
478             if (size == 8)
479                 env->mxccdata[0] = ((uint64_t)T1 << 32) | T2;
480             else
481                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
482             break;
483         case 0x01c00008: /* MXCC stream data register 1 */
484             if (size == 8)
485                 env->mxccdata[1] = ((uint64_t)T1 << 32) | T2;
486             else
487                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
488             break;
489         case 0x01c00010: /* MXCC stream data register 2 */
490             if (size == 8)
491                 env->mxccdata[2] = ((uint64_t)T1 << 32) | T2;
492             else
493                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
494             break;
495         case 0x01c00018: /* MXCC stream data register 3 */
496             if (size == 8)
497                 env->mxccdata[3] = ((uint64_t)T1 << 32) | T2;
498             else
499                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
500             break;
501         case 0x01c00100: /* MXCC stream source */
502             if (size == 8)
503                 env->mxccregs[0] = ((uint64_t)T1 << 32) | T2;
504             else
505                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
506             env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +  0);
507             env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +  8);
508             env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 16);
509             env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 24);
510             break;
511         case 0x01c00200: /* MXCC stream destination */
512             if (size == 8)
513                 env->mxccregs[1] = ((uint64_t)T1 << 32) | T2;
514             else
515                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
516             stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0, env->mxccdata[0]);
517             stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8, env->mxccdata[1]);
518             stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16, env->mxccdata[2]);
519             stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24, env->mxccdata[3]);
520             break;
521         case 0x01c00a00: /* MXCC control register */
522             if (size == 8)
523                 env->mxccregs[3] = ((uint64_t)T1 << 32) | T2;
524             else
525                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
526             break;
527         case 0x01c00a04: /* MXCC control register */
528             if (size == 4)
529                 env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000ULL) | T1;
530             else
531                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
532             break;
533         case 0x01c00e00: /* MXCC error register  */
534             // writing a 1 bit clears the error
535             if (size == 8)
536                 env->mxccregs[6] &= ~(((uint64_t)T1 << 32) | T2);
537             else
538                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
539             break;
540         case 0x01c00f00: /* MBus port address register */
541             if (size == 8)
542                 env->mxccregs[7] = ((uint64_t)T1 << 32) | T2;
543             else
544                 DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
545             break;
546         default:
547             DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
548             break;
549         }
550         DPRINTF_MXCC("asi = %d, size = %d, T0 = %08x, T1 = %08x\n", asi, size, T0, T1);
551 #ifdef DEBUG_MXCC
552         dump_mxcc(env);
553 #endif
554         break;
555     case 3: /* MMU flush */
556         {
557             int mmulev;
558
559             mmulev = (T0 >> 8) & 15;
560             DPRINTF_MMU("mmu flush level %d\n", mmulev);
561             switch (mmulev) {
562             case 0: // flush page
563                 tlb_flush_page(env, T0 & 0xfffff000);
564                 break;
565             case 1: // flush segment (256k)
566             case 2: // flush region (16M)
567             case 3: // flush context (4G)
568             case 4: // flush entire
569                 tlb_flush(env, 1);
570                 break;
571             default:
572                 break;
573             }
574 #ifdef DEBUG_MMU
575             dump_mmu(env);
576 #endif
577         }
578         break;
579     case 4: /* write MMU regs */
580         {
581             int reg = (T0 >> 8) & 0x1f;
582             uint32_t oldreg;
583
584             oldreg = env->mmuregs[reg];
585             switch(reg) {
586             case 0:
587                 env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
588                                     (T1 & 0x00ffffff);
589                 // Mappings generated during no-fault mode or MMU
590                 // disabled mode are invalid in normal mode
591                 if ((oldreg & (MMU_E | MMU_NF | env->mmu_bm)) !=
592                     (env->mmuregs[reg] & (MMU_E | MMU_NF | env->mmu_bm)))
593                     tlb_flush(env, 1);
594                 break;
595             case 2:
596                 env->mmuregs[reg] = T1;
597                 if (oldreg != env->mmuregs[reg]) {
598                     /* we flush when the MMU context changes because
599                        QEMU has no MMU context support */
600                     tlb_flush(env, 1);
601                 }
602                 break;
603             case 3:
604             case 4:
605                 break;
606             case 0x13:
607                 env->mmuregs[3] = T1;
608                 break;
609             case 0x14:
610                 env->mmuregs[4] = T1;
611                 break;
612             default:
613                 env->mmuregs[reg] = T1;
614                 break;
615             }
616             if (oldreg != env->mmuregs[reg]) {
617                 DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
618             }
619 #ifdef DEBUG_MMU
620             dump_mmu(env);
621 #endif
622         }
623         break;
624     case 0xa: /* User data access */
625         switch(size) {
626         case 1:
627             stb_user(T0, T1);
628             break;
629         case 2:
630             stw_user(T0 & ~1, T1);
631             break;
632         default:
633         case 4:
634             stl_user(T0 & ~3, T1);
635             break;
636         case 8:
637             stq_user(T0 & ~7, ((uint64_t)T1 << 32) | T2);
638             break;
639         }
640         break;
641     case 0xb: /* Supervisor data access */
642         switch(size) {
643         case 1:
644             stb_kernel(T0, T1);
645             break;
646         case 2:
647             stw_kernel(T0 & ~1, T1);
648             break;
649         default:
650         case 4:
651             stl_kernel(T0 & ~3, T1);
652             break;
653         case 8:
654             stq_kernel(T0 & ~7, ((uint64_t)T1 << 32) | T2);
655             break;
656         }
657         break;
658     case 0xc: /* I-cache tag */
659     case 0xd: /* I-cache data */
660     case 0xe: /* D-cache tag */
661     case 0xf: /* D-cache data */
662     case 0x10: /* I/D-cache flush page */
663     case 0x11: /* I/D-cache flush segment */
664     case 0x12: /* I/D-cache flush region */
665     case 0x13: /* I/D-cache flush context */
666     case 0x14: /* I/D-cache flush user */
667         break;
668     case 0x17: /* Block copy, sta access */
669         {
670             // value (T1) = src
671             // address (T0) = dst
672             // copy 32 bytes
673             unsigned int i;
674             uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
675
676             for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
677                 temp = ldl_kernel(src);
678                 stl_kernel(dst, temp);
679             }
680         }
681         break;
682     case 0x1f: /* Block fill, stda access */
683         {
684             // value (T1, T2)
685             // address (T0) = dst
686             // fill 32 bytes
687             unsigned int i;
688             uint32_t dst = T0 & 7;
689             uint64_t val;
690
691             val = (((uint64_t)T1) << 32) | T2;
692
693             for (i = 0; i < 32; i += 8, dst += 8)
694                 stq_kernel(dst, val);
695         }
696         break;
697     case 0x20: /* MMU passthrough */
698         {
699             switch(size) {
700             case 1:
701                 stb_phys(T0, T1);
702                 break;
703             case 2:
704                 stw_phys(T0 & ~1, T1);
705                 break;
706             case 4:
707             default:
708                 stl_phys(T0 & ~3, T1);
709                 break;
710             case 8:
711                 stq_phys(T0 & ~7, ((uint64_t)T1 << 32) | T2);
712                 break;
713             }
714         }
715         break;
716     case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
717     case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
718         {
719             switch(size) {
720             case 1:
721                 stb_phys((target_phys_addr_t)T0
722                          | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
723                 break;
724             case 2:
725                 stw_phys((target_phys_addr_t)(T0 & ~1)
726                             | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
727                 break;
728             case 4:
729             default:
730                 stl_phys((target_phys_addr_t)(T0 & ~3)
731                            | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
732                 break;
733             case 8:
734                 stq_phys((target_phys_addr_t)(T0 & ~7)
735                            | ((target_phys_addr_t)(asi & 0xf) << 32),
736                          ((uint64_t)T1 << 32) | T2);
737                 break;
738             }
739         }
740         break;
741     case 0x30: /* store buffer tags */
742     case 0x31: /* store buffer data or Ross RT620 I-cache flush */
743     case 0x32: /* store buffer control */
744     case 0x36: /* I-cache flash clear */
745     case 0x37: /* D-cache flash clear */
746     case 0x38: /* breakpoint diagnostics */
747     case 0x4c: /* breakpoint action */
748         break;
749     case 9: /* Supervisor code access, XXX */
750     case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
751     default:
752         do_unassigned_access(T0, 1, 0, asi);
753         break;
754     }
755 #ifdef DEBUG_ASI
756     dump_asi("write", T0, asi, size, T1, T2);
757 #endif
758 }
759
760 #endif /* CONFIG_USER_ONLY */
761 #else /* TARGET_SPARC64 */
762
763 #ifdef CONFIG_USER_ONLY
764 void helper_ld_asi(int asi, int size, int sign)
765 {
766     uint64_t ret = 0;
767
768     if (asi < 0x80)
769         raise_exception(TT_PRIV_ACT);
770
771     switch (asi) {
772     case 0x80: // Primary
773     case 0x82: // Primary no-fault
774     case 0x88: // Primary LE
775     case 0x8a: // Primary no-fault LE
776         {
777             switch(size) {
778             case 1:
779                 ret = ldub_raw(T0);
780                 break;
781             case 2:
782                 ret = lduw_raw(T0 & ~1);
783                 break;
784             case 4:
785                 ret = ldl_raw(T0 & ~3);
786                 break;
787             default:
788             case 8:
789                 ret = ldq_raw(T0 & ~7);
790                 break;
791             }
792         }
793         break;
794     case 0x81: // Secondary
795     case 0x83: // Secondary no-fault
796     case 0x89: // Secondary LE
797     case 0x8b: // Secondary no-fault LE
798         // XXX
799         break;
800     default:
801         break;
802     }
803
804     /* Convert from little endian */
805     switch (asi) {
806     case 0x88: // Primary LE
807     case 0x89: // Secondary LE
808     case 0x8a: // Primary no-fault LE
809     case 0x8b: // Secondary no-fault LE
810         switch(size) {
811         case 2:
812             ret = bswap16(ret);
813             break;
814         case 4:
815             ret = bswap32(ret);
816             break;
817         case 8:
818             ret = bswap64(ret);
819             break;
820         default:
821             break;
822         }
823     default:
824         break;
825     }
826
827     /* Convert to signed number */
828     if (sign) {
829         switch(size) {
830         case 1:
831             ret = (int8_t) ret;
832             break;
833         case 2:
834             ret = (int16_t) ret;
835             break;
836         case 4:
837             ret = (int32_t) ret;
838             break;
839         default:
840             break;
841         }
842     }
843     T1 = ret;
844 }
845
846 void helper_st_asi(int asi, int size)
847 {
848     if (asi < 0x80)
849         raise_exception(TT_PRIV_ACT);
850
851     /* Convert to little endian */
852     switch (asi) {
853     case 0x88: // Primary LE
854     case 0x89: // Secondary LE
855         switch(size) {
856         case 2:
857             T0 = bswap16(T0);
858             break;
859         case 4:
860             T0 = bswap32(T0);
861             break;
862         case 8:
863             T0 = bswap64(T0);
864             break;
865         default:
866             break;
867         }
868     default:
869         break;
870     }
871
872     switch(asi) {
873     case 0x80: // Primary
874     case 0x88: // Primary LE
875         {
876             switch(size) {
877             case 1:
878                 stb_raw(T0, T1);
879                 break;
880             case 2:
881                 stw_raw(T0 & ~1, T1);
882                 break;
883             case 4:
884                 stl_raw(T0 & ~3, T1);
885                 break;
886             case 8:
887             default:
888                 stq_raw(T0 & ~7, T1);
889                 break;
890             }
891         }
892         break;
893     case 0x81: // Secondary
894     case 0x89: // Secondary LE
895         // XXX
896         return;
897
898     case 0x82: // Primary no-fault, RO
899     case 0x83: // Secondary no-fault, RO
900     case 0x8a: // Primary no-fault LE, RO
901     case 0x8b: // Secondary no-fault LE, RO
902     default:
903         do_unassigned_access(T0, 1, 0, 1);
904         return;
905     }
906 }
907
908 #else /* CONFIG_USER_ONLY */
909
910 void helper_ld_asi(int asi, int size, int sign)
911 {
912     uint64_t ret = 0;
913
914     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
915         || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV)))
916         raise_exception(TT_PRIV_ACT);
917
918     switch (asi) {
919     case 0x10: // As if user primary
920     case 0x18: // As if user primary LE
921     case 0x80: // Primary
922     case 0x82: // Primary no-fault
923     case 0x88: // Primary LE
924     case 0x8a: // Primary no-fault LE
925         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
926             if (env->hpstate & HS_PRIV) {
927                 switch(size) {
928                 case 1:
929                     ret = ldub_hypv(T0);
930                     break;
931                 case 2:
932                     ret = lduw_hypv(T0 & ~1);
933                     break;
934                 case 4:
935                     ret = ldl_hypv(T0 & ~3);
936                     break;
937                 default:
938                 case 8:
939                     ret = ldq_hypv(T0 & ~7);
940                     break;
941                 }
942             } else {
943                 switch(size) {
944                 case 1:
945                     ret = ldub_kernel(T0);
946                     break;
947                 case 2:
948                     ret = lduw_kernel(T0 & ~1);
949                     break;
950                 case 4:
951                     ret = ldl_kernel(T0 & ~3);
952                     break;
953                 default:
954                 case 8:
955                     ret = ldq_kernel(T0 & ~7);
956                     break;
957                 }
958             }
959         } else {
960             switch(size) {
961             case 1:
962                 ret = ldub_user(T0);
963                 break;
964             case 2:
965                 ret = lduw_user(T0 & ~1);
966                 break;
967             case 4:
968                 ret = ldl_user(T0 & ~3);
969                 break;
970             default:
971             case 8:
972                 ret = ldq_user(T0 & ~7);
973                 break;
974             }
975         }
976         break;
977     case 0x14: // Bypass
978     case 0x15: // Bypass, non-cacheable
979     case 0x1c: // Bypass LE
980     case 0x1d: // Bypass, non-cacheable LE
981         {
982             switch(size) {
983             case 1:
984                 ret = ldub_phys(T0);
985                 break;
986             case 2:
987                 ret = lduw_phys(T0 & ~1);
988                 break;
989             case 4:
990                 ret = ldl_phys(T0 & ~3);
991                 break;
992             default:
993             case 8:
994                 ret = ldq_phys(T0 & ~7);
995                 break;
996             }
997             break;
998         }
999     case 0x04: // Nucleus
1000     case 0x0c: // Nucleus Little Endian (LE)
1001     case 0x11: // As if user secondary
1002     case 0x19: // As if user secondary LE
1003     case 0x24: // Nucleus quad LDD 128 bit atomic
1004     case 0x2c: // Nucleus quad LDD 128 bit atomic
1005     case 0x4a: // UPA config
1006     case 0x81: // Secondary
1007     case 0x83: // Secondary no-fault
1008     case 0x89: // Secondary LE
1009     case 0x8b: // Secondary no-fault LE
1010         // XXX
1011         break;
1012     case 0x45: // LSU
1013         ret = env->lsu;
1014         break;
1015     case 0x50: // I-MMU regs
1016         {
1017             int reg = (T0 >> 3) & 0xf;
1018
1019             ret = env->immuregs[reg];
1020             break;
1021         }
1022     case 0x51: // I-MMU 8k TSB pointer
1023     case 0x52: // I-MMU 64k TSB pointer
1024     case 0x55: // I-MMU data access
1025         // XXX
1026         break;
1027     case 0x56: // I-MMU tag read
1028         {
1029             unsigned int i;
1030
1031             for (i = 0; i < 64; i++) {
1032                 // Valid, ctx match, vaddr match
1033                 if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
1034                     env->itlb_tag[i] == T0) {
1035                     ret = env->itlb_tag[i];
1036                     break;
1037                 }
1038             }
1039             break;
1040         }
1041     case 0x58: // D-MMU regs
1042         {
1043             int reg = (T0 >> 3) & 0xf;
1044
1045             ret = env->dmmuregs[reg];
1046             break;
1047         }
1048     case 0x5e: // D-MMU tag read
1049         {
1050             unsigned int i;
1051
1052             for (i = 0; i < 64; i++) {
1053                 // Valid, ctx match, vaddr match
1054                 if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
1055                     env->dtlb_tag[i] == T0) {
1056                     ret = env->dtlb_tag[i];
1057                     break;
1058                 }
1059             }
1060             break;
1061         }
1062     case 0x59: // D-MMU 8k TSB pointer
1063     case 0x5a: // D-MMU 64k TSB pointer
1064     case 0x5b: // D-MMU data pointer
1065     case 0x5d: // D-MMU data access
1066     case 0x48: // Interrupt dispatch, RO
1067     case 0x49: // Interrupt data receive
1068     case 0x7f: // Incoming interrupt vector, RO
1069         // XXX
1070         break;
1071     case 0x54: // I-MMU data in, WO
1072     case 0x57: // I-MMU demap, WO
1073     case 0x5c: // D-MMU data in, WO
1074     case 0x5f: // D-MMU demap, WO
1075     case 0x77: // Interrupt vector, WO
1076     default:
1077         do_unassigned_access(T0, 0, 0, 1);
1078         ret = 0;
1079         break;
1080     }
1081
1082     /* Convert from little endian */
1083     switch (asi) {
1084     case 0x0c: // Nucleus Little Endian (LE)
1085     case 0x18: // As if user primary LE
1086     case 0x19: // As if user secondary LE
1087     case 0x1c: // Bypass LE
1088     case 0x1d: // Bypass, non-cacheable LE
1089     case 0x88: // Primary LE
1090     case 0x89: // Secondary LE
1091     case 0x8a: // Primary no-fault LE
1092     case 0x8b: // Secondary no-fault LE
1093         switch(size) {
1094         case 2:
1095             ret = bswap16(ret);
1096             break;
1097         case 4:
1098             ret = bswap32(ret);
1099             break;
1100         case 8:
1101             ret = bswap64(ret);
1102             break;
1103         default:
1104             break;
1105         }
1106     default:
1107         break;
1108     }
1109
1110     /* Convert to signed number */
1111     if (sign) {
1112         switch(size) {
1113         case 1:
1114             ret = (int8_t) ret;
1115             break;
1116         case 2:
1117             ret = (int16_t) ret;
1118             break;
1119         case 4:
1120             ret = (int32_t) ret;
1121             break;
1122         default:
1123             break;
1124         }
1125     }
1126     T1 = ret;
1127 }
1128
1129 void helper_st_asi(int asi, int size)
1130 {
1131     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1132         || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV)))
1133         raise_exception(TT_PRIV_ACT);
1134
1135     /* Convert to little endian */
1136     switch (asi) {
1137     case 0x0c: // Nucleus Little Endian (LE)
1138     case 0x18: // As if user primary LE
1139     case 0x19: // As if user secondary LE
1140     case 0x1c: // Bypass LE
1141     case 0x1d: // Bypass, non-cacheable LE
1142     case 0x88: // Primary LE
1143     case 0x89: // Secondary LE
1144         switch(size) {
1145         case 2:
1146             T0 = bswap16(T0);
1147             break;
1148         case 4:
1149             T0 = bswap32(T0);
1150             break;
1151         case 8:
1152             T0 = bswap64(T0);
1153             break;
1154         default:
1155             break;
1156         }
1157     default:
1158         break;
1159     }
1160
1161     switch(asi) {
1162     case 0x10: // As if user primary
1163     case 0x18: // As if user primary LE
1164     case 0x80: // Primary
1165     case 0x88: // Primary LE
1166         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1167             if (env->hpstate & HS_PRIV) {
1168                 switch(size) {
1169                 case 1:
1170                     stb_hypv(T0, T1);
1171                     break;
1172                 case 2:
1173                     stw_hypv(T0 & ~1, T1);
1174                     break;
1175                 case 4:
1176                     stl_hypv(T0 & ~3, T1);
1177                     break;
1178                 case 8:
1179                 default:
1180                     stq_hypv(T0 & ~7, T1);
1181                     break;
1182                 }
1183             } else {
1184                 switch(size) {
1185                 case 1:
1186                     stb_kernel(T0, T1);
1187                     break;
1188                 case 2:
1189                     stw_kernel(T0 & ~1, T1);
1190                     break;
1191                 case 4:
1192                     stl_kernel(T0 & ~3, T1);
1193                     break;
1194                 case 8:
1195                 default:
1196                     stq_kernel(T0 & ~7, T1);
1197                     break;
1198                 }
1199             }
1200         } else {
1201             switch(size) {
1202             case 1:
1203                 stb_user(T0, T1);
1204                 break;
1205             case 2:
1206                 stw_user(T0 & ~1, T1);
1207                 break;
1208             case 4:
1209                 stl_user(T0 & ~3, T1);
1210                 break;
1211             case 8:
1212             default:
1213                 stq_user(T0 & ~7, T1);
1214                 break;
1215             }
1216         }
1217         break;
1218     case 0x14: // Bypass
1219     case 0x15: // Bypass, non-cacheable
1220     case 0x1c: // Bypass LE
1221     case 0x1d: // Bypass, non-cacheable LE
1222         {
1223             switch(size) {
1224             case 1:
1225                 stb_phys(T0, T1);
1226                 break;
1227             case 2:
1228                 stw_phys(T0 & ~1, T1);
1229                 break;
1230             case 4:
1231                 stl_phys(T0 & ~3, T1);
1232                 break;
1233             case 8:
1234             default:
1235                 stq_phys(T0 & ~7, T1);
1236                 break;
1237             }
1238         }
1239         return;
1240     case 0x04: // Nucleus
1241     case 0x0c: // Nucleus Little Endian (LE)
1242     case 0x11: // As if user secondary
1243     case 0x19: // As if user secondary LE
1244     case 0x24: // Nucleus quad LDD 128 bit atomic
1245     case 0x2c: // Nucleus quad LDD 128 bit atomic
1246     case 0x4a: // UPA config
1247     case 0x81: // Secondary
1248     case 0x89: // Secondary LE
1249         // XXX
1250         return;
1251     case 0x45: // LSU
1252         {
1253             uint64_t oldreg;
1254
1255             oldreg = env->lsu;
1256             env->lsu = T1 & (DMMU_E | IMMU_E);
1257             // Mappings generated during D/I MMU disabled mode are
1258             // invalid in normal mode
1259             if (oldreg != env->lsu) {
1260                 DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
1261 #ifdef DEBUG_MMU
1262                 dump_mmu(env);
1263 #endif
1264                 tlb_flush(env, 1);
1265             }
1266             return;
1267         }
1268     case 0x50: // I-MMU regs
1269         {
1270             int reg = (T0 >> 3) & 0xf;
1271             uint64_t oldreg;
1272
1273             oldreg = env->immuregs[reg];
1274             switch(reg) {
1275             case 0: // RO
1276             case 4:
1277                 return;
1278             case 1: // Not in I-MMU
1279             case 2:
1280             case 7:
1281             case 8:
1282                 return;
1283             case 3: // SFSR
1284                 if ((T1 & 1) == 0)
1285                     T1 = 0; // Clear SFSR
1286                 break;
1287             case 5: // TSB access
1288             case 6: // Tag access
1289             default:
1290                 break;
1291             }
1292             env->immuregs[reg] = T1;
1293             if (oldreg != env->immuregs[reg]) {
1294                 DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
1295             }
1296 #ifdef DEBUG_MMU
1297             dump_mmu(env);
1298 #endif
1299             return;
1300         }
1301     case 0x54: // I-MMU data in
1302         {
1303             unsigned int i;
1304
1305             // Try finding an invalid entry
1306             for (i = 0; i < 64; i++) {
1307                 if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
1308                     env->itlb_tag[i] = env->immuregs[6];
1309                     env->itlb_tte[i] = T1;
1310                     return;
1311                 }
1312             }
1313             // Try finding an unlocked entry
1314             for (i = 0; i < 64; i++) {
1315                 if ((env->itlb_tte[i] & 0x40) == 0) {
1316                     env->itlb_tag[i] = env->immuregs[6];
1317                     env->itlb_tte[i] = T1;
1318                     return;
1319                 }
1320             }
1321             // error state?
1322             return;
1323         }
1324     case 0x55: // I-MMU data access
1325         {
1326             unsigned int i = (T0 >> 3) & 0x3f;
1327
1328             env->itlb_tag[i] = env->immuregs[6];
1329             env->itlb_tte[i] = T1;
1330             return;
1331         }
1332     case 0x57: // I-MMU demap
1333         // XXX
1334         return;
1335     case 0x58: // D-MMU regs
1336         {
1337             int reg = (T0 >> 3) & 0xf;
1338             uint64_t oldreg;
1339
1340             oldreg = env->dmmuregs[reg];
1341             switch(reg) {
1342             case 0: // RO
1343             case 4:
1344                 return;
1345             case 3: // SFSR
1346                 if ((T1 & 1) == 0) {
1347                     T1 = 0; // Clear SFSR, Fault address
1348                     env->dmmuregs[4] = 0;
1349                 }
1350                 env->dmmuregs[reg] = T1;
1351                 break;
1352             case 1: // Primary context
1353             case 2: // Secondary context
1354             case 5: // TSB access
1355             case 6: // Tag access
1356             case 7: // Virtual Watchpoint
1357             case 8: // Physical Watchpoint
1358             default:
1359                 break;
1360             }
1361             env->dmmuregs[reg] = T1;
1362             if (oldreg != env->dmmuregs[reg]) {
1363                 DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
1364             }
1365 #ifdef DEBUG_MMU
1366             dump_mmu(env);
1367 #endif
1368             return;
1369         }
1370     case 0x5c: // D-MMU data in
1371         {
1372             unsigned int i;
1373
1374             // Try finding an invalid entry
1375             for (i = 0; i < 64; i++) {
1376                 if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
1377                     env->dtlb_tag[i] = env->dmmuregs[6];
1378                     env->dtlb_tte[i] = T1;
1379                     return;
1380                 }
1381             }
1382             // Try finding an unlocked entry
1383             for (i = 0; i < 64; i++) {
1384                 if ((env->dtlb_tte[i] & 0x40) == 0) {
1385                     env->dtlb_tag[i] = env->dmmuregs[6];
1386                     env->dtlb_tte[i] = T1;
1387                     return;
1388                 }
1389             }
1390             // error state?
1391             return;
1392         }
1393     case 0x5d: // D-MMU data access
1394         {
1395             unsigned int i = (T0 >> 3) & 0x3f;
1396
1397             env->dtlb_tag[i] = env->dmmuregs[6];
1398             env->dtlb_tte[i] = T1;
1399             return;
1400         }
1401     case 0x5f: // D-MMU demap
1402     case 0x49: // Interrupt data receive
1403         // XXX
1404         return;
1405     case 0x51: // I-MMU 8k TSB pointer, RO
1406     case 0x52: // I-MMU 64k TSB pointer, RO
1407     case 0x56: // I-MMU tag read, RO
1408     case 0x59: // D-MMU 8k TSB pointer, RO
1409     case 0x5a: // D-MMU 64k TSB pointer, RO
1410     case 0x5b: // D-MMU data pointer, RO
1411     case 0x5e: // D-MMU tag read, RO
1412     case 0x48: // Interrupt dispatch, RO
1413     case 0x7f: // Incoming interrupt vector, RO
1414     case 0x82: // Primary no-fault, RO
1415     case 0x83: // Secondary no-fault, RO
1416     case 0x8a: // Primary no-fault LE, RO
1417     case 0x8b: // Secondary no-fault LE, RO
1418     default:
1419         do_unassigned_access(T0, 1, 0, 1);
1420         return;
1421     }
1422 }
1423 #endif /* CONFIG_USER_ONLY */
1424
1425 void helper_ldf_asi(int asi, int size, int rd)
1426 {
1427     target_ulong tmp_T0 = T0, tmp_T1 = T1;
1428     unsigned int i;
1429
1430     switch (asi) {
1431     case 0xf0: // Block load primary
1432     case 0xf1: // Block load secondary
1433     case 0xf8: // Block load primary LE
1434     case 0xf9: // Block load secondary LE
1435         if (rd & 7) {
1436             raise_exception(TT_ILL_INSN);
1437             return;
1438         }
1439         if (T0 & 0x3f) {
1440             raise_exception(TT_UNALIGNED);
1441             return;
1442         }
1443         for (i = 0; i < 16; i++) {
1444             helper_ld_asi(asi & 0x8f, 4, 0);
1445             *(uint32_t *)&env->fpr[rd++] = T1;
1446             T0 += 4;
1447         }
1448         T0 = tmp_T0;
1449         T1 = tmp_T1;
1450
1451         return;
1452     default:
1453         break;
1454     }
1455
1456     helper_ld_asi(asi, size, 0);
1457     switch(size) {
1458     default:
1459     case 4:
1460         *((uint32_t *)&FT0) = T1;
1461         break;
1462     case 8:
1463         *((int64_t *)&DT0) = T1;
1464         break;
1465 #if defined(CONFIG_USER_ONLY)
1466     case 16:
1467         // XXX
1468         break;
1469 #endif
1470     }
1471     T1 = tmp_T1;
1472 }
1473
1474 void helper_stf_asi(int asi, int size, int rd)
1475 {
1476     target_ulong tmp_T0 = T0, tmp_T1 = T1;
1477     unsigned int i;
1478
1479     switch (asi) {
1480     case 0xf0: // Block store primary
1481     case 0xf1: // Block store secondary
1482     case 0xf8: // Block store primary LE
1483     case 0xf9: // Block store secondary LE
1484         if (rd & 7) {
1485             raise_exception(TT_ILL_INSN);
1486             return;
1487         }
1488         if (T0 & 0x3f) {
1489             raise_exception(TT_UNALIGNED);
1490             return;
1491         }
1492         for (i = 0; i < 16; i++) {
1493             T1 = *(uint32_t *)&env->fpr[rd++];
1494             helper_st_asi(asi & 0x8f, 4);
1495             T0 += 4;
1496         }
1497         T0 = tmp_T0;
1498         T1 = tmp_T1;
1499
1500         return;
1501     default:
1502         break;
1503     }
1504
1505     switch(size) {
1506     default:
1507     case 4:
1508         T1 = *((uint32_t *)&FT0);
1509         break;
1510     case 8:
1511         T1 = *((int64_t *)&DT0);
1512         break;
1513 #if defined(CONFIG_USER_ONLY)
1514     case 16:
1515         // XXX
1516         break;
1517 #endif
1518     }
1519     helper_st_asi(asi, size);
1520     T1 = tmp_T1;
1521 }
1522
1523 #endif /* TARGET_SPARC64 */
1524
1525 #ifndef TARGET_SPARC64
1526 void helper_rett()
1527 {
1528     unsigned int cwp;
1529
1530     if (env->psret == 1)
1531         raise_exception(TT_ILL_INSN);
1532
1533     env->psret = 1;
1534     cwp = (env->cwp + 1) & (NWINDOWS - 1);
1535     if (env->wim & (1 << cwp)) {
1536         raise_exception(TT_WIN_UNF);
1537     }
1538     set_cwp(cwp);
1539     env->psrs = env->psrps;
1540 }
1541 #endif
1542
1543 void helper_ldfsr(void)
1544 {
1545     int rnd_mode;
1546     switch (env->fsr & FSR_RD_MASK) {
1547     case FSR_RD_NEAREST:
1548         rnd_mode = float_round_nearest_even;
1549         break;
1550     default:
1551     case FSR_RD_ZERO:
1552         rnd_mode = float_round_to_zero;
1553         break;
1554     case FSR_RD_POS:
1555         rnd_mode = float_round_up;
1556         break;
1557     case FSR_RD_NEG:
1558         rnd_mode = float_round_down;
1559         break;
1560     }
1561     set_float_rounding_mode(rnd_mode, &env->fp_status);
1562 }
1563
1564 void helper_debug()
1565 {
1566     env->exception_index = EXCP_DEBUG;
1567     cpu_loop_exit();
1568 }
1569
1570 #ifndef TARGET_SPARC64
1571 void do_wrpsr()
1572 {
1573     if ((T0 & PSR_CWP) >= NWINDOWS)
1574         raise_exception(TT_ILL_INSN);
1575     else
1576         PUT_PSR(env, T0);
1577 }
1578
1579 void do_rdpsr()
1580 {
1581     T0 = GET_PSR(env);
1582 }
1583
1584 #else
1585
1586 void do_popc()
1587 {
1588     T0 = ctpop64(T1);
1589 }
1590
1591 static inline uint64_t *get_gregset(uint64_t pstate)
1592 {
1593     switch (pstate) {
1594     default:
1595     case 0:
1596         return env->bgregs;
1597     case PS_AG:
1598         return env->agregs;
1599     case PS_MG:
1600         return env->mgregs;
1601     case PS_IG:
1602         return env->igregs;
1603     }
1604 }
1605
1606 static inline void change_pstate(uint64_t new_pstate)
1607 {
1608     uint64_t pstate_regs, new_pstate_regs;
1609     uint64_t *src, *dst;
1610
1611     pstate_regs = env->pstate & 0xc01;
1612     new_pstate_regs = new_pstate & 0xc01;
1613     if (new_pstate_regs != pstate_regs) {
1614         // Switch global register bank
1615         src = get_gregset(new_pstate_regs);
1616         dst = get_gregset(pstate_regs);
1617         memcpy32(dst, env->gregs);
1618         memcpy32(env->gregs, src);
1619     }
1620     env->pstate = new_pstate;
1621 }
1622
1623 void do_wrpstate(void)
1624 {
1625     change_pstate(T0 & 0xf3f);
1626 }
1627
1628 void do_done(void)
1629 {
1630     env->tl--;
1631     env->pc = env->tnpc[env->tl];
1632     env->npc = env->tnpc[env->tl] + 4;
1633     PUT_CCR(env, env->tstate[env->tl] >> 32);
1634     env->asi = (env->tstate[env->tl] >> 24) & 0xff;
1635     change_pstate((env->tstate[env->tl] >> 8) & 0xf3f);
1636     PUT_CWP64(env, env->tstate[env->tl] & 0xff);
1637 }
1638
1639 void do_retry(void)
1640 {
1641     env->tl--;
1642     env->pc = env->tpc[env->tl];
1643     env->npc = env->tnpc[env->tl];
1644     PUT_CCR(env, env->tstate[env->tl] >> 32);
1645     env->asi = (env->tstate[env->tl] >> 24) & 0xff;
1646     change_pstate((env->tstate[env->tl] >> 8) & 0xf3f);
1647     PUT_CWP64(env, env->tstate[env->tl] & 0xff);
1648 }
1649 #endif
1650
1651 void set_cwp(int new_cwp)
1652 {
1653     /* put the modified wrap registers at their proper location */
1654     if (env->cwp == (NWINDOWS - 1))
1655         memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
1656     env->cwp = new_cwp;
1657     /* put the wrap registers at their temporary location */
1658     if (new_cwp == (NWINDOWS - 1))
1659         memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
1660     env->regwptr = env->regbase + (new_cwp * 16);
1661     REGWPTR = env->regwptr;
1662 }
1663
1664 void cpu_set_cwp(CPUState *env1, int new_cwp)
1665 {
1666     CPUState *saved_env;
1667 #ifdef reg_REGWPTR
1668     target_ulong *saved_regwptr;
1669 #endif
1670
1671     saved_env = env;
1672 #ifdef reg_REGWPTR
1673     saved_regwptr = REGWPTR;
1674 #endif
1675     env = env1;
1676     set_cwp(new_cwp);
1677     env = saved_env;
1678 #ifdef reg_REGWPTR
1679     REGWPTR = saved_regwptr;
1680 #endif
1681 }
1682
1683 #ifdef TARGET_SPARC64
1684 #ifdef DEBUG_PCALL
1685 static const char * const excp_names[0x50] = {
1686     [TT_TFAULT] = "Instruction Access Fault",
1687     [TT_TMISS] = "Instruction Access MMU Miss",
1688     [TT_CODE_ACCESS] = "Instruction Access Error",
1689     [TT_ILL_INSN] = "Illegal Instruction",
1690     [TT_PRIV_INSN] = "Privileged Instruction",
1691     [TT_NFPU_INSN] = "FPU Disabled",
1692     [TT_FP_EXCP] = "FPU Exception",
1693     [TT_TOVF] = "Tag Overflow",
1694     [TT_CLRWIN] = "Clean Windows",
1695     [TT_DIV_ZERO] = "Division By Zero",
1696     [TT_DFAULT] = "Data Access Fault",
1697     [TT_DMISS] = "Data Access MMU Miss",
1698     [TT_DATA_ACCESS] = "Data Access Error",
1699     [TT_DPROT] = "Data Protection Error",
1700     [TT_UNALIGNED] = "Unaligned Memory Access",
1701     [TT_PRIV_ACT] = "Privileged Action",
1702     [TT_EXTINT | 0x1] = "External Interrupt 1",
1703     [TT_EXTINT | 0x2] = "External Interrupt 2",
1704     [TT_EXTINT | 0x3] = "External Interrupt 3",
1705     [TT_EXTINT | 0x4] = "External Interrupt 4",
1706     [TT_EXTINT | 0x5] = "External Interrupt 5",
1707     [TT_EXTINT | 0x6] = "External Interrupt 6",
1708     [TT_EXTINT | 0x7] = "External Interrupt 7",
1709     [TT_EXTINT | 0x8] = "External Interrupt 8",
1710     [TT_EXTINT | 0x9] = "External Interrupt 9",
1711     [TT_EXTINT | 0xa] = "External Interrupt 10",
1712     [TT_EXTINT | 0xb] = "External Interrupt 11",
1713     [TT_EXTINT | 0xc] = "External Interrupt 12",
1714     [TT_EXTINT | 0xd] = "External Interrupt 13",
1715     [TT_EXTINT | 0xe] = "External Interrupt 14",
1716     [TT_EXTINT | 0xf] = "External Interrupt 15",
1717 };
1718 #endif
1719
1720 void do_interrupt(int intno)
1721 {
1722 #ifdef DEBUG_PCALL
1723     if (loglevel & CPU_LOG_INT) {
1724         static int count;
1725         const char *name;
1726
1727         if (intno < 0 || intno >= 0x180 || (intno > 0x4f && intno < 0x80))
1728             name = "Unknown";
1729         else if (intno >= 0x100)
1730             name = "Trap Instruction";
1731         else if (intno >= 0xc0)
1732             name = "Window Fill";
1733         else if (intno >= 0x80)
1734             name = "Window Spill";
1735         else {
1736             name = excp_names[intno];
1737             if (!name)
1738                 name = "Unknown";
1739         }
1740
1741         fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
1742                 " SP=%016" PRIx64 "\n",
1743                 count, name, intno,
1744                 env->pc,
1745                 env->npc, env->regwptr[6]);
1746         cpu_dump_state(env, logfile, fprintf, 0);
1747 #if 0
1748         {
1749             int i;
1750             uint8_t *ptr;
1751
1752             fprintf(logfile, "       code=");
1753             ptr = (uint8_t *)env->pc;
1754             for(i = 0; i < 16; i++) {
1755                 fprintf(logfile, " %02x", ldub(ptr + i));
1756             }
1757             fprintf(logfile, "\n");
1758         }
1759 #endif
1760         count++;
1761     }
1762 #endif
1763 #if !defined(CONFIG_USER_ONLY)
1764     if (env->tl == MAXTL) {
1765         cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
1766         return;
1767     }
1768 #endif
1769     env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
1770         ((env->pstate & 0xf3f) << 8) | GET_CWP64(env);
1771     env->tpc[env->tl] = env->pc;
1772     env->tnpc[env->tl] = env->npc;
1773     env->tt[env->tl] = intno;
1774     change_pstate(PS_PEF | PS_PRIV | PS_AG);
1775
1776     if (intno == TT_CLRWIN)
1777         set_cwp((env->cwp - 1) & (NWINDOWS - 1));
1778     else if ((intno & 0x1c0) == TT_SPILL)
1779         set_cwp((env->cwp - env->cansave - 2) & (NWINDOWS - 1));
1780     else if ((intno & 0x1c0) == TT_FILL)
1781         set_cwp((env->cwp + 1) & (NWINDOWS - 1));
1782     env->tbr &= ~0x7fffULL;
1783     env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
1784     if (env->tl < MAXTL - 1) {
1785         env->tl++;
1786     } else {
1787         env->pstate |= PS_RED;
1788         if (env->tl != MAXTL)
1789             env->tl++;
1790     }
1791     env->pc = env->tbr;
1792     env->npc = env->pc + 4;
1793     env->exception_index = 0;
1794 }
1795 #else
1796 #ifdef DEBUG_PCALL
1797 static const char * const excp_names[0x80] = {
1798     [TT_TFAULT] = "Instruction Access Fault",
1799     [TT_ILL_INSN] = "Illegal Instruction",
1800     [TT_PRIV_INSN] = "Privileged Instruction",
1801     [TT_NFPU_INSN] = "FPU Disabled",
1802     [TT_WIN_OVF] = "Window Overflow",
1803     [TT_WIN_UNF] = "Window Underflow",
1804     [TT_UNALIGNED] = "Unaligned Memory Access",
1805     [TT_FP_EXCP] = "FPU Exception",
1806     [TT_DFAULT] = "Data Access Fault",
1807     [TT_TOVF] = "Tag Overflow",
1808     [TT_EXTINT | 0x1] = "External Interrupt 1",
1809     [TT_EXTINT | 0x2] = "External Interrupt 2",
1810     [TT_EXTINT | 0x3] = "External Interrupt 3",
1811     [TT_EXTINT | 0x4] = "External Interrupt 4",
1812     [TT_EXTINT | 0x5] = "External Interrupt 5",
1813     [TT_EXTINT | 0x6] = "External Interrupt 6",
1814     [TT_EXTINT | 0x7] = "External Interrupt 7",
1815     [TT_EXTINT | 0x8] = "External Interrupt 8",
1816     [TT_EXTINT | 0x9] = "External Interrupt 9",
1817     [TT_EXTINT | 0xa] = "External Interrupt 10",
1818     [TT_EXTINT | 0xb] = "External Interrupt 11",
1819     [TT_EXTINT | 0xc] = "External Interrupt 12",
1820     [TT_EXTINT | 0xd] = "External Interrupt 13",
1821     [TT_EXTINT | 0xe] = "External Interrupt 14",
1822     [TT_EXTINT | 0xf] = "External Interrupt 15",
1823     [TT_TOVF] = "Tag Overflow",
1824     [TT_CODE_ACCESS] = "Instruction Access Error",
1825     [TT_DATA_ACCESS] = "Data Access Error",
1826     [TT_DIV_ZERO] = "Division By Zero",
1827     [TT_NCP_INSN] = "Coprocessor Disabled",
1828 };
1829 #endif
1830
1831 void do_interrupt(int intno)
1832 {
1833     int cwp;
1834
1835 #ifdef DEBUG_PCALL
1836     if (loglevel & CPU_LOG_INT) {
1837         static int count;
1838         const char *name;
1839
1840         if (intno < 0 || intno >= 0x100)
1841             name = "Unknown";
1842         else if (intno >= 0x80)
1843             name = "Trap Instruction";
1844         else {
1845             name = excp_names[intno];
1846             if (!name)
1847                 name = "Unknown";
1848         }
1849
1850         fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
1851                 count, name, intno,
1852                 env->pc,
1853                 env->npc, env->regwptr[6]);
1854         cpu_dump_state(env, logfile, fprintf, 0);
1855 #if 0
1856         {
1857             int i;
1858             uint8_t *ptr;
1859
1860             fprintf(logfile, "       code=");
1861             ptr = (uint8_t *)env->pc;
1862             for(i = 0; i < 16; i++) {
1863                 fprintf(logfile, " %02x", ldub(ptr + i));
1864             }
1865             fprintf(logfile, "\n");
1866         }
1867 #endif
1868         count++;
1869     }
1870 #endif
1871 #if !defined(CONFIG_USER_ONLY)
1872     if (env->psret == 0) {
1873         cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
1874         return;
1875     }
1876 #endif
1877     env->psret = 0;
1878     cwp = (env->cwp - 1) & (NWINDOWS - 1);
1879     set_cwp(cwp);
1880     env->regwptr[9] = env->pc;
1881     env->regwptr[10] = env->npc;
1882     env->psrps = env->psrs;
1883     env->psrs = 1;
1884     env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
1885     env->pc = env->tbr;
1886     env->npc = env->pc + 4;
1887     env->exception_index = 0;
1888 }
1889 #endif
1890
1891 #if !defined(CONFIG_USER_ONLY)
1892
1893 static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
1894                                 void *retaddr);
1895
1896 #define MMUSUFFIX _mmu
1897 #define ALIGNED_ONLY
1898 #ifdef __s390__
1899 # define GETPC() ((void*)((unsigned long)__builtin_return_address(0) & 0x7fffffffUL))
1900 #else
1901 # define GETPC() (__builtin_return_address(0))
1902 #endif
1903
1904 #define SHIFT 0
1905 #include "softmmu_template.h"
1906
1907 #define SHIFT 1
1908 #include "softmmu_template.h"
1909
1910 #define SHIFT 2
1911 #include "softmmu_template.h"
1912
1913 #define SHIFT 3
1914 #include "softmmu_template.h"
1915
1916 static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
1917                                 void *retaddr)
1918 {
1919 #ifdef DEBUG_UNALIGNED
1920     printf("Unaligned access to 0x%x from 0x%x\n", addr, env->pc);
1921 #endif
1922     raise_exception(TT_UNALIGNED);
1923 }
1924
1925 /* try to fill the TLB and return an exception if error. If retaddr is
1926    NULL, it means that the function was called in C code (i.e. not
1927    from generated code or from helper.c) */
1928 /* XXX: fix it to restore all registers */
1929 void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
1930 {
1931     TranslationBlock *tb;
1932     int ret;
1933     unsigned long pc;
1934     CPUState *saved_env;
1935
1936     /* XXX: hack to restore env in all cases, even if not called from
1937        generated code */
1938     saved_env = env;
1939     env = cpu_single_env;
1940
1941     ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
1942     if (ret) {
1943         if (retaddr) {
1944             /* now we have a real cpu fault */
1945             pc = (unsigned long)retaddr;
1946             tb = tb_find_pc(pc);
1947             if (tb) {
1948                 /* the PC is inside the translated code. It means that we have
1949                    a virtual CPU fault */
1950                 cpu_restore_state(tb, env, pc, (void *)T2);
1951             }
1952         }
1953         cpu_loop_exit();
1954     }
1955     env = saved_env;
1956 }
1957
1958 #endif
1959
1960 #ifndef TARGET_SPARC64
1961 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
1962                           int is_asi)
1963 {
1964     CPUState *saved_env;
1965
1966     /* XXX: hack to restore env in all cases, even if not called from
1967        generated code */
1968     saved_env = env;
1969     env = cpu_single_env;
1970 #ifdef DEBUG_UNASSIGNED
1971     if (is_asi)
1972         printf("Unassigned mem %s access to " TARGET_FMT_plx " asi 0x%02x from "
1973                TARGET_FMT_lx "\n",
1974                is_exec ? "exec" : is_write ? "write" : "read", addr, is_asi,
1975                env->pc);
1976     else
1977         printf("Unassigned mem %s access to " TARGET_FMT_plx " from "
1978                TARGET_FMT_lx "\n",
1979                is_exec ? "exec" : is_write ? "write" : "read", addr, env->pc);
1980 #endif
1981     if (env->mmuregs[3]) /* Fault status register */
1982         env->mmuregs[3] = 1; /* overflow (not read before another fault) */
1983     if (is_asi)
1984         env->mmuregs[3] |= 1 << 16;
1985     if (env->psrs)
1986         env->mmuregs[3] |= 1 << 5;
1987     if (is_exec)
1988         env->mmuregs[3] |= 1 << 6;
1989     if (is_write)
1990         env->mmuregs[3] |= 1 << 7;
1991     env->mmuregs[3] |= (5 << 2) | 2;
1992     env->mmuregs[4] = addr; /* Fault address register */
1993     if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
1994         if (is_exec)
1995             raise_exception(TT_CODE_ACCESS);
1996         else
1997             raise_exception(TT_DATA_ACCESS);
1998     }
1999     env = saved_env;
2000 }
2001 #else
2002 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
2003                           int is_asi)
2004 {
2005 #ifdef DEBUG_UNASSIGNED
2006     CPUState *saved_env;
2007
2008     /* XXX: hack to restore env in all cases, even if not called from
2009        generated code */
2010     saved_env = env;
2011     env = cpu_single_env;
2012     printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx "\n",
2013            addr, env->pc);
2014     env = saved_env;
2015 #endif
2016     if (is_exec)
2017         raise_exception(TT_CODE_ACCESS);
2018     else
2019         raise_exception(TT_DATA_ACCESS);
2020 }
2021 #endif
2022