From patchwork Mon Sep 2 17:54:50 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 272029 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3AE2F2C00A3 for ; Tue, 3 Sep 2013 04:03:08 +1000 (EST) Received: from localhost ([::1]:41429 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGYSw-0006m7-5p for incoming@patchwork.ozlabs.org; Mon, 02 Sep 2013 14:03:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56730) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGYLm-00061t-PA for qemu-devel@nongnu.org; Mon, 02 Sep 2013 13:55:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VGYLg-0001Am-Hx for qemu-devel@nongnu.org; Mon, 02 Sep 2013 13:55:42 -0400 Received: from mail-pd0-x236.google.com ([2607:f8b0:400e:c02::236]:54319) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGYLg-0001AU-4B for qemu-devel@nongnu.org; Mon, 02 Sep 2013 13:55:36 -0400 Received: by mail-pd0-f182.google.com with SMTP id r10so5007981pdi.41 for ; Mon, 02 Sep 2013 10:55:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=vf6NmC8c4mgfnXkYkHHv0CYuDua/wKkWPZPvrbRuKzs=; b=jp+c1j80kiHk3+YziYj6YntCNYXaiOir60zKJYsv7T1tmYrobsEhBBzDvnMf3HYn3O /4U+tLq45GIs7JVSNI2C7+9ByLo2xIk/ov3sStgn/W6rwhrzD50VV52dL4qV9qzZvqOu TzUJnI7KpvQTiMbXxzVWjO1Vu0bRdTJH2qFjXaZQ+nl3C5bOw3jT02kQidvVzGGz1HDe P1bWss/7d6tkCsYYybD16FnzyIxB+YcOtICf/9FvMxHCLfT621upldlWTz4XzD5FZxgZ hk/tjcMscGLAElXXBusFu7eW8CveBhSPAK+/s0ffSngrsdYylMY/eAHsUYHDbYhkxIts Quew== X-Received: by 10.68.170.133 with SMTP id am5mr26721999pbc.104.1378144535104; Mon, 02 Sep 2013 10:55:35 -0700 (PDT) Received: from pebble.twiddle.net (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPSA id tr10sm17218114pbc.22.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 02 Sep 2013 10:55:34 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 2 Sep 2013 10:54:50 -0700 Message-Id: <1378144503-15808-17-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1378144503-15808-1-git-send-email-rth@twiddle.net> References: <1378144503-15808-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400e:c02::236 Cc: claudio.fontana@huawei.com, Richard Henderson Subject: [Qemu-devel] [PATCH v3 16/29] tcg-aarch64: Support add2, sub2 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 Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ tcg/aarch64/tcg-target.h | 8 ++--- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 0dc3fee..0587765 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -110,6 +110,7 @@ static inline void patch_reloc(uint8_t *code_ptr, int type, #define TCG_CT_CONST_AIMM 0x200 #define TCG_CT_CONST_LIMM 0x400 #define TCG_CT_CONST_ZERO 0x800 +#define TCG_CT_CONST_MONE 0x1000 /* parse target specific constraints */ static int target_parse_constraint(TCGArgConstraint *ct, @@ -143,6 +144,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, case 'L': /* Valid for logical immediate. */ ct->ct |= TCG_CT_CONST_LIMM; break; + case 'M': /* minus one */ + ct->ct |= TCG_CT_CONST_MONE; + break; case 'Z': /* zero */ ct->ct |= TCG_CT_CONST_ZERO; break; @@ -200,6 +204,9 @@ static int tcg_target_const_match(tcg_target_long val, if ((ct & TCG_CT_CONST_ZERO) && val == 0) { return 1; } + if ((ct & TCG_CT_CONST_MONE) && val == -1) { + return 1; + } return 0; } @@ -279,6 +286,10 @@ typedef enum { INSN_SUB = 0x4b000000, INSN_SUBS = 0x6b000000, + /* Add/subtract with carry instructions */ + INSN_ADC = 0x1a000000, + INSN_SBC = 0x5a000000, + /* Data-processing (2 source) instructions */ INSN_LSLV = 0x1ac02000, INSN_LSRV = 0x1ac02400, @@ -848,6 +859,47 @@ static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, tcg_fmt_Rdn_aimm(s, insn, ext, rd, rn, aimm); } +static inline void tcg_out_addsub2(TCGContext *s, int ext, TCGReg rl, + TCGReg rh, TCGReg al, TCGReg ah, + tcg_target_long bl, tcg_target_long bh, + bool const_bl, bool const_bh, bool sub) +{ + TCGReg orig_rl = rl; + AArch64Insn insn; + + if (rl == ah || (!const_bh && rl == bh)) { + rl = TCG_REG_TMP; + } + + if (const_bl) { + insn = INSN_ADDSI; + if ((bl < 0) ^ sub) { + insn = INSN_SUBSI; + bl = -bl; + } + tcg_fmt_Rdn_aimm(s, insn, ext, rl, al, bl); + } else { + tcg_fmt_Rdnm(s, sub ? INSN_SUBS : INSN_ADDS, ext, rl, al, bl); + } + + insn = INSN_ADC; + if (const_bh) { + /* Note that the only two constants we support are 0 and -1, and + that SBC = rn + ~rm + c, so adc -1 is sbc 0, and vice-versa. */ + if ((bh != 0) ^ sub) { + insn = INSN_SBC; + } + bh = TCG_REG_XZR; + } else if (sub) { + insn = INSN_SBC; + } + tcg_fmt_Rdnm(s, insn, ext, rh, ah, bh); + + if (rl != orig_rl) { + tcg_out_movr(s, ext, orig_rl, rl); + } +} + static inline void tcg_out_nop(TCGContext *s) { tcg_out32(s, 0xd503201f); @@ -1503,6 +1555,27 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]); break; + case INDEX_op_add2_i32: + a2 = (int32_t)args[4]; + c2 = false; + goto do_addsub2; + case INDEX_op_add2_i64: + a2 = args[4]; + c2 = false; + goto do_addsub2; + case INDEX_op_sub2_i32: + a2 = (int32_t)args[4]; + c2 = true; + goto do_addsub2; + case INDEX_op_sub2_i64: + a2 = args[4]; + c2 = true; + goto do_addsub2; + do_addsub2: + tcg_out_addsub2(s, ext, a0, a1, REG0(2), REG0(3), a2, + args[5], const_args[4], const_args[5], c2); + break; + case INDEX_op_mov_i64: case INDEX_op_mov_i32: case INDEX_op_movi_i64: @@ -1625,6 +1698,11 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_deposit_i32, { "r", "0", "rZ" } }, { INDEX_op_deposit_i64, { "r", "0", "rZ" } }, + { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rwA", "rwMZ" } }, + { INDEX_op_add2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, + { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rwA", "rwMZ" } }, + { INDEX_op_sub2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } }, + { -1 }, }; diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index 712e4e7..05e43e4 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -57,8 +57,8 @@ typedef enum { #define TCG_TARGET_HAS_nor_i32 0 #define TCG_TARGET_HAS_deposit_i32 1 #define TCG_TARGET_HAS_movcond_i32 1 -#define TCG_TARGET_HAS_add2_i32 0 -#define TCG_TARGET_HAS_sub2_i32 0 +#define TCG_TARGET_HAS_add2_i32 1 +#define TCG_TARGET_HAS_sub2_i32 1 #define TCG_TARGET_HAS_mulu2_i32 0 #define TCG_TARGET_HAS_muls2_i32 0 #define TCG_TARGET_HAS_muluh_i32 0 @@ -85,8 +85,8 @@ typedef enum { #define TCG_TARGET_HAS_nor_i64 0 #define TCG_TARGET_HAS_deposit_i64 1 #define TCG_TARGET_HAS_movcond_i64 1 -#define TCG_TARGET_HAS_add2_i64 0 -#define TCG_TARGET_HAS_sub2_i64 0 +#define TCG_TARGET_HAS_add2_i64 1 +#define TCG_TARGET_HAS_sub2_i64 1 #define TCG_TARGET_HAS_mulu2_i64 0 #define TCG_TARGET_HAS_muls2_i64 0 #define TCG_TARGET_HAS_muluh_i64 0