diff options
Diffstat (limited to 'target-sparc')
-rw-r--r-- | target-sparc/cpu.h | 21 | ||||
-rw-r--r-- | target-sparc/helper.c | 2 | ||||
-rw-r--r-- | target-sparc/helper.h | 4 | ||||
-rw-r--r-- | target-sparc/op_helper.c | 16 | ||||
-rw-r--r-- | target-sparc/translate.c | 31 |
5 files changed, 43 insertions, 31 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 2845fd5bde..e24031a680 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -147,10 +147,15 @@ #ifdef TARGET_SPARC64 #define FSR_FTT_NMASK 0xfffffffffffe3fffULL #define FSR_FTT_CEXC_NMASK 0xfffffffffffe3fe0ULL +#define FSR_LDFSR_OLDMASK 0x0000003f000fc000ULL +#define FSR_LDXFSR_MASK 0x0000003fcfc00fffULL +#define FSR_LDXFSR_OLDMASK 0x00000000000fc000ULL #else #define FSR_FTT_NMASK 0xfffe3fffULL #define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL +#define FSR_LDFSR_OLDMASK 0x000fc000ULL #endif +#define FSR_LDFSR_MASK 0xcfc00fffULL #define FSR_FTT_IEEE_EXCP (1ULL << 14) #define FSR_FTT_UNIMPFPOP (3ULL << 14) #define FSR_FTT_SEQ_ERROR (4ULL << 14) @@ -329,22 +334,6 @@ typedef struct CPUSPARCState { sparc_def_t *def; } CPUSPARCState; -#if defined(TARGET_SPARC64) -#define GET_FSR32(env) (env->fsr & 0xcfc1ffff) -#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ - env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \ - } while (0) -#define GET_FSR64(env) (env->fsr & 0x3fcfc1ffffULL) -#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \ - env->fsr = _tmp & 0x3fcfc1c3ffULL; \ - } while (0) -#else -#define GET_FSR32(env) (env->fsr) -#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ - env->fsr = (_tmp & 0xcfc1dfff) | (env->fsr & 0x000e0000); \ - } while (0) -#endif - /* helper.c */ CPUSPARCState *cpu_sparc_init(const char *cpu_model); void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 0a2e132c85..14014805d4 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -1412,7 +1412,7 @@ void cpu_dump_state(CPUState *env, FILE *f, env->psrs?'S':'-', env->psrps?'P':'-', env->psret?'E':'-', env->wim); #endif - cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env)); + cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr); } #ifdef TARGET_SPARC64 diff --git a/target-sparc/helper.h b/target-sparc/helper.h index 124732fb04..5f329844f6 100644 --- a/target-sparc/helper.h +++ b/target-sparc/helper.h @@ -55,8 +55,7 @@ DEF_HELPER(uint64_t, helper_ld_asi, (target_ulong addr, int asi, int size, \ DEF_HELPER(void, helper_st_asi, (target_ulong addr, uint64_t val, int asi, \ int size)) #endif -DEF_HELPER(void, helper_ldfsr, (void)) -DEF_HELPER(void, helper_stfsr, (void)) +DEF_HELPER(void, helper_ldfsr, (uint32_t new_fsr)) DEF_HELPER(void, helper_check_ieee_exceptions, (void)) DEF_HELPER(void, helper_clear_float_exceptions, (void)) DEF_HELPER(void, helper_fabss, (void)) @@ -70,6 +69,7 @@ DEF_HELPER(void, helper_fsqrtq, (void)) DEF_HELPER(void, helper_fcmpq, (void)) DEF_HELPER(void, helper_fcmpeq, (void)) #ifdef TARGET_SPARC64 +DEF_HELPER(void, helper_ldxfsr, (uint64_t new_fsr)) DEF_HELPER(void, helper_fabsd, (void)) DEF_HELPER(void, helper_fcmps_fcc1, (void)) DEF_HELPER(void, helper_fcmpd_fcc1, (void)) diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 75020a92f2..75d648bab1 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -2487,11 +2487,10 @@ void helper_stqf(target_ulong addr, int mem_idx) #endif } -void helper_ldfsr(void) +static inline void set_fsr(void) { int rnd_mode; - PUT_FSR32(env, *((uint32_t *) &FT0)); switch (env->fsr & FSR_RD_MASK) { case FSR_RD_NEAREST: rnd_mode = float_round_nearest_even; @@ -2510,11 +2509,20 @@ void helper_ldfsr(void) set_float_rounding_mode(rnd_mode, &env->fp_status); } -void helper_stfsr(void) +void helper_ldfsr(uint32_t new_fsr) { - *((uint32_t *) &FT0) = GET_FSR32(env); + env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK); + set_fsr(); } +#ifdef TARGET_SPARC64 +void helper_ldxfsr(uint64_t new_fsr) +{ + env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK); + set_fsr(); +} +#endif + void helper_debug(void) { env->exception_index = EXCP_DEBUG; diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 9dea1c4ea1..b07efdda03 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -4368,12 +4368,19 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fpr[rd])); break; - case 0x21: /* load fsr */ + case 0x21: /* ldfsr, V9 ldxfsr */ +#ifdef TARGET_SPARC64 gen_address_mask(dc, cpu_addr); - tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); - tcg_gen_st_i32(cpu_tmp32, cpu_env, - offsetof(CPUState, ft0)); - tcg_gen_helper_0_0(helper_ldfsr); + if (rd == 1) { + tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx); + tcg_gen_helper_0_1(helper_ldxfsr, cpu_tmp64); + } else +#else + { + tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); + tcg_gen_helper_0_1(helper_ldfsr, cpu_tmp32); + } +#endif break; case 0x22: /* load quad fpreg */ { @@ -4506,11 +4513,19 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); break; case 0x25: /* stfsr, V9 stxfsr */ +#ifdef TARGET_SPARC64 gen_address_mask(dc, cpu_addr); - tcg_gen_helper_0_0(helper_stfsr); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, - offsetof(CPUState, ft0)); + tcg_gen_ld_i64(cpu_tmp64, cpu_env, offsetof(CPUState, fsr)); + if (rd == 1) + tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx); + else { + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp64); + tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); + } +#else + tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr)); tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); +#endif break; case 0x26: #ifdef TARGET_SPARC64 |