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
120	      && !(GET_CODE (op) == SYMBOL_REF
121		   && SYMBOL_REF_LONG_CALL_P (op)));
122
123    case SYMBOL_GOT_GLOBAL:
124      /* Without explicit relocs, there is no special syntax for
125	 loading the address of a call destination into a register.
126	 Using "la $25,foo; jal $25" would prevent the lazy binding
127	 of "foo", so keep the address of global symbols with the
128	 jal macro.  */
129      return !TARGET_EXPLICIT_RELOCS;
130
131    default:
132      return false;
133    }
134})
135
136(define_predicate "call_insn_operand"
137  (ior (match_operand 0 "const_call_insn_operand")
138       (match_operand 0 "register_operand")))
139
140;; A legitimate CONST_INT operand that takes more than one instruction
141;; to load.
142(define_predicate "splittable_const_int_operand"
143  (match_code "const_int")
144{
145  /* When generating mips16 code, LEGITIMATE_CONSTANT_P rejects
146     CONST_INTs that can't be loaded using simple insns.  */
147  if (TARGET_MIPS16)
148    return false;
149
150  /* Don't handle multi-word moves this way; we don't want to introduce
151     the individual word-mode moves until after reload.  */
152  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
153    return false;
154
155  /* Otherwise check whether the constant can be loaded in a single
156     instruction.  */
157  return !LUI_INT (op) && !SMALL_INT (op) && !SMALL_INT_UNSIGNED (op);
158})
159
160;; A legitimate symbolic operand that takes more than one instruction
161;; to load.
162(define_predicate "splittable_symbolic_operand"
163  (match_code "const,symbol_ref,label_ref")
164{
165  enum mips_symbol_type symbol_type;
166  return (mips_symbolic_constant_p (op, &symbol_type)
167	  && mips_split_p[symbol_type]);
168})
169
170(define_predicate "move_operand"
171  (match_operand 0 "general_operand")
172{
173  enum mips_symbol_type symbol_type;
174
175  /* The thinking here is as follows:
176
177     (1) The move expanders should split complex load sequences into
178	 individual instructions.  Those individual instructions can
179	 then be optimized by all rtl passes.
180
181     (2) The target of pre-reload load sequences should not be used
182	 to store temporary results.  If the target register is only
183	 assigned one value, reload can rematerialize that value
184	 on demand, rather than spill it to the stack.
185
186     (3) If we allowed pre-reload passes like combine and cse to recreate
187	 complex load sequences, we would want to be able to split the
188	 sequences before reload as well, so that the pre-reload scheduler
189	 can see the individual instructions.  This falls foul of (2);
190	 the splitter would be forced to reuse the target register for
191	 intermediate results.
192
193     (4) We want to define complex load splitters for combine.  These
194	 splitters can request a temporary scratch register, which avoids
195	 the problem in (2).  They allow things like:
196
197	      (set (reg T1) (high SYM))
198	      (set (reg T2) (low (reg T1) SYM))
199	      (set (reg X) (plus (reg T2) (const_int OFFSET)))
200
201	 to be combined into:
202
203	      (set (reg T3) (high SYM+OFFSET))
204	      (set (reg X) (lo_sum (reg T3) SYM+OFFSET))
205
206	 if T2 is only used this once.  */
207  switch (GET_CODE (op))
208    {
209    case CONST_INT:
210      return !splittable_const_int_operand (op, mode);
211
212    case CONST:
213    case SYMBOL_REF:
214    case LABEL_REF:
215      if (CONST_GP_P (op))
216	return true;
217      return (mips_symbolic_constant_p (op, &symbol_type)
218	      && !mips_split_p[symbol_type]);
219
220    default:
221      return true;
222    }
223})
224
225(define_predicate "consttable_operand"
226  (match_test "CONSTANT_P (op)"))
227
228(define_predicate "symbolic_operand"
229  (match_code "const,symbol_ref,label_ref")
230{
231  enum mips_symbol_type type;
232  return mips_symbolic_constant_p (op, &type);
233})
234
235(define_predicate "general_symbolic_operand"
236  (match_code "const,symbol_ref,label_ref")
237{
238  enum mips_symbol_type type;
239  return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GENERAL;
240})
241
242(define_predicate "global_got_operand"
243  (match_code "const,symbol_ref,label_ref")
244{
245  enum mips_symbol_type type;
246  return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_GLOBAL;
247})
248
249(define_predicate "local_got_operand"
250  (match_code "const,symbol_ref,label_ref")
251{
252  enum mips_symbol_type type;
253  return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_LOCAL;
254})
255
256(define_predicate "stack_operand"
257  (and (match_code "mem")
258       (match_test "mips_stack_address_p (XEXP (op, 0), GET_MODE (op))")))
259
260(define_predicate "macc_msac_operand"
261  (ior (and (match_code "plus") (match_test "ISA_HAS_MACC"))
262       (and (match_code "minus") (match_test "ISA_HAS_MSAC")))
263{
264  rtx mult = XEXP (op, GET_CODE (op) == PLUS ? 0 : 1);
265  rtx accum = XEXP (op, GET_CODE (op) == PLUS ? 1 : 0);
266  return (GET_CODE (mult) == MULT
267	  && REG_P (XEXP (mult, 0))
268	  && REG_P (XEXP (mult, 1))
269	  && REG_P (accum));
270})
271
272
273(define_predicate "equality_operator"
274  (match_code "eq,ne"))
275
276(define_predicate "extend_operator"
277  (match_code "zero_extend,sign_extend"))
278
279(define_predicate "trap_comparison_operator"
280  (match_code "eq,ne,lt,ltu,ge,geu"))
281
282(define_predicate "order_operator"
283  (match_code "lt,ltu,le,leu,ge,geu,gt,gtu"))
284
285
286(define_predicate "small_data_pattern"
287  (and (match_code "set,parallel,unspec,unspec_volatile,prefetch")
288       (match_test "mips_small_data_pattern_p (op)")))
289