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