5 //#define DEBUG_UNALIGNED
6 //#define DEBUG_UNASSIGNED
8 void raise_exception(int tt
)
10 env
->exception_index
= tt
;
14 void check_ieee_exceptions()
16 T0
= get_float_exception_flags(&env
->fp_status
);
19 /* Copy IEEE 754 flags into FSR */
20 if (T0
& float_flag_invalid
)
22 if (T0
& float_flag_overflow
)
24 if (T0
& float_flag_underflow
)
26 if (T0
& float_flag_divbyzero
)
28 if (T0
& float_flag_inexact
)
31 if ((env
->fsr
& FSR_CEXC_MASK
) & ((env
->fsr
& FSR_TEM_MASK
) >> 23))
33 /* Unmasked exception, generate a trap */
34 env
->fsr
|= FSR_FTT_IEEE_EXCP
;
35 raise_exception(TT_FP_EXCP
);
39 /* Accumulate exceptions */
40 env
->fsr
|= (env
->fsr
& FSR_CEXC_MASK
) << 5;
45 #ifdef USE_INT_TO_FLOAT_HELPERS
48 set_float_exception_flags(0, &env
->fp_status
);
49 FT0
= int32_to_float32(*((int32_t *)&FT1
), &env
->fp_status
);
50 check_ieee_exceptions();
55 DT0
= int32_to_float64(*((int32_t *)&FT1
), &env
->fp_status
);
61 FT0
= float32_abs(FT1
);
67 DT0
= float64_abs(DT1
);
73 set_float_exception_flags(0, &env
->fp_status
);
74 FT0
= float32_sqrt(FT1
, &env
->fp_status
);
75 check_ieee_exceptions();
80 set_float_exception_flags(0, &env
->fp_status
);
81 DT0
= float64_sqrt(DT1
, &env
->fp_status
);
82 check_ieee_exceptions();
85 #define GEN_FCMP(name, size, reg1, reg2, FS, TRAP) \
86 void glue(do_, name) (void) \
88 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
89 switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \
90 case float_relation_unordered: \
91 T0 = (FSR_FCC1 | FSR_FCC0) << FS; \
92 if ((env->fsr & FSR_NVM) || TRAP) { \
94 env->fsr |= FSR_NVC; \
95 env->fsr |= FSR_FTT_IEEE_EXCP; \
96 raise_exception(TT_FP_EXCP); \
98 env->fsr |= FSR_NVA; \
101 case float_relation_less: \
102 T0 = FSR_FCC0 << FS; \
104 case float_relation_greater: \
105 T0 = FSR_FCC1 << FS; \
114 GEN_FCMP(fcmps
, float32
, FT0
, FT1
, 0, 0);
115 GEN_FCMP(fcmpd
, float64
, DT0
, DT1
, 0, 0);
117 GEN_FCMP(fcmpes
, float32
, FT0
, FT1
, 0, 1);
118 GEN_FCMP(fcmped
, float64
, DT0
, DT1
, 0, 1);
120 #ifdef TARGET_SPARC64
121 GEN_FCMP(fcmps_fcc1
, float32
, FT0
, FT1
, 22, 0);
122 GEN_FCMP(fcmpd_fcc1
, float64
, DT0
, DT1
, 22, 0);
124 GEN_FCMP(fcmps_fcc2
, float32
, FT0
, FT1
, 24, 0);
125 GEN_FCMP(fcmpd_fcc2
, float64
, DT0
, DT1
, 24, 0);
127 GEN_FCMP(fcmps_fcc3
, float32
, FT0
, FT1
, 26, 0);
128 GEN_FCMP(fcmpd_fcc3
, float64
, DT0
, DT1
, 26, 0);
130 GEN_FCMP(fcmpes_fcc1
, float32
, FT0
, FT1
, 22, 1);
131 GEN_FCMP(fcmped_fcc1
, float64
, DT0
, DT1
, 22, 1);
133 GEN_FCMP(fcmpes_fcc2
, float32
, FT0
, FT1
, 24, 1);
134 GEN_FCMP(fcmped_fcc2
, float64
, DT0
, DT1
, 24, 1);
136 GEN_FCMP(fcmpes_fcc3
, float32
, FT0
, FT1
, 26, 1);
137 GEN_FCMP(fcmped_fcc3
, float64
, DT0
, DT1
, 26, 1);
140 #if defined(CONFIG_USER_ONLY)
141 void helper_ld_asi(int asi
, int size
, int sign
)
145 void helper_st_asi(int asi
, int size
, int sign
)
149 #ifndef TARGET_SPARC64
150 void helper_ld_asi(int asi
, int size
, int sign
)
155 case 2: /* SuperSparc MXCC registers */
157 case 3: /* MMU probe */
161 mmulev
= (T0
>> 8) & 15;
165 ret
= mmu_probe(env
, T0
, mmulev
);
169 printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0
, mmulev
, ret
);
173 case 4: /* read MMU regs */
175 int reg
= (T0
>> 8) & 0xf;
177 ret
= env
->mmuregs
[reg
];
178 if (reg
== 3) /* Fault status cleared on read */
179 env
->mmuregs
[reg
] = 0;
181 printf("mmu_read: reg[%d] = 0x%08x\n", reg
, ret
);
185 case 9: /* Supervisor code access */
191 ret
= lduw_code(T0
& ~1);
195 ret
= ldl_code(T0
& ~3);
198 ret
= ldl_code(T0
& ~3);
199 T0
= ldl_code((T0
+ 4) & ~3);
203 case 0xc: /* I-cache tag */
204 case 0xd: /* I-cache data */
205 case 0xe: /* D-cache tag */
206 case 0xf: /* D-cache data */
208 case 0x20: /* MMU passthrough */
214 ret
= lduw_phys(T0
& ~1);
218 ret
= ldl_phys(T0
& ~3);
221 ret
= ldl_phys(T0
& ~3);
222 T0
= ldl_phys((T0
+ 4) & ~3);
226 case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
227 case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
230 ret
= ldub_phys((target_phys_addr_t
)T0
231 | ((target_phys_addr_t
)(asi
& 0xf) << 32));
234 ret
= lduw_phys((target_phys_addr_t
)(T0
& ~1)
235 | ((target_phys_addr_t
)(asi
& 0xf) << 32));
239 ret
= ldl_phys((target_phys_addr_t
)(T0
& ~3)
240 | ((target_phys_addr_t
)(asi
& 0xf) << 32));
243 ret
= ldl_phys((target_phys_addr_t
)(T0
& ~3)
244 | ((target_phys_addr_t
)(asi
& 0xf) << 32));
245 T0
= ldl_phys((target_phys_addr_t
)((T0
+ 4) & ~3)
246 | ((target_phys_addr_t
)(asi
& 0xf) << 32));
250 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
252 do_unassigned_access(T0
, 0, 0, 1);
259 void helper_st_asi(int asi
, int size
, int sign
)
262 case 2: /* SuperSparc MXCC registers */
264 case 3: /* MMU flush */
268 mmulev
= (T0
>> 8) & 15;
270 printf("mmu flush level %d\n", mmulev
);
273 case 0: // flush page
274 tlb_flush_page(env
, T0
& 0xfffff000);
276 case 1: // flush segment (256k)
277 case 2: // flush region (16M)
278 case 3: // flush context (4G)
279 case 4: // flush entire
290 case 4: /* write MMU regs */
292 int reg
= (T0
>> 8) & 0xf;
295 oldreg
= env
->mmuregs
[reg
];
298 env
->mmuregs
[reg
] &= ~(MMU_E
| MMU_NF
);
299 env
->mmuregs
[reg
] |= T1
& (MMU_E
| MMU_NF
);
300 // Mappings generated during no-fault mode or MMU
301 // disabled mode are invalid in normal mode
302 if (oldreg
!= env
->mmuregs
[reg
])
306 env
->mmuregs
[reg
] = T1
;
307 if (oldreg
!= env
->mmuregs
[reg
]) {
308 /* we flush when the MMU context changes because
309 QEMU has no MMU context support */
317 env
->mmuregs
[reg
] = T1
;
321 if (oldreg
!= env
->mmuregs
[reg
]) {
322 printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg
, oldreg
, env
->mmuregs
[reg
]);
328 case 0xc: /* I-cache tag */
329 case 0xd: /* I-cache data */
330 case 0xe: /* D-cache tag */
331 case 0xf: /* D-cache data */
332 case 0x10: /* I/D-cache flush page */
333 case 0x11: /* I/D-cache flush segment */
334 case 0x12: /* I/D-cache flush region */
335 case 0x13: /* I/D-cache flush context */
336 case 0x14: /* I/D-cache flush user */
338 case 0x17: /* Block copy, sta access */
341 // address (T0) = dst
344 uint32_t src
= T1
& ~3, dst
= T0
& ~3, temp
;
346 for (i
= 0; i
< 32; i
+= 4, src
+= 4, dst
+= 4) {
347 temp
= ldl_kernel(src
);
348 stl_kernel(dst
, temp
);
352 case 0x1f: /* Block fill, stda access */
355 // address (T0) = dst
358 uint32_t dst
= T0
& 7;
361 val
= (((uint64_t)T1
) << 32) | T2
;
363 for (i
= 0; i
< 32; i
+= 8, dst
+= 8)
364 stq_kernel(dst
, val
);
367 case 0x20: /* MMU passthrough */
374 stw_phys(T0
& ~1, T1
);
378 stl_phys(T0
& ~3, T1
);
381 stl_phys(T0
& ~3, T1
);
382 stl_phys((T0
+ 4) & ~3, T2
);
387 case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
388 case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
392 stb_phys((target_phys_addr_t
)T0
393 | ((target_phys_addr_t
)(asi
& 0xf) << 32), T1
);
396 stw_phys((target_phys_addr_t
)(T0
& ~1)
397 | ((target_phys_addr_t
)(asi
& 0xf) << 32), T1
);
401 stl_phys((target_phys_addr_t
)(T0
& ~3)
402 | ((target_phys_addr_t
)(asi
& 0xf) << 32), T1
);
405 stl_phys((target_phys_addr_t
)(T0
& ~3)
406 | ((target_phys_addr_t
)(asi
& 0xf) << 32), T1
);
407 stl_phys((target_phys_addr_t
)((T0
+ 4) & ~3)
408 | ((target_phys_addr_t
)(asi
& 0xf) << 32), T1
);
413 case 0x31: /* Ross RT620 I-cache flush */
414 case 0x36: /* I-cache flash clear */
415 case 0x37: /* D-cache flash clear */
417 case 9: /* Supervisor code access, XXX */
418 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
420 do_unassigned_access(T0
, 1, 0, 1);
427 void helper_ld_asi(int asi
, int size
, int sign
)
431 if (asi
< 0x80 && (env
->pstate
& PS_PRIV
) == 0)
432 raise_exception(TT_PRIV_ACT
);
436 case 0x15: // Bypass, non-cacheable
443 ret
= lduw_phys(T0
& ~1);
446 ret
= ldl_phys(T0
& ~3);
450 ret
= ldq_phys(T0
& ~7);
455 case 0x04: // Nucleus
456 case 0x0c: // Nucleus Little Endian (LE)
457 case 0x10: // As if user primary
458 case 0x11: // As if user secondary
459 case 0x18: // As if user primary LE
460 case 0x19: // As if user secondary LE
461 case 0x1c: // Bypass LE
462 case 0x1d: // Bypass, non-cacheable LE
463 case 0x24: // Nucleus quad LDD 128 bit atomic
464 case 0x2c: // Nucleus quad LDD 128 bit atomic
465 case 0x4a: // UPA config
466 case 0x82: // Primary no-fault
467 case 0x83: // Secondary no-fault
468 case 0x88: // Primary LE
469 case 0x89: // Secondary LE
470 case 0x8a: // Primary no-fault LE
471 case 0x8b: // Secondary no-fault LE
477 case 0x50: // I-MMU regs
479 int reg
= (T0
>> 3) & 0xf;
481 ret
= env
->immuregs
[reg
];
484 case 0x51: // I-MMU 8k TSB pointer
485 case 0x52: // I-MMU 64k TSB pointer
486 case 0x55: // I-MMU data access
489 case 0x56: // I-MMU tag read
493 for (i
= 0; i
< 64; i
++) {
494 // Valid, ctx match, vaddr match
495 if ((env
->itlb_tte
[i
] & 0x8000000000000000ULL
) != 0 &&
496 env
->itlb_tag
[i
] == T0
) {
497 ret
= env
->itlb_tag
[i
];
503 case 0x58: // D-MMU regs
505 int reg
= (T0
>> 3) & 0xf;
507 ret
= env
->dmmuregs
[reg
];
510 case 0x5e: // D-MMU tag read
514 for (i
= 0; i
< 64; i
++) {
515 // Valid, ctx match, vaddr match
516 if ((env
->dtlb_tte
[i
] & 0x8000000000000000ULL
) != 0 &&
517 env
->dtlb_tag
[i
] == T0
) {
518 ret
= env
->dtlb_tag
[i
];
524 case 0x59: // D-MMU 8k TSB pointer
525 case 0x5a: // D-MMU 64k TSB pointer
526 case 0x5b: // D-MMU data pointer
527 case 0x5d: // D-MMU data access
528 case 0x48: // Interrupt dispatch, RO
529 case 0x49: // Interrupt data receive
530 case 0x7f: // Incoming interrupt vector, RO
533 case 0x54: // I-MMU data in, WO
534 case 0x57: // I-MMU demap, WO
535 case 0x5c: // D-MMU data in, WO
536 case 0x5f: // D-MMU demap, WO
537 case 0x77: // Interrupt vector, WO
539 do_unassigned_access(T0
, 0, 0, 1);
546 void helper_st_asi(int asi
, int size
, int sign
)
548 if (asi
< 0x80 && (env
->pstate
& PS_PRIV
) == 0)
549 raise_exception(TT_PRIV_ACT
);
553 case 0x15: // Bypass, non-cacheable
560 stw_phys(T0
& ~1, T1
);
563 stl_phys(T0
& ~3, T1
);
567 stq_phys(T0
& ~7, T1
);
572 case 0x04: // Nucleus
573 case 0x0c: // Nucleus Little Endian (LE)
574 case 0x10: // As if user primary
575 case 0x11: // As if user secondary
576 case 0x18: // As if user primary LE
577 case 0x19: // As if user secondary LE
578 case 0x1c: // Bypass LE
579 case 0x1d: // Bypass, non-cacheable LE
580 case 0x24: // Nucleus quad LDD 128 bit atomic
581 case 0x2c: // Nucleus quad LDD 128 bit atomic
582 case 0x4a: // UPA config
583 case 0x88: // Primary LE
584 case 0x89: // Secondary LE
592 env
->lsu
= T1
& (DMMU_E
| IMMU_E
);
593 // Mappings generated during D/I MMU disabled mode are
594 // invalid in normal mode
595 if (oldreg
!= env
->lsu
) {
597 printf("LSU change: 0x%" PRIx64
" -> 0x%" PRIx64
"\n", oldreg
, env
->lsu
);
604 case 0x50: // I-MMU regs
606 int reg
= (T0
>> 3) & 0xf;
609 oldreg
= env
->immuregs
[reg
];
614 case 1: // Not in I-MMU
621 T1
= 0; // Clear SFSR
623 case 5: // TSB access
624 case 6: // Tag access
628 env
->immuregs
[reg
] = T1
;
630 if (oldreg
!= env
->immuregs
[reg
]) {
631 printf("mmu change reg[%d]: 0x%08" PRIx64
" -> 0x%08" PRIx64
"\n", reg
, oldreg
, env
->immuregs
[reg
]);
637 case 0x54: // I-MMU data in
641 // Try finding an invalid entry
642 for (i
= 0; i
< 64; i
++) {
643 if ((env
->itlb_tte
[i
] & 0x8000000000000000ULL
) == 0) {
644 env
->itlb_tag
[i
] = env
->immuregs
[6];
645 env
->itlb_tte
[i
] = T1
;
649 // Try finding an unlocked entry
650 for (i
= 0; i
< 64; i
++) {
651 if ((env
->itlb_tte
[i
] & 0x40) == 0) {
652 env
->itlb_tag
[i
] = env
->immuregs
[6];
653 env
->itlb_tte
[i
] = T1
;
660 case 0x55: // I-MMU data access
662 unsigned int i
= (T0
>> 3) & 0x3f;
664 env
->itlb_tag
[i
] = env
->immuregs
[6];
665 env
->itlb_tte
[i
] = T1
;
668 case 0x57: // I-MMU demap
671 case 0x58: // D-MMU regs
673 int reg
= (T0
>> 3) & 0xf;
676 oldreg
= env
->dmmuregs
[reg
];
683 T1
= 0; // Clear SFSR, Fault address
684 env
->dmmuregs
[4] = 0;
686 env
->dmmuregs
[reg
] = T1
;
688 case 1: // Primary context
689 case 2: // Secondary context
690 case 5: // TSB access
691 case 6: // Tag access
692 case 7: // Virtual Watchpoint
693 case 8: // Physical Watchpoint
697 env
->dmmuregs
[reg
] = T1
;
699 if (oldreg
!= env
->dmmuregs
[reg
]) {
700 printf("mmu change reg[%d]: 0x%08" PRIx64
" -> 0x%08" PRIx64
"\n", reg
, oldreg
, env
->dmmuregs
[reg
]);
706 case 0x5c: // D-MMU data in
710 // Try finding an invalid entry
711 for (i
= 0; i
< 64; i
++) {
712 if ((env
->dtlb_tte
[i
] & 0x8000000000000000ULL
) == 0) {
713 env
->dtlb_tag
[i
] = env
->dmmuregs
[6];
714 env
->dtlb_tte
[i
] = T1
;
718 // Try finding an unlocked entry
719 for (i
= 0; i
< 64; i
++) {
720 if ((env
->dtlb_tte
[i
] & 0x40) == 0) {
721 env
->dtlb_tag
[i
] = env
->dmmuregs
[6];
722 env
->dtlb_tte
[i
] = T1
;
729 case 0x5d: // D-MMU data access
731 unsigned int i
= (T0
>> 3) & 0x3f;
733 env
->dtlb_tag
[i
] = env
->dmmuregs
[6];
734 env
->dtlb_tte
[i
] = T1
;
737 case 0x5f: // D-MMU demap
738 case 0x49: // Interrupt data receive
741 case 0x51: // I-MMU 8k TSB pointer, RO
742 case 0x52: // I-MMU 64k TSB pointer, RO
743 case 0x56: // I-MMU tag read, RO
744 case 0x59: // D-MMU 8k TSB pointer, RO
745 case 0x5a: // D-MMU 64k TSB pointer, RO
746 case 0x5b: // D-MMU data pointer, RO
747 case 0x5e: // D-MMU tag read, RO
748 case 0x48: // Interrupt dispatch, RO
749 case 0x7f: // Incoming interrupt vector, RO
750 case 0x82: // Primary no-fault, RO
751 case 0x83: // Secondary no-fault, RO
752 case 0x8a: // Primary no-fault LE, RO
753 case 0x8b: // Secondary no-fault LE, RO
755 do_unassigned_access(T0
, 1, 0, 1);
760 #endif /* !CONFIG_USER_ONLY */
762 #ifndef TARGET_SPARC64
768 raise_exception(TT_ILL_INSN
);
771 cwp
= (env
->cwp
+ 1) & (NWINDOWS
- 1);
772 if (env
->wim
& (1 << cwp
)) {
773 raise_exception(TT_WIN_UNF
);
776 env
->psrs
= env
->psrps
;
780 void helper_ldfsr(void)
783 switch (env
->fsr
& FSR_RD_MASK
) {
785 rnd_mode
= float_round_nearest_even
;
789 rnd_mode
= float_round_to_zero
;
792 rnd_mode
= float_round_up
;
795 rnd_mode
= float_round_down
;
798 set_float_rounding_mode(rnd_mode
, &env
->fp_status
);
803 env
->exception_index
= EXCP_DEBUG
;
807 #ifndef TARGET_SPARC64
810 if ((T0
& PSR_CWP
) >= NWINDOWS
)
811 raise_exception(TT_ILL_INSN
);
825 T0
= (T1
& 0x5555555555555555ULL
) + ((T1
>> 1) & 0x5555555555555555ULL
);
826 T0
= (T0
& 0x3333333333333333ULL
) + ((T0
>> 2) & 0x3333333333333333ULL
);
827 T0
= (T0
& 0x0f0f0f0f0f0f0f0fULL
) + ((T0
>> 4) & 0x0f0f0f0f0f0f0f0fULL
);
828 T0
= (T0
& 0x00ff00ff00ff00ffULL
) + ((T0
>> 8) & 0x00ff00ff00ff00ffULL
);
829 T0
= (T0
& 0x0000ffff0000ffffULL
) + ((T0
>> 16) & 0x0000ffff0000ffffULL
);
830 T0
= (T0
& 0x00000000ffffffffULL
) + ((T0
>> 32) & 0x00000000ffffffffULL
);
833 static inline uint64_t *get_gregset(uint64_t pstate
)
850 uint64_t new_pstate
, pstate_regs
, new_pstate_regs
;
853 new_pstate
= T0
& 0xf3f;
854 pstate_regs
= env
->pstate
& 0xc01;
855 new_pstate_regs
= new_pstate
& 0xc01;
856 if (new_pstate_regs
!= pstate_regs
) {
857 // Switch global register bank
858 src
= get_gregset(new_pstate_regs
);
859 dst
= get_gregset(pstate_regs
);
860 memcpy32(dst
, env
->gregs
);
861 memcpy32(env
->gregs
, src
);
863 env
->pstate
= new_pstate
;
869 env
->pc
= env
->tnpc
[env
->tl
];
870 env
->npc
= env
->tnpc
[env
->tl
] + 4;
871 PUT_CCR(env
, env
->tstate
[env
->tl
] >> 32);
872 env
->asi
= (env
->tstate
[env
->tl
] >> 24) & 0xff;
873 env
->pstate
= (env
->tstate
[env
->tl
] >> 8) & 0xfff;
874 set_cwp(env
->tstate
[env
->tl
] & 0xff);
880 env
->pc
= env
->tpc
[env
->tl
];
881 env
->npc
= env
->tnpc
[env
->tl
];
882 PUT_CCR(env
, env
->tstate
[env
->tl
] >> 32);
883 env
->asi
= (env
->tstate
[env
->tl
] >> 24) & 0xff;
884 env
->pstate
= (env
->tstate
[env
->tl
] >> 8) & 0xfff;
885 set_cwp(env
->tstate
[env
->tl
] & 0xff);
889 void set_cwp(int new_cwp
)
891 /* put the modified wrap registers at their proper location */
892 if (env
->cwp
== (NWINDOWS
- 1))
893 memcpy32(env
->regbase
, env
->regbase
+ NWINDOWS
* 16);
895 /* put the wrap registers at their temporary location */
896 if (new_cwp
== (NWINDOWS
- 1))
897 memcpy32(env
->regbase
+ NWINDOWS
* 16, env
->regbase
);
898 env
->regwptr
= env
->regbase
+ (new_cwp
* 16);
899 REGWPTR
= env
->regwptr
;
902 void cpu_set_cwp(CPUState
*env1
, int new_cwp
)
906 target_ulong
*saved_regwptr
;
911 saved_regwptr
= REGWPTR
;
917 REGWPTR
= saved_regwptr
;
921 #ifdef TARGET_SPARC64
922 void do_interrupt(int intno
)
925 if (loglevel
& CPU_LOG_INT
) {
927 fprintf(logfile
, "%6d: v=%04x pc=%016" PRIx64
" npc=%016" PRIx64
" SP=%016" PRIx64
"\n",
930 env
->npc
, env
->regwptr
[6]);
931 cpu_dump_state(env
, logfile
, fprintf
, 0);
937 fprintf(logfile
, " code=");
938 ptr
= (uint8_t *)env
->pc
;
939 for(i
= 0; i
< 16; i
++) {
940 fprintf(logfile
, " %02x", ldub(ptr
+ i
));
942 fprintf(logfile
, "\n");
948 #if !defined(CONFIG_USER_ONLY)
949 if (env
->tl
== MAXTL
) {
950 cpu_abort(env
, "Trap 0x%04x while trap level is MAXTL, Error state", env
->exception_index
);
954 env
->tstate
[env
->tl
] = ((uint64_t)GET_CCR(env
) << 32) | ((env
->asi
& 0xff) << 24) |
955 ((env
->pstate
& 0xfff) << 8) | (env
->cwp
& 0xff);
956 env
->tpc
[env
->tl
] = env
->pc
;
957 env
->tnpc
[env
->tl
] = env
->npc
;
958 env
->tt
[env
->tl
] = intno
;
959 env
->pstate
= PS_PEF
| PS_PRIV
| PS_AG
;
960 env
->tbr
&= ~0x7fffULL
;
961 env
->tbr
|= ((env
->tl
> 1) ? 1 << 14 : 0) | (intno
<< 5);
962 if (env
->tl
< MAXTL
- 1) {
965 env
->pstate
|= PS_RED
;
966 if (env
->tl
!= MAXTL
)
970 env
->npc
= env
->pc
+ 4;
971 env
->exception_index
= 0;
974 void do_interrupt(int intno
)
979 if (loglevel
& CPU_LOG_INT
) {
981 fprintf(logfile
, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
984 env
->npc
, env
->regwptr
[6]);
985 cpu_dump_state(env
, logfile
, fprintf
, 0);
991 fprintf(logfile
, " code=");
992 ptr
= (uint8_t *)env
->pc
;
993 for(i
= 0; i
< 16; i
++) {
994 fprintf(logfile
, " %02x", ldub(ptr
+ i
));
996 fprintf(logfile
, "\n");
1002 #if !defined(CONFIG_USER_ONLY)
1003 if (env
->psret
== 0) {
1004 cpu_abort(env
, "Trap 0x%02x while interrupts disabled, Error state", env
->exception_index
);
1009 cwp
= (env
->cwp
- 1) & (NWINDOWS
- 1);
1011 env
->regwptr
[9] = env
->pc
;
1012 env
->regwptr
[10] = env
->npc
;
1013 env
->psrps
= env
->psrs
;
1015 env
->tbr
= (env
->tbr
& TBR_BASE_MASK
) | (intno
<< 4);
1017 env
->npc
= env
->pc
+ 4;
1018 env
->exception_index
= 0;
1022 #if !defined(CONFIG_USER_ONLY)
1024 static void do_unaligned_access(target_ulong addr
, int is_write
, int is_user
,
1027 #define MMUSUFFIX _mmu
1028 #define ALIGNED_ONLY
1029 #define GETPC() (__builtin_return_address(0))
1032 #include "softmmu_template.h"
1035 #include "softmmu_template.h"
1038 #include "softmmu_template.h"
1041 #include "softmmu_template.h"
1043 static void do_unaligned_access(target_ulong addr
, int is_write
, int is_user
,
1046 #ifdef DEBUG_UNALIGNED
1047 printf("Unaligned access to 0x%x from 0x%x\n", addr
, env
->pc
);
1049 raise_exception(TT_UNALIGNED
);
1052 /* try to fill the TLB and return an exception if error. If retaddr is
1053 NULL, it means that the function was called in C code (i.e. not
1054 from generated code or from helper.c) */
1055 /* XXX: fix it to restore all registers */
1056 void tlb_fill(target_ulong addr
, int is_write
, int is_user
, void *retaddr
)
1058 TranslationBlock
*tb
;
1061 CPUState
*saved_env
;
1063 /* XXX: hack to restore env in all cases, even if not called from
1066 env
= cpu_single_env
;
1068 ret
= cpu_sparc_handle_mmu_fault(env
, addr
, is_write
, is_user
, 1);
1071 /* now we have a real cpu fault */
1072 pc
= (unsigned long)retaddr
;
1073 tb
= tb_find_pc(pc
);
1075 /* the PC is inside the translated code. It means that we have
1076 a virtual CPU fault */
1077 cpu_restore_state(tb
, env
, pc
, (void *)T2
);
1087 #ifndef TARGET_SPARC64
1088 void do_unassigned_access(target_phys_addr_t addr
, int is_write
, int is_exec
,
1091 CPUState
*saved_env
;
1093 /* XXX: hack to restore env in all cases, even if not called from
1096 env
= cpu_single_env
;
1097 if (env
->mmuregs
[3]) /* Fault status register */
1098 env
->mmuregs
[3] = 1; /* overflow (not read before another fault) */
1100 env
->mmuregs
[3] |= 1 << 16;
1102 env
->mmuregs
[3] |= 1 << 5;
1104 env
->mmuregs
[3] |= 1 << 6;
1106 env
->mmuregs
[3] |= 1 << 7;
1107 env
->mmuregs
[3] |= (5 << 2) | 2;
1108 env
->mmuregs
[4] = addr
; /* Fault address register */
1109 if ((env
->mmuregs
[0] & MMU_E
) && !(env
->mmuregs
[0] & MMU_NF
)) {
1110 #ifdef DEBUG_UNASSIGNED
1111 printf("Unassigned mem access to " TARGET_FMT_plx
" from " TARGET_FMT_lx
1112 "\n", addr
, env
->pc
);
1114 raise_exception(TT_DATA_ACCESS
);
1119 void do_unassigned_access(target_phys_addr_t addr
, int is_write
, int is_exec
,
1122 #ifdef DEBUG_UNASSIGNED
1123 CPUState
*saved_env
;
1125 /* XXX: hack to restore env in all cases, even if not called from
1128 env
= cpu_single_env
;
1129 printf("Unassigned mem access to " TARGET_FMT_plx
" from " TARGET_FMT_lx
"\n",
1133 raise_exception(TT_DATA_ACCESS
);
1137 #ifdef TARGET_SPARC64
1138 void do_tick_set_count(void *opaque
, uint64_t count
)
1140 ptimer_set_count(opaque
, -count
);
1143 uint64_t do_tick_get_count(void *opaque
)
1145 return -ptimer_get_count(opaque
);
1148 void do_tick_set_limit(void *opaque
, uint64_t limit
)
1150 ptimer_set_limit(opaque
, -limit
, 0);