predicates.md revision 169689
1;; Predicate definitions for MIPS.
2;; Copyright (C) 2004 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 2, 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 COPYING.  If not, write to
18;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19;; Boston, MA 02110-1301, USA.
20
21(define_predicate "const_uns_arith_operand"
22  (and (match_code "const_int")
23       (match_test "SMALL_OPERAND_UNSIGNED (INTVAL (op))")))
24
25(define_predicate "uns_arith_operand"
26  (ior (match_operand 0 "const_uns_arith_operand")
27       (match_operand 0 "register_operand")))
28
29(define_predicate "const_arith_operand"
30  (and (match_code "const_int")
31       (match_test "SMALL_OPERAND (INTVAL (op))")))
32
33(define_predicate "arith_operand"
34  (ior (match_operand 0 "const_arith_operand")
35       (match_operand 0 "register_operand")))
36
37(define_predicate "const_uimm6_operand"
38  (and (match_code "const_int")
39       (match_test "UIMM6_OPERAND (INTVAL (op))")))
40
41(define_predicate "const_imm10_operand"
42  (and (match_code "const_int")
43       (match_test "IMM10_OPERAND (INTVAL (op))")))
44
45(define_predicate "reg_imm10_operand"
46  (ior (match_operand 0 "const_imm10_operand")
47       (match_operand 0 "register_operand")))
48
49(define_predicate "sle_operand"
50  (and (match_code "const_int")
51       (match_test "SMALL_OPERAND (INTVAL (op) + 1)")))
52
53(define_predicate "sleu_operand"
54  (and (match_operand 0 "sle_operand")
55       (match_test "INTVAL (op) + 1 != 0")))
56
57(define_predicate "const_0_operand"
58  (and (match_code "const_int,const_double,const_vector")
59       (match_test "op == CONST0_RTX (GET_MODE (op))")))
60
61(define_predicate "reg_or_0_operand"
62  (ior (and (match_operand 0 "const_0_operand")
63	    (match_test "!TARGET_MIPS16"))
64       (match_operand 0 "register_operand")))
65
66(define_predicate "const_1_operand"
67  (and (match_code "const_int,const_double,const_vector")
68       (match_test "op == CONST1_RTX (GET_MODE (op))")))
69
70(define_predicate "reg_or_1_operand"
71  (ior (match_operand 0 "const_1_operand")
72       (match_operand 0 "register_operand")))
73
74;; This is used for indexing into vectors, and hence only accepts const_int.
75(define_predicate "const_0_or_1_operand"
76  (and (match_code "const_int")
77       (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
78	    (match_test "op == CONST1_RTX (GET_MODE (op))"))))
79
80(define_predicate "fpr_operand"
81  (and (match_code "reg")
82       (match_test "FP_REG_P (REGNO (op))")))
83
84(define_predicate "lo_operand"
85  (and (match_code "reg")
86       (match_test "REGNO (op) == LO_REGNUM")))
87
88(define_predicate "fcc_reload_operand"
89  (and (match_code "reg,subreg")
90       (match_test "ST_REG_P (true_regnum (op))")))
91
92(define_special_predicate "pc_or_label_operand"
93  (match_code "pc,label_ref"))
94
95(define_predicate "const_call_insn_operand"
96  (match_code "const,symbol_ref,label_ref")
97{
98  enum mips_symbol_type symbol_type;
99
100  if (!mips_symbolic_constant_p (op, &symbol_type))
101    return false;
102
103  switch (symbol_type)
104    {
105    case SYMBOL_GENERAL:
106      /* We can only use direct calls for TARGET_ABSOLUTE_ABICALLS if we
107	 are sure that the target function does not need $25 to be live
108	 on entry.  This is true for any locally-defined function because
109	 any such function will use %hi/%lo accesses to set up $gp.  */
110      if (TARGET_ABSOLUTE_ABICALLS
111          && !(GET_CODE (op) == SYMBOL_REF
112	       && SYMBOL_REF_DECL (op)
113	       && !DECL_EXTERNAL (SYMBOL_REF_DECL (op))))
114	return false;
115
116      /* If -mlong-calls, force all calls to use register addressing.  Also,
117	 if this function has the long_call attribute, we must use register
118	 addressing.  */
119      return !TARGET_LONG_CALLS && !SYMBOL_REF_LONG_CALL_P (op);
120
121    case SYMBOL_GOT_GLOBAL:
122      /* Without explicit relocs, there is no special syntax for
123	 loading the address of a call destination into a register.
124	 Using "la $25,foo; jal $25" would prevent the lazy binding
125	 of "foo", so keep the address of global symbols with the
126	 jal macro.  */
127      return !TARGET_EXPLICIT_RELOCS;
128
129    default:
130      return false;
131    }
132})
133
134(define_predicate "call_insn_operand"
135  (ior (match_operand 0 "const_call_insn_operand")
136       (match_operand 0 "register_operand")))
137
138;; A legitimate CONST_INT operand that takes more than one instruction
139;; to load.
140(define_predicate "splittable_const_int_operand"
141  (match_code "const_int")
142{
143  /* When generating mips16 code, LEGITIMATE_CONSTANT_P rejects
144     CONST_INTs that can't be loaded using simple insns.  */
145  if (TARGET_MIPS16)
146    return false;
147
148  /* Don't handle multi-word moves this way; we don't want to introduce
149     the individual word-mode moves until after reload.  */
150  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
151    return false;
152
153  /* Otherwise check whether the constant can be loaded in a single
154     instruction.  */
155  return !LUI_INT (op) && !SMALL_INT (op) && !SMALL_INT_UNSIGNED (op);
156})
157
158;; A legitimate symbolic operand that takes more than one instruction
159;; to load.
160(define_predicate "splittable_symbolic_operand"
161  (match_code "const,symbol_ref,label_ref")
162{
163  enum mips_symbol_type symbol_type;
164  return (mips_symbolic_constant_p (op, &symbol_type)
165	  && mips_split_p[symbol_type]);
166})
167
168(define_predicate "move_operand"
169  (match_operand 0 "general_operand")
170{
171  enum mips_symbol_type symbol_type;
172
173  /* The thinking here is as follows:
174
175     (1) The move expanders should split complex load sequences into
176	 individual instructions.  Those individual instructions can
177	 then be optimized by all rtl passes.
178
179     (2) The target of pre-reload load sequences should not be used
180	 to store temporary results.  If the target register is only
181	 assigned one value, reload can rematerialize that value
182	 on demand, rather than spill it to the stack.
183
184     (3) If we allowed pre-reload passes like combine and cse to recreate
185	 complex load sequences, we would want to be able to split the
186	 sequences before reload as well, so that the pre-reload scheduler
187	 can see the individual instructions.  This falls foul of (2);
188	 the splitter would be forced to reuse the target register for
189	 intermediate results.
190
191     (4) We want to define complex load splitters for combine.  These
192	 splitters can request a temporary scratch register, which avoids
193	 the problem in (2).  They allow things like:
194
195	      (set (reg T1) (high SYM))
196	      (set (reg T2) (low (reg T1) SYM))
197	      (set (reg X) (plus (reg T2) (const_int OFFSET)))
198
199	 to be combined into:
200
201	      (set (reg T3) (high SYM+OFFSET))
202	      (set (reg X) (lo_sum (reg T3) SYM+OFFSET))
203
204	 if T2 is only used this once.  */
205  switch (GET_CODE (op))
206    {
207    case CONST_INT:
208      return !splittable_const_int_operand (op, mode);
209
210    case CONST:
211    case SYMBOL_REF:
212    case LABEL_REF:
213      if (CONST_GP_P (op))
214	return true;
215      return (mips_symbolic_constant_p (op, &symbol_type)
216	      && !mips_split_p[symbol_type]);
217
218    default:
219      return true;
220    }
221})
222
223(define_predicate "consttable_operand"
224  (match_test "CONSTANT_P (op)"))
225
226(define_predicate "symbolic_operand"
227  (match_code "const,symbol_ref,label_ref")
228{
229  enum mips_symbol_type type;
230  return mips_symbolic_constant_p (op, &type);
231})
232
233(define_predicate "general_symbolic_operand"
234  (match_code "const,symbol_ref,label_ref")
235{
236  enum mips_symbol_type type;
237  return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GENERAL;
238})
239
240(define_predicate "global_got_operand"
241  (match_code "const,symbol_ref,label_ref")
242{
243  enum mips_symbol_type type;
244  return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_GLOBAL;
245})
246
247(define_predicate "local_got_operand"
248  (match_code "const,symbol_ref,label_ref")
249{
250  enum mips_symbol_type type;
251  return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_LOCAL;
252})
253
254(define_predicate "stack_operand"
255  (and (match_code "mem")
256       (match_test "mips_stack_address_p (XEXP (op, 0), GET_MODE (op))")))
257
258(define_predicate "macc_msac_operand"
259  (ior (and (match_code "plus") (match_test "ISA_HAS_MACC"))
260       (and (match_code "minus") (match_test "ISA_HAS_MSAC")))
261{
262  rtx mult = XEXP (op, GET_CODE (op) == PLUS ? 0 : 1);
263  rtx accum = XEXP (op, GET_CODE (op) == PLUS ? 1 : 0);
264  return (GET_CODE (mult) == MULT
265	  && REG_P (XEXP (mult, 0))
266	  && REG_P (XEXP (mult, 1))
267	  && REG_P (accum));
268})
269
270
271(define_predicate "equality_operator"
272  (match_code "eq,ne"))
273
274(define_predicate "extend_operator"
275  (match_code "zero_extend,sign_extend"))
276
277(define_predicate "trap_comparison_operator"
278  (match_code "eq,ne,lt,ltu,ge,geu"))
279
280(define_predicate "order_operator"
281  (match_code "lt,ltu,le,leu,ge,geu,gt,gtu"))
282
283
284(define_predicate "small_data_pattern"
285  (and (match_code "set,parallel,unspec,unspec_volatile,prefetch")
286       (match_test "mips_small_data_pattern_p (op)")))
287