xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/mips/predicates.md (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1;; Predicate definitions for MIPS.
2;; Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc.
3;;
4;; This file is part of GCC.
5;;
6;; GCC is free software; you can redistribute it and/or modify
7;; it under the terms of the GNU General Public License as published by
8;; the Free Software Foundation; either version 3, or (at your option)
9;; any later version.
10;;
11;; GCC is distributed in the hope that it will be useful,
12;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14;; GNU General Public License for more details.
15;;
16;; You should have received a copy of the GNU General Public License
17;; along with GCC; see the file COPYING3.  If not see
18;; <http://www.gnu.org/licenses/>.
19
20(define_predicate "const_uns_arith_operand"
21  (and (match_code "const_int")
22       (match_test "SMALL_OPERAND_UNSIGNED (INTVAL (op))")))
23
24(define_predicate "uns_arith_operand"
25  (ior (match_operand 0 "const_uns_arith_operand")
26       (match_operand 0 "register_operand")))
27
28(define_predicate "const_arith_operand"
29  (and (match_code "const_int")
30       (match_test "SMALL_OPERAND (INTVAL (op))")))
31
32(define_predicate "arith_operand"
33  (ior (match_operand 0 "const_arith_operand")
34       (match_operand 0 "register_operand")))
35
36(define_predicate "const_uimm6_operand"
37  (and (match_code "const_int")
38       (match_test "UIMM6_OPERAND (INTVAL (op))")))
39
40(define_predicate "const_imm10_operand"
41  (and (match_code "const_int")
42       (match_test "IMM10_OPERAND (INTVAL (op))")))
43
44(define_predicate "reg_imm10_operand"
45  (ior (match_operand 0 "const_imm10_operand")
46       (match_operand 0 "register_operand")))
47
48(define_predicate "sle_operand"
49  (and (match_code "const_int")
50       (match_test "SMALL_OPERAND (INTVAL (op) + 1)")))
51
52(define_predicate "sleu_operand"
53  (and (match_operand 0 "sle_operand")
54       (match_test "INTVAL (op) + 1 != 0")))
55
56(define_predicate "const_0_operand"
57  (and (match_code "const_int,const_double,const_vector")
58       (match_test "op == CONST0_RTX (GET_MODE (op))")))
59
60(define_predicate "reg_or_0_operand"
61  (ior (and (match_operand 0 "const_0_operand")
62	    (match_test "!TARGET_MIPS16"))
63       (match_operand 0 "register_operand")))
64
65(define_predicate "const_1_operand"
66  (and (match_code "const_int,const_double,const_vector")
67       (match_test "op == CONST1_RTX (GET_MODE (op))")))
68
69(define_predicate "reg_or_1_operand"
70  (ior (match_operand 0 "const_1_operand")
71       (match_operand 0 "register_operand")))
72
73;; This is used for indexing into vectors, and hence only accepts const_int.
74(define_predicate "const_0_or_1_operand"
75  (and (match_code "const_int")
76       (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
77	    (match_test "op == CONST1_RTX (GET_MODE (op))"))))
78
79(define_predicate "qi_mask_operand"
80  (and (match_code "const_int")
81       (match_test "UINTVAL (op) == 0xff")))
82
83(define_predicate "hi_mask_operand"
84  (and (match_code "const_int")
85       (match_test "UINTVAL (op) == 0xffff")))
86
87(define_predicate "si_mask_operand"
88  (and (match_code "const_int")
89       (match_test "UINTVAL (op) == 0xffffffff")))
90
91(define_predicate "and_load_operand"
92  (ior (match_operand 0 "qi_mask_operand")
93       (match_operand 0 "hi_mask_operand")
94       (match_operand 0 "si_mask_operand")))
95
96(define_predicate "low_bitmask_operand"
97  (and (match_test "ISA_HAS_EXT_INS")
98       (match_code "const_int")
99       (match_test "low_bitmask_len (mode, INTVAL (op)) > 16")))
100
101(define_predicate "and_reg_operand"
102  (ior (match_operand 0 "register_operand")
103       (and (match_test "!TARGET_MIPS16")
104	    (match_operand 0 "const_uns_arith_operand"))
105       (match_operand 0 "low_bitmask_operand")
106       (match_operand 0 "si_mask_operand")))
107
108(define_predicate "and_operand"
109  (ior (match_operand 0 "and_load_operand")
110       (match_operand 0 "and_reg_operand")))
111
112(define_predicate "d_operand"
113  (and (match_code "reg")
114       (match_test "TARGET_MIPS16
115		    ? M16_REG_P (REGNO (op))
116		    : GP_REG_P (REGNO (op))")))
117
118(define_predicate "lo_operand"
119  (and (match_code "reg")
120       (match_test "REGNO (op) == LO_REGNUM")))
121
122(define_predicate "hilo_operand"
123  (and (match_code "reg")
124       (match_test "MD_REG_P (REGNO (op))")))
125
126(define_predicate "fcc_reload_operand"
127  (and (match_code "reg,subreg")
128       (match_test "ST_REG_P (true_regnum (op))")))
129
130(define_special_predicate "pc_or_label_operand"
131  (match_code "pc,label_ref"))
132
133(define_predicate "const_call_insn_operand"
134  (match_code "const,symbol_ref,label_ref")
135{
136  enum mips_symbol_type symbol_type;
137
138  if (!mips_symbolic_constant_p (op, SYMBOL_CONTEXT_CALL, &symbol_type))
139    return false;
140
141  switch (symbol_type)
142    {
143    case SYMBOL_ABSOLUTE:
144      /* We can only use direct calls if we're sure that the target
145	 function does not need $25 to be valid on entry.  */
146      if (mips_use_pic_fn_addr_reg_p (op))
147	return false;
148
149      /* If -mlong-calls or if this function has an explicit long_call
150	 attribute, we must use register addressing.  The
151	 SYMBOL_FLAG_LONG_CALL bit is set by mips_encode_section_info.  */
152      return !(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LONG_CALL_P (op));
153
154    case SYMBOL_GOT_DISP:
155      /* Without explicit relocs, there is no special syntax for
156	 loading the address of a call destination into a register.
157	 Using "la $25,foo; jal $25" would prevent the lazy binding
158	 of "foo", so keep the address of global symbols with the
159	 jal macro.  */
160      return !TARGET_EXPLICIT_RELOCS;
161
162    default:
163      return false;
164    }
165})
166
167(define_predicate "call_insn_operand"
168  (ior (match_operand 0 "const_call_insn_operand")
169       (match_operand 0 "register_operand")))
170
171;; A legitimate CONST_INT operand that takes more than one instruction
172;; to load.
173(define_predicate "splittable_const_int_operand"
174  (match_code "const_int")
175{
176  /* When generating mips16 code, LEGITIMATE_CONSTANT_P rejects
177     CONST_INTs that can't be loaded using simple insns.  */
178  if (TARGET_MIPS16)
179    return false;
180
181  /* Don't handle multi-word moves this way; we don't want to introduce
182     the individual word-mode moves until after reload.  */
183  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
184    return false;
185
186  /* Otherwise check whether the constant can be loaded in a single
187     instruction.  */
188  return !LUI_INT (op) && !SMALL_INT (op) && !SMALL_INT_UNSIGNED (op);
189})
190
191(define_predicate "move_operand"
192  (match_operand 0 "general_operand")
193{
194  enum mips_symbol_type symbol_type;
195
196  /* The thinking here is as follows:
197
198     (1) The move expanders should split complex load sequences into
199	 individual instructions.  Those individual instructions can
200	 then be optimized by all rtl passes.
201
202     (2) The target of pre-reload load sequences should not be used
203	 to store temporary results.  If the target register is only
204	 assigned one value, reload can rematerialize that value
205	 on demand, rather than spill it to the stack.
206
207     (3) If we allowed pre-reload passes like combine and cse to recreate
208	 complex load sequences, we would want to be able to split the
209	 sequences before reload as well, so that the pre-reload scheduler
210	 can see the individual instructions.  This falls foul of (2);
211	 the splitter would be forced to reuse the target register for
212	 intermediate results.
213
214     (4) We want to define complex load splitters for combine.  These
215	 splitters can request a temporary scratch register, which avoids
216	 the problem in (2).  They allow things like:
217
218	      (set (reg T1) (high SYM))
219	      (set (reg T2) (low (reg T1) SYM))
220	      (set (reg X) (plus (reg T2) (const_int OFFSET)))
221
222	 to be combined into:
223
224	      (set (reg T3) (high SYM+OFFSET))
225	      (set (reg X) (lo_sum (reg T3) SYM+OFFSET))
226
227	 if T2 is only used this once.  */
228  switch (GET_CODE (op))
229    {
230    case CONST_INT:
231      return !splittable_const_int_operand (op, mode);
232
233    case CONST:
234    case SYMBOL_REF:
235    case LABEL_REF:
236      if (CONST_GP_P (op))
237	return true;
238      return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
239	      && !mips_split_p[symbol_type]);
240
241    case HIGH:
242      op = XEXP (op, 0);
243      return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
244	      && !mips_split_hi_p[symbol_type]);
245
246    default:
247      return true;
248    }
249})
250
251(define_predicate "cprestore_save_slot_operand"
252  (and (match_code "mem")
253       (match_test "mips_cprestore_address_p (XEXP (op, 0), false)")))
254
255(define_predicate "cprestore_load_slot_operand"
256  (and (match_code "mem")
257       (match_test "mips_cprestore_address_p (XEXP (op, 0), true)")))
258
259(define_predicate "consttable_operand"
260  (match_test "CONSTANT_P (op)"))
261
262(define_predicate "symbolic_operand"
263  (match_code "const,symbol_ref,label_ref")
264{
265  enum mips_symbol_type type;
266  return mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type);
267})
268
269(define_predicate "absolute_symbolic_operand"
270  (match_code "const,symbol_ref,label_ref")
271{
272  enum mips_symbol_type type;
273  return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type)
274	  && type == SYMBOL_ABSOLUTE);
275})
276
277(define_predicate "force_to_mem_operand"
278  (match_code "const,symbol_ref,label_ref")
279{
280  enum mips_symbol_type symbol_type;
281  return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
282	  && symbol_type == SYMBOL_FORCE_TO_MEM);
283})
284
285(define_predicate "got_disp_operand"
286  (match_code "const,symbol_ref,label_ref")
287{
288  enum mips_symbol_type type;
289  return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type)
290	  && type == SYMBOL_GOT_DISP);
291})
292
293(define_predicate "got_page_ofst_operand"
294  (match_code "const,symbol_ref,label_ref")
295{
296  enum mips_symbol_type type;
297  return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &type)
298	  && type == SYMBOL_GOT_PAGE_OFST);
299})
300
301(define_predicate "symbol_ref_operand"
302  (match_code "symbol_ref"))
303
304(define_predicate "stack_operand"
305  (and (match_code "mem")
306       (match_test "mips_stack_address_p (XEXP (op, 0), GET_MODE (op))")))
307
308(define_predicate "macc_msac_operand"
309  (ior (and (match_code "plus") (match_test "ISA_HAS_MACC"))
310       (and (match_code "minus") (match_test "ISA_HAS_MSAC")))
311{
312  rtx mult = XEXP (op, GET_CODE (op) == PLUS ? 0 : 1);
313  rtx accum = XEXP (op, GET_CODE (op) == PLUS ? 1 : 0);
314  return (GET_CODE (mult) == MULT
315	  && REG_P (XEXP (mult, 0))
316	  && REG_P (XEXP (mult, 1))
317	  && REG_P (accum));
318})
319
320
321(define_predicate "equality_operator"
322  (match_code "eq,ne"))
323
324(define_predicate "extend_operator"
325  (match_code "zero_extend,sign_extend"))
326
327(define_predicate "trap_comparison_operator"
328  (match_code "eq,ne,lt,ltu,ge,geu"))
329
330(define_predicate "order_operator"
331  (match_code "lt,ltu,le,leu,ge,geu,gt,gtu"))
332
333;; For NE, cstore uses sltu instructions in which the first operand is $0.
334;; This isn't possible in mips16 code.
335
336(define_predicate "mips_cstore_operator"
337  (ior (match_code "eq,gt,gtu,ge,geu,lt,ltu,le,leu")
338       (and (match_code "ne") (match_test "!TARGET_MIPS16"))))
339
340(define_predicate "small_data_pattern"
341  (and (match_code "set,parallel,unspec,unspec_volatile,prefetch")
342       (match_test "mips_small_data_pattern_p (op)")))
343