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