[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 27/38] target-arm: A64: Add SIMD scalar 3 same add, s
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 27/38] target-arm: A64: Add SIMD scalar 3 same add, sub and compare ops |
Date: |
Wed, 29 Jan 2014 13:39:54 +0000 |
Implement the add, sub and compare ops from the SIMD "scalar three same"
group.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
---
target-arm/translate-a64.c | 131 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 130 insertions(+), 1 deletion(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index e098efd..f0ebbb5 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -5503,6 +5503,58 @@ static void
disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
unsupported_encoding(s, insn);
}
+static void handle_3same_64(DisasContext *s, int opcode, bool u,
+ TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 tcg_rm)
+{
+ /* Handle 64x64->64 opcodes which are shared between the scalar
+ * and vector 3-same groups. We cover every opcode where size == 3
+ * is valid in either the three-reg-same (integer, not pairwise)
+ * or scalar-three-reg-same groups. (Some opcodes are not yet
+ * implemented.)
+ */
+ TCGCond cond;
+
+ switch (opcode) {
+ case 0x6: /* CMGT, CMHI */
+ /* 64 bit integer comparison, result = test ? (2^64 - 1) : 0.
+ * We implement this using setcond (test) and then negating.
+ */
+ cond = u ? TCG_COND_GTU : TCG_COND_GT;
+ do_cmop:
+ tcg_gen_setcond_i64(cond, tcg_rd, tcg_rn, tcg_rm);
+ tcg_gen_neg_i64(tcg_rd, tcg_rd);
+ break;
+ case 0x7: /* CMGE, CMHS */
+ cond = u ? TCG_COND_GEU : TCG_COND_GE;
+ goto do_cmop;
+ case 0x11: /* CMTST, CMEQ */
+ if (u) {
+ cond = TCG_COND_EQ;
+ goto do_cmop;
+ }
+ /* CMTST : test is "if (X & Y != 0)". */
+ tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm);
+ tcg_gen_setcondi_i64(TCG_COND_NE, tcg_rd, tcg_rd, 0);
+ tcg_gen_neg_i64(tcg_rd, tcg_rd);
+ break;
+ case 0x10: /* ADD, SUB */
+ if (u) {
+ tcg_gen_sub_i64(tcg_rd, tcg_rn, tcg_rm);
+ } else {
+ tcg_gen_add_i64(tcg_rd, tcg_rn, tcg_rm);
+ }
+ break;
+ case 0x1: /* SQADD */
+ case 0x5: /* SQSUB */
+ case 0x8: /* SSHL, USHL */
+ case 0x9: /* SQSHL, UQSHL */
+ case 0xa: /* SRSHL, URSHL */
+ case 0xb: /* SQRSHL, UQRSHL */
+ default:
+ g_assert_not_reached();
+ }
+}
+
/* C3.6.11 AdvSIMD scalar three same
* 31 30 29 28 24 23 22 21 20 16 15 11 10 9 5 4 0
* +-----+---+-----------+------+---+------+--------+---+------+------+
@@ -5511,7 +5563,84 @@ static void
disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
*/
static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
{
- unsupported_encoding(s, insn);
+ int rd = extract32(insn, 0, 5);
+ int rn = extract32(insn, 5, 5);
+ int opcode = extract32(insn, 11, 5);
+ int rm = extract32(insn, 16, 5);
+ int size = extract32(insn, 22, 2);
+ bool u = extract32(insn, 29, 1);
+ TCGv_i64 tcg_rn;
+ TCGv_i64 tcg_rm;
+ TCGv_i64 tcg_rd;
+
+ if (opcode >= 0x18) {
+ /* Floating point: U, size[1] and opcode indicate operation */
+ int fpopcode = opcode | (extract32(size, 1, 1) << 5) | (u << 6);
+ switch (fpopcode) {
+ case 0x1b: /* FMULX */
+ case 0x1c: /* FCMEQ */
+ case 0x1f: /* FRECPS */
+ case 0x3f: /* FRSQRTS */
+ case 0x5c: /* FCMGE */
+ case 0x5d: /* FACGE */
+ case 0x7a: /* FABD */
+ case 0x7c: /* FCMGT */
+ case 0x7d: /* FACGT */
+ unsupported_encoding(s, insn);
+ return;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+ }
+
+ switch (opcode) {
+ case 0x1: /* SQADD, UQADD */
+ case 0x5: /* SQSUB, UQSUB */
+ case 0x8: /* SSHL, USHL */
+ case 0xa: /* SRSHL, URSHL */
+ unsupported_encoding(s, insn);
+ return;
+ case 0x6: /* CMGT, CMHI */
+ case 0x7: /* CMGE, CMHS */
+ case 0x11: /* CMTST, CMEQ */
+ case 0x10: /* ADD, SUB (vector) */
+ if (size != 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ break;
+ case 0x9: /* SQSHL, UQSHL */
+ case 0xb: /* SQRSHL, UQRSHL */
+ unsupported_encoding(s, insn);
+ return;
+ case 0x16: /* SQDMULH, SQRDMULH (vector) */
+ if (size != 1 && size != 2) {
+ unallocated_encoding(s);
+ return;
+ }
+ unsupported_encoding(s, insn);
+ return;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ tcg_rn = read_fp_dreg(s, rn); /* op1 */
+ tcg_rm = read_fp_dreg(s, rm); /* op2 */
+ tcg_rd = tcg_temp_new_i64();
+
+ /* For the moment we only support the opcodes which are
+ * 64-bit-width only. The size != 3 cases will
+ * be handled later when the relevant ops are implemented.
+ */
+ handle_3same_64(s, opcode, u, tcg_rd, tcg_rn, tcg_rm);
+
+ write_fp_dreg(s, rd, tcg_rd);
+
+ tcg_temp_free_i64(tcg_rn);
+ tcg_temp_free_i64(tcg_rm);
+ tcg_temp_free_i64(tcg_rd);
}
/* C3.6.12 AdvSIMD scalar two reg misc
--
1.8.5
- [Qemu-devel] [PULL 36/38] arm: vgic device control api support, (continued)
- [Qemu-devel] [PULL 36/38] arm: vgic device control api support, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 35/38] kvm: Common device control API functions, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 38/38] arm_gic: Fix GICD_ICPENDR and GICD_ISPENDR writes, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 06/38] target-arm: A64: Add SIMD ZIP/UZP/TRN, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 16/38] target-arm: Add AArch32 FP VRINTA, VRINTN, VRINTP and VRINTM, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 33/38] linux-headers: Update from Linus' master ba635f8, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 09/38] target-arm: A64: Add SIMD modified immediate group, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 34/38] kvm: Introduce kvm_arch_irqchip_create, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 32/38] target-arm: A64: Add SIMD shift by immediate, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 24/38] target-arm: Add AArch32 SIMD VCVTA, VCVTN, VCVTP and VCVTM, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 27/38] target-arm: A64: Add SIMD scalar 3 same add, sub and compare ops,
Peter Maydell <=
- [Qemu-devel] [PULL 17/38] target-arm: Add support for AArch32 FP VRINTR, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 31/38] target-arm: A64: Add simple SIMD 3-same floating point ops, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 29/38] target-arm: A64: Add logic ops from SIMD 3 same group, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 30/38] target-arm: A64: Add integer ops from SIMD 3-same group, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 28/38] target-arm: A64: Add top level decode for SIMD 3-same group, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 18/38] target-arm: Add support for AArch32 FP VRINTZ, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 01/38] target-arm: A64: Add SIMD ld/st multiple, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 14/38] display: avoid multi-statement macro, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 13/38] ZYNQ: Implement board MIDR control for Zynq, Peter Maydell, 2014/01/29
- [Qemu-devel] [PULL 19/38] target-arm: Add support for AArch32 FP VRINTX, Peter Maydell, 2014/01/29