From patchwork Wed Aug 15 02:55:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Pinski X-Patchwork-Id: 177530 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id BFD732C0088 for ; Wed, 15 Aug 2012 12:56:13 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1345604174; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:Date:Message-ID:Subject:From:To: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=4fKDdGa y0JudzvnI3Ely/UkEXTk=; b=WOch//TdUHjb8yPf1pTGZoNqfl2oADlqjSR/NDo ElzoY+8Hokfu0tRJT3n6qfqd6GB86a4R5jpC8zZ2eiuwWD6GRChMJkwZCc45bdUJ LDYJSoznT3rkOp3wN49i76nfxHphlKPz87MH9seo3Drsv07k+wsFaN5oJed5JZuS +Kxc= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:MIME-Version:Received:Received:Date:Message-ID:Subject:From:To:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=GIIxn7/lfUGVp0gz+YPZjDkcEtC2A1WMF5AdcSI3u3BXqPKqg1+HKwfEduxAPZ oDPmSf9bCEcWkJBe9p7UAj/3WsIm5uXx1ssO9FY5lNk6tILzYbfwBSPriMBYRsSl hLRbC6o96ts9kxylGugpUKAGW/+YHSvtMaGjsMMEeD3Ws=; Received: (qmail 6389 invoked by alias); 15 Aug 2012 02:56:08 -0000 Received: (qmail 6367 invoked by uid 22791); 15 Aug 2012 02:56:06 -0000 X-SWARE-Spam-Status: No, hits=-4.7 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-wg0-f51.google.com (HELO mail-wg0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 15 Aug 2012 02:55:52 +0000 Received: by wgbed3 with SMTP id ed3so761319wgb.8 for ; Tue, 14 Aug 2012 19:55:50 -0700 (PDT) MIME-Version: 1.0 Received: by 10.180.100.133 with SMTP id ey5mr33228652wib.4.1344999350883; Tue, 14 Aug 2012 19:55:50 -0700 (PDT) Received: by 10.216.219.68 with HTTP; Tue, 14 Aug 2012 19:55:50 -0700 (PDT) Date: Tue, 14 Aug 2012 19:55:50 -0700 Message-ID: Subject: [PATCH/MIPS] Use ins/dins instruction when written manually From: Andrew Pinski To: GCC Patches X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, Right now we only produce ins when a zero_extract is used on the right hand side. We can do better by adding some patterns which combine for the ins instruction. This patch adds those patterns and a testcase which shows a simple example where the code is improved. OK? Bootstrapped and tested on mips64-linux-gnu with no regressions. Thanks, Andrew Pinski ChangeLog: Andrew Pinski Adam Nemet * config/mips/mips-protos.h (mips_bitmask, mips_bitmask_p, mips_bottom_bitmask_p): Declare them. * config/mips/mips.c (mips_bitmask, mips_bitmask_p, mips_bottom_bitmask_p): New functions. * config/mips/mips.md (*insv_internal1): New pattern to match a bottom insert. (*insv_internal2): Likewise. (*insv_internal3): New pattern to match an insert. (*insv_internal4): Likewise. * config/mips/predicates.md (bitmask_operand bottom_bitmask_operand, inverse_bitmask_operand): New predicates. * testsuite/gcc.target/mips/ins-4.c: New testcase. Index: testsuite/gcc.target/mips/ins-4.c =================================================================== --- testsuite/gcc.target/mips/ins-4.c (revision 0) +++ testsuite/gcc.target/mips/ins-4.c (revision 0) @@ -0,0 +1,22 @@ +/* { dg-options "-O2 isa_rev>=2 -mgp64" } */ +/* { dg-final { scan-assembler-times "ins\t" 2 } } */ +/* { dg-final { scan-assembler-not "or\t" } } */ +/* { dg-final { scan-assembler-not "cins\t" } } */ + +#define shift 0 +#define mask (0xfffffull< 16"))) +(define_predicate "bitmask_operand" + (and (match_code "const_int") + (and (not (match_operand 0 "uns_arith_operand")) + (match_test "mips_bitmask_p (INTVAL (op))")))) + +(define_predicate "bottom_bitmask_operand" + (and (match_code "const_int") + (and (match_operand 0 "bitmask_operand") + (match_test "mips_bottom_bitmask_p (INTVAL (op))")))) + +(define_predicate "inverse_bitmask_operand" + (and (match_code "const_int") + (and (not (match_operand 0 "uns_arith_operand")) + (and (not (match_operand 0 "bottom_bitmask_operand")) + (match_test "mips_bitmask_p (~ INTVAL (op))"))))) + (define_predicate "and_reg_operand" (ior (match_operand 0 "register_operand") (and (not (match_test "TARGET_MIPS16")) Index: config/mips/mips.md =================================================================== --- config/mips/mips.md (revision 190403) +++ config/mips/mips.md (working copy) @@ -3903,6 +3903,112 @@ (define_insn "*cins" [(set_attr "type" "shift") (set_attr "mode" "")]) +(define_insn "*insv_internal1" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ior:GPR (and:GPR (match_operand:GPR 1 "register_operand" "0") + (match_operand:GPR 2 "const_int_operand" "i")) + (and:GPR (match_operand:GPR 3 "register_operand" "d") + (match_operand:GPR 4 "const_int_operand" "i"))))] + "ISA_HAS_EXT_INS && mips_bottom_bitmask_p (INTVAL (operands[4])) + && INTVAL(operands[2]) == ~INTVAL(operands[4])" +{ + int len, pos; + pos = mips_bitmask (INTVAL (operands[4]), &len, mode); + operands[2] = GEN_INT (pos); + operands[4] = GEN_INT (len); + return "ins\t%0,%3,%2,%4"; +} + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "*insv_internal2" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ior:GPR (and:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:GPR 2 "const_int_operand" "i")) + (and:GPR (match_operand:GPR 3 "register_operand" "0") + (match_operand:GPR 4 "const_int_operand" "i"))))] + "ISA_HAS_EXT_INS && mips_bottom_bitmask_p (INTVAL (operands[2])) + && INTVAL(operands[2]) == ~INTVAL(operands[4])" +{ + int len, pos; + pos = mips_bitmask (INTVAL (operands[2]), &len, mode); + operands[2] = GEN_INT (pos); + operands[4] = GEN_INT (len); + return "ins\t%0,%1,%2,%4"; +} + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "*insv_internal3" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ior:GPR (and:GPR (match_operand:GPR 1 "register_operand" "0") + (match_operand:GPR 2 "const_int_operand" "i")) + (and:GPR (ashift:GPR (match_operand:GPR 3 "register_operand" "d") + (match_operand:GPR 5 "const_int_operand" "i")) + (match_operand:GPR 4 "const_int_operand" "i"))))] + "ISA_HAS_EXT_INS + && mips_bitmask (INTVAL (operands[4]), NULL, VOIDmode) == INTVAL (operands[5]) + && INTVAL(operands[2]) == ~INTVAL(operands[4])" +{ + int len; + mips_bitmask (INTVAL (operands[4]), &len, mode); + operands[4] = GEN_INT (len); + return "ins\t%0,%3,%5,%4"; +} + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "*insv_internal4" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ior:GPR (and:GPR (ashift:GPR (match_operand:GPR 3 "register_operand" "d") + (match_operand:GPR 5 "const_int_operand" "i")) + (match_operand:GPR 4 "const_int_operand" "i")) + (and:GPR (match_operand:GPR 1 "register_operand" "0") + (match_operand:GPR 2 "const_int_operand" "i"))))] + "ISA_HAS_EXT_INS + && mips_bitmask (INTVAL (operands[4]), NULL, VOIDmode) == INTVAL (operands[5]) + && INTVAL(operands[2]) == ~INTVAL(operands[4])" +{ + int len; + mips_bitmask (INTVAL (operands[4]), &len, mode); + operands[4] = GEN_INT (len); + return "ins\t%0,%3,%5,%4"; +} + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "*insv_internal5" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ior:GPR (and:GPR (match_operand:GPR 1 "register_operand" "0") + (match_operand:GPR 2 "const_int_operand" "i")) + (ashift:GPR (match_operand:GPR 3 "register_operand" "d") + (match_operand:GPR 4 "const_int_operand" "i"))))] + "ISA_HAS_EXT_INS && mips_bitmask_ins_p (INTVAL (operands[2]), INTVAL (operands[4]), mode)" +{ + int len; + mips_bitmask (~INTVAL (operands[2]), &len, mode); + operands[2] = GEN_INT (len); + return "ins\t%0,%3,%4,%2"; +} + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "*insv_internal4" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ior:GPR (ashift:GPR (match_operand:GPR 3 "register_operand" "d") + (match_operand:GPR 4 "const_int_operand" "i")) + (and:GPR (match_operand:GPR 1 "register_operand" "0") + (match_operand:GPR 2 "const_int_operand" "i"))))] + "ISA_HAS_EXT_INS && mips_bitmask_ins_p (INTVAL (operands[2]), INTVAL (operands[4]), mode)" +{ + int len; + mips_bitmask (~INTVAL (operands[2]), &len, mode); + operands[2] = GEN_INT (len); + return "ins\t%0,%3,%4,%2"; +} + [(set_attr "type" "arith") + (set_attr "mode" "")]) + ;; Unaligned word moves generated by the bit field patterns. ;; ;; As far as the rtl is concerned, both the left-part and right-part Index: config/mips/mips-protos.h =================================================================== --- config/mips/mips-protos.h (revision 190403) +++ config/mips/mips-protos.h (working copy) @@ -310,6 +310,12 @@ extern bool mips16e_save_restore_pattern extern bool mask_low_and_shift_p (enum machine_mode, rtx, rtx, int); extern int mask_low_and_shift_len (enum machine_mode, rtx, rtx); + +extern int mips_bitmask (unsigned HOST_WIDE_INT, int *, enum machine_mode); +extern bool mips_bitmask_p (unsigned HOST_WIDE_INT); +extern bool mips_bitmask_ins_p (unsigned HOST_WIDE_INT, int, enum machine_mode); +extern bool mips_bottom_bitmask_p (unsigned HOST_WIDE_INT); + extern bool and_operands_ok (enum machine_mode, rtx, rtx); union mips_gen_fn_ptrs Index: config/mips/mips.c =================================================================== --- config/mips/mips.c (revision 190403) +++ config/mips/mips.c (working copy) @@ -7414,6 +7414,69 @@ mask_low_and_shift_len (enum machine_mod shval = INTVAL (shift) & (GET_MODE_BITSIZE (mode) - 1); return exact_log2 ((UINTVAL (mask) >> shval) + 1); } + +/* If X is a bitmask (consists of one consecutive block of ones) + return the position of the bottom bit and set *LEN to the length of + the bitmask. Otherwise return -1. MODE is the operation this + constant is used with. If VOIDmode LEN is not used an can be + passed as NULL. */ + +int +mips_bitmask (unsigned HOST_WIDE_INT x, int *len, enum machine_mode mode) +{ + int top, bottom; + + top = floor_log2 (x); + if (top == HOST_BITS_PER_WIDE_INT - 1) + x = -x; + else + x = ((unsigned HOST_WIDE_INT) 1 << (top + 1)) - x; + + bottom = exact_log2 (x); + if (mode == VOIDmode || bottom == -1) + return bottom; + + if (mode == SImode && top > 31) + { + if (top == 63) + top = 31; + else + gcc_unreachable (); + } + + *len = top - bottom + 1; + return bottom; +} + +/* True if X is a bitmask (consists of one consecutive block of + ones). */ + +bool +mips_bitmask_p (unsigned HOST_WIDE_INT x) +{ + return ISA_HAS_EXT_INS && mips_bitmask (x, NULL, VOIDmode) != -1; +} + +/* True if X is a bitmask in MODE and the starting of the bitmask is at + 0 and the length is the same as POS. */ +bool +mips_bitmask_ins_p (unsigned HOST_WIDE_INT x, int pos, enum machine_mode mode) +{ + int len, position; + if (!ISA_HAS_EXT_INS) + return 0; + position = mips_bitmask (x, &len, mode); + return position == 0 && len == pos; +} + +/* True if X is a bitmask (consists of one consecutive block of + ones) and only the bottom bits are set. */ + +bool +mips_bottom_bitmask_p (unsigned HOST_WIDE_INT x) +{ + return ISA_HAS_EXT_INS && mips_bitmask (x, NULL, VOIDmode) == 0; +} /* Return true if -msplit-addresses is selected and should be honored.