1169689Skan;; Predicate definitions for POWER and PowerPC.
2169689Skan;; Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3169689Skan;;
4169689Skan;; This file is part of GCC.
5169689Skan;;
6169689Skan;; GCC is free software; you can redistribute it and/or modify
7169689Skan;; it under the terms of the GNU General Public License as published by
8169689Skan;; the Free Software Foundation; either version 2, or (at your option)
9169689Skan;; any later version.
10169689Skan;;
11169689Skan;; GCC is distributed in the hope that it will be useful,
12169689Skan;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13169689Skan;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169689Skan;; GNU General Public License for more details.
15169689Skan;;
16169689Skan;; You should have received a copy of the GNU General Public License
17169689Skan;; along with GCC; see the file COPYING.  If not, write to
18169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19169689Skan;; Boston, MA 02110-1301, USA.
20169689Skan
21169689Skan;; Return 1 for anything except PARALLEL.
22169689Skan(define_predicate "any_operand"
23169689Skan  (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem"))
24169689Skan
25169689Skan;; Return 1 for any PARALLEL.
26169689Skan(define_predicate "any_parallel_operand"
27169689Skan  (match_code "parallel"))
28169689Skan
29169689Skan;; Return 1 if op is COUNT register.
30169689Skan(define_predicate "count_register_operand"
31169689Skan  (and (match_code "reg")
32169689Skan       (match_test "REGNO (op) == COUNT_REGISTER_REGNUM
33169689Skan		    || REGNO (op) > LAST_VIRTUAL_REGISTER")))
34169689Skan  
35169689Skan;; Return 1 if op is an Altivec register.
36169689Skan(define_predicate "altivec_register_operand"
37169689Skan   (and (match_operand 0 "register_operand")
38169689Skan	(match_test "GET_CODE (op) != REG
39169689Skan		     || ALTIVEC_REGNO_P (REGNO (op))
40169689Skan		     || REGNO (op) > LAST_VIRTUAL_REGISTER")))
41169689Skan
42169689Skan;; Return 1 if op is XER register.
43169689Skan(define_predicate "xer_operand"
44169689Skan  (and (match_code "reg")
45169689Skan       (match_test "XER_REGNO_P (REGNO (op))")))
46169689Skan
47169689Skan;; Return 1 if op is a signed 5-bit constant integer.
48169689Skan(define_predicate "s5bit_cint_operand"
49169689Skan  (and (match_code "const_int")
50169689Skan       (match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15")))
51169689Skan
52169689Skan;; Return 1 if op is a unsigned 5-bit constant integer.
53169689Skan(define_predicate "u5bit_cint_operand"
54169689Skan  (and (match_code "const_int")
55169689Skan       (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 31")))
56169689Skan
57169689Skan;; Return 1 if op is a signed 8-bit constant integer.
58169689Skan;; Integer multiplication complete more quickly
59169689Skan(define_predicate "s8bit_cint_operand"
60169689Skan  (and (match_code "const_int")
61169689Skan       (match_test "INTVAL (op) >= -128 && INTVAL (op) <= 127")))
62169689Skan
63169689Skan;; Return 1 if op is a constant integer that can fit in a D field.
64169689Skan(define_predicate "short_cint_operand"
65169689Skan  (and (match_code "const_int")
66169689Skan       (match_test "satisfies_constraint_I (op)")))
67169689Skan
68169689Skan;; Return 1 if op is a constant integer that can fit in an unsigned D field.
69169689Skan(define_predicate "u_short_cint_operand"
70169689Skan  (and (match_code "const_int")
71169689Skan       (match_test "satisfies_constraint_K (op)")))
72169689Skan
73169689Skan;; Return 1 if op is a constant integer that cannot fit in a signed D field.
74169689Skan(define_predicate "non_short_cint_operand"
75169689Skan  (and (match_code "const_int")
76169689Skan       (match_test "(unsigned HOST_WIDE_INT)
77169689Skan		    (INTVAL (op) + 0x8000) >= 0x10000")))
78169689Skan
79169689Skan;; Return 1 if op is a positive constant integer that is an exact power of 2.
80169689Skan(define_predicate "exact_log2_cint_operand"
81169689Skan  (and (match_code "const_int")
82169689Skan       (match_test "INTVAL (op) > 0 && exact_log2 (INTVAL (op)) >= 0")))
83169689Skan
84169689Skan;; Return 1 if op is a register that is not special.
85169689Skan(define_predicate "gpc_reg_operand"
86169689Skan   (and (match_operand 0 "register_operand")
87169689Skan	(match_test "(GET_CODE (op) != REG
88169689Skan		      || (REGNO (op) >= ARG_POINTER_REGNUM
89169689Skan			  && !XER_REGNO_P (REGNO (op)))
90169689Skan		      || REGNO (op) < MQ_REGNO)
91169689Skan		     && !((TARGET_E500_DOUBLE || TARGET_SPE)
92169689Skan			  && invalid_e500_subreg (op, mode))")))
93169689Skan
94169689Skan;; Return 1 if op is a register that is a condition register field.
95169689Skan(define_predicate "cc_reg_operand"
96169689Skan   (and (match_operand 0 "register_operand")
97169689Skan	(match_test "GET_CODE (op) != REG
98169689Skan		     || REGNO (op) > LAST_VIRTUAL_REGISTER
99169689Skan		     || CR_REGNO_P (REGNO (op))")))
100169689Skan
101169689Skan;; Return 1 if op is a register that is a condition register field not cr0.
102169689Skan(define_predicate "cc_reg_not_cr0_operand"
103169689Skan   (and (match_operand 0 "register_operand")
104169689Skan	(match_test "GET_CODE (op) != REG
105169689Skan		     || REGNO (op) > LAST_VIRTUAL_REGISTER
106169689Skan		     || CR_REGNO_NOT_CR0_P (REGNO (op))")))
107169689Skan
108169689Skan;; Return 1 if op is a constant integer valid for D field
109169689Skan;; or non-special register register.
110169689Skan(define_predicate "reg_or_short_operand"
111169689Skan  (if_then_else (match_code "const_int")
112169689Skan    (match_operand 0 "short_cint_operand")
113169689Skan    (match_operand 0 "gpc_reg_operand")))
114169689Skan
115169689Skan;; Return 1 if op is a constant integer valid whose negation is valid for
116169689Skan;; D field or non-special register register.
117169689Skan;; Do not allow a constant zero because all patterns that call this
118169689Skan;; predicate use "addic r1,r2,-const" to set carry when r2 is greater than
119169689Skan;; or equal to const, which does not work for zero.
120169689Skan(define_predicate "reg_or_neg_short_operand"
121169689Skan  (if_then_else (match_code "const_int")
122169689Skan    (match_test "satisfies_constraint_P (op)
123169689Skan		 && INTVAL (op) != 0")
124169689Skan    (match_operand 0 "gpc_reg_operand")))
125169689Skan
126169689Skan;; Return 1 if op is a constant integer valid for DS field
127169689Skan;; or non-special register.
128169689Skan(define_predicate "reg_or_aligned_short_operand"
129169689Skan  (if_then_else (match_code "const_int")
130169689Skan    (and (match_operand 0 "short_cint_operand")
131169689Skan	 (match_test "!(INTVAL (op) & 3)"))
132169689Skan    (match_operand 0 "gpc_reg_operand")))
133169689Skan
134169689Skan;; Return 1 if op is a constant integer whose high-order 16 bits are zero
135169689Skan;; or non-special register.
136169689Skan(define_predicate "reg_or_u_short_operand"
137169689Skan  (if_then_else (match_code "const_int")
138169689Skan    (match_operand 0 "u_short_cint_operand")
139169689Skan    (match_operand 0 "gpc_reg_operand")))
140169689Skan
141169689Skan;; Return 1 if op is any constant integer 
142169689Skan;; or non-special register.
143169689Skan(define_predicate "reg_or_cint_operand"
144169689Skan  (ior (match_code "const_int")
145169689Skan       (match_operand 0 "gpc_reg_operand")))
146169689Skan
147169689Skan;; Return 1 if op is a constant integer valid for addition
148169689Skan;; or non-special register.
149169689Skan(define_predicate "reg_or_add_cint_operand"
150169689Skan  (if_then_else (match_code "const_int")
151169689Skan    (match_test "(HOST_BITS_PER_WIDE_INT == 32
152169689Skan		  && (mode == SImode || INTVAL (op) < 0x7fff8000))
153169689Skan		 || ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
154169689Skan		     < (unsigned HOST_WIDE_INT) 0x100000000ll)")
155169689Skan    (match_operand 0 "gpc_reg_operand")))
156169689Skan
157169689Skan;; Return 1 if op is a constant integer valid for subtraction
158169689Skan;; or non-special register.
159169689Skan(define_predicate "reg_or_sub_cint_operand"
160169689Skan  (if_then_else (match_code "const_int")
161169689Skan    (match_test "(HOST_BITS_PER_WIDE_INT == 32
162169689Skan		  && (mode == SImode || - INTVAL (op) < 0x7fff8000))
163169689Skan		 || ((unsigned HOST_WIDE_INT) (- INTVAL (op) 
164169689Skan					       + (mode == SImode
165169689Skan						  ? 0x80000000 : 0x80008000))
166169689Skan		     < (unsigned HOST_WIDE_INT) 0x100000000ll)")
167169689Skan    (match_operand 0 "gpc_reg_operand")))
168169689Skan
169169689Skan;; Return 1 if op is any 32-bit unsigned constant integer
170169689Skan;; or non-special register.
171169689Skan(define_predicate "reg_or_logical_cint_operand"
172169689Skan  (if_then_else (match_code "const_int")
173169689Skan    (match_test "(GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT
174169689Skan		  && INTVAL (op) >= 0)
175169689Skan		 || ((INTVAL (op) & GET_MODE_MASK (mode)
176169689Skan		      & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0)")
177169689Skan    (if_then_else (match_code "const_double")
178169689Skan      (match_test "GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT
179169689Skan		   && mode == DImode
180169689Skan		   && CONST_DOUBLE_HIGH (op) == 0")
181169689Skan      (match_operand 0 "gpc_reg_operand"))))
182169689Skan
183169689Skan;; Return 1 if operand is a CONST_DOUBLE that can be set in a register
184169689Skan;; with no more than one instruction per word.
185169689Skan(define_predicate "easy_fp_constant"
186169689Skan  (match_code "const_double")
187169689Skan{
188169689Skan  long k[4];
189169689Skan  REAL_VALUE_TYPE rv;
190169689Skan
191169689Skan  if (GET_MODE (op) != mode
192169689Skan      || (!SCALAR_FLOAT_MODE_P (mode) && mode != DImode))
193169689Skan    return 0;
194169689Skan
195169689Skan  /* Consider all constants with -msoft-float to be easy.  */
196169689Skan  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
197169689Skan      && mode != DImode)
198169689Skan    return 1;
199169689Skan
200169689Skan  if (DECIMAL_FLOAT_MODE_P (mode))
201169689Skan    return 0;
202169689Skan
203169689Skan  /* If we are using V.4 style PIC, consider all constants to be hard.  */
204169689Skan  if (flag_pic && DEFAULT_ABI == ABI_V4)
205169689Skan    return 0;
206169689Skan
207169689Skan#ifdef TARGET_RELOCATABLE
208169689Skan  /* Similarly if we are using -mrelocatable, consider all constants
209169689Skan     to be hard.  */
210169689Skan  if (TARGET_RELOCATABLE)
211169689Skan    return 0;
212169689Skan#endif
213169689Skan
214169689Skan  switch (mode)
215169689Skan    {
216169689Skan    case TFmode:
217169689Skan      REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
218169689Skan      REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
219169689Skan
220169689Skan      return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
221169689Skan	      && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
222169689Skan	      && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
223169689Skan	      && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
224169689Skan
225169689Skan    case DFmode:
226169689Skan      /* Force constants to memory before reload to utilize
227169689Skan	 compress_float_constant.
228169689Skan	 Avoid this when flag_unsafe_math_optimizations is enabled
229169689Skan	 because RDIV division to reciprocal optimization is not able
230169689Skan	 to regenerate the division.  */
231169689Skan      if (TARGET_E500_DOUBLE
232169689Skan          || (!reload_in_progress && !reload_completed
233169689Skan	      && !flag_unsafe_math_optimizations))
234169689Skan        return 0;
235169689Skan
236169689Skan      REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
237169689Skan      REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
238169689Skan
239169689Skan      return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
240169689Skan	      && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
241169689Skan
242169689Skan    case SFmode:
243169689Skan      /* The constant 0.f is easy.  */
244169689Skan      if (op == CONST0_RTX (SFmode))
245169689Skan	return 1;
246169689Skan
247169689Skan      /* Force constants to memory before reload to utilize
248169689Skan	 compress_float_constant.
249169689Skan	 Avoid this when flag_unsafe_math_optimizations is enabled
250169689Skan	 because RDIV division to reciprocal optimization is not able
251169689Skan	 to regenerate the division.  */
252169689Skan      if (!reload_in_progress && !reload_completed
253169689Skan          && !flag_unsafe_math_optimizations)
254169689Skan	return 0;
255169689Skan
256169689Skan      REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
257169689Skan      REAL_VALUE_TO_TARGET_SINGLE (rv, k[0]);
258169689Skan
259169689Skan      return num_insns_constant_wide (k[0]) == 1;
260169689Skan
261169689Skan  case DImode:
262169689Skan    return ((TARGET_POWERPC64
263169689Skan	     && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
264169689Skan	    || (num_insns_constant (op, DImode) <= 2));
265169689Skan
266169689Skan  case SImode:
267169689Skan    return 1;
268169689Skan
269169689Skan  default:
270169689Skan    gcc_unreachable ();
271169689Skan  }
272169689Skan})
273169689Skan
274169689Skan;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a
275169689Skan;; vector register without using memory.
276169689Skan(define_predicate "easy_vector_constant"
277169689Skan  (match_code "const_vector")
278169689Skan{
279169689Skan  if (ALTIVEC_VECTOR_MODE (mode))
280169689Skan    {
281169689Skan      if (zero_constant (op, mode))
282169689Skan        return true;
283169689Skan      return easy_altivec_constant (op, mode);
284169689Skan    }
285169689Skan
286169689Skan  if (SPE_VECTOR_MODE (mode))
287169689Skan    {
288169689Skan      int cst, cst2;
289169689Skan      if (zero_constant (op, mode))
290169689Skan	return true;
291169689Skan      if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
292169689Skan        return false;
293169689Skan
294169689Skan      /* Limit SPE vectors to 15 bits signed.  These we can generate with:
295169689Skan	   li r0, CONSTANT1
296169689Skan	   evmergelo r0, r0, r0
297169689Skan	   li r0, CONSTANT2
298169689Skan
299169689Skan	 I don't know how efficient it would be to allow bigger constants,
300169689Skan	 considering we'll have an extra 'ori' for every 'li'.  I doubt 5
301169689Skan	 instructions is better than a 64-bit memory load, but I don't
302169689Skan	 have the e500 timing specs.  */
303169689Skan      if (mode == V2SImode)
304169689Skan	{
305169689Skan	  cst  = INTVAL (CONST_VECTOR_ELT (op, 0));
306169689Skan	  cst2 = INTVAL (CONST_VECTOR_ELT (op, 1));
307169689Skan	  return cst  >= -0x7fff && cst <= 0x7fff
308169689Skan	         && cst2 >= -0x7fff && cst2 <= 0x7fff;
309169689Skan	}
310169689Skan    }
311169689Skan
312169689Skan  return false;
313169689Skan})
314169689Skan
315169689Skan;; Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF.
316169689Skan(define_predicate "easy_vector_constant_add_self"
317169689Skan  (and (match_code "const_vector")
318169689Skan       (and (match_test "TARGET_ALTIVEC")
319169689Skan	    (match_test "easy_altivec_constant (op, mode)")))
320169689Skan{
321169689Skan  rtx last = CONST_VECTOR_ELT (op, GET_MODE_NUNITS (mode) - 1);
322169689Skan  HOST_WIDE_INT val = ((INTVAL (last) & 0xff) ^ 0x80) - 0x80;
323169689Skan  return EASY_VECTOR_15_ADD_SELF (val);
324169689Skan})
325169689Skan
326169689Skan;; Return 1 if operand is constant zero (scalars and vectors).
327169689Skan(define_predicate "zero_constant"
328169689Skan  (and (match_code "const_int,const_double,const_vector")
329169689Skan       (match_test "op == CONST0_RTX (mode)")))
330169689Skan
331169689Skan;; Return 1 if operand is 0.0.
332169689Skan;; or non-special register register field no cr0
333169689Skan(define_predicate "zero_fp_constant"
334169689Skan  (and (match_code "const_double")
335169689Skan       (match_test "SCALAR_FLOAT_MODE_P (mode)
336169689Skan		    && op == CONST0_RTX (mode)")))
337169689Skan
338169689Skan;; Return 1 if the operand is in volatile memory.  Note that during the
339169689Skan;; RTL generation phase, memory_operand does not return TRUE for volatile
340169689Skan;; memory references.  So this function allows us to recognize volatile
341169689Skan;; references where it's safe.
342169689Skan(define_predicate "volatile_mem_operand"
343169689Skan  (and (and (match_code "mem")
344169689Skan	    (match_test "MEM_VOLATILE_P (op)"))
345169689Skan       (if_then_else (match_test "reload_completed")
346169689Skan         (match_operand 0 "memory_operand")
347169689Skan         (if_then_else (match_test "reload_in_progress")
348169689Skan	   (match_test "strict_memory_address_p (mode, XEXP (op, 0))")
349169689Skan	   (match_test "memory_address_p (mode, XEXP (op, 0))")))))
350169689Skan
351169689Skan;; Return 1 if the operand is an offsettable memory operand.
352169689Skan(define_predicate "offsettable_mem_operand"
353169689Skan  (and (match_code "mem")
354169689Skan       (match_test "offsettable_address_p (reload_completed
355169689Skan					   || reload_in_progress,
356169689Skan					   mode, XEXP (op, 0))")))
357169689Skan
358169689Skan;; Return 1 if the operand is a memory operand with an address divisible by 4
359169689Skan(define_predicate "word_offset_memref_operand"
360169689Skan  (and (match_operand 0 "memory_operand")
361169689Skan       (match_test "GET_CODE (XEXP (op, 0)) != PLUS
362169689Skan		    || ! REG_P (XEXP (XEXP (op, 0), 0)) 
363169689Skan		    || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT
364169689Skan		    || INTVAL (XEXP (XEXP (op, 0), 1)) % 4 == 0")))
365169689Skan
366169689Skan;; Return 1 if the operand is an indexed or indirect memory operand.
367169689Skan(define_predicate "indexed_or_indirect_operand"
368169689Skan  (match_code "mem")
369169689Skan{
370169689Skan  op = XEXP (op, 0);
371169689Skan  if (TARGET_ALTIVEC
372169689Skan      && ALTIVEC_VECTOR_MODE (mode)
373169689Skan      && GET_CODE (op) == AND
374169689Skan      && GET_CODE (XEXP (op, 1)) == CONST_INT
375169689Skan      && INTVAL (XEXP (op, 1)) == -16)
376169689Skan    op = XEXP (op, 0);
377169689Skan
378169689Skan  return indexed_or_indirect_address (op, mode);
379169689Skan})
380169689Skan
381169689Skan;; Return 1 if the operand is an indexed or indirect address.
382169689Skan(define_special_predicate "indexed_or_indirect_address"
383169689Skan  (and (match_test "REG_P (op)
384169689Skan		    || (GET_CODE (op) == PLUS
385169689Skan			/* Omit testing REG_P (XEXP (op, 0)).  */
386169689Skan			&& REG_P (XEXP (op, 1)))")
387169689Skan       (match_operand 0 "address_operand")))
388169689Skan
389169689Skan;; Used for the destination of the fix_truncdfsi2 expander.
390169689Skan;; If stfiwx will be used, the result goes to memory; otherwise,
391169689Skan;; we're going to emit a store and a load of a subreg, so the dest is a
392169689Skan;; register.
393169689Skan(define_predicate "fix_trunc_dest_operand"
394169689Skan  (if_then_else (match_test "! TARGET_E500_DOUBLE && TARGET_PPC_GFXOPT")
395169689Skan   (match_operand 0 "memory_operand")
396169689Skan   (match_operand 0 "gpc_reg_operand")))
397169689Skan
398169689Skan;; Return 1 if the operand is either a non-special register or can be used
399169689Skan;; as the operand of a `mode' add insn.
400169689Skan(define_predicate "add_operand"
401169689Skan  (if_then_else (match_code "const_int")
402169689Skan    (match_test "satisfies_constraint_I (op)
403169689Skan		 || satisfies_constraint_L (op)")
404169689Skan    (match_operand 0 "gpc_reg_operand")))
405169689Skan
406169689Skan;; Return 1 if OP is a constant but not a valid add_operand.
407169689Skan(define_predicate "non_add_cint_operand"
408169689Skan  (and (match_code "const_int")
409169689Skan       (match_test "!satisfies_constraint_I (op)
410169689Skan		    && !satisfies_constraint_L (op)")))
411169689Skan
412169689Skan;; Return 1 if the operand is a constant that can be used as the operand
413169689Skan;; of an OR or XOR.
414169689Skan(define_predicate "logical_const_operand"
415169689Skan  (match_code "const_int,const_double")
416169689Skan{
417169689Skan  HOST_WIDE_INT opl, oph;
418169689Skan
419169689Skan  if (GET_CODE (op) == CONST_INT)
420169689Skan    {
421169689Skan      opl = INTVAL (op) & GET_MODE_MASK (mode);
422169689Skan
423169689Skan      if (HOST_BITS_PER_WIDE_INT <= 32
424169689Skan	  && GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
425169689Skan	return 0;
426169689Skan    }
427169689Skan  else if (GET_CODE (op) == CONST_DOUBLE)
428169689Skan    {
429169689Skan      gcc_assert (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT);
430169689Skan
431169689Skan      opl = CONST_DOUBLE_LOW (op);
432169689Skan      oph = CONST_DOUBLE_HIGH (op);
433169689Skan      if (oph != 0)
434169689Skan	return 0;
435169689Skan    }
436169689Skan  else
437169689Skan    return 0;
438169689Skan
439169689Skan  return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
440169689Skan	  || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
441169689Skan})
442169689Skan
443169689Skan;; Return 1 if the operand is a non-special register or a constant that
444169689Skan;; can be used as the operand of an OR or XOR.
445169689Skan(define_predicate "logical_operand"
446169689Skan  (ior (match_operand 0 "gpc_reg_operand")
447169689Skan       (match_operand 0 "logical_const_operand")))
448169689Skan
449169689Skan;; Return 1 if op is a constant that is not a logical operand, but could
450169689Skan;; be split into one.
451169689Skan(define_predicate "non_logical_cint_operand"
452169689Skan  (and (match_code "const_int,const_double")
453169689Skan       (and (not (match_operand 0 "logical_operand"))
454169689Skan	    (match_operand 0 "reg_or_logical_cint_operand"))))
455169689Skan
456169689Skan;; Return 1 if op is a constant that can be encoded in a 32-bit mask,
457169689Skan;; suitable for use with rlwinm (no more than two 1->0 or 0->1
458169689Skan;; transitions).  Reject all ones and all zeros, since these should have
459169689Skan;; been optimized away and confuse the making of MB and ME.
460169689Skan(define_predicate "mask_operand"
461169689Skan  (match_code "const_int")
462169689Skan{
463169689Skan  HOST_WIDE_INT c, lsb;
464169689Skan
465169689Skan  c = INTVAL (op);
466169689Skan
467169689Skan  if (TARGET_POWERPC64)
468169689Skan    {
469169689Skan      /* Fail if the mask is not 32-bit.  */
470169689Skan      if (mode == DImode && (c & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0)
471169689Skan	return 0;
472169689Skan
473169689Skan      /* Fail if the mask wraps around because the upper 32-bits of the
474169689Skan	 mask will all be 1s, contrary to GCC's internal view.  */
475169689Skan      if ((c & 0x80000001) == 0x80000001)
476169689Skan	return 0;
477169689Skan    }
478169689Skan
479169689Skan  /* We don't change the number of transitions by inverting,
480169689Skan     so make sure we start with the LS bit zero.  */
481169689Skan  if (c & 1)
482169689Skan    c = ~c;
483169689Skan
484169689Skan  /* Reject all zeros or all ones.  */
485169689Skan  if (c == 0)
486169689Skan    return 0;
487169689Skan
488169689Skan  /* Find the first transition.  */
489169689Skan  lsb = c & -c;
490169689Skan
491169689Skan  /* Invert to look for a second transition.  */
492169689Skan  c = ~c;
493169689Skan
494169689Skan  /* Erase first transition.  */
495169689Skan  c &= -lsb;
496169689Skan
497169689Skan  /* Find the second transition (if any).  */
498169689Skan  lsb = c & -c;
499169689Skan
500169689Skan  /* Match if all the bits above are 1's (or c is zero).  */
501169689Skan  return c == -lsb;
502169689Skan})
503169689Skan
504169689Skan;; Return 1 for the PowerPC64 rlwinm corner case.
505169689Skan(define_predicate "mask_operand_wrap"
506169689Skan  (match_code "const_int")
507169689Skan{
508169689Skan  HOST_WIDE_INT c, lsb;
509169689Skan
510169689Skan  c = INTVAL (op);
511169689Skan
512169689Skan  if ((c & 0x80000001) != 0x80000001)
513169689Skan    return 0;
514169689Skan
515169689Skan  c = ~c;
516169689Skan  if (c == 0)
517169689Skan    return 0;
518169689Skan
519169689Skan  lsb = c & -c;
520169689Skan  c = ~c;
521169689Skan  c &= -lsb;
522169689Skan  lsb = c & -c;
523169689Skan  return c == -lsb;
524169689Skan})
525169689Skan
526169689Skan;; Return 1 if the operand is a constant that is a PowerPC64 mask
527169689Skan;; suitable for use with rldicl or rldicr (no more than one 1->0 or 0->1
528169689Skan;; transition).  Reject all zeros, since zero should have been
529169689Skan;; optimized away and confuses the making of MB and ME.
530169689Skan(define_predicate "mask64_operand"
531169689Skan  (match_code "const_int")
532169689Skan{
533169689Skan  HOST_WIDE_INT c, lsb;
534169689Skan
535169689Skan  c = INTVAL (op);
536169689Skan
537169689Skan  /* Reject all zeros.  */
538169689Skan  if (c == 0)
539169689Skan    return 0;
540169689Skan
541169689Skan  /* We don't change the number of transitions by inverting,
542169689Skan     so make sure we start with the LS bit zero.  */
543169689Skan  if (c & 1)
544169689Skan    c = ~c;
545169689Skan
546169689Skan  /* Find the first transition.  */
547169689Skan  lsb = c & -c;
548169689Skan
549169689Skan  /* Match if all the bits above are 1's (or c is zero).  */
550169689Skan  return c == -lsb;
551169689Skan})
552169689Skan
553169689Skan;; Like mask64_operand, but allow up to three transitions.  This
554169689Skan;; predicate is used by insn patterns that generate two rldicl or
555169689Skan;; rldicr machine insns.
556169689Skan(define_predicate "mask64_2_operand"
557169689Skan  (match_code "const_int")
558169689Skan{
559169689Skan  HOST_WIDE_INT c, lsb;
560169689Skan
561169689Skan  c = INTVAL (op);
562169689Skan
563169689Skan  /* Disallow all zeros.  */
564169689Skan  if (c == 0)
565169689Skan    return 0;
566169689Skan
567169689Skan  /* We don't change the number of transitions by inverting,
568169689Skan     so make sure we start with the LS bit zero.  */
569169689Skan  if (c & 1)
570169689Skan    c = ~c;
571169689Skan
572169689Skan  /* Find the first transition.  */
573169689Skan  lsb = c & -c;
574169689Skan
575169689Skan  /* Invert to look for a second transition.  */
576169689Skan  c = ~c;
577169689Skan
578169689Skan  /* Erase first transition.  */
579169689Skan  c &= -lsb;
580169689Skan
581169689Skan  /* Find the second transition.  */
582169689Skan  lsb = c & -c;
583169689Skan
584169689Skan  /* Invert to look for a third transition.  */
585169689Skan  c = ~c;
586169689Skan
587169689Skan  /* Erase second transition.  */
588169689Skan  c &= -lsb;
589169689Skan
590169689Skan  /* Find the third transition (if any).  */
591169689Skan  lsb = c & -c;
592169689Skan
593169689Skan  /* Match if all the bits above are 1's (or c is zero).  */
594169689Skan  return c == -lsb;
595169689Skan})
596169689Skan
597169689Skan;; Like and_operand, but also match constants that can be implemented
598169689Skan;; with two rldicl or rldicr insns.
599169689Skan(define_predicate "and64_2_operand"
600169689Skan  (ior (match_operand 0 "mask64_2_operand")
601169689Skan       (if_then_else (match_test "fixed_regs[CR0_REGNO]")
602169689Skan	 (match_operand 0 "gpc_reg_operand")
603169689Skan	 (match_operand 0 "logical_operand"))))
604169689Skan
605169689Skan;; Return 1 if the operand is either a non-special register or a
606169689Skan;; constant that can be used as the operand of a logical AND.
607169689Skan(define_predicate "and_operand"
608169689Skan  (ior (match_operand 0 "mask_operand")
609169689Skan       (ior (and (match_test "TARGET_POWERPC64 && mode == DImode")
610169689Skan		 (match_operand 0 "mask64_operand"))
611169689Skan            (if_then_else (match_test "fixed_regs[CR0_REGNO]")
612169689Skan	      (match_operand 0 "gpc_reg_operand")
613169689Skan	      (match_operand 0 "logical_operand")))))
614169689Skan
615169689Skan;; Return 1 if the operand is either a logical operand or a short cint operand.
616169689Skan(define_predicate "scc_eq_operand"
617169689Skan  (ior (match_operand 0 "logical_operand")
618169689Skan       (match_operand 0 "short_cint_operand")))
619169689Skan
620169689Skan;; Return 1 if the operand is a general non-special register or memory operand.
621169689Skan(define_predicate "reg_or_mem_operand"
622169689Skan     (ior (match_operand 0 "memory_operand")
623169689Skan	  (ior (and (match_code "mem")
624169689Skan		    (match_test "macho_lo_sum_memory_operand (op, mode)"))
625169689Skan	       (ior (match_operand 0 "volatile_mem_operand")
626169689Skan		    (match_operand 0 "gpc_reg_operand")))))
627169689Skan
628169689Skan;; Return 1 if the operand is either an easy FP constant or memory or reg.
629169689Skan(define_predicate "reg_or_none500mem_operand"
630169689Skan  (if_then_else (match_code "mem")
631169689Skan     (and (match_test "!TARGET_E500_DOUBLE")
632169689Skan	  (ior (match_operand 0 "memory_operand")
633169689Skan	       (ior (match_test "macho_lo_sum_memory_operand (op, mode)")
634169689Skan		    (match_operand 0 "volatile_mem_operand"))))
635169689Skan     (match_operand 0 "gpc_reg_operand")))
636169689Skan
637169689Skan;; Return 1 if the operand is CONST_DOUBLE 0, register or memory operand.
638169689Skan(define_predicate "zero_reg_mem_operand"
639169689Skan  (ior (match_operand 0 "zero_fp_constant")
640169689Skan       (match_operand 0 "reg_or_mem_operand")))
641169689Skan
642169689Skan;; Return 1 if the operand is a general register or memory operand without
643169689Skan;; pre_inc or pre_dec, which produces invalid form of PowerPC lwa
644169689Skan;; instruction.
645169689Skan(define_predicate "lwa_operand"
646169689Skan  (match_code "reg,subreg,mem")
647169689Skan{
648169689Skan  rtx inner = op;
649169689Skan
650169689Skan  if (reload_completed && GET_CODE (inner) == SUBREG)
651169689Skan    inner = SUBREG_REG (inner);
652169689Skan
653169689Skan  return gpc_reg_operand (inner, mode)
654169689Skan    || (memory_operand (inner, mode)
655169689Skan	&& GET_CODE (XEXP (inner, 0)) != PRE_INC
656169689Skan	&& GET_CODE (XEXP (inner, 0)) != PRE_DEC
657169689Skan	&& (GET_CODE (XEXP (inner, 0)) != PLUS
658169689Skan	    || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
659169689Skan	    || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
660169689Skan})
661169689Skan
662169689Skan;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF.
663169689Skan(define_predicate "symbol_ref_operand"
664169689Skan  (and (match_code "symbol_ref")
665169689Skan       (match_test "(mode == VOIDmode || GET_MODE (op) == mode)
666169689Skan		    && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))")))
667169689Skan
668169689Skan;; Return 1 if op is an operand that can be loaded via the GOT.
669169689Skan;; or non-special register register field no cr0
670169689Skan(define_predicate "got_operand"
671169689Skan  (match_code "symbol_ref,const,label_ref"))
672169689Skan
673169689Skan;; Return 1 if op is a simple reference that can be loaded via the GOT,
674169689Skan;; excluding labels involving addition.
675169689Skan(define_predicate "got_no_const_operand"
676169689Skan  (match_code "symbol_ref,label_ref"))
677169689Skan
678169689Skan;; Return 1 if op is a SYMBOL_REF for a TLS symbol.
679169689Skan(define_predicate "rs6000_tls_symbol_ref"
680169689Skan  (and (match_code "symbol_ref")
681169689Skan       (match_test "RS6000_SYMBOL_REF_TLS_P (op)")))
682169689Skan
683169689Skan;; Return 1 if the operand, used inside a MEM, is a valid first argument
684169689Skan;; to CALL.  This is a SYMBOL_REF, a pseudo-register, LR or CTR.
685169689Skan(define_predicate "call_operand"
686169689Skan  (if_then_else (match_code "reg")
687169689Skan     (match_test "REGNO (op) == LINK_REGISTER_REGNUM
688169689Skan		  || REGNO (op) == COUNT_REGISTER_REGNUM
689169689Skan		  || REGNO (op) >= FIRST_PSEUDO_REGISTER")
690169689Skan     (match_code "symbol_ref")))
691169689Skan
692169689Skan;; Return 1 if the operand is a SYMBOL_REF for a function known to be in
693169689Skan;; this file.
694169689Skan(define_predicate "current_file_function_operand"
695169689Skan  (and (match_code "symbol_ref")
696169689Skan       (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
697171825Skan		    && ((SYMBOL_REF_LOCAL_P (op)
698171825Skan			 && (DEFAULT_ABI != ABI_AIX
699171825Skan			     || !SYMBOL_REF_EXTERNAL_P (op)))
700169689Skan		        || (op == XEXP (DECL_RTL (current_function_decl),
701169689Skan						  0)))")))
702169689Skan
703169689Skan;; Return 1 if this operand is a valid input for a move insn.
704169689Skan(define_predicate "input_operand"
705169689Skan  (match_code "label_ref,symbol_ref,const,high,reg,subreg,mem,
706169689Skan	       const_double,const_vector,const_int,plus")
707169689Skan{
708169689Skan  /* Memory is always valid.  */
709169689Skan  if (memory_operand (op, mode))
710169689Skan    return 1;
711169689Skan
712169689Skan  /* For floating-point, easy constants are valid.  */
713169689Skan  if (SCALAR_FLOAT_MODE_P (mode)
714169689Skan      && CONSTANT_P (op)
715169689Skan      && easy_fp_constant (op, mode))
716169689Skan    return 1;
717169689Skan
718169689Skan  /* Allow any integer constant.  */
719169689Skan  if (GET_MODE_CLASS (mode) == MODE_INT
720169689Skan      && (GET_CODE (op) == CONST_INT
721169689Skan	  || GET_CODE (op) == CONST_DOUBLE))
722169689Skan    return 1;
723169689Skan
724169689Skan  /* Allow easy vector constants.  */
725169689Skan  if (GET_CODE (op) == CONST_VECTOR
726169689Skan      && easy_vector_constant (op, mode))
727169689Skan    return 1;
728169689Skan
729169689Skan  /* Do not allow invalid E500 subregs.  */
730169689Skan  if ((TARGET_E500_DOUBLE || TARGET_SPE)
731169689Skan      && GET_CODE (op) == SUBREG
732169689Skan      && invalid_e500_subreg (op, mode))
733169689Skan    return 0;
734169689Skan
735169689Skan  /* For floating-point or multi-word mode, the only remaining valid type
736169689Skan     is a register.  */
737169689Skan  if (SCALAR_FLOAT_MODE_P (mode)
738169689Skan      || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
739169689Skan    return register_operand (op, mode);
740169689Skan
741169689Skan  /* The only cases left are integral modes one word or smaller (we
742169689Skan     do not get called for MODE_CC values).  These can be in any
743169689Skan     register.  */
744169689Skan  if (register_operand (op, mode))
745169689Skan    return 1;
746169689Skan
747169689Skan  /* A SYMBOL_REF referring to the TOC is valid.  */
748169689Skan  if (legitimate_constant_pool_address_p (op))
749169689Skan    return 1;
750169689Skan
751169689Skan  /* A constant pool expression (relative to the TOC) is valid */
752169689Skan  if (toc_relative_expr_p (op))
753169689Skan    return 1;
754169689Skan
755169689Skan  /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
756169689Skan     to be valid.  */
757169689Skan  if (DEFAULT_ABI == ABI_V4
758169689Skan      && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
759169689Skan      && small_data_operand (op, Pmode))
760169689Skan    return 1;
761169689Skan
762169689Skan  return 0;
763169689Skan})
764169689Skan
765169689Skan;; Return true if OP is an invalid SUBREG operation on the e500.
766169689Skan(define_predicate "rs6000_nonimmediate_operand"
767169689Skan  (match_code "reg,subreg,mem")
768169689Skan{
769169689Skan  if ((TARGET_E500_DOUBLE || TARGET_SPE)
770169689Skan      && GET_CODE (op) == SUBREG
771169689Skan      && invalid_e500_subreg (op, mode))
772169689Skan    return 0;
773169689Skan
774169689Skan  return nonimmediate_operand (op, mode);
775169689Skan})
776169689Skan
777169689Skan;; Return true if operand is boolean operator.
778169689Skan(define_predicate "boolean_operator"
779169689Skan  (match_code "and,ior,xor"))
780169689Skan
781169689Skan;; Return true if operand is OR-form of boolean operator.
782169689Skan(define_predicate "boolean_or_operator"
783169689Skan  (match_code "ior,xor"))
784169689Skan
785169689Skan;; Return true if operand is an equality operator.
786169689Skan(define_special_predicate "equality_operator"
787169689Skan  (match_code "eq,ne"))
788169689Skan
789169689Skan;; Return true if operand is MIN or MAX operator.
790169689Skan(define_predicate "min_max_operator"
791169689Skan  (match_code "smin,smax,umin,umax"))
792169689Skan
793169689Skan;; Return 1 if OP is a comparison operation that is valid for a branch
794169689Skan;; instruction.  We check the opcode against the mode of the CC value.
795169689Skan;; validate_condition_mode is an assertion.
796169689Skan(define_predicate "branch_comparison_operator"
797169689Skan   (and (match_operand 0 "comparison_operator")
798169689Skan	(and (match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC")
799169689Skan	     (match_test "validate_condition_mode (GET_CODE (op),
800169689Skan						   GET_MODE (XEXP (op, 0))),
801169689Skan			  1"))))
802169689Skan
803169689Skan;; Return 1 if OP is a comparison operation that is valid for an SCC insn --
804169689Skan;; it must be a positive comparison.
805169689Skan(define_predicate "scc_comparison_operator"
806169689Skan  (and (match_operand 0 "branch_comparison_operator")
807169689Skan       (match_code "eq,lt,gt,ltu,gtu,unordered")))
808169689Skan
809169689Skan;; Return 1 if OP is a comparison operation that is valid for a branch
810169689Skan;; insn, which is true if the corresponding bit in the CC register is set.
811169689Skan(define_predicate "branch_positive_comparison_operator"
812169689Skan  (and (match_operand 0 "branch_comparison_operator")
813169689Skan       (match_code "eq,lt,gt,ltu,gtu,unordered")))
814169689Skan
815169689Skan;; Return 1 is OP is a comparison operation that is valid for a trap insn.
816169689Skan(define_predicate "trap_comparison_operator"
817169689Skan   (and (match_operand 0 "comparison_operator")
818169689Skan	(match_code "eq,ne,le,lt,ge,gt,leu,ltu,geu,gtu")))
819169689Skan
820169689Skan;; Return 1 if OP is a load multiple operation, known to be a PARALLEL.
821169689Skan(define_predicate "load_multiple_operation"
822169689Skan  (match_code "parallel")
823169689Skan{
824169689Skan  int count = XVECLEN (op, 0);
825169689Skan  unsigned int dest_regno;
826169689Skan  rtx src_addr;
827169689Skan  int i;
828169689Skan
829169689Skan  /* Perform a quick check so we don't blow up below.  */
830169689Skan  if (count <= 1
831169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET
832169689Skan      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
833169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
834169689Skan    return 0;
835169689Skan
836169689Skan  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
837169689Skan  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
838169689Skan
839169689Skan  for (i = 1; i < count; i++)
840169689Skan    {
841169689Skan      rtx elt = XVECEXP (op, 0, i);
842169689Skan
843169689Skan      if (GET_CODE (elt) != SET
844169689Skan	  || GET_CODE (SET_DEST (elt)) != REG
845169689Skan	  || GET_MODE (SET_DEST (elt)) != SImode
846169689Skan	  || REGNO (SET_DEST (elt)) != dest_regno + i
847169689Skan	  || GET_CODE (SET_SRC (elt)) != MEM
848169689Skan	  || GET_MODE (SET_SRC (elt)) != SImode
849169689Skan	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
850169689Skan	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
851169689Skan	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
852169689Skan	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
853169689Skan	return 0;
854169689Skan    }
855169689Skan
856169689Skan  return 1;
857169689Skan})
858169689Skan
859169689Skan;; Return 1 if OP is a store multiple operation, known to be a PARALLEL.
860169689Skan;; The second vector element is a CLOBBER.
861169689Skan(define_predicate "store_multiple_operation"
862169689Skan  (match_code "parallel")
863169689Skan{
864169689Skan  int count = XVECLEN (op, 0) - 1;
865169689Skan  unsigned int src_regno;
866169689Skan  rtx dest_addr;
867169689Skan  int i;
868169689Skan
869169689Skan  /* Perform a quick check so we don't blow up below.  */
870169689Skan  if (count <= 1
871169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET
872169689Skan      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
873169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
874169689Skan    return 0;
875169689Skan
876169689Skan  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
877169689Skan  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
878169689Skan
879169689Skan  for (i = 1; i < count; i++)
880169689Skan    {
881169689Skan      rtx elt = XVECEXP (op, 0, i + 1);
882169689Skan
883169689Skan      if (GET_CODE (elt) != SET
884169689Skan	  || GET_CODE (SET_SRC (elt)) != REG
885169689Skan	  || GET_MODE (SET_SRC (elt)) != SImode
886169689Skan	  || REGNO (SET_SRC (elt)) != src_regno + i
887169689Skan	  || GET_CODE (SET_DEST (elt)) != MEM
888169689Skan	  || GET_MODE (SET_DEST (elt)) != SImode
889169689Skan	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
890169689Skan	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
891169689Skan	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
892169689Skan	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
893169689Skan	return 0;
894169689Skan    }
895169689Skan
896169689Skan  return 1;
897169689Skan})
898169689Skan
899169689Skan;; Return 1 if OP is valid for a save_world call in prologue, known to be
900169689Skan;; a PARLLEL.
901169689Skan(define_predicate "save_world_operation"
902169689Skan  (match_code "parallel")
903169689Skan{
904169689Skan  int index;
905169689Skan  int i;
906169689Skan  rtx elt;
907169689Skan  int count = XVECLEN (op, 0);
908169689Skan
909169689Skan  if (count != 55)
910169689Skan    return 0;
911169689Skan
912169689Skan  index = 0;
913169689Skan  if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
914169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != USE)
915169689Skan    return 0;
916169689Skan
917169689Skan  for (i=1; i <= 18; i++)
918169689Skan    {
919169689Skan      elt = XVECEXP (op, 0, index++);
920169689Skan      if (GET_CODE (elt) != SET
921169689Skan	  || GET_CODE (SET_DEST (elt)) != MEM
922169689Skan	  || ! memory_operand (SET_DEST (elt), DFmode)
923169689Skan	  || GET_CODE (SET_SRC (elt)) != REG
924169689Skan	  || GET_MODE (SET_SRC (elt)) != DFmode)
925169689Skan	return 0;
926169689Skan    }
927169689Skan
928169689Skan  for (i=1; i <= 12; i++)
929169689Skan    {
930169689Skan      elt = XVECEXP (op, 0, index++);
931169689Skan      if (GET_CODE (elt) != SET
932169689Skan	  || GET_CODE (SET_DEST (elt)) != MEM
933169689Skan	  || GET_CODE (SET_SRC (elt)) != REG
934169689Skan	  || GET_MODE (SET_SRC (elt)) != V4SImode)
935169689Skan	return 0;
936169689Skan    }
937169689Skan
938169689Skan  for (i=1; i <= 19; i++)
939169689Skan    {
940169689Skan      elt = XVECEXP (op, 0, index++);
941169689Skan      if (GET_CODE (elt) != SET
942169689Skan	  || GET_CODE (SET_DEST (elt)) != MEM
943169689Skan	  || ! memory_operand (SET_DEST (elt), Pmode)
944169689Skan	  || GET_CODE (SET_SRC (elt)) != REG
945169689Skan	  || GET_MODE (SET_SRC (elt)) != Pmode)
946169689Skan	return 0;
947169689Skan    }
948169689Skan
949169689Skan  elt = XVECEXP (op, 0, index++);
950169689Skan  if (GET_CODE (elt) != SET
951169689Skan      || GET_CODE (SET_DEST (elt)) != MEM
952169689Skan      || ! memory_operand (SET_DEST (elt), Pmode)
953169689Skan      || GET_CODE (SET_SRC (elt)) != REG
954169689Skan      || REGNO (SET_SRC (elt)) != CR2_REGNO
955169689Skan      || GET_MODE (SET_SRC (elt)) != Pmode)
956169689Skan    return 0;
957169689Skan
958169689Skan  if (GET_CODE (XVECEXP (op, 0, index++)) != USE
959169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != USE
960169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER)
961169689Skan    return 0;
962169689Skan  return 1;
963169689Skan})
964169689Skan
965169689Skan;; Return 1 if OP is valid for a restore_world call in epilogue, known to be
966169689Skan;; a PARLLEL.
967169689Skan(define_predicate "restore_world_operation"
968169689Skan  (match_code "parallel")
969169689Skan{
970169689Skan  int index;
971169689Skan  int i;
972169689Skan  rtx elt;
973169689Skan  int count = XVECLEN (op, 0);
974169689Skan
975169689Skan  if (count != 59)
976169689Skan    return 0;
977169689Skan
978169689Skan  index = 0;
979169689Skan  if (GET_CODE (XVECEXP (op, 0, index++)) != RETURN
980169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != USE
981169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != USE
982169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER)
983169689Skan    return 0;
984169689Skan
985169689Skan  elt = XVECEXP (op, 0, index++);
986169689Skan  if (GET_CODE (elt) != SET
987169689Skan      || GET_CODE (SET_SRC (elt)) != MEM
988169689Skan      || ! memory_operand (SET_SRC (elt), Pmode)
989169689Skan      || GET_CODE (SET_DEST (elt)) != REG
990169689Skan      || REGNO (SET_DEST (elt)) != CR2_REGNO
991169689Skan      || GET_MODE (SET_DEST (elt)) != Pmode)
992169689Skan    return 0;
993169689Skan
994169689Skan  for (i=1; i <= 19; i++)
995169689Skan    {
996169689Skan      elt = XVECEXP (op, 0, index++);
997169689Skan      if (GET_CODE (elt) != SET
998169689Skan	  || GET_CODE (SET_SRC (elt)) != MEM
999169689Skan	  || ! memory_operand (SET_SRC (elt), Pmode)
1000169689Skan	  || GET_CODE (SET_DEST (elt)) != REG
1001169689Skan	  || GET_MODE (SET_DEST (elt)) != Pmode)
1002169689Skan	return 0;
1003169689Skan    }
1004169689Skan
1005169689Skan  for (i=1; i <= 12; i++)
1006169689Skan    {
1007169689Skan      elt = XVECEXP (op, 0, index++);
1008169689Skan      if (GET_CODE (elt) != SET
1009169689Skan	  || GET_CODE (SET_SRC (elt)) != MEM
1010169689Skan	  || GET_CODE (SET_DEST (elt)) != REG
1011169689Skan	  || GET_MODE (SET_DEST (elt)) != V4SImode)
1012169689Skan	return 0;
1013169689Skan    }
1014169689Skan
1015169689Skan  for (i=1; i <= 18; i++)
1016169689Skan    {
1017169689Skan      elt = XVECEXP (op, 0, index++);
1018169689Skan      if (GET_CODE (elt) != SET
1019169689Skan	  || GET_CODE (SET_SRC (elt)) != MEM
1020169689Skan	  || ! memory_operand (SET_SRC (elt), DFmode)
1021169689Skan	  || GET_CODE (SET_DEST (elt)) != REG
1022169689Skan	  || GET_MODE (SET_DEST (elt)) != DFmode)
1023169689Skan	return 0;
1024169689Skan    }
1025169689Skan
1026169689Skan  if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
1027169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
1028169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
1029169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER
1030169689Skan      || GET_CODE (XVECEXP (op, 0, index++)) != USE)
1031169689Skan    return 0;
1032169689Skan  return 1;
1033169689Skan})
1034169689Skan
1035169689Skan;; Return 1 if OP is valid for a vrsave call, known to be a PARALLEL.
1036169689Skan(define_predicate "vrsave_operation"
1037169689Skan  (match_code "parallel")
1038169689Skan{
1039169689Skan  int count = XVECLEN (op, 0);
1040169689Skan  unsigned int dest_regno, src_regno;
1041169689Skan  int i;
1042169689Skan
1043169689Skan  if (count <= 1
1044169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET
1045169689Skan      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1046169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE
1047169689Skan      || XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPECV_SET_VRSAVE)
1048169689Skan    return 0;
1049169689Skan
1050169689Skan  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1051169689Skan  src_regno  = REGNO (XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 1));
1052169689Skan
1053169689Skan  if (dest_regno != VRSAVE_REGNO || src_regno != VRSAVE_REGNO)
1054169689Skan    return 0;
1055169689Skan
1056169689Skan  for (i = 1; i < count; i++)
1057169689Skan    {
1058169689Skan      rtx elt = XVECEXP (op, 0, i);
1059169689Skan
1060169689Skan      if (GET_CODE (elt) != CLOBBER
1061169689Skan	  && GET_CODE (elt) != SET)
1062169689Skan	return 0;
1063169689Skan    }
1064169689Skan
1065169689Skan  return 1;
1066169689Skan})
1067169689Skan
1068169689Skan;; Return 1 if OP is valid for mfcr insn, known to be a PARALLEL.
1069169689Skan(define_predicate "mfcr_operation"
1070169689Skan  (match_code "parallel")
1071169689Skan{
1072169689Skan  int count = XVECLEN (op, 0);
1073169689Skan  int i;
1074169689Skan
1075169689Skan  /* Perform a quick check so we don't blow up below.  */
1076169689Skan  if (count < 1
1077169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET
1078169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
1079169689Skan      || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
1080169689Skan    return 0;
1081169689Skan
1082169689Skan  for (i = 0; i < count; i++)
1083169689Skan    {
1084169689Skan      rtx exp = XVECEXP (op, 0, i);
1085169689Skan      rtx unspec;
1086169689Skan      int maskval;
1087169689Skan      rtx src_reg;
1088169689Skan
1089169689Skan      src_reg = XVECEXP (SET_SRC (exp), 0, 0);
1090169689Skan
1091169689Skan      if (GET_CODE (src_reg) != REG
1092169689Skan	  || GET_MODE (src_reg) != CCmode
1093169689Skan	  || ! CR_REGNO_P (REGNO (src_reg)))
1094169689Skan	return 0;
1095169689Skan
1096169689Skan      if (GET_CODE (exp) != SET
1097169689Skan	  || GET_CODE (SET_DEST (exp)) != REG
1098169689Skan	  || GET_MODE (SET_DEST (exp)) != SImode
1099169689Skan	  || ! INT_REGNO_P (REGNO (SET_DEST (exp))))
1100169689Skan	return 0;
1101169689Skan      unspec = SET_SRC (exp);
1102169689Skan      maskval = 1 << (MAX_CR_REGNO - REGNO (src_reg));
1103169689Skan
1104169689Skan      if (GET_CODE (unspec) != UNSPEC
1105169689Skan	  || XINT (unspec, 1) != UNSPEC_MOVESI_FROM_CR
1106169689Skan	  || XVECLEN (unspec, 0) != 2
1107169689Skan	  || XVECEXP (unspec, 0, 0) != src_reg
1108169689Skan	  || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
1109169689Skan	  || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
1110169689Skan	return 0;
1111169689Skan    }
1112169689Skan  return 1;
1113169689Skan})
1114169689Skan
1115169689Skan;; Return 1 if OP is valid for mtcrf insn, known to be a PARALLEL.
1116169689Skan(define_predicate "mtcrf_operation"
1117169689Skan  (match_code "parallel")
1118169689Skan{
1119169689Skan  int count = XVECLEN (op, 0);
1120169689Skan  int i;
1121169689Skan  rtx src_reg;
1122169689Skan
1123169689Skan  /* Perform a quick check so we don't blow up below.  */
1124169689Skan  if (count < 1
1125169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET
1126169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
1127169689Skan      || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
1128169689Skan    return 0;
1129169689Skan  src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
1130169689Skan
1131169689Skan  if (GET_CODE (src_reg) != REG
1132169689Skan      || GET_MODE (src_reg) != SImode
1133169689Skan      || ! INT_REGNO_P (REGNO (src_reg)))
1134169689Skan    return 0;
1135169689Skan
1136169689Skan  for (i = 0; i < count; i++)
1137169689Skan    {
1138169689Skan      rtx exp = XVECEXP (op, 0, i);
1139169689Skan      rtx unspec;
1140169689Skan      int maskval;
1141169689Skan
1142169689Skan      if (GET_CODE (exp) != SET
1143169689Skan	  || GET_CODE (SET_DEST (exp)) != REG
1144169689Skan	  || GET_MODE (SET_DEST (exp)) != CCmode
1145169689Skan	  || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
1146169689Skan	return 0;
1147169689Skan      unspec = SET_SRC (exp);
1148169689Skan      maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
1149169689Skan
1150169689Skan      if (GET_CODE (unspec) != UNSPEC
1151169689Skan	  || XINT (unspec, 1) != UNSPEC_MOVESI_TO_CR
1152169689Skan	  || XVECLEN (unspec, 0) != 2
1153169689Skan	  || XVECEXP (unspec, 0, 0) != src_reg
1154169689Skan	  || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
1155169689Skan	  || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
1156169689Skan	return 0;
1157169689Skan    }
1158169689Skan  return 1;
1159169689Skan})
1160169689Skan
1161169689Skan;; Return 1 if OP is valid for lmw insn, known to be a PARALLEL.
1162169689Skan(define_predicate "lmw_operation"
1163169689Skan  (match_code "parallel")
1164169689Skan{
1165169689Skan  int count = XVECLEN (op, 0);
1166169689Skan  unsigned int dest_regno;
1167169689Skan  rtx src_addr;
1168169689Skan  unsigned int base_regno;
1169169689Skan  HOST_WIDE_INT offset;
1170169689Skan  int i;
1171169689Skan
1172169689Skan  /* Perform a quick check so we don't blow up below.  */
1173169689Skan  if (count <= 1
1174169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET
1175169689Skan      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
1176169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
1177169689Skan    return 0;
1178169689Skan
1179169689Skan  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
1180169689Skan  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
1181169689Skan
1182169689Skan  if (dest_regno > 31
1183169689Skan      || count != 32 - (int) dest_regno)
1184169689Skan    return 0;
1185169689Skan
1186169689Skan  if (legitimate_indirect_address_p (src_addr, 0))
1187169689Skan    {
1188169689Skan      offset = 0;
1189169689Skan      base_regno = REGNO (src_addr);
1190169689Skan      if (base_regno == 0)
1191169689Skan	return 0;
1192169689Skan    }
1193169689Skan  else if (rs6000_legitimate_offset_address_p (SImode, src_addr, 0))
1194169689Skan    {
1195169689Skan      offset = INTVAL (XEXP (src_addr, 1));
1196169689Skan      base_regno = REGNO (XEXP (src_addr, 0));
1197169689Skan    }
1198169689Skan  else
1199169689Skan    return 0;
1200169689Skan
1201169689Skan  for (i = 0; i < count; i++)
1202169689Skan    {
1203169689Skan      rtx elt = XVECEXP (op, 0, i);
1204169689Skan      rtx newaddr;
1205169689Skan      rtx addr_reg;
1206169689Skan      HOST_WIDE_INT newoffset;
1207169689Skan
1208169689Skan      if (GET_CODE (elt) != SET
1209169689Skan	  || GET_CODE (SET_DEST (elt)) != REG
1210169689Skan	  || GET_MODE (SET_DEST (elt)) != SImode
1211169689Skan	  || REGNO (SET_DEST (elt)) != dest_regno + i
1212169689Skan	  || GET_CODE (SET_SRC (elt)) != MEM
1213169689Skan	  || GET_MODE (SET_SRC (elt)) != SImode)
1214169689Skan	return 0;
1215169689Skan      newaddr = XEXP (SET_SRC (elt), 0);
1216169689Skan      if (legitimate_indirect_address_p (newaddr, 0))
1217169689Skan	{
1218169689Skan	  newoffset = 0;
1219169689Skan	  addr_reg = newaddr;
1220169689Skan	}
1221169689Skan      else if (rs6000_legitimate_offset_address_p (SImode, newaddr, 0))
1222169689Skan	{
1223169689Skan	  addr_reg = XEXP (newaddr, 0);
1224169689Skan	  newoffset = INTVAL (XEXP (newaddr, 1));
1225169689Skan	}
1226169689Skan      else
1227169689Skan	return 0;
1228169689Skan      if (REGNO (addr_reg) != base_regno
1229169689Skan	  || newoffset != offset + 4 * i)
1230169689Skan	return 0;
1231169689Skan    }
1232169689Skan
1233169689Skan  return 1;
1234169689Skan})
1235169689Skan
1236169689Skan;; Return 1 if OP is valid for stmw insn, known to be a PARALLEL.
1237169689Skan(define_predicate "stmw_operation"
1238169689Skan  (match_code "parallel")
1239169689Skan{
1240169689Skan  int count = XVECLEN (op, 0);
1241169689Skan  unsigned int src_regno;
1242169689Skan  rtx dest_addr;
1243169689Skan  unsigned int base_regno;
1244169689Skan  HOST_WIDE_INT offset;
1245169689Skan  int i;
1246169689Skan
1247169689Skan  /* Perform a quick check so we don't blow up below.  */
1248169689Skan  if (count <= 1
1249169689Skan      || GET_CODE (XVECEXP (op, 0, 0)) != SET
1250169689Skan      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
1251169689Skan      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
1252169689Skan    return 0;
1253169689Skan
1254169689Skan  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
1255169689Skan  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
1256169689Skan
1257169689Skan  if (src_regno > 31
1258169689Skan      || count != 32 - (int) src_regno)
1259169689Skan    return 0;
1260169689Skan
1261169689Skan  if (legitimate_indirect_address_p (dest_addr, 0))
1262169689Skan    {
1263169689Skan      offset = 0;
1264169689Skan      base_regno = REGNO (dest_addr);
1265169689Skan      if (base_regno == 0)
1266169689Skan	return 0;
1267169689Skan    }
1268169689Skan  else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, 0))
1269169689Skan    {
1270169689Skan      offset = INTVAL (XEXP (dest_addr, 1));
1271169689Skan      base_regno = REGNO (XEXP (dest_addr, 0));
1272169689Skan    }
1273169689Skan  else
1274169689Skan    return 0;
1275169689Skan
1276169689Skan  for (i = 0; i < count; i++)
1277169689Skan    {
1278169689Skan      rtx elt = XVECEXP (op, 0, i);
1279169689Skan      rtx newaddr;
1280169689Skan      rtx addr_reg;
1281169689Skan      HOST_WIDE_INT newoffset;
1282169689Skan
1283169689Skan      if (GET_CODE (elt) != SET
1284169689Skan	  || GET_CODE (SET_SRC (elt)) != REG
1285169689Skan	  || GET_MODE (SET_SRC (elt)) != SImode
1286169689Skan	  || REGNO (SET_SRC (elt)) != src_regno + i
1287169689Skan	  || GET_CODE (SET_DEST (elt)) != MEM
1288169689Skan	  || GET_MODE (SET_DEST (elt)) != SImode)
1289169689Skan	return 0;
1290169689Skan      newaddr = XEXP (SET_DEST (elt), 0);
1291169689Skan      if (legitimate_indirect_address_p (newaddr, 0))
1292169689Skan	{
1293169689Skan	  newoffset = 0;
1294169689Skan	  addr_reg = newaddr;
1295169689Skan	}
1296169689Skan      else if (rs6000_legitimate_offset_address_p (SImode, newaddr, 0))
1297169689Skan	{
1298169689Skan	  addr_reg = XEXP (newaddr, 0);
1299169689Skan	  newoffset = INTVAL (XEXP (newaddr, 1));
1300169689Skan	}
1301169689Skan      else
1302169689Skan	return 0;
1303169689Skan      if (REGNO (addr_reg) != base_regno
1304169689Skan	  || newoffset != offset + 4 * i)
1305169689Skan	return 0;
1306169689Skan    }
1307169689Skan
1308169689Skan  return 1;
1309169689Skan})
1310