qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Will Newton <will.newton@linaro.org>
To: qemu-devel@nongnu.org
Cc: patches@linaro.org
Subject: [Qemu-devel] [PATCH] target-arm: Implement ARMv8 VSEL instruction.
Date: Thu, 03 Oct 2013 10:58:07 +0100	[thread overview]
Message-ID: <524D3FAF.7020701@linaro.org> (raw)


This adds support for the VSEL floating point selection instruction
which was added in ARMv8. It is based on the previous patch[1] from
Mans Rullgard, but attempts to addres the feedback given on that patch.

[1] http://lists.nongnu.org/archive/html/qemu-devel/2013-06/msg03117.html

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

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 998bde2..7bfd606 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2617,6 +2617,114 @@ static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
     return tmp;
 }

+static int disas_v8vfp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
+{
+    uint32_t rd, rn, rm, dp = (insn >> 8) & 1;
+
+    if (!s->vfp_enabled)
+      return 1;
+
+    if (dp) {
+        VFP_DREG_D(rd, insn);
+        VFP_DREG_N(rn, insn);
+        VFP_DREG_M(rm, insn);
+    } else {
+        rd = VFP_SREG_D(insn);
+        rn = VFP_SREG_N(insn);
+        rm = VFP_SREG_M(insn);
+    }
+
+    if (((insn >> 23) & 1) == 0) {
+        /* vsel */
+        uint32_t cc = (insn >> 20) & 3;
+	TCGv_i32 tmp, zero;
+
+	zero = tcg_const_tl(0);
+
+	if (dp) {
+	    TCGv_i64 ftmp1, ftmp2, ftmp3;
+
+	    ftmp1 = tcg_temp_new_i64();
+	    ftmp2 = tcg_temp_new_i64();
+	    ftmp3 = tcg_temp_new_i64();
+	    tcg_gen_ld_f64(ftmp1, cpu_env, vfp_reg_offset(dp, rn));
+	    tcg_gen_ld_f64(ftmp2, cpu_env, vfp_reg_offset(dp, rm));
+	    switch (cc) {
+	    case 0: /* eq: Z */
+		tcg_gen_movcond_i64(TCG_COND_EQ, ftmp3, cpu_ZF, zero,
+				    ftmp1, ftmp2);
+		break;
+	    case 1: /* vs: V */
+		tcg_gen_movcond_i64(TCG_COND_LT, ftmp3, cpu_VF, zero,
+				    ftmp1, ftmp2);
+		break;
+	    case 2: /* ge: N == V -> N ^ V == 0 */
+		tmp = tcg_temp_new_i32();
+		tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
+		tcg_gen_movcond_i64(TCG_COND_GE, ftmp3, tmp, zero,
+				    ftmp1, ftmp2);
+		tcg_temp_free_i32(tmp);
+		break;
+	    case 3: /* gt: !Z && N == V */
+		tcg_gen_movcond_i64(TCG_COND_NE, ftmp3, cpu_ZF, zero,
+				    ftmp1, ftmp2);
+		tmp = tcg_temp_new_i32();
+		tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
+		tcg_gen_movcond_i64(TCG_COND_GE, ftmp3, tmp, zero,
+				    ftmp3, ftmp2);
+		tcg_temp_free_i32(tmp);
+		break;
+	    }
+	    tcg_gen_st_f64(ftmp3, cpu_env, vfp_reg_offset(dp, rd));
+	    tcg_temp_free_i64(ftmp1);
+	    tcg_temp_free_i64(ftmp2);
+	    tcg_temp_free_i64(ftmp3);
+	} else {
+	    TCGv_i32 ftmp1, ftmp2, ftmp3;
+
+	    ftmp1 = tcg_temp_new_i32();
+	    ftmp2 = tcg_temp_new_i32();
+	    ftmp3 = tcg_temp_new_i32();
+	    tcg_gen_ld_f32(ftmp1, cpu_env, vfp_reg_offset(dp, rn));
+	    tcg_gen_ld_f32(ftmp2, cpu_env, vfp_reg_offset(dp, rm));
+	    switch (cc) {
+	    case 0: /* eq: Z */
+		tcg_gen_movcond_i32(TCG_COND_EQ, ftmp3, cpu_ZF, zero,
+				    ftmp1, ftmp2);
+		break;
+	    case 1: /* vs: V */
+		tcg_gen_movcond_i32(TCG_COND_LT, ftmp3, cpu_VF, zero,
+				    ftmp1, ftmp2);
+		break;
+	    case 2: /* ge: N == V -> N ^ V == 0 */
+		tmp = tcg_temp_new_i32();
+		tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
+		tcg_gen_movcond_i32(TCG_COND_GE, ftmp3, tmp, zero,
+				    ftmp1, ftmp2);
+		tcg_temp_free_i32(tmp);
+		break;
+	    case 3: /* gt: !Z && N == V */
+		tcg_gen_movcond_i32(TCG_COND_NE, ftmp3, cpu_ZF, zero,
+				    ftmp1, ftmp2);
+		tmp = tcg_temp_new_i32();
+		tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
+		tcg_gen_movcond_i32(TCG_COND_GE, ftmp3, tmp, zero,
+				    ftmp3, ftmp2);
+		tcg_temp_free_i32(tmp);
+		break;
+	    }
+	    tcg_gen_st_f32(ftmp3, cpu_env, vfp_reg_offset(dp, rd));
+	    tcg_temp_free_i32(ftmp1);
+	    tcg_temp_free_i32(ftmp2);
+	    tcg_temp_free_i32(ftmp3);
+	}
+
+        return 0;
+    }
+
+    return 1;
+}
+
 /* Disassemble a VFP instruction.  Returns nonzero if an error occurred
    (ie. an undefined instruction).  */
 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
@@ -6756,6 +6864,13 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
                 goto illegal_op;
             return;
         }
+	if ((insn & 0x0f800e50) == 0x0e000a00) {
+	    /* ARMv8 VFP.  */
+	    ARCH(8);
+
+	    if (disas_v8vfp_insn(env, s, insn))
+		goto illegal_op;
+	}
         if (((insn & 0x0f30f000) == 0x0510f000) ||
             ((insn & 0x0f30f010) == 0x0710f000)) {
             if ((insn & (1 << 22)) == 0) {
@@ -8768,6 +8883,12 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
             insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
             if (disas_neon_data_insn(env, s, insn))
                 goto illegal_op;
+	} else if ((insn & 0x0f800e50) == 0x0e000a00) {
+	    /* ARMv8 VFP.  */
+	    ARCH(8);
+
+	    if (disas_v8vfp_insn(env, s, insn))
+		goto illegal_op;
         } else {
             if (insn & (1 << 28))
                 goto illegal_op;
-- 
1.8.1.4

             reply	other threads:[~2013-10-03  9:58 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-03  9:58 Will Newton [this message]
2013-10-03 11:31 ` [Qemu-devel] [PATCH] target-arm: Implement ARMv8 VSEL instruction Alex Bennée
2013-10-03 12:11   ` Peter Maydell
  -- strict thread matches above, loose matches on Subject: below --
2013-06-18 14:30 [Qemu-devel] [PATCH] target-arm: implement " Mans Rullgard
2013-06-20 19:23 ` Peter Maydell
2013-06-20 23:25   ` Måns Rullgård
2013-07-02 12:56     ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=524D3FAF.7020701@linaro.org \
    --to=will.newton@linaro.org \
    --cc=patches@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).