tcg_temp_free_i32(vd);
return true;
}
+
+static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
+{
+ TCGv_i32 vd, shift;
+ TCGv_ptr fpst;
+ int frac_bits;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
+
+ vd = tcg_temp_new_i32();
+ neon_load_reg32(vd, a->vd);
+
+ fpst = get_fpstatus_ptr(false);
+ shift = tcg_const_i32(frac_bits);
+
+ /* Switch on op:U:sx bits */
+ switch (a->opc) {
+ case 0:
+ gen_helper_vfp_shtos(vd, vd, shift, fpst);
+ break;
+ case 1:
+ gen_helper_vfp_sltos(vd, vd, shift, fpst);
+ break;
+ case 2:
+ gen_helper_vfp_uhtos(vd, vd, shift, fpst);
+ break;
+ case 3:
+ gen_helper_vfp_ultos(vd, vd, shift, fpst);
+ break;
+ case 4:
+ gen_helper_vfp_toshs_round_to_zero(vd, vd, shift, fpst);
+ break;
+ case 5:
+ gen_helper_vfp_tosls_round_to_zero(vd, vd, shift, fpst);
+ break;
+ case 6:
+ gen_helper_vfp_touhs_round_to_zero(vd, vd, shift, fpst);
+ break;
+ case 7:
+ gen_helper_vfp_touls_round_to_zero(vd, vd, shift, fpst);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ neon_store_reg32(vd, a->vd);
+ tcg_temp_free_i32(vd);
+ tcg_temp_free_i32(shift);
+ tcg_temp_free_ptr(fpst);
+ return true;
+}
+
+static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
+{
+ TCGv_i64 vd;
+ TCGv_i32 shift;
+ TCGv_ptr fpst;
+ int frac_bits;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
+
+ vd = tcg_temp_new_i64();
+ neon_load_reg64(vd, a->vd);
+
+ fpst = get_fpstatus_ptr(false);
+ shift = tcg_const_i32(frac_bits);
+
+ /* Switch on op:U:sx bits */
+ switch (a->opc) {
+ case 0:
+ gen_helper_vfp_shtod(vd, vd, shift, fpst);
+ break;
+ case 1:
+ gen_helper_vfp_sltod(vd, vd, shift, fpst);
+ break;
+ case 2:
+ gen_helper_vfp_uhtod(vd, vd, shift, fpst);
+ break;
+ case 3:
+ gen_helper_vfp_ultod(vd, vd, shift, fpst);
+ break;
+ case 4:
+ gen_helper_vfp_toshd_round_to_zero(vd, vd, shift, fpst);
+ break;
+ case 5:
+ gen_helper_vfp_tosld_round_to_zero(vd, vd, shift, fpst);
+ break;
+ case 6:
+ gen_helper_vfp_touhd_round_to_zero(vd, vd, shift, fpst);
+ break;
+ case 7:
+ gen_helper_vfp_tould_round_to_zero(vd, vd, shift, fpst);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ neon_store_reg64(vd, a->vd);
+ tcg_temp_free_i64(vd);
+ tcg_temp_free_i32(shift);
+ tcg_temp_free_ptr(fpst);
+ return true;
+}
tcg_temp_free_i32(tmp_shift); \
tcg_temp_free_ptr(statusptr); \
}
-VFP_GEN_FIX(tosh, _round_to_zero)
VFP_GEN_FIX(tosl, _round_to_zero)
-VFP_GEN_FIX(touh, _round_to_zero)
VFP_GEN_FIX(toul, _round_to_zero)
-VFP_GEN_FIX(shto, )
VFP_GEN_FIX(slto, )
-VFP_GEN_FIX(uhto, )
VFP_GEN_FIX(ulto, )
#undef VFP_GEN_FIX
return 1;
case 15:
switch (rn) {
- case 0 ... 19:
+ case 0 ... 23:
+ case 28 ... 31:
/* Already handled by decodetree */
return 1;
default:
rd_is_dp = false;
break;
- case 0x14: /* vcvt fp <-> fixed */
- case 0x15:
- case 0x16:
- case 0x17:
- case 0x1c:
- case 0x1d:
- case 0x1e:
- case 0x1f:
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
- return 1;
- }
- /* Immediate frac_bits has same format as SREG_M. */
- rm_is_dp = false;
- break;
-
default:
return 1;
}
/* Load the initial operands. */
if (op == 15) {
switch (rn) {
- case 0x14: /* vcvt fp <-> fixed */
- case 0x15:
- case 0x16:
- case 0x17:
- case 0x1c:
- case 0x1d:
- case 0x1e:
- case 0x1f:
- /* Source and destination the same. */
- gen_mov_F0_vreg(dp, rd);
- break;
default:
/* One source operand. */
gen_mov_F0_vreg(rm_is_dp, rm);
switch (op) {
case 15: /* extension space */
switch (rn) {
- case 20: /* fshto */
- gen_vfp_shto(dp, 16 - rm, 0);
- break;
- case 21: /* fslto */
- gen_vfp_slto(dp, 32 - rm, 0);
- break;
- case 22: /* fuhto */
- gen_vfp_uhto(dp, 16 - rm, 0);
- break;
- case 23: /* fulto */
- gen_vfp_ulto(dp, 32 - rm, 0);
- break;
case 24: /* ftoui */
gen_vfp_toui(dp, 0);
break;
case 27: /* ftosiz */
gen_vfp_tosiz(dp, 0);
break;
- case 28: /* ftosh */
- gen_vfp_tosh(dp, 16 - rm, 0);
- break;
- case 29: /* ftosl */
- gen_vfp_tosl(dp, 32 - rm, 0);
- break;
- case 30: /* ftouh */
- gen_vfp_touh(dp, 16 - rm, 0);
- break;
- case 31: /* ftoul */
- gen_vfp_toul(dp, 32 - rm, 0);
- break;
default: /* undefined */
g_assert_not_reached();
}