110d565efSmrg;; Predicate definitions for code generation on the EPIPHANY cpu. 2*ec02198aSmrg;; Copyright (C) 1994-2020 Free Software Foundation, Inc. 310d565efSmrg;; Contributed by Embecosm on behalf of Adapteva, Inc. 410d565efSmrg;; 510d565efSmrg;; This file is part of GCC. 610d565efSmrg 710d565efSmrg;; GCC is free software; you can redistribute it and/or modify 810d565efSmrg;; it under the terms of the GNU General Public License as published by 910d565efSmrg;; the Free Software Foundation; either version 3, or (at your option) 1010d565efSmrg;; any later version. 1110d565efSmrg 1210d565efSmrg;; GCC is distributed in the hope that it will be useful, 1310d565efSmrg;; but WITHOUT ANY WARRANTY; without even the implied warranty of 1410d565efSmrg;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1510d565efSmrg;; GNU General Public License for more details. 1610d565efSmrg 1710d565efSmrg;; You should have received a copy of the GNU General Public License 1810d565efSmrg;; along with GCC; see the file COPYING3. If not see 1910d565efSmrg;; <http://www.gnu.org/licenses/>. 2010d565efSmrg 2110d565efSmrg;; Returns true iff OP is a symbol reference that is a valid operand 2210d565efSmrg;; in a jump or call instruction. 2310d565efSmrg 2410d565efSmrg(define_predicate "symbolic_operand" 2510d565efSmrg (match_code "symbol_ref,label_ref,const") 2610d565efSmrg{ 2710d565efSmrg if (GET_CODE (op) == SYMBOL_REF) 2810d565efSmrg return (!epiphany_is_long_call_p (op) 2910d565efSmrg && (!flag_pic || SYMBOL_REF_LOCAL_P (op))); 3010d565efSmrg if (GET_CODE (op) == LABEL_REF) 3110d565efSmrg return true; 3210d565efSmrg if (GET_CODE (op) == CONST) 3310d565efSmrg { 3410d565efSmrg op = XEXP (op, 0); 3510d565efSmrg if (GET_CODE (op) != PLUS || !symbolic_operand (XEXP (op, 0), mode)) 3610d565efSmrg return false; 3710d565efSmrg /* The idea here is that a 'small' constant offset should be OK. 3810d565efSmrg What exactly is considered 'small' is a bit arbitrary. */ 3910d565efSmrg return satisfies_constraint_L (XEXP (op, 1)); 4010d565efSmrg } 4110d565efSmrg gcc_unreachable (); 4210d565efSmrg}) 4310d565efSmrg 4410d565efSmrg;; Acceptable arguments to the call insn. 4510d565efSmrg 4610d565efSmrg(define_predicate "call_address_operand" 4710d565efSmrg (ior (match_code "reg") 4810d565efSmrg (match_operand 0 "symbolic_operand"))) 4910d565efSmrg 5010d565efSmrg(define_predicate "call_operand" 5110d565efSmrg (match_code "mem") 5210d565efSmrg{ 5310d565efSmrg op = XEXP (op, 0); 5410d565efSmrg return call_address_operand (op, mode); 5510d565efSmrg}) 5610d565efSmrg 5710d565efSmrg;; general purpose register. 5810d565efSmrg(define_predicate "gpr_operand" 5910d565efSmrg (match_code "reg,subreg") 6010d565efSmrg{ 6110d565efSmrg int regno; 6210d565efSmrg 6310d565efSmrg if (!register_operand (op, mode)) 6410d565efSmrg return 0; 6510d565efSmrg if (GET_CODE (op) == SUBREG) 6610d565efSmrg op = XEXP (op, 0); 6710d565efSmrg regno = REGNO (op); 6810d565efSmrg return regno >= FIRST_PSEUDO_REGISTER || regno <= 63; 6910d565efSmrg}) 7010d565efSmrg 7110d565efSmrg(define_special_predicate "any_gpr_operand" 7210d565efSmrg (match_code "subreg,reg") 7310d565efSmrg{ 7410d565efSmrg return gpr_operand (op, mode); 7510d565efSmrg}) 7610d565efSmrg 7710d565efSmrg;; register suitable for integer add / sub operations; besides general purpose 7810d565efSmrg;; registers we allow fake hard registers that are eliminated to a real 7910d565efSmrg;; hard register via an offset. 8010d565efSmrg(define_predicate "add_reg_operand" 8110d565efSmrg (match_code "reg,subreg") 8210d565efSmrg{ 8310d565efSmrg int regno; 8410d565efSmrg 8510d565efSmrg if (!register_operand (op, mode)) 8610d565efSmrg return 0; 8710d565efSmrg if (GET_CODE (op) == SUBREG) 8810d565efSmrg op = XEXP (op, 0); 8910d565efSmrg regno = REGNO (op); 9010d565efSmrg return (regno >= FIRST_PSEUDO_REGISTER || regno <= 63 9110d565efSmrg || regno == FRAME_POINTER_REGNUM 9210d565efSmrg || regno == ARG_POINTER_REGNUM); 9310d565efSmrg}) 9410d565efSmrg 9510d565efSmrg;; Also allows suitable constants 9610d565efSmrg(define_predicate "add_operand" 9710d565efSmrg (match_code "reg,subreg,const_int,symbol_ref,label_ref,const") 9810d565efSmrg{ 9910d565efSmrg if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG) 10010d565efSmrg return add_reg_operand (op, mode); 10110d565efSmrg return satisfies_constraint_L (op) || satisfies_constraint_CnL (op); 10210d565efSmrg}) 10310d565efSmrg 10410d565efSmrg;; Ordinary 3rd operand for arithmetic operations 10510d565efSmrg(define_predicate "arith_operand" 10610d565efSmrg (match_code "reg,subreg,const_int,symbol_ref,label_ref,const") 10710d565efSmrg{ 10810d565efSmrg if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG) 10910d565efSmrg return register_operand (op, mode); 11010d565efSmrg return satisfies_constraint_L (op); 11110d565efSmrg}) 11210d565efSmrg 11310d565efSmrg;; Constant integer 3rd operand for arithmetic operations 11410d565efSmrg(define_predicate "arith_int_operand" 11510d565efSmrg (match_code "const_int,symbol_ref,label_ref,const") 11610d565efSmrg{ 11710d565efSmrg return satisfies_constraint_L (op); 11810d565efSmrg}) 11910d565efSmrg 12010d565efSmrg;; Return true if OP is an acceptable argument for a single word move source. 12110d565efSmrg 12210d565efSmrg(define_predicate "move_src_operand" 12310d565efSmrg (match_code 12410d565efSmrg "symbol_ref,label_ref,const,const_int,const_double,reg,subreg,mem,unspec") 12510d565efSmrg{ 12610d565efSmrg switch (GET_CODE (op)) 12710d565efSmrg { 12810d565efSmrg case SYMBOL_REF : 12910d565efSmrg case LABEL_REF : 13010d565efSmrg case CONST : 13110d565efSmrg return 1; 13210d565efSmrg case CONST_INT : 13310d565efSmrg return immediate_operand (op, mode); 13410d565efSmrg case CONST_DOUBLE : 13510d565efSmrg /* SImode constants should always fit into a CONST_INT. Large 13610d565efSmrg unsigned 32-bit constants are represented as negative CONST_INTs. */ 13710d565efSmrg gcc_assert (GET_MODE (op) != SImode); 13810d565efSmrg /* We can handle 32-bit floating point constants. */ 13910d565efSmrg if (mode == SFmode) 14010d565efSmrg return GET_MODE (op) == SFmode; 14110d565efSmrg return 0; 14210d565efSmrg case REG : 14310d565efSmrg return op != frame_pointer_rtx && register_operand (op, mode); 14410d565efSmrg case SUBREG : 14510d565efSmrg /* (subreg (mem ...) ...) can occur here if the inner part was once a 14610d565efSmrg pseudo-reg and is now a stack slot. */ 14710d565efSmrg if (GET_CODE (SUBREG_REG (op)) == MEM) 14810d565efSmrg return address_operand (XEXP (SUBREG_REG (op), 0), mode); 14910d565efSmrg else 15010d565efSmrg return register_operand (op, mode); 15110d565efSmrg case MEM : 15210d565efSmrg return address_operand (XEXP (op, 0), mode); 15310d565efSmrg case UNSPEC: 15410d565efSmrg return satisfies_constraint_Sra (op); 15510d565efSmrg default : 15610d565efSmrg return 0; 15710d565efSmrg } 15810d565efSmrg}) 15910d565efSmrg 16010d565efSmrg;; Return true if OP is an acceptable argument for a double word move source. 16110d565efSmrg 16210d565efSmrg(define_predicate "move_double_src_operand" 16310d565efSmrg (match_code "reg,subreg,mem,const_int,const_double,const_vector") 16410d565efSmrg{ 16510d565efSmrg if (GET_CODE (op) == MEM && misaligned_operand (op, mode) 16610d565efSmrg && !address_operand (plus_constant (Pmode, XEXP (op, 0), 4), SImode)) 16710d565efSmrg return 0; 16810d565efSmrg return general_operand (op, mode); 16910d565efSmrg}) 17010d565efSmrg 17110d565efSmrg;; Return true if OP is an acceptable argument for a move destination. 17210d565efSmrg 17310d565efSmrg(define_predicate "move_dest_operand" 17410d565efSmrg (match_code "reg,subreg,mem") 17510d565efSmrg{ 17610d565efSmrg switch (GET_CODE (op)) 17710d565efSmrg { 17810d565efSmrg case REG : 17910d565efSmrg return register_operand (op, mode); 18010d565efSmrg case SUBREG : 18110d565efSmrg /* (subreg (mem ...) ...) can occur here if the inner part was once a 18210d565efSmrg pseudo-reg and is now a stack slot. */ 18310d565efSmrg if (GET_CODE (SUBREG_REG (op)) == MEM) 18410d565efSmrg { 18510d565efSmrg return address_operand (XEXP (SUBREG_REG (op), 0), mode); 18610d565efSmrg } 18710d565efSmrg else 18810d565efSmrg { 18910d565efSmrg return register_operand (op, mode); 19010d565efSmrg } 19110d565efSmrg case MEM : 19210d565efSmrg if (GET_MODE_SIZE (mode) == 8 && misaligned_operand (op, mode) 19310d565efSmrg && !address_operand (plus_constant (Pmode, XEXP (op, 0), 4), SImode)) 19410d565efSmrg return 0; 19510d565efSmrg return address_operand (XEXP (op, 0), mode); 19610d565efSmrg default : 19710d565efSmrg return 0; 19810d565efSmrg } 19910d565efSmrg}) 20010d565efSmrg 20110d565efSmrg(define_special_predicate "stacktop_operand" 20210d565efSmrg (match_code "mem") 20310d565efSmrg{ 20410d565efSmrg if (mode != VOIDmode && GET_MODE (op) != mode) 20510d565efSmrg return false; 20610d565efSmrg return rtx_equal_p (XEXP (op, 0), stack_pointer_rtx); 20710d565efSmrg}) 20810d565efSmrg 20910d565efSmrg;; Return 1 if OP is a comparison operator valid for the mode of CC. 21010d565efSmrg;; This allows the use of MATCH_OPERATOR to recognize all the branch insns. 21110d565efSmrg;; 21210d565efSmrg;; Some insns only set a few bits in the condition code. So only allow those 21310d565efSmrg;; comparisons that use the bits that are valid. 21410d565efSmrg 21510d565efSmrg(define_predicate "proper_comparison_operator" 21610d565efSmrg (match_code "eq, ne, le, lt, ge, gt, leu, ltu, geu, gtu, unordered, ordered, uneq, unge, ungt, unle, unlt, ltgt") 21710d565efSmrg{ 21810d565efSmrg enum rtx_code code = GET_CODE (op); 21910d565efSmrg rtx cc = XEXP (op, 0); 22010d565efSmrg 22110d565efSmrg /* combine can try strange things. */ 22210d565efSmrg if (!REG_P (cc)) 22310d565efSmrg return 0; 22410d565efSmrg switch (GET_MODE (cc)) 22510d565efSmrg { 226c7a68eb7Smrg case E_CC_Zmode: 227c7a68eb7Smrg case E_CC_N_NEmode: 228c7a68eb7Smrg case E_CC_FP_EQmode: 22910d565efSmrg return REGNO (cc) == CC_REGNUM && (code == EQ || code == NE); 230c7a68eb7Smrg case E_CC_C_LTUmode: 23110d565efSmrg return REGNO (cc) == CC_REGNUM && (code == LTU || code == GEU); 232c7a68eb7Smrg case E_CC_C_GTUmode: 23310d565efSmrg return REGNO (cc) == CC_REGNUM && (code == GTU || code == LEU); 234c7a68eb7Smrg case E_CC_FPmode: 23510d565efSmrg return (REGNO (cc) == CCFP_REGNUM 23610d565efSmrg && (code == EQ || code == NE || code == LT || code == LE)); 237c7a68eb7Smrg case E_CC_FP_GTEmode: 23810d565efSmrg return (REGNO (cc) == CC_REGNUM 23910d565efSmrg && (code == EQ || code == NE || code == GT || code == GE 24010d565efSmrg || code == UNLE || code == UNLT)); 241c7a68eb7Smrg case E_CC_FP_ORDmode: 24210d565efSmrg return REGNO (cc) == CC_REGNUM && (code == ORDERED || code == UNORDERED); 243c7a68eb7Smrg case E_CC_FP_UNEQmode: 24410d565efSmrg return REGNO (cc) == CC_REGNUM && (code == UNEQ || code == LTGT); 245c7a68eb7Smrg case E_CCmode: 24610d565efSmrg return REGNO (cc) == CC_REGNUM; 24710d565efSmrg /* From combiner. */ 248c7a68eb7Smrg case E_QImode: case E_SImode: case E_SFmode: case E_HImode: 24910d565efSmrg /* From cse.c:dead_libcall_p. */ 250c7a68eb7Smrg case E_DFmode: 25110d565efSmrg return 0; 25210d565efSmrg default: 25310d565efSmrg gcc_unreachable (); 25410d565efSmrg } 25510d565efSmrg}) 25610d565efSmrg 25710d565efSmrg(define_predicate "addsub_operator" 25810d565efSmrg (match_code "plus, minus")) 25910d565efSmrg 26010d565efSmrg(define_predicate "cc_operand" 26110d565efSmrg (and (match_code "reg") 26210d565efSmrg (match_test "REGNO (op) == CC_REGNUM || REGNO (op) == CCFP_REGNUM"))) 26310d565efSmrg 26410d565efSmrg(define_predicate "const0_operand" 26510d565efSmrg (match_code "const_int, const_double") 26610d565efSmrg{ 26710d565efSmrg if (mode == VOIDmode) 26810d565efSmrg mode = GET_MODE (op); 26910d565efSmrg return op == CONST0_RTX (mode); 27010d565efSmrg}) 27110d565efSmrg 27210d565efSmrg(define_predicate "const_float_1_operand" 27310d565efSmrg (match_code "const_double") 27410d565efSmrg{ 27510d565efSmrg return op == CONST1_RTX (mode); 27610d565efSmrg}) 27710d565efSmrg 27810d565efSmrg(define_predicate "cc_move_operand" 27910d565efSmrg (and (match_code "reg") 28010d565efSmrg (ior (match_test "REGNO (op) == CC_REGNUM") 28110d565efSmrg (match_test "gpr_operand (op, mode)")))) 28210d565efSmrg 28310d565efSmrg(define_predicate "float_operation" 28410d565efSmrg (match_code "parallel") 28510d565efSmrg{ 28610d565efSmrg /* Most patterns start out with one SET and one CLOBBER, and gain a USE 28710d565efSmrg or two of FP_NEAREST_REGNUM / FP_TRUNCATE_REGNUM / FP_ANYFP_REGNUM 28810d565efSmrg after mode switching. The longer patterns are 28910d565efSmrg all beyond length 4, and before mode switching, end with a 29010d565efSmrg CLOBBER of CCFP_REGNUM. */ 29110d565efSmrg int count = XVECLEN (op, 0); 29210d565efSmrg bool inserted = MACHINE_FUNCTION (cfun)->control_use_inserted; 29310d565efSmrg int i; 29410d565efSmrg 29510d565efSmrg if (count == 2 29610d565efSmrg /* Vector ashift has an extra use for the constant factor required to 29710d565efSmrg implement the shift as multiply. */ 29810d565efSmrg || (count == 3 && GET_CODE (XVECEXP (op, 0, 0)) == SET 29910d565efSmrg && GET_CODE (XEXP (XVECEXP (op, 0, 0), 1)) == ASHIFT)) 30010d565efSmrg return !inserted; 30110d565efSmrg 30210d565efSmrg /* combine / recog will pass any old garbage here before checking the 30310d565efSmrg rest of the insn. */ 30410d565efSmrg if (count <= 3) 30510d565efSmrg return false; 30610d565efSmrg 30710d565efSmrg i = 1; 30810d565efSmrg if (count > 4) 30910d565efSmrg for (i = 2; i < count; i++) 31010d565efSmrg { 31110d565efSmrg rtx x = XVECEXP (op, 0, i); 31210d565efSmrg 31310d565efSmrg if (GET_CODE (x) == CLOBBER) 31410d565efSmrg { 31510d565efSmrg if (!REG_P (XEXP (x, 0))) 31610d565efSmrg return false; 31710d565efSmrg if (REGNO (XEXP (x, 0)) == CCFP_REGNUM) 31810d565efSmrg { 31910d565efSmrg if (count == i + 1) 32010d565efSmrg return !inserted; 32110d565efSmrg break; 32210d565efSmrg } 32310d565efSmrg /* Just an ordinary clobber, keep looking. */ 32410d565efSmrg } 32510d565efSmrg else if (GET_CODE (x) == USE 32610d565efSmrg || (GET_CODE (x) == SET && i == 2)) 32710d565efSmrg continue; 32810d565efSmrg else 32910d565efSmrg return false; 33010d565efSmrg } 33110d565efSmrg if (count != i + 3 || !inserted) 33210d565efSmrg return false; 33310d565efSmrg for (i = i+1; i < count; i++) 33410d565efSmrg { 33510d565efSmrg rtx x = XVECEXP (op, 0, i); 33610d565efSmrg 33710d565efSmrg if (GET_CODE (x) != USE && GET_CODE (x) != CLOBBER) 33810d565efSmrg return false; 33910d565efSmrg x = XEXP (x, 0); 34010d565efSmrg if (!REG_P (x) 34110d565efSmrg || (REGNO (x) != FP_NEAREST_REGNUM 34210d565efSmrg && REGNO (x) != FP_TRUNCATE_REGNUM 34310d565efSmrg && REGNO (x) != FP_ANYFP_REGNUM)) 34410d565efSmrg return false; 34510d565efSmrg } 34610d565efSmrg return true; 34710d565efSmrg}) 34810d565efSmrg 34910d565efSmrg(define_predicate "set_fp_mode_operand" 35010d565efSmrg (ior (match_test "gpr_operand (op, mode)") 35110d565efSmrg (and (match_code "const") 35210d565efSmrg (match_test "satisfies_constraint_Cfm (op)")))) 35310d565efSmrg 35410d565efSmrg(define_predicate "post_modify_address" 35510d565efSmrg (match_code "post_modify,post_inc,post_dec")) 35610d565efSmrg 35710d565efSmrg(define_predicate "post_modify_operand" 35810d565efSmrg (and (match_code "mem") 35910d565efSmrg (match_test "post_modify_address (XEXP (op, 0), Pmode)"))) 36010d565efSmrg 36110d565efSmrg; used in the memory clobber of stack_adjust_str, allows addresses with 36210d565efSmrg; large offsets. 36310d565efSmrg(define_predicate "memclob_operand" 36410d565efSmrg (match_code "mem")) 36510d565efSmrg 36610d565efSmrg(define_predicate "nonsymbolic_immediate_operand" 36710d565efSmrg (ior (match_test "immediate_operand (op, mode)") 36810d565efSmrg (match_code "const_vector"))) /* Is this specific enough? */ 36910d565efSmrg 37010d565efSmrg;; Return true if OP is misaligned memory operand 37110d565efSmrg(define_predicate "misaligned_operand" 37210d565efSmrg (and (match_code "mem") 37310d565efSmrg (match_test "MEM_ALIGN (op) < GET_MODE_ALIGNMENT (mode)"))) 374