Home | History | Annotate | Line # | Download | only in iq2000
      1 ;; Predicate definitions for Vitesse IQ2000.
      2 ;; Copyright (C) 2005-2022 Free Software Foundation, Inc.
      3 ;;
      4 ;; This file is part of GCC.
      5 ;;
      6 ;; GCC is free software; you can redistribute it and/or modify
      7 ;; it under the terms of the GNU General Public License as published by
      8 ;; the Free Software Foundation; either version 3, or (at your option)
      9 ;; any later version.
     10 ;;
     11 ;; GCC is distributed in the hope that it will be useful,
     12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 ;; GNU General Public License for more details.
     15 ;;
     16 ;; You should have received a copy of the GNU General Public License
     17 ;; along with GCC; see the file COPYING3.  If not see
     18 ;; <http://www.gnu.org/licenses/>.
     19 
     20 ;; Return 1 if OP can be used as an operand where a register or 16-bit
     21 ;; unsigned integer is needed.
     22 
     23 (define_predicate "uns_arith_operand"
     24   (match_code "reg,const_int,subreg")
     25 {
     26   if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
     27     return 1;
     28 
     29   return register_operand (op, mode);
     30 })
     31 
     32 ;; Return 1 if OP can be used as an operand where a 16-bit integer is
     33 ;; needed.
     34 
     35 (define_predicate "arith_operand"
     36   (match_code "reg,const_int,subreg")
     37 {
     38   if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
     39     return 1;
     40 
     41   return register_operand (op, mode);
     42 })
     43 
     44 ;; Return 1 if OP is a register or a constant.  gen_int_relational
     45 ;; takes care of forcing out-of-range constants into a register.
     46 
     47 (define_predicate "reg_or_const_operand"
     48   (ior (match_code "const_int")
     49        (and (match_code "reg,subreg")
     50             (match_operand 0 "register_operand"))))
     51 
     52 ;; Return 1 if OP is a integer which fits in 16 bits.
     53 
     54 (define_predicate "small_int"
     55   (match_code "const_int")
     56 {
     57   return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
     58 })
     59 
     60 ;; Return 1 if OP is a 32-bit integer which is too big to be loaded
     61 ;; with one instruction.
     62 
     63 (define_predicate "large_int"
     64   (match_code "const_int")
     65 {
     66   HOST_WIDE_INT value;
     67 
     68   if (GET_CODE (op) != CONST_INT)
     69     return 0;
     70 
     71   value = INTVAL (op);
     72 
     73   /* IOR reg,$r0,value.  */
     74   if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0)
     75     return 0;
     76 
     77   /* SUBU reg,$r0,value.  */
     78   if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767)
     79     return 0;
     80 
     81   /* LUI reg,value >> 16.  */
     82   if ((value & 0x0000ffff) == 0)
     83     return 0;
     84 
     85   return 1;
     86 })
     87 
     88 ;; Return 1 if OP is a register or the constant 0.
     89 
     90 (define_predicate "reg_or_0_operand"
     91   (match_code "reg,const_int,const_double,subreg")
     92 {
     93   switch (GET_CODE (op))
     94     {
     95     case CONST_INT:
     96       return INTVAL (op) == 0;
     97 
     98     case CONST_DOUBLE:
     99       return op == CONST0_RTX (mode);
    100 
    101     case REG:
    102     case SUBREG:
    103       return register_operand (op, mode);
    104 
    105     default:
    106       break;
    107     }
    108 
    109   return 0;
    110 })
    111 
    112 ;; Return 1 if OP is a memory operand that fits in a single
    113 ;; instruction (i.e., register + small offset).
    114 
    115 (define_predicate "simple_memory_operand"
    116   (match_code "mem,subreg")
    117 {
    118   rtx addr, plus0, plus1;
    119 
    120   /* Eliminate non-memory operations.  */
    121   if (GET_CODE (op) != MEM)
    122     return 0;
    123 
    124   /* Dword operations really put out 2 instructions, so eliminate them.  */
    125   if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD)
    126     return 0;
    127 
    128   /* Decode the address now.  */
    129   addr = XEXP (op, 0);
    130   switch (GET_CODE (addr))
    131     {
    132     case REG:
    133     case LO_SUM:
    134       return 1;
    135 
    136     case CONST_INT:
    137       return SMALL_INT (addr);
    138 
    139     case PLUS:
    140       plus0 = XEXP (addr, 0);
    141       plus1 = XEXP (addr, 1);
    142       if (GET_CODE (plus0) == REG
    143 	  && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1)
    144 	  && SMALL_INT_UNSIGNED (plus1) /* No negative offsets.  */)
    145 	return 1;
    146 
    147       else if (GET_CODE (plus1) == REG
    148 	       && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0)
    149 	       && SMALL_INT_UNSIGNED (plus1) /* No negative offsets.  */)
    150 	return 1;
    151 
    152       else
    153 	return 0;
    154 
    155     case SYMBOL_REF:
    156       return 0;
    157 
    158     default:
    159       break;
    160     }
    161 
    162   return 0;
    163 })
    164 
    165 ;; Return nonzero if the code of this rtx pattern is EQ or NE.
    166 
    167 (define_predicate "equality_op"
    168   (match_code "eq,ne")
    169 {
    170   if (mode != GET_MODE (op))
    171     return 0;
    172 
    173   return GET_CODE (op) == EQ || GET_CODE (op) == NE;
    174 })
    175 
    176 ;; Return nonzero if the code is a relational operations (EQ, LE,
    177 ;; etc).
    178 
    179 (define_predicate "cmp_op"
    180   (match_code "eq,ne,gt,ge,gtu,geu,lt,le,ltu,leu")
    181 {
    182   if (mode != GET_MODE (op))
    183     return 0;
    184 
    185   return COMPARISON_P (op);
    186 })
    187 
    188 ;; Return nonzero if the operand is either the PC or a label_ref.
    189 
    190 (define_special_predicate "pc_or_label_operand"
    191   (match_code "pc,label_ref")
    192 {
    193   if (op == pc_rtx)
    194     return 1;
    195 
    196   if (GET_CODE (op) == LABEL_REF)
    197     return 1;
    198 
    199   return 0;
    200 })
    201 
    202 ;; Return nonzero if OP is a valid operand for a call instruction.
    203 
    204 (define_predicate "call_insn_operand"
    205   (match_code "const_int,const,symbol_ref,reg")
    206 {
    207   return (CONSTANT_ADDRESS_P (op)
    208 	  || (GET_CODE (op) == REG && op != arg_pointer_rtx
    209 	      && ! (REGNO (op) >= FIRST_PSEUDO_REGISTER
    210 		    && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
    211 })
    212 
    213 ;; Return nonzero if OP is valid as a source operand for a move
    214 ;; instruction.
    215 
    216 (define_predicate "move_operand"
    217   (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem")
    218 {
    219   /* Accept any general operand after reload has started; doing so
    220      avoids losing if reload does an in-place replacement of a register
    221      with a SYMBOL_REF or CONST.  */
    222   return (general_operand (op, mode)
    223 	  && (! (iq2000_check_split (op, mode))
    224 	      || reload_in_progress || reload_completed));
    225 })
    226 
    227 ;; Return nonzero if OP is a constant power of 2.
    228 
    229 (define_predicate "power_of_2_operand"
    230   (match_code "const_int")
    231 {
    232   int intval;
    233 
    234   if (GET_CODE (op) != CONST_INT)
    235     return 0;
    236   else
    237     intval = INTVAL (op);
    238 
    239   return ((intval & ((unsigned)(intval) - 1)) == 0);
    240 })
    241