5 void raise_exception(int tt)
7 env->exception_index = tt;
11 #ifdef USE_INT_TO_FLOAT_HELPERS
14 FT0 = (float) *((int32_t *)&FT1);
19 DT0 = (double) *((int32_t *)&FT1);
25 FT0 = float32_abs(FT1);
31 DT0 = float64_abs(DT1);
37 FT0 = float32_sqrt(FT1, &env->fp_status);
42 DT0 = float64_sqrt(DT1, &env->fp_status);
48 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
49 if (isnan(FT0) || isnan(FT1)) {
50 T0 = (FSR_FCC1 | FSR_FCC0) << FS;
51 if (env->fsr & FSR_NVM) {
53 raise_exception(TT_FP_EXCP);
57 } else if (FT0 < FT1) {
59 } else if (FT0 > FT1) {
69 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
70 if (isnan(DT0) || isnan(DT1)) {
71 T0 = (FSR_FCC1 | FSR_FCC0) << FS;
72 if (env->fsr & FSR_NVM) {
74 raise_exception(TT_FP_EXCP);
78 } else if (DT0 < DT1) {
80 } else if (DT0 > DT1) {
91 void do_fcmps_fcc1 (void)
93 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
94 if (isnan(FT0) || isnan(FT1)) {
95 T0 = (FSR_FCC1 | FSR_FCC0) << FS;
96 if (env->fsr & FSR_NVM) {
98 raise_exception(TT_FP_EXCP);
102 } else if (FT0 < FT1) {
104 } else if (FT0 > FT1) {
112 void do_fcmpd_fcc1 (void)
114 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
115 if (isnan(DT0) || isnan(DT1)) {
116 T0 = (FSR_FCC1 | FSR_FCC0) << FS;
117 if (env->fsr & FSR_NVM) {
119 raise_exception(TT_FP_EXCP);
123 } else if (DT0 < DT1) {
125 } else if (DT0 > DT1) {
135 void do_fcmps_fcc2 (void)
137 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
138 if (isnan(FT0) || isnan(FT1)) {
139 T0 = (FSR_FCC1 | FSR_FCC0) << FS;
140 if (env->fsr & FSR_NVM) {
142 raise_exception(TT_FP_EXCP);
146 } else if (FT0 < FT1) {
148 } else if (FT0 > FT1) {
156 void do_fcmpd_fcc2 (void)
158 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
159 if (isnan(DT0) || isnan(DT1)) {
160 T0 = (FSR_FCC1 | FSR_FCC0) << FS;
161 if (env->fsr & FSR_NVM) {
163 raise_exception(TT_FP_EXCP);
167 } else if (DT0 < DT1) {
169 } else if (DT0 > DT1) {
179 void do_fcmps_fcc3 (void)
181 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
182 if (isnan(FT0) || isnan(FT1)) {
183 T0 = (FSR_FCC1 | FSR_FCC0) << FS;
184 if (env->fsr & FSR_NVM) {
186 raise_exception(TT_FP_EXCP);
190 } else if (FT0 < FT1) {
192 } else if (FT0 > FT1) {
200 void do_fcmpd_fcc3 (void)
202 env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
203 if (isnan(DT0) || isnan(DT1)) {
204 T0 = (FSR_FCC1 | FSR_FCC0) << FS;
205 if (env->fsr & FSR_NVM) {
207 raise_exception(TT_FP_EXCP);
211 } else if (DT0 < DT1) {
213 } else if (DT0 > DT1) {
223 #ifndef TARGET_SPARC64
224 void helper_ld_asi(int asi, int size, int sign)
229 case 3: /* MMU probe */
233 mmulev = (T0 >> 8) & 15;
237 ret = mmu_probe(env, T0, mmulev);
241 printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
245 case 4: /* read MMU regs */
247 int reg = (T0 >> 8) & 0xf;
249 ret = env->mmuregs[reg];
250 if (reg == 3) /* Fault status cleared on read */
251 env->mmuregs[reg] = 0;
253 printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
257 case 0x20 ... 0x2f: /* MMU passthrough */
258 cpu_physical_memory_read(T0, (void *) &ret, size);
262 tswap16s((uint16_t *)&ret);
271 void helper_st_asi(int asi, int size, int sign)
274 case 3: /* MMU flush */
278 mmulev = (T0 >> 8) & 15;
280 printf("mmu flush level %d\n", mmulev);
283 case 0: // flush page
284 tlb_flush_page(env, T0 & 0xfffff000);
286 case 1: // flush segment (256k)
287 case 2: // flush region (16M)
288 case 3: // flush context (4G)
289 case 4: // flush entire
300 case 4: /* write MMU regs */
302 int reg = (T0 >> 8) & 0xf, oldreg;
304 oldreg = env->mmuregs[reg];
307 env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
308 env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
309 // Mappings generated during no-fault mode or MMU
310 // disabled mode are invalid in normal mode
311 if (oldreg != env->mmuregs[reg])
315 env->mmuregs[reg] = T1;
316 if (oldreg != env->mmuregs[reg]) {
317 /* we flush when the MMU context changes because
318 QEMU has no MMU context support */
326 env->mmuregs[reg] = T1;
330 if (oldreg != env->mmuregs[reg]) {
331 printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
337 case 0x17: /* Block copy, sta access */
340 // address (T0) = dst
342 int src = T1, dst = T0;
347 cpu_physical_memory_read(src, (void *) &temp, 32);
348 cpu_physical_memory_write(dst, (void *) &temp, 32);
351 case 0x1f: /* Block fill, stda access */
354 // address (T0) = dst
359 val = (((uint64_t)T1) << 32) | T2;
362 for (i = 0; i < 32; i += 8, dst += 8) {
363 cpu_physical_memory_write(dst, (void *) &val, 8);
367 case 0x20 ... 0x2f: /* MMU passthrough */
373 tswap16s((uint16_t *)&temp);
374 cpu_physical_memory_write(T0, (void *) &temp, size);
384 void helper_ld_asi(int asi, int size, int sign)
388 if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
389 raise_exception(TT_PRIV_INSN);
393 case 0x15: // Bypass, non-cacheable
395 cpu_physical_memory_read(T0, (void *) &ret, size);
399 tswap32s((uint32_t *)&ret);
401 tswap16s((uint16_t *)&ret);
404 case 0x1c: // Bypass LE
405 case 0x1d: // Bypass, non-cacheable LE
411 case 0x50: // I-MMU regs
413 int reg = (T0 >> 3) & 0xf;
415 ret = env->immuregs[reg];
418 case 0x51: // I-MMU 8k TSB pointer
419 case 0x52: // I-MMU 64k TSB pointer
420 case 0x55: // I-MMU data access
421 case 0x56: // I-MMU tag read
423 case 0x58: // D-MMU regs
425 int reg = (T0 >> 3) & 0xf;
427 ret = env->dmmuregs[reg];
430 case 0x59: // D-MMU 8k TSB pointer
431 case 0x5a: // D-MMU 64k TSB pointer
432 case 0x5b: // D-MMU data pointer
433 case 0x5d: // D-MMU data access
434 case 0x5e: // D-MMU tag read
436 case 0x54: // I-MMU data in, WO
437 case 0x57: // I-MMU demap, WO
438 case 0x5c: // D-MMU data in, WO
439 case 0x5f: // D-MMU demap, WO
447 void helper_st_asi(int asi, int size, int sign)
449 if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
450 raise_exception(TT_PRIV_INSN);
454 case 0x15: // Bypass, non-cacheable
456 target_ulong temp = T1;
460 tswap32s((uint32_t *)&temp);
462 tswap16s((uint16_t *)&temp);
463 cpu_physical_memory_write(T0, (void *) &temp, size);
466 case 0x1c: // Bypass LE
467 case 0x1d: // Bypass, non-cacheable LE
475 env->lsu = T1 & (DMMU_E | IMMU_E);
476 // Mappings generated during D/I MMU disabled mode are
477 // invalid in normal mode
478 if (oldreg != env->lsu)
482 case 0x50: // I-MMU regs
484 int reg = (T0 >> 3) & 0xf;
487 oldreg = env->immuregs[reg];
492 case 1: // Not in I-MMU
499 T1 = 0; // Clear SFSR
501 case 5: // TSB access
502 case 6: // Tag access
506 env->immuregs[reg] = T1;
508 if (oldreg != env->immuregs[reg]) {
509 printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->immuregs[reg]);
515 case 0x54: // I-MMU data in
519 // Try finding an invalid entry
520 for (i = 0; i < 64; i++) {
521 if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
522 env->itlb_tag[i] = env->immuregs[6];
523 env->itlb_tte[i] = T1;
527 // Try finding an unlocked entry
528 for (i = 0; i < 64; i++) {
529 if ((env->itlb_tte[i] & 0x40) == 0) {
530 env->itlb_tag[i] = env->immuregs[6];
531 env->itlb_tte[i] = T1;
538 case 0x55: // I-MMU data access
540 unsigned int i = (T0 >> 3) & 0x3f;
542 env->itlb_tag[i] = env->immuregs[6];
543 env->itlb_tte[i] = T1;
546 case 0x57: // I-MMU demap
548 case 0x58: // D-MMU regs
550 int reg = (T0 >> 3) & 0xf;
553 oldreg = env->dmmuregs[reg];
560 T1 = 0; // Clear SFSR, Fault address
561 env->dmmuregs[4] = 0;
563 env->dmmuregs[reg] = T1;
565 case 1: // Primary context
566 case 2: // Secondary context
567 case 5: // TSB access
568 case 6: // Tag access
569 case 7: // Virtual Watchpoint
570 case 8: // Physical Watchpoint
574 env->dmmuregs[reg] = T1;
576 if (oldreg != env->dmmuregs[reg]) {
577 printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->dmmuregs[reg]);
583 case 0x5c: // D-MMU data in
587 // Try finding an invalid entry
588 for (i = 0; i < 64; i++) {
589 if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
590 env->dtlb_tag[i] = env->dmmuregs[6];
591 env->dtlb_tte[i] = T1;
595 // Try finding an unlocked entry
596 for (i = 0; i < 64; i++) {
597 if ((env->dtlb_tte[i] & 0x40) == 0) {
598 env->dtlb_tag[i] = env->dmmuregs[6];
599 env->dtlb_tte[i] = T1;
606 case 0x5d: // D-MMU data access
608 unsigned int i = (T0 >> 3) & 0x3f;
610 env->dtlb_tag[i] = env->dmmuregs[6];
611 env->dtlb_tte[i] = T1;
614 case 0x5f: // D-MMU demap
616 case 0x51: // I-MMU 8k TSB pointer, RO
617 case 0x52: // I-MMU 64k TSB pointer, RO
618 case 0x56: // I-MMU tag read, RO
619 case 0x59: // D-MMU 8k TSB pointer, RO
620 case 0x5a: // D-MMU 64k TSB pointer, RO
621 case 0x5b: // D-MMU data pointer, RO
622 case 0x5e: // D-MMU tag read, RO
630 #ifndef TARGET_SPARC64
636 cwp = (env->cwp + 1) & (NWINDOWS - 1);
637 if (env->wim & (1 << cwp)) {
638 raise_exception(TT_WIN_UNF);
641 env->psrs = env->psrps;
645 void helper_ldfsr(void)
648 switch (env->fsr & FSR_RD_MASK) {
650 rnd_mode = float_round_nearest_even;
654 rnd_mode = float_round_to_zero;
657 rnd_mode = float_round_up;
660 rnd_mode = float_round_down;
663 set_float_rounding_mode(rnd_mode, &env->fp_status);
666 void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f)
670 *pmant = ldexp(frexp(f, &exptemp), 53);
674 double cpu_put_fp64(uint64_t mant, uint16_t exp)
676 return ldexp((double) mant, exp - 53);
681 env->exception_index = EXCP_DEBUG;
685 #ifndef TARGET_SPARC64
700 T0 = (T1 & 0x5555555555555555ULL) + ((T1 >> 1) & 0x5555555555555555ULL);
701 T0 = (T0 & 0x3333333333333333ULL) + ((T0 >> 2) & 0x3333333333333333ULL);
702 T0 = (T0 & 0x0f0f0f0f0f0f0f0fULL) + ((T0 >> 4) & 0x0f0f0f0f0f0f0f0fULL);
703 T0 = (T0 & 0x00ff00ff00ff00ffULL) + ((T0 >> 8) & 0x00ff00ff00ff00ffULL);
704 T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL);
705 T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL);
709 void set_cwp(int new_cwp)
711 /* put the modified wrap registers at their proper location */
712 if (env->cwp == (NWINDOWS - 1))
713 memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
715 /* put the wrap registers at their temporary location */
716 if (new_cwp == (NWINDOWS - 1))
717 memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
718 env->regwptr = env->regbase + (new_cwp * 16);
719 REGWPTR = env->regwptr;
722 void cpu_set_cwp(CPUState *env1, int new_cwp)
726 target_ulong *saved_regwptr;
731 saved_regwptr = REGWPTR;
737 REGWPTR = saved_regwptr;
741 #ifdef TARGET_SPARC64
742 void do_interrupt(int intno)
745 if (loglevel & CPU_LOG_INT) {
747 fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
750 env->npc, env->regwptr[6]);
751 cpu_dump_state(env, logfile, fprintf, 0);
757 fprintf(logfile, " code=");
758 ptr = (uint8_t *)env->pc;
759 for(i = 0; i < 16; i++) {
760 fprintf(logfile, " %02x", ldub(ptr + i));
762 fprintf(logfile, "\n");
768 #if !defined(CONFIG_USER_ONLY)
769 if (env->pstate & PS_IE) {
770 cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
774 env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
775 ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
776 env->tpc[env->tl] = env->pc;
777 env->tnpc[env->tl] = env->npc;
778 env->tt[env->tl] = intno;
779 env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4);
782 env->npc = env->pc + 4;
783 env->exception_index = 0;
786 void do_interrupt(int intno)
791 if (loglevel & CPU_LOG_INT) {
793 fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
796 env->npc, env->regwptr[6]);
797 cpu_dump_state(env, logfile, fprintf, 0);
803 fprintf(logfile, " code=");
804 ptr = (uint8_t *)env->pc;
805 for(i = 0; i < 16; i++) {
806 fprintf(logfile, " %02x", ldub(ptr + i));
808 fprintf(logfile, "\n");
814 #if !defined(CONFIG_USER_ONLY)
815 if (env->psret == 0) {
816 cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
821 cwp = (env->cwp - 1) & (NWINDOWS - 1);
823 env->regwptr[9] = env->pc;
824 env->regwptr[10] = env->npc;
825 env->psrps = env->psrs;
827 env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
829 env->npc = env->pc + 4;
830 env->exception_index = 0;
834 #if !defined(CONFIG_USER_ONLY)
836 #define MMUSUFFIX _mmu
837 #define GETPC() (__builtin_return_address(0))
840 #include "softmmu_template.h"
843 #include "softmmu_template.h"
846 #include "softmmu_template.h"
849 #include "softmmu_template.h"
852 /* try to fill the TLB and return an exception if error. If retaddr is
853 NULL, it means that the function was called in C code (i.e. not
854 from generated code or from helper.c) */
855 /* XXX: fix it to restore all registers */
856 void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
858 TranslationBlock *tb;
863 /* XXX: hack to restore env in all cases, even if not called from
866 env = cpu_single_env;
868 ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
871 /* now we have a real cpu fault */
872 pc = (unsigned long)retaddr;
875 /* the PC is inside the translated code. It means that we have
876 a virtual CPU fault */
877 cpu_restore_state(tb, env, pc, (void *)T2);