From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 75623 invoked by alias); 12 Aug 2015 01:11:52 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 75524 invoked by uid 89); 12 Aug 2015 01:11:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f50.google.com Received: from mail-pa0-f50.google.com (HELO mail-pa0-f50.google.com) (209.85.220.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 12 Aug 2015 01:11:50 +0000 Received: by pacrr5 with SMTP id rr5so2211317pac.3 for ; Tue, 11 Aug 2015 18:11:48 -0700 (PDT) X-Received: by 10.66.140.70 with SMTP id re6mr56880301pab.31.1439341908481; Tue, 11 Aug 2015 18:11:48 -0700 (PDT) Received: from bigtime.twiddle.net (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by smtp.gmail.com with ESMTPSA id kv10sm4167810pbc.2.2015.08.11.18.11.47 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 11 Aug 2015 18:11:47 -0700 (PDT) From: Richard Henderson To: gcc-patches@gcc.gnu.org Cc: David Edelsohn Subject: [PATCH 01/15] rs6000: Split out rs6000_is_valid_and_mask_wide Date: Wed, 12 Aug 2015 01:11:00 -0000 Message-Id: <1439341904-9345-2-git-send-email-rth@redhat.com> In-Reply-To: <1439341904-9345-1-git-send-email-rth@redhat.com> References: <1439341904-9345-1-git-send-email-rth@redhat.com> X-IsSubscribed: yes X-SW-Source: 2015-08/txt/msg00551.txt.bz2 This allows testing for a mask without having to call GEN_INT. Cc: David Edelsohn --- * config/rs6000/rs6000.c (rs6000_is_valid_mask_wide): Split out from... (rs6000_is_valid_mask): ... here. (rs6000_is_valid_and_mask_wide): Split out from... (rs6000_is_valid_and_mask): ... here. (rs6000_is_valid_2insn_and): Use rs6000_is_valid_and_mask_wide. (rs6000_emit_2insn_and): Likewise. (rs6000_rtx_costs): Likewise. --- gcc/config/rs6000/rs6000.c | 76 ++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index e37ef9f..a33b9d3 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1108,6 +1108,8 @@ static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *); static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *); static tree rs6000_builtin_vectorized_libmass (tree, tree, tree); static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT); +static bool rs6000_is_valid_and_mask_wide (unsigned HOST_WIDE_INT val, + machine_mode mode); static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool); static bool rs6000_debug_rtx_costs (rtx, machine_mode, int, int, int *, bool); static int rs6000_debug_address_cost (rtx, machine_mode, addr_space_t, @@ -16378,18 +16380,13 @@ validate_condition_mode (enum rtx_code code, machine_mode mode) the single stretch of 1 bits begins; and similarly for B, the bit offset where it ends. */ -bool -rs6000_is_valid_mask (rtx mask, int *b, int *e, machine_mode mode) +static bool +rs6000_is_valid_mask_wide (unsigned HOST_WIDE_INT val, int *b, int *e, int n) { - unsigned HOST_WIDE_INT val = INTVAL (mask); unsigned HOST_WIDE_INT bit; int nb, ne; - int n = GET_MODE_PRECISION (mode); - if (mode != DImode && mode != SImode) - return false; - - if (INTVAL (mask) >= 0) + if ((HOST_WIDE_INT)val >= 0) { bit = val & -val; ne = exact_log2 (bit); @@ -16430,27 +16427,54 @@ rs6000_is_valid_mask (rtx mask, int *b, int *e, machine_mode mode) return true; } +bool +rs6000_is_valid_mask (rtx mask, int *b, int *e, machine_mode mode) +{ + int n; + + if (mode == DImode) + n = 64; + else if (mode == SImode) + n = 32; + else + return false; + + unsigned HOST_WIDE_INT val = INTVAL (mask); + return rs6000_is_valid_mask_wide (val, b, e, n); +} + /* Return whether MASK (a CONST_INT) is a valid mask for any rlwinm, rldicl, or rldicr instruction, to implement an AND with it in mode MODE. */ -bool -rs6000_is_valid_and_mask (rtx mask, machine_mode mode) +static bool +rs6000_is_valid_and_mask_wide (unsigned HOST_WIDE_INT val, machine_mode mode) { int nb, ne; - if (!rs6000_is_valid_mask (mask, &nb, &ne, mode)) - return false; + switch (mode) + { + case DImode: + if (!rs6000_is_valid_mask_wide (val, &nb, &ne, 64)) + return false; + /* For DImode, we need a rldicl, rldicr, or a rlwinm with + mask that does not wrap. */ + return (ne == 0 || nb == 63 || (nb < 32 && ne <= nb)); - /* For DImode, we need a rldicl, rldicr, or a rlwinm with mask that - does not wrap. */ - if (mode == DImode) - return (ne == 0 || nb == 63 || (nb < 32 && ne <= nb)); + case SImode: + if (!rs6000_is_valid_mask_wide (val, &nb, &ne, 32)) + return false; + /* For SImode, rlwinm can do everything. */ + return (nb < 32 && ne < 32); - /* For SImode, rlwinm can do everything. */ - if (mode == SImode) - return (nb < 32 && ne < 32); + default: + return false; + } +} - return false; +bool +rs6000_is_valid_and_mask (rtx mask, machine_mode mode) +{ + return rs6000_is_valid_and_mask_wide (UINTVAL (mask), mode); } /* Return the instruction template for an AND with mask in mode MODE, with @@ -16739,12 +16763,12 @@ rs6000_is_valid_2insn_and (rtx c, machine_mode mode) /* Otherwise, fill in the lowest "hole"; if we can do the result with one insn, we can do the whole thing with two. */ - unsigned HOST_WIDE_INT val = INTVAL (c); + unsigned HOST_WIDE_INT val = UINTVAL (c); unsigned HOST_WIDE_INT bit1 = val & -val; unsigned HOST_WIDE_INT bit2 = (val + bit1) & ~val; unsigned HOST_WIDE_INT val1 = (val + bit1) & val; unsigned HOST_WIDE_INT bit3 = val1 & -val1; - return rs6000_is_valid_and_mask (GEN_INT (val + bit3 - bit2), mode); + return rs6000_is_valid_and_mask_wide (val + bit3 - bit2, mode); } /* Emit a potentially record-form instruction, setting DST from SRC. @@ -16835,10 +16859,10 @@ rs6000_emit_2insn_and (machine_mode mode, rtx *operands, bool expand, int dot) unsigned HOST_WIDE_INT mask1 = -bit3 + bit2 - 1; unsigned HOST_WIDE_INT mask2 = val + bit3 - bit2; - gcc_assert (rs6000_is_valid_and_mask (GEN_INT (mask2), mode)); + gcc_assert (rs6000_is_valid_and_mask_wide (mask2, mode)); /* Two "no-rotate"-and-mask instructions, for SImode. */ - if (rs6000_is_valid_and_mask (GEN_INT (mask1), mode)) + if (rs6000_is_valid_and_mask_wide (mask1, mode)) { gcc_assert (mode == SImode); @@ -16855,7 +16879,7 @@ rs6000_emit_2insn_and (machine_mode mode, rtx *operands, bool expand, int dot) /* Two "no-rotate"-and-mask instructions, for DImode: both are rlwinm insns; we have to do the first in SImode, because it wraps. */ if (mask2 <= 0xffffffff - && rs6000_is_valid_and_mask (GEN_INT (mask1), SImode)) + && rs6000_is_valid_and_mask_wide (mask1, SImode)) { rtx reg = expand ? gen_reg_rtx (mode) : operands[0]; rtx tmp = gen_rtx_AND (SImode, gen_lowpart (SImode, operands[1]), @@ -31070,7 +31094,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, /* rotate-and-mask (no rotate), andi., andis.: 1 insn. */ HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); - if (rs6000_is_valid_and_mask (XEXP (x, 1), mode) + if (rs6000_is_valid_and_mask_wide (val, mode) || (val & 0xffff) == val || (val & 0xffff0000) == val || ((val & 0xffff) == 0 && mode == SImode)) -- 2.4.3