From patchwork Mon Sep 2 17:54:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 272027 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 5C03D2C009A for ; Tue, 3 Sep 2013 04:01:17 +1000 (EST) Received: from localhost ([::1]:41403 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGYR9-0004r3-HN for incoming@patchwork.ozlabs.org; Mon, 02 Sep 2013 14:01:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56649) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGYLc-0005vl-UQ for qemu-devel@nongnu.org; Mon, 02 Sep 2013 13:55:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VGYLW-00017b-K5 for qemu-devel@nongnu.org; Mon, 02 Sep 2013 13:55:32 -0400 Received: from mail-pd0-x232.google.com ([2607:f8b0:400e:c02::232]:36151) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGYLW-00017T-81 for qemu-devel@nongnu.org; Mon, 02 Sep 2013 13:55:26 -0400 Received: by mail-pd0-f178.google.com with SMTP id w10so5031088pde.9 for ; Mon, 02 Sep 2013 10:55:25 -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=7dEeKXtbnc3F75mtNlDhBWnyc3Ck7XWU04xjg1TG7rU=; b=rWRVWCfgbnix21WCxYis9D12sRQDXhHHCvmesoRvk5+WjjwZKbharjhuwLnyWcsw4j LgrCLs47tJ6ftBx8YQbK7bw8AWlaeMWNvqZNQaXePMVTmC50KnjLcDQoXeDtKLlSl+eO LY2XbSZuyN9Ml1mmy0u3LUMywvcKBi9FSYphK26LhzqMcfZGEWfbHC+Kcl0YyZYa58qJ 3yx4re6nBjv165D8z0woXy8ZrpuR/aH6/5ENuEnsbFsi+er66vX9O2wBg4gHaxQ8Ax0q ezjbXj8y0lz7A5dFNMumtF5FxKuKiWGd8/chN74lyB3HgTnJljOadyJLyB8jRw/NJlQR YXsw== X-Received: by 10.69.12.36 with SMTP id en4mr26763620pbd.54.1378144525246; Mon, 02 Sep 2013 10:55:25 -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:24 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 2 Sep 2013 10:54:44 -0700 Message-Id: <1378144503-15808-11-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::232 Cc: claudio.fontana@huawei.com, Richard Henderson Subject: [Qemu-devel] [PATCH v3 10/29] tcg-aarch64: Handle constant operands to add, sub, and compare 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 | 101 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 22 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 64c8d19..dbb1c45 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -106,6 +106,9 @@ static inline void patch_reloc(uint8_t *code_ptr, int type, } } +#define TCG_CT_CONST_IS32 0x100 +#define TCG_CT_CONST_AIMM 0x200 + /* parse target specific constraints */ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) @@ -129,6 +132,12 @@ static int target_parse_constraint(TCGArgConstraint *ct, tcg_regset_reset_reg(ct->u.regs, TCG_REG_X3); #endif break; + case 'w': /* The operand should be considered 32-bit. */ + ct->ct |= TCG_CT_CONST_IS32; + break; + case 'A': /* Valid for arithmetic immediate (positive or negative). */ + ct->ct |= TCG_CT_CONST_AIMM; + break; default: return -1; } @@ -138,14 +147,25 @@ static int target_parse_constraint(TCGArgConstraint *ct, return 0; } -static inline int tcg_target_const_match(tcg_target_long val, - const TCGArgConstraint *arg_ct) +static inline bool is_aimm(uint64_t val) +{ + return (val & ~0xfff) == 0 || (val & ~0xfff000) == 0; +} + +static int tcg_target_const_match(tcg_target_long val, + const TCGArgConstraint *arg_ct) { int ct = arg_ct->ct; if (ct & TCG_CT_CONST) { return 1; } + if (ct & TCG_CT_CONST_IS32) { + val = (int32_t)val; + } + if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) { + return 1; + } return 0; } @@ -548,11 +568,21 @@ static inline void tcg_out_rotl(TCGContext *s, bool ext, tcg_out_extr(s, ext, rd, rn, rn, bits - (m & max)); } -static inline void tcg_out_cmp(TCGContext *s, bool ext, TCGReg rn, TCGReg rm, - int shift_imm) +static void tcg_out_cmp(TCGContext *s, bool ext, TCGReg a, + tcg_target_long b, bool const_b) { - /* Using CMP alias SUBS wzr, Wn, Wm */ - tcg_fmt_Rdnm_shift(s, INSN_SUBS, ext, TCG_REG_XZR, rn, rm, shift_imm); + if (const_b) { + /* Using CMP or CMN aliases. */ + AArch64Insn insn = INSN_SUBSI; + if (b < 0) { + insn = INSN_ADDSI; + b = -b; + } + tcg_fmt_Rdn_aimm(s, insn, ext, TCG_REG_XZR, a, b); + } else { + /* Using CMP alias SUBS wzr, Wn, Wm */ + tcg_fmt_Rdnm(s, INSN_SUBS, ext, TCG_REG_XZR, a, b); + } } static inline void tcg_out_cset(TCGContext *s, bool ext, TCGReg rd, TCGCond c) @@ -747,6 +777,17 @@ static inline void tcg_out_uxt(TCGContext *s, int s_bits, tcg_out_ubfm(s, 0, rd, rn, 0, bits); } +static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, + TCGReg rn, int aimm) +{ + AArch64Insn insn = INSN_ADDI; + if (aimm < 0) { + insn = INSN_SUBI; + aimm = -aimm; + } + tcg_fmt_Rdn_aimm(s, insn, ext, rd, rn, aimm); +} + static inline void tcg_out_nop(TCGContext *s) { tcg_out32(s, 0xd503201f); @@ -1144,14 +1185,26 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, a0, a1, a2); break; - case INDEX_op_add_i64: case INDEX_op_add_i32: - tcg_fmt_Rdnm(s, INSN_ADD, ext, a0, a1, a2); + a2 = (int32_t)a2; + /* FALLTHRU */ + case INDEX_op_add_i64: + if (c2) { + tcg_out_addsubi(s, ext, a0, a1, a2); + } else { + tcg_fmt_Rdnm(s, INSN_ADD, ext, a0, a1, a2); + } break; - case INDEX_op_sub_i64: case INDEX_op_sub_i32: - tcg_fmt_Rdnm(s, INSN_SUB, ext, a0, a1, a2); + a2 = (int32_t)a2; + /* FALLTHRU */ + case INDEX_op_sub_i64: + if (c2) { + tcg_out_addsubi(s, ext, a0, a1, -a2); + } else { + tcg_fmt_Rdnm(s, INSN_SUB, ext, a0, a1, a2); + } break; case INDEX_op_and_i64: @@ -1220,15 +1273,19 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_brcond_i64: case INDEX_op_brcond_i32: - tcg_out_cmp(s, ext, a0, a1, 0); + a1 = (int32_t)a1; + /* FALLTHRU */ + case INDEX_op_brcond_i64: + tcg_out_cmp(s, ext, a0, a1, const_args[1]); tcg_out_goto_label_cond(s, a2, args[3]); break; - case INDEX_op_setcond_i64: case INDEX_op_setcond_i32: - tcg_out_cmp(s, ext, a1, a2, 0); + a2 = (int32_t)a2; + /* FALLTHRU */ + case INDEX_op_setcond_i64: + tcg_out_cmp(s, ext, a1, a2, c2); tcg_out_cset(s, 0, a0, args[3]); break; @@ -1349,10 +1406,10 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_st32_i64, { "r", "r" } }, { INDEX_op_st_i64, { "r", "r" } }, - { INDEX_op_add_i32, { "r", "r", "r" } }, - { INDEX_op_add_i64, { "r", "r", "r" } }, - { INDEX_op_sub_i32, { "r", "r", "r" } }, - { INDEX_op_sub_i64, { "r", "r", "r" } }, + { INDEX_op_add_i32, { "r", "r", "rwA" } }, + { INDEX_op_add_i64, { "r", "r", "rA" } }, + { INDEX_op_sub_i32, { "r", "r", "rwA" } }, + { INDEX_op_sub_i64, { "r", "r", "rA" } }, { INDEX_op_mul_i32, { "r", "r", "r" } }, { INDEX_op_mul_i64, { "r", "r", "r" } }, { INDEX_op_and_i32, { "r", "r", "r" } }, @@ -1373,10 +1430,10 @@ static const TCGTargetOpDef aarch64_op_defs[] = { { INDEX_op_rotl_i64, { "r", "r", "ri" } }, { INDEX_op_rotr_i64, { "r", "r", "ri" } }, - { INDEX_op_brcond_i32, { "r", "r" } }, - { INDEX_op_setcond_i32, { "r", "r", "r" } }, - { INDEX_op_brcond_i64, { "r", "r" } }, - { INDEX_op_setcond_i64, { "r", "r", "r" } }, + { INDEX_op_brcond_i32, { "r", "rwA" } }, + { INDEX_op_brcond_i64, { "r", "rA" } }, + { INDEX_op_setcond_i32, { "r", "r", "rwA" } }, + { INDEX_op_setcond_i64, { "r", "r", "rA" } }, { INDEX_op_qemu_ld8u, { "r", "l" } }, { INDEX_op_qemu_ld8s, { "r", "l" } },