From patchwork Fri Apr 9 17:45:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 50163 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DFFB4B7D2F for ; Thu, 15 Apr 2010 00:34:42 +1000 (EST) Received: from localhost ([127.0.0.1]:54197 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O23fr-0002Dq-G0 for incoming@patchwork.ozlabs.org; Wed, 14 Apr 2010 10:34:39 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1O23VB-0007J3-6C for qemu-devel@nongnu.org; Wed, 14 Apr 2010 10:23:37 -0400 Received: from [140.186.70.92] (port=37321 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O23V7-0007H8-0U for qemu-devel@nongnu.org; Wed, 14 Apr 2010 10:23:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1O23V2-0006ct-Pa for qemu-devel@nongnu.org; Wed, 14 Apr 2010 10:23:32 -0400 Received: from are.twiddle.net ([75.149.56.221]:43811) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1O23V2-0006bq-DP for qemu-devel@nongnu.org; Wed, 14 Apr 2010 10:23:28 -0400 Received: by are.twiddle.net (Postfix, from userid 5000) id 05414A61; Wed, 14 Apr 2010 07:16:20 -0700 (PDT) Message-Id: <97e615e06acb9597e0087cf89e44ae83a53f67ce.1271253049.git.rth@twiddle.net> In-Reply-To: References: From: Richard Henderson Date: Fri, 9 Apr 2010 10:45:49 -0700 To: qemu-devel@nongnu.org X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: aurelien@aurel32.net Subject: [Qemu-devel] [PATCH 1/6] tcg-hppa: Constrain immediate inputs to and_i32, or_i32, andc_i32. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Define "M" constraint for and_mask_p and "O" constraint for or_mask_p. Assume that inputs are correct in tcg_out_ori and tcg_out_andi. Signed-off-by: Richard Henderson --- tcg/hppa/tcg-target.c | 108 ++++++++++++++++++++++++------------------------ tcg/hppa/tcg-target.h | 2 + 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index daddaab..c9410b2 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -97,6 +97,9 @@ static inline int check_fit_tl(tcg_target_long val, unsigned int bits) Copied from gcc sources. */ static inline int or_mask_p(tcg_target_ulong mask) { + if (mask == 0 || mask == -1) { + return 0; + } mask += mask & -mask; return (mask & (mask - 1)) == 0; } @@ -213,6 +216,12 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) case 'K': ct->ct |= TCG_CT_CONST_MS11; break; + case 'M': + ct->ct |= TCG_CT_CONST_AND; + break; + case 'O': + ct->ct |= TCG_CT_CONST_OR; + break; default: return -1; } @@ -236,6 +245,10 @@ static int tcg_target_const_match(tcg_target_long val, return check_fit_tl(val, 11); } else if (ct & TCG_CT_CONST_MS11) { return check_fit_tl(-val, 11); + } else if (ct & TCG_CT_CONST_AND) { + return and_mask_p(val); + } else if (ct & TCG_CT_CONST_OR) { + return or_mask_p(val); } return 0; } @@ -474,70 +487,54 @@ static void tcg_out_vshd(TCGContext *s, int ret, int hi, int lo, int creg) static void tcg_out_ori(TCGContext *s, int ret, int arg, tcg_target_ulong m) { - if (m == 0) { - tcg_out_mov(s, ret, arg); - } else if (m == -1) { - tcg_out_movi(s, TCG_TYPE_I32, ret, -1); - } else if (or_mask_p(m)) { - int bs0, bs1; - - for (bs0 = 0; bs0 < 32; bs0++) { - if ((m & (1u << bs0)) != 0) { - break; - } + int bs0, bs1; + + /* Note that the argument is constrained to match or_mask_p. */ + for (bs0 = 0; bs0 < 32; bs0++) { + if ((m & (1u << bs0)) != 0) { + break; } - for (bs1 = bs0; bs1 < 32; bs1++) { - if ((m & (1u << bs1)) == 0) { - break; - } + } + for (bs1 = bs0; bs1 < 32; bs1++) { + if ((m & (1u << bs1)) == 0) { + break; } - assert(bs1 == 32 || (1ul << bs1) > m); - - tcg_out_mov(s, ret, arg); - tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1) - | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0)); - } else { - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m); - tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_OR); } + assert(bs1 == 32 || (1ul << bs1) > m); + + tcg_out_mov(s, ret, arg); + tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1) + | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0)); } static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m) { - if (m == 0) { - tcg_out_mov(s, ret, TCG_REG_R0); - } else if (m == -1) { - tcg_out_mov(s, ret, arg); - } else if (and_mask_p(m)) { - int ls0, ls1, ms0; + int ls0, ls1, ms0; - for (ls0 = 0; ls0 < 32; ls0++) { - if ((m & (1u << ls0)) == 0) { - break; - } + /* Note that the argument is constrained to match and_mask_p. */ + for (ls0 = 0; ls0 < 32; ls0++) { + if ((m & (1u << ls0)) == 0) { + break; } - for (ls1 = ls0; ls1 < 32; ls1++) { - if ((m & (1u << ls1)) != 0) { - break; - } + } + for (ls1 = ls0; ls1 < 32; ls1++) { + if ((m & (1u << ls1)) != 0) { + break; } - for (ms0 = ls1; ms0 < 32; ms0++) { - if ((m & (1u << ms0)) == 0) { - break; - } + } + for (ms0 = ls1; ms0 < 32; ms0++) { + if ((m & (1u << ms0)) == 0) { + break; } - assert (ms0 == 32); + } + assert (ms0 == 32); - if (ls1 == 32) { - tcg_out_extr(s, ret, arg, 0, ls0, 0); - } else { - tcg_out_mov(s, ret, arg); - tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0) - | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0)); - } + if (ls1 == 32) { + tcg_out_extr(s, ret, arg, 0, ls0, 0); } else { - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R1, m); - tcg_out_arith(s, ret, arg, TCG_REG_R1, INSN_AND); + tcg_out_mov(s, ret, arg); + tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0) + | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0)); } } @@ -1539,10 +1536,13 @@ static const TCGTargetOpDef hppa_op_defs[] = { { INDEX_op_add_i32, { "r", "rZ", "ri" } }, { INDEX_op_sub_i32, { "r", "rI", "ri" } }, - { INDEX_op_and_i32, { "r", "rZ", "ri" } }, - { INDEX_op_or_i32, { "r", "rZ", "ri" } }, + { INDEX_op_and_i32, { "r", "rZ", "rM" } }, + { INDEX_op_or_i32, { "r", "rZ", "rO" } }, { INDEX_op_xor_i32, { "r", "rZ", "rZ" } }, - { INDEX_op_andc_i32, { "r", "rZ", "ri" } }, + /* Note that the second argument will be inverted, which means + we want a constant whose inversion matches M, and that O = ~M. + See the implementation of and_mask_p. */ + { INDEX_op_andc_i32, { "r", "rZ", "rO" } }, { INDEX_op_mul_i32, { "r", "r", "r" } }, { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h index b76e389..7e21f1d 100644 --- a/tcg/hppa/tcg-target.h +++ b/tcg/hppa/tcg-target.h @@ -73,6 +73,8 @@ enum { #define TCG_CT_CONST_S5 0x0200 #define TCG_CT_CONST_S11 0x0400 #define TCG_CT_CONST_MS11 0x0800 +#define TCG_CT_CONST_AND 0x1000 +#define TCG_CT_CONST_OR 0x2000 /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_SP