1;; Predicate description for RISC-V target. 2;; Copyright (C) 2011-2020 Free Software Foundation, Inc. 3;; Contributed by Andrew Waterman (andrew@sifive.com). 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_arith_operand" 23 (and (match_code "const_int") 24 (match_test "SMALL_OPERAND (INTVAL (op))"))) 25 26(define_predicate "arith_operand" 27 (ior (match_operand 0 "const_arith_operand") 28 (match_operand 0 "register_operand"))) 29 30(define_predicate "lui_operand" 31 (and (match_code "const_int") 32 (match_test "LUI_OPERAND (INTVAL (op))"))) 33 34(define_predicate "sfb_alu_operand" 35 (ior (match_operand 0 "arith_operand") 36 (match_operand 0 "lui_operand"))) 37 38(define_predicate "const_csr_operand" 39 (and (match_code "const_int") 40 (match_test "IN_RANGE (INTVAL (op), 0, 31)"))) 41 42(define_predicate "csr_operand" 43 (ior (match_operand 0 "const_csr_operand") 44 (match_operand 0 "register_operand"))) 45 46(define_predicate "sle_operand" 47 (and (match_code "const_int") 48 (match_test "SMALL_OPERAND (INTVAL (op) + 1)"))) 49 50(define_predicate "sleu_operand" 51 (and (match_operand 0 "sle_operand") 52 (match_test "INTVAL (op) + 1 != 0"))) 53 54(define_predicate "const_0_operand" 55 (and (match_code "const_int,const_wide_int,const_double,const_vector") 56 (match_test "op == CONST0_RTX (GET_MODE (op))"))) 57 58(define_predicate "reg_or_0_operand" 59 (ior (match_operand 0 "const_0_operand") 60 (match_operand 0 "register_operand"))) 61 62;; Only use branch-on-bit sequences when the mask is not an ANDI immediate. 63(define_predicate "branch_on_bit_operand" 64 (and (match_code "const_int") 65 (match_test "INTVAL (op) >= IMM_BITS - 1"))) 66 67;; A legitimate CONST_INT operand that takes more than one instruction 68;; to load. 69(define_predicate "splittable_const_int_operand" 70 (match_code "const_int") 71{ 72 /* Don't handle multi-word moves this way; we don't want to introduce 73 the individual word-mode moves until after reload. */ 74 if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) 75 return false; 76 77 /* Otherwise check whether the constant can be loaded in a single 78 instruction. */ 79 return !LUI_OPERAND (INTVAL (op)) && !SMALL_OPERAND (INTVAL (op)); 80}) 81 82(define_predicate "p2m1_shift_operand" 83 (match_code "const_int") 84{ 85 int val = exact_log2 (INTVAL (op) + 1); 86 if (val < 12) 87 return false; 88 return true; 89 }) 90 91(define_predicate "high_mask_shift_operand" 92 (match_code "const_int") 93{ 94 int val1 = clz_hwi (~ INTVAL (op)); 95 int val0 = ctz_hwi (INTVAL (op)); 96 if ((val0 + val1 == BITS_PER_WORD) 97 && val0 > 31 && val0 < 64) 98 return true; 99 return false; 100}) 101 102(define_predicate "move_operand" 103 (match_operand 0 "general_operand") 104{ 105 enum riscv_symbol_type symbol_type; 106 107 /* The thinking here is as follows: 108 109 (1) The move expanders should split complex load sequences into 110 individual instructions. Those individual instructions can 111 then be optimized by all rtl passes. 112 113 (2) The target of pre-reload load sequences should not be used 114 to store temporary results. If the target register is only 115 assigned one value, reload can rematerialize that value 116 on demand, rather than spill it to the stack. 117 118 (3) If we allowed pre-reload passes like combine and cse to recreate 119 complex load sequences, we would want to be able to split the 120 sequences before reload as well, so that the pre-reload scheduler 121 can see the individual instructions. This falls foul of (2); 122 the splitter would be forced to reuse the target register for 123 intermediate results. 124 125 (4) We want to define complex load splitters for combine. These 126 splitters can request a temporary scratch register, which avoids 127 the problem in (2). They allow things like: 128 129 (set (reg T1) (high SYM)) 130 (set (reg T2) (low (reg T1) SYM)) 131 (set (reg X) (plus (reg T2) (const_int OFFSET))) 132 133 to be combined into: 134 135 (set (reg T3) (high SYM+OFFSET)) 136 (set (reg X) (lo_sum (reg T3) SYM+OFFSET)) 137 138 if T2 is only used this once. */ 139 switch (GET_CODE (op)) 140 { 141 case CONST_INT: 142 return !splittable_const_int_operand (op, mode); 143 144 case CONST: 145 case SYMBOL_REF: 146 case LABEL_REF: 147 return riscv_symbolic_constant_p (op, &symbol_type) 148 && !riscv_split_symbol_type (symbol_type); 149 150 case HIGH: 151 op = XEXP (op, 0); 152 return riscv_symbolic_constant_p (op, &symbol_type) 153 && riscv_split_symbol_type (symbol_type) 154 && symbol_type != SYMBOL_PCREL; 155 156 default: 157 return true; 158 } 159}) 160 161(define_predicate "symbolic_operand" 162 (match_code "const,symbol_ref,label_ref") 163{ 164 enum riscv_symbol_type type; 165 return riscv_symbolic_constant_p (op, &type); 166}) 167 168(define_predicate "absolute_symbolic_operand" 169 (match_code "const,symbol_ref,label_ref") 170{ 171 enum riscv_symbol_type type; 172 return (riscv_symbolic_constant_p (op, &type) 173 && (type == SYMBOL_ABSOLUTE || type == SYMBOL_PCREL)); 174}) 175 176(define_predicate "plt_symbolic_operand" 177 (match_code "const,symbol_ref,label_ref") 178{ 179 enum riscv_symbol_type type; 180 return (riscv_symbolic_constant_p (op, &type) 181 && type == SYMBOL_GOT_DISP && !SYMBOL_REF_WEAK (op) && TARGET_PLT); 182}) 183 184(define_predicate "call_insn_operand" 185 (ior (match_operand 0 "absolute_symbolic_operand") 186 (match_operand 0 "plt_symbolic_operand") 187 (match_operand 0 "register_operand"))) 188 189(define_predicate "modular_operator" 190 (match_code "plus,minus,mult,ashift")) 191 192(define_predicate "equality_operator" 193 (match_code "eq,ne")) 194 195(define_predicate "order_operator" 196 (match_code "eq,ne,lt,ltu,le,leu,ge,geu,gt,gtu")) 197 198(define_predicate "signed_order_operator" 199 (match_code "eq,ne,lt,le,ge,gt")) 200 201(define_predicate "fp_native_comparison" 202 (match_code "eq,lt,le,gt,ge")) 203 204(define_predicate "fp_scc_comparison" 205 (match_code "unordered,ordered,unlt,unge,unle,ungt,ltgt,ne,eq,lt,le,gt,ge")) 206 207(define_predicate "fp_branch_comparison" 208 (match_code "unordered,ordered,unlt,unge,unle,ungt,uneq,ltgt,ne,eq,lt,le,gt,ge")) 209 210(define_special_predicate "gpr_save_operation" 211 (match_code "parallel") 212{ 213 return riscv_gpr_save_operation_p (op); 214}) 215