From: Peter Maydell <peter.maydell@linaro.org>
To: Anthony Liguori <aliguori@amazon.com>
Cc: Blue Swirl <blauwirbel@gmail.com>,
qemu-devel@nongnu.org, Aurelien Jarno <aurelien@aurel32.net>
Subject: [Qemu-devel] [PULL 31/37] target-arm: Implement ARMv8 VSEL instruction.
Date: Tue, 10 Dec 2013 14:43:27 +0000 [thread overview]
Message-ID: <1386686613-2390-32-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1386686613-2390-1-git-send-email-peter.maydell@linaro.org>
From: Will Newton <will.newton@linaro.org>
This adds support for the VSEL floating point selection instruction
which was added in ARMv8.
Signed-off-by: Will Newton <will.newton@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1386158099-9239-3-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/translate.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 134 insertions(+), 1 deletion(-)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f63e89d..0a22ad8 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2614,6 +2614,139 @@ static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
return tmp;
}
+static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
+ uint32_t dp)
+{
+ uint32_t cc = extract32(insn, 20, 2);
+
+ if (dp) {
+ TCGv_i64 frn, frm, dest;
+ TCGv_i64 tmp, zero, zf, nf, vf;
+
+ zero = tcg_const_i64(0);
+
+ frn = tcg_temp_new_i64();
+ frm = tcg_temp_new_i64();
+ dest = tcg_temp_new_i64();
+
+ zf = tcg_temp_new_i64();
+ nf = tcg_temp_new_i64();
+ vf = tcg_temp_new_i64();
+
+ tcg_gen_extu_i32_i64(zf, cpu_ZF);
+ tcg_gen_ext_i32_i64(nf, cpu_NF);
+ tcg_gen_ext_i32_i64(vf, cpu_VF);
+
+ tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
+ tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
+ switch (cc) {
+ case 0: /* eq: Z */
+ tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
+ frn, frm);
+ break;
+ case 1: /* vs: V */
+ tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
+ frn, frm);
+ break;
+ case 2: /* ge: N == V -> N ^ V == 0 */
+ tmp = tcg_temp_new_i64();
+ tcg_gen_xor_i64(tmp, vf, nf);
+ tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
+ frn, frm);
+ tcg_temp_free_i64(tmp);
+ break;
+ case 3: /* gt: !Z && N == V */
+ tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
+ frn, frm);
+ tmp = tcg_temp_new_i64();
+ tcg_gen_xor_i64(tmp, vf, nf);
+ tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
+ dest, frm);
+ tcg_temp_free_i64(tmp);
+ break;
+ }
+ 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);
+
+ tcg_temp_free_i64(zf);
+ tcg_temp_free_i64(nf);
+ tcg_temp_free_i64(vf);
+
+ tcg_temp_free_i64(zero);
+ } else {
+ TCGv_i32 frn, frm, dest;
+ TCGv_i32 tmp, zero;
+
+ zero = tcg_const_i32(0);
+
+ 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));
+ switch (cc) {
+ case 0: /* eq: Z */
+ tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
+ frn, frm);
+ break;
+ case 1: /* vs: V */
+ tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
+ frn, frm);
+ 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, dest, tmp, zero,
+ frn, frm);
+ tcg_temp_free_i32(tmp);
+ break;
+ case 3: /* gt: !Z && N == V */
+ tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
+ frn, frm);
+ tmp = tcg_temp_new_i32();
+ tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
+ tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
+ dest, frm);
+ tcg_temp_free_i32(tmp);
+ break;
+ }
+ 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_i32(zero);
+ }
+
+ 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);
+
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
+ 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 & 0x0f800e50) == 0x0e000a00) {
+ return handle_vsel(insn, rd, rn, rm, dp);
+ }
+ 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)
@@ -2641,7 +2774,7 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
/* Encodings with T=1 (Thumb) or unconditional (ARM):
* only used in v8 and above.
*/
- return 1;
+ return disas_vfp_v8_insn(env, s, insn);
}
dp = ((insn & 0xf00) == 0xb00);
--
1.8.5
next prev parent reply other threads:[~2013-12-10 14:43 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-10 14:42 [Qemu-devel] [PULL 00/37] target-arm queue Peter Maydell
2013-12-10 14:42 ` [Qemu-devel] [PULL 01/37] integrator/cp: add support for REFCNT register Peter Maydell
2013-12-10 14:42 ` [Qemu-devel] [PULL 02/37] cpu/a9mpcore: rename timerbusdev variable Peter Maydell
2013-12-10 14:42 ` [Qemu-devel] [PULL 03/37] cpu/a9mpcore: reorder operations/declarations Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 04/37] hw/timer: Introduce ARM A9 Global Timer Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 05/37] cpu/a9mpcore: Add " Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 06/37] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 07/37] device_tree.c: Terminate the empty reservemap in create_device_tree() Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 08/37] hw/arm/boot: Allow boards to provide an fdt blob Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 09/37] target-arm: Provide PSCI constants to generic QEMU code Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 10/37] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 11/37] target-arm: Allow secondary KVM CPUs to be booted via PSCI Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 12/37] hw/arm: Add 'virt' platform Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 13/37] target-arm: Don't hardcode KVM target CPU to be A15 Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 14/37] target-arm: Provide '-cpu host' when running KVM Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 15/37] hw/arm/virt: Support -cpu host Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 16/37] net/cadence_gem: Implement mac level loopback mode Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 17/37] net/cadence_gem: Update DMA rx descriptors as we process them Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 18/37] net/cadence_gem: Don't assert against 0 buffer address Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 19/37] net/cadence_gem: simplify rx buf descriptor walking Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 20/37] net/cadence_gem: Prefetch rx descriptors ASAP Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 21/37] net/cadence_gem: Implement RX descriptor match mode flags Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 22/37] net/cadence_gem: Implement SAR match bit in rx desc Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 23/37] net/cadence_gem: Implement SAR (de)activation Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 24/37] net/cadence_gem: Add missing VMSTATE_END_OF_LIST Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 25/37] net/cadence_gem: Fix rx multi-fragment packets Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 26/37] net/cadence_gem: Fix small packet FCS stripping Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 27/37] net/cadence_gem: Fix register w1c logic Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 28/37] net/cadence_gem: Improve can_receive debug printfery Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 29/37] net/cadence_gem: Don't rx packets when no rx buffer available Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 30/37] target-arm: Move call to disas_vfp_insn out of disas_coproc_insn Peter Maydell
2013-12-10 14:43 ` Peter Maydell [this message]
2013-12-10 14:43 ` [Qemu-devel] [PULL 32/37] softfloat: Remove unused argument from MINMAX macro Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 33/37] softfloat: Add minNum() and maxNum() functions to softfloat Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 34/37] target-arm: Implement ARMv8 FP VMAXNM and VMINNM instructions Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 35/37] target-arm: Implement ARMv8 SIMD " Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 36/37] target-arm: Use new qemu_ld/st opcodes Peter Maydell
2013-12-10 14:43 ` [Qemu-devel] [PULL 37/37] target-arm: fix TTBCR write masking 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=1386686613-2390-32-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=aliguori@amazon.com \
--cc=aurelien@aurel32.net \
--cc=blauwirbel@gmail.com \
--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).