From 40cfacdd806b68706b10ceeeca6d0eea417d1a75 Mon Sep 17 00:00:00 2001 From: Will Newton Date: Fri, 6 Dec 2013 17:01:41 +0000 Subject: target-arm: Implement ARMv8 FP VMAXNM and VMINNM instructions. This adds support for the ARMv8 floating point VMAXNM and VMINNM instructions. Signed-off-by: Will Newton Reviewed-by: Peter Maydell Message-id: 1386158099-9239-6-git-send-email-will.newton@linaro.org Signed-off-by: Peter Maydell --- target-arm/translate.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'target-arm/translate.c') diff --git a/target-arm/translate.c b/target-arm/translate.c index 0a22ad8e1c..9a8069ee3a 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -2723,6 +2723,54 @@ static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm, return 0; } +static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn, + uint32_t rm, uint32_t dp) +{ + uint32_t vmin = extract32(insn, 6, 1); + TCGv_ptr fpst = get_fpstatus_ptr(0); + + if (dp) { + TCGv_i64 frn, frm, dest; + + frn = tcg_temp_new_i64(); + frm = tcg_temp_new_i64(); + dest = tcg_temp_new_i64(); + + tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn)); + tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm)); + if (vmin) { + gen_helper_vfp_minnmd(dest, frn, frm, fpst); + } else { + gen_helper_vfp_maxnmd(dest, frn, frm, fpst); + } + tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd)); + tcg_temp_free_i64(frn); + tcg_temp_free_i64(frm); + tcg_temp_free_i64(dest); + } else { + TCGv_i32 frn, frm, dest; + + frn = tcg_temp_new_i32(); + frm = tcg_temp_new_i32(); + dest = tcg_temp_new_i32(); + + tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn)); + tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm)); + if (vmin) { + gen_helper_vfp_minnms(dest, frn, frm, fpst); + } else { + gen_helper_vfp_maxnms(dest, frn, frm, fpst); + } + tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd)); + tcg_temp_free_i32(frn); + tcg_temp_free_i32(frm); + tcg_temp_free_i32(dest); + } + + tcg_temp_free_ptr(fpst); + return 0; +} + static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn) { uint32_t rd, rn, rm, dp = extract32(insn, 8, 1); @@ -2743,6 +2791,8 @@ static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn) if ((insn & 0x0f800e50) == 0x0e000a00) { return handle_vsel(insn, rd, rn, rm, dp); + } else if ((insn & 0x0fb00e10) == 0x0e800a00) { + return handle_vminmaxnm(insn, rd, rn, rm, dp); } return 1; } -- cgit v1.2.1