qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location.
@ 2014-01-28 11:22 Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 02/11] target-arm: Add AArch32 FP VRINTA, VRINTN, VRINTP and VRINTM Will Newton
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

This function will be needed for AArch32 ARMv8 support, so move it to
helper.c where it can be used by both targets. Also moves the code out
of line, but as it is quite a large function I don't believe this
should be a significant performance impact.

Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h           |  2 ++
 target-arm/helper.c        | 28 ++++++++++++++++++++++++++++
 target-arm/translate-a64.c | 28 ----------------------------
 3 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 198b6b8..383c582 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -496,6 +496,8 @@ enum arm_fprounding {
     FPROUNDING_ODD
 };
 
+int arm_rmode_to_sf(int rmode);
+
 enum arm_cpu_mode {
   ARM_CPU_MODE_USR = 0x10,
   ARM_CPU_MODE_FIQ = 0x11,
diff --git a/target-arm/helper.c b/target-arm/helper.c
index c708f15..b1541b9 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4418,3 +4418,31 @@ float64 HELPER(rintd)(float64 x, void *fp_status)
 
     return ret;
 }
+
+/* Convert ARM rounding mode to softfloat */
+int arm_rmode_to_sf(int rmode)
+{
+    switch (rmode) {
+    case FPROUNDING_TIEAWAY:
+        rmode = float_round_ties_away;
+        break;
+    case FPROUNDING_ODD:
+        /* FIXME: add support for TIEAWAY and ODD */
+        qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
+                      rmode);
+    case FPROUNDING_TIEEVEN:
+    default:
+        rmode = float_round_nearest_even;
+        break;
+    case FPROUNDING_POSINF:
+        rmode = float_round_up;
+        break;
+    case FPROUNDING_NEGINF:
+        rmode = float_round_down;
+        break;
+    case FPROUNDING_ZERO:
+        rmode = float_round_to_zero;
+        break;
+    }
+    return rmode;
+}
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index cf80c46..8effbe2 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -3186,34 +3186,6 @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
     }
 }
 
-/* Convert ARM rounding mode to softfloat */
-static inline int arm_rmode_to_sf(int rmode)
-{
-    switch (rmode) {
-    case FPROUNDING_TIEAWAY:
-        rmode = float_round_ties_away;
-        break;
-    case FPROUNDING_ODD:
-        /* FIXME: add support for TIEAWAY and ODD */
-        qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
-                      rmode);
-    case FPROUNDING_TIEEVEN:
-    default:
-        rmode = float_round_nearest_even;
-        break;
-    case FPROUNDING_POSINF:
-        rmode = float_round_up;
-        break;
-    case FPROUNDING_NEGINF:
-        rmode = float_round_down;
-        break;
-    case FPROUNDING_ZERO:
-        rmode = float_round_to_zero;
-        break;
-    }
-    return rmode;
-}
-
 static void handle_fp_compare(DisasContext *s, bool is_double,
                               unsigned int rn, unsigned int rm,
                               bool cmp_with_zero, bool signal_all_nans)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 02/11] target-arm: Add AArch32 FP VRINTA, VRINTN, VRINTP and VRINTM
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 03/11] target-arm: Add support for AArch32 FP VRINTR Will Newton
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for AArch32 ARMv8 FP VRINTA, VRINTN, VRINTP and VRINTM
instructions.

Signed-off-by: Will Newton <will.newton@linaro.org>
---
 target-arm/translate.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

Changes in v2:
 - Add comment to fp_decode_rm lookup table

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 8d240e1..2db6812 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2759,6 +2759,56 @@ static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
     return 0;
 }
 
+static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
+                        int rounding)
+{
+    TCGv_ptr fpst = get_fpstatus_ptr(0);
+    TCGv_i32 tcg_rmode;
+
+    tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
+    gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+
+    if (dp) {
+        TCGv_i64 tcg_op;
+        TCGv_i64 tcg_res;
+        tcg_op = tcg_temp_new_i64();
+        tcg_res = tcg_temp_new_i64();
+        tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
+        gen_helper_rintd(tcg_res, tcg_op, fpst);
+        tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
+        tcg_temp_free_i64(tcg_op);
+        tcg_temp_free_i64(tcg_res);
+    } else {
+        TCGv_i32 tcg_op;
+        TCGv_i32 tcg_res;
+        tcg_op = tcg_temp_new_i32();
+        tcg_res = tcg_temp_new_i32();
+        tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
+        gen_helper_rints(tcg_res, tcg_op, fpst);
+        tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
+        tcg_temp_free_i32(tcg_op);
+        tcg_temp_free_i32(tcg_res);
+    }
+
+    gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+    tcg_temp_free_i32(tcg_rmode);
+
+    tcg_temp_free_ptr(fpst);
+    return 0;
+}
+
+
+/* Table for converting the most common AArch32 encoding of
+ * rounding mode to arm_fprounding order (which matches the
+ * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
+ */
+static const uint8_t fp_decode_rm[] = {
+    FPROUNDING_TIEAWAY,
+    FPROUNDING_TIEEVEN,
+    FPROUNDING_POSINF,
+    FPROUNDING_NEGINF,
+};
+
 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
 {
     uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
@@ -2781,6 +2831,10 @@ static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
         return handle_vsel(insn, rd, rn, rm, dp);
     } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
         return handle_vminmaxnm(insn, rd, rn, rm, dp);
+    } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
+        /* VRINTA, VRINTN, VRINTP, VRINTM */
+        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
+        return handle_vrint(insn, rd, rm, dp, rounding);
     }
     return 1;
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 03/11] target-arm: Add support for AArch32 FP VRINTR
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 02/11] target-arm: Add AArch32 FP VRINTA, VRINTN, VRINTP and VRINTM Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 04/11] target-arm: Add support for AArch32 FP VRINTZ Will Newton
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for the AArch32 floating-point VRINTR instruction.

Signed-off-by: Will Newton <will.newton@linaro.org>
---
 target-arm/translate.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

Changes in v2:
 - Move code outside the arms of the if

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 2db6812..2b3157c 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3379,6 +3379,17 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                         gen_vfp_F1_ld0(dp);
                         gen_vfp_cmpe(dp);
                         break;
+                    case 12: /* vrintr */
+                    {
+                        TCGv_ptr fpst = get_fpstatus_ptr(0);
+                        if (dp) {
+                            gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
+                        } else {
+                            gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
+                        }
+                        tcg_temp_free_ptr(fpst);
+                        break;
+                    }
                     case 15: /* single<->double conversion */
                         if (dp)
                             gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 04/11] target-arm: Add support for AArch32 FP VRINTZ
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 02/11] target-arm: Add AArch32 FP VRINTA, VRINTN, VRINTP and VRINTM Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 03/11] target-arm: Add support for AArch32 FP VRINTR Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 05/11] target-arm: Add support for AArch32 FP VRINTX Will Newton
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for the AArch32 floating-point VRINTZ instruction.

Signed-off-by: Will Newton <will.newton@linaro.org>
---
 target-arm/translate.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Changes in v2:
 - Move code outside the arms of the if

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 2b3157c..9afb19f 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3390,6 +3390,22 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                         tcg_temp_free_ptr(fpst);
                         break;
                     }
+                    case 13: /* vrintz */
+                    {
+                        TCGv_ptr fpst = get_fpstatus_ptr(0);
+                        TCGv_i32 tcg_rmode;
+                        tcg_rmode = tcg_const_i32(float_round_to_zero);
+                        gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+                        if (dp) {
+                            gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
+                        } else {
+                            gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
+                        }
+                        gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+                        tcg_temp_free_i32(tcg_rmode);
+                        tcg_temp_free_ptr(fpst);
+                        break;
+                    }
                     case 15: /* single<->double conversion */
                         if (dp)
                             gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 05/11] target-arm: Add support for AArch32 FP VRINTX
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
                   ` (2 preceding siblings ...)
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 04/11] target-arm: Add support for AArch32 FP VRINTZ Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 06/11] target-arm: Add support for AArch32 SIMD VRINTX Will Newton
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for the AArch32 floating-point VRINTX instruction.

Signed-off-by: Will Newton <will.newton@linaro.org>
---
 target-arm/translate.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

Changes in v2:
 - Move code outside the arms of the if

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9afb19f..9eb5b92 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3406,6 +3406,17 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                         tcg_temp_free_ptr(fpst);
                         break;
                     }
+                    case 14: /* vrintx */
+                    {
+                        TCGv_ptr fpst = get_fpstatus_ptr(0);
+                        if (dp) {
+                            gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
+                        } else {
+                            gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
+                        }
+                        tcg_temp_free_ptr(fpst);
+                        break;
+                    }
                     case 15: /* single<->double conversion */
                         if (dp)
                             gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 06/11] target-arm: Add support for AArch32 SIMD VRINTX
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
                   ` (3 preceding siblings ...)
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 05/11] target-arm: Add support for AArch32 FP VRINTX Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 07/11] target-arm: Add set_neon_rmode helper Will Newton
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for the AArch32 Advanced SIMD VRINTX instruction.

Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9eb5b92..c179817 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4709,6 +4709,7 @@ static const uint8_t neon_3r_sizes[] = {
 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
 #define NEON_2RM_VSHLL 38
+#define NEON_2RM_VRINTX 41
 #define NEON_2RM_VCVT_F16_F32 44
 #define NEON_2RM_VCVT_F32_F16 46
 #define NEON_2RM_VRECPE 56
@@ -4724,7 +4725,7 @@ static int neon_2rm_is_float_op(int op)
 {
     /* Return true if this neon 2reg-misc op is float-to-float */
     return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
-            op >= NEON_2RM_VRECPE_F);
+            op == NEON_2RM_VRINTX || op >= NEON_2RM_VRECPE_F);
 }
 
 /* Each entry in this array has bit n set if the insn allows
@@ -4768,6 +4769,7 @@ static const uint8_t neon_2rm_sizes[] = {
     [NEON_2RM_VMOVN] = 0x7,
     [NEON_2RM_VQMOVN] = 0x7,
     [NEON_2RM_VSHLL] = 0x7,
+    [NEON_2RM_VRINTX] = 0x4,
     [NEON_2RM_VCVT_F16_F32] = 0x2,
     [NEON_2RM_VCVT_F32_F16] = 0x2,
     [NEON_2RM_VRECPE] = 0x4,
@@ -6480,6 +6482,13 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             }
                             neon_store_reg(rm, pass, tmp2);
                             break;
+                        case NEON_2RM_VRINTX:
+                        {
+                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
+                            gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
+                            tcg_temp_free_ptr(fpstatus);
+                            break;
+                        }
                         case NEON_2RM_VRECPE:
                             gen_helper_recpe_u32(tmp, tmp, cpu_env);
                             break;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 07/11] target-arm: Add set_neon_rmode helper
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
                   ` (4 preceding siblings ...)
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 06/11] target-arm: Add support for AArch32 SIMD VRINTX Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 08/11] target-arm: Add AArch32 SIMD VRINTA, VRINTN, VRINTP, VRINTM, VRINTZ Will Newton
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

This helper sets the rounding mode in the standard_fp_status word to
allow NEON instructions to modify the rounding mode whilst using the
standard FPSCR values for everything else.

Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 17 +++++++++++++++++
 target-arm/helper.h |  1 +
 2 files changed, 18 insertions(+)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index b1541b9..ca5b000 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4048,6 +4048,23 @@ uint32_t HELPER(set_rmode)(uint32_t rmode, CPUARMState *env)
     return prev_rmode;
 }
 
+/* Set the current fp rounding mode in the standard fp status and return
+ * the old one. This is for NEON instructions that need to change the
+ * rounding mode but wish to use the standard FPSCR values for everything
+ * else. Always set the rounding mode back to the correct value after
+ * modifying it.
+ * The argument is a softfloat float_round_ value.
+ */
+uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env)
+{
+    float_status *fp_status = &env->vfp.standard_fp_status;
+
+    uint32_t prev_rmode = get_float_rounding_mode(fp_status);
+    set_float_rounding_mode(rmode, fp_status);
+
+    return prev_rmode;
+}
+
 /* Half precision conversions.  */
 static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s)
 {
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 70872df..71b8411 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -149,6 +149,7 @@ DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
 DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
 
 DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, env)
+DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
 
 DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
 DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 08/11] target-arm: Add AArch32 SIMD VRINTA, VRINTN, VRINTP, VRINTM, VRINTZ
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
                   ` (5 preceding siblings ...)
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 07/11] target-arm: Add set_neon_rmode helper Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 09/11] target-arm: Add AArch32 FP VCVTA, VCVTN, VCVTP and VCVTM Will Newton
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for the AArch32 Advanced SIMD VRINTA, VRINTN, VRINTP
VRINTM and VRINTZ instructions.

Signed-off-by: Will Newton <will.newton@linaro.org>
---
 target-arm/translate.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

Changes in v2:
 - Merge VRINTZ handling into the same block

diff --git a/target-arm/translate.c b/target-arm/translate.c
index c179817..5a8ca24 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4709,9 +4709,14 @@ static const uint8_t neon_3r_sizes[] = {
 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
 #define NEON_2RM_VSHLL 38
+#define NEON_2RM_VRINTN 40
 #define NEON_2RM_VRINTX 41
+#define NEON_2RM_VRINTA 42
+#define NEON_2RM_VRINTZ 43
 #define NEON_2RM_VCVT_F16_F32 44
+#define NEON_2RM_VRINTM 45
 #define NEON_2RM_VCVT_F32_F16 46
+#define NEON_2RM_VRINTP 47
 #define NEON_2RM_VRECPE 56
 #define NEON_2RM_VRSQRTE 57
 #define NEON_2RM_VRECPE_F 58
@@ -4725,7 +4730,9 @@ static int neon_2rm_is_float_op(int op)
 {
     /* Return true if this neon 2reg-misc op is float-to-float */
     return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
-            op == NEON_2RM_VRINTX || op >= NEON_2RM_VRECPE_F);
+            (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
+            op == NEON_2RM_VRINTM || op == NEON_2RM_VRINTP ||
+            op >= NEON_2RM_VRECPE_F);
 }
 
 /* Each entry in this array has bit n set if the insn allows
@@ -4769,9 +4776,14 @@ static const uint8_t neon_2rm_sizes[] = {
     [NEON_2RM_VMOVN] = 0x7,
     [NEON_2RM_VQMOVN] = 0x7,
     [NEON_2RM_VSHLL] = 0x7,
+    [NEON_2RM_VRINTN] = 0x4,
     [NEON_2RM_VRINTX] = 0x4,
+    [NEON_2RM_VRINTA] = 0x4,
+    [NEON_2RM_VRINTZ] = 0x4,
     [NEON_2RM_VCVT_F16_F32] = 0x2,
+    [NEON_2RM_VRINTM] = 0x4,
     [NEON_2RM_VCVT_F32_F16] = 0x2,
+    [NEON_2RM_VRINTP] = 0x4,
     [NEON_2RM_VRECPE] = 0x4,
     [NEON_2RM_VRSQRTE] = 0x4,
     [NEON_2RM_VRECPE_F] = 0x4,
@@ -6482,6 +6494,32 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             }
                             neon_store_reg(rm, pass, tmp2);
                             break;
+                        case NEON_2RM_VRINTN:
+                        case NEON_2RM_VRINTA:
+                        case NEON_2RM_VRINTM:
+                        case NEON_2RM_VRINTP:
+                        case NEON_2RM_VRINTZ:
+                        {
+                            TCGv_i32 tcg_rmode;
+                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
+                            int rmode;
+
+                            if (op == NEON_2RM_VRINTZ) {
+                                rmode = FPROUNDING_ZERO;
+                            } else {
+                                rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
+                            }
+
+                            tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
+                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
+                                                      cpu_env);
+                            gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
+                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
+                                                      cpu_env);
+                            tcg_temp_free_ptr(fpstatus);
+                            tcg_temp_free_i32(tcg_rmode);
+                            break;
+                        }
                         case NEON_2RM_VRINTX:
                         {
                             TCGv_ptr fpstatus = get_fpstatus_ptr(1);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 09/11] target-arm: Add AArch32 FP VCVTA, VCVTN, VCVTP and VCVTM
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
                   ` (6 preceding siblings ...)
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 08/11] target-arm: Add AArch32 SIMD VRINTA, VRINTN, VRINTP, VRINTM, VRINTZ Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 10/11] target-arm: Add AArch32 SIMD " Will Newton
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for the AArch32 floating-point VCVTA, VCVTN, VCVTP
and VCVTM instructions.

Signed-off-by: Will Newton <will.newton@linaro.org>
---
 target-arm/translate.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 5a8ca24..0fcc159 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2797,6 +2797,63 @@ static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
     return 0;
 }
 
+static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
+                       int rounding)
+{
+    bool is_signed = extract32(insn, 7, 1);
+    TCGv_ptr fpst = get_fpstatus_ptr(0);
+    TCGv_i32 tcg_rmode, tcg_shift;
+
+    tcg_shift = tcg_const_i32(0);
+
+    tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
+    gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+
+    if (dp) {
+        TCGv_i64 tcg_double, tcg_res;
+        TCGv_i32 tcg_tmp;
+        /* Rd is encoded as a single precision register even when the source
+         * is double precision.
+         */
+        rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
+        tcg_double = tcg_temp_new_i64();
+        tcg_res = tcg_temp_new_i64();
+        tcg_tmp = tcg_temp_new_i32();
+        tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
+        if (is_signed) {
+            gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
+        } else {
+            gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
+        }
+        tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
+        tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
+        tcg_temp_free_i32(tcg_tmp);
+        tcg_temp_free_i64(tcg_res);
+        tcg_temp_free_i64(tcg_double);
+    } else {
+        TCGv_i32 tcg_single, tcg_res;
+        tcg_single = tcg_temp_new_i32();
+        tcg_res = tcg_temp_new_i32();
+        tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
+        if (is_signed) {
+            gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
+        } else {
+            gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
+        }
+        tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
+        tcg_temp_free_i32(tcg_res);
+        tcg_temp_free_i32(tcg_single);
+    }
+
+    gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+    tcg_temp_free_i32(tcg_rmode);
+
+    tcg_temp_free_i32(tcg_shift);
+
+    tcg_temp_free_ptr(fpst);
+
+    return 0;
+}
 
 /* Table for converting the most common AArch32 encoding of
  * rounding mode to arm_fprounding order (which matches the
@@ -2835,6 +2892,10 @@ static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
         /* VRINTA, VRINTN, VRINTP, VRINTM */
         int rounding = fp_decode_rm[extract32(insn, 16, 2)];
         return handle_vrint(insn, rd, rm, dp, rounding);
+    } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
+        /* VCVTA, VCVTN, VCVTP, VCVTM */
+        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
+        return handle_vcvt(insn, rd, rm, dp, rounding);
     }
     return 1;
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 10/11] target-arm: Add AArch32 SIMD VCVTA, VCVTN, VCVTP and VCVTM
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
                   ` (7 preceding siblings ...)
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 09/11] target-arm: Add AArch32 FP VCVTA, VCVTN, VCVTP and VCVTM Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 11/11] target-arm: Add support for AArch32 64bit VCVTB and VCVTT Will Newton
  2014-01-28 15:05 ` [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Peter Maydell
  10 siblings, 0 replies; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for the AArch32 Advanced SIMD VCVTA, VCVTN, VCVTP
and VCVTM instructions.

Signed-off-by: Will Newton <will.newton@linaro.org>
---
 target-arm/translate.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0fcc159..e701c0f 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4778,6 +4778,14 @@ static const uint8_t neon_3r_sizes[] = {
 #define NEON_2RM_VRINTM 45
 #define NEON_2RM_VCVT_F32_F16 46
 #define NEON_2RM_VRINTP 47
+#define NEON_2RM_VCVTAU 48
+#define NEON_2RM_VCVTAS 49
+#define NEON_2RM_VCVTNU 50
+#define NEON_2RM_VCVTNS 51
+#define NEON_2RM_VCVTPU 52
+#define NEON_2RM_VCVTPS 53
+#define NEON_2RM_VCVTMU 54
+#define NEON_2RM_VCVTMS 55
 #define NEON_2RM_VRECPE 56
 #define NEON_2RM_VRSQRTE 57
 #define NEON_2RM_VRECPE_F 58
@@ -4792,7 +4800,8 @@ static int neon_2rm_is_float_op(int op)
     /* Return true if this neon 2reg-misc op is float-to-float */
     return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
             (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
-            op == NEON_2RM_VRINTM || op == NEON_2RM_VRINTP ||
+            op == NEON_2RM_VRINTM ||
+            (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
             op >= NEON_2RM_VRECPE_F);
 }
 
@@ -4845,6 +4854,14 @@ static const uint8_t neon_2rm_sizes[] = {
     [NEON_2RM_VRINTM] = 0x4,
     [NEON_2RM_VCVT_F32_F16] = 0x2,
     [NEON_2RM_VRINTP] = 0x4,
+    [NEON_2RM_VCVTAU] = 0x4,
+    [NEON_2RM_VCVTAS] = 0x4,
+    [NEON_2RM_VCVTNU] = 0x4,
+    [NEON_2RM_VCVTNS] = 0x4,
+    [NEON_2RM_VCVTPU] = 0x4,
+    [NEON_2RM_VCVTPS] = 0x4,
+    [NEON_2RM_VCVTMU] = 0x4,
+    [NEON_2RM_VCVTMS] = 0x4,
     [NEON_2RM_VRECPE] = 0x4,
     [NEON_2RM_VRSQRTE] = 0x4,
     [NEON_2RM_VRECPE_F] = 0x4,
@@ -6588,6 +6605,40 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
                             tcg_temp_free_ptr(fpstatus);
                             break;
                         }
+                        case NEON_2RM_VCVTAU:
+                        case NEON_2RM_VCVTAS:
+                        case NEON_2RM_VCVTNU:
+                        case NEON_2RM_VCVTNS:
+                        case NEON_2RM_VCVTPU:
+                        case NEON_2RM_VCVTPS:
+                        case NEON_2RM_VCVTMU:
+                        case NEON_2RM_VCVTMS:
+                        {
+                            bool is_signed = !extract32(insn, 7, 1);
+                            TCGv_ptr fpst = get_fpstatus_ptr(1);
+                            TCGv_i32 tcg_rmode, tcg_shift;
+                            int rmode = fp_decode_rm[extract32(insn, 8, 2)];
+
+                            tcg_shift = tcg_const_i32(0);
+                            tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
+                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
+                                                      cpu_env);
+
+                            if (is_signed) {
+                                gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
+                                                     tcg_shift, fpst);
+                            } else {
+                                gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
+                                                     tcg_shift, fpst);
+                            }
+
+                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
+                                                      cpu_env);
+                            tcg_temp_free_i32(tcg_rmode);
+                            tcg_temp_free_i32(tcg_shift);
+                            tcg_temp_free_ptr(fpst);
+                            break;
+                        }
                         case NEON_2RM_VRECPE:
                             gen_helper_recpe_u32(tmp, tmp, cpu_env);
                             break;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH v2 11/11] target-arm: Add support for AArch32 64bit VCVTB and VCVTT
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
                   ` (8 preceding siblings ...)
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 10/11] target-arm: Add AArch32 SIMD " Will Newton
@ 2014-01-28 11:22 ` Will Newton
  2014-01-28 15:26   ` Peter Maydell
  2014-01-28 15:05 ` [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Peter Maydell
  10 siblings, 1 reply; 13+ messages in thread
From: Will Newton @ 2014-01-28 11:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, patches

Add support for the AArch32 floating-point half-precision to double-
precision conversion VCVTB and VCVTT instructions.

Signed-off-by: Will Newton <will.newton@linaro.org>
---
 target-arm/translate.c | 62 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 48 insertions(+), 14 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index e701c0f..dfda2c4 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3142,14 +3142,16 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                     VFP_DREG_N(rn, insn);
                 }
 
-                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
+                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
+                                 ((rn & 0x1e) == 0x6))) {
                     /* Integer or single precision destination.  */
                     rd = VFP_SREG_D(insn);
                 } else {
                     VFP_DREG_D(rd, insn);
                 }
                 if (op == 15 &&
-                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
+                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
+                     ((rn & 0x1e) == 0x4))) {
                     /* VCVT from int is always from S reg regardless of dp bit.
                      * VCVT with immediate frac_bits has same format as SREG_M
                      */
@@ -3241,12 +3243,19 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                 case 5:
                 case 6:
                 case 7:
-                    /* VCVTB, VCVTT: only present with the halfprec extension,
-                     * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
+                    /* VCVTB, VCVTT: only present with the halfprec extension
+                     * UNPREDICTABLE if bit 8 is set prior to ARMv8
+                     * (we choose to UNDEF)
                      */
-                    if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
+                    if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
+                        !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
                         return 1;
                     }
+                    if ((rn & 0x1e) == 0x4) {
+                        /* Single precision source */
+                        gen_mov_F0_vreg(0, rm);
+                        break;
+                    }
                     /* Otherwise fall through */
                 default:
                     /* One source operand.  */
@@ -3394,21 +3403,39 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                     case 3: /* sqrt */
                         gen_vfp_sqrt(dp);
                         break;
-                    case 4: /* vcvtb.f32.f16 */
+                    case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
                         tmp = gen_vfp_mrs();
                         tcg_gen_ext16u_i32(tmp, tmp);
-                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
+                        if (dp) {
+                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
+                                                           cpu_env);
+                        } else {
+                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
+                                                           cpu_env);
+                        }
                         tcg_temp_free_i32(tmp);
                         break;
-                    case 5: /* vcvtt.f32.f16 */
+                    case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
                         tmp = gen_vfp_mrs();
                         tcg_gen_shri_i32(tmp, tmp, 16);
-                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
+                        if (dp) {
+                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
+                                                           cpu_env);
+                        } else {
+                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
+                                                           cpu_env);
+                        }
                         tcg_temp_free_i32(tmp);
                         break;
-                    case 6: /* vcvtb.f16.f32 */
+                    case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
                         tmp = tcg_temp_new_i32();
-                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
+                        if (dp) {
+                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
+                                                           cpu_env);
+                        } else {
+                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
+                                                           cpu_env);
+                        }
                         gen_mov_F0_vreg(0, rd);
                         tmp2 = gen_vfp_mrs();
                         tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
@@ -3416,9 +3443,15 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                         tcg_temp_free_i32(tmp2);
                         gen_vfp_msr(tmp);
                         break;
-                    case 7: /* vcvtt.f16.f32 */
+                    case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
                         tmp = tcg_temp_new_i32();
-                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
+                        if (dp) {
+                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
+                                                           cpu_env);
+                        } else {
+                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
+                                                           cpu_env);
+                        }
                         tcg_gen_shli_i32(tmp, tmp, 16);
                         gen_mov_F0_vreg(0, rd);
                         tmp2 = gen_vfp_mrs();
@@ -3553,7 +3586,8 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                 /* Write back the result.  */
                 if (op == 15 && (rn >= 8 && rn <= 11))
                     ; /* Comparison, do nothing.  */
-                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
+                else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
+                                            (rn & 0x1e) == 0x6))
                     /* VCVT double to int: always integer result. */
                     gen_mov_vreg_F0(0, rd);
                 else if (op == 15 && rn == 15)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location.
  2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
                   ` (9 preceding siblings ...)
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 11/11] target-arm: Add support for AArch32 64bit VCVTB and VCVTT Will Newton
@ 2014-01-28 15:05 ` Peter Maydell
  10 siblings, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2014-01-28 15:05 UTC (permalink / raw)
  To: Will Newton; +Cc: QEMU Developers, Patch Tracking

On 28 January 2014 11:22, Will Newton <will.newton@linaro.org> wrote:
> This function will be needed for AArch32 ARMv8 support, so move it to
> helper.c where it can be used by both targets. Also moves the code out
> of line, but as it is quite a large function I don't believe this
> should be a significant performance impact

I've reviewed and tested patches 1..10 of this series, and
applied them to target-arm.next. Patch 11 I'm going to make
some review comments on.

PS: please don't forget the cover letter next time you send
a multipatch series.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH v2 11/11] target-arm: Add support for AArch32 64bit VCVTB and VCVTT
  2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 11/11] target-arm: Add support for AArch32 64bit VCVTB and VCVTT Will Newton
@ 2014-01-28 15:26   ` Peter Maydell
  0 siblings, 0 replies; 13+ messages in thread
From: Peter Maydell @ 2014-01-28 15:26 UTC (permalink / raw)
  To: Will Newton; +Cc: QEMU Developers, Patch Tracking

On 28 January 2014 11:22, Will Newton <will.newton@linaro.org> wrote:
> Add support for the AArch32 floating-point half-precision to double-
> precision conversion VCVTB and VCVTT instructions.
>
> Signed-off-by: Will Newton <will.newton@linaro.org>
> ---
>  target-arm/translate.c | 62 ++++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 48 insertions(+), 14 deletions(-)
>
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index e701c0f..dfda2c4 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -3142,14 +3142,16 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                      VFP_DREG_N(rn, insn);
>                  }
>
> -                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
> +                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
> +                                 ((rn & 0x1e) == 0x6))) {
>                      /* Integer or single precision destination.  */
>                      rd = VFP_SREG_D(insn);

You should update the comment here, since the destination
is halfprec in the case you've added.

>                  } else {
>                      VFP_DREG_D(rd, insn);
>                  }
>                  if (op == 15 &&
> -                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
> +                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
> +                     ((rn & 0x1e) == 0x4))) {
>                      /* VCVT from int is always from S reg regardless of dp bit.
>                       * VCVT with immediate frac_bits has same format as SREG_M
>                       */

Again, the comment needs updating since you've added an extra case.

> @@ -3241,12 +3243,19 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                  case 5:
>                  case 6:
>                  case 7:
> -                    /* VCVTB, VCVTT: only present with the halfprec extension,
> -                     * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
> +                    /* VCVTB, VCVTT: only present with the halfprec extension
> +                     * UNPREDICTABLE if bit 8 is set prior to ARMv8
> +                     * (we choose to UNDEF)
>                       */
> -                    if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
> +                    if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
> +                        !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
>                          return 1;
>                      }
> +                    if ((rn & 0x1e) == 0x4) {
> +                        /* Single precision source */
> +                        gen_mov_F0_vreg(0, rm);
> +                        break;
> +                    }

This is confusing, because actually you're using this to catch the
case of a half-precision source. I think it will be clearer to say:

          if (!extract32(rn, 1, 1)) {
              /* Half precision source */
              gen_mov_F0_vreg(0, rm);
              break;
          }

which then catches the half-prec sources for both to-single
and to-double, and leaves just the "source is as per dp flag"
cases to fall through. (We didn't need to catch halfprec sources
separately when we only had 32<->16 since they both get handled
similarly, but now we have the possibility of dp!=0 it's clearer
to handle them explicitly.

>                      /* Otherwise fall through */
>                  default:
>                      /* One source operand.  */
> @@ -3394,21 +3403,39 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                      case 3: /* sqrt */
>                          gen_vfp_sqrt(dp);
>                          break;
> -                    case 4: /* vcvtb.f32.f16 */
> +                    case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
>                          tmp = gen_vfp_mrs();
>                          tcg_gen_ext16u_i32(tmp, tmp);
> -                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
> +                        if (dp) {
> +                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
> +                                                           cpu_env);
> +                        } else {
> +                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
> +                                                           cpu_env);
> +                        }
>                          tcg_temp_free_i32(tmp);
>                          break;
> -                    case 5: /* vcvtt.f32.f16 */
> +                    case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
>                          tmp = gen_vfp_mrs();
>                          tcg_gen_shri_i32(tmp, tmp, 16);
> -                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
> +                        if (dp) {
> +                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
> +                                                           cpu_env);
> +                        } else {
> +                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
> +                                                           cpu_env);
> +                        }
>                          tcg_temp_free_i32(tmp);
>                          break;
> -                    case 6: /* vcvtb.f16.f32 */
> +                    case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
>                          tmp = tcg_temp_new_i32();
> -                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
> +                        if (dp) {
> +                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
> +                                                           cpu_env);
> +                        } else {
> +                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
> +                                                           cpu_env);
> +                        }
>                          gen_mov_F0_vreg(0, rd);
>                          tmp2 = gen_vfp_mrs();
>                          tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
> @@ -3416,9 +3443,15 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                          tcg_temp_free_i32(tmp2);
>                          gen_vfp_msr(tmp);
>                          break;
> -                    case 7: /* vcvtt.f16.f32 */
> +                    case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
>                          tmp = tcg_temp_new_i32();
> -                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
> +                        if (dp) {
> +                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
> +                                                           cpu_env);
> +                        } else {
> +                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
> +                                                           cpu_env);
> +                        }
>                          tcg_gen_shli_i32(tmp, tmp, 16);
>                          gen_mov_F0_vreg(0, rd);
>                          tmp2 = gen_vfp_mrs();
> @@ -3553,7 +3586,8 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
>                  /* Write back the result.  */
>                  if (op == 15 && (rn >= 8 && rn <= 11))
>                      ; /* Comparison, do nothing.  */
> -                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
> +                else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
> +                                            (rn & 0x1e) == 0x6))
>                      /* VCVT double to int: always integer result. */
>                      gen_mov_vreg_F0(0, rd);
>                  else if (op == 15 && rn == 15)

Again, you need to update the comment because you've added a case.

Incidentally, my testing of this patch revealed a bug in
the softfloat float<->float conversion functions: if the
input is a NaN with the sign bit set and the top N bits of the
mantissa clear (where N is the number of mantissa bits in the
destination fp format), then we will incorrectly return a NaN
with sign bit clear and topmost mantissa bit only set, whereas
the ARM ARM demands that the signbit be the same as the input.
This is because the softfloat code for handling "what does an
input NaN get turned into for float/float conversion" (ie the
float*ToCommonNaN and commonNaNToFloat* functions) don't do
what the ARM ARM specifies; they should probably be specifiable
by the target architecture. At the moment we try to work around
this by always calling float*_maybe_silence_nan() after the
conversion, but this turns out to be not sufficient to fix up
the semantics...

thanks
-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-01-28 15:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-28 11:22 [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 02/11] target-arm: Add AArch32 FP VRINTA, VRINTN, VRINTP and VRINTM Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 03/11] target-arm: Add support for AArch32 FP VRINTR Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 04/11] target-arm: Add support for AArch32 FP VRINTZ Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 05/11] target-arm: Add support for AArch32 FP VRINTX Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 06/11] target-arm: Add support for AArch32 SIMD VRINTX Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 07/11] target-arm: Add set_neon_rmode helper Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 08/11] target-arm: Add AArch32 SIMD VRINTA, VRINTN, VRINTP, VRINTM, VRINTZ Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 09/11] target-arm: Add AArch32 FP VCVTA, VCVTN, VCVTP and VCVTM Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 10/11] target-arm: Add AArch32 SIMD " Will Newton
2014-01-28 11:22 ` [Qemu-devel] [PATCH v2 11/11] target-arm: Add support for AArch32 64bit VCVTB and VCVTT Will Newton
2014-01-28 15:26   ` Peter Maydell
2014-01-28 15:05 ` [Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).