With AArch64 VFP can now handle 64bit wide VFP float-int conversions. Add handlers for them.
Signed-off-by: Alexander Graf <ag...@suse.de> --- target-arm/helper.c | 40 +++++++++++++++++++++++++--------------- target-arm/helper.h | 8 ++++++++ 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index 2b031a8..7bf32b8 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3698,36 +3698,46 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env) } /* VFP3 fixed point conversion. */ -#define VFP_CONV_FIX(name, p, fsz, itype, sign) \ -float##fsz HELPER(vfp_##name##to##p)(uint##fsz##_t x, uint32_t shift, \ +#define VFP_CONV_FIX(name, p, fsz, isz, itype, sign) \ +float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ void *fpstp) \ { \ float_status *fpst = fpstp; \ float##fsz tmp; \ - tmp = sign##int32_to_##float##fsz((itype##_t)x, fpst); \ + tmp = sign##int##isz##_to_##float##fsz((itype##_t)x, fpst); \ return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ } \ -uint##fsz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \ +uint##isz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \ void *fpstp) \ { \ float_status *fpst = fpstp; \ float##fsz tmp; \ + uint##isz##_t r; \ if (float##fsz##_is_any_nan(x)) { \ float_raise(float_flag_invalid, fpst); \ return 0; \ } \ tmp = float##fsz##_scalbn(x, shift, fpst); \ - return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \ -} - -VFP_CONV_FIX(sh, d, 64, int16, ) -VFP_CONV_FIX(sl, d, 64, int32, ) -VFP_CONV_FIX(uh, d, 64, uint16, u) -VFP_CONV_FIX(ul, d, 64, uint32, u) -VFP_CONV_FIX(sh, s, 32, int16, ) -VFP_CONV_FIX(sl, s, 32, int32, ) -VFP_CONV_FIX(uh, s, 32, uint16, u) -VFP_CONV_FIX(ul, s, 32, uint32, u) + if (((float_status*)fpstp)->float_rounding_mode == float_round_to_zero) { \ + r = float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \ + } else { \ + r = float##fsz##_to_##itype(tmp, fpst); \ + } \ + return r; \ +} + +VFP_CONV_FIX(sh, d, 64, 64, int16, ) +VFP_CONV_FIX(sl, d, 64, 64, int32, ) +VFP_CONV_FIX(sq, d, 64, 64, int64, ) +VFP_CONV_FIX(uh, d, 64, 64, uint16, u) +VFP_CONV_FIX(ul, d, 64, 64, uint32, u) +VFP_CONV_FIX(uq, d, 64, 64, uint64, u) +VFP_CONV_FIX(sh, s, 32, 32, int16, ) +VFP_CONV_FIX(sl, s, 32, 32, int32, ) +VFP_CONV_FIX(sq, s, 32, 64, int64, ) +VFP_CONV_FIX(uh, s, 32, 32, uint16, u) +VFP_CONV_FIX(ul, s, 32, 32, uint32, u) +VFP_CONV_FIX(uq, s, 32, 64, int64, u) #undef VFP_CONV_FIX /* Half precision conversions. */ diff --git a/target-arm/helper.h b/target-arm/helper.h index e66362a..2caa219 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -113,20 +113,28 @@ DEF_HELPER_2(vfp_tosizd, i32, f64, ptr) DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr) DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr) DEF_HELPER_3(vfp_touhs, i32, f32, i32, ptr) DEF_HELPER_3(vfp_touls, i32, f32, i32, ptr) +DEF_HELPER_3(vfp_touqs, i64, f32, i32, ptr) DEF_HELPER_3(vfp_toshd, i64, f64, i32, ptr) DEF_HELPER_3(vfp_tosld, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_tosqd, i64, f64, i32, ptr) DEF_HELPER_3(vfp_touhd, i64, f64, i32, ptr) DEF_HELPER_3(vfp_tould, i64, f64, i32, ptr) +DEF_HELPER_3(vfp_touqd, i64, f64, i32, ptr) DEF_HELPER_3(vfp_shtos, f32, i32, i32, ptr) DEF_HELPER_3(vfp_sltos, f32, i32, i32, ptr) +DEF_HELPER_3(vfp_sqtos, f32, i64, i32, ptr) DEF_HELPER_3(vfp_uhtos, f32, i32, i32, ptr) DEF_HELPER_3(vfp_ultos, f32, i32, i32, ptr) +DEF_HELPER_3(vfp_uqtos, f32, i64, i32, ptr) DEF_HELPER_3(vfp_shtod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_sltod, f64, i64, i32, ptr) +DEF_HELPER_3(vfp_sqtod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr) +DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr) DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env) DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env) -- 1.7.12.4