diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/translate.c | 62 |
1 files changed, 28 insertions, 34 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c index 0fb94b7..d8b4613 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -80,6 +80,8 @@ static const char * const regnames[] = /* Function prototypes for gen_ functions calling Neon helpers. */ typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32); +/* Function prototypes for gen_ functions for fix point conversions */ +typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr); /* initialize TCG globals. */ void arm_translate_init(void) @@ -1374,27 +1376,6 @@ static TCGv_ptr get_fpstatus_ptr(int neon) return statusptr; } -#define VFP_GEN_FIX(name, round) \ -static inline void gen_vfp_##name(int dp, int shift, int neon) \ -{ \ - TCGv_i32 tmp_shift = tcg_const_i32(shift); \ - TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ - if (dp) { \ - gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \ - statusptr); \ - } else { \ - gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \ - statusptr); \ - } \ - tcg_temp_free_i32(tmp_shift); \ - tcg_temp_free_ptr(statusptr); \ -} -VFP_GEN_FIX(tosl, _round_to_zero) -VFP_GEN_FIX(toul, _round_to_zero) -VFP_GEN_FIX(slto, ) -VFP_GEN_FIX(ulto, ) -#undef VFP_GEN_FIX - static inline long vfp_reg_offset(bool dp, unsigned reg) { if (dp) { @@ -5721,28 +5702,41 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) } } else if (op >= 14) { /* VCVT fixed-point. */ + TCGv_ptr fpst; + TCGv_i32 shiftv; + VFPGenFixPointFn *fn; + if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) { return 1; } + + if (!(op & 1)) { + if (u) { + fn = gen_helper_vfp_ultos; + } else { + fn = gen_helper_vfp_sltos; + } + } else { + if (u) { + fn = gen_helper_vfp_touls_round_to_zero; + } else { + fn = gen_helper_vfp_tosls_round_to_zero; + } + } + /* We have already masked out the must-be-1 top bit of imm6, * hence this 32-shift where the ARM ARM has 64-imm6. */ shift = 32 - shift; + fpst = get_fpstatus_ptr(1); + shiftv = tcg_const_i32(shift); for (pass = 0; pass < (q ? 4 : 2); pass++) { - tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass)); - if (!(op & 1)) { - if (u) - gen_vfp_ulto(0, shift, 1); - else - gen_vfp_slto(0, shift, 1); - } else { - if (u) - gen_vfp_toul(0, shift, 1); - else - gen_vfp_tosl(0, shift, 1); - } - tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass)); + TCGv_i32 tmpf = neon_load_reg(rm, pass); + fn(tmpf, tmpf, shiftv, fpst); + neon_store_reg(rd, pass, tmpf); } + tcg_temp_free_ptr(fpst); + tcg_temp_free_i32(shiftv); } else { return 1; } |