From patchwork Fri Mar 4 13:25:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 592048 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C8C67140213 for ; Sat, 5 Mar 2016 00:28:13 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=R8BX6KFa; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; q=dns; s=default; b=wnkKk6Jv+DBO1cc52Gs y8r/z/9HPSI3NX2XxGgH0SA/JXVWi4OtoqEI6NfBbrG4RXvf2gwOVk2I9BpOkcY3 q6RzYv7rCIzqDPgYLklOpDvF/pi+ijooym4xhNA+D9GzUg8jE7JBpCJ/eIo+ue9s f0rrWYVPpcAn2kuMmDW4Z3aI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; s=default; bh=IhUBqizF7hFX+JJsossomeoKd wk=; b=R8BX6KFarBrhvi5s0ycI+7/x7fpvzarXJCRe0QtspHWxTc+2RR5OU3dwl FzFBZnf1E5ul3l0g8qkODfgDnTD/xz/MKi9pUapJHvs/h70v52otW7DHi563i9jP itPn50zg39sOqPzKroPKFLt7kiATDfal4ssDazARWsP/A692Z8= Received: (qmail 44802 invoked by alias); 4 Mar 2016 13:26:24 -0000 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 Received: (qmail 44737 invoked by uid 89); 4 Mar 2016 13:26:23 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-0.3 required=5.0 tests=AWL, BAYES_40, LIKELY_SPAM_BODY, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 spammy=Position, nn, chi, cbn X-HELO: mail-wm0-f53.google.com Received: from mail-wm0-f53.google.com (HELO mail-wm0-f53.google.com) (74.125.82.53) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 04 Mar 2016 13:26:07 +0000 Received: by mail-wm0-f53.google.com with SMTP id n186so34788175wmn.1 for ; Fri, 04 Mar 2016 05:26:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=MY58zVs4lPHRhtQpAL+4TCyfRC1mbX2td9Zk/1JLB9U=; b=UajmJ0FZ/WXD3vTiuttQl+qv1zJIcfvuSR7i39DDXNp/BOjRUSnPZoLR4WJxRQ5Vfh ZhrcfjNZfCkiNSCTJX0emRpyN5oK6mrrnsX4NPay2TiN99VYnc9RXBHR0FsWgV5QoDZO 5mxzEvLIvWJG4cdPR4Fq/KvXsXpeS8L6UHBqMnVpEIpgfZW/aGo37pJHD1/akqofDisJ gmeGKKET3K+mgS1SMgg8wEqtL+REdorNbBKLYAHsuxmXFxeAWMeBbXw+AuB7R2naAnUN bQ+cG0lhiqXD50p8sSsODhsh2ar+qWb1gwUSGNuReF5YzXGA6XmHAC/qNkclmTEg2bgD 7phw== X-Gm-Message-State: AD7BkJKVp75aTz8XABEXTBL3P7IS3janIMK3OE0/suV+ECo8DNWjepFs8OC/pDNzaVgF5w== X-Received: by 10.194.119.201 with SMTP id kw9mr9925792wjb.173.1457097964323; Fri, 04 Mar 2016 05:26:04 -0800 (PST) Received: from localhost (host86-138-94-184.range86-138.btcentralplus.com. [86.138.94.184]) by smtp.gmail.com with ESMTPSA id h128sm3327354wmf.23.2016.03.04.05.26.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Mar 2016 05:26:03 -0800 (PST) From: Andrew Burgess To: gcc-patches@gcc.gnu.org Cc: noamca@mellanox.com, Claudiu.Zissulescu@synopsys.com, Andrew Burgess Subject: [PATCH 07/10] gcc/arc: Add nps400 bitops support Date: Fri, 4 Mar 2016 13:25:39 +0000 Message-Id: <90a078f4c7d4a8caeacda49886443bcd23f5d25e.1457097757.git.andrew.burgess@embecosm.com> In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes Add support for nps400 bit operation instructions. There's a new flag -mbitops that turns this feature on. There are new instructions, some changes to existing instructions, a new register class to support the new instructions, and some new expand and peephole optimisations. gcc/ChangeLog: * config/arc/arc.c (arc_conditional_register_usage): Take TARGET_RRQ_CLASS into account. (arc_print_operand): Support printing 'p' and 's' operands. * config/arc/arc.h (TARGET_NPS400_BITOPS_DEFAULT): Provide default as 0. (TARGET_RRQ_CLASS): Define. (IS_POWEROF2_OR_0_P): Define. * config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi alternatives. (*tst_movb): New define_insn. (*tst): Avoid recognition if it could prevent '*tst_movb' combination; replace c/CnL with c/Chs alternative. (*tst_bitfield_tst): New define_insn. (*tst_bitfield_asr): New define_insn. (*tst_bitfield): New define_insn. (andsi3_i): Add Rrq variant. (extzv): New define_expand. (insv): New define_expand. (*insv_i): New define_insn. (*movb): New define_insn. (*movb_signed): New define_insn. (*movb_high): New define_insn. (*movb_high_signed): New define_insn. (*movb_high_signed + 1): New define_split pattern. (*mrgb): New define_insn. (*mrgb + 1): New define_peephole2 pattern. (*mrgb + 2): New define_peephole2 pattern. * config/arc/arc.opt (mbitops): New option for nps400, uses TARGET_NPS400_BITOPS_DEFAULT. * config/arc/constraints.md (q): Make register class conditional. (Rrq): New register constraint. (Chs): New constraint. (Clo): New constraint. (Chi): New constraint. (Cbf): New constraint. (Cbn): New constraint. (C18): New constraint. (Cbi): New constraint. gcc/testsuite/ChangeLog: * gcc.target/arc/extzv-1.c: New file. * gcc.target/arc/insv-1.c: New file. * gcc.target/arc/insv-2.c: New file. * gcc.target/arc/movb-1.c: New file. * gcc.target/arc/movb-2.c: New file. * gcc.target/arc/movb-3.c: New file. * gcc.target/arc/movb-4.c: New file. * gcc.target/arc/movb-5.c: New file. * gcc.target/arc/movb_cl-1.c: New file. * gcc.target/arc/movb_cl-2.c: New file. * gcc.target/arc/movbi_cl-1.c: New file. * gcc.target/arc/movl-1.c: New file. * gcc.target/arc/mrgb-1.c: New file. --- gcc/ChangeLog.NPS400 | 42 ++++ gcc/config/arc/arc.c | 33 ++- gcc/config/arc/arc.h | 9 + gcc/config/arc/arc.md | 382 ++++++++++++++++++++++++++---- gcc/config/arc/arc.opt | 4 + gcc/config/arc/constraints.md | 58 ++++- gcc/testsuite/ChangeLog.NPS400 | 17 ++ gcc/testsuite/gcc.target/arc/extzv-1.c | 11 + gcc/testsuite/gcc.target/arc/insv-1.c | 21 ++ gcc/testsuite/gcc.target/arc/insv-2.c | 18 ++ gcc/testsuite/gcc.target/arc/movb-1.c | 13 + gcc/testsuite/gcc.target/arc/movb-2.c | 13 + gcc/testsuite/gcc.target/arc/movb-3.c | 13 + gcc/testsuite/gcc.target/arc/movb-4.c | 13 + gcc/testsuite/gcc.target/arc/movb-5.c | 13 + gcc/testsuite/gcc.target/arc/movb_cl-1.c | 9 + gcc/testsuite/gcc.target/arc/movb_cl-2.c | 11 + gcc/testsuite/gcc.target/arc/movbi_cl-1.c | 9 + gcc/testsuite/gcc.target/arc/movl-1.c | 17 ++ gcc/testsuite/gcc.target/arc/mrgb-1.c | 14 ++ 20 files changed, 663 insertions(+), 57 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arc/extzv-1.c create mode 100644 gcc/testsuite/gcc.target/arc/insv-1.c create mode 100644 gcc/testsuite/gcc.target/arc/insv-2.c create mode 100644 gcc/testsuite/gcc.target/arc/movb-1.c create mode 100644 gcc/testsuite/gcc.target/arc/movb-2.c create mode 100644 gcc/testsuite/gcc.target/arc/movb-3.c create mode 100644 gcc/testsuite/gcc.target/arc/movb-4.c create mode 100644 gcc/testsuite/gcc.target/arc/movb-5.c create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-1.c create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-2.c create mode 100644 gcc/testsuite/gcc.target/arc/movbi_cl-1.c create mode 100644 gcc/testsuite/gcc.target/arc/movl-1.c create mode 100644 gcc/testsuite/gcc.target/arc/mrgb-1.c diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400 index 2a0f820..8229d67 100644 --- a/gcc/ChangeLog.NPS400 +++ b/gcc/ChangeLog.NPS400 @@ -1,3 +1,45 @@ +2013-02-19 Joern Rennecke + Andrew Burgess + + * config/arc/arc.c (arc_conditional_register_usage): Take + TARGET_RRQ_CLASS into account. + (arc_print_operand): Support printing 'p' and 's' operands. + * config/arc/arc.h (TARGET_NPS400_BITOPS_DEFAULT): Provide default + as 0. + (TARGET_RRQ_CLASS): Define. + (IS_POWEROF2_OR_0_P): Define. + * config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi + alternatives. + (*tst_movb): New define_insn. + (*tst): Avoid recognition if it could prevent '*tst_movb' + combination; replace c/CnL with c/Chs alternative. + (*tst_bitfield_tst): New define_insn. + (*tst_bitfield_asr): New define_insn. + (*tst_bitfield): New define_insn. + (andsi3_i): Add Rrq variant. + (extzv): New define_expand. + (insv): New define_expand. + (*insv_i): New define_insn. + (*movb): New define_insn. + (*movb_signed): New define_insn. + (*movb_high): New define_insn. + (*movb_high_signed): New define_insn. + (*movb_high_signed + 1): New define_split pattern. + (*mrgb): New define_insn. + (*mrgb + 1): New define_peephole2 pattern. + (*mrgb + 2): New define_peephole2 pattern. + * config/arc/arc.opt (mbitops): New option for nps400, uses + TARGET_NPS400_BITOPS_DEFAULT. + * config/arc/constraints.md (q): Make register class conditional. + (Rrq): New register constraint. + (Chs): New constraint. + (Clo): New constraint. + (Chi): New constraint. + (Cbf): New constraint. + (Cbn): New constraint. + (C18): New constraint. + (Cbi): New constraint. + 2013-08-31 Joern Rennecke Andrew Burgess diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 25ff693..a75f200 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -1371,7 +1371,8 @@ arc_conditional_register_usage (void) { if (i < 29) { - if (TARGET_Q_CLASS && ((i <= 3) || ((i >= 12) && (i <= 15)))) + if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS) + && ((i <= 3) || ((i >= 12) && (i <= 15)))) arc_regno_reg_class[i] = ARCOMPACT16_REGS; else arc_regno_reg_class[i] = GENERAL_REGS; @@ -1388,12 +1389,12 @@ arc_conditional_register_usage (void) arc_regno_reg_class[i] = NO_REGS; } - /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS has not been activated. */ + /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS + has not been activated. */ + if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS) + CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]); if (!TARGET_Q_CLASS) - { - CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]); - CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]); - } + CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]); gcc_assert (FIRST_PSEUDO_REGISTER >= 144); @@ -2935,6 +2936,8 @@ static int output_scaled = 0; 'Z': log2(x+1)-1 'z': log2 'M': log2(~x) + 'p': bit Position of lsb + 's': size of bit field '#': condbranch delay slot suffix '*': jump delay slot suffix '?' : nonjump-insn suffix for conditional execution or short instruction @@ -2985,6 +2988,24 @@ arc_print_operand (FILE *file, rtx x, int code) return; + case 'p': + if (GET_CODE (x) == CONST_INT) + fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x))); + else + output_operand_lossage ("invalid operand to %%p code"); + return; + + case 's': + if (GET_CODE (x) == CONST_INT) + { + HOST_WIDE_INT i = INTVAL (x); + HOST_WIDE_INT s = exact_log2 (i & -i); + fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1)); + } + else + output_operand_lossage ("invalid operand to %%s code"); + return; + case '#' : /* Conditional branches depending on condition codes. Note that this is only for branches that were known to depend on diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index 28c3ef1..f278bf5 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -318,10 +318,18 @@ along with GCC; see the file COPYING3. If not see #define UNALIGNED_ACCESS_DEFAULT 0 #endif +#ifndef TARGET_NPS400_BITOPS_DEFAULT +#define TARGET_NPS400_BITOPS_DEFAULT 0 +#endif + #ifndef TARGET_NPS400_CMEM_DEFAULT #define TARGET_NPS400_CMEM_DEFAULT 0 #endif +/* Enable the RRQ instruction alternatives. */ + +#define TARGET_RRQ_CLASS TARGET_NPS400_BITOPS + /* Target machine storage layout. */ /* We want zero_extract to mean the same @@ -1025,6 +1033,7 @@ extern int arc_initial_elimination_offset(int from, int to); /* Is the argument a const_int rtx, containing an exact power of 2 */ #define IS_POWEROF2_P(X) (! ( (X) & ((X) - 1)) && (X)) +#define IS_POWEROF2_OR_0_P(X) (! ( (X) & ((X) - 1))) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index 33e6dee..e318fc8 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -691,8 +691,8 @@ ; insns it should lengthen the return insn. ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . (define_insn "*movsi_insn" - [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w, w,???w, ?w, w,Rcq#q, w,Rcq, S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc") - (match_operand:SI 1 "move_src_operand" " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))] + [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,w,w,w,w,???w,?w,w,Rcq#q,w,Rcq,S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc") + (match_operand:SI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))] "register_operand (operands[0], SImode) || register_operand (operands[1], SImode) || (CONSTANT_P (operands[1]) @@ -707,29 +707,32 @@ mov%? %0,%1 ;3 mov%? %0,%1 ;4 ror %0,((%1*2+1) & 0x3f) ;5 - mov%? %0,%1 ;6 - add %0,%S1 ;7 + movl.cl %0,%1 ;6 + movh.cl %0,%L1>>16 ;7 + * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\"; + mov%? %0,%1 ;9 + add %0,%S1 ;10 * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\"; - mov%? %0,%S1%& ;9 - mov%? %0,%S1 ;10 - ld%? %0,%1%& ;11 - st%? %1,%0%& ;12 + mov%? %0,%S1%& ;12 + mov%? %0,%S1 ;13 + ld%? %0,%1%& ;14 + st%? %1,%0%& ;15 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\"); * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\"); - ld%? %0,%1%& ;15 - xld%U1 %0,%1 ;16 - ld%U1%V1 %0,%1 ;17 - xst%U0 %1,%0 ;18 - st%U0%V0 %1,%0 ;19 - st%U0%V0 %1,%0 ;20 - st%U0%V0 %S1,%0 ;21" - [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store") - (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false") + ld%? %0,%1%& ;18 + xld%U1 %0,%1 ;19 + ld%U1%V1 %0,%1 ;20 + xst%U0 %1,%0 ;21 + st%U0%V0 %1,%0 ;22 + st%U0%V0 %1,%0 ;23 + st%U0%V0 %S1,%0 ;24" + [(set_attr "type" "move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store") + (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false") ; Use default length for iscompact to allow for COND_EXEC. But set length ; of Crr to 4. - (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8") - (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no") - (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) + (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8") + (set_attr "predicable" "yes,no,yes,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no") + (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) ;; Sometimes generated by the epilogue code. We don't want to ;; recognize these addresses in general, because the limm is costly, @@ -800,6 +803,24 @@ (set_attr "cond" "set_zn") (set_attr "length" "4")]) +; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees +; a c/???Cal/X alternative, so we say it's c/???Cal/c instead, +; even if we don't need the clobber. +(define_insn_and_split "*tst_movb" + [(set + (match_operand 0 "cc_register" "") + (match_operator 4 "zn_compare_operator" + [(and:SI + (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq, 3, c") + (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal")) + (const_int 0)])) + (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))] + "TARGET_NPS400_BITOPS" + "movb.f.cl %3,%1,%p2,%p2,%s2" + "reload_completed + && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)" + [(set (match_dup 0) (match_dup 4))]) + (define_insn "*tst" [(set (match_operand 0 "cc_register" "") @@ -808,12 +829,14 @@ (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c, c, c") (match_operand:SI 2 "nonmemory_operand" - " Rcq,C0p,cI,cL,C1p,Ccp,CnL,Cal")) + " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal")) (const_int 0)]))] - "(register_operand (operands[1], SImode) - && nonmemory_operand (operands[2], SImode)) - || (memory_operand (operands[1], SImode) - && satisfies_constraint_Cux (operands[2]))" + "reload_completed + || !satisfies_constraint_Cbf (operands[2]) + || satisfies_constraint_C0p (operands[2]) + || satisfies_constraint_I (operands[2]) + || satisfies_constraint_C1p (operands[2]) + || satisfies_constraint_Chs (operands[2])" "* switch (which_alternative) { @@ -826,17 +849,79 @@ case 5: return \"bclr%?.f 0,%1,%M2%&\"; case 6: - return \"bic%?.f 0,%1,%n2-1\"; + return \"asr.f 0,%1,%p2\"; default: gcc_unreachable (); } " [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false") - (set_attr "type" "compare") + (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare") (set_attr "length" "*,*,4,4,4,4,4,8") (set_attr "predicable" "no,yes,no,yes,no,no,no,yes") (set_attr "cond" "set_zn")]) +; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract, +; combine will do that and not try the AND. + +; It would take 66 constraint combinations to describe the zero_extract +; constants that are covered by the 12-bit signed constant for tst +; (excluding the ones that are better done by mov or btst). +; so we rather use an extra pattern for tst; +; since this is about constants, reload shouldn't care. +(define_insn "*tst_bitfield_tst" + [(set (match_operand:CC_ZN 0 "cc_set_register" "") + (match_operator 4 "zn_compare_operator" + [(zero_extract:SI + (match_operand:SI 1 "register_operand" "c") + (match_operand:SI 2 "const_int_operand" "n") + (match_operand:SI 3 "const_int_operand" "n")) + (const_int 0)]))] + "INTVAL (operands[2]) > 1 + && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11 + || (INTVAL (operands[3]) <= 11 + && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))" + "tst %1,(1<<%2)-1<<%3" + [(set_attr "type" "compare") + (set_attr "cond" "set_zn") + (set_attr "length" "4")]) + +; Likewise for asr.f. +(define_insn "*tst_bitfield_asr" + [(set (match_operand:CC_ZN 0 "cc_set_register" "") + (match_operator 4 "zn_compare_operator" + [(zero_extract:SI + (match_operand:SI 1 "register_operand" "c") + (match_operand:SI 2 "const_int_operand" "n") + (match_operand:SI 3 "const_int_operand" "n")) + (const_int 0)]))] + "INTVAL (operands[2]) > 1 + && INTVAL (operands[3]) + INTVAL (operands[2]) == 32" + "asr.f 0,%1,%3" + [(set_attr "type" "shift") + (set_attr "cond" "set_zn") + (set_attr "length" "4")]) + +(define_insn "*tst_bitfield" + [(set (match_operand:CC_ZN 0 "cc_set_register" "") + (match_operator 5 "zn_compare_operator" + [(zero_extract:SI + (match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c") + (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n") + (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n")) + (const_int 0)])) + (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))] + "" + "@ + btst%? %1,%3 + btst %1,%3 + bmsk.f 0,%1,%2-1 + movb.f.cl %4,%1,%3,%3,%2 + and.f 0,%1,((1<<%2)-1)<<%3" + [(set_attr "iscompact" "maybe,false,false,false,false") + (set_attr "type" "compare,compare,compare,shift,compare") + (set_attr "cond" "set_zn") + (set_attr "length" "*,4,4,4,8")]) + (define_insn "*commutative_binary_comparison" [(set (match_operand:CC_ZN 0 "cc_set_register" "") (match_operator:CC_ZN 5 "zn_compare_operator" @@ -2947,30 +3032,40 @@ operands[1] = arc_rewrite_small_data (operands[1]);") (define_insn "andsi3_i" - [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw, w, w, w, w,w,Rcw, w, W") - (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,0, 0, c, o") - (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, C1p, Ccp, Cux, cL, 0,C1p,Ccp,CnL, I, Lc,C1p,Ccp,CnL,I,Cal,Cal,Cux")))] + [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,w,w,w,w,Rrq,w,Rcw,w,W") + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,0,0,Rcqq,0,c,0,0,0,0,c,c,c,c,Rrq,0,0,c,o") + (match_operand:SI 2 "nonmemory_operand" "Rcqq,0,C1p,Ccp,Cux,cL,0,C1p,Ccp,CnL,I,Lc,C1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))] "(register_operand (operands[1], SImode) && nonmemory_operand (operands[2], SImode)) || (memory_operand (operands[1], SImode) && satisfies_constraint_Cux (operands[2]))" - "* { switch (which_alternative) { - case 0: case 5: case 10: case 11: case 15: case 16: case 17: - return \"and%? %0,%1,%2%&\"; + case 0: case 5: case 10: case 11: case 16: case 17: case 18: + return "and%? %0,%1,%2%&"; case 1: case 6: - return \"and%? %0,%2,%1%&\"; + return "and%? %0,%2,%1%&"; case 2: case 7: case 12: - return \"bmsk%? %0,%1,%Z2%&\"; + return "bmsk%? %0,%1,%Z2%&"; case 3: case 8: case 13: - return \"bclr%? %0,%1,%M2%&\"; + return "bclr%? %0,%1,%M2%&"; case 4: return (INTVAL (operands[2]) == 0xff - ? \"extb%? %0,%1%&\" : \"ext%_%? %0,%1%&\"); + ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&"); case 9: case 14: return \"bic%? %0,%1,%n2-1\"; - case 18: + case 15: + return "movb.cl %0,%1,%p2,%p2,%s2"; + + case 19: + const char *tmpl; + + if (satisfies_constraint_Ucm (operands[1])) + tmpl = (INTVAL (operands[2]) == 0xff + ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1"); + else + tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1"; + if (TARGET_BIG_ENDIAN) { rtx xop[2]; @@ -2978,21 +3073,19 @@ xop[0] = operands[0]; xop[1] = adjust_address (operands[1], QImode, INTVAL (operands[2]) == 0xff ? 3 : 2); - output_asm_insn (INTVAL (operands[2]) == 0xff - ? \"ldb %0,%1\" : \"ld%_ %0,%1\", - xop); - return \"\"; + output_asm_insn (tmpl, xop); + return ""; } - return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ld%_ %0,%1\"; + return tmpl; default: gcc_unreachable (); } -}" - [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false") - (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load") - (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*") - (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,yes,no,no") - (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")]) +} + [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false") + (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load") + (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*") + (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no") + (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")]) ; combiner splitter, pattern found in ldtoa.c . ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1 @@ -5642,7 +5735,6 @@ [(set_attr "length" "4") (set_attr "type" "misc")]) - ;; FPU/FPX expands ;;add @@ -5785,6 +5877,196 @@ gcc_unreachable (); ") +(define_expand "extzv" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extract:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "const_int_operand" "") + (match_operand:SI 3 "const_int_operand" "")))] + "TARGET_NPS400_BITOPS") + +; We need a sanity check in the instuction predicate because combine +; will throw any old rubbish at us and see what sticks. +(define_insn "*extzv_i" + [(set (match_operand:SI 0 "register_operand" "=Rrq") + (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq") + (match_operand:SI 2 "const_int_operand" "n") + (match_operand:SI 3 "const_int_operand" "n")))] + "TARGET_NPS400_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32" + "movb.cl %0,%1,0,%3,%2" + [(set_attr "type" "shift") + (set_attr "length" "4")]) + +(define_expand "insv" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "const_int_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand:SI 3 "nonmemory_operand" ""))] + "TARGET_NPS400_BITOPS" +{ + int size = INTVAL (operands[1]); + + if (size != 1 && size != 2 && size != 4 && size != 8) + operands[3] = force_reg (SImode, operands[3]); +}) + +(define_insn "*insv_i" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq") + (match_operand:SI 1 "const_int_operand" "C18,n") + (match_operand:SI 2 "const_int_operand" "n,n")) + (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))] + "TARGET_NPS400_BITOPS + && (register_operand (operands[3], SImode) + || satisfies_constraint_C18 (operands[1]))" + "@ + movbi %0,%0,%3,%2,%1 + movb %0,%0,%3,%2,0,%1" + [(set_attr "type" "shift") + (set_attr "length" "4")]) + +(define_insn "*movb" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) + (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq") + (match_dup 1) + (match_operand:SI 4 "const_int_operand" "n")))] + "TARGET_NPS400_BITOPS" + "movb %0,%0,%3,%2,%4,%1" + [(set_attr "type" "shift") + (set_attr "length" "4")]) + +(define_insn "*movb_signed" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) + (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq") + (match_dup 1) + (match_operand:SI 4 "const_int_operand" "n")))] + "TARGET_NPS400_BITOPS" + "movb %0,%0,%3,%2,%4,%1" + [(set_attr "type" "shift") + (set_attr "length" "4")]) + +(define_insn "*movb_high" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) + (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq") + (match_operand:SI 4 "const_int_operand" "n")))] + "TARGET_NPS400_BITOPS + && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32" + "movb %0,%0,%3,%2,%4,%1" + [(set_attr "type" "shift") + (set_attr "length" "4")]) + +; N.B.: when processing signed bitfields that fit in the top half of +; a word, gcc will use a narrow sign extending load, and in this case +; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8) +(define_insn "*movb_high_signed" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) + (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq") + (match_operand:SI 4 "const_int_operand" "n")))] + "TARGET_NPS400_BITOPS + && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32" + "movb %0,%0,%3,%2,%4,%1" + [(set_attr "type" "shift") + (set_attr "length" "4")]) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (subreg:SI (match_operand 3 "") 0)))] + "TARGET_NPS400_BITOPS + && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2]) + && !reg_overlap_mentioned_p (operands[0], operands[1])" + [(set (match_dup 0) (zero_extend:SI (match_dup 3))) + (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2)) + (match_dup 1))] + "operands[4] = GEN_INT (32 - INTVAL (operands[2]));") + +(define_insn "*mrgb" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) + (zero_extract:SI (match_dup 0) (match_dup 1) + (match_operand:SI 3 "const_int_operand" "n"))) + (set (zero_extract:SI (match_dup 0) + (match_operand:SI 4 "const_int_operand" "n") + (match_operand:SI 5 "const_int_operand" "n")) + (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq") + (match_dup 4) + (match_operand:SI 7 "const_int_operand" "n")))] + "TARGET_NPS400_BITOPS" +{ + output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands); + /* The ;%? updates the known unalignment. */ + return arc_short_long (insn, ";%?", "nop_s"); +} + [(set_attr "type" "shift") + (set_attr "length" "6") + (set_attr "iscompact" "true")]) + +;; combine fumbles combination of two movb patterns, and then the +;; combination is rejected by combinable_i3pat. +;; Thus, we can only use a peephole2 to combine two such insns. + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "register_operand" "")) + (set (zero_extract:SI (match_dup 0) + (match_operand:SI 2 "const_int_operand" "") + (match_operand:SI 3 "const_int_operand" "")) + (zero_extract:SI (match_dup 1) + (match_dup 2) + (match_operand:SI 4 "const_int_operand" ""))) + (match_operand 9) ; unrelated insn scheduled here + (set (zero_extract:SI (match_dup 0) + (match_operand:SI 5 "const_int_operand" "") + (match_operand:SI 6 "const_int_operand" "")) + (zero_extract:SI (match_operand:SI 7 "register_operand" "") + (match_dup 5) + (match_operand:SI 8 "const_int_operand" "")))] + "TARGET_NPS400_BITOPS + // Check that the second movb doesn't clobber an input of the extra insn. + && !reg_overlap_mentioned_p (operands[0], operands[9]) + // And vice versa. + && !reg_set_p (operands[0], operands[9]) + && !reg_set_p (operands[7], operands[9])" + [(set (match_dup 0) (match_dup 1)) + (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) + (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4))) + (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) + (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))]) + (match_dup 9)]) + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "register_operand" "")) + (set (zero_extract:SI (match_dup 0) + (match_operand:SI 2 "const_int_operand" "") + (match_operand:SI 3 "const_int_operand" "")) + (zero_extract:SI (match_dup 1) + (match_dup 2) + (match_operand:SI 4 "const_int_operand" ""))) + (set (match_dup 1) (match_operand 8)) + (set (zero_extract:SI (match_dup 0) + (match_operand:SI 5 "const_int_operand" "") + (match_operand:SI 6 "const_int_operand" "")) + (zero_extract:SI (match_dup 1) (match_dup 5) + (match_operand:SI 7 "const_int_operand" "")))] + "TARGET_NPS400_BITOPS + && !reg_overlap_mentioned_p (operands[0], operands[8])" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 1) (match_dup 8)) + (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3)) + (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4))) + (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6)) + (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))]) + (match_dup 1)]) + ;; include the arc-FPX instructions (include "fpx.md") diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt index 4816238..3411599 100644 --- a/gcc/config/arc/arc.opt +++ b/gcc/config/arc/arc.opt @@ -457,6 +457,10 @@ Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD) EnumValue Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD) +mbitops +Target Report Var(TARGET_NPS400_BITOPS) Init(TARGET_NPS400_BITOPS_DEFAULT) Condition(ARC_NPS400) +Enable use of NPS400 bit operations. + mcmem Target Report Var(TARGET_NPS400_CMEM) Init(TARGET_NPS400_CMEM_DEFAULT) Condition(ARC_NPS400) Enable use of NPS400 xld/xst extension. diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md index 409e7d6..37370dd 100644 --- a/gcc/config/arc/constraints.md +++ b/gcc/config/arc/constraints.md @@ -66,10 +66,18 @@ Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30}, @code{blink}:@code{r31},") -(define_register_constraint "q" "ARCOMPACT16_REGS" +(define_register_constraint "q" "TARGET_Q_CLASS ? ARCOMPACT16_REGS : NO_REGS" "Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}") +; NPS400 bitfield instructions require registers from the r0-r3,r12-r15 +; range, and thus we need a register class and constraint that works +; independently of size optimization. +(define_register_constraint + "Rrq" "TARGET_RRQ_CLASS ? ARCOMPACT16_REGS : NO_REGS" + "Registers usable in NPS400 bitfield instructions: @code{r0}-@code{r3}, + @code{r12}-@code{r15}") + (define_register_constraint "e" "AC16_BASE_REGS" "Registers usable as base-regs of memory addresses in ARCompact 16-bit memory instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}") @@ -236,12 +244,60 @@ (and (match_code "const_int") (match_test "ival == 0xff || ival == 0xffff"))) +(define_constraint "Chs" + "@internal + constant for a highpart that can be checked with a shift (asr.f 0,rn,m)" + (and (match_code "const_int") + (match_test "IS_POWEROF2_P (-ival)"))) + +(define_constraint "Clo" + "@internal + constant that fits into 16 lower bits, for movl" + (and (match_code "const_int") + (match_test "TARGET_NPS400_BITOPS") + (match_test "(ival & ~0xffffU) == 0"))) + +(define_constraint "Chi" + "@internal + constant that fits into 16 higher bits, for movh_i" + (and (match_code "const_int") + (match_test "TARGET_NPS400_BITOPS") + (match_test "trunc_int_for_mode (ival >> 16, HImode) << 16 == ival"))) + +(define_constraint "Cbf" + "@internal + a mask for a bit field, for AND using movb_i" + (and (match_code "const_int") + (match_test "TARGET_NPS400_BITOPS") + (match_test "IS_POWEROF2_OR_0_P (ival + (ival & -ival))"))) + +(define_constraint "Cbn" + "@internal + a constant integer, valid only if TARGET_NPS400_BITOPS is true" + (and (match_code "const_int") + (match_test "TARGET_NPS400_BITOPS"))) + +(define_constraint "C18" + "@internal + 1,2,4 or 8" + (and (match_code "const_int") + (match_test "ival == 1 || ival == 2 || ival == 4 || ival == 8"))) + (define_constraint "Crr" "@internal constant that can be loaded with ror b,u6" (and (match_code "const_int") (match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()"))) +(define_constraint "Cbi" + "@internal + constant that can be loaded with movbi.cl" + (and (match_code "const_int") + (match_test "TARGET_NPS400_BITOPS") + (match_test "!ival + || ((ival & 0xffffffffUL) >> exact_log2 (ival & -ival) + <= 0xff)"))) + ;; Floating-point constraints (define_constraint "G" diff --git a/gcc/testsuite/ChangeLog.NPS400 b/gcc/testsuite/ChangeLog.NPS400 index bc5e68c..22dec32 100644 --- a/gcc/testsuite/ChangeLog.NPS400 +++ b/gcc/testsuite/ChangeLog.NPS400 @@ -1,3 +1,20 @@ +2013-02-19 Joern Rennecke + Andrew Burgess + + * gcc.target/arc/extzv-1.c: New file. + * gcc.target/arc/insv-1.c: New file. + * gcc.target/arc/insv-2.c: New file. + * gcc.target/arc/movb-1.c: New file. + * gcc.target/arc/movb-2.c: New file. + * gcc.target/arc/movb-3.c: New file. + * gcc.target/arc/movb-4.c: New file. + * gcc.target/arc/movb-5.c: New file. + * gcc.target/arc/movb_cl-1.c: New file. + * gcc.target/arc/movb_cl-2.c: New file. + * gcc.target/arc/movbi_cl-1.c: New file. + * gcc.target/arc/movl-1.c: New file. + * gcc.target/arc/mrgb-1.c: New file. + 2013-08-09 Joern Rennecke Andrew Burgess diff --git a/gcc/testsuite/gcc.target/arc/extzv-1.c b/gcc/testsuite/gcc.target/arc/extzv-1.c new file mode 100644 index 0000000..465a377 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/extzv-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +struct foo { unsigned a: 3, b: 5, c: 24; }; + +int +f (struct foo i) +{ + return i.b; +} +/* { dg-final { scan-assembler "movb\.cl" } } */ diff --git a/gcc/testsuite/gcc.target/arc/insv-1.c b/gcc/testsuite/gcc.target/arc/insv-1.c new file mode 100644 index 0000000..cbba28e --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/insv-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +/* ??? Irrespective of insn set, generated code for this is a mess. */ +struct foo { unsigned a: 3, b: 8, c: 21; }; + +struct foo +f (struct foo i) +{ + i.b = 42; + return i; +} + +struct foo +g (struct foo i, int j) +{ + i.b = j; + return i; +} +/* { dg-final { scan-assembler "movbi\[ \t\]" } } */ +/* { dg-final { scan-assembler "movb\[ \t\]" } } */ diff --git a/gcc/testsuite/gcc.target/arc/insv-2.c b/gcc/testsuite/gcc.target/arc/insv-2.c new file mode 100644 index 0000000..7c468b3 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/insv-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +struct foo { unsigned a: 3, b: 8, c: 21; } bar; + +void +f (void) +{ + bar.b = 42; +} + +void +g (int j) +{ + bar.b = j; +} +/* { dg-final { scan-assembler "movbi\[ \t\]" } } */ +/* { dg-final { scan-assembler "movb\[ \t\]" } } */ diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c new file mode 100644 index 0000000..bcd9ea3 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movb-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +struct { unsigned a: 5, b: 8, c: 19; } foo; +struct { unsigned a: 3, b: 8, c: 21; } bar; + +void +f (void) +{ + bar.b = foo.b; +} +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */ +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c new file mode 100644 index 0000000..5d1aac8 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movb-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +struct { unsigned a: 23, b: 9; } foo; +struct { unsigned a: 23, b: 9; } bar; + +void +f (void) +{ + bar.b = foo.b; +} +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */ +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arc/movb-3.c b/gcc/testsuite/gcc.target/arc/movb-3.c new file mode 100644 index 0000000..77cac4a --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movb-3.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +struct { int a: 23, b: 9; } foo; +struct { int a: 23, b: 9; } bar; + +void +f (void) +{ + bar.a = foo.a; +} +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *23" { target arc-*-* } } } */ +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *9, *9, *23" { target arceb-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arc/movb-4.c b/gcc/testsuite/gcc.target/arc/movb-4.c new file mode 100644 index 0000000..c45e35a --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movb-4.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +struct { int a: 13, b: 19; } foo; +struct { int a: 13, b: 19; } bar; + +void +f (void) +{ + bar.b = foo.b; +} +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *13, *13, *19" { target arc-*-* } } } */ +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *19" { target arceb-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c new file mode 100644 index 0000000..6de13ae --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movb-5.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +struct { int a: 23, b: 9; } foo; +struct { int a: 23, b: 9; } bar; + +void +f (void) +{ + bar.b = foo.b; +} +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */ +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-1.c b/gcc/testsuite/gcc.target/arc/movb_cl-1.c new file mode 100644 index 0000000..7d2c388 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movb_cl-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +int +f (int i) +{ + return i & 0x0ffff000; +} +/* { dg-final { scan-assembler "movb\.cl" } } */ diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-2.c b/gcc/testsuite/gcc.target/arc/movb_cl-2.c new file mode 100644 index 0000000..21df97b --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movb_cl-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +extern void g (void); +int +f (int i) +{ + if (i & 0x0ffff000) + g (); +} +/* { dg-final { scan-assembler "movb\.f\.cl" } } */ diff --git a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c new file mode 100644 index 0000000..af74b22 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +int +f (int i) +{ + return 0x6e00; +} +/* { dg-final { scan-assembler "mov(bi|l)\.cl" } } */ diff --git a/gcc/testsuite/gcc.target/arc/movl-1.c b/gcc/testsuite/gcc.target/arc/movl-1.c new file mode 100644 index 0000000..f4f810a --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/movl-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +int +f (void) +{ + return 0xd00d; +} + +int +g (void) +{ + return 0x7ff00000; +} + +/* { dg-final { scan-assembler "movl\.cl\[ \t\]" } } */ +/* { dg-final { scan-assembler "movh\.cl\[ \t\]" } } */ diff --git a/gcc/testsuite/gcc.target/arc/mrgb-1.c b/gcc/testsuite/gcc.target/arc/mrgb-1.c new file mode 100644 index 0000000..11c9fe2 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/mrgb-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target arc*-mellanox-* } } */ +/* { dg-options "-O2 -mbitops" } */ + +struct { unsigned a: 5, b: 8, c: 8, d: 11; } foo; +struct { unsigned a: 3, b: 8, c: 21; } bar; + +void +f (void) +{ + foo.b = foo.c; + foo.c = bar.b; +} +/* { dg-final { scan-assembler "mrgb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *13, *8, *13, *3, *8" { target arc-*-* } } } */ +/* { dg-final { scan-assembler "mrgb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *11, *8, *11, *21, *8" { target arceb-*-* } } } */