mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 07:55:28 +00:00
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:
parent
9c5b6f06a2
commit
74a6af4e23
|
@ -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;
|
||||
|
|
|
@ -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 .... \
|
||||
|
|
Loading…
Reference in a new issue