From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 113445 invoked by alias); 29 Apr 2016 14:22:20 -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 113430 invoked by uid 89); 29 Apr 2016 14:22:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.0 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,LIKELY_SPAM_BODY,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=co, rtx_code, 0x00000000, sk:insn_is X-HELO: smtprelay.synopsys.com Received: from smtprelay4.synopsys.com (HELO smtprelay.synopsys.com) (198.182.47.9) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 29 Apr 2016 14:22:08 +0000 Received: from dc8secmta2.synopsys.com (dc8secmta2.synopsys.com [10.13.218.202]) by smtprelay.synopsys.com (Postfix) with ESMTP id B295B24E16C2; Fri, 29 Apr 2016 07:22:04 -0700 (PDT) Received: from dc8secmta2.internal.synopsys.com (dc8secmta2.internal.synopsys.com [127.0.0.1]) by dc8secmta2.internal.synopsys.com (Service) with ESMTP id 94488A4112; Fri, 29 Apr 2016 07:22:04 -0700 (PDT) Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by dc8secmta2.internal.synopsys.com (Service) with ESMTP id 500C6A4102; Fri, 29 Apr 2016 07:22:04 -0700 (PDT) Received: from mailhost.synopsys.com (localhost [127.0.0.1]) by mailhost.synopsys.com (Postfix) with ESMTP id 309BAC5A; Fri, 29 Apr 2016 07:22:04 -0700 (PDT) Received: from us01wehtc1.internal.synopsys.com (us01wehtc1.internal.synopsys.com [10.12.239.235]) by mailhost.synopsys.com (Postfix) with ESMTP id D0A3BC58; Fri, 29 Apr 2016 07:22:03 -0700 (PDT) Received: from IN01WEHTCB.internal.synopsys.com (10.144.199.106) by us01wehtc1.internal.synopsys.com (10.12.239.231) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 29 Apr 2016 07:22:03 -0700 Received: from IN01WEHTCA.internal.synopsys.com (10.144.199.103) by IN01WEHTCB.internal.synopsys.com (10.144.199.105) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 29 Apr 2016 19:52:00 +0530 Received: from nl20droid1.internal.synopsys.com (10.100.24.228) by IN01WEHTCA.internal.synopsys.com (10.144.199.243) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 29 Apr 2016 19:52:00 +0530 From: Claudiu Zissulescu To: CC: , , , Subject: [PATCH] [ARC] Add new ARCv2 instructions. Date: Fri, 29 Apr 2016 14:22:00 -0000 Message-ID: <1461939628-30722-1-git-send-email-claziss@synopsys.com> In-Reply-To: <57222A12.20909@amylaar.uk> References: <57222A12.20909@amylaar.uk> MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2016-04/txt/msg02017.txt.bz2 Please find the updated patch. Ok to commit? Claudiu gcc/ 2016-04-20 Claudiu Zissulescu * config/arc/arc-protos.h (compact_memory_operand_p): Declare. * config/arc/arc.c (arc_output_commutative_cond_exec): Consider bmaskn instruction. (arc_dwarf_register_span): Remove enum keyword. (compact_memory_operand_p): New function. * config/arc/arc.h (reg_class): Add code density register classes. (REG_CLASS_NAMES): Likewise. (REG_CLASS_CONTENTS): Likewise. * config/arc/arc.md (*movqi_insn): Add code density instructions. (*movhi_insn, *movsi_insn, *movsf_insn): Likewise. (*extendhisi2_i, andsi3_i, cmpsi_cc_insn_mixed): Likewise. (*cmpsi_cc_c_insn, *movsi_ne): Likewise. * config/arc/constraints.md (C2p, Uts, Cm1, Cm3, Ucd): New constraints. (h, Rcd, Rsd, Rzd): New register constraints. (T): Use compact_memory_operand_p function. * config/arc/predicates.md (compact_load_memory_operand): Remove. --- gcc/config/arc/arc-protos.h | 2 +- gcc/config/arc/arc.c | 146 +++++++++++++++++++++++++++++++++++++++ gcc/config/arc/arc.h | 9 +++ gcc/config/arc/arc.md | 154 ++++++++++++++++++++++++------------------ gcc/config/arc/constraints.md | 61 ++++++++++++++++- gcc/config/arc/predicates.md | 89 ------------------------ 6 files changed, 304 insertions(+), 157 deletions(-) diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h index 3bf28a0..8630e2d 100644 --- a/gcc/config/arc/arc-protos.h +++ b/gcc/config/arc/arc-protos.h @@ -44,7 +44,7 @@ extern void emit_shift (enum rtx_code, rtx, rtx, rtx); extern void arc_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx); extern void arc_split_compare_and_swap (rtx *); extern void arc_expand_compare_and_swap (rtx *); - +extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool); #endif /* RTX_CODE */ #ifdef TREE_CODE diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index dfaea7b..a54fddb 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -7389,6 +7389,11 @@ arc_output_commutative_cond_exec (rtx *operands, bool output_p) case AND: if (satisfies_constraint_C1p (operands[2])) pat = "bmsk%? %0,%1,%Z2"; + else if (satisfies_constraint_C2p (operands[2])) + { + operands[2] = GEN_INT ((~INTVAL (operands[2]))); + pat = "bmskn%? %0,%1,%Z2"; + } else if (satisfies_constraint_Ccp (operands[2])) pat = "bclr%? %0,%1,%M2"; else if (satisfies_constraint_CnL (operands[2])) @@ -9859,12 +9864,153 @@ arc_dwarf_register_span (rtx rtl) /* We can't inline this in INSN_REFERENCES_ARE_DELAYED because resource.h doesn't include the required header files. */ + bool insn_is_tls_gd_dispatch (rtx_insn *insn) { return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch; } +/* Return true if OP is an acceptable memory operand for ARCompact + 16-bit load instructions of MODE. + + AV2SHORT: TRUE if address needs to fit into the new ARCv2 short + non scaled instructions. + + SCALED: TRUE if address can be scaled. */ + +bool +compact_memory_operand_p (rtx op, machine_mode mode, + bool av2short, bool scaled) +{ + rtx addr, plus0, plus1; + int size, off; + + /* Eliminate non-memory operations. */ + if (GET_CODE (op) != MEM) + return 0; + + /* .di instructions have no 16-bit form. */ + if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET) + return false; + + if (mode == VOIDmode) + mode = GET_MODE (op); + + size = GET_MODE_SIZE (mode); + + /* dword operations really put out 2 instructions, so eliminate + them. */ + if (size > UNITS_PER_WORD) + return false; + + /* Decode the address now. */ + addr = XEXP (op, 0); + switch (GET_CODE (addr)) + { + case REG: + return (REGNO (addr) >= FIRST_PSEUDO_REGISTER + || COMPACT_GP_REG_P (REGNO (addr)) + || (SP_REG_P (REGNO (addr)) && (size != 2))); + case PLUS: + plus0 = XEXP (addr, 0); + plus1 = XEXP (addr, 1); + + if ((GET_CODE (plus0) == REG) + && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) + || COMPACT_GP_REG_P (REGNO (plus0))) + && ((GET_CODE (plus1) == REG) + && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) + || COMPACT_GP_REG_P (REGNO (plus1))))) + { + return !av2short; + } + + if ((GET_CODE (plus0) == REG) + && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) + || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short) + || (IN_RANGE (REGNO (plus0), 0, 31) && av2short)) + && (GET_CODE (plus1) == CONST_INT)) + { + bool valid = false; + + off = INTVAL (plus1); + + /* Negative offset is not supported in 16-bit load/store insns. */ + if (off < 0) + return 0; + + /* Only u5 immediates allowed in code density instructions. */ + if (av2short) + { + switch (size) + { + case 1: + return false; + case 2: + /* This is an ldh_s.x instruction, check the u6 + immediate. */ + if (COMPACT_GP_REG_P (REGNO (plus0))) + valid = true; + break; + case 4: + /* Only u5 immediates allowed in 32bit access code + density instructions. */ + if (REGNO (plus0) <= 31) + return ((off < 32) && (off % 4 == 0)); + break; + default: + return false; + } + } + else + if (COMPACT_GP_REG_P (REGNO (plus0))) + valid = true; + + if (valid) + { + + switch (size) + { + case 1: + return (off < 32); + case 2: + /* The 6-bit constant get shifted to fit the real + 5-bits field. Check also for the alignment. */ + return ((off < 64) && (off % 2 == 0)); + case 4: + return ((off < 128) && (off % 4 == 0)); + default: + return false; + } + } + } + + if (REG_P (plus0) && CONST_INT_P (plus1) + && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) + || SP_REG_P (REGNO (plus0))) + && !av2short) + { + off = INTVAL (plus1); + return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0)); + } + + if ((GET_CODE (plus0) == MULT) + && (GET_CODE (XEXP (plus0, 0)) == REG) + && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER) + || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0)))) + && (GET_CODE (plus1) == REG) + && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) + || COMPACT_GP_REG_P (REGNO (plus1)))) + return scaled; + default: + break ; + /* TODO: 'gp' and 'pcl' are to supported as base address operand + for 16-bit load instructions. */ + } + return false; +} + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-arc.h" diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h index bc14d11..f6b85ea 100644 --- a/gcc/config/arc/arc.h +++ b/gcc/config/arc/arc.h @@ -674,6 +674,9 @@ enum reg_class WRITABLE_CORE_REGS, /* 'w' */ CHEAP_CORE_REGS, /* 'c' */ ALL_CORE_REGS, /* 'Rac' */ + R0R3_CD_REGS, /* 'Rcd' */ + R0R1_CD_REGS, /* 'Rsd' */ + AC16_H_REGS, /* 'h' */ ALL_REGS, LIM_REG_CLASSES }; @@ -700,6 +703,9 @@ enum reg_class "MPY_WRITABLE_CORE_REGS", \ "WRITABLE_CORE_REGS", \ "CHEAP_CORE_REGS", \ + "R0R3_CD_REGS", \ + "R0R1_CD_REGS", \ + "AC16_H_REGS", \ "ALL_CORE_REGS", \ "ALL_REGS" \ } @@ -732,6 +738,9 @@ enum reg_class {0xffffffff, 0xd0000000, 0x00000000, 0x00000000, 0x00000000}, /* 'w', r0-r31, r60 */ \ {0xffffffff, 0xdfffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'c', r0-r60, ap, pcl */ \ {0xffffffff, 0xdfffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'Rac', r0-r60, ap, pcl */ \ + {0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rcd', r0-r3 */ \ + {0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rsd', r0-r1 */ \ + {0x9fffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'h', r0-28, r30 */ \ {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff} /* All Registers */ \ } diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index d1a9159..944c7fe 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -620,14 +620,15 @@ ; The iscompact attribute allows the epilogue expander to know for which ; insns it should lengthen the return insn. (define_insn "*movqi_insn" - [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,w,Rcq,S,!*x,r,r,Ucm,m,???m") - (match_operand:QI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))] + [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w, w,Rcq, S,!*x, r,r, Ucm,m,???m") + (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))] "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)" "@ mov%? %0,%1%& mov%? %0,%1%& mov%? %0,%1%& + mov%? %0,%1%& mov%? %0,%1 mov%? %0,%1 mov%? %0,%1 @@ -640,10 +641,10 @@ xstb%U0 %1,%0 stb%U0%V0 %1,%0 stb%U0%V0 %1,%0" - [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,load,store,store,store") - (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false,false,false") - (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no,no,no") - (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*")]) + [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store") + (set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,false,true,true,true,false,false,false,false,false") + (set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,no,no,no,no,no,no,no,no") + (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*")]) (define_expand "movhi" [(set (match_operand:HI 0 "move_dest_operand" "") @@ -652,8 +653,8 @@ "if (prepare_move_operands (operands, HImode)) DONE;") (define_insn "*movhi_insn" - [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,Rcq#q,w,Rcq,S,r,r,Ucm,m,???m,VUsc") - (match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,?i,T,Rcq,Ucm,m,?Rac,c,?Rac,i"))] + [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w,Rcq#q, w,Rcq, S, r,r, Ucm,m,???m,VUsc,VUsc") + (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac, ?i,?i, T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))] "register_operand (operands[0], HImode) || register_operand (operands[1], HImode) || (CONSTANT_P (operands[1]) @@ -665,6 +666,7 @@ mov%? %0,%1%& mov%? %0,%1%& mov%? %0,%1%& + mov%? %0,%1%& mov%? %0,%1 mov%? %0,%1 mov%? %0,%1 @@ -677,11 +679,12 @@ xst%_%U0 %1,%0 st%_%U0%V0 %1,%0 st%_%U0%V0 %1,%0 + st%_%U0%V0 %S1,%0 st%_%U0%V0 %S1,%0" - [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store") - (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false") - (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no") - (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*")]) + [(set_attr "type" "move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store") + (set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false,false") + (set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no") + (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")]) (define_expand "movsi" [(set (match_operand:SI 0 "move_dest_operand" "") @@ -699,9 +702,9 @@ ; the iscompact attribute allows the epilogue expander to know for which ; 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,???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"))] +(define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 + [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc") + (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))] "register_operand (operands[0], SImode) || register_operand (operands[1], SImode) || (CONSTANT_P (operands[1]) @@ -713,35 +716,40 @@ mov%? %0,%1%& ;0 mov%? %0,%1%& ;1 mov%? %0,%1%& ;2 - mov%? %0,%1 ;3 + mov%? %0,%1%& ;3 mov%? %0,%1 ;4 - ror %0,((%1*2+1) & 0x3f) ;5 - movl.cl %0,%1 ;6 - movh.cl %0,%L1>>16 ;7 + mov%? %0,%1 ;5 + ror %0,((%1*2+1) & 0x3f) ;6 + movl.cl %0,%1 ;7 + movh.cl %0,%L1>>16 ;8 * 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 + mov%? %0,%1 ;10 + add %0,%S1 ;11 * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\"; - mov%? %0,%S1%& ;12 - mov%? %0,%S1 ;13 - ld%? %0,%1%& ;14 - st%? %1,%0%& ;15 + mov%? %0,%S1%& ;13 + mov%? %0,%S1 ;14 + ld%? %0,%1%& ;15 + st%? %1,%0%& ;16 * 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%& ;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") + ld%? %0,%1%& ;19 + xld%U1 %0,%1 ;20 + ld%? %0,%1%& ;21 + ld%? %0,%1%& ;22 + ld%U1%V1 %0,%1 ;23 + xst%U0 %1,%0 ;24 + st%? %1,%0%& ;25 + st%U0%V0 %1,%0 ;26 + st%U0%V0 %1,%0 ;27 + st%U0%V0 %1,%0 ;28 + st%U0%V0 %S1,%0 ;29" + [(set_attr "type" "move,move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,load,load,store,store,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,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,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,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) + (set_attr "length" "*,*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8") + (set_attr "predicable" "yes,no,yes,no,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no") + (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")]) ;; Sometimes generated by the epilogue code. We don't want to ;; recognize these addresses in general, because the limm is costly, @@ -1136,17 +1144,19 @@ "if (prepare_move_operands (operands, SFmode)) DONE;") (define_insn "*movsf_insn" - [(set (match_operand:SF 0 "move_dest_operand" "=w,w,r,m") - (match_operand:SF 1 "move_src_operand" "c,E,m,c"))] + [(set (match_operand:SF 0 "move_dest_operand" "=h,w,w,r,m") + (match_operand:SF 1 "move_src_operand" "hCm1,c,E,m,c"))] "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)" "@ mov%? %0,%1 + mov%? %0,%1 mov%? %0,%1 ; %A1 ld%U1%V1 %0,%1 st%U0%V0 %1,%0" - [(set_attr "type" "move,move,load,store") - (set_attr "predicable" "yes,yes,no,no")]) + [(set_attr "type" "move,move,move,load,store") + (set_attr "predicable" "no,yes,yes,no,no") + (set_attr "iscompact" "true,false,false,false,false")]) (define_expand "movdf" [(set (match_operand:DF 0 "nonimmediate_operand" "") @@ -1664,17 +1674,18 @@ ) (define_insn "*extendhisi2_i" - [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r") - (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))] + [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcq,r,r") + (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))] "" "@ sex%_%? %0,%1%& sex%_ %0,%1 + ldh%?.x %0,%1%& ld%_.x%U1%V1 %0,%1 ld%_.x%U1%V1 %0,%1" - [(set_attr "type" "unary,unary,load,load") - (set_attr "iscompact" "true,false,false,false") - (set_attr "length" "*,*,4,8")]) + [(set_attr "type" "unary,unary,load,load,load") + (set_attr "iscompact" "true,false,true,false,false") + (set_attr "length" "*,*,*,4,8")]) (define_expand "extendhisi2" [(set (match_operand:SI 0 "dest_reg_operand" "") @@ -3041,9 +3052,9 @@ 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,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")))] + [(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,C2pC1p,Ccp,CnL, I,Lc,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))] "(register_operand (operands[1], SImode) && nonmemory_operand (operands[2], SImode)) || (memory_operand (operands[1], SImode) @@ -3055,8 +3066,18 @@ return "and%? %0,%1,%2%&"; case 1: case 6: return "and%? %0,%2,%1%&"; - case 2: case 7: case 12: + case 2: return "bmsk%? %0,%1,%Z2%&"; + case 7: case 12: + if (satisfies_constraint_C2p (operands[2])) + { + operands[2] = GEN_INT ((~INTVAL (operands[2]))); + return "bmskn%? %0,%1,%Z2%&"; + } + else + { + return "bmsk%? %0,%1,%Z2%&"; + } case 3: case 8: case 13: return "bclr%? %0,%1,%M2%&"; case 4: @@ -3368,15 +3389,15 @@ ;; modifed cc user if second, but not first operand is a compact register. (define_insn "cmpsi_cc_insn_mixed" [(set (reg:CC CC_REG) - (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,c,c, qRcq, c") - (match_operand:SI 1 "nonmemory_operand" "cO,cI,cL, Cal, Cal")))] + (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q, h, c, c,qRcq,c") + (match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI,cL, Cal,Cal")))] "" "cmp%? %0,%B1%&" [(set_attr "type" "compare") - (set_attr "iscompact" "true,false,false,true_limm,false") - (set_attr "predicable" "no,no,yes,no,yes") + (set_attr "iscompact" "true,true,false,false,true_limm,false") + (set_attr "predicable" "no,no,no,yes,no,yes") (set_attr "cond" "set") - (set_attr "length" "*,4,4,*,8")]) + (set_attr "length" "*,*,4,4,*,8")]) (define_insn "*cmpsi_cc_zn_insn" [(set (reg:CC_ZN CC_REG) @@ -3452,14 +3473,14 @@ (define_insn "*cmpsi_cc_c_insn" [(set (reg:CC_C CC_REG) - (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, c,Rcqq, c") - (match_operand:SI 1 "nonmemory_operand" "cO, cI, Cal,Cal")))] + (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, h, c,Rcqq, c") + (match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI, Cal,Cal")))] "" "cmp%? %0,%S1%&" [(set_attr "type" "compare") - (set_attr "iscompact" "true,false,true_limm,false") + (set_attr "iscompact" "true,true,false,true_limm,false") (set_attr "cond" "set") - (set_attr "length" "*,4,*,8")]) + (set_attr "length" "*,*,4,*,8")]) ;; Next come the scc insns. @@ -3552,17 +3573,20 @@ ; cond_exec patterns (define_insn "*movsi_ne" [(cond_exec - (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc") (const_int 0)) - (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w") - (match_operand:SI 1 "nonmemory_operand" "C_0,Lc,?Cal")))] + (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0)) + (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w") + (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))] "" "@ * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\"; + * current_insn_predicate = 0; return \"mov%?.ne %0,%1\"; + * current_insn_predicate = 0; return \"mov%?.ne %0,%1\"; mov.ne %0,%1 mov.ne %0,%S1" - [(set_attr "type" "cmove,cmove,cmove") - (set_attr "iscompact" "true,false,false") - (set_attr "length" "2,4,8")]) + [(set_attr "type" "cmove") + (set_attr "iscompact" "true,true,true_limm,false,false") + (set_attr "length" "2,2,6,4,8") + (set_attr "cpu_facility" "*,av2,av2,*,*")]) (define_insn "*movsi_cond_exec" [(cond_exec diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md index 5069d7d..b7bf2d3 100644 --- a/gcc/config/arc/constraints.md +++ b/gcc/config/arc/constraints.md @@ -226,6 +226,14 @@ (and (match_code "const_int") (match_test "ival && IS_POWEROF2_P (ival + 1)"))) +(define_constraint "C2p" + "@internal + constant such that (~x)+1 is a power of two, and x < -1" + (and (match_code "const_int") + (match_test "TARGET_V2 + && (ival < -1) + && IS_POWEROF2_P ((~ival) + 1)"))) + (define_constraint "C3p" "@internal constant int used to select xbfu a,b,u6 instruction. The values accepted are 1 and 2." @@ -317,7 +325,13 @@ "@internal A valid memory operand for ARCompact load instructions" (and (match_code "mem") - (match_test "compact_load_memory_operand (op, VOIDmode)"))) + (match_test "compact_memory_operand_p (op, mode, false, false)"))) + +(define_memory_constraint "Uts" + "@internal + A valid memory operand for ARCompact load instructions scaled" + (and (match_code "mem") + (match_test "compact_memory_operand_p (op, mode, false, TARGET_CODE_DENSITY)"))) (define_memory_constraint "S" "@internal @@ -340,7 +354,7 @@ "@internal A valid _small-data_ memory operand for ARCompact instructions" (and (match_code "mem") - (match_test "compact_sda_memory_operand (op, VOIDmode)"))) + (match_test "compact_sda_memory_operand (op, VOIDmode)"))) (define_memory_constraint "Usc" "@internal @@ -483,12 +497,26 @@ (and (match_code "const_int") (match_test "IS_ZERO (ival)"))) +(define_constraint "Cm1" + "@internal + Integer signed constant in the interval [-1,6]" + (and (match_code "const_int") + (match_test "(ival >= -1) && (ival <=6)") + (match_test "TARGET_V2"))) + (define_constraint "Cm2" "@internal A signed 9-bit integer constant." (and (match_code "const_int") (match_test "(ival >= -256) && (ival <=255)"))) +(define_constraint "Cm3" + "@internal + A signed 6-bit integer constant." + (and (match_code "const_int") + (match_test "(ival >= -32) && (ival <=31)") + (match_test "TARGET_V2"))) + (define_constraint "C62" "@internal An unsigned 6-bit integer constant, up to 62." @@ -511,3 +539,32 @@ An unsigned 16-bit integer constant" (and (match_code "const_int") (match_test "UNSIGNED_INT16 (ival)"))) + +; Memory addresses suited for code density load ops +(define_memory_constraint "Ucd" + "@internal + A valid memory operand for use with code density load ops" + (and (match_code "mem") + (match_test "compact_memory_operand_p (op, mode, true, false)") + (match_test "TARGET_V2"))) + +(define_register_constraint "h" + "TARGET_V2 ? AC16_H_REGS : NO_REGS" + "5-bit h register set except @code{r30} and @code{r29}: + @code{r0}-@code{r31}, nonfixed core register") + +; Code density registers +(define_register_constraint "Rcd" + "TARGET_CODE_DENSITY ? R0R3_CD_REGS : NO_REGS" + "@internal + core register @code{r0}-@code{r3}") + +(define_register_constraint "Rsd" + "TARGET_CODE_DENSITY ? R0R1_CD_REGS : NO_REGS" + "@internal + core register @code{r0}-@code{r1}") + +(define_register_constraint "Rzd" + "TARGET_CODE_DENSITY ? R0_REGS : NO_REGS" + "@internal + @code{r0} register for code density instructions.") diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md index 8e4b4b4..f85f931 100644 --- a/gcc/config/arc/predicates.md +++ b/gcc/config/arc/predicates.md @@ -185,95 +185,6 @@ ) ;; Return true if OP is an acceptable memory operand for ARCompact -;; 16-bit load instructions. -(define_predicate "compact_load_memory_operand" - (match_code "mem") -{ - rtx addr, plus0, plus1; - int size, off; - - /* Eliminate non-memory operations. */ - if (GET_CODE (op) != MEM) - return 0; - - /* .di instructions have no 16-bit form. */ - if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET) - return 0; - - if (mode == VOIDmode) - mode = GET_MODE (op); - - size = GET_MODE_SIZE (mode); - - /* dword operations really put out 2 instructions, so eliminate them. */ - if (size > UNITS_PER_WORD) - return 0; - - /* Decode the address now. */ - addr = XEXP (op, 0); - switch (GET_CODE (addr)) - { - case REG: - return (REGNO (addr) >= FIRST_PSEUDO_REGISTER - || COMPACT_GP_REG_P (REGNO (addr)) - || (SP_REG_P (REGNO (addr)) && (size != 2))); - /* Reverting for the moment since ldw_s does not have sp as a valid - parameter. */ - case PLUS: - plus0 = XEXP (addr, 0); - plus1 = XEXP (addr, 1); - - if ((GET_CODE (plus0) == REG) - && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) - || COMPACT_GP_REG_P (REGNO (plus0))) - && ((GET_CODE (plus1) == REG) - && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) - || COMPACT_GP_REG_P (REGNO (plus1))))) - { - return 1; - } - - if ((GET_CODE (plus0) == REG) - && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) - || COMPACT_GP_REG_P (REGNO (plus0))) - && (GET_CODE (plus1) == CONST_INT)) - { - off = INTVAL (plus1); - - /* Negative offset is not supported in 16-bit load/store insns. */ - if (off < 0) - return 0; - - switch (size) - { - case 1: - return (off < 32); - case 2: - return ((off < 64) && (off % 2 == 0)); - case 4: - return ((off < 128) && (off % 4 == 0)); - } - } - - if ((GET_CODE (plus0) == REG) - && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) - || SP_REG_P (REGNO (plus0))) - && (GET_CODE (plus1) == CONST_INT)) - { - off = INTVAL (plus1); - return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0)); - } - default: - break ; - /* TODO: 'gp' and 'pcl' are to supported as base address operand - for 16-bit load instructions. */ - } - return 0; - -} -) - -;; Return true if OP is an acceptable memory operand for ARCompact ;; 16-bit store instructions (define_predicate "compact_store_memory_operand" (match_code "mem") -- 1.9.1