Implement ldxfsr/stxfsr, fix ld(x)fsr masks, convert to TCG
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>
Tue, 9 Sep 2008 19:02:49 +0000 (19:02 +0000)
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>
Tue, 9 Sep 2008 19:02:49 +0000 (19:02 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5185 c046a42c-6fe2-441c-8c8c-71466251a162

target-sparc/cpu.h
target-sparc/helper.c
target-sparc/helper.h
target-sparc/op_helper.c
target-sparc/translate.c

index 2845fd5..e24031a 100644 (file)
 #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);
index 0a2e132..1401480 100644 (file)
@@ -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
index 124732f..5f32984 100644 (file)
@@ -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))
index 75020a9..75d648b 100644 (file)
@@ -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;
index 9dea1c4..b07efdd 100644 (file)
@@ -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