Home | History | Annotate | Line # | Download | only in s390
predicates.md revision 1.1.1.6
      1 ;; Predicate definitions for S/390 and zSeries.
      2 ;; Copyright (C) 2005-2018 Free Software Foundation, Inc.
      3 ;; Contributed by Hartmut Penner (hpenner (a] de.ibm.com) and
      4 ;;                Ulrich Weigand (uweigand (a] de.ibm.com).
      5 ;;
      6 ;; This file is part of GCC.
      7 ;;
      8 ;; GCC is free software; you can redistribute it and/or modify
      9 ;; it under the terms of the GNU General Public License as published by
     10 ;; the Free Software Foundation; either version 3, or (at your option)
     11 ;; any later version.
     12 ;;
     13 ;; GCC is distributed in the hope that it will be useful,
     14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 ;; GNU General Public License for more details.
     17 ;;
     18 ;; You should have received a copy of the GNU General Public License
     19 ;; along with GCC; see the file COPYING3.  If not see
     20 ;; <http://www.gnu.org/licenses/>.
     21 
     22 ;; OP is the current operation.
     23 ;; MODE is the current operation mode.
     24 
     25 ;; operands --------------------------------------------------------------
     26 
     27 ;; Return true if OP a const 0 operand (int/float/vector).
     28 (define_predicate "const0_operand"
     29   (and (match_code "const_int,const_wide_int,const_double,const_vector")
     30        (match_test "op == CONST0_RTX (mode)")))
     31 
     32 ;; Return true if OP an all ones operand (int/vector).
     33 (define_predicate "all_ones_operand"
     34   (and (match_code "const_int, const_wide_int, const_vector")
     35        (match_test "INTEGRAL_MODE_P (GET_MODE (op))")
     36        (match_test "op == CONSTM1_RTX (mode)")))
     37 
     38 ;; Return true if OP is a 4 bit mask operand
     39 (define_predicate "const_mask_operand"
     40   (and (match_code "const_int")
     41        (match_test "UINTVAL (op) < 16")))
     42 
     43 ;; Return true if OP is constant.
     44 
     45 (define_special_predicate "consttable_operand"
     46   (and (match_code "symbol_ref, label_ref, const, const_int, const_wide_int, const_double, const_vector")
     47        (match_test "CONSTANT_P (op)")))
     48 
     49 ;; Return true if OP is a valid S-type operand.
     50 
     51 (define_predicate "s_operand"
     52   (and (match_code "subreg, mem")
     53        (match_operand 0 "general_operand"))
     54 {
     55   /* Just like memory_operand, allow (subreg (mem ...))
     56      after reload.  */
     57   if (reload_completed
     58       && GET_CODE (op) == SUBREG
     59       && GET_CODE (SUBREG_REG (op)) == MEM)
     60     op = SUBREG_REG (op);
     61 
     62   if (GET_CODE (op) != MEM)
     63     return false;
     64   if (!s390_legitimate_address_without_index_p (op))
     65     return false;
     66 
     67   return true;
     68 })
     69 
     70 ;; Return true of the address of the mem operand plus 16 is still a
     71 ;; valid Q constraint address.
     72 
     73 (define_predicate "plus16_Q_operand"
     74   (and (match_code "mem")
     75        (match_operand 0 "general_operand"))
     76 {
     77   rtx addr = XEXP (op, 0);
     78   if (REG_P (addr))
     79     return true;
     80 
     81   if (GET_CODE (addr) != PLUS
     82       || !REG_P (XEXP (addr, 0))
     83       || !CONST_INT_P (XEXP (addr, 1)))
     84     return false;
     85 
     86   return SHORT_DISP_IN_RANGE (INTVAL (XEXP (addr, 1)) + 16);
     87 })
     88 
     89 ;; Return true if OP is a valid operand for the BRAS instruction.
     90 ;; Allow SYMBOL_REFs and @PLT stubs.
     91 
     92 (define_special_predicate "bras_sym_operand"
     93   (ior (and (match_code "symbol_ref")
     94 	    (match_test "!flag_pic || SYMBOL_REF_LOCAL_P (op)"))
     95        (and (match_code "const")
     96 	    (and (match_test "GET_CODE (XEXP (op, 0)) == UNSPEC")
     97 		 (match_test "XINT (XEXP (op, 0), 1) == UNSPEC_PLT")))))
     98 
     99 ;; Return true if OP is a PLUS that is not a legitimate
    100 ;; operand for the LA instruction.
    101 
    102 (define_predicate "s390_plus_operand"
    103   (and (match_code "plus")
    104        (and (match_test "mode == Pmode")
    105 	    (match_test "!legitimate_la_operand_p (op)"))))
    106 
    107 ;; Return true if OP is a valid operand as scalar shift count or setmem.
    108 
    109 (define_predicate "setmem_operand"
    110   (match_code "reg, subreg, plus, const_int")
    111 {
    112   HOST_WIDE_INT offset;
    113   rtx base;
    114 
    115   if (GET_MODE (op) != VOIDmode
    116       && GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
    117     return false;
    118 
    119   /* Extract base register and offset.  */
    120   if (!s390_decompose_addrstyle_without_index (op, &base, &offset))
    121     return false;
    122 
    123   /* Don't allow any non-base hard registers.  Doing so without
    124      confusing reload and/or regrename would be tricky, and doesn't
    125      buy us much anyway.  */
    126   if (base && REGNO (base) < FIRST_PSEUDO_REGISTER && !ADDR_REG_P (base))
    127     return false;
    128 
    129   /* Unfortunately we have to reject constants that are invalid
    130      for an address, or else reload will get confused.  */
    131   if (!DISP_IN_RANGE (offset))
    132     return false;
    133 
    134   return true;
    135 })
    136 
    137 ; An integer operand with the lowest order 6 bits all ones.
    138 (define_predicate "const_int_6bitset_operand"
    139  (and (match_code "const_int")
    140       (match_test "(INTVAL (op) & 63) == 63")))
    141 (define_predicate "nonzero_shift_count_operand"
    142   (and (match_code "const_int")
    143        (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)")))
    144 
    145 ;;  Return true if OP a valid operand for the LARL instruction.
    146 
    147 (define_predicate "larl_operand"
    148   (match_code "label_ref, symbol_ref, const")
    149 {
    150   /* Allow labels and local symbols.  */
    151   if (GET_CODE (op) == LABEL_REF)
    152     return true;
    153   if (SYMBOL_REF_P (op))
    154     return (!SYMBOL_FLAG_NOTALIGN2_P (op)
    155 	    && SYMBOL_REF_TLS_MODEL (op) == 0
    156 	    && s390_rel_address_ok_p (op));
    157 
    158   /* Everything else must have a CONST, so strip it.  */
    159   if (GET_CODE (op) != CONST)
    160     return false;
    161   op = XEXP (op, 0);
    162 
    163   /* Allow adding *even* in-range constants.  */
    164   if (GET_CODE (op) == PLUS)
    165     {
    166       if (GET_CODE (XEXP (op, 1)) != CONST_INT
    167           || (INTVAL (XEXP (op, 1)) & 1) != 0)
    168         return false;
    169       if (INTVAL (XEXP (op, 1)) >= HOST_WIDE_INT_1 << 31
    170 	  || INTVAL (XEXP (op, 1)) < -(HOST_WIDE_INT_1 << 31))
    171         return false;
    172       op = XEXP (op, 0);
    173     }
    174 
    175   /* Labels and local symbols allowed here as well.  */
    176   if (GET_CODE (op) == LABEL_REF)
    177     return true;
    178   if (SYMBOL_REF_P (op))
    179     return (!SYMBOL_FLAG_NOTALIGN2_P (op)
    180 	    && SYMBOL_REF_TLS_MODEL (op) == 0
    181 	    && s390_rel_address_ok_p (op));
    182 
    183 
    184   /* Now we must have a @GOTENT offset or @PLT stub
    185      or an @INDNTPOFF TLS offset.  */
    186   if (GET_CODE (op) == UNSPEC
    187       && XINT (op, 1) == UNSPEC_GOTENT)
    188     return true;
    189   if (GET_CODE (op) == UNSPEC
    190       && XINT (op, 1) == UNSPEC_PLT)
    191     return true;
    192   if (GET_CODE (op) == UNSPEC
    193       && XINT (op, 1) == UNSPEC_INDNTPOFF)
    194     return true;
    195 
    196   return false;
    197 })
    198 
    199 ; Predicate that always allows wraparound of the one-bit range.
    200 (define_predicate "contiguous_bitmask_operand"
    201   (match_code "const_int")
    202 {
    203   return s390_contiguous_bitmask_p (INTVAL (op), true,
    204                                     GET_MODE_BITSIZE (mode), NULL, NULL);
    205 })
    206 
    207 ; Same without wraparound.
    208 (define_predicate "contiguous_bitmask_nowrap_operand"
    209   (match_code "const_int")
    210 {
    211   return s390_contiguous_bitmask_p
    212     (INTVAL (op), false, GET_MODE_BITSIZE (mode), NULL, NULL);
    213 })
    214 
    215 ;; Return true if OP is ligitimate for any LOC instruction.
    216 
    217 (define_predicate "loc_operand"
    218   (ior (match_operand 0 "nonimmediate_operand")
    219       (and (match_code "const_int")
    220 	   (match_test "INTVAL (op) <= 32767 && INTVAL (op) >= -32768"))))
    221 
    222 (define_predicate "reload_const_wide_int_operand"
    223   (and (match_code "const_wide_int")
    224        (match_test "legitimate_reload_constant_p (op)")))
    225 
    226 
    227 ;; operators --------------------------------------------------------------
    228 
    229 ;; Return nonzero if OP is a valid comparison operator
    230 ;; for a branch condition.
    231 
    232 (define_predicate "s390_comparison"
    233   (match_code "eq, ne, lt, gt, le, ge, ltu, gtu, leu, geu,
    234 	       uneq, unlt, ungt, unle, unge, ltgt,
    235 	       unordered, ordered")
    236 {
    237   if (GET_CODE (XEXP (op, 0)) != REG
    238       || REGNO (XEXP (op, 0)) != CC_REGNUM
    239       || (XEXP (op, 1) != const0_rtx
    240           && !(CONST_INT_P (XEXP (op, 1))
    241 	       && GET_MODE (XEXP (op, 0)) == CCRAWmode
    242 	       && INTVAL (XEXP (op, 1)) >= 0
    243                && INTVAL (XEXP (op, 1)) <= 15)))
    244     return false;
    245 
    246   return (s390_branch_condition_mask (op) >= 0);
    247 })
    248 
    249 ;; Return true if op is the cc register.
    250 (define_predicate "cc_reg_operand"
    251   (and (match_code "reg")
    252        (match_test "REGNO (op) == CC_REGNUM")))
    253 
    254 (define_predicate "s390_signed_integer_comparison"
    255   (match_code "eq, ne, lt, gt, le, ge")
    256 {
    257   return (s390_compare_and_branch_condition_mask (op) >= 0);
    258 })
    259 
    260 (define_predicate "s390_unsigned_integer_comparison"
    261   (match_code "eq, ne, ltu, gtu, leu, geu")
    262 {
    263   return (s390_compare_and_branch_condition_mask (op) >= 0);
    264 })
    265 
    266 ;; Return nonzero if OP is a valid comparison operator for the
    267 ;; cstore expanders -- respectively cstorecc4 and integer cstore.
    268 (define_predicate "s390_eqne_operator"
    269   (match_code "eq, ne"))
    270 
    271 (define_predicate "s390_scond_operator"
    272   (match_code "ltu, gtu, leu, geu"))
    273 
    274 (define_predicate "s390_brx_operator"
    275   (match_code "le, gt"))
    276 
    277 ;; Return nonzero if OP is a valid comparison operator
    278 ;; for an ALC condition.
    279 
    280 (define_predicate "s390_alc_comparison"
    281   (match_code "zero_extend, sign_extend, ltu, gtu, leu, geu")
    282 {
    283   while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
    284     op = XEXP (op, 0);
    285 
    286   if (!COMPARISON_P (op))
    287     return false;
    288 
    289   if (GET_CODE (XEXP (op, 0)) != REG
    290       || REGNO (XEXP (op, 0)) != CC_REGNUM
    291       || (XEXP (op, 1) != const0_rtx
    292           && !(CONST_INT_P (XEXP (op, 1))
    293 	       && GET_MODE (XEXP (op, 0)) == CCRAWmode
    294 	       && INTVAL (XEXP (op, 1)) >= 0
    295                && INTVAL (XEXP (op, 1)) <= 15)))
    296     return false;
    297 
    298   switch (GET_MODE (XEXP (op, 0)))
    299     {
    300     case E_CCL1mode:
    301       return GET_CODE (op) == LTU;
    302 
    303     case E_CCL2mode:
    304       return GET_CODE (op) == LEU;
    305 
    306     case E_CCL3mode:
    307       return GET_CODE (op) == GEU;
    308 
    309     case E_CCUmode:
    310       return GET_CODE (op) == GTU;
    311 
    312     case E_CCURmode:
    313       return GET_CODE (op) == LTU;
    314 
    315     case E_CCSmode:
    316       return GET_CODE (op) == UNGT;
    317 
    318     case E_CCSRmode:
    319       return GET_CODE (op) == UNLT;
    320 
    321     default:
    322       return false;
    323     }
    324 })
    325 
    326 ;; Return nonzero if OP is a valid comparison operator
    327 ;; for an SLB condition.
    328 
    329 (define_predicate "s390_slb_comparison"
    330   (match_code "zero_extend, sign_extend, ltu, gtu, leu, geu")
    331 {
    332   while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)
    333     op = XEXP (op, 0);
    334 
    335   if (!COMPARISON_P (op))
    336     return false;
    337 
    338   if (GET_CODE (XEXP (op, 0)) != REG
    339       || REGNO (XEXP (op, 0)) != CC_REGNUM
    340       || XEXP (op, 1) != const0_rtx)
    341     return false;
    342 
    343   switch (GET_MODE (XEXP (op, 0)))
    344     {
    345     case E_CCL1mode:
    346       return GET_CODE (op) == GEU;
    347 
    348     case E_CCL2mode:
    349       return GET_CODE (op) == GTU;
    350 
    351     case E_CCL3mode:
    352       return GET_CODE (op) == LTU;
    353 
    354     case E_CCUmode:
    355       return GET_CODE (op) == LEU;
    356 
    357     case E_CCURmode:
    358       return GET_CODE (op) == GEU;
    359 
    360     case E_CCSmode:
    361       return GET_CODE (op) == LE;
    362 
    363     case E_CCSRmode:
    364       return GET_CODE (op) == GE;
    365 
    366     default:
    367       return false;
    368     }
    369 })
    370 
    371 ;; Return true if OP is a load multiple operation.  It is known to be a
    372 ;; PARALLEL and the first section will be tested.
    373 
    374 (define_special_predicate "load_multiple_operation"
    375   (match_code "parallel")
    376 {
    377   machine_mode elt_mode;
    378   int count = XVECLEN (op, 0);
    379   unsigned int dest_regno;
    380   rtx src_addr;
    381   int i, off;
    382 
    383   /* Perform a quick check so we don't blow up below.  */
    384   if (count <= 1
    385       || GET_CODE (XVECEXP (op, 0, 0)) != SET
    386       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
    387       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
    388     return false;
    389 
    390   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
    391   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
    392   elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
    393 
    394   /* Check, is base, or base + displacement.  */
    395 
    396   if (GET_CODE (src_addr) == REG)
    397     off = 0;
    398   else if (GET_CODE (src_addr) == PLUS
    399 	   && GET_CODE (XEXP (src_addr, 0)) == REG
    400 	   && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
    401     {
    402       off = INTVAL (XEXP (src_addr, 1));
    403       src_addr = XEXP (src_addr, 0);
    404     }
    405   else
    406     return false;
    407 
    408   for (i = 1; i < count; i++)
    409     {
    410       rtx elt = XVECEXP (op, 0, i);
    411 
    412       if (GET_CODE (elt) != SET
    413 	  || GET_CODE (SET_DEST (elt)) != REG
    414 	  || GET_MODE (SET_DEST (elt)) != elt_mode
    415 	  || REGNO (SET_DEST (elt)) != dest_regno + i
    416 	  || GET_CODE (SET_SRC (elt)) != MEM
    417 	  || GET_MODE (SET_SRC (elt)) != elt_mode
    418 	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
    419 	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
    420 	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
    421 	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
    422 	     != off + i * GET_MODE_SIZE (elt_mode))
    423 	return false;
    424     }
    425 
    426   return true;
    427 })
    428 
    429 ;; For an execute pattern the target instruction is embedded into the
    430 ;; RTX but will not get checked for validity by recog automatically.
    431 ;; The execute_operation predicate extracts the target RTX and invokes
    432 ;; recog.
    433 (define_special_predicate "execute_operation"
    434   (match_code "parallel")
    435 {
    436   rtx pattern = op;
    437   rtx_insn *insn;
    438   int icode;
    439 
    440   /* This is redundant but since this predicate is evaluated
    441      first when recognizing the insn we can prevent the more
    442      expensive code below from being executed for many cases.  */
    443   if (GET_CODE (XVECEXP (pattern, 0, 0)) != UNSPEC
    444       || XINT (XVECEXP (pattern, 0, 0), 1) != UNSPEC_EXECUTE)
    445     return false;
    446 
    447   /* Keep in sync with s390_execute_target.  */
    448   if (XVECLEN (pattern, 0) == 2)
    449     {
    450       pattern = copy_rtx (XVECEXP (pattern, 0, 1));
    451     }
    452   else
    453     {
    454       rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
    455       int i;
    456 
    457       for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
    458 	RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
    459 
    460       pattern = gen_rtx_PARALLEL (VOIDmode, vec);
    461     }
    462 
    463   /* Since we do not have the wrapping insn here we have to build one.  */
    464   insn = make_insn_raw (pattern);
    465   icode = recog_memoized (insn);
    466   if (icode < 0)
    467     return false;
    468 
    469   extract_constrain_insn (insn);
    470 
    471   return which_alternative >= 0;
    472 })
    473 
    474 ;; Return true if OP is a store multiple operation.  It is known to be a
    475 ;; PARALLEL and the first section will be tested.
    476 
    477 (define_special_predicate "store_multiple_operation"
    478   (match_code "parallel")
    479 {
    480   machine_mode elt_mode;
    481   int count = XVECLEN (op, 0);
    482   unsigned int src_regno;
    483   rtx dest_addr;
    484   int i, off;
    485 
    486   /* Perform a quick check so we don't blow up below.  */
    487   if (count <= 1
    488       || GET_CODE (XVECEXP (op, 0, 0)) != SET
    489       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
    490       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
    491     return false;
    492 
    493   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
    494   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
    495   elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
    496 
    497   /* Check, is base, or base + displacement.  */
    498 
    499   if (GET_CODE (dest_addr) == REG)
    500     off = 0;
    501   else if (GET_CODE (dest_addr) == PLUS
    502 	   && GET_CODE (XEXP (dest_addr, 0)) == REG
    503 	   && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
    504     {
    505       off = INTVAL (XEXP (dest_addr, 1));
    506       dest_addr = XEXP (dest_addr, 0);
    507     }
    508   else
    509     return false;
    510 
    511   for (i = 1; i < count; i++)
    512     {
    513       rtx elt = XVECEXP (op, 0, i);
    514 
    515       if (GET_CODE (elt) != SET
    516 	  || GET_CODE (SET_SRC (elt)) != REG
    517 	  || GET_MODE (SET_SRC (elt)) != elt_mode
    518 	  || REGNO (SET_SRC (elt)) != src_regno + i
    519 	  || GET_CODE (SET_DEST (elt)) != MEM
    520 	  || GET_MODE (SET_DEST (elt)) != elt_mode
    521 	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
    522 	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
    523 	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
    524 	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
    525 	     != off + i * GET_MODE_SIZE (elt_mode))
    526 	return false;
    527     }
    528   return true;
    529 })
    530 
    531 (define_predicate "const_shift_by_byte_operand"
    532   (match_code "const_int")
    533 {
    534   unsigned HOST_WIDE_INT val = INTVAL (op);
    535   return val <= 128 && val % 8 == 0;
    536 })
    537