diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 0de7adef..ed727f60 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -4366,6 +4366,7 @@ sparc_symbols = ( 'cpu_get_psr', 'cpu_put_psr', 'cpu_put_psr_raw', + 'cpu_raise_exception_ra', 'cpu_set_cwp', 'cpu_sparc_exec', 'cpu_sparc_init', diff --git a/qemu/sparc.h b/qemu/sparc.h index 193f6257..2f55d01d 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -3352,6 +3352,7 @@ #define cpu_get_psr cpu_get_psr_sparc #define cpu_put_psr cpu_put_psr_sparc #define cpu_put_psr_raw cpu_put_psr_raw_sparc +#define cpu_raise_exception_ra cpu_raise_exception_ra_sparc #define cpu_set_cwp cpu_set_cwp_sparc #define cpu_sparc_exec cpu_sparc_exec_sparc #define cpu_sparc_init cpu_sparc_init_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 0eb55bae..b8c05a31 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -3352,6 +3352,7 @@ #define cpu_get_psr cpu_get_psr_sparc64 #define cpu_put_psr cpu_put_psr_sparc64 #define cpu_put_psr_raw cpu_put_psr_raw_sparc64 +#define cpu_raise_exception_ra cpu_raise_exception_ra_sparc64 #define cpu_set_cwp cpu_set_cwp_sparc64 #define cpu_sparc_exec cpu_sparc_exec_sparc64 #define cpu_sparc_init cpu_sparc_init_sparc64 diff --git a/qemu/target-sparc/cpu.h b/qemu/target-sparc/cpu.h index f912c725..1c1a9297 100644 --- a/qemu/target-sparc/cpu.h +++ b/qemu/target-sparc/cpu.h @@ -540,6 +540,7 @@ void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); +void cpu_raise_exception_ra(CPUSPARCState *, int, uintptr_t) QEMU_NORETURN; #ifndef NO_CPU_IO_DEFS /* cpu_init.c */ diff --git a/qemu/target-sparc/helper.c b/qemu/target-sparc/helper.c index 17b18c21..c1642d44 100644 --- a/qemu/target-sparc/helper.c +++ b/qemu/target-sparc/helper.c @@ -24,6 +24,14 @@ #include "exec/helper-proto.h" #include "sysemu/sysemu.h" +void cpu_raise_exception_ra(CPUSPARCState *env, int tt, uintptr_t ra) +{ + CPUState *cs = CPU(sparc_env_get_cpu(env)); + + cs->exception_index = tt; + cpu_loop_exit_restore(cs, ra); +} + void helper_raise_exception(CPUSPARCState *env, int tt) { CPUState *cs = CPU(sparc_env_get_cpu(env)); @@ -61,7 +69,7 @@ uint64_t helper_tick_get_count(CPUSPARCState *env, void *opaque, int mem_idx) CPUTimer *timer = opaque; if (timer->npt && mem_idx < MMU_KERNEL_IDX) { - helper_raise_exception(env, TT_PRIV_INSN); + cpu_raise_exception_ra(env, TT_PRIV_INSN, GETPC()); } return cpu_tick_get_count(timer);*/ @@ -79,10 +87,9 @@ void helper_tick_set_limit(void *opaque, uint64_t limit) } #endif -static target_ulong helper_udiv_common(CPUSPARCState *env, target_ulong a, - target_ulong b, int cc) +static target_ulong do_udiv(CPUSPARCState *env, target_ulong a, + target_ulong b, int cc, uintptr_t ra) { - SPARCCPU *cpu = sparc_env_get_cpu(env); int overflow = 0; uint64_t x0; uint32_t x1; @@ -91,8 +98,7 @@ static target_ulong helper_udiv_common(CPUSPARCState *env, target_ulong a, x1 = (b & 0xffffffff); if (x1 == 0) { - cpu_restore_state(CPU(cpu), GETPC()); - helper_raise_exception(env, TT_DIV_ZERO); + cpu_raise_exception_ra(env, TT_DIV_ZERO, ra); } x0 = x0 / x1; @@ -111,18 +117,17 @@ static target_ulong helper_udiv_common(CPUSPARCState *env, target_ulong a, target_ulong helper_udiv(CPUSPARCState *env, target_ulong a, target_ulong b) { - return helper_udiv_common(env, a, b, 0); + return do_udiv(env, a, b, 0, GETPC()); } target_ulong helper_udiv_cc(CPUSPARCState *env, target_ulong a, target_ulong b) { - return helper_udiv_common(env, a, b, 1); + return do_udiv(env, a, b, 1, GETPC()); } -static target_ulong helper_sdiv_common(CPUSPARCState *env, target_ulong a, - target_ulong b, int cc) +static target_ulong do_sdiv(CPUSPARCState *env, target_ulong a, + target_ulong b, int cc, uintptr_t ra) { - SPARCCPU *cpu = sparc_env_get_cpu(env); int overflow = 0; int64_t x0; int32_t x1; @@ -131,8 +136,7 @@ static target_ulong helper_sdiv_common(CPUSPARCState *env, target_ulong a, x1 = (b & 0xffffffff); if (x1 == 0) { - cpu_restore_state(CPU(cpu), GETPC()); - helper_raise_exception(env, TT_DIV_ZERO); + cpu_raise_exception_ra(env, TT_DIV_ZERO, ra); } else if (x1 == -1 && x0 == INT64_MIN) { x0 = INT32_MAX; overflow = 1; @@ -154,12 +158,12 @@ static target_ulong helper_sdiv_common(CPUSPARCState *env, target_ulong a, target_ulong helper_sdiv(CPUSPARCState *env, target_ulong a, target_ulong b) { - return helper_sdiv_common(env, a, b, 0); + return do_sdiv(env, a, b, 0, GETPC()); } target_ulong helper_sdiv_cc(CPUSPARCState *env, target_ulong a, target_ulong b) { - return helper_sdiv_common(env, a, b, 1); + return do_sdiv(env, a, b, 1, GETPC()); } #ifdef TARGET_SPARC64 @@ -167,10 +171,7 @@ int64_t helper_sdivx(CPUSPARCState *env, int64_t a, int64_t b) { if (b == 0) { /* Raise divide by zero trap. */ - SPARCCPU *cpu = sparc_env_get_cpu(env); - - cpu_restore_state(CPU(cpu), GETPC()); - helper_raise_exception(env, TT_DIV_ZERO); + cpu_raise_exception_ra(env, TT_DIV_ZERO, GETPC()); } else if (b == -1) { /* Avoid overflow trap with i386 divide insn. */ return -a; @@ -183,10 +184,7 @@ uint64_t helper_udivx(CPUSPARCState *env, uint64_t a, uint64_t b) { if (b == 0) { /* Raise divide by zero trap. */ - SPARCCPU *cpu = sparc_env_get_cpu(env); - - cpu_restore_state(CPU(cpu), GETPC()); - helper_raise_exception(env, TT_DIV_ZERO); + cpu_raise_exception_ra(env, TT_DIV_ZERO, GETPC()); } return a / b; } @@ -195,7 +193,6 @@ uint64_t helper_udivx(CPUSPARCState *env, uint64_t a, uint64_t b) target_ulong helper_taddcctv(CPUSPARCState *env, target_ulong src1, target_ulong src2) { - SPARCCPU *cpu = sparc_env_get_cpu(env); target_ulong dst; /* Tag overflow occurs if either input has bits 0 or 1 set. */ @@ -218,14 +215,12 @@ target_ulong helper_taddcctv(CPUSPARCState *env, target_ulong src1, return dst; tag_overflow: - cpu_restore_state(CPU(cpu), GETPC()); - helper_raise_exception(env, TT_TOVF); + cpu_raise_exception_ra(env, TT_TOVF, GETPC()); } target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1, target_ulong src2) { - SPARCCPU *cpu = sparc_env_get_cpu(env); target_ulong dst; /* Tag overflow occurs if either input has bits 0 or 1 set. */ @@ -248,8 +243,7 @@ target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1, return dst; tag_overflow: - cpu_restore_state(CPU(cpu), GETPC()); - helper_raise_exception(env, TT_TOVF); + cpu_raise_exception_ra(env, TT_TOVF, GETPC()); } //#ifndef TARGET_SPARC64 diff --git a/qemu/target-sparc/ldst_helper.c b/qemu/target-sparc/ldst_helper.c index b11efb8e..e86e628c 100644 --- a/qemu/target-sparc/ldst_helper.c +++ b/qemu/target-sparc/ldst_helper.c @@ -254,17 +254,23 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb, #endif -void helper_check_align(CPUSPARCState *env, target_ulong addr, uint32_t align) +static void do_check_align(CPUSPARCState *env, target_ulong addr, + uint32_t align, uintptr_t ra) { if (addr & align) { #ifdef DEBUG_UNALIGNED printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx "\n", addr, env->pc); #endif - helper_raise_exception(env, TT_UNALIGNED); + cpu_raise_exception_ra(env, TT_UNALIGNED, ra); } } +void helper_check_align(CPUSPARCState *env, target_ulong addr, uint32_t align) +{ + do_check_align(env, addr, align, GETPC()); +} + #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \ defined(DEBUG_MXCC) static void dump_mxcc(CPUSPARCState *env) @@ -393,7 +399,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, uint32_t last_addr = addr; #endif - helper_check_align(env, addr, size - 1); + do_check_align(env, addr, size - 1, GETPC()); switch (asi) { case ASI_M_MXCC: /* SuperSparc MXCC registers, or... */ /* case ASI_LEON_CACHEREGS: Leon3 cache control */ @@ -663,7 +669,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, SPARCCPU *cpu = sparc_env_get_cpu(env); CPUState *cs = CPU(cpu); - helper_check_align(env, addr, size - 1); + do_check_align(env, addr, size - 1, GETPC()); switch (asi) { case ASI_M_MXCC: /* SuperSparc MXCC registers, or... */ /* case ASI_LEON_CACHEREGS: Leon3 cache control */ @@ -1117,10 +1123,10 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, #endif if (asi < 0x80) { - helper_raise_exception(env, TT_PRIV_ACT); + cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC()); } - helper_check_align(env, addr, size - 1); + do_check_align(env, addr, size - 1, GETPC()); addr = asi_address_mask(env, asi, addr); switch (asi) { @@ -1223,10 +1229,9 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, dump_asi("write", addr, asi, size, val); #endif if (asi < 0x80) { - helper_raise_exception(env, TT_PRIV_ACT); + cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC()); } - - helper_check_align(env, addr, size - 1); + do_check_align(env, addr, size - 1, GETPC()); addr = asi_address_mask(env, asi, addr); /* Convert to little endian */ @@ -1281,7 +1286,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, case ASI_PNFL: /* Primary no-fault LE, RO */ case ASI_SNFL: /* Secondary no-fault LE, RO */ default: - helper_raise_exception(env, TT_DATA_ACCESS); + cpu_raise_exception_ra(env, TT_DATA_ACCESS, GETPC()); return; } } @@ -1305,10 +1310,10 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, || (cpu_has_hypervisor(env) && asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) { - helper_raise_exception(env, TT_PRIV_ACT); + cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC()); } - helper_check_align(env, addr, size - 1); + do_check_align(env, addr, size - 1, GETPC()); addr = asi_address_mask(env, asi, addr); /* process nonfaulting loads first */ @@ -1327,7 +1332,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, dump_asi("read ", last_addr, asi, size, ret); #endif /* env->exception_index is set in get_physical_address_data(). */ - helper_raise_exception(env, cs->exception_index); + cpu_raise_exception_ra(env, cs->exception_index, GETPC()); } /* convert nonfaulting load ASIs to normal load ASIs */ @@ -1619,7 +1624,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, case ASI_TWINX_S: /* Secondary, twinx */ case ASI_TWINX_SL: /* Secondary, twinx, LE */ /* These are all 128-bit atomic; only ldda (now ldtxa) allowed */ - helper_raise_exception(env, TT_ILL_INSN); + cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); return 0; } @@ -1688,10 +1693,10 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, || (cpu_has_hypervisor(env) && asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) { - helper_raise_exception(env, TT_PRIV_ACT); + cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC()); } - helper_check_align(env, addr, size - 1); + do_check_align(env, addr, size - 1, GETPC()); addr = asi_address_mask(env, asi, addr); /* Convert to little endian */ @@ -2037,7 +2042,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, case ASI_TWINX_S: /* Secondary, twinx */ case ASI_TWINX_SL: /* Secondary, twinx, LE */ /* Only stda allowed */ - helper_raise_exception(env, TT_ILL_INSN); + cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); return; case ASI_DCACHE_DATA: /* D-cache data */ case ASI_DCACHE_TAG: /* D-cache tag access */ @@ -2081,7 +2086,7 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi) || (cpu_has_hypervisor(env) && asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) { - helper_raise_exception(env, TT_PRIV_ACT); + cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC()); } addr = asi_address_mask(env, asi, addr); @@ -2090,19 +2095,19 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi) #if !defined(CONFIG_USER_ONLY) case ASI_TWINX_AIUP: /* As if user primary, twinx */ case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */ - helper_check_align(env, addr, 0xf); + do_check_align(env, addr, 0xf, GETPC()); h = cpu_ldq_user(env, addr); l = cpu_ldq_user(env, addr + 8); break; case ASI_TWINX_AIUS: /* As if user secondary, twinx */ case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */ - helper_check_align(env, addr, 0xf); + do_check_align(env, addr, 0xf, GETPC()); h = cpu_ldq_user_secondary(env, addr); l = cpu_ldq_user_secondary(env, addr + 8); break; case ASI_TWINX_REAL: /* Real address, twinx */ case ASI_TWINX_REAL_L: /* Real address, twinx, LE */ - helper_check_align(env, addr, 0xf); + do_check_align(env, addr, 0xf, GETPC()); { CPUState *cs = CPU(sparc_env_get_cpu(env)); h = ldq_phys(cs->as, addr); @@ -2113,14 +2118,14 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi) case ASI_NUCLEUS_QUAD_LDD_L: case ASI_TWINX_N: /* Nucleus, twinx */ case ASI_TWINX_NL: /* Nucleus, twinx, LE */ - helper_check_align(env, addr, 0xf); + do_check_align(env, addr, 0xf, GETPC()); h = cpu_ldq_nucleus(env, addr); l = cpu_ldq_nucleus(env, addr + 8); break; case ASI_TWINX_S: /* Secondary, twinx */ case ASI_TWINX_SL: /* Secondary, twinx, LE */ if (!cpu_hypervisor_mode(env)) { - helper_check_align(env, addr, 0xf); + do_check_align(env, addr, 0xf, GETPC()); if (env->pstate & PS_PRIV) { h = cpu_ldq_kernel_secondary(env, addr); l = cpu_ldq_kernel_secondary(env, addr + 8); @@ -2133,7 +2138,7 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi) /* fallthru */ case ASI_TWINX_P: /* Primary, twinx */ case ASI_TWINX_PL: /* Primary, twinx, LE */ - helper_check_align(env, addr, 0xf); + do_check_align(env, addr, 0xf, GETPC()); h = cpu_ldq_data(env, addr); l = cpu_ldq_data(env, addr + 8); break; @@ -2144,7 +2149,7 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi) case ASI_TWINX_SL: /* Primary, twinx, LE */ /* ??? Should be available, but we need to implement an atomic 128-bit load. */ - helper_raise_exception(env, TT_PRIV_ACT); + cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC()); #endif default: /* Non-twinx asi, so this is the legacy ldda insn, which @@ -2152,7 +2157,7 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi) /* ??? The UA2011 manual recommends emulating this with a single 64-bit load. However, LE asis *are* treated as two 32-bit loads individually byte swapped. */ - helper_check_align(env, addr, 0x7); + do_check_align(env, addr, 7, GETPC()); QT0.high = (uint32_t)helper_ld_asi(env, addr, asi, MO_UL); QT0.low = (uint32_t)helper_ld_asi(env, addr + 4, asi, MO_UL); return; @@ -2202,7 +2207,7 @@ void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx) /* XXX add 128 bit load */ CPU_QuadU u; - helper_check_align(env, addr, 7); + do_check_align(env, addr, 7, GETPC()); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { case MMU_USER_IDX: @@ -2238,7 +2243,7 @@ void helper_stqf(CPUSPARCState *env, target_ulong addr, int mem_idx) /* XXX add 128 bit store */ CPU_QuadU u; - helper_check_align(env, addr, 7); + do_check_align(env, addr, 7, GETPC()); #if !defined(CONFIG_USER_ONLY) switch (mem_idx) { case MMU_USER_IDX: @@ -2320,11 +2325,8 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr, } if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) { - if (is_exec) { - helper_raise_exception(env, TT_CODE_ACCESS); - } else { - helper_raise_exception(env, TT_DATA_ACCESS); - } + int tt = is_exec ? TT_CODE_ACCESS : TT_DATA_ACCESS; + cpu_raise_exception_ra(env, tt, GETPC()); } /* flush neverland mappings created during no-fault mode, @@ -2340,17 +2342,14 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr, { SPARCCPU *cpu = SPARC_CPU(cs->uc, cs); CPUSPARCState *env = &cpu->env; + int tt = is_exec ? TT_CODE_ACCESS : TT_DATA_ACCESS; #ifdef DEBUG_UNASSIGNED printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx "\n", addr, env->pc); #endif - if (is_exec) { - helper_raise_exception(env, TT_CODE_ACCESS); - } else { - helper_raise_exception(env, TT_DATA_ACCESS); - } + cpu_raise_exception_ra(env, tt, GETPC()); } #endif #endif @@ -2368,10 +2367,7 @@ void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs, vaddr addr, printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx "\n", addr, env->pc); #endif - if (retaddr) { - cpu_restore_state(CPU(cpu), retaddr); - } - helper_raise_exception(env, TT_UNALIGNED); + cpu_raise_exception_ra(env, TT_UNALIGNED, retaddr); } /* try to fill the TLB and return an exception if error. If retaddr is @@ -2385,10 +2381,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, ret = sparc_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx); if (ret) { - if (retaddr) { - cpu_restore_state(cs, retaddr); - } - cpu_loop_exit(cs); + cpu_loop_exit_restore(cs, retaddr); } } #endif diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c index 17ee82d5..e952a92e 100644 --- a/qemu/target-sparc/translate.c +++ b/qemu/target-sparc/translate.c @@ -3637,7 +3637,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins break; } else if (xop == 0x2b) { /* rdtbr / V9 flushw */ #ifdef TARGET_SPARC64 - save_state(dc); gen_helper_flushw(tcg_ctx, tcg_ctx->cpu_env); #else if (!supervisor(dc)) @@ -5241,12 +5240,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins /* nop */ break; case 0x3c: /* save */ - save_state(dc); gen_helper_save(tcg_ctx, tcg_ctx->cpu_env); gen_store_gpr(dc, rd, cpu_tmp0); break; case 0x3d: /* restore */ - save_state(dc); gen_helper_restore(tcg_ctx, tcg_ctx->cpu_env); gen_store_gpr(dc, rd, cpu_tmp0); break; diff --git a/qemu/target-sparc/win_helper.c b/qemu/target-sparc/win_helper.c index c4fa4c96..5a9f155e 100644 --- a/qemu/target-sparc/win_helper.c +++ b/qemu/target-sparc/win_helper.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "exec/exec-all.h" #include "exec/helper-proto.h" static inline void memcpy32(target_ulong *dst, const target_ulong *src) @@ -112,13 +113,13 @@ void helper_rett(CPUSPARCState *env) unsigned int cwp; if (env->psret == 1) { - helper_raise_exception(env, TT_ILL_INSN); + cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); } env->psret = 1; cwp = cpu_cwp_inc(env, env->cwp + 1) ; if (env->wim & (1 << cwp)) { - helper_raise_exception(env, TT_WIN_UNF); + cpu_raise_exception_ra(env, TT_WIN_UNF, GETPC()); } cpu_set_cwp(env, cwp); env->psrs = env->psrps; @@ -132,7 +133,7 @@ void helper_save(CPUSPARCState *env) cwp = cpu_cwp_dec(env, env->cwp - 1); if (env->wim & (1 << cwp)) { - helper_raise_exception(env, TT_WIN_OVF); + cpu_raise_exception_ra(env, TT_WIN_OVF, GETPC()); } cpu_set_cwp(env, cwp); } @@ -143,7 +144,7 @@ void helper_restore(CPUSPARCState *env) cwp = cpu_cwp_inc(env, env->cwp + 1); if (env->wim & (1 << cwp)) { - helper_raise_exception(env, TT_WIN_UNF); + cpu_raise_exception_ra(env, TT_WIN_UNF, GETPC()); } cpu_set_cwp(env, cwp); } @@ -151,7 +152,7 @@ void helper_restore(CPUSPARCState *env) void helper_wrpsr(CPUSPARCState *env, target_ulong new_psr) { if ((new_psr & PSR_CWP) >= env->nwindows) { - helper_raise_exception(env, TT_ILL_INSN); + cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); } else { cpu_put_psr(env, new_psr); } @@ -171,14 +172,14 @@ void helper_save(CPUSPARCState *env) cwp = cpu_cwp_dec(env, env->cwp - 1); if (env->cansave == 0) { - helper_raise_exception(env, TT_SPILL | (env->otherwin != 0 ? - (TT_WOTHER | - ((env->wstate & 0x38) >> 1)) : - ((env->wstate & 0x7) << 2))); + int tt = TT_SPILL | (env->otherwin != 0 + ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) + : ((env->wstate & 0x7) << 2)); + cpu_raise_exception_ra(env, tt, GETPC()); } else { if (env->cleanwin - env->canrestore == 0) { /* XXX Clean windows without trap */ - helper_raise_exception(env, TT_CLRWIN); + cpu_raise_exception_ra(env, TT_CLRWIN, GETPC()); } else { env->cansave--; env->canrestore++; @@ -193,10 +194,10 @@ void helper_restore(CPUSPARCState *env) cwp = cpu_cwp_inc(env, env->cwp + 1); if (env->canrestore == 0) { - helper_raise_exception(env, TT_FILL | (env->otherwin != 0 ? - (TT_WOTHER | - ((env->wstate & 0x38) >> 1)) : - ((env->wstate & 0x7) << 2))); + int tt = TT_FILL | (env->otherwin != 0 + ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) + : ((env->wstate & 0x7) << 2)); + cpu_raise_exception_ra(env, tt, GETPC()); } else { env->cansave++; env->canrestore--; @@ -207,10 +208,10 @@ void helper_restore(CPUSPARCState *env) void helper_flushw(CPUSPARCState *env) { if (env->cansave != env->nwindows - 2) { - helper_raise_exception(env, TT_SPILL | (env->otherwin != 0 ? - (TT_WOTHER | - ((env->wstate & 0x38) >> 1)) : - ((env->wstate & 0x7) << 2))); + int tt = TT_SPILL | (env->otherwin != 0 + ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)) + : ((env->wstate & 0x7) << 2)); + cpu_raise_exception_ra(env, tt, GETPC()); } }