From patchwork Fri Jan 17 18:44:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 312166 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4216B2C009A for ; Sat, 18 Jan 2014 05:45:10 +1100 (EST) Received: from localhost ([::1]:39583 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W4EPk-0000up-4s for incoming@patchwork.ozlabs.org; Fri, 17 Jan 2014 13:45:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44312) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W4EPA-0008J1-7V for qemu-devel@nongnu.org; Fri, 17 Jan 2014 13:44:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W4EP7-0000jn-6U for qemu-devel@nongnu.org; Fri, 17 Jan 2014 13:44:32 -0500 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:44900) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W4EP6-0000iH-Uk for qemu-devel@nongnu.org; Fri, 17 Jan 2014 13:44:29 -0500 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1W4EOv-0001mh-BG; Fri, 17 Jan 2014 18:44:17 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 17 Jan 2014 18:44:12 +0000 Message-Id: <1389984257-6822-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1389984257-6822-1-git-send-email-peter.maydell@linaro.org> References: <1389984257-6822-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Cc: patches@linaro.org, Michael Matz , Alexander Graf , Claudio Fontana , Dirk Mueller , Will Newton , Laurent Desnogues , =?UTF-8?q?Alex=20Benn=C3=A9e?= , kvmarm@lists.cs.columbia.edu, Christoffer Dall , Richard Henderson Subject: [Qemu-devel] [PATCH 3/8] target-arm: A64: Add SIMD scalar 3 same add, sub and compare ops X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Implement the add, sub and compare ops from the SIMD "scalar three same" group. Signed-off-by: Peter Maydell --- 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 78f5eb9..2b3f3a3 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5501,6 +5501,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 subtracting 1. + */ + cond = u ? TCG_COND_GTU : TCG_COND_GT; + do_cmop: + tcg_gen_setcond_i64(tcg_invert_cond(cond), tcg_rd, tcg_rn, tcg_rm); + tcg_gen_subi_i64(tcg_rd, tcg_rd, 1); + 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_EQ, tcg_rd, tcg_rd, 0); + tcg_gen_subi_i64(tcg_rd, tcg_rd, 1); + 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 * +-----+---+-----------+------+---+------+--------+---+------+------+ @@ -5509,7 +5561,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