Home | History | Annotate | Line # | Download | only in loongarch
predicates.md revision 1.1
      1 ;; Predicate definitions for LoongArch target.
      2 ;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
      3 ;; Contributed by Loongson Ltd.
      4 ;; Based on MIPS target for GNU compiler.
      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 (define_predicate "const_uns_arith_operand"
     23   (and (match_code "const_int")
     24        (match_test "IMM12_OPERAND_UNSIGNED (INTVAL (op))")))
     25 
     26 (define_predicate "uns_arith_operand"
     27   (ior (match_operand 0 "const_uns_arith_operand")
     28        (match_operand 0 "register_operand")))
     29 
     30 (define_predicate "const_lu32i_operand"
     31   (and (match_code "const_int")
     32        (match_test "LU32I_OPERAND (INTVAL (op))")))
     33 
     34 (define_predicate "const_lu52i_operand"
     35   (and (match_code "const_int")
     36        (match_test "LU52I_OPERAND (INTVAL (op))")))
     37 
     38 (define_predicate "const_arith_operand"
     39   (and (match_code "const_int")
     40        (match_test "IMM12_OPERAND (INTVAL (op))")))
     41 
     42 (define_predicate "const_imm16_operand"
     43   (and (match_code "const_int")
     44        (match_test "IMM16_OPERAND (INTVAL (op))")))
     45 
     46 (define_predicate "arith_operand"
     47   (ior (match_operand 0 "const_arith_operand")
     48        (match_operand 0 "register_operand")))
     49 
     50 (define_predicate "const_immalsl_operand"
     51   (and (match_code "const_int")
     52        (match_test "IN_RANGE (INTVAL (op), 1, 4)")))
     53 
     54 (define_predicate "const_uimm5_operand"
     55   (and (match_code "const_int")
     56        (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
     57 
     58 (define_predicate "const_uimm14_operand"
     59   (and (match_code "const_int")
     60        (match_test "IN_RANGE (INTVAL (op), 0, 16383)")))
     61 
     62 (define_predicate "const_uimm15_operand"
     63   (and (match_code "const_int")
     64        (match_test "IN_RANGE (INTVAL (op), 0, 32767)")))
     65 
     66 (define_predicate "const_imm12_operand"
     67   (and (match_code "const_int")
     68        (match_test "IMM12_OPERAND (INTVAL (op))")))
     69 
     70 (define_predicate "sle_operand"
     71   (and (match_code "const_int")
     72        (match_test "IMM12_OPERAND (INTVAL (op) + 1)")))
     73 
     74 (define_predicate "sleu_operand"
     75   (and (match_operand 0 "sle_operand")
     76        (match_test "INTVAL (op) + 1 != 0")))
     77 
     78 (define_predicate "const_0_operand"
     79   (and (match_code "const_int,const_double,const_vector")
     80        (match_test "op == CONST0_RTX (GET_MODE (op))")))
     81 
     82 (define_predicate "reg_or_0_operand"
     83   (ior (match_operand 0 "const_0_operand")
     84        (match_operand 0 "register_operand")))
     85 
     86 (define_predicate "const_1_operand"
     87   (and (match_code "const_int,const_double,const_vector")
     88        (match_test "op == CONST1_RTX (GET_MODE (op))")))
     89 
     90 (define_predicate "reg_or_1_operand"
     91   (ior (match_operand 0 "const_1_operand")
     92        (match_operand 0 "register_operand")))
     93 
     94 (define_predicate "const_0_to_3_operand"
     95   (and (match_code "const_int")
     96        (match_test "IN_RANGE (INTVAL (op), 0, 3)")))
     97 
     98 (define_predicate "const_0_to_7_operand"
     99   (and (match_code "const_int")
    100        (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
    101 
    102 (define_predicate "lu52i_mask_operand"
    103   (and (match_code "const_int")
    104        (match_test "UINTVAL (op) == 0xfffffffffffff")))
    105 
    106 (define_predicate "low_bitmask_operand"
    107   (and (match_code "const_int")
    108        (match_test "low_bitmask_len (mode, INTVAL (op)) > 12")))
    109 
    110 (define_predicate "const_call_insn_operand"
    111   (match_code "const,symbol_ref,label_ref")
    112 {
    113   enum loongarch_symbol_type symbol_type;
    114 
    115   if (!loongarch_symbolic_constant_p (op, &symbol_type))
    116     return false;
    117 
    118   switch (symbol_type)
    119     {
    120     case SYMBOL_GOT_DISP:
    121       /* Without explicit relocs, there is no special syntax for
    122 	 loading the address of a call destination into a register.
    123 	 Using "la.global JIRL_REGS,foo; jirl JIRL_REGS" would prevent the lazy
    124 	 binding of "foo", so keep the address of global symbols with the jirl
    125 	 macro.  */
    126       return 1;
    127 
    128     default:
    129       return false;
    130     }
    131 })
    132 
    133 (define_predicate "call_insn_operand"
    134   (ior (match_operand 0 "const_call_insn_operand")
    135        (match_operand 0 "register_operand")))
    136 
    137 (define_predicate "is_const_call_local_symbol"
    138   (and (match_operand 0 "const_call_insn_operand")
    139        (ior (match_test "loongarch_global_symbol_p (op) == 0")
    140 	    (match_test "loongarch_symbol_binds_local_p (op) != 0"))
    141        (match_test "CONSTANT_P (op)")))
    142 
    143 (define_predicate "is_const_call_weak_symbol"
    144   (and (match_operand 0 "const_call_insn_operand")
    145        (not (match_operand 0 "is_const_call_local_symbol"))
    146        (match_test "loongarch_weak_symbol_p (op) != 0")
    147        (match_test "CONSTANT_P (op)")))
    148 
    149 (define_predicate "is_const_call_plt_symbol"
    150   (and (match_operand 0 "const_call_insn_operand")
    151        (match_test "flag_plt != 0")
    152        (match_test "loongarch_global_symbol_noweak_p (op) != 0")
    153        (match_test "CONSTANT_P (op)")))
    154 
    155 (define_predicate "is_const_call_global_noplt_symbol"
    156   (and (match_operand 0 "const_call_insn_operand")
    157        (match_test "flag_plt == 0")
    158        (match_test "loongarch_global_symbol_noweak_p (op) != 0")
    159        (match_test "CONSTANT_P (op)")))
    160 
    161 ;; A legitimate CONST_INT operand that takes more than one instruction
    162 ;; to load.
    163 (define_predicate "splittable_const_int_operand"
    164   (match_code "const_int")
    165 {
    166   /* Don't handle multi-word moves this way; we don't want to introduce
    167      the individual word-mode moves until after reload.  */
    168   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
    169     return false;
    170 
    171   /* Otherwise check whether the constant can be loaded in a single
    172      instruction.  */
    173   return !LU12I_INT (op) && !IMM12_INT (op) && !IMM12_INT_UNSIGNED (op)
    174 	 && !LU52I_INT (op);
    175 })
    176 
    177 (define_predicate "move_operand"
    178   (match_operand 0 "general_operand")
    179 {
    180   enum loongarch_symbol_type symbol_type;
    181 
    182   /* The thinking here is as follows:
    183 
    184      (1) The move expanders should split complex load sequences into
    185 	 individual instructions.  Those individual instructions can
    186 	 then be optimized by all rtl passes.
    187 
    188      (2) The target of pre-reload load sequences should not be used
    189 	 to store temporary results.  If the target register is only
    190 	 assigned one value, reload can rematerialize that value
    191 	 on demand, rather than spill it to the stack.
    192 
    193      (3) If we allowed pre-reload passes like combine and cse to recreate
    194 	 complex load sequences, we would want to be able to split the
    195 	 sequences before reload as well, so that the pre-reload scheduler
    196 	 can see the individual instructions.  This falls foul of (2);
    197 	 the splitter would be forced to reuse the target register for
    198 	 intermediate results.
    199 
    200      (4) We want to define complex load splitters for combine.  These
    201 	 splitters can request a temporary scratch register, which avoids
    202 	 the problem in (2).  They allow things like:
    203 
    204 	      (set (reg T1) (high SYM))
    205 	      (set (reg T2) (low (reg T1) SYM))
    206 	      (set (reg X) (plus (reg T2) (const_int OFFSET)))
    207 
    208 	 to be combined into:
    209 
    210 	      (set (reg T3) (high SYM+OFFSET))
    211 	      (set (reg X) (lo_sum (reg T3) SYM+OFFSET))
    212 
    213 	 if T2 is only used this once.  */
    214   switch (GET_CODE (op))
    215     {
    216     case CONST_INT:
    217       return !splittable_const_int_operand (op, mode);
    218 
    219     case CONST:
    220     case SYMBOL_REF:
    221     case LABEL_REF:
    222       return (loongarch_symbolic_constant_p (op, &symbol_type));
    223     default:
    224       return true;
    225     }
    226 })
    227 
    228 (define_predicate "symbolic_operand"
    229   (match_code "const,symbol_ref,label_ref")
    230 {
    231   enum loongarch_symbol_type type;
    232   return loongarch_symbolic_constant_p (op, &type);
    233 })
    234 
    235 (define_predicate "equality_operator"
    236   (match_code "eq,ne"))
    237 
    238 (define_predicate "order_operator"
    239   (match_code "lt,ltu,le,leu,ge,geu,gt,gtu"))
    240 
    241 ;; For NE, cstore uses sltu instructions in which the first operand is $0.
    242 
    243 (define_predicate "loongarch_cstore_operator"
    244   (match_code "ne,eq,gt,gtu,ge,geu,lt,ltu,le,leu"))
    245 
    246 (define_predicate "small_data_pattern"
    247   (and (match_code "set,parallel,unspec,unspec_volatile,prefetch")
    248        (match_test "loongarch_small_data_pattern_p (op)")))
    249 
    250 ;; Return 1 if the operand is in non-volatile memory.
    251 (define_predicate "non_volatile_mem_operand"
    252   (and (match_operand 0 "memory_operand")
    253        (not (match_test "MEM_VOLATILE_P (op)"))))
    254