target/arm: Implement VFP fp16 VCVT between float and fixed-point

Implement the fp16 versions of the VFP VCVT instruction forms which
convert between floating point and fixed-point.

Backports a149e2de0b63e3906729ed1d3df7d9ecdb6de5e6
This commit is contained in:
Peter Maydell 2021-02-28 05:15:38 -05:00 committed by Lioncash
parent 9c5b6f06a2
commit 74a6af4e23
2 changed files with 62 additions and 0 deletions

View file

@ -3023,6 +3023,66 @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
return true;
}
static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
{
TCGv_i32 vd, shift;
TCGv_ptr fpst;
int frac_bits;
TCGContext *tcg_ctx = s->uc->tcg_ctx;
if (!dc_isar_feature(aa32_fp16_arith, s)) {
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(tcg_ctx);
neon_load_reg32(s, vd, a->vd);
fpst = fpstatus_ptr(tcg_ctx, FPST_FPCR_F16);
shift = tcg_const_i32(tcg_ctx, frac_bits);
/* Switch on op:U:sx bits */
switch (a->opc) {
case 0:
gen_helper_vfp_shtoh(tcg_ctx, vd, vd, shift, fpst);
break;
case 1:
gen_helper_vfp_sltoh(tcg_ctx, vd, vd, shift, fpst);
break;
case 2:
gen_helper_vfp_uhtoh(tcg_ctx, vd, vd, shift, fpst);
break;
case 3:
gen_helper_vfp_ultoh(tcg_ctx, vd, vd, shift, fpst);
break;
case 4:
gen_helper_vfp_toshh_round_to_zero(tcg_ctx, vd, vd, shift, fpst);
break;
case 5:
gen_helper_vfp_toslh_round_to_zero(tcg_ctx, vd, vd, shift, fpst);
break;
case 6:
gen_helper_vfp_touhh_round_to_zero(tcg_ctx, vd, vd, shift, fpst);
break;
case 7:
gen_helper_vfp_toulh_round_to_zero(tcg_ctx, vd, vd, shift, fpst);
break;
default:
g_assert_not_reached();
}
neon_store_reg32(s, vd, a->vd);
tcg_temp_free_i32(tcg_ctx, vd);
tcg_temp_free_i32(tcg_ctx, shift);
tcg_temp_free_ptr(tcg_ctx, fpst);
return true;
}
static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;

View file

@ -225,6 +225,8 @@ VJCVT ---- 1110 1.11 1001 .... 1011 11.0 .... @vfp_dm_sd
# We assemble bits 18 (op), 16 (u) and 7 (sx) into a single opc field
# for the convenience of the trans_VCVT_fix functions.
%vcvt_fix_op 18:1 16:1 7:1
VCVT_fix_hp ---- 1110 1.11 1.1. .... 1001 .1.0 .... \
vd=%vd_sp imm=%vm_sp opc=%vcvt_fix_op
VCVT_fix_sp ---- 1110 1.11 1.1. .... 1010 .1.0 .... \
vd=%vd_sp imm=%vm_sp opc=%vcvt_fix_op
VCVT_fix_dp ---- 1110 1.11 1.1. .... 1011 .1.0 .... \