@@ -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. */
@@ -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)
With AArch64 VFP can now handle 64bit wide VFP float-int conversions. Add handlers for them. Signed-off-by: Alexander Graf <agraf@suse.de> --- target-arm/helper.c | 40 +++++++++++++++++++++++++--------------- target-arm/helper.h | 8 ++++++++ 2 files changed, 33 insertions(+), 15 deletions(-)