@@ -127,6 +127,16 @@ DEF_HELPER_2(vfp_sltod, f64, i64, i32)
DEF_HELPER_2(vfp_uhtod, f64, i64, i32)
DEF_HELPER_2(vfp_ultod, f64, i64, i32)
+DEF_HELPER_1(neon_sitos, f32, i32)
+DEF_HELPER_1(neon_uitos, f32, i32)
+DEF_HELPER_1(neon_tosizs, i32, f32)
+DEF_HELPER_1(neon_touizs, i32, f32)
+
+DEF_HELPER_2(neon_ultos, f32, i32, i32);
+DEF_HELPER_2(neon_sltos, f32, i32, i32);
+DEF_HELPER_2(neon_touls, i32, f32, i32);
+DEF_HELPER_2(neon_tosls, i32, f32, i32);
+
DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env)
DEF_HELPER_2(neon_fcvt_f16_to_f32, f32, i32, env)
@@ -448,14 +448,23 @@ CONV_ITOF(vfp_##name##to##p, fsz, sign, &env->vfp.fp_status) \
CONV_FTOI(vfp_##to##name##p, fsz, sign, &env->vfp.fp_status, ) \
CONV_FTOI(vfp_##to##name##z##p, fsz, sign, &env->vfp.fp_status, _round_to_zero)
+#define NEON_CONVS(name, p, fsz, sign) \
+CONV_ITOF(neon_##name##to##p, fsz, sign, &env->vfp.standard_fp_status) \
+CONV_FTOI(neon_##to##name##z##p, fsz, sign, &env->vfp.standard_fp_status, \
+ _round_to_zero)
+
VFP_CONVS(si, s, 32, )
VFP_CONVS(si, d, 64, )
VFP_CONVS(ui, s, 32, u)
VFP_CONVS(ui, d, 64, u)
+NEON_CONVS(si, s, 32, )
+NEON_CONVS(ui, s, 32, u)
+
#undef CONV_ITOF
#undef CONV_FTOI
#undef VFP_CONVS
+#undef NEON_CONVS
/* VFP3 fixed point conversion. */
#define VFP_CONV_FIX(pfx, name, p, fsz, itype, sign, status) \
@@ -485,4 +494,7 @@ VFP_CONV_FIX(vfp_, sl, s, 32, int32, , &env->vfp.fp_status)
VFP_CONV_FIX(vfp_, uh, s, 32, uint16, u, &env->vfp.fp_status)
VFP_CONV_FIX(vfp_, ul, s, 32, uint32, u, &env->vfp.fp_status)
+VFP_CONV_FIX(neon_, sl, s, 32, int32, , &env->vfp.standard_fp_status)
+VFP_CONV_FIX(neon_, ul, s, 32, uint32, u, &env->vfp.standard_fp_status)
+
#undef VFP_CONV_FIX
@@ -5220,6 +5220,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
}
} else if (op >= 14) {
/* VCVT fixed-point. */
+ TCGv tmp_shift;
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
return 1;
}
@@ -5227,21 +5228,25 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
* hence this 32-shift where the ARM ARM has 64-imm6.
*/
shift = 32 - shift;
+ tmp_shift = tcg_const_i32(shift);
for (pass = 0; pass < (q ? 4 : 2); pass++) {
tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
if (!(op & 1)) {
- if (u)
- gen_vfp_ulto(0, shift);
- else
- gen_vfp_slto(0, shift);
+ if (u) {
+ gen_helper_neon_ultos(cpu_F0s, cpu_F0s, tmp_shift);
+ } else {
+ gen_helper_neon_sltos(cpu_F0s, cpu_F0s, tmp_shift);
+ }
} else {
- if (u)
- gen_vfp_toul(0, shift);
- else
- gen_vfp_tosl(0, shift);
+ if (u) {
+ gen_helper_neon_touls(cpu_F0s, cpu_F0s, tmp_shift);
+ } else {
+ gen_helper_neon_tosls(cpu_F0s, cpu_F0s, tmp_shift);
+ }
}
tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
}
+ tcg_temp_free_i32(tmp_shift);
} else {
return 1;
}
@@ -6051,16 +6056,16 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
break;
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
- gen_vfp_sito(0);
+ gen_helper_neon_sitos(cpu_F0s, cpu_F0s);
break;
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
- gen_vfp_uito(0);
+ gen_helper_neon_uitos(cpu_F0s, cpu_F0s);
break;
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
- gen_vfp_tosiz(0);
+ gen_helper_neon_tosizs(cpu_F0s, cpu_F0s);
break;
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
- gen_vfp_touiz(0);
+ gen_helper_neon_touizs(cpu_F0s, cpu_F0s);
break;
default:
/* Reserved op values were caught by the
Add the Neon-specific float-int conversion helper functions which use the standard FPSCR value rather than the VFP FPSCR. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target-arm/helper.h | 10 ++++++++++ target-arm/op_helper.c | 12 ++++++++++++ target-arm/translate.c | 29 +++++++++++++++++------------ 3 files changed, 39 insertions(+), 12 deletions(-)