diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-09-10 19:54:51 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-09-10 19:54:51 +0000 |
commit | 714547bbc7db79a1d7e6544bf90c9ee1073d6881 (patch) | |
tree | 39f632d257a81885912413a237f80eef15141261 /target-sparc | |
parent | bcdf9b4d169f6d6735a817c4d9e57a5490843041 (diff) |
Convert basic float32 ops to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5189 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc')
-rw-r--r-- | target-sparc/helper.h | 47 | ||||
-rw-r--r-- | target-sparc/op_helper.c | 75 | ||||
-rw-r--r-- | target-sparc/translate.c | 397 |
3 files changed, 329 insertions, 190 deletions
diff --git a/target-sparc/helper.h b/target-sparc/helper.h index 5f329844f6..a22c716cbf 100644 --- a/target-sparc/helper.h +++ b/target-sparc/helper.h @@ -58,12 +58,12 @@ DEF_HELPER(void, helper_st_asi, (target_ulong addr, uint64_t val, int asi, \ 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)) -DEF_HELPER(void, helper_fsqrts, (void)) +DEF_HELPER(float32, helper_fabss, (float32 src)) +DEF_HELPER(float32, helper_fsqrts, (float32 src)) DEF_HELPER(void, helper_fsqrtd, (void)) -DEF_HELPER(void, helper_fcmps, (void)) +DEF_HELPER(void, helper_fcmps, (float32 src1, float32 src2)) DEF_HELPER(void, helper_fcmpd, (void)) -DEF_HELPER(void, helper_fcmpes, (void)) +DEF_HELPER(void, helper_fcmpes, (float32 src1, float32 src2)) DEF_HELPER(void, helper_fcmped, (void)) DEF_HELPER(void, helper_fsqrtq, (void)) DEF_HELPER(void, helper_fcmpq, (void)) @@ -71,17 +71,17 @@ 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_fcmps_fcc1, (float32 src1, float32 src2)) +DEF_HELPER(void, helper_fcmps_fcc2, (float32 src1, float32 src2)) +DEF_HELPER(void, helper_fcmps_fcc3, (float32 src1, float32 src2)) DEF_HELPER(void, helper_fcmpd_fcc1, (void)) -DEF_HELPER(void, helper_fcmps_fcc2, (void)) DEF_HELPER(void, helper_fcmpd_fcc2, (void)) -DEF_HELPER(void, helper_fcmps_fcc3, (void)) DEF_HELPER(void, helper_fcmpd_fcc3, (void)) -DEF_HELPER(void, helper_fcmpes_fcc1, (void)) +DEF_HELPER(void, helper_fcmpes_fcc1, (float32 src1, float32 src2)) +DEF_HELPER(void, helper_fcmpes_fcc2, (float32 src1, float32 src2)) +DEF_HELPER(void, helper_fcmpes_fcc3, (float32 src1, float32 src2)) DEF_HELPER(void, helper_fcmped_fcc1, (void)) -DEF_HELPER(void, helper_fcmpes_fcc2, (void)) DEF_HELPER(void, helper_fcmped_fcc2, (void)) -DEF_HELPER(void, helper_fcmpes_fcc3, (void)) DEF_HELPER(void, helper_fcmped_fcc3, (void)) DEF_HELPER(void, helper_fabsq, (void)) DEF_HELPER(void, helper_fcmpq_fcc1, (void)) @@ -97,17 +97,28 @@ DEF_HELPER(void, raise_exception, (int tt)) F_HELPER_0_0(name ## s); \ F_HELPER_0_0(name ## d); \ F_HELPER_0_0(name ## q) +#define F_HELPER_DQ_0_0(name) \ + F_HELPER_0_0(name ## d); \ + F_HELPER_0_0(name ## q) + +F_HELPER_DQ_0_0(add); +F_HELPER_DQ_0_0(sub); +F_HELPER_DQ_0_0(mul); +F_HELPER_DQ_0_0(div); -F_HELPER_SDQ_0_0(add); -F_HELPER_SDQ_0_0(sub); -F_HELPER_SDQ_0_0(mul); -F_HELPER_SDQ_0_0(div); +DEF_HELPER(float32, helper_fadds, (float32 src1, float32 src2)) +DEF_HELPER(float32, helper_fsubs, (float32 src1, float32 src2)) +DEF_HELPER(float32, helper_fmuls, (float32 src1, float32 src2)) +DEF_HELPER(float32, helper_fdivs, (float32 src1, float32 src2)) F_HELPER_0_0(smuld); F_HELPER_0_0(dmulq); -DEF_HELPER(void, helper_fnegs, (void)) -F_HELPER_SDQ_0_0(ito); +DEF_HELPER(float32, helper_fnegs, (float32 src)) +F_HELPER_DQ_0_0(ito); + +DEF_HELPER(float32, helper_fitos, (int32_t src)) + #ifdef TARGET_SPARC64 DEF_HELPER(void, helper_fnegd, (void)) DEF_HELPER(void, helper_fnegq, (void)) @@ -119,7 +130,7 @@ F_HELPER_0_0(qtos); F_HELPER_0_0(stoq); F_HELPER_0_0(qtod); F_HELPER_0_0(dtoq); -F_HELPER_0_0(stoi); +DEF_HELPER(int32_t, helper_fstoi, (float32 src)) F_HELPER_0_0(dtoi); F_HELPER_0_0(qtoi); #ifdef TARGET_SPARC64 @@ -176,6 +187,6 @@ VIS_CMPHELPER(cmple); VIS_CMPHELPER(cmpne); #endif #undef F_HELPER_0_0 -#undef F_HELPER_SDQ_0_0 +#undef F_HELPER_DQ_0_0 #undef VIS_HELPER #undef VIS_CMPHELPER diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 75d648bab1..84ed6f6c46 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -87,9 +87,9 @@ void helper_check_align(target_ulong addr, uint32_t align) #define F_HELPER(name, p) void helper_f##name##p(void) #define F_BINOP(name) \ - F_HELPER(name, s) \ + float32 helper_f ## name ## s (float32 src1, float32 src2) \ { \ - FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \ + return float32_ ## name (src1, src2, &env->fp_status); \ } \ F_HELPER(name, d) \ { \ @@ -120,9 +120,9 @@ void helper_fdmulq(void) &env->fp_status); } -F_HELPER(neg, s) +float32 helper_fnegs(float32 src) { - FT0 = float32_chs(FT1); + return float32_chs(src); } #ifdef TARGET_SPARC64 @@ -138,9 +138,9 @@ F_HELPER(neg, q) #endif /* Integer to float conversion. */ -F_HELPER(ito, s) +float32 helper_fitos(int32_t src) { - FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); + return int32_to_float32(src, &env->fp_status); } F_HELPER(ito, d) @@ -203,9 +203,9 @@ void helper_fdtoq(void) } /* Float to integer conversion. */ -void helper_fstoi(void) +int32_t helper_fstoi(float32 src) { - *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status); + return float32_to_int32_round_to_zero(src, &env->fp_status); } void helper_fdtoi(void) @@ -714,9 +714,9 @@ void helper_clear_float_exceptions(void) set_float_exception_flags(0, &env->fp_status); } -void helper_fabss(void) +float32 helper_fabss(float32 src) { - FT0 = float32_abs(FT1); + return float32_abs(src); } #ifdef TARGET_SPARC64 @@ -731,9 +731,9 @@ void helper_fabsq(void) } #endif -void helper_fsqrts(void) +float32 helper_fsqrts(float32 src) { - FT0 = float32_sqrt(FT1, &env->fp_status); + return float32_sqrt(src, &env->fp_status); } void helper_fsqrtd(void) @@ -776,41 +776,72 @@ void helper_fsqrtq(void) } \ env->fsr |= new_fsr; \ } +#define GEN_FCMPS(name, size, FS, TRAP) \ + void glue(helper_, name)(float32 src1, float32 src2) \ + { \ + target_ulong new_fsr; \ + \ + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ + switch (glue(size, _compare) (src1, src2, &env->fp_status)) { \ + case float_relation_unordered: \ + new_fsr = (FSR_FCC1 | FSR_FCC0) << FS; \ + if ((env->fsr & FSR_NVM) || TRAP) { \ + env->fsr |= new_fsr; \ + env->fsr |= FSR_NVC; \ + env->fsr |= FSR_FTT_IEEE_EXCP; \ + raise_exception(TT_FP_EXCP); \ + } else { \ + env->fsr |= FSR_NVA; \ + } \ + break; \ + case float_relation_less: \ + new_fsr = FSR_FCC0 << FS; \ + break; \ + case float_relation_greater: \ + new_fsr = FSR_FCC1 << FS; \ + break; \ + default: \ + new_fsr = 0; \ + break; \ + } \ + env->fsr |= new_fsr; \ + } -GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0); +GEN_FCMPS(fcmps, float32, 0, 0); GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0); -GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1); +GEN_FCMPS(fcmpes, float32, 0, 1); GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1); GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0); GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1); #ifdef TARGET_SPARC64 -GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0); +GEN_FCMPS(fcmps_fcc1, float32, 22, 0); GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0); GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0); -GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0); +GEN_FCMPS(fcmps_fcc2, float32, 24, 0); GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0); GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0); -GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0); +GEN_FCMPS(fcmps_fcc3, float32, 26, 0); GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0); GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0); -GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1); +GEN_FCMPS(fcmpes_fcc1, float32, 22, 1); GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1); GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1); -GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1); +GEN_FCMPS(fcmpes_fcc2, float32, 24, 1); GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1); GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1); -GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1); +GEN_FCMPS(fcmpes_fcc3, float32, 26, 1); GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1); GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1); #endif +#undef GEN_FCMPS #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \ defined(DEBUG_MXCC) @@ -2220,7 +2251,7 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) switch(size) { default: case 4: - *((uint32_t *)&FT0) = val; + *((uint32_t *)&env->fpr[rd]) = val; break; case 8: *((int64_t *)&DT0) = val; @@ -2261,7 +2292,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) switch(size) { default: case 4: - val = *((uint32_t *)&FT0); + val = *((uint32_t *)&env->fpr[rd]); break; case 8: val = *((int64_t *)&DT0); diff --git a/target-sparc/translate.c b/target-sparc/translate.c index b07efdda03..937c7084c2 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -55,6 +55,8 @@ static TCGv cpu_wim; #endif /* local register indexes (only used inside old micro ops) */ static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64; +/* Floating point registers */ +static TCGv cpu_fpr[TARGET_FPREGS]; #include "gen-icount.h" @@ -102,98 +104,77 @@ static int sign_extend(int x, int len) /* floating point registers moves */ static void gen_op_load_fpr_FT0(unsigned int src) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0)); + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, ft0)); } static void gen_op_load_fpr_FT1(unsigned int src) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1)); + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, ft1)); } static void gen_op_store_FT0_fpr(unsigned int dst) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0)); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst])); + tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, ft0)); } static void gen_op_load_fpr_DT0(unsigned int src) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper)); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + + tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower)); } static void gen_op_load_fpr_DT1(unsigned int src) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.upper)); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + + tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.lower)); } static void gen_op_store_DT0_fpr(unsigned int dst) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + + tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper)); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst])); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + + tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower)); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1])); } static void gen_op_load_fpr_QT0(unsigned int src) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost)); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + + tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper)); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + + tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower)); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + + tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest)); } static void gen_op_load_fpr_QT1(unsigned int src) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upmost)); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + + tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upper)); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + + tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lower)); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3])); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + + tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lowest)); } static void gen_op_store_QT0_fpr(unsigned int dst) { - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + + tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost)); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst])); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + + tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper)); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1])); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + + tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower)); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2])); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + + tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest)); - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3])); } /* moves */ @@ -1496,13 +1477,6 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, } } -static GenOpFunc * const gen_fcmps[4] = { - helper_fcmps, - helper_fcmps_fcc1, - helper_fcmps_fcc2, - helper_fcmps_fcc3, -}; - static GenOpFunc * const gen_fcmpd[4] = { helper_fcmpd, helper_fcmpd_fcc1, @@ -1517,13 +1491,6 @@ static GenOpFunc * const gen_fcmpq[4] = { helper_fcmpq_fcc3, }; -static GenOpFunc * const gen_fcmpes[4] = { - helper_fcmpes, - helper_fcmpes_fcc1, - helper_fcmpes_fcc2, - helper_fcmpes_fcc3, -}; - static GenOpFunc * const gen_fcmped[4] = { helper_fcmped, helper_fcmped_fcc1, @@ -1538,9 +1505,22 @@ static GenOpFunc * const gen_fcmpeq[4] = { helper_fcmpeq_fcc3, }; -static inline void gen_op_fcmps(int fccno) +static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2) { - tcg_gen_helper_0_0(gen_fcmps[fccno]); + switch (fccno) { + case 0: + tcg_gen_helper_0_2(helper_fcmps, r_rs1, r_rs2); + break; + case 1: + tcg_gen_helper_0_2(helper_fcmps_fcc1, r_rs1, r_rs2); + break; + case 2: + tcg_gen_helper_0_2(helper_fcmps_fcc2, r_rs1, r_rs2); + break; + case 3: + tcg_gen_helper_0_2(helper_fcmps_fcc3, r_rs1, r_rs2); + break; + } } static inline void gen_op_fcmpd(int fccno) @@ -1553,9 +1533,22 @@ static inline void gen_op_fcmpq(int fccno) tcg_gen_helper_0_0(gen_fcmpq[fccno]); } -static inline void gen_op_fcmpes(int fccno) +static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2) { - tcg_gen_helper_0_0(gen_fcmpes[fccno]); + switch (fccno) { + case 0: + tcg_gen_helper_0_2(helper_fcmpes, r_rs1, r_rs2); + break; + case 1: + tcg_gen_helper_0_2(helper_fcmpes_fcc1, r_rs1, r_rs2); + break; + case 2: + tcg_gen_helper_0_2(helper_fcmpes_fcc2, r_rs1, r_rs2); + break; + case 3: + tcg_gen_helper_0_2(helper_fcmpes_fcc3, r_rs1, r_rs2); + break; + } } static inline void gen_op_fcmped(int fccno) @@ -1570,9 +1563,9 @@ static inline void gen_op_fcmpeq(int fccno) #else -static inline void gen_op_fcmps(int fccno) +static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2) { - tcg_gen_helper_0_0(helper_fcmps); + tcg_gen_helper_0_2(helper_fcmps, r_rs1, r_rs2); } static inline void gen_op_fcmpd(int fccno) @@ -1585,9 +1578,9 @@ static inline void gen_op_fcmpq(int fccno) tcg_gen_helper_0_0(helper_fcmpq); } -static inline void gen_op_fcmpes(int fccno) +static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2) { - tcg_gen_helper_0_0(helper_fcmpes); + tcg_gen_helper_0_2(helper_fcmpes, r_rs1, r_rs2); } static inline void gen_op_fcmped(int fccno) @@ -2349,26 +2342,23 @@ static void disas_sparc_insn(DisasContext * dc) xop = GET_FIELD(insn, 18, 26); switch (xop) { case 0x1: /* fmovs */ - gen_op_load_fpr_FT0(rs2); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); break; case 0x5: /* fnegs */ - gen_op_load_fpr_FT1(rs2); - tcg_gen_helper_0_0(helper_fnegs); - gen_op_store_FT0_fpr(rd); + tcg_gen_helper_1_1(helper_fnegs, cpu_fpr[rd], + cpu_fpr[rs2]); break; case 0x9: /* fabss */ - gen_op_load_fpr_FT1(rs2); - tcg_gen_helper_0_0(helper_fabss); - gen_op_store_FT0_fpr(rd); + tcg_gen_helper_1_1(helper_fabss, cpu_fpr[rd], + cpu_fpr[rs2]); break; case 0x29: /* fsqrts */ CHECK_FPU_FEATURE(dc, FSQRT); - gen_op_load_fpr_FT1(rs2); gen_clear_float_exceptions(); - tcg_gen_helper_0_0(helper_fsqrts); + tcg_gen_helper_1_1(helper_fsqrts, cpu_tmp32, + cpu_fpr[rs2]); tcg_gen_helper_0_0(helper_check_ieee_exceptions); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); break; case 0x2a: /* fsqrtd */ CHECK_FPU_FEATURE(dc, FSQRT); @@ -2386,13 +2376,12 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_helper_0_0(helper_check_ieee_exceptions); gen_op_store_QT0_fpr(QFPREG(rd)); break; - case 0x41: - gen_op_load_fpr_FT0(rs1); - gen_op_load_fpr_FT1(rs2); + case 0x41: /* fadds */ gen_clear_float_exceptions(); - tcg_gen_helper_0_0(helper_fadds); + tcg_gen_helper_1_2(helper_fadds, cpu_tmp32, + cpu_fpr[rs1], cpu_fpr[rs2]); tcg_gen_helper_0_0(helper_check_ieee_exceptions); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); break; case 0x42: gen_op_load_fpr_DT0(DFPREG(rs1)); @@ -2411,13 +2400,12 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_helper_0_0(helper_check_ieee_exceptions); gen_op_store_QT0_fpr(QFPREG(rd)); break; - case 0x45: - gen_op_load_fpr_FT0(rs1); - gen_op_load_fpr_FT1(rs2); + case 0x45: /* fsubs */ gen_clear_float_exceptions(); - tcg_gen_helper_0_0(helper_fsubs); + tcg_gen_helper_1_2(helper_fsubs, cpu_tmp32, + cpu_fpr[rs1], cpu_fpr[rs2]); tcg_gen_helper_0_0(helper_check_ieee_exceptions); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); break; case 0x46: gen_op_load_fpr_DT0(DFPREG(rs1)); @@ -2438,12 +2426,11 @@ static void disas_sparc_insn(DisasContext * dc) break; case 0x49: /* fmuls */ CHECK_FPU_FEATURE(dc, FMUL); - gen_op_load_fpr_FT0(rs1); - gen_op_load_fpr_FT1(rs2); gen_clear_float_exceptions(); - tcg_gen_helper_0_0(helper_fmuls); + tcg_gen_helper_1_2(helper_fmuls, cpu_tmp32, + cpu_fpr[rs1], cpu_fpr[rs2]); tcg_gen_helper_0_0(helper_check_ieee_exceptions); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); break; case 0x4a: /* fmuld */ CHECK_FPU_FEATURE(dc, FMUL); @@ -2464,13 +2451,12 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_helper_0_0(helper_check_ieee_exceptions); gen_op_store_QT0_fpr(QFPREG(rd)); break; - case 0x4d: - gen_op_load_fpr_FT0(rs1); - gen_op_load_fpr_FT1(rs2); + case 0x4d: /* fdivs */ gen_clear_float_exceptions(); - tcg_gen_helper_0_0(helper_fdivs); + tcg_gen_helper_1_2(helper_fdivs, cpu_tmp32, + cpu_fpr[rs1], cpu_fpr[rs2]); tcg_gen_helper_0_0(helper_check_ieee_exceptions); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); break; case 0x4e: gen_op_load_fpr_DT0(DFPREG(rs1)); @@ -2507,12 +2493,12 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_helper_0_0(helper_check_ieee_exceptions); gen_op_store_QT0_fpr(QFPREG(rd)); break; - case 0xc4: - gen_op_load_fpr_FT1(rs2); + case 0xc4: /* fitos */ gen_clear_float_exceptions(); - tcg_gen_helper_0_0(helper_fitos); + tcg_gen_helper_1_1(helper_fitos, cpu_tmp32, + cpu_fpr[rs2]); tcg_gen_helper_0_0(helper_check_ieee_exceptions); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); break; case 0xc6: gen_op_load_fpr_DT1(DFPREG(rs2)); @@ -2565,12 +2551,12 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_helper_0_0(helper_fdtoq); gen_op_store_QT0_fpr(QFPREG(rd)); break; - case 0xd1: - gen_op_load_fpr_FT1(rs2); + case 0xd1: /* fstoi */ gen_clear_float_exceptions(); - tcg_gen_helper_0_0(helper_fstoi); + tcg_gen_helper_1_1(helper_fstoi, cpu_tmp32, + cpu_fpr[rs2]); tcg_gen_helper_0_0(helper_check_ieee_exceptions); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); break; case 0xd2: gen_op_load_fpr_DT1(DFPREG(rs2)); @@ -2589,13 +2575,21 @@ static void disas_sparc_insn(DisasContext * dc) break; #ifdef TARGET_SPARC64 case 0x2: /* V9 fmovd */ - gen_op_load_fpr_DT0(DFPREG(rs2)); - gen_op_store_DT0_fpr(DFPREG(rd)); + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], + cpu_fpr[DFPREG(rs2)]); + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], + cpu_fpr[DFPREG(rs2) + 1]); break; case 0x3: /* V9 fmovq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT0(QFPREG(rs2)); - gen_op_store_QT0_fpr(QFPREG(rd)); + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], + cpu_fpr[QFPREG(rs2)]); + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], + cpu_fpr[QFPREG(rs2) + 1]); + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], + cpu_fpr[QFPREG(rs2) + 2]); + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], + cpu_fpr[QFPREG(rs2) + 3]); break; case 0x6: /* V9 fnegd */ gen_op_load_fpr_DT1(DFPREG(rs2)); @@ -2686,8 +2680,7 @@ static void disas_sparc_insn(DisasContext * dc) cpu_src1 = get_src1(insn, cpu_src1); tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, 0, l1); - gen_op_load_fpr_FT0(rs2); - gen_op_store_FT0_fpr(rd); + tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); gen_set_label(l1); break; } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr @@ -2698,8 +2691,8 @@ static void disas_sparc_insn(DisasContext * dc) cpu_src1 = get_src1(insn, cpu_src1); tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, 0, l1); - gen_op_load_fpr_DT0(DFPREG(rs2)); - gen_op_store_DT0_fpr(DFPREG(rd)); + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]); + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]); gen_set_label(l1); break; } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr @@ -2711,15 +2704,17 @@ static void disas_sparc_insn(DisasContext * dc) cpu_src1 = get_src1(insn, cpu_src1); tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, 0, l1); - gen_op_load_fpr_QT0(QFPREG(rs2)); - gen_op_store_QT0_fpr(QFPREG(rd)); + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]); + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]); + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]); + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]); gen_set_label(l1); break; } #endif switch (xop) { #ifdef TARGET_SPARC64 -#define FMOVCC(size_FDQ, fcc) \ +#define FMOVSCC(fcc) \ { \ TCGv r_cond; \ int l1; \ @@ -2730,54 +2725,93 @@ static void disas_sparc_insn(DisasContext * dc) gen_fcond(r_cond, fcc, cond); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ 0, l1); \ - glue(glue(gen_op_load_fpr_, size_FDQ), T0) \ - (glue(size_FDQ, FPREG(rs2))); \ - glue(glue(gen_op_store_, size_FDQ), T0_fpr) \ - (glue(size_FDQ, FPREG(rd))); \ + tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \ + gen_set_label(l1); \ + tcg_temp_free(r_cond); \ + } +#define FMOVDCC(fcc) \ + { \ + TCGv r_cond; \ + int l1; \ + \ + l1 = gen_new_label(); \ + r_cond = tcg_temp_new(TCG_TYPE_TL); \ + cond = GET_FIELD_SP(insn, 14, 17); \ + gen_fcond(r_cond, fcc, cond); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ + 0, l1); \ + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \ + cpu_fpr[DFPREG(rs2)]); \ + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \ + cpu_fpr[DFPREG(rs2) + 1]); \ + gen_set_label(l1); \ + tcg_temp_free(r_cond); \ + } +#define FMOVQCC(fcc) \ + { \ + TCGv r_cond; \ + int l1; \ + \ + l1 = gen_new_label(); \ + r_cond = tcg_temp_new(TCG_TYPE_TL); \ + cond = GET_FIELD_SP(insn, 14, 17); \ + gen_fcond(r_cond, fcc, cond); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ + 0, l1); \ + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \ + cpu_fpr[QFPREG(rs2)]); \ + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \ + cpu_fpr[QFPREG(rs2) + 1]); \ + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \ + cpu_fpr[QFPREG(rs2) + 2]); \ + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \ + cpu_fpr[QFPREG(rs2) + 3]); \ gen_set_label(l1); \ tcg_temp_free(r_cond); \ } case 0x001: /* V9 fmovscc %fcc0 */ - FMOVCC(F, 0); + FMOVSCC(0); break; case 0x002: /* V9 fmovdcc %fcc0 */ - FMOVCC(D, 0); + FMOVDCC(0); break; case 0x003: /* V9 fmovqcc %fcc0 */ CHECK_FPU_FEATURE(dc, FLOAT128); - FMOVCC(Q, 0); + FMOVQCC(0); break; case 0x041: /* V9 fmovscc %fcc1 */ - FMOVCC(F, 1); + FMOVSCC(1); break; case 0x042: /* V9 fmovdcc %fcc1 */ - FMOVCC(D, 1); + FMOVDCC(1); break; case 0x043: /* V9 fmovqcc %fcc1 */ CHECK_FPU_FEATURE(dc, FLOAT128); - FMOVCC(Q, 1); + FMOVQCC(1); break; case 0x081: /* V9 fmovscc %fcc2 */ - FMOVCC(F, 2); + FMOVSCC(2); break; case 0x082: /* V9 fmovdcc %fcc2 */ - FMOVCC(D, 2); + FMOVDCC(2); break; case 0x083: /* V9 fmovqcc %fcc2 */ CHECK_FPU_FEATURE(dc, FLOAT128); - FMOVCC(Q, 2); + FMOVQCC(2); break; case 0x0c1: /* V9 fmovscc %fcc3 */ - FMOVCC(F, 3); + FMOVSCC(3); break; case 0x0c2: /* V9 fmovdcc %fcc3 */ - FMOVCC(D, 3); + FMOVDCC(3); break; case 0x0c3: /* V9 fmovqcc %fcc3 */ CHECK_FPU_FEATURE(dc, FLOAT128); - FMOVCC(Q, 3); + FMOVQCC(3); break; -#undef FMOVCC +#undef FMOVSCC +#undef FMOVDCC +#undef FMOVQCC #define FMOVCC(size_FDQ, icc) \ { \ TCGv r_cond; \ @@ -2796,32 +2830,87 @@ static void disas_sparc_insn(DisasContext * dc) gen_set_label(l1); \ tcg_temp_free(r_cond); \ } +#define FMOVSCC(icc) \ + { \ + TCGv r_cond; \ + int l1; \ + \ + l1 = gen_new_label(); \ + r_cond = tcg_temp_new(TCG_TYPE_TL); \ + cond = GET_FIELD_SP(insn, 14, 17); \ + gen_cond(r_cond, icc, cond); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ + 0, l1); \ + tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \ + gen_set_label(l1); \ + tcg_temp_free(r_cond); \ + } +#define FMOVDCC(icc) \ + { \ + TCGv r_cond; \ + int l1; \ + \ + l1 = gen_new_label(); \ + r_cond = tcg_temp_new(TCG_TYPE_TL); \ + cond = GET_FIELD_SP(insn, 14, 17); \ + gen_cond(r_cond, icc, cond); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ + 0, l1); \ + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \ + cpu_fpr[DFPREG(rs2)]); \ + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \ + cpu_fpr[DFPREG(rs2) + 1]); \ + gen_set_label(l1); \ + tcg_temp_free(r_cond); \ + } +#define FMOVQCC(icc) \ + { \ + TCGv r_cond; \ + int l1; \ + \ + l1 = gen_new_label(); \ + r_cond = tcg_temp_new(TCG_TYPE_TL); \ + cond = GET_FIELD_SP(insn, 14, 17); \ + gen_cond(r_cond, icc, cond); \ + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ + 0, l1); \ + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \ + cpu_fpr[QFPREG(rs2)]); \ + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \ + cpu_fpr[QFPREG(rs2) + 1]); \ + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \ + cpu_fpr[QFPREG(rs2) + 2]); \ + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \ + cpu_fpr[QFPREG(rs2) + 3]); \ + gen_set_label(l1); \ + tcg_temp_free(r_cond); \ + } case 0x101: /* V9 fmovscc %icc */ - FMOVCC(F, 0); + FMOVSCC(0); break; case 0x102: /* V9 fmovdcc %icc */ - FMOVCC(D, 0); + FMOVDCC(0); case 0x103: /* V9 fmovqcc %icc */ CHECK_FPU_FEATURE(dc, FLOAT128); - FMOVCC(Q, 0); + FMOVQCC(0); break; case 0x181: /* V9 fmovscc %xcc */ - FMOVCC(F, 1); + FMOVSCC(1); break; case 0x182: /* V9 fmovdcc %xcc */ - FMOVCC(D, 1); + FMOVDCC(1); break; case 0x183: /* V9 fmovqcc %xcc */ CHECK_FPU_FEATURE(dc, FLOAT128); - FMOVCC(Q, 1); + FMOVQCC(1); break; -#undef FMOVCC +#undef FMOVSCC +#undef FMOVDCC +#undef FMOVQCC #endif case 0x51: /* fcmps, V9 %fcc */ - gen_op_load_fpr_FT0(rs1); - gen_op_load_fpr_FT1(rs2); - gen_op_fcmps(rd & 3); + gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]); break; case 0x52: /* fcmpd, V9 %fcc */ gen_op_load_fpr_DT0(DFPREG(rs1)); @@ -2835,9 +2924,7 @@ static void disas_sparc_insn(DisasContext * dc) gen_op_fcmpq(rd & 3); break; case 0x55: /* fcmpes, V9 %fcc */ - gen_op_load_fpr_FT0(rs1); - gen_op_load_fpr_FT1(rs2); - gen_op_fcmpes(rd & 3); + gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]); break; case 0x56: /* fcmped, V9 %fcc */ gen_op_load_fpr_DT0(DFPREG(rs1)); @@ -4364,9 +4451,7 @@ static void disas_sparc_insn(DisasContext * dc) switch (xop) { case 0x20: /* load fpreg */ 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, fpr[rd])); + tcg_gen_qemu_ld32u(cpu_fpr[rd], cpu_addr, dc->mem_idx); break; case 0x21: /* ldfsr, V9 ldxfsr */ #ifdef TARGET_SPARC64 @@ -4508,9 +4593,7 @@ static void disas_sparc_insn(DisasContext * dc) switch (xop) { case 0x24: /* store fpreg */ gen_address_mask(dc, cpu_addr); - tcg_gen_ld_i32(cpu_tmp32, cpu_env, - offsetof(CPUState, fpr[rd])); - tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); + tcg_gen_qemu_st32(cpu_fpr[rd], cpu_addr, dc->mem_idx); break; case 0x25: /* stfsr, V9 stxfsr */ #ifdef TARGET_SPARC64 @@ -4570,7 +4653,6 @@ static void disas_sparc_insn(DisasContext * dc) switch (xop) { #ifdef TARGET_SPARC64 case 0x34: /* V9 stfa */ - gen_op_load_fpr_FT0(rd); gen_stf_asi(cpu_addr, insn, 4, rd); break; case 0x36: /* V9 stqfa */ @@ -4858,6 +4940,16 @@ void gen_intermediate_code_init(CPUSPARCState *env) "g6", "g7", }; + static const char * const fregnames[64] = { + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", + "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", + "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", + "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", + "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63", + }; /* init various static tables */ if (!inited) { @@ -4945,6 +5037,11 @@ void gen_intermediate_code_init(CPUSPARCState *env) cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, offsetof(CPUState, gregs[i]), gregnames[i]); + for (i = 0; i < TARGET_FPREGS; i++) + cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, + offsetof(CPUState, fpr[i]), + fregnames[i]); + /* register helpers */ #undef DEF_HELPER |