1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2;; Copyright (C) 1990-2018 Free Software Foundation, Inc.
3;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5;; This file is part of GCC.
6
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23;;
24;; REGNOS
25;;
26
27(define_constants
28  [(FIRST_GPR_REGNO		0)
29   (STACK_POINTER_REGNUM	1)
30   (TOC_REGNUM			2)
31   (STATIC_CHAIN_REGNUM		11)
32   (HARD_FRAME_POINTER_REGNUM	31)
33   (LAST_GPR_REGNO		31)
34   (FIRST_FPR_REGNO		32)
35   (LAST_FPR_REGNO		63)
36   (LR_REGNO			65)
37   (CTR_REGNO			66)
38   (ARG_POINTER_REGNUM		67)
39   (CR0_REGNO			68)
40   (CR1_REGNO			69)
41   (CR2_REGNO			70)
42   (CR3_REGNO			71)
43   (CR4_REGNO			72)
44   (CR5_REGNO			73)
45   (CR6_REGNO			74)
46   (CR7_REGNO			75)
47   (MAX_CR_REGNO		75)
48   (CA_REGNO			76)
49   (FIRST_ALTIVEC_REGNO		77)
50   (LAST_ALTIVEC_REGNO		108)
51   (VRSAVE_REGNO		109)
52   (VSCR_REGNO			110)
53   (SPE_ACC_REGNO		111)
54   (SPEFSCR_REGNO		112)
55   (FRAME_POINTER_REGNUM	113)
56   (TFHAR_REGNO			114)
57   (TFIAR_REGNO			115)
58   (TEXASR_REGNO		116)
59   (FIRST_SPE_HIGH_REGNO	117)
60   (LAST_SPE_HIGH_REGNO		148)
61  ])
62
63;;
64;; UNSPEC usage
65;;
66
67(define_c_enum "unspec"
68  [UNSPEC_FRSP			; frsp for POWER machines
69   UNSPEC_PROBE_STACK		; probe stack memory reference
70   UNSPEC_TOCPTR		; address of a word pointing to the TOC
71   UNSPEC_TOC			; address of the TOC (more-or-less)
72   UNSPEC_TOCSLOT		; offset from r1 of toc pointer save slot
73   UNSPEC_MOVSI_GOT
74   UNSPEC_MV_CR_OV		; move_from_CR_ov_bit
75   UNSPEC_FCTIWZ
76   UNSPEC_FRIM
77   UNSPEC_FRIN
78   UNSPEC_FRIP
79   UNSPEC_FRIZ
80   UNSPEC_XSRDPI
81   UNSPEC_LD_MPIC		; load_macho_picbase
82   UNSPEC_RELD_MPIC		; re-load_macho_picbase
83   UNSPEC_MPIC_CORRECT		; macho_correct_pic
84   UNSPEC_TLSGD
85   UNSPEC_TLSLD
86   UNSPEC_MOVESI_FROM_CR
87   UNSPEC_MOVESI_TO_CR
88   UNSPEC_TLSDTPREL
89   UNSPEC_TLSDTPRELHA
90   UNSPEC_TLSDTPRELLO
91   UNSPEC_TLSGOTDTPREL
92   UNSPEC_TLSTPREL
93   UNSPEC_TLSTPRELHA
94   UNSPEC_TLSTPRELLO
95   UNSPEC_TLSGOTTPREL
96   UNSPEC_TLSTLS
97   UNSPEC_FIX_TRUNC_TF		; fadd, rounding towards zero
98   UNSPEC_MV_CR_GT		; move_from_CR_gt_bit
99   UNSPEC_STFIWX
100   UNSPEC_POPCNTB
101   UNSPEC_FRES
102   UNSPEC_SP_SET
103   UNSPEC_SP_TEST
104   UNSPEC_SYNC
105   UNSPEC_LWSYNC
106   UNSPEC_SYNC_OP
107   UNSPEC_ATOMIC
108   UNSPEC_CMPXCHG
109   UNSPEC_XCHG
110   UNSPEC_AND
111   UNSPEC_DLMZB
112   UNSPEC_DLMZB_CR
113   UNSPEC_DLMZB_STRLEN
114   UNSPEC_RSQRT
115   UNSPEC_TOCREL
116   UNSPEC_MACHOPIC_OFFSET
117   UNSPEC_BPERM
118   UNSPEC_COPYSIGN
119   UNSPEC_PARITY
120   UNSPEC_FCTIW
121   UNSPEC_FCTID
122   UNSPEC_LFIWAX
123   UNSPEC_LFIWZX
124   UNSPEC_FCTIWUZ
125   UNSPEC_NOP
126   UNSPEC_GRP_END_NOP
127   UNSPEC_P8V_FMRGOW
128   UNSPEC_P8V_MTVSRWZ
129   UNSPEC_P8V_RELOAD_FROM_GPR
130   UNSPEC_P8V_MTVSRD
131   UNSPEC_P8V_XXPERMDI
132   UNSPEC_P8V_RELOAD_FROM_VSX
133   UNSPEC_ADDG6S
134   UNSPEC_CDTBCD
135   UNSPEC_CBCDTD
136   UNSPEC_DIVE
137   UNSPEC_DIVEU
138   UNSPEC_UNPACK_128BIT
139   UNSPEC_PACK_128BIT
140   UNSPEC_LSQ
141   UNSPEC_FUSION_GPR
142   UNSPEC_STACK_CHECK
143   UNSPEC_FUSION_P9
144   UNSPEC_FUSION_ADDIS
145   UNSPEC_ROUND_TO_ODD
146   UNSPEC_IEEE128_MOVE
147   UNSPEC_IEEE128_CONVERT
148   UNSPEC_SIGNBIT
149   UNSPEC_DOLOOP
150  ])
151
152;;
153;; UNSPEC_VOLATILE usage
154;;
155
156(define_c_enum "unspecv"
157  [UNSPECV_BLOCK
158   UNSPECV_LL			; load-locked
159   UNSPECV_SC			; store-conditional
160   UNSPECV_PROBE_STACK_RANGE	; probe range of stack addresses
161   UNSPECV_EH_RR		; eh_reg_restore
162   UNSPECV_ISYNC		; isync instruction
163   UNSPECV_MFTB			; move from time base
164   UNSPECV_NLGR			; non-local goto receiver
165   UNSPECV_MFFS			; Move from FPSCR
166   UNSPECV_MTFSF		; Move to FPSCR Fields
167   UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
168  ])
169
170
171;; Define an insn type attribute.  This is used in function unit delay
172;; computations.
173(define_attr "type"
174  "integer,two,three,
175   add,logical,shift,insert,
176   mul,halfmul,div,
177   exts,cntlz,popcnt,isel,
178   load,store,fpload,fpstore,vecload,vecstore,
179   cmp,
180   branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
181   cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
182   fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
183   brinc,
184   vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
185   vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
186   veclogical,veccmpfx,vecexts,vecmove,
187   htm,htmsimple,dfp"
188  (const_string "integer"))
189
190;; What data size does this instruction work on?
191;; This is used for insert, mul and others as necessary.
192(define_attr "size" "8,16,32,64,128" (const_string "32"))
193
194;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
195;; This is used for add, logical, shift, exts, mul.
196(define_attr "dot" "no,yes" (const_string "no"))
197
198;; Does this instruction sign-extend its result?
199;; This is used for load insns.
200(define_attr "sign_extend" "no,yes" (const_string "no"))
201
202;; Does this instruction use indexed (that is, reg+reg) addressing?
203;; This is used for load and store insns.  If operand 0 or 1 is a MEM
204;; it is automatically set based on that.  If a load or store instruction
205;; has fewer than two operands it needs to set this attribute manually
206;; or the compiler will crash.
207(define_attr "indexed" "no,yes"
208  (if_then_else (ior (match_operand 0 "indexed_address_mem")
209		     (match_operand 1 "indexed_address_mem"))
210		(const_string "yes")
211		(const_string "no")))
212
213;; Does this instruction use update addressing?
214;; This is used for load and store insns.  See the comments for "indexed".
215(define_attr "update" "no,yes"
216  (if_then_else (ior (match_operand 0 "update_address_mem")
217		     (match_operand 1 "update_address_mem"))
218		(const_string "yes")
219		(const_string "no")))
220
221;; Is this instruction using operands[2] as shift amount, and can that be a
222;; register?
223;; This is used for shift insns.
224(define_attr "maybe_var_shift" "no,yes" (const_string "no"))
225
226;; Is this instruction using a shift amount from a register?
227;; This is used for shift insns.
228(define_attr "var_shift" "no,yes"
229  (if_then_else (and (eq_attr "type" "shift")
230		     (eq_attr "maybe_var_shift" "yes"))
231		(if_then_else (match_operand 2 "gpc_reg_operand")
232			      (const_string "yes")
233			      (const_string "no"))
234		(const_string "no")))
235
236;; Is copying of this instruction disallowed?
237(define_attr "cannot_copy" "no,yes" (const_string "no"))
238
239;; Define floating point instruction sub-types for use with Xfpu.md
240(define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
241
242;; Length (in bytes).
243; '(pc)' in the following doesn't include the instruction itself; it is
244; calculated as if the instruction had zero size.
245(define_attr "length" ""
246  (if_then_else (eq_attr "type" "branch")
247		(if_then_else (and (ge (minus (match_dup 0) (pc))
248				       (const_int -32768))
249				   (lt (minus (match_dup 0) (pc))
250				       (const_int 32764)))
251			      (const_int 4)
252			      (const_int 8))
253		(const_int 4)))
254
255;; Processor type -- this attribute must exactly match the processor_type
256;; enumeration in rs6000-opts.h.
257(define_attr "cpu"
258  "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
259   ppc750,ppc7400,ppc7450,
260   ppc403,ppc405,ppc440,ppc476,
261   ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
262   power4,power5,power6,power7,power8,power9,
263   rs64a,mpccore,cell,ppca2,titan"
264  (const (symbol_ref "rs6000_cpu_attr")))
265
266
267;; If this instruction is microcoded on the CELL processor
268; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
269(define_attr "cell_micro" "not,conditional,always"
270  (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
271			  (eq_attr "dot" "yes"))
272		     (and (eq_attr "type" "load")
273			  (eq_attr "sign_extend" "yes"))
274		     (and (eq_attr "type" "shift")
275			  (eq_attr "var_shift" "yes")))
276		(const_string "always")
277		(const_string "not")))
278
279(automata_option "ndfa")
280
281(include "rs64.md")
282(include "mpc.md")
283(include "40x.md")
284(include "440.md")
285(include "476.md")
286(include "601.md")
287(include "603.md")
288(include "6xx.md")
289(include "7xx.md")
290(include "7450.md")
291(include "8540.md")
292(include "e300c2c3.md")
293(include "e500mc.md")
294(include "e500mc64.md")
295(include "e5500.md")
296(include "e6500.md")
297(include "power4.md")
298(include "power5.md")
299(include "power6.md")
300(include "power7.md")
301(include "power8.md")
302(include "power9.md")
303(include "cell.md")
304(include "xfpu.md")
305(include "a2.md")
306(include "titan.md")
307
308(include "predicates.md")
309(include "constraints.md")
310
311(include "darwin.md")
312
313
314;; Mode iterators
315
316; This mode iterator allows :GPR to be used to indicate the allowable size
317; of whole values in GPRs.
318(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
319
320; Any supported integer mode.
321(define_mode_iterator INT [QI HI SI DI TI PTI])
322
323; Any supported integer mode that fits in one register.
324(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
325
326; Everything we can extend QImode to.
327(define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
328
329; Everything we can extend HImode to.
330(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
331
332; Everything we can extend SImode to.
333(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
334
335; QImode or HImode for small atomic ops
336(define_mode_iterator QHI [QI HI])
337
338; QImode, HImode, SImode for fused ops only for GPR loads
339(define_mode_iterator QHSI [QI HI SI])
340
341; HImode or SImode for sign extended fusion ops
342(define_mode_iterator HSI [HI SI])
343
344; SImode or DImode, even if DImode doesn't fit in GPRs.
345(define_mode_iterator SDI [SI DI])
346
347; Types that can be fused with an ADDIS instruction to load or store a GPR
348; register that has reg+offset addressing.
349(define_mode_iterator GPR_FUSION [QI
350				  HI
351				  SI
352				  (DI	"TARGET_POWERPC64")
353				  SF
354				  (DF	"TARGET_POWERPC64")])
355
356; Types that can be fused with an ADDIS instruction to load or store a FPR
357; register that has reg+offset addressing.
358(define_mode_iterator FPR_FUSION [DI SF DF])
359
360; The size of a pointer.  Also, the size of the value that a record-condition
361; (one with a '.') will compare; and the size used for arithmetic carries.
362(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
363
364; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
365; PTImode is GPR only)
366(define_mode_iterator TI2 [TI PTI])
367
368; Any hardware-supported floating-point mode
369(define_mode_iterator FP [
370  (SF "TARGET_HARD_FLOAT
371   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
372  (DF "TARGET_HARD_FLOAT
373   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
374  (TF "TARGET_HARD_FLOAT
375   && (TARGET_FPRS || TARGET_E500_DOUBLE)
376   && TARGET_LONG_DOUBLE_128")
377  (IF "TARGET_FLOAT128")
378  (KF "TARGET_FLOAT128")
379  (DD "TARGET_DFP")
380  (TD "TARGET_DFP")])
381
382; Any fma capable floating-point mode.
383(define_mode_iterator FMA_F [
384  (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
385  (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
386       || VECTOR_UNIT_VSX_P (DFmode)")
387  (V2SF "TARGET_PAIRED_FLOAT")
388  (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
389  (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
390  (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
391  (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
392  ])
393
394; Floating point move iterators to combine binary and decimal moves
395(define_mode_iterator FMOVE32 [SF SD])
396(define_mode_iterator FMOVE64 [DF DD])
397(define_mode_iterator FMOVE64X [DI DF DD])
398(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
399				(IF "TARGET_LONG_DOUBLE_128")
400				(TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
401
402(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
403				    (IF "FLOAT128_2REG_P (IFmode)")
404				    (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
405
406; Iterators for 128 bit types for direct move
407(define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
408				    (V16QI "")
409				    (V8HI  "")
410				    (V4SI  "")
411				    (V4SF  "")
412				    (V2DI  "")
413				    (V2DF  "")
414				    (V1TI  "")
415				    (KF    "FLOAT128_VECTOR_P (KFmode)")
416				    (TF    "FLOAT128_VECTOR_P (TFmode)")])
417
418; Iterator for 128-bit VSX types for pack/unpack
419(define_mode_iterator FMOVE128_VSX [V1TI KF])
420
421; Whether a floating point move is ok, don't allow SD without hardware FP
422(define_mode_attr fmove_ok [(SF "")
423			    (DF "")
424			    (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
425			    (DD "")])
426
427; Convert REAL_VALUE to the appropriate bits
428(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
429					(DF "REAL_VALUE_TO_TARGET_DOUBLE")
430					(SD "REAL_VALUE_TO_TARGET_DECIMAL32")
431					(DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
432
433; Whether 0.0 has an all-zero bit pattern
434(define_mode_attr zero_fp [(SF "j")
435			   (DF "j")
436			   (TF "j")
437			   (IF "j")
438			   (KF "j")
439			   (SD "wn")
440			   (DD "wn")
441			   (TD "wn")])
442
443; Definitions for 64-bit VSX
444(define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
445
446; Definitions for 64-bit direct move
447(define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
448
449; Definitions for 64-bit use of altivec registers
450(define_mode_attr f64_av  [(DF "wv") (DD "wn")])
451
452; Definitions for 64-bit access to ISA 3.0 (power9) vector
453(define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
454
455; These modes do not fit in integer registers in 32-bit mode.
456; but on e500v2, the gpr are 64 bit registers
457(define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
458
459; Iterator for reciprocal estimate instructions
460(define_mode_iterator RECIPF [SF DF V4SF V2DF])
461
462; Iterator for just SF/DF
463(define_mode_iterator SFDF [SF DF])
464
465; Like SFDF, but a different name to match conditional move where the
466; comparison operands may be a different mode than the input operands.
467(define_mode_iterator SFDF2 [SF DF])
468
469; Iterator for 128-bit floating point that uses the IBM double-double format
470(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
471			      (TF "FLOAT128_IBM_P (TFmode)")])
472
473; Iterator for 128-bit floating point that uses IEEE 128-bit float
474(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
475			       (TF "FLOAT128_IEEE_P (TFmode)")])
476
477; Iterator for 128-bit floating point
478(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
479				(IF "TARGET_FLOAT128")
480				(TF "TARGET_LONG_DOUBLE_128")])
481
482; Iterator for signbit on 64-bit machines with direct move
483(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
484			       (TF "FLOAT128_VECTOR_P (TFmode)")])
485
486; SF/DF suffix for traditional floating instructions
487(define_mode_attr Ftrad		[(SF "s") (DF "")])
488
489; SF/DF suffix for VSX instructions
490(define_mode_attr Fvsx		[(SF "sp") (DF	"dp")])
491
492; SF/DF constraint for arithmetic on traditional floating point registers
493(define_mode_attr Ff		[(SF "f") (DF "d") (DI "d")])
494
495; SF/DF constraint for arithmetic on VSX registers using instructions added in
496; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
497; but are used on SFmode, since internally SFmode values are kept in the DFmode
498; format.
499(define_mode_attr Fv		[(SF "ww") (DF "ws") (DI "wi")])
500
501; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
502; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
503; instructions added in ISA 2.07 (power8)
504(define_mode_attr Fv2		[(SF "wy") (DF "ws") (DI "wi")])
505
506; SF/DF constraint for arithmetic on altivec registers
507(define_mode_attr Fa		[(SF "wu") (DF "wv")])
508
509; s/d suffix for things like fp_addsub_s/fp_addsub_d
510(define_mode_attr Fs		[(SF "s")  (DF "d")])
511
512; FRE/FRES support
513(define_mode_attr Ffre		[(SF "fres") (DF "fre")])
514(define_mode_attr FFRE		[(SF "FRES") (DF "FRE")])
515
516; Conditional returns.
517(define_code_iterator any_return [return simple_return])
518(define_code_attr return_pred [(return "direct_return ()")
519			       (simple_return "1")])
520(define_code_attr return_str [(return "") (simple_return "simple_")])
521
522; Logical operators.
523(define_code_iterator iorxor [ior xor])
524
525; Signed/unsigned variants of ops.
526(define_code_iterator any_extend	[sign_extend zero_extend])
527(define_code_iterator any_fix		[fix unsigned_fix])
528(define_code_iterator any_float		[float unsigned_float])
529
530(define_code_attr u  [(sign_extend	"")
531		      (zero_extend	"u")])
532
533(define_code_attr su [(sign_extend	"s")
534		      (zero_extend	"u")
535		      (fix		"s")
536		      (unsigned_fix	"u")
537		      (float		"s")
538		      (unsigned_float	"u")])
539
540(define_code_attr az [(sign_extend	"a")
541		      (zero_extend	"z")
542		      (fix		"a")
543		      (unsigned_fix	"z")
544		      (float		"a")
545		      (unsigned_float	"z")])
546
547(define_code_attr uns [(fix		"")
548		       (unsigned_fix	"uns")
549		       (float		"")
550		       (unsigned_float	"uns")])
551
552; Various instructions that come in SI and DI forms.
553; A generic w/d attribute, for things like cmpw/cmpd.
554(define_mode_attr wd [(QI    "b")
555		      (HI    "h")
556		      (SI    "w")
557		      (DI    "d")
558		      (V16QI "b")
559		      (V8HI  "h")
560		      (V4SI  "w")
561		      (V2DI  "d")
562		      (V1TI  "q")
563		      (TI    "q")])
564
565;; How many bits in this mode?
566(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
567
568; DImode bits
569(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
570
571;; ISEL/ISEL64 target selection
572(define_mode_attr sel [(SI "") (DI "64")])
573
574;; Bitmask for shift instructions
575(define_mode_attr hH [(SI "h") (DI "H")])
576
577;; A mode twice the size of the given mode
578(define_mode_attr dmode [(SI "di") (DI "ti")])
579(define_mode_attr DMODE [(SI "DI") (DI "TI")])
580
581;; Suffix for reload patterns
582(define_mode_attr ptrsize [(SI "32bit")
583			   (DI "64bit")])
584
585(define_mode_attr tptrsize [(SI "TARGET_32BIT")
586			    (DI "TARGET_64BIT")])
587
588(define_mode_attr mptrsize [(SI "si")
589			    (DI "di")])
590
591(define_mode_attr ptrload [(SI "lwz")
592			   (DI "ld")])
593
594(define_mode_attr ptrm [(SI "m")
595			(DI "Y")])
596
597(define_mode_attr rreg [(SF   "f")
598			(DF   "ws")
599			(TF   "f")
600			(TD   "f")
601			(V4SF "wf")
602			(V2DF "wd")])
603
604(define_mode_attr rreg2 [(SF   "f")
605			 (DF   "d")])
606
607(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
608				 (DF "TARGET_FCFID")])
609
610(define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
611				(DF "TARGET_E500_DOUBLE")])
612
613(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
614				(DF "TARGET_DOUBLE_FLOAT")])
615
616;; Mode iterator for logical operations on 128-bit types
617(define_mode_iterator BOOL_128		[TI
618					 PTI
619					 (V16QI	"TARGET_ALTIVEC")
620					 (V8HI	"TARGET_ALTIVEC")
621					 (V4SI	"TARGET_ALTIVEC")
622					 (V4SF	"TARGET_ALTIVEC")
623					 (V2DI	"TARGET_ALTIVEC")
624					 (V2DF	"TARGET_ALTIVEC")
625					 (V1TI  "TARGET_ALTIVEC")])
626
627;; For the GPRs we use 3 constraints for register outputs, two that are the
628;; same as the output register, and a third where the output register is an
629;; early clobber, so we don't have to deal with register overlaps.  For the
630;; vector types, we prefer to use the vector registers.  For TI mode, allow
631;; either.
632
633;; Mode attribute for boolean operation register constraints for output
634(define_mode_attr BOOL_REGS_OUTPUT	[(TI	"&r,r,r,wt,v")
635					 (PTI	"&r,r,r")
636					 (V16QI	"wa,v,&?r,?r,?r")
637					 (V8HI	"wa,v,&?r,?r,?r")
638					 (V4SI	"wa,v,&?r,?r,?r")
639					 (V4SF	"wa,v,&?r,?r,?r")
640					 (V2DI	"wa,v,&?r,?r,?r")
641					 (V2DF	"wa,v,&?r,?r,?r")
642					 (V1TI	"wa,v,&?r,?r,?r")])
643
644;; Mode attribute for boolean operation register constraints for operand1
645(define_mode_attr BOOL_REGS_OP1		[(TI	"r,0,r,wt,v")
646					 (PTI	"r,0,r")
647					 (V16QI	"wa,v,r,0,r")
648					 (V8HI	"wa,v,r,0,r")
649					 (V4SI	"wa,v,r,0,r")
650					 (V4SF	"wa,v,r,0,r")
651					 (V2DI	"wa,v,r,0,r")
652					 (V2DF	"wa,v,r,0,r")
653					 (V1TI	"wa,v,r,0,r")])
654
655;; Mode attribute for boolean operation register constraints for operand2
656(define_mode_attr BOOL_REGS_OP2		[(TI	"r,r,0,wt,v")
657					 (PTI	"r,r,0")
658					 (V16QI	"wa,v,r,r,0")
659					 (V8HI	"wa,v,r,r,0")
660					 (V4SI	"wa,v,r,r,0")
661					 (V4SF	"wa,v,r,r,0")
662					 (V2DI	"wa,v,r,r,0")
663					 (V2DF	"wa,v,r,r,0")
664					 (V1TI	"wa,v,r,r,0")])
665
666;; Mode attribute for boolean operation register constraints for operand1
667;; for one_cmpl.  To simplify things, we repeat the constraint where 0
668;; is used for operand1 or operand2
669(define_mode_attr BOOL_REGS_UNARY	[(TI	"r,0,0,wt,v")
670					 (PTI	"r,0,0")
671					 (V16QI	"wa,v,r,0,0")
672					 (V8HI	"wa,v,r,0,0")
673					 (V4SI	"wa,v,r,0,0")
674					 (V4SF	"wa,v,r,0,0")
675					 (V2DI	"wa,v,r,0,0")
676					 (V2DF	"wa,v,r,0,0")
677					 (V1TI	"wa,v,r,0,0")])
678
679;; Reload iterator for creating the function to allocate a base register to
680;; supplement addressing modes.
681(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
682			      SF SD SI DF DD DI TI PTI KF IF TF])
683
684;; Iterate over smin, smax
685(define_code_iterator fp_minmax	[smin smax])
686
687(define_code_attr     minmax	[(smin "min")
688				 (smax "max")])
689
690(define_code_attr     SMINMAX	[(smin "SMIN")
691				 (smax "SMAX")])
692
693;; Iterator to optimize the following cases:
694;;	D-form load to FPR register & move to Altivec register
695;;	Move Altivec register to FPR register and store
696(define_mode_iterator ALTIVEC_DFORM [DF SF])
697
698
699;; Start with fixed-point load and store insns.  Here we put only the more
700;; complex forms.  Basic data transfer is done later.
701
702(define_insn "zero_extendqi<mode>2"
703  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
704	(zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
705  ""
706  "@
707   lbz%U1%X1 %0,%1
708   rlwinm %0,%1,0,0xff"
709  [(set_attr "type" "load,shift")])
710
711(define_insn "*zero_extendqi<mode>2_dot"
712  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
713	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
714		    (const_int 0)))
715   (clobber (match_scratch:EXTQI 0 "=r,r"))]
716  "rs6000_gen_cell_microcode"
717  "@
718   andi. %0,%1,0xff
719   rlwinm %0,%1,0,0xff\;cmpwi %2,%0,0"
720  [(set_attr "type" "logical")
721   (set_attr "dot" "yes")
722   (set_attr "length" "4,8")])
723
724(define_insn "*zero_extendqi<mode>2_dot2"
725  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
727		    (const_int 0)))
728   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
729	(zero_extend:EXTQI (match_dup 1)))]
730  "rs6000_gen_cell_microcode"
731  "@
732   andi. %0,%1,0xff
733   rlwinm %0,%1,0,0xff\;cmpwi %2,%0,0"
734  [(set_attr "type" "logical")
735   (set_attr "dot" "yes")
736   (set_attr "length" "4,8")])
737
738
739(define_insn "zero_extendhi<mode>2"
740  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
741	(zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
742  ""
743  "@
744   lhz%U1%X1 %0,%1
745   rlwinm %0,%1,0,0xffff"
746  [(set_attr "type" "load,shift")])
747
748(define_insn_and_split "*zero_extendhi<mode>2_dot"
749  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
750	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
751		    (const_int 0)))
752   (clobber (match_scratch:EXTHI 0 "=r,r"))]
753  "rs6000_gen_cell_microcode"
754  "@
755   andi. %0,%1,0xffff
756   #"
757  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
758  [(set (match_dup 0)
759	(zero_extend:EXTHI (match_dup 1)))
760   (set (match_dup 2)
761	(compare:CC (match_dup 0)
762		    (const_int 0)))]
763  ""
764  [(set_attr "type" "logical")
765   (set_attr "dot" "yes")
766   (set_attr "length" "4,8")])
767
768(define_insn_and_split "*zero_extendhi<mode>2_dot2"
769  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
770	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
771		    (const_int 0)))
772   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
773	(zero_extend:EXTHI (match_dup 1)))]
774  "rs6000_gen_cell_microcode"
775  "@
776   andi. %0,%1,0xffff
777   #"
778  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
779  [(set (match_dup 0)
780	(zero_extend:EXTHI (match_dup 1)))
781   (set (match_dup 2)
782	(compare:CC (match_dup 0)
783		    (const_int 0)))]
784  ""
785  [(set_attr "type" "logical")
786   (set_attr "dot" "yes")
787   (set_attr "length" "4,8")])
788
789
790(define_insn "zero_extendsi<mode>2"
791  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
792	(zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
793  ""
794  "@
795   lwz%U1%X1 %0,%1
796   rldicl %0,%1,0,32
797   mtvsrwz %x0,%1
798   lfiwzx %0,%y1
799   lxsiwzx %x0,%y1"
800  [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
801
802(define_insn_and_split "*zero_extendsi<mode>2_dot"
803  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
804	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
805		    (const_int 0)))
806   (clobber (match_scratch:EXTSI 0 "=r,r"))]
807  "rs6000_gen_cell_microcode"
808  "@
809   rldicl. %0,%1,0,32
810   #"
811  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
812  [(set (match_dup 0)
813	(zero_extend:DI (match_dup 1)))
814   (set (match_dup 2)
815	(compare:CC (match_dup 0)
816		    (const_int 0)))]
817  ""
818  [(set_attr "type" "shift")
819   (set_attr "dot" "yes")
820   (set_attr "length" "4,8")])
821
822(define_insn_and_split "*zero_extendsi<mode>2_dot2"
823  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
824	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
825		    (const_int 0)))
826   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
827	(zero_extend:EXTSI (match_dup 1)))]
828  "rs6000_gen_cell_microcode"
829  "@
830   rldicl. %0,%1,0,32
831   #"
832  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
833  [(set (match_dup 0)
834	(zero_extend:EXTSI (match_dup 1)))
835   (set (match_dup 2)
836	(compare:CC (match_dup 0)
837		    (const_int 0)))]
838  ""
839  [(set_attr "type" "shift")
840   (set_attr "dot" "yes")
841   (set_attr "length" "4,8")])
842
843
844(define_insn "extendqi<mode>2"
845  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
846	(sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
847  ""
848  "extsb %0,%1"
849  [(set_attr "type" "exts")])
850
851(define_insn "*extendqi<mode>2_dot"
852  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
853	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
854		    (const_int 0)))
855   (clobber (match_scratch:EXTQI 0 "=r,r"))]
856  "rs6000_gen_cell_microcode"
857  "@
858   extsb. %0,%1
859   extsb %0,%1\;cmpwi %2,%0,0"
860  [(set_attr "type" "exts")
861   (set_attr "dot" "yes")
862   (set_attr "length" "4,8")])
863
864(define_insn "*extendqi<mode>2_dot2"
865  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
866	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
867		    (const_int 0)))
868   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
869	(sign_extend:EXTQI (match_dup 1)))]
870  "rs6000_gen_cell_microcode"
871  "@
872   extsb. %0,%1
873   extsb %0,%1\;cmpwi %2,%0,0"
874  [(set_attr "type" "exts")
875   (set_attr "dot" "yes")
876   (set_attr "length" "4,8")])
877
878
879(define_expand "extendhi<mode>2"
880  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
881	(sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
882  ""
883  "")
884
885(define_insn "*extendhi<mode>2"
886  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
887	(sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
888  "rs6000_gen_cell_microcode"
889  "@
890   lha%U1%X1 %0,%1
891   extsh %0,%1"
892  [(set_attr "type" "load,exts")
893   (set_attr "sign_extend" "yes")])
894
895(define_insn "*extendhi<mode>2_noload"
896  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
897        (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
898  "!rs6000_gen_cell_microcode"
899  "extsh %0,%1"
900  [(set_attr "type" "exts")])
901
902(define_insn_and_split "*extendhi<mode>2_dot"
903  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
904	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
905		    (const_int 0)))
906   (clobber (match_scratch:EXTHI 0 "=r,r"))]
907  "rs6000_gen_cell_microcode"
908  "@
909   extsh. %0,%1
910   #"
911  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
912  [(set (match_dup 0)
913	(sign_extend:EXTHI (match_dup 1)))
914   (set (match_dup 2)
915	(compare:CC (match_dup 0)
916		    (const_int 0)))]
917  ""
918  [(set_attr "type" "exts")
919   (set_attr "dot" "yes")
920   (set_attr "length" "4,8")])
921
922(define_insn_and_split "*extendhi<mode>2_dot2"
923  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
924	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
925		    (const_int 0)))
926   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
927	(sign_extend:EXTHI (match_dup 1)))]
928  "rs6000_gen_cell_microcode"
929  "@
930   extsh. %0,%1
931   #"
932  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
933  [(set (match_dup 0)
934	(sign_extend:EXTHI (match_dup 1)))
935   (set (match_dup 2)
936	(compare:CC (match_dup 0)
937		    (const_int 0)))]
938  ""
939  [(set_attr "type" "exts")
940   (set_attr "dot" "yes")
941   (set_attr "length" "4,8")])
942
943
944(define_insn "extendsi<mode>2"
945  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
946	(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
947  ""
948  "@
949   lwa%U1%X1 %0,%1
950   extsw %0,%1
951   mtvsrwa %x0,%1
952   lfiwax %0,%y1
953   lxsiwax %x0,%y1"
954  [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
955   (set_attr "sign_extend" "yes")])
956
957(define_insn_and_split "*extendsi<mode>2_dot"
958  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
959	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
960		    (const_int 0)))
961   (clobber (match_scratch:EXTSI 0 "=r,r"))]
962  "rs6000_gen_cell_microcode"
963  "@
964   extsw. %0,%1
965   #"
966  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
967  [(set (match_dup 0)
968	(sign_extend:EXTSI (match_dup 1)))
969   (set (match_dup 2)
970	(compare:CC (match_dup 0)
971		    (const_int 0)))]
972  ""
973  [(set_attr "type" "exts")
974   (set_attr "dot" "yes")
975   (set_attr "length" "4,8")])
976
977(define_insn_and_split "*extendsi<mode>2_dot2"
978  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
979	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
980		    (const_int 0)))
981   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
982	(sign_extend:EXTSI (match_dup 1)))]
983  "rs6000_gen_cell_microcode"
984  "@
985   extsw. %0,%1
986   #"
987  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
988  [(set (match_dup 0)
989	(sign_extend:EXTSI (match_dup 1)))
990   (set (match_dup 2)
991	(compare:CC (match_dup 0)
992		    (const_int 0)))]
993  ""
994  [(set_attr "type" "exts")
995   (set_attr "dot" "yes")
996   (set_attr "length" "4,8")])
997
998;; IBM 405, 440, 464 and 476 half-word multiplication operations.
999
1000(define_insn "*macchwc"
1001  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1002        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1003                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1004                                       (const_int 16))
1005                                      (sign_extend:SI
1006                                       (match_operand:HI 1 "gpc_reg_operand" "r")))
1007                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1008                    (const_int 0)))
1009   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1010        (plus:SI (mult:SI (ashiftrt:SI
1011                           (match_dup 2)
1012                           (const_int 16))
1013                          (sign_extend:SI
1014                           (match_dup 1)))
1015                 (match_dup 4)))]
1016  "TARGET_MULHW"
1017  "macchw. %0,%1,%2"
1018  [(set_attr "type" "halfmul")])
1019
1020(define_insn "*macchw"
1021  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1022        (plus:SI (mult:SI (ashiftrt:SI
1023                           (match_operand:SI 2 "gpc_reg_operand" "r")
1024                           (const_int 16))
1025                          (sign_extend:SI
1026                           (match_operand:HI 1 "gpc_reg_operand" "r")))
1027                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1028  "TARGET_MULHW"
1029  "macchw %0,%1,%2"
1030  [(set_attr "type" "halfmul")])
1031
1032(define_insn "*macchwuc"
1033  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1034        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1035                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1036                                       (const_int 16))
1037                                      (zero_extend:SI
1038                                       (match_operand:HI 1 "gpc_reg_operand" "r")))
1039                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1040                    (const_int 0)))
1041   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1042        (plus:SI (mult:SI (lshiftrt:SI
1043                           (match_dup 2)
1044                           (const_int 16))
1045                          (zero_extend:SI
1046                           (match_dup 1)))
1047                 (match_dup 4)))]
1048  "TARGET_MULHW"
1049  "macchwu. %0,%1,%2"
1050  [(set_attr "type" "halfmul")])
1051
1052(define_insn "*macchwu"
1053  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1054        (plus:SI (mult:SI (lshiftrt:SI
1055                           (match_operand:SI 2 "gpc_reg_operand" "r")
1056                           (const_int 16))
1057                          (zero_extend:SI
1058                           (match_operand:HI 1 "gpc_reg_operand" "r")))
1059                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1060  "TARGET_MULHW"
1061  "macchwu %0,%1,%2"
1062  [(set_attr "type" "halfmul")])
1063
1064(define_insn "*machhwc"
1065  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1066        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1067                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
1068                                       (const_int 16))
1069                                      (ashiftrt:SI
1070                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1071                                       (const_int 16)))
1072                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1073                    (const_int 0)))
1074   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1075        (plus:SI (mult:SI (ashiftrt:SI
1076                           (match_dup 1)
1077                           (const_int 16))
1078                          (ashiftrt:SI
1079                           (match_dup 2)
1080                           (const_int 16)))
1081                 (match_dup 4)))]
1082  "TARGET_MULHW"
1083  "machhw. %0,%1,%2"
1084  [(set_attr "type" "halfmul")])
1085
1086(define_insn "*machhw"
1087  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1088        (plus:SI (mult:SI (ashiftrt:SI
1089                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1090                           (const_int 16))
1091                          (ashiftrt:SI
1092                           (match_operand:SI 2 "gpc_reg_operand" "r")
1093                           (const_int 16)))
1094                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1095  "TARGET_MULHW"
1096  "machhw %0,%1,%2"
1097  [(set_attr "type" "halfmul")])
1098
1099(define_insn "*machhwuc"
1100  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1101        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1102                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
1103                                       (const_int 16))
1104                                      (lshiftrt:SI
1105                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1106                                       (const_int 16)))
1107                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1108                    (const_int 0)))
1109   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1110        (plus:SI (mult:SI (lshiftrt:SI
1111                           (match_dup 1)
1112                           (const_int 16))
1113                          (lshiftrt:SI
1114                           (match_dup 2)
1115                           (const_int 16)))
1116                 (match_dup 4)))]
1117  "TARGET_MULHW"
1118  "machhwu. %0,%1,%2"
1119  [(set_attr "type" "halfmul")])
1120
1121(define_insn "*machhwu"
1122  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1123        (plus:SI (mult:SI (lshiftrt:SI
1124                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1125                           (const_int 16))
1126                          (lshiftrt:SI
1127                           (match_operand:SI 2 "gpc_reg_operand" "r")
1128                           (const_int 16)))
1129                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1130  "TARGET_MULHW"
1131  "machhwu %0,%1,%2"
1132  [(set_attr "type" "halfmul")])
1133
1134(define_insn "*maclhwc"
1135  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1136        (compare:CC (plus:SI (mult:SI (sign_extend:SI
1137                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1138                                      (sign_extend:SI
1139                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1140                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1141                    (const_int 0)))
1142   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1143        (plus:SI (mult:SI (sign_extend:SI
1144                           (match_dup 1))
1145                          (sign_extend:SI
1146                           (match_dup 2)))
1147                 (match_dup 4)))]
1148  "TARGET_MULHW"
1149  "maclhw. %0,%1,%2"
1150  [(set_attr "type" "halfmul")])
1151
1152(define_insn "*maclhw"
1153  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1154        (plus:SI (mult:SI (sign_extend:SI
1155                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1156                          (sign_extend:SI
1157                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1158                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1159  "TARGET_MULHW"
1160  "maclhw %0,%1,%2"
1161  [(set_attr "type" "halfmul")])
1162
1163(define_insn "*maclhwuc"
1164  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1165        (compare:CC (plus:SI (mult:SI (zero_extend:SI
1166                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1167                                      (zero_extend:SI
1168                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1169                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1170                    (const_int 0)))
1171   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1172        (plus:SI (mult:SI (zero_extend:SI
1173                           (match_dup 1))
1174                          (zero_extend:SI
1175                           (match_dup 2)))
1176                 (match_dup 4)))]
1177  "TARGET_MULHW"
1178  "maclhwu. %0,%1,%2"
1179  [(set_attr "type" "halfmul")])
1180
1181(define_insn "*maclhwu"
1182  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1183        (plus:SI (mult:SI (zero_extend:SI
1184                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1185                          (zero_extend:SI
1186                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1187                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1188  "TARGET_MULHW"
1189  "maclhwu %0,%1,%2"
1190  [(set_attr "type" "halfmul")])
1191
1192(define_insn "*nmacchwc"
1193  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1194        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1195                              (mult:SI (ashiftrt:SI
1196                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1197                                        (const_int 16))
1198                                       (sign_extend:SI
1199                                        (match_operand:HI 1 "gpc_reg_operand" "r"))))
1200                    (const_int 0)))
1201   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202        (minus:SI (match_dup 4)
1203                  (mult:SI (ashiftrt:SI
1204                            (match_dup 2)
1205                            (const_int 16))
1206                           (sign_extend:SI
1207                            (match_dup 1)))))]
1208  "TARGET_MULHW"
1209  "nmacchw. %0,%1,%2"
1210  [(set_attr "type" "halfmul")])
1211
1212(define_insn "*nmacchw"
1213  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1215                  (mult:SI (ashiftrt:SI
1216                            (match_operand:SI 2 "gpc_reg_operand" "r")
1217                            (const_int 16))
1218                           (sign_extend:SI
1219                            (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1220  "TARGET_MULHW"
1221  "nmacchw %0,%1,%2"
1222  [(set_attr "type" "halfmul")])
1223
1224(define_insn "*nmachhwc"
1225  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1226        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1227                              (mult:SI (ashiftrt:SI
1228                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1229                                        (const_int 16))
1230                                       (ashiftrt:SI
1231                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1232                                        (const_int 16))))
1233                    (const_int 0)))
1234   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235        (minus:SI (match_dup 4)
1236                  (mult:SI (ashiftrt:SI
1237                            (match_dup 1)
1238                            (const_int 16))
1239                           (ashiftrt:SI
1240                            (match_dup 2)
1241                            (const_int 16)))))]
1242  "TARGET_MULHW"
1243  "nmachhw. %0,%1,%2"
1244  [(set_attr "type" "halfmul")])
1245
1246(define_insn "*nmachhw"
1247  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1248        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1249                  (mult:SI (ashiftrt:SI
1250                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1251                            (const_int 16))
1252                           (ashiftrt:SI
1253                            (match_operand:SI 2 "gpc_reg_operand" "r")
1254                            (const_int 16)))))]
1255  "TARGET_MULHW"
1256  "nmachhw %0,%1,%2"
1257  [(set_attr "type" "halfmul")])
1258
1259(define_insn "*nmaclhwc"
1260  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1261        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1262                              (mult:SI (sign_extend:SI
1263                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1264                                       (sign_extend:SI
1265                                        (match_operand:HI 2 "gpc_reg_operand" "r"))))
1266                    (const_int 0)))
1267   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1268        (minus:SI (match_dup 4)
1269                  (mult:SI (sign_extend:SI
1270                            (match_dup 1))
1271                           (sign_extend:SI
1272                            (match_dup 2)))))]
1273  "TARGET_MULHW"
1274  "nmaclhw. %0,%1,%2"
1275  [(set_attr "type" "halfmul")])
1276
1277(define_insn "*nmaclhw"
1278  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1279        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1280                  (mult:SI (sign_extend:SI
1281                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1282                           (sign_extend:SI
1283                            (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1284  "TARGET_MULHW"
1285  "nmaclhw %0,%1,%2"
1286  [(set_attr "type" "halfmul")])
1287
1288(define_insn "*mulchwc"
1289  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1290        (compare:CC (mult:SI (ashiftrt:SI
1291                              (match_operand:SI 2 "gpc_reg_operand" "r")
1292                              (const_int 16))
1293                             (sign_extend:SI
1294                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1295                    (const_int 0)))
1296   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1297        (mult:SI (ashiftrt:SI
1298                  (match_dup 2)
1299                  (const_int 16))
1300                 (sign_extend:SI
1301                  (match_dup 1))))]
1302  "TARGET_MULHW"
1303  "mulchw. %0,%1,%2"
1304  [(set_attr "type" "halfmul")])
1305
1306(define_insn "*mulchw"
1307  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1308        (mult:SI (ashiftrt:SI
1309                  (match_operand:SI 2 "gpc_reg_operand" "r")
1310                  (const_int 16))
1311                 (sign_extend:SI
1312                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1313  "TARGET_MULHW"
1314  "mulchw %0,%1,%2"
1315  [(set_attr "type" "halfmul")])
1316
1317(define_insn "*mulchwuc"
1318  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1319        (compare:CC (mult:SI (lshiftrt:SI
1320                              (match_operand:SI 2 "gpc_reg_operand" "r")
1321                              (const_int 16))
1322                             (zero_extend:SI
1323                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1324                    (const_int 0)))
1325   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1326        (mult:SI (lshiftrt:SI
1327                  (match_dup 2)
1328                  (const_int 16))
1329                 (zero_extend:SI
1330                  (match_dup 1))))]
1331  "TARGET_MULHW"
1332  "mulchwu. %0,%1,%2"
1333  [(set_attr "type" "halfmul")])
1334
1335(define_insn "*mulchwu"
1336  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1337        (mult:SI (lshiftrt:SI
1338                  (match_operand:SI 2 "gpc_reg_operand" "r")
1339                  (const_int 16))
1340                 (zero_extend:SI
1341                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1342  "TARGET_MULHW"
1343  "mulchwu %0,%1,%2"
1344  [(set_attr "type" "halfmul")])
1345
1346(define_insn "*mulhhwc"
1347  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1348        (compare:CC (mult:SI (ashiftrt:SI
1349                              (match_operand:SI 1 "gpc_reg_operand" "%r")
1350                              (const_int 16))
1351                             (ashiftrt:SI
1352                              (match_operand:SI 2 "gpc_reg_operand" "r")
1353                              (const_int 16)))
1354                    (const_int 0)))
1355   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1356        (mult:SI (ashiftrt:SI
1357                  (match_dup 1)
1358                  (const_int 16))
1359                 (ashiftrt:SI
1360                  (match_dup 2)
1361                  (const_int 16))))]
1362  "TARGET_MULHW"
1363  "mulhhw. %0,%1,%2"
1364  [(set_attr "type" "halfmul")])
1365
1366(define_insn "*mulhhw"
1367  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1368        (mult:SI (ashiftrt:SI
1369                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1370                  (const_int 16))
1371                 (ashiftrt:SI
1372                  (match_operand:SI 2 "gpc_reg_operand" "r")
1373                  (const_int 16))))]
1374  "TARGET_MULHW"
1375  "mulhhw %0,%1,%2"
1376  [(set_attr "type" "halfmul")])
1377
1378(define_insn "*mulhhwuc"
1379  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1380        (compare:CC (mult:SI (lshiftrt:SI
1381                              (match_operand:SI 1 "gpc_reg_operand" "%r")
1382                              (const_int 16))
1383                             (lshiftrt:SI
1384                              (match_operand:SI 2 "gpc_reg_operand" "r")
1385                              (const_int 16)))
1386                    (const_int 0)))
1387   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1388        (mult:SI (lshiftrt:SI
1389                  (match_dup 1)
1390                  (const_int 16))
1391                 (lshiftrt:SI
1392                  (match_dup 2)
1393                  (const_int 16))))]
1394  "TARGET_MULHW"
1395  "mulhhwu. %0,%1,%2"
1396  [(set_attr "type" "halfmul")])
1397
1398(define_insn "*mulhhwu"
1399  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400        (mult:SI (lshiftrt:SI
1401                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1402                  (const_int 16))
1403                 (lshiftrt:SI
1404                  (match_operand:SI 2 "gpc_reg_operand" "r")
1405                  (const_int 16))))]
1406  "TARGET_MULHW"
1407  "mulhhwu %0,%1,%2"
1408  [(set_attr "type" "halfmul")])
1409
1410(define_insn "*mullhwc"
1411  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1412        (compare:CC (mult:SI (sign_extend:SI
1413                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1414                             (sign_extend:SI
1415                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1416                    (const_int 0)))
1417   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1418        (mult:SI (sign_extend:SI
1419                  (match_dup 1))
1420                 (sign_extend:SI
1421                  (match_dup 2))))]
1422  "TARGET_MULHW"
1423  "mullhw. %0,%1,%2"
1424  [(set_attr "type" "halfmul")])
1425
1426(define_insn "*mullhw"
1427  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1428        (mult:SI (sign_extend:SI
1429                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1430                 (sign_extend:SI
1431                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1432  "TARGET_MULHW"
1433  "mullhw %0,%1,%2"
1434  [(set_attr "type" "halfmul")])
1435
1436(define_insn "*mullhwuc"
1437  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1438        (compare:CC (mult:SI (zero_extend:SI
1439                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1440                             (zero_extend:SI
1441                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1442                    (const_int 0)))
1443   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444        (mult:SI (zero_extend:SI
1445                  (match_dup 1))
1446                 (zero_extend:SI
1447                  (match_dup 2))))]
1448  "TARGET_MULHW"
1449  "mullhwu. %0,%1,%2"
1450  [(set_attr "type" "halfmul")])
1451
1452(define_insn "*mullhwu"
1453  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454        (mult:SI (zero_extend:SI
1455                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1456                 (zero_extend:SI
1457                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1458  "TARGET_MULHW"
1459  "mullhwu %0,%1,%2"
1460  [(set_attr "type" "halfmul")])
1461
1462;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1463(define_insn "dlmzb"
1464  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1465        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1466                    (match_operand:SI 2 "gpc_reg_operand" "r")]
1467                   UNSPEC_DLMZB_CR))
1468   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1469        (unspec:SI [(match_dup 1)
1470                    (match_dup 2)]
1471                   UNSPEC_DLMZB))]
1472  "TARGET_DLMZB"
1473  "dlmzb. %0,%1,%2")
1474
1475(define_expand "strlensi"
1476  [(set (match_operand:SI 0 "gpc_reg_operand" "")
1477        (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1478                    (match_operand:QI 2 "const_int_operand" "")
1479                    (match_operand 3 "const_int_operand" "")]
1480                   UNSPEC_DLMZB_STRLEN))
1481   (clobber (match_scratch:CC 4 "=x"))]
1482  "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1483{
1484  rtx result = operands[0];
1485  rtx src = operands[1];
1486  rtx search_char = operands[2];
1487  rtx align = operands[3];
1488  rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1489  rtx loop_label, end_label, mem, cr0, cond;
1490  if (search_char != const0_rtx
1491      || GET_CODE (align) != CONST_INT
1492      || INTVAL (align) < 8)
1493        FAIL;
1494  word1 = gen_reg_rtx (SImode);
1495  word2 = gen_reg_rtx (SImode);
1496  scratch_dlmzb = gen_reg_rtx (SImode);
1497  scratch_string = gen_reg_rtx (Pmode);
1498  loop_label = gen_label_rtx ();
1499  end_label = gen_label_rtx ();
1500  addr = force_reg (Pmode, XEXP (src, 0));
1501  emit_move_insn (scratch_string, addr);
1502  emit_label (loop_label);
1503  mem = change_address (src, SImode, scratch_string);
1504  emit_move_insn (word1, mem);
1505  emit_move_insn (word2, adjust_address (mem, SImode, 4));
1506  cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1507  emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1508  cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1509  emit_jump_insn (gen_rtx_SET (pc_rtx,
1510                               gen_rtx_IF_THEN_ELSE (VOIDmode,
1511                                                     cond,
1512                                                     gen_rtx_LABEL_REF
1513                                                       (VOIDmode,
1514                                                        end_label),
1515                                                     pc_rtx)));
1516  emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1517  emit_jump_insn (gen_rtx_SET (pc_rtx,
1518                               gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1519  emit_barrier ();
1520  emit_label (end_label);
1521  emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1522  emit_insn (gen_subsi3 (result, scratch_string, addr));
1523  emit_insn (gen_addsi3 (result, result, constm1_rtx));
1524  DONE;
1525})
1526
1527;; Fixed-point arithmetic insns.
1528
1529(define_expand "add<mode>3"
1530  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1531	(plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1532		  (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1533  ""
1534{
1535  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1536    {
1537      rtx lo0 = gen_lowpart (SImode, operands[0]);
1538      rtx lo1 = gen_lowpart (SImode, operands[1]);
1539      rtx lo2 = gen_lowpart (SImode, operands[2]);
1540      rtx hi0 = gen_highpart (SImode, operands[0]);
1541      rtx hi1 = gen_highpart (SImode, operands[1]);
1542      rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1543
1544      if (!reg_or_short_operand (lo2, SImode))
1545	lo2 = force_reg (SImode, lo2);
1546      if (!adde_operand (hi2, SImode))
1547	hi2 = force_reg (SImode, hi2);
1548
1549      emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1550      emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1551      DONE;
1552    }
1553
1554  if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1555    {
1556      rtx tmp = ((!can_create_pseudo_p ()
1557		  || rtx_equal_p (operands[0], operands[1]))
1558		 ? operands[0] : gen_reg_rtx (<MODE>mode));
1559
1560      /* Adding a constant to r0 is not a valid insn, so use a different
1561	 strategy in that case.  */
1562      if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1563	{
1564	  if (operands[0] == operands[1])
1565	    FAIL;
1566	  rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1567	  emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1568	  DONE;
1569	}
1570
1571      HOST_WIDE_INT val = INTVAL (operands[2]);
1572      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1573      HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1574
1575      if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1576	FAIL;
1577
1578      /* The ordering here is important for the prolog expander.
1579	 When space is allocated from the stack, adding 'low' first may
1580	 produce a temporary deallocation (which would be bad).  */
1581      emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1582      emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1583      DONE;
1584    }
1585})
1586
1587(define_insn "*add<mode>3"
1588  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1589	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1590		  (match_operand:GPR 2 "add_operand" "r,I,L")))]
1591  ""
1592  "@
1593   add %0,%1,%2
1594   addi %0,%1,%2
1595   addis %0,%1,%v2"
1596  [(set_attr "type" "add")])
1597
1598(define_insn "addsi3_high"
1599  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1600        (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1601                 (high:SI (match_operand 2 "" ""))))]
1602  "TARGET_MACHO && !TARGET_64BIT"
1603  "addis %0,%1,ha16(%2)"
1604  [(set_attr "type" "add")])
1605
1606(define_insn_and_split "*add<mode>3_dot"
1607  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1608	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1609			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1610		    (const_int 0)))
1611   (clobber (match_scratch:GPR 0 "=r,r"))]
1612  "<MODE>mode == Pmode"
1613  "@
1614   add. %0,%1,%2
1615   #"
1616  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1617  [(set (match_dup 0)
1618	(plus:GPR (match_dup 1)
1619		 (match_dup 2)))
1620   (set (match_dup 3)
1621	(compare:CC (match_dup 0)
1622		    (const_int 0)))]
1623  ""
1624  [(set_attr "type" "add")
1625   (set_attr "dot" "yes")
1626   (set_attr "length" "4,8")])
1627
1628(define_insn_and_split "*add<mode>3_dot2"
1629  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1630	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1631			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1632		    (const_int 0)))
1633   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1634	(plus:GPR (match_dup 1)
1635		  (match_dup 2)))]
1636  "<MODE>mode == Pmode"
1637  "@
1638   add. %0,%1,%2
1639   #"
1640  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1641  [(set (match_dup 0)
1642	(plus:GPR (match_dup 1)
1643		  (match_dup 2)))
1644   (set (match_dup 3)
1645	(compare:CC (match_dup 0)
1646		    (const_int 0)))]
1647  ""
1648  [(set_attr "type" "add")
1649   (set_attr "dot" "yes")
1650   (set_attr "length" "4,8")])
1651
1652(define_insn_and_split "*add<mode>3_imm_dot"
1653  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1654	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1655			      (match_operand:GPR 2 "short_cint_operand" "I,I"))
1656		    (const_int 0)))
1657   (clobber (match_scratch:GPR 0 "=r,r"))
1658   (clobber (reg:GPR CA_REGNO))]
1659  "<MODE>mode == Pmode"
1660  "@
1661   addic. %0,%1,%2
1662   #"
1663  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1664  [(set (match_dup 0)
1665	(plus:GPR (match_dup 1)
1666		  (match_dup 2)))
1667   (set (match_dup 3)
1668	(compare:CC (match_dup 0)
1669		    (const_int 0)))]
1670  ""
1671  [(set_attr "type" "add")
1672   (set_attr "dot" "yes")
1673   (set_attr "length" "4,8")])
1674
1675(define_insn_and_split "*add<mode>3_imm_dot2"
1676  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1677	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1678			      (match_operand:GPR 2 "short_cint_operand" "I,I"))
1679		    (const_int 0)))
1680   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1681	(plus:GPR (match_dup 1)
1682		  (match_dup 2)))
1683   (clobber (reg:GPR CA_REGNO))]
1684  "<MODE>mode == Pmode"
1685  "@
1686   addic. %0,%1,%2
1687   #"
1688  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1689  [(set (match_dup 0)
1690	(plus:GPR (match_dup 1)
1691		  (match_dup 2)))
1692   (set (match_dup 3)
1693	(compare:CC (match_dup 0)
1694		    (const_int 0)))]
1695  ""
1696  [(set_attr "type" "add")
1697   (set_attr "dot" "yes")
1698   (set_attr "length" "4,8")])
1699
1700;; Split an add that we can't do in one insn into two insns, each of which
1701;; does one 16-bit part.  This is used by combine.  Note that the low-order
1702;; add should be last in case the result gets used in an address.
1703
1704(define_split
1705  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1706	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1707		  (match_operand:GPR 2 "non_add_cint_operand" "")))]
1708  ""
1709  [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1710   (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1711{
1712  HOST_WIDE_INT val = INTVAL (operands[2]);
1713  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1714  HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1715
1716  operands[4] = GEN_INT (low);
1717  if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1718    operands[3] = GEN_INT (rest);
1719  else if (can_create_pseudo_p ())
1720    {
1721      operands[3] = gen_reg_rtx (DImode);
1722      emit_move_insn (operands[3], operands[2]);
1723      emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1724      DONE;
1725    }
1726  else
1727    FAIL;
1728})
1729
1730
1731(define_insn "add<mode>3_carry"
1732  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1733	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1734		(match_operand:P 2 "reg_or_short_operand" "rI")))
1735   (set (reg:P CA_REGNO)
1736	(ltu:P (plus:P (match_dup 1)
1737		       (match_dup 2))
1738	       (match_dup 1)))]
1739  ""
1740  "add%I2c %0,%1,%2"
1741  [(set_attr "type" "add")])
1742
1743(define_insn "*add<mode>3_imm_carry_pos"
1744  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1745	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1746		(match_operand:P 2 "short_cint_operand" "n")))
1747   (set (reg:P CA_REGNO)
1748	(geu:P (match_dup 1)
1749	       (match_operand:P 3 "const_int_operand" "n")))]
1750  "INTVAL (operands[2]) > 0
1751   && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1752  "addic %0,%1,%2"
1753  [(set_attr "type" "add")])
1754
1755(define_insn "*add<mode>3_imm_carry_0"
1756  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1757	(match_operand:P 1 "gpc_reg_operand" "r"))
1758   (set (reg:P CA_REGNO)
1759	(const_int 0))]
1760  ""
1761  "addic %0,%1,0"
1762  [(set_attr "type" "add")])
1763
1764(define_insn "*add<mode>3_imm_carry_m1"
1765  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1766	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1767		(const_int -1)))
1768   (set (reg:P CA_REGNO)
1769	(ne:P (match_dup 1)
1770	      (const_int 0)))]
1771  ""
1772  "addic %0,%1,-1"
1773  [(set_attr "type" "add")])
1774
1775(define_insn "*add<mode>3_imm_carry_neg"
1776  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1777	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1778		(match_operand:P 2 "short_cint_operand" "n")))
1779   (set (reg:P CA_REGNO)
1780	(gtu:P (match_dup 1)
1781	       (match_operand:P 3 "const_int_operand" "n")))]
1782  "INTVAL (operands[2]) < 0
1783   && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1784  "addic %0,%1,%2"
1785  [(set_attr "type" "add")])
1786
1787
1788(define_expand "add<mode>3_carry_in"
1789  [(parallel [
1790     (set (match_operand:GPR 0 "gpc_reg_operand")
1791	  (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1792			      (match_operand:GPR 2 "adde_operand"))
1793		    (reg:GPR CA_REGNO)))
1794     (clobber (reg:GPR CA_REGNO))])]
1795  ""
1796{
1797  if (operands[2] == const0_rtx)
1798    {
1799      emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1800      DONE;
1801    }
1802  if (operands[2] == constm1_rtx)
1803    {
1804      emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1805      DONE;
1806    }
1807})
1808
1809(define_insn "*add<mode>3_carry_in_internal"
1810  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1811	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1812			    (match_operand:GPR 2 "gpc_reg_operand" "r"))
1813		  (reg:GPR CA_REGNO)))
1814   (clobber (reg:GPR CA_REGNO))]
1815  ""
1816  "adde %0,%1,%2"
1817  [(set_attr "type" "add")])
1818
1819(define_insn "add<mode>3_carry_in_0"
1820  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1821	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1822		  (reg:GPR CA_REGNO)))
1823   (clobber (reg:GPR CA_REGNO))]
1824  ""
1825  "addze %0,%1"
1826  [(set_attr "type" "add")])
1827
1828(define_insn "add<mode>3_carry_in_m1"
1829  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1830	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1831			    (reg:GPR CA_REGNO))
1832		  (const_int -1)))
1833   (clobber (reg:GPR CA_REGNO))]
1834  ""
1835  "addme %0,%1"
1836  [(set_attr "type" "add")])
1837
1838
1839(define_expand "one_cmpl<mode>2"
1840  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1841	(not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1842  ""
1843{
1844  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1845    {
1846      rs6000_split_logical (operands, NOT, false, false, false);
1847      DONE;
1848    }
1849})
1850
1851(define_insn "*one_cmpl<mode>2"
1852  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1853	(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1854  ""
1855  "not %0,%1")
1856
1857(define_insn_and_split "*one_cmpl<mode>2_dot"
1858  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1859	(compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1860		    (const_int 0)))
1861   (clobber (match_scratch:GPR 0 "=r,r"))]
1862  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1863  "@
1864   not. %0,%1
1865   #"
1866  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1867  [(set (match_dup 0)
1868	(not:GPR (match_dup 1)))
1869   (set (match_dup 2)
1870	(compare:CC (match_dup 0)
1871		    (const_int 0)))]
1872  ""
1873  [(set_attr "type" "logical")
1874   (set_attr "dot" "yes")
1875   (set_attr "length" "4,8")])
1876
1877(define_insn_and_split "*one_cmpl<mode>2_dot2"
1878  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1879	(compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1880		    (const_int 0)))
1881   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1882	(not:GPR (match_dup 1)))]
1883  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1884  "@
1885   not. %0,%1
1886   #"
1887  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1888  [(set (match_dup 0)
1889	(not:GPR (match_dup 1)))
1890   (set (match_dup 2)
1891	(compare:CC (match_dup 0)
1892		    (const_int 0)))]
1893  ""
1894  [(set_attr "type" "logical")
1895   (set_attr "dot" "yes")
1896   (set_attr "length" "4,8")])
1897
1898
1899(define_expand "sub<mode>3"
1900  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1901	(minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1902		   (match_operand:SDI 2 "gpc_reg_operand" "")))]
1903  ""
1904{
1905  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1906    {
1907      rtx lo0 = gen_lowpart (SImode, operands[0]);
1908      rtx lo1 = gen_lowpart (SImode, operands[1]);
1909      rtx lo2 = gen_lowpart (SImode, operands[2]);
1910      rtx hi0 = gen_highpart (SImode, operands[0]);
1911      rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1912      rtx hi2 = gen_highpart (SImode, operands[2]);
1913
1914      if (!reg_or_short_operand (lo1, SImode))
1915	lo1 = force_reg (SImode, lo1);
1916      if (!adde_operand (hi1, SImode))
1917	hi1 = force_reg (SImode, hi1);
1918
1919      emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1920      emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1921      DONE;
1922    }
1923
1924  if (short_cint_operand (operands[1], <MODE>mode))
1925    {
1926      emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1927      DONE;
1928    }
1929})
1930
1931(define_insn "*subf<mode>3"
1932  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1933	(minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1934		   (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1935  ""
1936  "subf %0,%1,%2"
1937  [(set_attr "type" "add")])
1938
1939(define_insn_and_split "*subf<mode>3_dot"
1940  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1941	(compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1942			       (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1943		    (const_int 0)))
1944   (clobber (match_scratch:GPR 0 "=r,r"))]
1945  "<MODE>mode == Pmode"
1946  "@
1947   subf. %0,%1,%2
1948   #"
1949  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1950  [(set (match_dup 0)
1951	(minus:GPR (match_dup 2)
1952		   (match_dup 1)))
1953   (set (match_dup 3)
1954	(compare:CC (match_dup 0)
1955		    (const_int 0)))]
1956  ""
1957  [(set_attr "type" "add")
1958   (set_attr "dot" "yes")
1959   (set_attr "length" "4,8")])
1960
1961(define_insn_and_split "*subf<mode>3_dot2"
1962  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1963	(compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1964			       (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1965		    (const_int 0)))
1966   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1967	(minus:GPR (match_dup 2)
1968		   (match_dup 1)))]
1969  "<MODE>mode == Pmode"
1970  "@
1971   subf. %0,%1,%2
1972   #"
1973  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1974  [(set (match_dup 0)
1975	(minus:GPR (match_dup 2)
1976		   (match_dup 1)))
1977   (set (match_dup 3)
1978	(compare:CC (match_dup 0)
1979		    (const_int 0)))]
1980  ""
1981  [(set_attr "type" "add")
1982   (set_attr "dot" "yes")
1983   (set_attr "length" "4,8")])
1984
1985(define_insn "subf<mode>3_imm"
1986  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1987	(minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1988		   (match_operand:GPR 1 "gpc_reg_operand" "r")))
1989   (clobber (reg:GPR CA_REGNO))]
1990  ""
1991  "subfic %0,%1,%2"
1992  [(set_attr "type" "add")])
1993
1994
1995(define_insn "subf<mode>3_carry"
1996  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1997	(minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
1998		 (match_operand:P 1 "gpc_reg_operand" "r")))
1999   (set (reg:P CA_REGNO)
2000	(leu:P (match_dup 1)
2001	       (match_dup 2)))]
2002  ""
2003  "subf%I2c %0,%1,%2"
2004  [(set_attr "type" "add")])
2005
2006(define_insn "*subf<mode>3_imm_carry_0"
2007  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2008	(neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2009   (set (reg:P CA_REGNO)
2010	(eq:P (match_dup 1)
2011	      (const_int 0)))]
2012  ""
2013  "subfic %0,%1,0"
2014  [(set_attr "type" "add")])
2015
2016(define_insn "*subf<mode>3_imm_carry_m1"
2017  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2018	(not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2019   (set (reg:P CA_REGNO)
2020	(const_int 1))]
2021  ""
2022  "subfic %0,%1,-1"
2023  [(set_attr "type" "add")])
2024
2025
2026(define_expand "subf<mode>3_carry_in"
2027  [(parallel [
2028     (set (match_operand:GPR 0 "gpc_reg_operand")
2029	  (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2030			      (reg:GPR CA_REGNO))
2031		    (match_operand:GPR 2 "adde_operand")))
2032     (clobber (reg:GPR CA_REGNO))])]
2033  ""
2034{
2035  if (operands[2] == const0_rtx)
2036    {
2037      emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2038      DONE;
2039    }
2040  if (operands[2] == constm1_rtx)
2041    {
2042      emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2043      DONE;
2044    }
2045})
2046
2047(define_insn "*subf<mode>3_carry_in_internal"
2048  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2049	(plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2050			    (reg:GPR CA_REGNO))
2051		  (match_operand:GPR 2 "gpc_reg_operand" "r")))
2052   (clobber (reg:GPR CA_REGNO))]
2053  ""
2054  "subfe %0,%1,%2"
2055  [(set_attr "type" "add")])
2056
2057(define_insn "subf<mode>3_carry_in_0"
2058  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2059	(plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2060		  (reg:GPR CA_REGNO)))
2061   (clobber (reg:GPR CA_REGNO))]
2062  ""
2063  "subfze %0,%1"
2064  [(set_attr "type" "add")])
2065
2066(define_insn "subf<mode>3_carry_in_m1"
2067  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2068	(plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2069			     (match_operand:GPR 1 "gpc_reg_operand" "r"))
2070		  (const_int -2)))
2071   (clobber (reg:GPR CA_REGNO))]
2072  ""
2073  "subfme %0,%1"
2074  [(set_attr "type" "add")])
2075
2076(define_insn "subf<mode>3_carry_in_xx"
2077  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2078	(plus:GPR (reg:GPR CA_REGNO)
2079		  (const_int -1)))
2080   (clobber (reg:GPR CA_REGNO))]
2081  ""
2082  "subfe %0,%0,%0"
2083  [(set_attr "type" "add")])
2084
2085
2086(define_insn "neg<mode>2"
2087  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2088	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2089  ""
2090  "neg %0,%1"
2091  [(set_attr "type" "add")])
2092
2093(define_insn_and_split "*neg<mode>2_dot"
2094  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2095	(compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2096		    (const_int 0)))
2097   (clobber (match_scratch:GPR 0 "=r,r"))]
2098  "<MODE>mode == Pmode"
2099  "@
2100   neg. %0,%1
2101   #"
2102  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2103  [(set (match_dup 0)
2104	(neg:GPR (match_dup 1)))
2105   (set (match_dup 2)
2106	(compare:CC (match_dup 0)
2107		    (const_int 0)))]
2108  ""
2109  [(set_attr "type" "add")
2110   (set_attr "dot" "yes")
2111   (set_attr "length" "4,8")])
2112
2113(define_insn_and_split "*neg<mode>2_dot2"
2114  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2115	(compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2116		    (const_int 0)))
2117   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2118	(neg:GPR (match_dup 1)))]
2119  "<MODE>mode == Pmode"
2120  "@
2121   neg. %0,%1
2122   #"
2123  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2124  [(set (match_dup 0)
2125	(neg:GPR (match_dup 1)))
2126   (set (match_dup 2)
2127	(compare:CC (match_dup 0)
2128		    (const_int 0)))]
2129  ""
2130  [(set_attr "type" "add")
2131   (set_attr "dot" "yes")
2132   (set_attr "length" "4,8")])
2133
2134
2135(define_insn "clz<mode>2"
2136  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2137	(clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2138  ""
2139  "cntlz<wd> %0,%1"
2140  [(set_attr "type" "cntlz")])
2141
2142(define_expand "ctz<mode>2"
2143  [(set (match_dup 2)
2144	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2145   (set (match_dup 3)
2146	(and:GPR (match_dup 1)
2147		 (match_dup 2)))
2148   (set (match_dup 4)
2149	(clz:GPR (match_dup 3)))
2150   (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2151		   (minus:GPR (match_dup 5)
2152			      (match_dup 4)))
2153	      (clobber (reg:GPR CA_REGNO))])]
2154  ""
2155{
2156  if (TARGET_CTZ)
2157    {
2158      emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2159      DONE;
2160    }
2161
2162  operands[2] = gen_reg_rtx (<MODE>mode);
2163  operands[3] = gen_reg_rtx (<MODE>mode);
2164  operands[4] = gen_reg_rtx (<MODE>mode);
2165  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2166})
2167
2168(define_insn "ctz<mode>2_hw"
2169  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170	(ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2171  "TARGET_CTZ"
2172  "cnttz<wd> %0,%1"
2173  [(set_attr "type" "cntlz")])
2174
2175(define_expand "ffs<mode>2"
2176  [(set (match_dup 2)
2177	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2178   (set (match_dup 3)
2179	(and:GPR (match_dup 1)
2180		 (match_dup 2)))
2181   (set (match_dup 4)
2182	(clz:GPR (match_dup 3)))
2183   (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2184		   (minus:GPR (match_dup 5)
2185			      (match_dup 4)))
2186	      (clobber (reg:GPR CA_REGNO))])]
2187  ""
2188{
2189  operands[2] = gen_reg_rtx (<MODE>mode);
2190  operands[3] = gen_reg_rtx (<MODE>mode);
2191  operands[4] = gen_reg_rtx (<MODE>mode);
2192  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2193})
2194
2195
2196(define_expand "popcount<mode>2"
2197  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2198	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2199  "TARGET_POPCNTB || TARGET_POPCNTD"
2200{
2201  rs6000_emit_popcount (operands[0], operands[1]);
2202  DONE;
2203})
2204
2205(define_insn "popcntb<mode>2"
2206  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2207	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2208		    UNSPEC_POPCNTB))]
2209  "TARGET_POPCNTB"
2210  "popcntb %0,%1"
2211  [(set_attr "type" "popcnt")])
2212
2213(define_insn "popcntd<mode>2"
2214  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2215	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2216  "TARGET_POPCNTD"
2217  "popcnt<wd> %0,%1"
2218  [(set_attr "type" "popcnt")])
2219
2220
2221(define_expand "parity<mode>2"
2222  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2223	(parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2224  "TARGET_POPCNTB"
2225{
2226  rs6000_emit_parity (operands[0], operands[1]);
2227  DONE;
2228})
2229
2230(define_insn "parity<mode>2_cmpb"
2231  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2232	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2233  "TARGET_CMPB && TARGET_POPCNTB"
2234  "prty<wd> %0,%1"
2235  [(set_attr "type" "popcnt")])
2236
2237
2238;; Since the hardware zeros the upper part of the register, save generating the
2239;; AND immediate if we are converting to unsigned
2240(define_insn "*bswap<mode>2_extenddi"
2241  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2242	(zero_extend:DI
2243	 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2244  "TARGET_POWERPC64"
2245  "l<wd>brx %0,%y1"
2246  [(set_attr "length" "4")
2247   (set_attr "type" "load")])
2248
2249(define_insn "*bswaphi2_extendsi"
2250  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2251	(zero_extend:SI
2252	 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2253  ""
2254  "lhbrx %0,%y1"
2255  [(set_attr "length" "4")
2256   (set_attr "type" "load")])
2257
2258;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2259;; the register allocator from converting a gpr<-gpr swap into a store and then
2260;; load with byte swap, which can be slower than doing it in the registers.  It
2261;; also prevents certain failures with the RELOAD register allocator.
2262
2263(define_expand "bswap<mode>2"
2264  [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2265   (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2266  ""
2267{
2268  rtx dest = operands[0];
2269  rtx src = operands[1];
2270
2271  if (!REG_P (dest) && !REG_P (src))
2272    src = force_reg (<MODE>mode, src);
2273
2274  if (MEM_P (src))
2275    emit_insn (gen_bswap<mode>2_load (dest, src));
2276  else if (MEM_P (dest))
2277    emit_insn (gen_bswap<mode>2_store (dest, src));
2278  else
2279    emit_insn (gen_bswap<mode>2_reg (dest, src));
2280  DONE;
2281})
2282
2283(define_insn "bswap<mode>2_load"
2284  [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2285	(bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2286  ""
2287  "l<wd>brx %0,%y1"
2288  [(set_attr "type" "load")])
2289
2290(define_insn "bswap<mode>2_store"
2291  [(set (match_operand:HSI 0 "memory_operand" "=Z")
2292	(bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2293  ""
2294  "st<wd>brx %1,%y0"
2295  [(set_attr "type" "store")])
2296
2297(define_insn_and_split "bswaphi2_reg"
2298  [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2299	(bswap:HI
2300	 (match_operand:HI 1 "gpc_reg_operand" "r")))
2301   (clobber (match_scratch:SI 2 "=&r"))]
2302  ""
2303  "#"
2304  "reload_completed"
2305  [(set (match_dup 3)
2306	(and:SI (lshiftrt:SI (match_dup 4)
2307			     (const_int 8))
2308		(const_int 255)))
2309   (set (match_dup 2)
2310	(and:SI (ashift:SI (match_dup 4)
2311			   (const_int 8))
2312		(const_int 65280)))		;; 0xff00
2313   (set (match_dup 3)
2314	(ior:SI (match_dup 3)
2315		(match_dup 2)))]
2316{
2317  operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2318  operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2319}
2320  [(set_attr "length" "12")
2321   (set_attr "type" "*")])
2322
2323;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2324;; zero_extract insns do not change for -mlittle.
2325(define_insn_and_split "bswapsi2_reg"
2326  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2327	(bswap:SI
2328	 (match_operand:SI 1 "gpc_reg_operand" "r")))]
2329  ""
2330  "#"
2331  "reload_completed"
2332  [(set (match_dup 0)					; DABC
2333	(rotate:SI (match_dup 1)
2334		   (const_int 24)))
2335   (set (match_dup 0)					; DCBC
2336	(ior:SI (and:SI (ashift:SI (match_dup 1)
2337				   (const_int 8))
2338			(const_int 16711680))
2339		(and:SI (match_dup 0)
2340			(const_int -16711681))))
2341   (set (match_dup 0)					; DCBA
2342	(ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2343				     (const_int 24))
2344			(const_int 255))
2345		(and:SI (match_dup 0)
2346			(const_int -256))))]
2347  "")
2348
2349;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2350;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2351;; complex code.
2352
2353(define_expand "bswapdi2"
2354  [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2355		   (bswap:DI
2356		    (match_operand:DI 1 "reg_or_mem_operand" "")))
2357	      (clobber (match_scratch:DI 2 ""))
2358	      (clobber (match_scratch:DI 3 ""))])]
2359  ""
2360{
2361  rtx dest = operands[0];
2362  rtx src = operands[1];
2363
2364  if (!REG_P (dest) && !REG_P (src))
2365    operands[1] = src = force_reg (DImode, src);
2366
2367  if (TARGET_POWERPC64 && TARGET_LDBRX)
2368    {
2369      if (MEM_P (src))
2370	emit_insn (gen_bswapdi2_load (dest, src));
2371      else if (MEM_P (dest))
2372	emit_insn (gen_bswapdi2_store (dest, src));
2373      else
2374	emit_insn (gen_bswapdi2_reg (dest, src));
2375      DONE;
2376    }
2377
2378  if (!TARGET_POWERPC64)
2379    {
2380      /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2381	 that uses 64-bit registers needs the same scratch registers as 64-bit
2382	 mode.  */
2383      emit_insn (gen_bswapdi2_32bit (dest, src));
2384      DONE;
2385    }
2386})
2387
2388;; Power7/cell has ldbrx/stdbrx, so use it directly
2389(define_insn "bswapdi2_load"
2390  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2391	(bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2392  "TARGET_POWERPC64 && TARGET_LDBRX"
2393  "ldbrx %0,%y1"
2394  [(set_attr "type" "load")])
2395
2396(define_insn "bswapdi2_store"
2397  [(set (match_operand:DI 0 "memory_operand" "=Z")
2398	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2399  "TARGET_POWERPC64 && TARGET_LDBRX"
2400  "stdbrx %1,%y0"
2401  [(set_attr "type" "store")])
2402
2403(define_insn "bswapdi2_reg"
2404  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2405	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2406   (clobber (match_scratch:DI 2 "=&r"))
2407   (clobber (match_scratch:DI 3 "=&r"))]
2408  "TARGET_POWERPC64 && TARGET_LDBRX"
2409  "#"
2410  [(set_attr "length" "36")])
2411
2412;; Non-power7/cell, fall back to use lwbrx/stwbrx
2413(define_insn "*bswapdi2_64bit"
2414  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2415	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2416   (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2417   (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2418  "TARGET_POWERPC64 && !TARGET_LDBRX
2419   && (REG_P (operands[0]) || REG_P (operands[1]))
2420   && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2421   && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2422  "#"
2423  [(set_attr "length" "16,12,36")])
2424
2425(define_split
2426  [(set (match_operand:DI 0 "gpc_reg_operand" "")
2427	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2428   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2429   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2430  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2431  [(const_int 0)]
2432  "
2433{
2434  rtx dest   = operands[0];
2435  rtx src    = operands[1];
2436  rtx op2    = operands[2];
2437  rtx op3    = operands[3];
2438  rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2439				    BYTES_BIG_ENDIAN ? 4 : 0);
2440  rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2441				     BYTES_BIG_ENDIAN ? 4 : 0);
2442  rtx addr1;
2443  rtx addr2;
2444  rtx word1;
2445  rtx word2;
2446
2447  addr1 = XEXP (src, 0);
2448  if (GET_CODE (addr1) == PLUS)
2449    {
2450      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2451      if (TARGET_AVOID_XFORM)
2452	{
2453	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2454	  addr2 = op2;
2455	}
2456      else
2457	addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2458    }
2459  else if (TARGET_AVOID_XFORM)
2460    {
2461      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2462      addr2 = op2;
2463    }
2464  else
2465    {
2466      emit_move_insn (op2, GEN_INT (4));
2467      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2468    }
2469
2470  word1 = change_address (src, SImode, addr1);
2471  word2 = change_address (src, SImode, addr2);
2472
2473  if (BYTES_BIG_ENDIAN)
2474    {
2475      emit_insn (gen_bswapsi2 (op3_32, word2));
2476      emit_insn (gen_bswapsi2 (dest_32, word1));
2477    }
2478  else
2479    {
2480      emit_insn (gen_bswapsi2 (op3_32, word1));
2481      emit_insn (gen_bswapsi2 (dest_32, word2));
2482    }
2483
2484  emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2485  emit_insn (gen_iordi3 (dest, dest, op3));
2486  DONE;
2487}")
2488
2489(define_split
2490  [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2491	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2492   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2493   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2494  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2495  [(const_int 0)]
2496  "
2497{
2498  rtx dest   = operands[0];
2499  rtx src    = operands[1];
2500  rtx op2    = operands[2];
2501  rtx op3    = operands[3];
2502  rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2503				    BYTES_BIG_ENDIAN ? 4 : 0);
2504  rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2505				    BYTES_BIG_ENDIAN ? 4 : 0);
2506  rtx addr1;
2507  rtx addr2;
2508  rtx word1;
2509  rtx word2;
2510
2511  addr1 = XEXP (dest, 0);
2512  if (GET_CODE (addr1) == PLUS)
2513    {
2514      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2515      if (TARGET_AVOID_XFORM)
2516	{
2517	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2518	  addr2 = op2;
2519	}
2520      else
2521	addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2522    }
2523  else if (TARGET_AVOID_XFORM)
2524    {
2525      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2526      addr2 = op2;
2527    }
2528  else
2529    {
2530      emit_move_insn (op2, GEN_INT (4));
2531      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2532    }
2533
2534  word1 = change_address (dest, SImode, addr1);
2535  word2 = change_address (dest, SImode, addr2);
2536
2537  emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2538
2539  if (BYTES_BIG_ENDIAN)
2540    {
2541      emit_insn (gen_bswapsi2 (word1, src_si));
2542      emit_insn (gen_bswapsi2 (word2, op3_si));
2543    }
2544  else
2545    {
2546      emit_insn (gen_bswapsi2 (word2, src_si));
2547      emit_insn (gen_bswapsi2 (word1, op3_si));
2548    }
2549  DONE;
2550}")
2551
2552(define_split
2553  [(set (match_operand:DI 0 "gpc_reg_operand" "")
2554	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2555   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2556   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2557  "TARGET_POWERPC64 && reload_completed"
2558  [(const_int 0)]
2559  "
2560{
2561  rtx dest    = operands[0];
2562  rtx src     = operands[1];
2563  rtx op2     = operands[2];
2564  rtx op3     = operands[3];
2565  int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2566  rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2567  rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2568  rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2569  rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2570
2571  emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2572  emit_insn (gen_bswapsi2 (dest_si, src_si));
2573  emit_insn (gen_bswapsi2 (op3_si, op2_si));
2574  emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2575  emit_insn (gen_iordi3 (dest, dest, op3));
2576  DONE;
2577}")
2578
2579(define_insn "bswapdi2_32bit"
2580  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2581	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2582   (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2583  "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2584  "#"
2585  [(set_attr "length" "16,12,36")])
2586
2587(define_split
2588  [(set (match_operand:DI 0 "gpc_reg_operand" "")
2589	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2590   (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2591  "!TARGET_POWERPC64 && reload_completed"
2592  [(const_int 0)]
2593  "
2594{
2595  rtx dest  = operands[0];
2596  rtx src   = operands[1];
2597  rtx op2   = operands[2];
2598  rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2599  rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2600  rtx addr1;
2601  rtx addr2;
2602  rtx word1;
2603  rtx word2;
2604
2605  addr1 = XEXP (src, 0);
2606  if (GET_CODE (addr1) == PLUS)
2607    {
2608      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2609      if (TARGET_AVOID_XFORM
2610	  || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2611	{
2612	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2613	  addr2 = op2;
2614	}
2615      else
2616	addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2617    }
2618  else if (TARGET_AVOID_XFORM
2619	   || REGNO (addr1) == REGNO (dest2))
2620    {
2621      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2622      addr2 = op2;
2623    }
2624  else
2625    {
2626      emit_move_insn (op2, GEN_INT (4));
2627      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2628    }
2629
2630  word1 = change_address (src, SImode, addr1);
2631  word2 = change_address (src, SImode, addr2);
2632
2633  emit_insn (gen_bswapsi2 (dest2, word1));
2634  /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2635     thus allowing us to omit an early clobber on the output.  */
2636  emit_insn (gen_bswapsi2 (dest1, word2));
2637  DONE;
2638}")
2639
2640(define_split
2641  [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2642	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2643   (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2644  "!TARGET_POWERPC64 && reload_completed"
2645  [(const_int 0)]
2646  "
2647{
2648  rtx dest = operands[0];
2649  rtx src  = operands[1];
2650  rtx op2  = operands[2];
2651  rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2652  rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2653  rtx addr1;
2654  rtx addr2;
2655  rtx word1;
2656  rtx word2;
2657
2658  addr1 = XEXP (dest, 0);
2659  if (GET_CODE (addr1) == PLUS)
2660    {
2661      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2662      if (TARGET_AVOID_XFORM)
2663	{
2664	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2665	  addr2 = op2;
2666	}
2667      else
2668	addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2669    }
2670  else if (TARGET_AVOID_XFORM)
2671    {
2672      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2673      addr2 = op2;
2674    }
2675  else
2676    {
2677      emit_move_insn (op2, GEN_INT (4));
2678      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2679    }
2680
2681  word1 = change_address (dest, SImode, addr1);
2682  word2 = change_address (dest, SImode, addr2);
2683
2684  emit_insn (gen_bswapsi2 (word2, src1));
2685  emit_insn (gen_bswapsi2 (word1, src2));
2686  DONE;
2687}")
2688
2689(define_split
2690  [(set (match_operand:DI 0 "gpc_reg_operand" "")
2691	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2692   (clobber (match_operand:SI 2 "" ""))]
2693  "!TARGET_POWERPC64 && reload_completed"
2694  [(const_int 0)]
2695  "
2696{
2697  rtx dest  = operands[0];
2698  rtx src   = operands[1];
2699  rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2700  rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2701  rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2702  rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2703
2704  emit_insn (gen_bswapsi2 (dest1, src2));
2705  emit_insn (gen_bswapsi2 (dest2, src1));
2706  DONE;
2707}")
2708
2709
2710(define_insn "mul<mode>3"
2711  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2712	(mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2713		  (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2714  ""
2715  "@
2716   mull<wd> %0,%1,%2
2717   mulli %0,%1,%2"
2718   [(set_attr "type" "mul")
2719    (set (attr "size")
2720      (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2721		(const_string "8")
2722             (match_operand:GPR 2 "short_cint_operand" "")
2723		(const_string "16")]
2724	(const_string "<bits>")))])
2725
2726(define_insn_and_split "*mul<mode>3_dot"
2727  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2728	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2729			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2730		    (const_int 0)))
2731   (clobber (match_scratch:GPR 0 "=r,r"))]
2732  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2733  "@
2734   mull<wd>. %0,%1,%2
2735   #"
2736  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2737  [(set (match_dup 0)
2738	(mult:GPR (match_dup 1)
2739		  (match_dup 2)))
2740   (set (match_dup 3)
2741	(compare:CC (match_dup 0)
2742		    (const_int 0)))]
2743  ""
2744  [(set_attr "type" "mul")
2745   (set_attr "size" "<bits>")
2746   (set_attr "dot" "yes")
2747   (set_attr "length" "4,8")])
2748
2749(define_insn_and_split "*mul<mode>3_dot2"
2750  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2751	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2752			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2753		    (const_int 0)))
2754   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2755	(mult:GPR (match_dup 1)
2756		  (match_dup 2)))]
2757  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2758  "@
2759   mull<wd>. %0,%1,%2
2760   #"
2761  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2762  [(set (match_dup 0)
2763	(mult:GPR (match_dup 1)
2764		  (match_dup 2)))
2765   (set (match_dup 3)
2766	(compare:CC (match_dup 0)
2767		    (const_int 0)))]
2768  ""
2769  [(set_attr "type" "mul")
2770   (set_attr "size" "<bits>")
2771   (set_attr "dot" "yes")
2772   (set_attr "length" "4,8")])
2773
2774
2775(define_expand "<su>mul<mode>3_highpart"
2776  [(set (match_operand:GPR 0 "gpc_reg_operand")
2777	(subreg:GPR
2778	  (mult:<DMODE> (any_extend:<DMODE>
2779			  (match_operand:GPR 1 "gpc_reg_operand"))
2780			(any_extend:<DMODE>
2781			  (match_operand:GPR 2 "gpc_reg_operand")))
2782	 0))]
2783  ""
2784{
2785  if (<MODE>mode == SImode && TARGET_POWERPC64)
2786    {
2787      emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2788					     operands[2]));
2789      DONE;
2790    }
2791
2792  if (!WORDS_BIG_ENDIAN)
2793    {
2794      emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2795						 operands[2]));
2796      DONE;
2797    }
2798})
2799
2800(define_insn "*<su>mul<mode>3_highpart"
2801  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2802	(subreg:GPR
2803	  (mult:<DMODE> (any_extend:<DMODE>
2804			  (match_operand:GPR 1 "gpc_reg_operand" "r"))
2805			(any_extend:<DMODE>
2806			  (match_operand:GPR 2 "gpc_reg_operand" "r")))
2807	 0))]
2808  "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2809  "mulh<wd><u> %0,%1,%2"
2810  [(set_attr "type" "mul")
2811   (set_attr "size" "<bits>")])
2812
2813(define_insn "<su>mulsi3_highpart_le"
2814  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2815	(subreg:SI
2816	  (mult:DI (any_extend:DI
2817		     (match_operand:SI 1 "gpc_reg_operand" "r"))
2818		   (any_extend:DI
2819		     (match_operand:SI 2 "gpc_reg_operand" "r")))
2820	 4))]
2821  "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2822  "mulhw<u> %0,%1,%2"
2823  [(set_attr "type" "mul")])
2824
2825(define_insn "<su>muldi3_highpart_le"
2826  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2827	(subreg:DI
2828	  (mult:TI (any_extend:TI
2829		     (match_operand:DI 1 "gpc_reg_operand" "r"))
2830		   (any_extend:TI
2831		     (match_operand:DI 2 "gpc_reg_operand" "r")))
2832	 8))]
2833  "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2834  "mulhd<u> %0,%1,%2"
2835  [(set_attr "type" "mul")
2836   (set_attr "size" "64")])
2837
2838(define_insn "<su>mulsi3_highpart_64"
2839  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2840	(truncate:SI
2841	  (lshiftrt:DI
2842	    (mult:DI (any_extend:DI
2843		       (match_operand:SI 1 "gpc_reg_operand" "r"))
2844		     (any_extend:DI
2845		       (match_operand:SI 2 "gpc_reg_operand" "r")))
2846	    (const_int 32))))]
2847  "TARGET_POWERPC64"
2848  "mulhw<u> %0,%1,%2"
2849  [(set_attr "type" "mul")])
2850
2851(define_expand "<u>mul<mode><dmode>3"
2852  [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2853	(mult:<DMODE> (any_extend:<DMODE>
2854			(match_operand:GPR 1 "gpc_reg_operand"))
2855		      (any_extend:<DMODE>
2856			(match_operand:GPR 2 "gpc_reg_operand"))))]
2857  "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2858{
2859  rtx l = gen_reg_rtx (<MODE>mode);
2860  rtx h = gen_reg_rtx (<MODE>mode);
2861  emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2862  emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2863  emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2864  emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2865  DONE;
2866})
2867
2868(define_insn "*maddld4"
2869  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2870	(plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2871			  (match_operand:DI 2 "gpc_reg_operand" "r"))
2872		 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2873  "TARGET_MADDLD"
2874  "maddld %0,%1,%2,%3"
2875  [(set_attr "type" "mul")])
2876
2877(define_insn "udiv<mode>3"
2878  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2879        (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2880		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2881  ""
2882  "div<wd>u %0,%1,%2"
2883  [(set_attr "type" "div")
2884   (set_attr "size" "<bits>")])
2885
2886
2887;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2888;; modulus.  If it isn't a power of two, force operands into register and do
2889;; a normal divide.
2890(define_expand "div<mode>3"
2891  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2892	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2893		 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2894  ""
2895{
2896  if (CONST_INT_P (operands[2])
2897      && INTVAL (operands[2]) > 0
2898      && exact_log2 (INTVAL (operands[2])) >= 0)
2899    {
2900      emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2901      DONE;
2902    }
2903
2904  operands[2] = force_reg (<MODE>mode, operands[2]);
2905})
2906
2907(define_insn "*div<mode>3"
2908  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2909        (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2910		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2911  ""
2912  "div<wd> %0,%1,%2"
2913  [(set_attr "type" "div")
2914   (set_attr "size" "<bits>")])
2915
2916(define_insn "div<mode>3_sra"
2917  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2918	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2919		 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2920   (clobber (reg:GPR CA_REGNO))]
2921  ""
2922  "sra<wd>i %0,%1,%p2\;addze %0,%0"
2923  [(set_attr "type" "two")
2924   (set_attr "length" "8")])
2925
2926(define_insn_and_split "*div<mode>3_sra_dot"
2927  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2928	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2929			     (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2930		    (const_int 0)))
2931   (clobber (match_scratch:GPR 0 "=r,r"))
2932   (clobber (reg:GPR CA_REGNO))]
2933  "<MODE>mode == Pmode"
2934  "@
2935   sra<wd>i %0,%1,%p2\;addze. %0,%0
2936   #"
2937  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2938  [(parallel [(set (match_dup 0)
2939		   (div:GPR (match_dup 1)
2940			    (match_dup 2)))
2941	      (clobber (reg:GPR CA_REGNO))])
2942   (set (match_dup 3)
2943	(compare:CC (match_dup 0)
2944		    (const_int 0)))]
2945  ""
2946  [(set_attr "type" "two")
2947   (set_attr "length" "8,12")
2948   (set_attr "cell_micro" "not")])
2949
2950(define_insn_and_split "*div<mode>3_sra_dot2"
2951  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2952	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2953			     (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2954		    (const_int 0)))
2955   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2956	(div:GPR (match_dup 1)
2957		 (match_dup 2)))
2958   (clobber (reg:GPR CA_REGNO))]
2959  "<MODE>mode == Pmode"
2960  "@
2961   sra<wd>i %0,%1,%p2\;addze. %0,%0
2962   #"
2963  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2964  [(parallel [(set (match_dup 0)
2965		   (div:GPR (match_dup 1)
2966			    (match_dup 2)))
2967	      (clobber (reg:GPR CA_REGNO))])
2968   (set (match_dup 3)
2969	(compare:CC (match_dup 0)
2970		    (const_int 0)))]
2971  ""
2972  [(set_attr "type" "two")
2973   (set_attr "length" "8,12")
2974   (set_attr "cell_micro" "not")])
2975
2976(define_expand "mod<mode>3"
2977  [(set (match_operand:GPR 0 "gpc_reg_operand")
2978	(mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
2979		 (match_operand:GPR 2 "reg_or_cint_operand")))]
2980  ""
2981{
2982  int i;
2983  rtx temp1;
2984  rtx temp2;
2985
2986  if (GET_CODE (operands[2]) != CONST_INT
2987      || INTVAL (operands[2]) <= 0
2988      || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2989    {
2990      if (!TARGET_MODULO)
2991	FAIL;
2992
2993      operands[2] = force_reg (<MODE>mode, operands[2]);
2994    }
2995  else
2996    {
2997      temp1 = gen_reg_rtx (<MODE>mode);
2998      temp2 = gen_reg_rtx (<MODE>mode);
2999
3000      emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3001      emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3002      emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3003      DONE;
3004    }
3005})
3006
3007;; In order to enable using a peephole2 for combining div/mod to eliminate the
3008;; mod, prefer putting the result of mod into a different register
3009(define_insn "*mod<mode>3"
3010  [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3011        (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3012		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3013  "TARGET_MODULO"
3014  "mods<wd> %0,%1,%2"
3015  [(set_attr "type" "div")
3016   (set_attr "size" "<bits>")])
3017
3018
3019(define_insn "umod<mode>3"
3020  [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3021        (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3022		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3023  "TARGET_MODULO"
3024  "modu<wd> %0,%1,%2"
3025  [(set_attr "type" "div")
3026   (set_attr "size" "<bits>")])
3027
3028;; On machines with modulo support, do a combined div/mod the old fashioned
3029;; method, since the multiply/subtract is faster than doing the mod instruction
3030;; after a divide.
3031
3032(define_peephole2
3033  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3034	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3035		 (match_operand:GPR 2 "gpc_reg_operand" "")))
3036   (set (match_operand:GPR 3 "gpc_reg_operand" "")
3037	(mod:GPR (match_dup 1)
3038		 (match_dup 2)))]
3039  "TARGET_MODULO
3040   && ! reg_mentioned_p (operands[0], operands[1])
3041   && ! reg_mentioned_p (operands[0], operands[2])
3042   && ! reg_mentioned_p (operands[3], operands[1])
3043   && ! reg_mentioned_p (operands[3], operands[2])"
3044  [(set (match_dup 0)
3045	(div:GPR (match_dup 1)
3046		 (match_dup 2)))
3047   (set (match_dup 3)
3048	(mult:GPR (match_dup 0)
3049		  (match_dup 2)))
3050   (set (match_dup 3)
3051	(minus:GPR (match_dup 1)
3052		   (match_dup 3)))])
3053
3054(define_peephole2
3055  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3056	(udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3057		  (match_operand:GPR 2 "gpc_reg_operand" "")))
3058   (set (match_operand:GPR 3 "gpc_reg_operand" "")
3059	(umod:GPR (match_dup 1)
3060		  (match_dup 2)))]
3061  "TARGET_MODULO
3062   && ! reg_mentioned_p (operands[0], operands[1])
3063   && ! reg_mentioned_p (operands[0], operands[2])
3064   && ! reg_mentioned_p (operands[3], operands[1])
3065   && ! reg_mentioned_p (operands[3], operands[2])"
3066  [(set (match_dup 0)
3067	(udiv:GPR (match_dup 1)
3068		  (match_dup 2)))
3069   (set (match_dup 3)
3070	(mult:GPR (match_dup 0)
3071		  (match_dup 2)))
3072   (set (match_dup 3)
3073	(minus:GPR (match_dup 1)
3074		   (match_dup 3)))])
3075
3076
3077;; Logical instructions
3078;; The logical instructions are mostly combined by using match_operator,
3079;; but the plain AND insns are somewhat different because there is no
3080;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3081;; those rotate-and-mask operations.  Thus, the AND insns come first.
3082
3083(define_expand "and<mode>3"
3084  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3085	(and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3086		 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3087  ""
3088{
3089  if (<MODE>mode == DImode && !TARGET_POWERPC64)
3090    {
3091      rs6000_split_logical (operands, AND, false, false, false);
3092      DONE;
3093    }
3094
3095  if (CONST_INT_P (operands[2]))
3096    {
3097      if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3098	{
3099	  emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3100	  DONE;
3101	}
3102
3103      if (logical_const_operand (operands[2], <MODE>mode)
3104	  && rs6000_gen_cell_microcode)
3105	{
3106	  emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3107	  DONE;
3108	}
3109
3110      if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3111	{
3112	  rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3113	  DONE;
3114	}
3115
3116      operands[2] = force_reg (<MODE>mode, operands[2]);
3117    }
3118})
3119
3120
3121(define_insn "and<mode>3_imm"
3122  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3123	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3124		 (match_operand:GPR 2 "logical_const_operand" "n")))
3125   (clobber (match_scratch:CC 3 "=x"))]
3126  "rs6000_gen_cell_microcode
3127   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3128  "andi%e2. %0,%1,%u2"
3129  [(set_attr "type" "logical")
3130   (set_attr "dot" "yes")])
3131
3132(define_insn_and_split "*and<mode>3_imm_dot"
3133  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3134	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3135			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3136		    (const_int 0)))
3137   (clobber (match_scratch:GPR 0 "=r,r"))
3138   (clobber (match_scratch:CC 4 "=X,x"))]
3139  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3140   && rs6000_gen_cell_microcode
3141   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3142  "@
3143   andi%e2. %0,%1,%u2
3144   #"
3145  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3146  [(parallel [(set (match_dup 0)
3147		   (and:GPR (match_dup 1)
3148			    (match_dup 2)))
3149	      (clobber (match_dup 4))])
3150   (set (match_dup 3)
3151	(compare:CC (match_dup 0)
3152		    (const_int 0)))]
3153  ""
3154  [(set_attr "type" "logical")
3155   (set_attr "dot" "yes")
3156   (set_attr "length" "4,8")])
3157
3158(define_insn_and_split "*and<mode>3_imm_dot2"
3159  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3160	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3161			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3162		    (const_int 0)))
3163   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3164	(and:GPR (match_dup 1)
3165		 (match_dup 2)))
3166   (clobber (match_scratch:CC 4 "=X,x"))]
3167  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3168   && rs6000_gen_cell_microcode
3169   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3170  "@
3171   andi%e2. %0,%1,%u2
3172   #"
3173  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3174  [(parallel [(set (match_dup 0)
3175		   (and:GPR (match_dup 1)
3176			    (match_dup 2)))
3177	      (clobber (match_dup 4))])
3178   (set (match_dup 3)
3179	(compare:CC (match_dup 0)
3180		    (const_int 0)))]
3181  ""
3182  [(set_attr "type" "logical")
3183   (set_attr "dot" "yes")
3184   (set_attr "length" "4,8")])
3185
3186(define_insn_and_split "*and<mode>3_imm_mask_dot"
3187  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3188	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3189			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3190		    (const_int 0)))
3191   (clobber (match_scratch:GPR 0 "=r,r"))]
3192  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3193   && rs6000_gen_cell_microcode"
3194  "@
3195   andi%e2. %0,%1,%u2
3196   #"
3197  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3198  [(set (match_dup 0)
3199	(and:GPR (match_dup 1)
3200		 (match_dup 2)))
3201   (set (match_dup 3)
3202	(compare:CC (match_dup 0)
3203		    (const_int 0)))]
3204  ""
3205  [(set_attr "type" "logical")
3206   (set_attr "dot" "yes")
3207   (set_attr "length" "4,8")])
3208
3209(define_insn_and_split "*and<mode>3_imm_mask_dot2"
3210  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3211	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3212			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3213		    (const_int 0)))
3214   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3215	(and:GPR (match_dup 1)
3216		 (match_dup 2)))]
3217  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3218   && rs6000_gen_cell_microcode"
3219  "@
3220   andi%e2. %0,%1,%u2
3221   #"
3222  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3223  [(set (match_dup 0)
3224	(and:GPR (match_dup 1)
3225		 (match_dup 2)))
3226   (set (match_dup 3)
3227	(compare:CC (match_dup 0)
3228		    (const_int 0)))]
3229  ""
3230  [(set_attr "type" "logical")
3231   (set_attr "dot" "yes")
3232   (set_attr "length" "4,8")])
3233
3234(define_insn "*and<mode>3_imm_dot_shifted"
3235  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3236	(compare:CC
3237	  (and:GPR
3238	    (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3239			  (match_operand:SI 4 "const_int_operand" "n"))
3240	    (match_operand:GPR 2 "const_int_operand" "n"))
3241	  (const_int 0)))
3242   (clobber (match_scratch:GPR 0 "=r"))]
3243  "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3244				   << INTVAL (operands[4])),
3245			  DImode)
3246   && (<MODE>mode == Pmode
3247       || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3248   && rs6000_gen_cell_microcode"
3249{
3250  operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3251  return "andi%e2. %0,%1,%u2";
3252}
3253  [(set_attr "type" "logical")
3254   (set_attr "dot" "yes")])
3255
3256
3257(define_insn "and<mode>3_mask"
3258  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3259	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3260		 (match_operand:GPR 2 "const_int_operand" "n")))]
3261  "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3262{
3263  return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3264}
3265  [(set_attr "type" "shift")])
3266
3267(define_insn_and_split "*and<mode>3_mask_dot"
3268  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3269	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3270			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3271		    (const_int 0)))
3272   (clobber (match_scratch:GPR 0 "=r,r"))]
3273  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3274   && rs6000_gen_cell_microcode
3275   && !logical_const_operand (operands[2], <MODE>mode)
3276   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3277{
3278  if (which_alternative == 0)
3279    return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3280  else
3281    return "#";
3282}
3283  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3284  [(set (match_dup 0)
3285	(and:GPR (match_dup 1)
3286		 (match_dup 2)))
3287   (set (match_dup 3)
3288	(compare:CC (match_dup 0)
3289		    (const_int 0)))]
3290  ""
3291  [(set_attr "type" "shift")
3292   (set_attr "dot" "yes")
3293   (set_attr "length" "4,8")])
3294
3295(define_insn_and_split "*and<mode>3_mask_dot2"
3296  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3297	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3298			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3299		    (const_int 0)))
3300   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3301	(and:GPR (match_dup 1)
3302		 (match_dup 2)))]
3303  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3304   && rs6000_gen_cell_microcode
3305   && !logical_const_operand (operands[2], <MODE>mode)
3306   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3307{
3308  if (which_alternative == 0)
3309    return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3310  else
3311    return "#";
3312}
3313  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3314  [(set (match_dup 0)
3315	(and:GPR (match_dup 1)
3316		 (match_dup 2)))
3317   (set (match_dup 3)
3318	(compare:CC (match_dup 0)
3319		    (const_int 0)))]
3320  ""
3321  [(set_attr "type" "shift")
3322   (set_attr "dot" "yes")
3323   (set_attr "length" "4,8")])
3324
3325
3326(define_insn_and_split "*and<mode>3_2insn"
3327  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3328	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3329		 (match_operand:GPR 2 "const_int_operand" "n")))]
3330  "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3331   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3332	|| (logical_const_operand (operands[2], <MODE>mode)
3333	    && rs6000_gen_cell_microcode))"
3334  "#"
3335  "&& 1"
3336  [(pc)]
3337{
3338  rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3339  DONE;
3340}
3341  [(set_attr "type" "shift")
3342   (set_attr "length" "8")])
3343
3344(define_insn_and_split "*and<mode>3_2insn_dot"
3345  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3346	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3347			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3348		    (const_int 0)))
3349   (clobber (match_scratch:GPR 0 "=r,r"))]
3350  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3351   && rs6000_gen_cell_microcode
3352   && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3353   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3354	|| (logical_const_operand (operands[2], <MODE>mode)
3355	    && rs6000_gen_cell_microcode))"
3356  "#"
3357  "&& reload_completed"
3358  [(pc)]
3359{
3360  rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3361  DONE;
3362}
3363  [(set_attr "type" "shift")
3364   (set_attr "dot" "yes")
3365   (set_attr "length" "8,12")])
3366
3367(define_insn_and_split "*and<mode>3_2insn_dot2"
3368  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3369	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3370			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3371		    (const_int 0)))
3372   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3373	(and:GPR (match_dup 1)
3374		 (match_dup 2)))]
3375  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3376   && rs6000_gen_cell_microcode
3377   && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3378   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3379	|| (logical_const_operand (operands[2], <MODE>mode)
3380	    && rs6000_gen_cell_microcode))"
3381  "#"
3382  "&& reload_completed"
3383  [(pc)]
3384{
3385  rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3386  DONE;
3387}
3388  [(set_attr "type" "shift")
3389   (set_attr "dot" "yes")
3390   (set_attr "length" "8,12")])
3391
3392
3393(define_expand "<code><mode>3"
3394  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3395	(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3396		    (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3397  ""
3398{
3399  if (<MODE>mode == DImode && !TARGET_POWERPC64)
3400    {
3401      rs6000_split_logical (operands, <CODE>, false, false, false);
3402      DONE;
3403    }
3404
3405  if (non_logical_cint_operand (operands[2], <MODE>mode))
3406    {
3407      rtx tmp = ((!can_create_pseudo_p ()
3408		  || rtx_equal_p (operands[0], operands[1]))
3409		 ? operands[0] : gen_reg_rtx (<MODE>mode));
3410
3411      HOST_WIDE_INT value = INTVAL (operands[2]);
3412      HOST_WIDE_INT lo = value & 0xffff;
3413      HOST_WIDE_INT hi = value - lo;
3414
3415      emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3416      emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3417      DONE;
3418    }
3419
3420  if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3421    operands[2] = force_reg (<MODE>mode, operands[2]);
3422})
3423
3424(define_split
3425  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3426	(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3427		    (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3428  ""
3429  [(set (match_dup 3)
3430	(iorxor:GPR (match_dup 1)
3431		    (match_dup 4)))
3432   (set (match_dup 0)
3433	(iorxor:GPR (match_dup 3)
3434		    (match_dup 5)))]
3435{
3436  operands[3] = ((!can_create_pseudo_p ()
3437		  || rtx_equal_p (operands[0], operands[1]))
3438		 ? operands[0] : gen_reg_rtx (<MODE>mode));
3439
3440  HOST_WIDE_INT value = INTVAL (operands[2]);
3441  HOST_WIDE_INT lo = value & 0xffff;
3442  HOST_WIDE_INT hi = value - lo;
3443
3444  operands[4] = GEN_INT (hi);
3445  operands[5] = GEN_INT (lo);
3446})
3447
3448(define_insn "*bool<mode>3_imm"
3449  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3450	(match_operator:GPR 3 "boolean_or_operator"
3451	 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3452	  (match_operand:GPR 2 "logical_const_operand" "n")]))]
3453  ""
3454  "%q3i%e2 %0,%1,%u2"
3455  [(set_attr "type" "logical")])
3456
3457(define_insn "*bool<mode>3"
3458  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3459	(match_operator:GPR 3 "boolean_operator"
3460	 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3461	  (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3462  ""
3463  "%q3 %0,%1,%2"
3464  [(set_attr "type" "logical")])
3465
3466(define_insn_and_split "*bool<mode>3_dot"
3467  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3468	(compare:CC (match_operator:GPR 3 "boolean_operator"
3469	 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3470	  (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3471	 (const_int 0)))
3472   (clobber (match_scratch:GPR 0 "=r,r"))]
3473  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3474  "@
3475   %q3. %0,%1,%2
3476   #"
3477  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3478  [(set (match_dup 0)
3479	(match_dup 3))
3480   (set (match_dup 4)
3481	(compare:CC (match_dup 0)
3482		    (const_int 0)))]
3483  ""
3484  [(set_attr "type" "logical")
3485   (set_attr "dot" "yes")
3486   (set_attr "length" "4,8")])
3487
3488(define_insn_and_split "*bool<mode>3_dot2"
3489  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3490	(compare:CC (match_operator:GPR 3 "boolean_operator"
3491	 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3492	  (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3493	 (const_int 0)))
3494   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3495	(match_dup 3))]
3496  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3497  "@
3498   %q3. %0,%1,%2
3499   #"
3500  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3501  [(set (match_dup 0)
3502	(match_dup 3))
3503   (set (match_dup 4)
3504	(compare:CC (match_dup 0)
3505		    (const_int 0)))]
3506  ""
3507  [(set_attr "type" "logical")
3508   (set_attr "dot" "yes")
3509   (set_attr "length" "4,8")])
3510
3511
3512(define_insn "*boolc<mode>3"
3513  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3514	(match_operator:GPR 3 "boolean_operator"
3515	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3516	  (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3517  ""
3518  "%q3 %0,%1,%2"
3519  [(set_attr "type" "logical")])
3520
3521(define_insn_and_split "*boolc<mode>3_dot"
3522  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3523	(compare:CC (match_operator:GPR 3 "boolean_operator"
3524	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3525	  (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3526	 (const_int 0)))
3527   (clobber (match_scratch:GPR 0 "=r,r"))]
3528  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3529  "@
3530   %q3. %0,%1,%2
3531   #"
3532  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3533  [(set (match_dup 0)
3534	(match_dup 3))
3535   (set (match_dup 4)
3536	(compare:CC (match_dup 0)
3537		    (const_int 0)))]
3538  ""
3539  [(set_attr "type" "logical")
3540   (set_attr "dot" "yes")
3541   (set_attr "length" "4,8")])
3542
3543(define_insn_and_split "*boolc<mode>3_dot2"
3544  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3545	(compare:CC (match_operator:GPR 3 "boolean_operator"
3546	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3547	  (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3548	 (const_int 0)))
3549   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3550	(match_dup 3))]
3551  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3552  "@
3553   %q3. %0,%1,%2
3554   #"
3555  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3556  [(set (match_dup 0)
3557	(match_dup 3))
3558   (set (match_dup 4)
3559	(compare:CC (match_dup 0)
3560		    (const_int 0)))]
3561  ""
3562  [(set_attr "type" "logical")
3563   (set_attr "dot" "yes")
3564   (set_attr "length" "4,8")])
3565
3566
3567(define_insn "*boolcc<mode>3"
3568  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3569	(match_operator:GPR 3 "boolean_operator"
3570	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3571	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3572  ""
3573  "%q3 %0,%1,%2"
3574  [(set_attr "type" "logical")])
3575
3576(define_insn_and_split "*boolcc<mode>3_dot"
3577  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3578	(compare:CC (match_operator:GPR 3 "boolean_operator"
3579	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3580	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3581	 (const_int 0)))
3582   (clobber (match_scratch:GPR 0 "=r,r"))]
3583  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3584  "@
3585   %q3. %0,%1,%2
3586   #"
3587  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3588  [(set (match_dup 0)
3589	(match_dup 3))
3590   (set (match_dup 4)
3591	(compare:CC (match_dup 0)
3592		    (const_int 0)))]
3593  ""
3594  [(set_attr "type" "logical")
3595   (set_attr "dot" "yes")
3596   (set_attr "length" "4,8")])
3597
3598(define_insn_and_split "*boolcc<mode>3_dot2"
3599  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3600	(compare:CC (match_operator:GPR 3 "boolean_operator"
3601	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3602	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3603	 (const_int 0)))
3604   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3605	(match_dup 3))]
3606  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3607  "@
3608   %q3. %0,%1,%2
3609   #"
3610  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3611  [(set (match_dup 0)
3612	(match_dup 3))
3613   (set (match_dup 4)
3614	(compare:CC (match_dup 0)
3615		    (const_int 0)))]
3616  ""
3617  [(set_attr "type" "logical")
3618   (set_attr "dot" "yes")
3619   (set_attr "length" "4,8")])
3620
3621
3622;; TODO: Should have dots of this as well.
3623(define_insn "*eqv<mode>3"
3624  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3625	(not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3626			  (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3627  ""
3628  "eqv %0,%1,%2"
3629  [(set_attr "type" "logical")])
3630
3631;; Rotate-and-mask and insert.
3632
3633(define_insn "*rotl<mode>3_mask"
3634  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3635	(and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3636		  [(match_operand:GPR 1 "gpc_reg_operand" "r")
3637		   (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3638		 (match_operand:GPR 3 "const_int_operand" "n")))]
3639  "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3640{
3641  return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3642}
3643  [(set_attr "type" "shift")
3644   (set_attr "maybe_var_shift" "yes")])
3645
3646(define_insn_and_split "*rotl<mode>3_mask_dot"
3647  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3648	(compare:CC
3649	  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3650		    [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3651		     (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3652		   (match_operand:GPR 3 "const_int_operand" "n,n"))
3653	  (const_int 0)))
3654   (clobber (match_scratch:GPR 0 "=r,r"))]
3655  "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3656   && rs6000_gen_cell_microcode
3657   && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3658{
3659  if (which_alternative == 0)
3660    return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3661  else
3662    return "#";
3663}
3664  "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3665  [(set (match_dup 0)
3666	(and:GPR (match_dup 4)
3667		 (match_dup 3)))
3668   (set (match_dup 5)
3669	(compare:CC (match_dup 0)
3670		    (const_int 0)))]
3671  ""
3672  [(set_attr "type" "shift")
3673   (set_attr "maybe_var_shift" "yes")
3674   (set_attr "dot" "yes")
3675   (set_attr "length" "4,8")])
3676
3677(define_insn_and_split "*rotl<mode>3_mask_dot2"
3678  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3679	(compare:CC
3680	  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3681		    [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3682		     (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3683		   (match_operand:GPR 3 "const_int_operand" "n,n"))
3684	  (const_int 0)))
3685   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3686	(and:GPR (match_dup 4)
3687		 (match_dup 3)))]
3688  "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3689   && rs6000_gen_cell_microcode
3690   && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3691{
3692  if (which_alternative == 0)
3693    return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3694  else
3695    return "#";
3696}
3697  "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3698  [(set (match_dup 0)
3699	(and:GPR (match_dup 4)
3700		 (match_dup 3)))
3701   (set (match_dup 5)
3702	(compare:CC (match_dup 0)
3703		    (const_int 0)))]
3704  ""
3705  [(set_attr "type" "shift")
3706   (set_attr "maybe_var_shift" "yes")
3707   (set_attr "dot" "yes")
3708   (set_attr "length" "4,8")])
3709
3710; Special case for less-than-0.  We can do it with just one machine
3711; instruction, but the generic optimizers do not realise it is cheap.
3712(define_insn "*lt0_disi"
3713  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3714	(lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3715	       (const_int 0)))]
3716  "TARGET_POWERPC64"
3717  "rlwinm %0,%1,1,31,31"
3718  [(set_attr "type" "shift")])
3719
3720
3721
3722; Two forms for insert (the two arms of the IOR are not canonicalized,
3723; both are an AND so are the same precedence).
3724(define_insn "*rotl<mode>3_insert"
3725  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3726	(ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3727			   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3728			    (match_operand:SI 2 "const_int_operand" "n")])
3729			  (match_operand:GPR 3 "const_int_operand" "n"))
3730		 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3731			  (match_operand:GPR 6 "const_int_operand" "n"))))]
3732  "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3733   && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3734{
3735  return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3736}
3737  [(set_attr "type" "insert")])
3738; FIXME: this needs an attr "size", so that the scheduler can see the
3739; difference between rlwimi and rldimi.  We also might want dot forms,
3740; but not for rlwimi on POWER4 and similar processors.
3741
3742(define_insn "*rotl<mode>3_insert_2"
3743  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3744	(ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3745			  (match_operand:GPR 6 "const_int_operand" "n"))
3746		 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3747			   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3748			    (match_operand:SI 2 "const_int_operand" "n")])
3749			  (match_operand:GPR 3 "const_int_operand" "n"))))]
3750  "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3751   && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3752{
3753  return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3754}
3755  [(set_attr "type" "insert")])
3756
3757; There are also some forms without one of the ANDs.
3758(define_insn "*rotl<mode>3_insert_3"
3759  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3760	(ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3761			  (match_operand:GPR 4 "const_int_operand" "n"))
3762		 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3763			     (match_operand:SI 2 "const_int_operand" "n"))))]
3764  "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3765{
3766  if (<MODE>mode == SImode)
3767    return "rlwimi %0,%1,%h2,0,31-%h2";
3768  else
3769    return "rldimi %0,%1,%H2,0";
3770}
3771  [(set_attr "type" "insert")])
3772
3773(define_insn "*rotl<mode>3_insert_4"
3774  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3775	(ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3776			  (match_operand:GPR 4 "const_int_operand" "n"))
3777		 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3778			       (match_operand:SI 2 "const_int_operand" "n"))))]
3779  "<MODE>mode == SImode &&
3780   GET_MODE_PRECISION (<MODE>mode)
3781   == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3782{
3783  operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3784			 - INTVAL (operands[2]));
3785  if (<MODE>mode == SImode)
3786    return "rlwimi %0,%1,%h2,32-%h2,31";
3787  else
3788    return "rldimi %0,%1,%H2,64-%H2";
3789}
3790  [(set_attr "type" "insert")])
3791
3792
3793; This handles the important case of multiple-precision shifts.  There is
3794; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3795(define_split
3796  [(set (match_operand:GPR 0 "gpc_reg_operand")
3797	(ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3798			     (match_operand:SI 3 "const_int_operand"))
3799		 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3800			       (match_operand:SI 4 "const_int_operand"))))]
3801  "can_create_pseudo_p ()
3802   && INTVAL (operands[3]) + INTVAL (operands[4])
3803      >= GET_MODE_PRECISION (<MODE>mode)"
3804  [(set (match_dup 5)
3805	(lshiftrt:GPR (match_dup 2)
3806		      (match_dup 4)))
3807   (set (match_dup 0)
3808	(ior:GPR (and:GPR (match_dup 5)
3809			  (match_dup 6))
3810		 (ashift:GPR (match_dup 1)
3811			     (match_dup 3))))]
3812{
3813  unsigned HOST_WIDE_INT mask = 1;
3814  mask = (mask << INTVAL (operands[3])) - 1;
3815  operands[5] = gen_reg_rtx (<MODE>mode);
3816  operands[6] = GEN_INT (mask);
3817})
3818
3819(define_split
3820  [(set (match_operand:GPR 0 "gpc_reg_operand")
3821	(ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3822			       (match_operand:SI 4 "const_int_operand"))
3823		 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3824			     (match_operand:SI 3 "const_int_operand"))))]
3825  "can_create_pseudo_p ()
3826   && INTVAL (operands[3]) + INTVAL (operands[4])
3827      >= GET_MODE_PRECISION (<MODE>mode)"
3828  [(set (match_dup 5)
3829	(lshiftrt:GPR (match_dup 2)
3830		      (match_dup 4)))
3831   (set (match_dup 0)
3832	(ior:GPR (and:GPR (match_dup 5)
3833			  (match_dup 6))
3834		 (ashift:GPR (match_dup 1)
3835			     (match_dup 3))))]
3836{
3837  unsigned HOST_WIDE_INT mask = 1;
3838  mask = (mask << INTVAL (operands[3])) - 1;
3839  operands[5] = gen_reg_rtx (<MODE>mode);
3840  operands[6] = GEN_INT (mask);
3841})
3842
3843
3844; Another important case is setting some bits to 1; we can do that with
3845; an insert instruction, in many cases.
3846(define_insn_and_split "*ior<mode>_mask"
3847  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3848	(ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3849		 (match_operand:GPR 2 "const_int_operand" "n")))
3850   (clobber (match_scratch:GPR 3 "=r"))]
3851  "!logical_const_operand (operands[2], <MODE>mode)
3852   && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3853  "#"
3854  "&& 1"
3855  [(set (match_dup 3)
3856	(const_int -1))
3857   (set (match_dup 0)
3858	(ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3859				      (match_dup 4))
3860			  (match_dup 2))
3861		 (and:GPR (match_dup 1)
3862			  (match_dup 5))))]
3863{
3864  int nb, ne;
3865  rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3866  if (GET_CODE (operands[3]) == SCRATCH)
3867    operands[3] = gen_reg_rtx (<MODE>mode);
3868  operands[4] = GEN_INT (ne);
3869  operands[5] = GEN_INT (~UINTVAL (operands[2]));
3870}
3871  [(set_attr "type" "two")
3872   (set_attr "length" "8")])
3873
3874
3875;; Now the simple shifts.
3876
3877(define_insn "rotl<mode>3"
3878  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3879	(rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3880		    (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3881  ""
3882  "rotl<wd>%I2 %0,%1,%<hH>2"
3883  [(set_attr "type" "shift")
3884   (set_attr "maybe_var_shift" "yes")])
3885
3886(define_insn "*rotlsi3_64"
3887  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3888	(zero_extend:DI
3889	    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3890		       (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3891  "TARGET_POWERPC64"
3892  "rotlw%I2 %0,%1,%h2"
3893  [(set_attr "type" "shift")
3894   (set_attr "maybe_var_shift" "yes")])
3895
3896(define_insn_and_split "*rotl<mode>3_dot"
3897  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3898	(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3899				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3900		    (const_int 0)))
3901   (clobber (match_scratch:GPR 0 "=r,r"))]
3902  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3903  "@
3904   rotl<wd>%I2. %0,%1,%<hH>2
3905   #"
3906  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3907  [(set (match_dup 0)
3908	(rotate:GPR (match_dup 1)
3909		    (match_dup 2)))
3910   (set (match_dup 3)
3911	(compare:CC (match_dup 0)
3912		    (const_int 0)))]
3913  ""
3914  [(set_attr "type" "shift")
3915   (set_attr "maybe_var_shift" "yes")
3916   (set_attr "dot" "yes")
3917   (set_attr "length" "4,8")])
3918
3919(define_insn_and_split "*rotl<mode>3_dot2"
3920  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3921	(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3922				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3923		    (const_int 0)))
3924   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3925	(rotate:GPR (match_dup 1)
3926		    (match_dup 2)))]
3927  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3928  "@
3929   rotl<wd>%I2. %0,%1,%<hH>2
3930   #"
3931  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3932  [(set (match_dup 0)
3933	(rotate:GPR (match_dup 1)
3934		    (match_dup 2)))
3935   (set (match_dup 3)
3936	(compare:CC (match_dup 0)
3937		    (const_int 0)))]
3938  ""
3939  [(set_attr "type" "shift")
3940   (set_attr "maybe_var_shift" "yes")
3941   (set_attr "dot" "yes")
3942   (set_attr "length" "4,8")])
3943
3944
3945(define_insn "ashl<mode>3"
3946  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3947	(ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3948		    (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3949  ""
3950  "sl<wd>%I2 %0,%1,%<hH>2"
3951  [(set_attr "type" "shift")
3952   (set_attr "maybe_var_shift" "yes")])
3953
3954(define_insn "*ashlsi3_64"
3955  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3956	(zero_extend:DI
3957	    (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3958		       (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3959  "TARGET_POWERPC64"
3960  "slw%I2 %0,%1,%h2"
3961  [(set_attr "type" "shift")
3962   (set_attr "maybe_var_shift" "yes")])
3963
3964(define_insn_and_split "*ashl<mode>3_dot"
3965  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3966	(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3967				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3968		    (const_int 0)))
3969   (clobber (match_scratch:GPR 0 "=r,r"))]
3970  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3971  "@
3972   sl<wd>%I2. %0,%1,%<hH>2
3973   #"
3974  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3975  [(set (match_dup 0)
3976	(ashift:GPR (match_dup 1)
3977		    (match_dup 2)))
3978   (set (match_dup 3)
3979	(compare:CC (match_dup 0)
3980		    (const_int 0)))]
3981  ""
3982  [(set_attr "type" "shift")
3983   (set_attr "maybe_var_shift" "yes")
3984   (set_attr "dot" "yes")
3985   (set_attr "length" "4,8")])
3986
3987(define_insn_and_split "*ashl<mode>3_dot2"
3988  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3989	(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3990				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3991		    (const_int 0)))
3992   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3993	(ashift:GPR (match_dup 1)
3994		    (match_dup 2)))]
3995  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3996  "@
3997   sl<wd>%I2. %0,%1,%<hH>2
3998   #"
3999  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4000  [(set (match_dup 0)
4001	(ashift:GPR (match_dup 1)
4002		    (match_dup 2)))
4003   (set (match_dup 3)
4004	(compare:CC (match_dup 0)
4005		    (const_int 0)))]
4006  ""
4007  [(set_attr "type" "shift")
4008   (set_attr "maybe_var_shift" "yes")
4009   (set_attr "dot" "yes")
4010   (set_attr "length" "4,8")])
4011
4012;; Pretend we have a memory form of extswsli until register allocation is done
4013;; so that we use LWZ to load the value from memory, instead of LWA.
4014(define_insn_and_split "ashdi3_extswsli"
4015  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4016	(ashift:DI
4017	 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4018	 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4019  "TARGET_EXTSWSLI"
4020  "@
4021   extswsli %0,%1,%2
4022   #"
4023  "&& reload_completed && MEM_P (operands[1])"
4024  [(set (match_dup 3)
4025	(match_dup 1))
4026   (set (match_dup 0)
4027	(ashift:DI (sign_extend:DI (match_dup 3))
4028		   (match_dup 2)))]
4029{
4030  operands[3] = gen_lowpart (SImode, operands[0]);
4031}
4032  [(set_attr "type" "shift")
4033   (set_attr "maybe_var_shift" "no")])
4034
4035
4036(define_insn_and_split "ashdi3_extswsli_dot"
4037  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4038	(compare:CC
4039	 (ashift:DI
4040	  (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4041	  (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4042	 (const_int 0)))
4043   (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4044  "TARGET_EXTSWSLI"
4045  "@
4046   extswsli. %0,%1,%2
4047   #
4048   #
4049   #"
4050  "&& reload_completed
4051   && (cc_reg_not_cr0_operand (operands[3], CCmode)
4052       || memory_operand (operands[1], SImode))"
4053  [(pc)]
4054{
4055  rtx dest = operands[0];
4056  rtx src = operands[1];
4057  rtx shift = operands[2];
4058  rtx cr = operands[3];
4059  rtx src2;
4060
4061  if (!MEM_P (src))
4062    src2 = src;
4063  else
4064    {
4065      src2 = gen_lowpart (SImode, dest);
4066      emit_move_insn (src2, src);
4067    }
4068
4069  if (REGNO (cr) == CR0_REGNO)
4070    {
4071      emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4072      DONE;
4073    }
4074
4075  emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4076  emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4077  DONE;
4078}
4079  [(set_attr "type" "shift")
4080   (set_attr "maybe_var_shift" "no")
4081   (set_attr "dot" "yes")
4082   (set_attr "length" "4,8,8,12")])
4083
4084(define_insn_and_split "ashdi3_extswsli_dot2"
4085  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4086	(compare:CC
4087	 (ashift:DI
4088	  (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4089	  (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4090	 (const_int 0)))
4091   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4092	(ashift:DI (sign_extend:DI (match_dup 1))
4093		   (match_dup 2)))]
4094  "TARGET_EXTSWSLI"
4095  "@
4096   extswsli. %0,%1,%2
4097   #
4098   #
4099   #"
4100  "&& reload_completed
4101   && (cc_reg_not_cr0_operand (operands[3], CCmode)
4102       || memory_operand (operands[1], SImode))"
4103  [(pc)]
4104{
4105  rtx dest = operands[0];
4106  rtx src = operands[1];
4107  rtx shift = operands[2];
4108  rtx cr = operands[3];
4109  rtx src2;
4110
4111  if (!MEM_P (src))
4112    src2 = src;
4113  else
4114    {
4115      src2 = gen_lowpart (SImode, dest);
4116      emit_move_insn (src2, src);
4117    }
4118
4119  if (REGNO (cr) == CR0_REGNO)
4120    {
4121      emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4122      DONE;
4123    }
4124
4125  emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4126  emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4127  DONE;
4128}
4129  [(set_attr "type" "shift")
4130   (set_attr "maybe_var_shift" "no")
4131   (set_attr "dot" "yes")
4132   (set_attr "length" "4,8,8,12")])
4133
4134(define_insn "lshr<mode>3"
4135  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4136	(lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4137		      (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4138  ""
4139  "sr<wd>%I2 %0,%1,%<hH>2"
4140  [(set_attr "type" "shift")
4141   (set_attr "maybe_var_shift" "yes")])
4142
4143(define_insn "*lshrsi3_64"
4144  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4145	(zero_extend:DI
4146	    (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4147			 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4148  "TARGET_POWERPC64"
4149  "srw%I2 %0,%1,%h2"
4150  [(set_attr "type" "shift")
4151   (set_attr "maybe_var_shift" "yes")])
4152
4153(define_insn_and_split "*lshr<mode>3_dot"
4154  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4155	(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4156				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4157		    (const_int 0)))
4158   (clobber (match_scratch:GPR 0 "=r,r"))]
4159  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4160  "@
4161   sr<wd>%I2. %0,%1,%<hH>2
4162   #"
4163  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4164  [(set (match_dup 0)
4165	(lshiftrt:GPR (match_dup 1)
4166		      (match_dup 2)))
4167   (set (match_dup 3)
4168	(compare:CC (match_dup 0)
4169		    (const_int 0)))]
4170  ""
4171  [(set_attr "type" "shift")
4172   (set_attr "maybe_var_shift" "yes")
4173   (set_attr "dot" "yes")
4174   (set_attr "length" "4,8")])
4175
4176(define_insn_and_split "*lshr<mode>3_dot2"
4177  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4178	(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4179				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4180		    (const_int 0)))
4181   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4182	(lshiftrt:GPR (match_dup 1)
4183		      (match_dup 2)))]
4184  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4185  "@
4186   sr<wd>%I2. %0,%1,%<hH>2
4187   #"
4188  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4189  [(set (match_dup 0)
4190	(lshiftrt:GPR (match_dup 1)
4191		      (match_dup 2)))
4192   (set (match_dup 3)
4193	(compare:CC (match_dup 0)
4194		    (const_int 0)))]
4195  ""
4196  [(set_attr "type" "shift")
4197   (set_attr "maybe_var_shift" "yes")
4198   (set_attr "dot" "yes")
4199   (set_attr "length" "4,8")])
4200
4201
4202(define_insn "ashr<mode>3"
4203  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4204	(ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4205		      (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4206   (clobber (reg:GPR CA_REGNO))]
4207  ""
4208  "sra<wd>%I2 %0,%1,%<hH>2"
4209  [(set_attr "type" "shift")
4210   (set_attr "maybe_var_shift" "yes")])
4211
4212(define_insn "*ashrsi3_64"
4213  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4214	(sign_extend:DI
4215	    (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4216			 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4217   (clobber (reg:SI CA_REGNO))]
4218  "TARGET_POWERPC64"
4219  "sraw%I2 %0,%1,%h2"
4220  [(set_attr "type" "shift")
4221   (set_attr "maybe_var_shift" "yes")])
4222
4223(define_insn_and_split "*ashr<mode>3_dot"
4224  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4225	(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4226				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4227		    (const_int 0)))
4228   (clobber (match_scratch:GPR 0 "=r,r"))
4229   (clobber (reg:GPR CA_REGNO))]
4230  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4231  "@
4232   sra<wd>%I2. %0,%1,%<hH>2
4233   #"
4234  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4235  [(parallel [(set (match_dup 0)
4236		   (ashiftrt:GPR (match_dup 1)
4237				 (match_dup 2)))
4238	      (clobber (reg:GPR CA_REGNO))])
4239   (set (match_dup 3)
4240	(compare:CC (match_dup 0)
4241		    (const_int 0)))]
4242  ""
4243  [(set_attr "type" "shift")
4244   (set_attr "maybe_var_shift" "yes")
4245   (set_attr "dot" "yes")
4246   (set_attr "length" "4,8")])
4247
4248(define_insn_and_split "*ashr<mode>3_dot2"
4249  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4250	(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4251				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4252		    (const_int 0)))
4253   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4254	(ashiftrt:GPR (match_dup 1)
4255		      (match_dup 2)))
4256   (clobber (reg:GPR CA_REGNO))]
4257  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4258  "@
4259   sra<wd>%I2. %0,%1,%<hH>2
4260   #"
4261  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4262  [(parallel [(set (match_dup 0)
4263		   (ashiftrt:GPR (match_dup 1)
4264				 (match_dup 2)))
4265	      (clobber (reg:GPR CA_REGNO))])
4266   (set (match_dup 3)
4267	(compare:CC (match_dup 0)
4268		    (const_int 0)))]
4269  ""
4270  [(set_attr "type" "shift")
4271   (set_attr "maybe_var_shift" "yes")
4272   (set_attr "dot" "yes")
4273   (set_attr "length" "4,8")])
4274
4275;; Builtins to replace a division to generate FRE reciprocal estimate
4276;; instructions and the necessary fixup instructions
4277(define_expand "recip<mode>3"
4278  [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4279   (match_operand:RECIPF 1 "gpc_reg_operand" "")
4280   (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4281  "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4282{
4283   rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4284   DONE;
4285})
4286
4287;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4288;; hardware division.  This is only done before register allocation and with
4289;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4290(define_split
4291  [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4292	(div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4293		    (match_operand 2 "gpc_reg_operand" "")))]
4294  "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4295   && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4296   && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4297  [(const_int 0)]
4298{
4299  rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4300  DONE;
4301})
4302
4303;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4304;; appropriate fixup.
4305(define_expand "rsqrt<mode>2"
4306  [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4307   (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4308  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4309{
4310  rs6000_emit_swsqrt (operands[0], operands[1], 1);
4311  DONE;
4312})
4313
4314;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4315;; modes here, and also add in conditional vsx/power8-vector support to access
4316;; values in the traditional Altivec registers if the appropriate
4317;; -mupper-regs-{df,sf} option is enabled.
4318
4319(define_expand "abs<mode>2"
4320  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4321	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4322  "TARGET_<MODE>_INSN"
4323  "")
4324
4325(define_insn "*abs<mode>2_fpr"
4326  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4327	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4328  "TARGET_<MODE>_FPR"
4329  "@
4330   fabs %0,%1
4331   xsabsdp %x0,%x1"
4332  [(set_attr "type" "fpsimple")
4333   (set_attr "fp_type" "fp_addsub_<Fs>")])
4334
4335(define_insn "*nabs<mode>2_fpr"
4336  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4337	(neg:SFDF
4338	 (abs:SFDF
4339	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4340  "TARGET_<MODE>_FPR"
4341  "@
4342   fnabs %0,%1
4343   xsnabsdp %x0,%x1"
4344  [(set_attr "type" "fpsimple")
4345   (set_attr "fp_type" "fp_addsub_<Fs>")])
4346
4347(define_expand "neg<mode>2"
4348  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4349	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4350  "TARGET_<MODE>_INSN"
4351  "")
4352
4353(define_insn "*neg<mode>2_fpr"
4354  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4355	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4356  "TARGET_<MODE>_FPR"
4357  "@
4358   fneg %0,%1
4359   xsnegdp %x0,%x1"
4360  [(set_attr "type" "fpsimple")
4361   (set_attr "fp_type" "fp_addsub_<Fs>")])
4362
4363(define_expand "add<mode>3"
4364  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4365	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4366		   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4367  "TARGET_<MODE>_INSN"
4368  "")
4369
4370(define_insn "*add<mode>3_fpr"
4371  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4372	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4373		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4374  "TARGET_<MODE>_FPR"
4375  "@
4376   fadd<Ftrad> %0,%1,%2
4377   xsadd<Fvsx> %x0,%x1,%x2"
4378  [(set_attr "type" "fp")
4379   (set_attr "fp_type" "fp_addsub_<Fs>")])
4380
4381(define_expand "sub<mode>3"
4382  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4383	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4384		    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4385  "TARGET_<MODE>_INSN"
4386  "")
4387
4388(define_insn "*sub<mode>3_fpr"
4389  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4390	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4391		    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4392  "TARGET_<MODE>_FPR"
4393  "@
4394   fsub<Ftrad> %0,%1,%2
4395   xssub<Fvsx> %x0,%x1,%x2"
4396  [(set_attr "type" "fp")
4397   (set_attr "fp_type" "fp_addsub_<Fs>")])
4398
4399(define_expand "mul<mode>3"
4400  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4401	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4402		   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4403  "TARGET_<MODE>_INSN"
4404  "")
4405
4406(define_insn "*mul<mode>3_fpr"
4407  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4408	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4409		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4410  "TARGET_<MODE>_FPR"
4411  "@
4412   fmul<Ftrad> %0,%1,%2
4413   xsmul<Fvsx> %x0,%x1,%x2"
4414  [(set_attr "type" "dmul")
4415   (set_attr "fp_type" "fp_mul_<Fs>")])
4416
4417(define_expand "div<mode>3"
4418  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4419	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4420		  (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4421  "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4422  "")
4423
4424(define_insn "*div<mode>3_fpr"
4425  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4426	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4427		  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4428  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4429  "@
4430   fdiv<Ftrad> %0,%1,%2
4431   xsdiv<Fvsx> %x0,%x1,%x2"
4432  [(set_attr "type" "<Fs>div")
4433   (set_attr "fp_type" "fp_div_<Fs>")])
4434
4435(define_insn "*sqrt<mode>2_internal"
4436  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4437	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4438  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4439   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4440  "@
4441   fsqrt<Ftrad> %0,%1
4442   xssqrt<Fvsx> %x0,%x1"
4443  [(set_attr "type" "<Fs>sqrt")
4444   (set_attr "fp_type" "fp_sqrt_<Fs>")])
4445
4446(define_expand "sqrt<mode>2"
4447  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4448	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4449  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4450   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4451{
4452  if (<MODE>mode == SFmode
4453      && TARGET_RECIP_PRECISION
4454      && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4455      && !optimize_function_for_size_p (cfun)
4456      && flag_finite_math_only && !flag_trapping_math
4457      && flag_unsafe_math_optimizations)
4458    {
4459      rs6000_emit_swsqrt (operands[0], operands[1], 0);
4460      DONE;
4461    }
4462})
4463
4464;; Floating point reciprocal approximation
4465(define_insn "fre<Fs>"
4466  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4467	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4468		     UNSPEC_FRES))]
4469  "TARGET_<FFRE>"
4470  "@
4471   fre<Ftrad> %0,%1
4472   xsre<Fvsx> %x0,%x1"
4473  [(set_attr "type" "fp")])
4474
4475(define_insn "*rsqrt<mode>2"
4476  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4477	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4478		     UNSPEC_RSQRT))]
4479  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4480  "@
4481   frsqrte<Ftrad> %0,%1
4482   xsrsqrte<Fvsx> %x0,%x1"
4483  [(set_attr "type" "fp")])
4484
4485;; Floating point comparisons
4486(define_insn "*cmp<mode>_fpr"
4487  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4488	(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4489		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4490  "TARGET_<MODE>_FPR"
4491  "@
4492   fcmpu %0,%1,%2
4493   xscmpudp %0,%x1,%x2"
4494  [(set_attr "type" "fpcompare")])
4495
4496;; Floating point conversions
4497(define_expand "extendsfdf2"
4498  [(set (match_operand:DF 0 "gpc_reg_operand" "")
4499	(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4500  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4501  "")
4502
4503(define_insn_and_split "*extendsfdf2_fpr"
4504  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4505	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4506  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4507  "@
4508   #
4509   fmr %0,%1
4510   lfs%U1%X1 %0,%1
4511   #
4512   xscpsgndp %x0,%x1,%x1
4513   lxsspx %x0,%y1
4514   lxssp %0,%1"
4515  "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4516  [(const_int 0)]
4517{
4518  emit_note (NOTE_INSN_DELETED);
4519  DONE;
4520}
4521  [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4522
4523(define_expand "truncdfsf2"
4524  [(set (match_operand:SF 0 "gpc_reg_operand" "")
4525	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4526  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4527  "")
4528
4529(define_insn "*truncdfsf2_fpr"
4530  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4531	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4532  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4533  "@
4534   frsp %0,%1
4535   xsrsp %x0,%x1"
4536  [(set_attr "type" "fp")])
4537
4538;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4539;; builtins.c and optabs.c that are not correct for IBM long double
4540;; when little-endian.
4541(define_expand "signbit<mode>2"
4542  [(set (match_dup 2)
4543	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4544   (set (match_dup 3)
4545   	(subreg:DI (match_dup 2) 0))
4546   (set (match_dup 4)
4547   	(match_dup 5))
4548   (set (match_operand:SI 0 "gpc_reg_operand" "")
4549  	(match_dup 6))]
4550  "TARGET_HARD_FLOAT
4551   && (TARGET_FPRS || TARGET_E500_DOUBLE)
4552   && (!FLOAT128_IEEE_P (<MODE>mode)
4553       || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4554{
4555  if (FLOAT128_IEEE_P (<MODE>mode))
4556    {
4557      rtx dest = operands[0];
4558      rtx src = operands[1];
4559      rtx tmp = gen_reg_rtx (DImode);
4560      rtx dest_di = gen_lowpart (DImode, dest);
4561
4562      if (<MODE>mode == KFmode)
4563	emit_insn (gen_signbitkf2_dm (tmp, src));
4564      else if (<MODE>mode == TFmode)
4565	emit_insn (gen_signbittf2_dm (tmp, src));
4566      else
4567	gcc_unreachable ();
4568
4569      emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4570      DONE;
4571    }
4572  operands[2] = gen_reg_rtx (DFmode);
4573  operands[3] = gen_reg_rtx (DImode);
4574  if (TARGET_POWERPC64)
4575    {
4576      operands[4] = gen_reg_rtx (DImode);
4577      operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4578      operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4579				    WORDS_BIG_ENDIAN ? 4 : 0);
4580    }
4581  else
4582    {
4583      operands[4] = gen_reg_rtx (SImode);
4584      operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4585				    WORDS_BIG_ENDIAN ? 0 : 4);
4586      operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4587    }
4588})
4589
4590;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4591;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4592;; register allocator would typically move the entire _Float128 item to GPRs (2
4593;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4594;;
4595;; After register allocation, if the _Float128 had originally been in GPRs, the
4596;; split allows the post reload phases to eliminate the move, and do the shift
4597;; directly with the register that contains the signbit.
4598(define_insn_and_split "signbit<mode>2_dm"
4599  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4600	(unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4601		   UNSPEC_SIGNBIT))]
4602  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4603  "@
4604   mfvsrd %0,%x1
4605   #"
4606  "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4607  [(set (match_dup 0)
4608	(match_dup 2))]
4609{
4610  operands[2] = gen_highpart (DImode, operands[1]);
4611}
4612 [(set_attr "type" "mftgpr,*")])
4613
4614;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4615;; register and then doing a direct move if the value comes from memory.  On
4616;; little endian, we have to load the 2nd double-word to get the sign bit.
4617(define_insn_and_split "*signbit<mode>2_dm_mem"
4618  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4619	(unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4620		   UNSPEC_SIGNBIT))]
4621  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4622  "#"
4623  "&& 1"
4624  [(set (match_dup 0)
4625	(match_dup 2))]
4626{
4627  rtx dest = operands[0];
4628  rtx src = operands[1];
4629  rtx addr = XEXP (src, 0);
4630
4631  if (WORDS_BIG_ENDIAN)
4632    operands[2] = adjust_address (src, DImode, 0);
4633
4634  else if (REG_P (addr) || SUBREG_P (addr))
4635    operands[2] = adjust_address (src, DImode, 8);
4636
4637  else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4638	   && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4639    operands[2] = adjust_address (src, DImode, 8);
4640
4641  else
4642    {
4643      rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4644      emit_insn (gen_rtx_SET (tmp, addr));
4645      operands[2] = change_address (src, DImode,
4646				    gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4647    }
4648})
4649
4650(define_expand "copysign<mode>3"
4651  [(set (match_dup 3)
4652        (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4653   (set (match_dup 4)
4654	(neg:SFDF (abs:SFDF (match_dup 1))))
4655   (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4656        (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4657			       (match_dup 5))
4658			 (match_dup 3)
4659			 (match_dup 4)))]
4660  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4661   && ((TARGET_PPC_GFXOPT
4662        && !HONOR_NANS (<MODE>mode)
4663        && !HONOR_SIGNED_ZEROS (<MODE>mode))
4664       || TARGET_CMPB
4665       || VECTOR_UNIT_VSX_P (<MODE>mode))"
4666{
4667  if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4668    {
4669      emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4670					     operands[2]));
4671      DONE;
4672    }
4673
4674   operands[3] = gen_reg_rtx (<MODE>mode);
4675   operands[4] = gen_reg_rtx (<MODE>mode);
4676   operands[5] = CONST0_RTX (<MODE>mode);
4677  })
4678
4679;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4680;; compiler from optimizing -0.0
4681(define_insn "copysign<mode>3_fcpsgn"
4682  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4683	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4684		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4685		     UNSPEC_COPYSIGN))]
4686  "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4687  "@
4688   fcpsgn %0,%2,%1
4689   xscpsgndp %x0,%x2,%x1"
4690  [(set_attr "type" "fpsimple")])
4691
4692;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4693;; fsel instruction and some auxiliary computations.  Then we just have a
4694;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4695;; combine.
4696;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4697;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4698;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4699;; define_splits to make them if made by combine.  On VSX machines we have the
4700;; min/max instructions.
4701;;
4702;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4703;; to allow either DF/SF to use only traditional registers.
4704
4705(define_expand "s<minmax><mode>3"
4706  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4707	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4708			(match_operand:SFDF 2 "gpc_reg_operand" "")))]
4709  "TARGET_MINMAX_<MODE>"
4710{
4711  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4712  DONE;
4713})
4714
4715(define_insn "*s<minmax><mode>3_vsx"
4716  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4717	(fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4718			(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4719  "TARGET_VSX && TARGET_<MODE>_FPR"
4720{
4721  return (TARGET_P9_MINMAX
4722	  ? "xs<minmax>cdp %x0,%x1,%x2"
4723	  : "xs<minmax>dp %x0,%x1,%x2");
4724}
4725  [(set_attr "type" "fp")])
4726
4727;; The conditional move instructions allow us to perform max and min operations
4728;; even when we don't have the appropriate max/min instruction using the FSEL
4729;; instruction.
4730
4731(define_insn_and_split "*s<minmax><mode>3_fpr"
4732  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4733	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4734			(match_operand:SFDF 2 "gpc_reg_operand" "")))]
4735  "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4736  "#"
4737  "&& 1"
4738  [(const_int 0)]
4739{
4740  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4741  DONE;
4742})
4743
4744(define_expand "mov<mode>cc"
4745   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4746	 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4747			   (match_operand:GPR 2 "gpc_reg_operand" "")
4748			   (match_operand:GPR 3 "gpc_reg_operand" "")))]
4749  "TARGET_ISEL<sel>"
4750  "
4751{
4752  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4753    DONE;
4754  else
4755    FAIL;
4756}")
4757
4758;; We use the BASE_REGS for the isel input operands because, if rA is
4759;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4760;; because we may switch the operands and rB may end up being rA.
4761;;
4762;; We need 2 patterns: an unsigned and a signed pattern.  We could
4763;; leave out the mode in operand 4 and use one pattern, but reload can
4764;; change the mode underneath our feet and then gets confused trying
4765;; to reload the value.
4766(define_insn "isel_signed_<mode>"
4767  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4768	(if_then_else:GPR
4769	 (match_operator 1 "scc_comparison_operator"
4770			 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4771			  (const_int 0)])
4772	 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4773	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4774  "TARGET_ISEL<sel>"
4775  "*
4776{ return output_isel (operands); }"
4777  [(set_attr "type" "isel")
4778   (set_attr "length" "4")])
4779
4780(define_insn "isel_unsigned_<mode>"
4781  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4782	(if_then_else:GPR
4783	 (match_operator 1 "scc_comparison_operator"
4784			 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4785			  (const_int 0)])
4786	 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4787	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4788  "TARGET_ISEL<sel>"
4789  "*
4790{ return output_isel (operands); }"
4791  [(set_attr "type" "isel")
4792   (set_attr "length" "4")])
4793
4794;; These patterns can be useful for combine; they let combine know that
4795;; isel can handle reversed comparisons so long as the operands are
4796;; registers.
4797
4798(define_insn "*isel_reversed_signed_<mode>"
4799  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4800	(if_then_else:GPR
4801	 (match_operator 1 "scc_rev_comparison_operator"
4802			 [(match_operand:CC 4 "cc_reg_operand" "y")
4803			  (const_int 0)])
4804	 (match_operand:GPR 2 "gpc_reg_operand" "b")
4805	 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4806  "TARGET_ISEL<sel>"
4807  "*
4808{ return output_isel (operands); }"
4809  [(set_attr "type" "isel")
4810   (set_attr "length" "4")])
4811
4812(define_insn "*isel_reversed_unsigned_<mode>"
4813  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4814	(if_then_else:GPR
4815	 (match_operator 1 "scc_rev_comparison_operator"
4816			 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4817			  (const_int 0)])
4818	 (match_operand:GPR 2 "gpc_reg_operand" "b")
4819	 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4820  "TARGET_ISEL<sel>"
4821  "*
4822{ return output_isel (operands); }"
4823  [(set_attr "type" "isel")
4824   (set_attr "length" "4")])
4825
4826;; Floating point conditional move
4827(define_expand "mov<mode>cc"
4828   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4829	 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4830			    (match_operand:SFDF 2 "gpc_reg_operand" "")
4831			    (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4832  "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4833  "
4834{
4835  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4836    DONE;
4837  else
4838    FAIL;
4839}")
4840
4841(define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4842  [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4843	(if_then_else:SFDF
4844	 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4845	     (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4846	 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4847	 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4848  "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4849  "fsel %0,%1,%2,%3"
4850  [(set_attr "type" "fp")])
4851
4852(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4853  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4854	(if_then_else:SFDF
4855	 (match_operator:CCFP 1 "fpmask_comparison_operator"
4856		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4857		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4858	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4859	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4860   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4861  "TARGET_P9_MINMAX"
4862  "#"
4863  ""
4864  [(set (match_dup 6)
4865	(if_then_else:V2DI (match_dup 1)
4866			   (match_dup 7)
4867			   (match_dup 8)))
4868   (set (match_dup 0)
4869	(if_then_else:SFDF (ne (match_dup 6)
4870			       (match_dup 8))
4871			   (match_dup 4)
4872			   (match_dup 5)))]
4873{
4874  if (GET_CODE (operands[6]) == SCRATCH)
4875    operands[6] = gen_reg_rtx (V2DImode);
4876
4877  operands[7] = CONSTM1_RTX (V2DImode);
4878  operands[8] = CONST0_RTX (V2DImode);
4879}
4880 [(set_attr "length" "8")
4881  (set_attr "type" "vecperm")])
4882
4883;; Handle inverting the fpmask comparisons.
4884(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4885  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4886	(if_then_else:SFDF
4887	 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4888		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4889		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4890	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4891	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4892   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4893  "TARGET_P9_MINMAX"
4894  "#"
4895  "&& 1"
4896  [(set (match_dup 6)
4897	(if_then_else:V2DI (match_dup 9)
4898			   (match_dup 7)
4899			   (match_dup 8)))
4900   (set (match_dup 0)
4901	(if_then_else:SFDF (ne (match_dup 6)
4902			       (match_dup 8))
4903			   (match_dup 5)
4904			   (match_dup 4)))]
4905{
4906  rtx op1 = operands[1];
4907  enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
4908
4909  if (GET_CODE (operands[6]) == SCRATCH)
4910    operands[6] = gen_reg_rtx (V2DImode);
4911
4912  operands[7] = CONSTM1_RTX (V2DImode);
4913  operands[8] = CONST0_RTX (V2DImode);
4914
4915  operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
4916}
4917 [(set_attr "length" "8")
4918  (set_attr "type" "vecperm")])
4919
4920(define_insn "*fpmask<mode>"
4921  [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
4922	(if_then_else:V2DI
4923	 (match_operator:CCFP 1 "fpmask_comparison_operator"
4924		[(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
4925		 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
4926	 (match_operand:V2DI 4 "all_ones_constant" "")
4927	 (match_operand:V2DI 5 "zero_constant" "")))]
4928  "TARGET_P9_MINMAX"
4929  "xscmp%V1dp %x0,%x2,%x3"
4930  [(set_attr "type" "fpcompare")])
4931
4932(define_insn "*xxsel<mode>"
4933  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4934	(if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
4935			       (match_operand:V2DI 2 "zero_constant" ""))
4936			   (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
4937			   (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
4938  "TARGET_P9_MINMAX"
4939  "xxsel %x0,%x4,%x3,%x1"
4940  [(set_attr "type" "vecmove")])
4941
4942
4943;; Conversions to and from floating-point.
4944
4945; We don't define lfiwax/lfiwzx with the normal definition, because we
4946; don't want to support putting SImode in FPR registers.
4947(define_insn "lfiwax"
4948  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4949	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4950		   UNSPEC_LFIWAX))]
4951  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4952  "@
4953   lfiwax %0,%y1
4954   lxsiwax %x0,%y1
4955   mtvsrwa %x0,%1"
4956  [(set_attr "type" "fpload,fpload,mffgpr")])
4957
4958; This split must be run before register allocation because it allocates the
4959; memory slot that is needed to move values to/from the FPR.  We don't allocate
4960; it earlier to allow for the combiner to merge insns together where it might
4961; not be needed and also in case the insns are deleted as dead code.
4962
4963(define_insn_and_split "floatsi<mode>2_lfiwax"
4964  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4965	(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4966   (clobber (match_scratch:DI 2 "=wj"))]
4967  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4968   && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4969  "#"
4970  ""
4971  [(pc)]
4972  "
4973{
4974  rtx dest = operands[0];
4975  rtx src = operands[1];
4976  rtx tmp;
4977
4978  if (!MEM_P (src) && TARGET_POWERPC64
4979      && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4980    tmp = convert_to_mode (DImode, src, false);
4981  else
4982    {
4983      tmp = operands[2];
4984      if (GET_CODE (tmp) == SCRATCH)
4985	tmp = gen_reg_rtx (DImode);
4986      if (MEM_P (src))
4987	{
4988	  src = rs6000_address_for_fpconvert (src);
4989	  emit_insn (gen_lfiwax (tmp, src));
4990	}
4991      else
4992	{
4993	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4994	  emit_move_insn (stack, src);
4995	  emit_insn (gen_lfiwax (tmp, stack));
4996	}
4997    }
4998  emit_insn (gen_floatdi<mode>2 (dest, tmp));
4999  DONE;
5000}"
5001  [(set_attr "length" "12")
5002   (set_attr "type" "fpload")])
5003
5004(define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5005  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
5006	(float:SFDF
5007	 (sign_extend:DI
5008	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5009   (clobber (match_scratch:DI 2 "=0,d"))]
5010  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5011   && <SI_CONVERT_FP>"
5012  "#"
5013  ""
5014  [(pc)]
5015  "
5016{
5017  operands[1] = rs6000_address_for_fpconvert (operands[1]);
5018  if (GET_CODE (operands[2]) == SCRATCH)
5019    operands[2] = gen_reg_rtx (DImode);
5020  emit_insn (gen_lfiwax (operands[2], operands[1]));
5021  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5022  DONE;
5023}"
5024  [(set_attr "length" "8")
5025   (set_attr "type" "fpload")])
5026
5027(define_insn "lfiwzx"
5028  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
5029	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
5030		   UNSPEC_LFIWZX))]
5031  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5032  "@
5033   lfiwzx %0,%y1
5034   lxsiwzx %x0,%y1
5035   mtvsrwz %x0,%1"
5036  [(set_attr "type" "fpload,fpload,mftgpr")])
5037
5038(define_insn_and_split "floatunssi<mode>2_lfiwzx"
5039  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5040	(unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5041   (clobber (match_scratch:DI 2 "=wj"))]
5042  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5043   && <SI_CONVERT_FP>"
5044  "#"
5045  ""
5046  [(pc)]
5047  "
5048{
5049  rtx dest = operands[0];
5050  rtx src = operands[1];
5051  rtx tmp;
5052
5053  if (!MEM_P (src) && TARGET_POWERPC64
5054      && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5055    tmp = convert_to_mode (DImode, src, true);
5056  else
5057    {
5058      tmp = operands[2];
5059      if (GET_CODE (tmp) == SCRATCH)
5060	tmp = gen_reg_rtx (DImode);
5061      if (MEM_P (src))
5062	{
5063	  src = rs6000_address_for_fpconvert (src);
5064	  emit_insn (gen_lfiwzx (tmp, src));
5065	}
5066      else
5067	{
5068	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5069	  emit_move_insn (stack, src);
5070	  emit_insn (gen_lfiwzx (tmp, stack));
5071	}
5072    }
5073  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5074  DONE;
5075}"
5076  [(set_attr "length" "12")
5077   (set_attr "type" "fpload")])
5078
5079(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5080  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
5081	(unsigned_float:SFDF
5082	 (zero_extend:DI
5083	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5084   (clobber (match_scratch:DI 2 "=0,d"))]
5085  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5086   && <SI_CONVERT_FP>"
5087  "#"
5088  ""
5089  [(pc)]
5090  "
5091{
5092  operands[1] = rs6000_address_for_fpconvert (operands[1]);
5093  if (GET_CODE (operands[2]) == SCRATCH)
5094    operands[2] = gen_reg_rtx (DImode);
5095  emit_insn (gen_lfiwzx (operands[2], operands[1]));
5096  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5097  DONE;
5098}"
5099  [(set_attr "length" "8")
5100   (set_attr "type" "fpload")])
5101
5102; For each of these conversions, there is a define_expand, a define_insn
5103; with a '#' template, and a define_split (with C code).  The idea is
5104; to allow constant folding with the template of the define_insn,
5105; then to have the insns split later (between sched1 and final).
5106
5107(define_expand "floatsidf2"
5108  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5109		   (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5110	      (use (match_dup 2))
5111	      (use (match_dup 3))
5112	      (clobber (match_dup 4))
5113	      (clobber (match_dup 5))
5114	      (clobber (match_dup 6))])]
5115  "TARGET_HARD_FLOAT
5116   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5117  "
5118{
5119  if (TARGET_E500_DOUBLE)
5120    {
5121      if (!REG_P (operands[1]))
5122	operands[1] = force_reg (SImode, operands[1]);
5123      emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5124      DONE;
5125    }
5126  else if (TARGET_LFIWAX && TARGET_FCFID)
5127    {
5128      emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5129      DONE;
5130    }
5131  else if (TARGET_FCFID)
5132    {
5133      rtx dreg = operands[1];
5134      if (!REG_P (dreg))
5135	dreg = force_reg (SImode, dreg);
5136      dreg = convert_to_mode (DImode, dreg, false);
5137      emit_insn (gen_floatdidf2 (operands[0], dreg));
5138      DONE;
5139    }
5140
5141  if (!REG_P (operands[1]))
5142    operands[1] = force_reg (SImode, operands[1]);
5143  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5144  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5145  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5146  operands[5] = gen_reg_rtx (DFmode);
5147  operands[6] = gen_reg_rtx (SImode);
5148}")
5149
5150(define_insn_and_split "*floatsidf2_internal"
5151  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5152	(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5153   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5154   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5155   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5156   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5157   (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5158  "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5159  "#"
5160  ""
5161  [(pc)]
5162  "
5163{
5164  rtx lowword, highword;
5165  gcc_assert (MEM_P (operands[4]));
5166  highword = adjust_address (operands[4], SImode, 0);
5167  lowword = adjust_address (operands[4], SImode, 4);
5168  if (! WORDS_BIG_ENDIAN)
5169    std::swap (lowword, highword);
5170
5171  emit_insn (gen_xorsi3 (operands[6], operands[1],
5172			 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5173  emit_move_insn (lowword, operands[6]);
5174  emit_move_insn (highword, operands[2]);
5175  emit_move_insn (operands[5], operands[4]);
5176  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5177  DONE;
5178}"
5179  [(set_attr "length" "24")
5180   (set_attr "type" "fp")])
5181
5182;; If we don't have a direct conversion to single precision, don't enable this
5183;; conversion for 32-bit without fast math, because we don't have the insn to
5184;; generate the fixup swizzle to avoid double rounding problems.
5185(define_expand "floatunssisf2"
5186  [(set (match_operand:SF 0 "gpc_reg_operand" "")
5187        (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5188  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5189   && (!TARGET_FPRS
5190       || (TARGET_FPRS
5191	   && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5192	       || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5193		   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5194  "
5195{
5196  if (!TARGET_FPRS)
5197    {
5198      if (!REG_P (operands[1]))
5199	operands[1] = force_reg (SImode, operands[1]);
5200    }
5201  else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5202    {
5203      emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5204      DONE;
5205    }
5206  else
5207    {
5208      rtx dreg = operands[1];
5209      if (!REG_P (dreg))
5210	dreg = force_reg (SImode, dreg);
5211      dreg = convert_to_mode (DImode, dreg, true);
5212      emit_insn (gen_floatdisf2 (operands[0], dreg));
5213      DONE;
5214    }
5215}")
5216
5217(define_expand "floatunssidf2"
5218  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5219		   (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5220	      (use (match_dup 2))
5221	      (use (match_dup 3))
5222	      (clobber (match_dup 4))
5223	      (clobber (match_dup 5))])]
5224  "TARGET_HARD_FLOAT
5225   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5226  "
5227{
5228  if (TARGET_E500_DOUBLE)
5229    {
5230      if (!REG_P (operands[1]))
5231	operands[1] = force_reg (SImode, operands[1]);
5232      emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5233      DONE;
5234    }
5235  else if (TARGET_LFIWZX && TARGET_FCFID)
5236    {
5237      emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5238      DONE;
5239    }
5240  else if (TARGET_FCFID)
5241    {
5242      rtx dreg = operands[1];
5243      if (!REG_P (dreg))
5244	dreg = force_reg (SImode, dreg);
5245      dreg = convert_to_mode (DImode, dreg, true);
5246      emit_insn (gen_floatdidf2 (operands[0], dreg));
5247      DONE;
5248    }
5249
5250  if (!REG_P (operands[1]))
5251    operands[1] = force_reg (SImode, operands[1]);
5252  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5253  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5254  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5255  operands[5] = gen_reg_rtx (DFmode);
5256}")
5257
5258(define_insn_and_split "*floatunssidf2_internal"
5259  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5260	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5261   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5262   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5263   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5264   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5265  "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5266   && !(TARGET_FCFID && TARGET_POWERPC64)"
5267  "#"
5268  ""
5269  [(pc)]
5270  "
5271{
5272  rtx lowword, highword;
5273  gcc_assert (MEM_P (operands[4]));
5274  highword = adjust_address (operands[4], SImode, 0);
5275  lowword = adjust_address (operands[4], SImode, 4);
5276  if (! WORDS_BIG_ENDIAN)
5277    std::swap (lowword, highword);
5278
5279  emit_move_insn (lowword, operands[1]);
5280  emit_move_insn (highword, operands[2]);
5281  emit_move_insn (operands[5], operands[4]);
5282  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5283  DONE;
5284}"
5285  [(set_attr "length" "20")
5286   (set_attr "type" "fp")])
5287
5288(define_expand "fix_trunc<mode>si2"
5289  [(set (match_operand:SI 0 "gpc_reg_operand" "")
5290	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5291  "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5292  "
5293{
5294  if (!<E500_CONVERT>)
5295    {
5296      rtx tmp, stack;
5297
5298      if (TARGET_STFIWX)
5299	emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5300      else
5301	{
5302	  tmp = gen_reg_rtx (DImode);
5303	  stack = rs6000_allocate_stack_temp (DImode, true, false);
5304	  emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5305						      tmp, stack));
5306	}
5307      DONE;
5308    }
5309}")
5310
5311; Like the convert to float patterns, this insn must be split before
5312; register allocation so that it can allocate the memory slot if it
5313; needed
5314(define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5315  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5316	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5317   (clobber (match_scratch:DI 2 "=d"))]
5318  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5319   && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5320   && TARGET_STFIWX && can_create_pseudo_p ()"
5321  "#"
5322  ""
5323  [(pc)]
5324{
5325  rtx dest = operands[0];
5326  rtx src = operands[1];
5327  rtx tmp = operands[2];
5328
5329  if (GET_CODE (tmp) == SCRATCH)
5330    tmp = gen_reg_rtx (DImode);
5331
5332  emit_insn (gen_fctiwz_<mode> (tmp, src));
5333  if (MEM_P (dest))
5334    {
5335      dest = rs6000_address_for_fpconvert (dest);
5336      emit_insn (gen_stfiwx (dest, tmp));
5337      DONE;
5338    }
5339  else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5340    {
5341      dest = gen_lowpart (DImode, dest);
5342      emit_move_insn (dest, tmp);
5343      DONE;
5344    }
5345  else
5346    {
5347      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5348      emit_insn (gen_stfiwx (stack, tmp));
5349      emit_move_insn (dest, stack);
5350      DONE;
5351    }
5352}
5353  [(set_attr "length" "12")
5354   (set_attr "type" "fp")])
5355
5356(define_insn_and_split "fix_trunc<mode>si2_internal"
5357  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5358	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5359   (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5360   (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5361  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5362  "#"
5363  ""
5364  [(pc)]
5365  "
5366{
5367  rtx lowword;
5368  gcc_assert (MEM_P (operands[3]));
5369  lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5370
5371  emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5372  emit_move_insn (operands[3], operands[2]);
5373  emit_move_insn (operands[0], lowword);
5374  DONE;
5375}"
5376  [(set_attr "length" "16")
5377   (set_attr "type" "fp")])
5378
5379(define_expand "fix_trunc<mode>di2"
5380  [(set (match_operand:DI 0 "gpc_reg_operand" "")
5381	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5382  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5383   && TARGET_FCFID"
5384  "")
5385
5386(define_insn "*fix_trunc<mode>di2_fctidz"
5387  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5388	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5389  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5390    && TARGET_FCFID"
5391  "@
5392   fctidz %0,%1
5393   xscvdpsxds %x0,%x1"
5394  [(set_attr "type" "fp")])
5395
5396(define_expand "fixuns_trunc<mode>si2"
5397  [(set (match_operand:SI 0 "gpc_reg_operand" "")
5398	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5399  "TARGET_HARD_FLOAT
5400   && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5401       || <E500_CONVERT>)"
5402  "
5403{
5404  if (!<E500_CONVERT>)
5405    {
5406      emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5407      DONE;
5408    }
5409}")
5410
5411(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5412  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5413	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5414   (clobber (match_scratch:DI 2 "=d"))]
5415  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5416   && TARGET_STFIWX && can_create_pseudo_p ()"
5417  "#"
5418  ""
5419  [(pc)]
5420{
5421  rtx dest = operands[0];
5422  rtx src = operands[1];
5423  rtx tmp = operands[2];
5424
5425  if (GET_CODE (tmp) == SCRATCH)
5426    tmp = gen_reg_rtx (DImode);
5427
5428  emit_insn (gen_fctiwuz_<mode> (tmp, src));
5429  if (MEM_P (dest))
5430    {
5431      dest = rs6000_address_for_fpconvert (dest);
5432      emit_insn (gen_stfiwx (dest, tmp));
5433      DONE;
5434    }
5435  else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5436    {
5437      dest = gen_lowpart (DImode, dest);
5438      emit_move_insn (dest, tmp);
5439      DONE;
5440    }
5441  else
5442    {
5443      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5444      emit_insn (gen_stfiwx (stack, tmp));
5445      emit_move_insn (dest, stack);
5446      DONE;
5447    }
5448}
5449  [(set_attr "length" "12")
5450   (set_attr "type" "fp")])
5451
5452(define_insn "fixuns_trunc<mode>di2"
5453  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5454	(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5455  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
5456  "@
5457   fctiduz %0,%1
5458   xscvdpuxds %x0,%x1"
5459  [(set_attr "type" "fp")])
5460
5461; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5462; rather than (set (subreg:SI (reg)) (fix:SI ...))
5463; because the first makes it clear that operand 0 is not live
5464; before the instruction.
5465(define_insn "fctiwz_<mode>"
5466  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5467	(unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5468		   UNSPEC_FCTIWZ))]
5469  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5470  "@
5471   fctiwz %0,%1
5472   xscvdpsxws %x0,%x1"
5473  [(set_attr "type" "fp")])
5474
5475(define_insn "fctiwuz_<mode>"
5476  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5477	(unspec:DI [(unsigned_fix:SI
5478		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5479		   UNSPEC_FCTIWUZ))]
5480  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5481  "@
5482   fctiwuz %0,%1
5483   xscvdpuxws %x0,%x1"
5484  [(set_attr "type" "fp")])
5485
5486;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5487;; since the friz instruction does not truncate the value if the floating
5488;; point value is < LONG_MIN or > LONG_MAX.
5489(define_insn "*friz"
5490  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5491	(float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5492  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5493   && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5494  "@
5495   friz %0,%1
5496   xsrdpiz %x0,%x1"
5497  [(set_attr "type" "fp")])
5498
5499;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5500;; optimization prevents on ISA 2.06 systems and earlier having to store the
5501;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5502;; extend it, store it back on the stack from the GPR, load it back into the
5503;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5504;; disable using store and load to sign/zero extend the value.
5505(define_insn_and_split "*round32<mode>2_fprs"
5506  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5507	(float:SFDF
5508	 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5509   (clobber (match_scratch:DI 2 "=d"))
5510   (clobber (match_scratch:DI 3 "=d"))]
5511  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5512   && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5513   && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5514  "#"
5515  ""
5516  [(pc)]
5517{
5518  rtx dest = operands[0];
5519  rtx src = operands[1];
5520  rtx tmp1 = operands[2];
5521  rtx tmp2 = operands[3];
5522  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5523
5524  if (GET_CODE (tmp1) == SCRATCH)
5525    tmp1 = gen_reg_rtx (DImode);
5526  if (GET_CODE (tmp2) == SCRATCH)
5527    tmp2 = gen_reg_rtx (DImode);
5528
5529  emit_insn (gen_fctiwz_<mode> (tmp1, src));
5530  emit_insn (gen_stfiwx (stack, tmp1));
5531  emit_insn (gen_lfiwax (tmp2, stack));
5532  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5533  DONE;
5534}
5535  [(set_attr "type" "fpload")
5536   (set_attr "length" "16")])
5537
5538(define_insn_and_split "*roundu32<mode>2_fprs"
5539  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5540	(unsigned_float:SFDF
5541	 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5542   (clobber (match_scratch:DI 2 "=d"))
5543   (clobber (match_scratch:DI 3 "=d"))]
5544  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5545   && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5546   && can_create_pseudo_p ()"
5547  "#"
5548  ""
5549  [(pc)]
5550{
5551  rtx dest = operands[0];
5552  rtx src = operands[1];
5553  rtx tmp1 = operands[2];
5554  rtx tmp2 = operands[3];
5555  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5556
5557  if (GET_CODE (tmp1) == SCRATCH)
5558    tmp1 = gen_reg_rtx (DImode);
5559  if (GET_CODE (tmp2) == SCRATCH)
5560    tmp2 = gen_reg_rtx (DImode);
5561
5562  emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5563  emit_insn (gen_stfiwx (stack, tmp1));
5564  emit_insn (gen_lfiwzx (tmp2, stack));
5565  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5566  DONE;
5567}
5568  [(set_attr "type" "fpload")
5569   (set_attr "length" "16")])
5570
5571;; No VSX equivalent to fctid
5572(define_insn "lrint<mode>di2"
5573  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5574	(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5575		   UNSPEC_FCTID))]
5576  "TARGET_<MODE>_FPR && TARGET_FPRND"
5577  "fctid %0,%1"
5578  [(set_attr "type" "fp")])
5579
5580(define_insn "btrunc<mode>2"
5581  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5582	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5583		     UNSPEC_FRIZ))]
5584  "TARGET_<MODE>_FPR && TARGET_FPRND"
5585  "@
5586   friz %0,%1
5587   xsrdpiz %x0,%x1"
5588  [(set_attr "type" "fp")
5589   (set_attr "fp_type" "fp_addsub_<Fs>")])
5590
5591(define_insn "ceil<mode>2"
5592  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5593	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5594		     UNSPEC_FRIP))]
5595  "TARGET_<MODE>_FPR && TARGET_FPRND"
5596  "@
5597   frip %0,%1
5598   xsrdpip %x0,%x1"
5599  [(set_attr "type" "fp")
5600   (set_attr "fp_type" "fp_addsub_<Fs>")])
5601
5602(define_insn "floor<mode>2"
5603  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5604	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5605		     UNSPEC_FRIM))]
5606  "TARGET_<MODE>_FPR && TARGET_FPRND"
5607  "@
5608   frim %0,%1
5609   xsrdpim %x0,%x1"
5610  [(set_attr "type" "fp")
5611   (set_attr "fp_type" "fp_addsub_<Fs>")])
5612
5613;; No VSX equivalent to frin
5614(define_insn "round<mode>2"
5615  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5616	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5617		     UNSPEC_FRIN))]
5618  "TARGET_<MODE>_FPR && TARGET_FPRND"
5619  "frin %0,%1"
5620  [(set_attr "type" "fp")
5621   (set_attr "fp_type" "fp_addsub_<Fs>")])
5622
5623(define_insn "*xsrdpi<mode>2"
5624  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5625	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5626		     UNSPEC_XSRDPI))]
5627  "TARGET_<MODE>_FPR && TARGET_VSX"
5628  "xsrdpi %x0,%x1"
5629  [(set_attr "type" "fp")
5630   (set_attr "fp_type" "fp_addsub_<Fs>")])
5631
5632(define_expand "lround<mode>di2"
5633  [(set (match_dup 2)
5634	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5635		     UNSPEC_XSRDPI))
5636   (set (match_operand:DI 0 "gpc_reg_operand" "")
5637	(unspec:DI [(match_dup 2)]
5638		   UNSPEC_FCTID))]
5639  "TARGET_<MODE>_FPR && TARGET_VSX"
5640{
5641  operands[2] = gen_reg_rtx (<MODE>mode);
5642})
5643
5644; An UNSPEC is used so we don't have to support SImode in FP registers.
5645(define_insn "stfiwx"
5646  [(set (match_operand:SI 0 "memory_operand" "=Z")
5647	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5648		   UNSPEC_STFIWX))]
5649  "TARGET_PPC_GFXOPT"
5650  "stfiwx %1,%y0"
5651  [(set_attr "type" "fpstore")])
5652
5653;; If we don't have a direct conversion to single precision, don't enable this
5654;; conversion for 32-bit without fast math, because we don't have the insn to
5655;; generate the fixup swizzle to avoid double rounding problems.
5656(define_expand "floatsisf2"
5657  [(set (match_operand:SF 0 "gpc_reg_operand" "")
5658        (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5659  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5660   && (!TARGET_FPRS
5661       || (TARGET_FPRS
5662	   && ((TARGET_FCFIDS && TARGET_LFIWAX)
5663	       || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5664		   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5665  "
5666{
5667  if (!TARGET_FPRS)
5668    {
5669      if (!REG_P (operands[1]))
5670	operands[1] = force_reg (SImode, operands[1]);
5671    }
5672  else if (TARGET_FCFIDS && TARGET_LFIWAX)
5673    {
5674      emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5675      DONE;
5676    }
5677  else if (TARGET_FCFID && TARGET_LFIWAX)
5678    {
5679      rtx dfreg = gen_reg_rtx (DFmode);
5680      emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5681      emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5682      DONE;
5683    }
5684  else
5685    {
5686      rtx dreg = operands[1];
5687      if (!REG_P (dreg))
5688	dreg = force_reg (SImode, dreg);
5689      dreg = convert_to_mode (DImode, dreg, false);
5690      emit_insn (gen_floatdisf2 (operands[0], dreg));
5691      DONE;
5692    }
5693}")
5694
5695(define_expand "floatdidf2"
5696  [(set (match_operand:DF 0 "gpc_reg_operand" "")
5697	(float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5698  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5699  "")
5700
5701(define_insn "*floatdidf2_fpr"
5702  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5703	(float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5704  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5705  "@
5706   fcfid %0,%1
5707   xscvsxddp %x0,%x1"
5708  [(set_attr "type" "fp")])
5709
5710; Allow the combiner to merge source memory operands to the conversion so that
5711; the optimizer/register allocator doesn't try to load the value too early in a
5712; GPR and then use store/load to move it to a FPR and suffer from a store-load
5713; hit.  We will split after reload to avoid the trip through the GPRs
5714
5715(define_insn_and_split "*floatdidf2_mem"
5716  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5717	(float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5718   (clobber (match_scratch:DI 2 "=d,wi"))]
5719  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5720  "#"
5721  "&& reload_completed"
5722  [(set (match_dup 2) (match_dup 1))
5723   (set (match_dup 0) (float:DF (match_dup 2)))]
5724  ""
5725  [(set_attr "length" "8")
5726   (set_attr "type" "fpload")])
5727
5728(define_expand "floatunsdidf2"
5729  [(set (match_operand:DF 0 "gpc_reg_operand" "")
5730	(unsigned_float:DF
5731	 (match_operand:DI 1 "gpc_reg_operand" "")))]
5732  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5733  "")
5734
5735(define_insn "*floatunsdidf2_fcfidu"
5736  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5737	(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5738  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5739  "@
5740   fcfidu %0,%1
5741   xscvuxddp %x0,%x1"
5742  [(set_attr "type" "fp")
5743   (set_attr "length" "4")])
5744
5745(define_insn_and_split "*floatunsdidf2_mem"
5746  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5747	(unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5748   (clobber (match_scratch:DI 2 "=d,wi"))]
5749  "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5750  "#"
5751  "&& reload_completed"
5752  [(set (match_dup 2) (match_dup 1))
5753   (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5754  ""
5755  [(set_attr "length" "8")
5756   (set_attr "type" "fpload")])
5757
5758(define_expand "floatdisf2"
5759  [(set (match_operand:SF 0 "gpc_reg_operand" "")
5760        (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5761  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5762   && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5763  "
5764{
5765  if (!TARGET_FCFIDS)
5766    {
5767      rtx val = operands[1];
5768      if (!flag_unsafe_math_optimizations)
5769	{
5770	  rtx label = gen_label_rtx ();
5771	  val = gen_reg_rtx (DImode);
5772	  emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5773	  emit_label (label);
5774	}
5775      emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5776      DONE;
5777    }
5778}")
5779
5780(define_insn "floatdisf2_fcfids"
5781  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5782	(float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5783  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5784   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5785  "@
5786   fcfids %0,%1
5787   xscvsxdsp %x0,%x1"
5788  [(set_attr "type" "fp")])
5789
5790(define_insn_and_split "*floatdisf2_mem"
5791  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5792	(float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5793   (clobber (match_scratch:DI 2 "=d,d,wi"))]
5794  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5795   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5796  "#"
5797  "&& reload_completed"
5798  [(pc)]
5799  "
5800{
5801  emit_move_insn (operands[2], operands[1]);
5802  emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5803  DONE;
5804}"
5805  [(set_attr "length" "8")])
5806
5807;; This is not IEEE compliant if rounding mode is "round to nearest".
5808;; If the DI->DF conversion is inexact, then it's possible to suffer
5809;; from double rounding.
5810;; Instead of creating a new cpu type for two FP operations, just use fp
5811(define_insn_and_split "floatdisf2_internal1"
5812  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5813        (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5814   (clobber (match_scratch:DF 2 "=d"))]
5815  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5816   && !TARGET_FCFIDS"
5817  "#"
5818  "&& reload_completed"
5819  [(set (match_dup 2)
5820        (float:DF (match_dup 1)))
5821   (set (match_dup 0)
5822        (float_truncate:SF (match_dup 2)))]
5823  ""
5824  [(set_attr "length" "8")
5825   (set_attr "type" "fp")])
5826
5827;; Twiddles bits to avoid double rounding.
5828;; Bits that might be truncated when converting to DFmode are replaced
5829;; by a bit that won't be lost at that stage, but is below the SFmode
5830;; rounding position.
5831(define_expand "floatdisf2_internal2"
5832  [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5833					      (const_int 53)))
5834	      (clobber (reg:DI CA_REGNO))])
5835   (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5836					   (const_int 2047)))
5837   (set (match_dup 3) (plus:DI (match_dup 3)
5838			       (const_int 1)))
5839   (set (match_dup 0) (plus:DI (match_dup 0)
5840			       (const_int 2047)))
5841   (set (match_dup 4) (compare:CCUNS (match_dup 3)
5842				     (const_int 2)))
5843   (set (match_dup 0) (ior:DI (match_dup 0)
5844			      (match_dup 1)))
5845   (set (match_dup 0) (and:DI (match_dup 0)
5846			      (const_int -2048)))
5847   (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5848			   (label_ref (match_operand:DI 2 "" ""))
5849			   (pc)))
5850   (set (match_dup 0) (match_dup 1))]
5851  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5852   && !TARGET_FCFIDS"
5853  "
5854{
5855  operands[3] = gen_reg_rtx (DImode);
5856  operands[4] = gen_reg_rtx (CCUNSmode);
5857}")
5858
5859(define_expand "floatunsdisf2"
5860  [(set (match_operand:SF 0 "gpc_reg_operand" "")
5861        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5862  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5863   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5864  "")
5865
5866(define_insn "floatunsdisf2_fcfidus"
5867  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5868        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5869  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5870   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5871  "@
5872   fcfidus %0,%1
5873   xscvuxdsp %x0,%x1"
5874  [(set_attr "type" "fp")])
5875
5876(define_insn_and_split "*floatunsdisf2_mem"
5877  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5878	(unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5879   (clobber (match_scratch:DI 2 "=d,d,wi"))]
5880  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5881   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5882  "#"
5883  "&& reload_completed"
5884  [(pc)]
5885  "
5886{
5887  emit_move_insn (operands[2], operands[1]);
5888  emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5889  DONE;
5890}"
5891  [(set_attr "length" "8")
5892   (set_attr "type" "fpload")])
5893
5894;; Define the TImode operations that can be done in a small number
5895;; of instructions.  The & constraints are to prevent the register
5896;; allocator from allocating registers that overlap with the inputs
5897;; (for example, having an input in 7,8 and an output in 6,7).  We
5898;; also allow for the output being the same as one of the inputs.
5899
5900(define_expand "addti3"
5901  [(set (match_operand:TI 0 "gpc_reg_operand" "")
5902	(plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5903		 (match_operand:TI 2 "reg_or_short_operand" "")))]
5904  "TARGET_64BIT"
5905{
5906  rtx lo0 = gen_lowpart (DImode, operands[0]);
5907  rtx lo1 = gen_lowpart (DImode, operands[1]);
5908  rtx lo2 = gen_lowpart (DImode, operands[2]);
5909  rtx hi0 = gen_highpart (DImode, operands[0]);
5910  rtx hi1 = gen_highpart (DImode, operands[1]);
5911  rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5912
5913  if (!reg_or_short_operand (lo2, DImode))
5914    lo2 = force_reg (DImode, lo2);
5915  if (!adde_operand (hi2, DImode))
5916    hi2 = force_reg (DImode, hi2);
5917
5918  emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5919  emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5920  DONE;
5921})
5922
5923(define_expand "subti3"
5924  [(set (match_operand:TI 0 "gpc_reg_operand" "")
5925	(minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5926		  (match_operand:TI 2 "gpc_reg_operand" "")))]
5927  "TARGET_64BIT"
5928{
5929  rtx lo0 = gen_lowpart (DImode, operands[0]);
5930  rtx lo1 = gen_lowpart (DImode, operands[1]);
5931  rtx lo2 = gen_lowpart (DImode, operands[2]);
5932  rtx hi0 = gen_highpart (DImode, operands[0]);
5933  rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5934  rtx hi2 = gen_highpart (DImode, operands[2]);
5935
5936  if (!reg_or_short_operand (lo1, DImode))
5937    lo1 = force_reg (DImode, lo1);
5938  if (!adde_operand (hi1, DImode))
5939    hi1 = force_reg (DImode, hi1);
5940
5941  emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5942  emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5943  DONE;
5944})
5945
5946;; 128-bit logical operations expanders
5947
5948(define_expand "and<mode>3"
5949  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5950	(and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5951		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5952  ""
5953  "")
5954
5955(define_expand "ior<mode>3"
5956  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5957        (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5958		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5959  ""
5960  "")
5961
5962(define_expand "xor<mode>3"
5963  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5964        (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5965		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5966  ""
5967  "")
5968
5969(define_expand "one_cmpl<mode>2"
5970  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5971        (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5972  ""
5973  "")
5974
5975(define_expand "nor<mode>3"
5976  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5977	(and:BOOL_128
5978	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5979	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5980  ""
5981  "")
5982
5983(define_expand "andc<mode>3"
5984  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5985        (and:BOOL_128
5986	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5987	 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5988  ""
5989  "")
5990
5991;; Power8 vector logical instructions.
5992(define_expand "eqv<mode>3"
5993  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5994	(not:BOOL_128
5995	 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5996		       (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5997  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5998  "")
5999
6000;; Rewrite nand into canonical form
6001(define_expand "nand<mode>3"
6002  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6003	(ior:BOOL_128
6004	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6005	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6006  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6007  "")
6008
6009;; The canonical form is to have the negated element first, so we need to
6010;; reverse arguments.
6011(define_expand "orc<mode>3"
6012  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6013	(ior:BOOL_128
6014	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6015	 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6016  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6017  "")
6018
6019;; 128-bit logical operations insns and split operations
6020(define_insn_and_split "*and<mode>3_internal"
6021  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6022        (and:BOOL_128
6023	 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6024	 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6025  ""
6026{
6027  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6028    return "xxland %x0,%x1,%x2";
6029
6030  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6031    return "vand %0,%1,%2";
6032
6033  return "#";
6034}
6035  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6036  [(const_int 0)]
6037{
6038  rs6000_split_logical (operands, AND, false, false, false);
6039  DONE;
6040}
6041  [(set (attr "type")
6042      (if_then_else
6043	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6044	(const_string "veclogical")
6045	(const_string "integer")))
6046   (set (attr "length")
6047      (if_then_else
6048	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6049	(const_string "4")
6050	(if_then_else
6051	 (match_test "TARGET_POWERPC64")
6052	 (const_string "8")
6053	 (const_string "16"))))])
6054
6055;; 128-bit IOR/XOR
6056(define_insn_and_split "*bool<mode>3_internal"
6057  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6058	(match_operator:BOOL_128 3 "boolean_or_operator"
6059	 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6060	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6061  ""
6062{
6063  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6064    return "xxl%q3 %x0,%x1,%x2";
6065
6066  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6067    return "v%q3 %0,%1,%2";
6068
6069  return "#";
6070}
6071  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6072  [(const_int 0)]
6073{
6074  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6075  DONE;
6076}
6077  [(set (attr "type")
6078      (if_then_else
6079	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6080	(const_string "veclogical")
6081	(const_string "integer")))
6082   (set (attr "length")
6083      (if_then_else
6084	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6085	(const_string "4")
6086	(if_then_else
6087	 (match_test "TARGET_POWERPC64")
6088	 (const_string "8")
6089	 (const_string "16"))))])
6090
6091;; 128-bit ANDC/ORC
6092(define_insn_and_split "*boolc<mode>3_internal1"
6093  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6094	(match_operator:BOOL_128 3 "boolean_operator"
6095	 [(not:BOOL_128
6096	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6097	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6098  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6099{
6100  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6101    return "xxl%q3 %x0,%x1,%x2";
6102
6103  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6104    return "v%q3 %0,%1,%2";
6105
6106  return "#";
6107}
6108  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6109   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6110  [(const_int 0)]
6111{
6112  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6113  DONE;
6114}
6115  [(set (attr "type")
6116      (if_then_else
6117	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6118	(const_string "veclogical")
6119	(const_string "integer")))
6120   (set (attr "length")
6121      (if_then_else
6122	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6123	(const_string "4")
6124	(if_then_else
6125	 (match_test "TARGET_POWERPC64")
6126	 (const_string "8")
6127	 (const_string "16"))))])
6128
6129(define_insn_and_split "*boolc<mode>3_internal2"
6130  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6131	(match_operator:TI2 3 "boolean_operator"
6132	 [(not:TI2
6133	   (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6134	  (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6135  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6136  "#"
6137  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6138  [(const_int 0)]
6139{
6140  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6141  DONE;
6142}
6143  [(set_attr "type" "integer")
6144   (set (attr "length")
6145	(if_then_else
6146	 (match_test "TARGET_POWERPC64")
6147	 (const_string "8")
6148	 (const_string "16")))])
6149
6150;; 128-bit NAND/NOR
6151(define_insn_and_split "*boolcc<mode>3_internal1"
6152  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6153	(match_operator:BOOL_128 3 "boolean_operator"
6154	 [(not:BOOL_128
6155	   (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6156	  (not:BOOL_128
6157	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6158  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6159{
6160  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6161    return "xxl%q3 %x0,%x1,%x2";
6162
6163  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6164    return "v%q3 %0,%1,%2";
6165
6166  return "#";
6167}
6168  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6169   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6170  [(const_int 0)]
6171{
6172  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6173  DONE;
6174}
6175  [(set (attr "type")
6176      (if_then_else
6177	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6178	(const_string "veclogical")
6179	(const_string "integer")))
6180   (set (attr "length")
6181      (if_then_else
6182	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6183	(const_string "4")
6184	(if_then_else
6185	 (match_test "TARGET_POWERPC64")
6186	 (const_string "8")
6187	 (const_string "16"))))])
6188
6189(define_insn_and_split "*boolcc<mode>3_internal2"
6190  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6191	(match_operator:TI2 3 "boolean_operator"
6192	 [(not:TI2
6193	   (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6194	  (not:TI2
6195	   (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6196  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6197  "#"
6198  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6199  [(const_int 0)]
6200{
6201  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6202  DONE;
6203}
6204  [(set_attr "type" "integer")
6205   (set (attr "length")
6206	(if_then_else
6207	 (match_test "TARGET_POWERPC64")
6208	 (const_string "8")
6209	 (const_string "16")))])
6210
6211
6212;; 128-bit EQV
6213(define_insn_and_split "*eqv<mode>3_internal1"
6214  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6215	(not:BOOL_128
6216	 (xor:BOOL_128
6217	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6218	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6219  "TARGET_P8_VECTOR"
6220{
6221  if (vsx_register_operand (operands[0], <MODE>mode))
6222    return "xxleqv %x0,%x1,%x2";
6223
6224  return "#";
6225}
6226  "TARGET_P8_VECTOR && reload_completed
6227   && int_reg_operand (operands[0], <MODE>mode)"
6228  [(const_int 0)]
6229{
6230  rs6000_split_logical (operands, XOR, true, false, false);
6231  DONE;
6232}
6233  [(set (attr "type")
6234      (if_then_else
6235	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6236	(const_string "veclogical")
6237	(const_string "integer")))
6238   (set (attr "length")
6239      (if_then_else
6240	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6241	(const_string "4")
6242	(if_then_else
6243	 (match_test "TARGET_POWERPC64")
6244	 (const_string "8")
6245	 (const_string "16"))))])
6246
6247(define_insn_and_split "*eqv<mode>3_internal2"
6248  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6249	(not:TI2
6250	 (xor:TI2
6251	  (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6252	  (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6253  "!TARGET_P8_VECTOR"
6254  "#"
6255  "reload_completed && !TARGET_P8_VECTOR"
6256  [(const_int 0)]
6257{
6258  rs6000_split_logical (operands, XOR, true, false, false);
6259  DONE;
6260}
6261  [(set_attr "type" "integer")
6262   (set (attr "length")
6263	(if_then_else
6264	 (match_test "TARGET_POWERPC64")
6265	 (const_string "8")
6266	 (const_string "16")))])
6267
6268;; 128-bit one's complement
6269(define_insn_and_split "*one_cmpl<mode>3_internal"
6270  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6271	(not:BOOL_128
6272	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6273  ""
6274{
6275  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6276    return "xxlnor %x0,%x1,%x1";
6277
6278  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6279    return "vnor %0,%1,%1";
6280
6281  return "#";
6282}
6283  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6284  [(const_int 0)]
6285{
6286  rs6000_split_logical (operands, NOT, false, false, false);
6287  DONE;
6288}
6289  [(set (attr "type")
6290      (if_then_else
6291	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6292	(const_string "veclogical")
6293	(const_string "integer")))
6294   (set (attr "length")
6295      (if_then_else
6296	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6297	(const_string "4")
6298	(if_then_else
6299	 (match_test "TARGET_POWERPC64")
6300	 (const_string "8")
6301	 (const_string "16"))))])
6302
6303
6304;; Now define ways of moving data around.
6305
6306;; Set up a register with a value from the GOT table
6307
6308(define_expand "movsi_got"
6309  [(set (match_operand:SI 0 "gpc_reg_operand" "")
6310	(unspec:SI [(match_operand:SI 1 "got_operand" "")
6311		    (match_dup 2)] UNSPEC_MOVSI_GOT))]
6312  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6313  "
6314{
6315  if (GET_CODE (operands[1]) == CONST)
6316    {
6317      rtx offset = const0_rtx;
6318      HOST_WIDE_INT value;
6319
6320      operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6321      value = INTVAL (offset);
6322      if (value != 0)
6323	{
6324	  rtx tmp = (!can_create_pseudo_p ()
6325		     ? operands[0]
6326		     : gen_reg_rtx (Pmode));
6327	  emit_insn (gen_movsi_got (tmp, operands[1]));
6328	  emit_insn (gen_addsi3 (operands[0], tmp, offset));
6329	  DONE;
6330	}
6331    }
6332
6333  operands[2] = rs6000_got_register (operands[1]);
6334}")
6335
6336(define_insn "*movsi_got_internal"
6337  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6338	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6339		    (match_operand:SI 2 "gpc_reg_operand" "b")]
6340		   UNSPEC_MOVSI_GOT))]
6341  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6342  "lwz %0,%a1@got(%2)"
6343  [(set_attr "type" "load")])
6344
6345;; Used by sched, shorten_branches and final when the GOT pseudo reg
6346;; didn't get allocated to a hard register.
6347(define_split
6348  [(set (match_operand:SI 0 "gpc_reg_operand" "")
6349	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6350		    (match_operand:SI 2 "memory_operand" "")]
6351		   UNSPEC_MOVSI_GOT))]
6352  "DEFAULT_ABI == ABI_V4
6353    && flag_pic == 1
6354    && (reload_in_progress || reload_completed)"
6355  [(set (match_dup 0) (match_dup 2))
6356   (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6357				 UNSPEC_MOVSI_GOT))]
6358  "")
6359
6360;; For SI, we special-case integers that can't be loaded in one insn.  We
6361;; do the load 16-bits at a time.  We could do this by loading from memory,
6362;; and this is even supposed to be faster, but it is simpler not to get
6363;; integers in the TOC.
6364(define_insn "movsi_low"
6365  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6366        (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6367                           (match_operand 2 "" ""))))]
6368  "TARGET_MACHO && ! TARGET_64BIT"
6369  "lwz %0,lo16(%2)(%1)"
6370  [(set_attr "type" "load")
6371   (set_attr "length" "4")])
6372
6373(define_insn "*movsi_internal1"
6374  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6375	(match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6376  "!TARGET_SINGLE_FPU &&
6377   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6378  "@
6379   mr %0,%1
6380   la %0,%a1
6381   lwz%U1%X1 %0,%1
6382   stw%U0%X0 %1,%0
6383   li %0,%1
6384   lis %0,%v1
6385   #
6386   mf%1 %0
6387   mt%0 %1
6388   mt%0 %1
6389   nop"
6390  [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6391   (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6392
6393(define_insn "*movsi_internal1_single"
6394  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6395        (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6396  "TARGET_SINGLE_FPU &&
6397   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6398  "@
6399   mr %0,%1
6400   la %0,%a1
6401   lwz%U1%X1 %0,%1
6402   stw%U0%X0 %1,%0
6403   li %0,%1
6404   lis %0,%v1
6405   #
6406   mf%1 %0
6407   mt%0 %1
6408   mt%0 %1
6409   nop
6410   stfs%U0%X0 %1,%0
6411   lfs%U1%X1 %0,%1"
6412  [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6413   (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6414
6415;; Split a load of a large constant into the appropriate two-insn
6416;; sequence.
6417
6418(define_split
6419  [(set (match_operand:SI 0 "gpc_reg_operand" "")
6420	(match_operand:SI 1 "const_int_operand" ""))]
6421  "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6422   && (INTVAL (operands[1]) & 0xffff) != 0"
6423  [(set (match_dup 0)
6424	(match_dup 2))
6425   (set (match_dup 0)
6426	(ior:SI (match_dup 0)
6427		(match_dup 3)))]
6428  "
6429{
6430  if (rs6000_emit_set_const (operands[0], operands[1]))
6431    DONE;
6432  else
6433    FAIL;
6434}")
6435
6436(define_insn "*mov<mode>_internal2"
6437  [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6438	(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6439		    (const_int 0)))
6440   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6441  ""
6442  "@
6443   cmp<wd>i %2,%0,0
6444   mr. %0,%1
6445   #"
6446  [(set_attr "type" "cmp,logical,cmp")
6447   (set_attr "dot" "yes")
6448   (set_attr "length" "4,4,8")])
6449
6450(define_split
6451  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6452	(compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6453		    (const_int 0)))
6454   (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6455  "reload_completed"
6456  [(set (match_dup 0) (match_dup 1))
6457   (set (match_dup 2)
6458	(compare:CC (match_dup 0)
6459		    (const_int 0)))]
6460  "")
6461
6462(define_insn "*movhi_internal"
6463  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6464	(match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6465  "gpc_reg_operand (operands[0], HImode)
6466   || gpc_reg_operand (operands[1], HImode)"
6467  "@
6468   mr %0,%1
6469   lhz%U1%X1 %0,%1
6470   sth%U0%X0 %1,%0
6471   li %0,%w1
6472   mf%1 %0
6473   mt%0 %1
6474   nop"
6475  [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6476
6477(define_expand "mov<mode>"
6478  [(set (match_operand:INT 0 "general_operand" "")
6479	(match_operand:INT 1 "any_operand" ""))]
6480  ""
6481  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6482
6483(define_insn "*movqi_internal"
6484  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6485	(match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6486  "gpc_reg_operand (operands[0], QImode)
6487   || gpc_reg_operand (operands[1], QImode)"
6488  "@
6489   mr %0,%1
6490   lbz%U1%X1 %0,%1
6491   stb%U0%X0 %1,%0
6492   li %0,%1
6493   mf%1 %0
6494   mt%0 %1
6495   nop"
6496  [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6497
6498;; Here is how to move condition codes around.  When we store CC data in
6499;; an integer register or memory, we store just the high-order 4 bits.
6500;; This lets us not shift in the most common case of CR0.
6501(define_expand "movcc"
6502  [(set (match_operand:CC 0 "nonimmediate_operand" "")
6503	(match_operand:CC 1 "nonimmediate_operand" ""))]
6504  ""
6505  "")
6506
6507(define_insn "*movcc_internal1"
6508  [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6509	(match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6510  "register_operand (operands[0], CCmode)
6511   || register_operand (operands[1], CCmode)"
6512  "@
6513   mcrf %0,%1
6514   mtcrf 128,%1
6515   rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6516   crxor %0,%0,%0
6517   mfcr %0%Q1
6518   mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6519   mr %0,%1
6520   li %0,%1
6521   mf%1 %0
6522   mt%0 %1
6523   lwz%U1%X1 %0,%1
6524   stw%U0%X0 %1,%0"
6525  [(set (attr "type")
6526     (cond [(eq_attr "alternative" "0,3")
6527		(const_string "cr_logical")
6528	    (eq_attr "alternative" "1,2")
6529		(const_string "mtcr")
6530	    (eq_attr "alternative" "6,7")
6531		(const_string "integer")
6532	    (eq_attr "alternative" "8")
6533		(const_string "mfjmpr")
6534	    (eq_attr "alternative" "9")
6535		(const_string "mtjmpr")
6536	    (eq_attr "alternative" "10")
6537		(const_string "load")
6538	    (eq_attr "alternative" "11")
6539		(const_string "store")
6540	    (match_test "TARGET_MFCRF")
6541		(const_string "mfcrf")
6542	   ]
6543	(const_string "mfcr")))
6544   (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6545
6546;; For floating-point, we normally deal with the floating-point registers
6547;; unless -msoft-float is used.  The sole exception is that parameter passing
6548;; can produce floating-point values in fixed-point registers.  Unless the
6549;; value is a simple constant or already in memory, we deal with this by
6550;; allocating memory and copying the value explicitly via that memory location.
6551
6552;; Move 32-bit binary/decimal floating point
6553(define_expand "mov<mode>"
6554  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6555	(match_operand:FMOVE32 1 "any_operand" ""))]
6556  "<fmove_ok>"
6557  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6558
6559(define_split
6560  [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6561	(match_operand:FMOVE32 1 "const_double_operand" ""))]
6562  "reload_completed
6563   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6564       || (GET_CODE (operands[0]) == SUBREG
6565	   && GET_CODE (SUBREG_REG (operands[0])) == REG
6566	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
6567  [(set (match_dup 2) (match_dup 3))]
6568  "
6569{
6570  long l;
6571
6572  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6573
6574  if (! TARGET_POWERPC64)
6575    operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6576  else
6577    operands[2] = gen_lowpart (SImode, operands[0]);
6578
6579  operands[3] = gen_int_mode (l, SImode);
6580}")
6581
6582;; Originally, we tried to keep movsf and movsd common, but the differences
6583;; addressing was making it rather difficult to hide with mode attributes.  In
6584;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
6585;; before the VSX stores meant that the register allocator would tend to do a
6586;; direct move to the GPR (which involves conversion from scalar to
6587;; vector/memory formats) to save values in the traditional Altivec registers,
6588;; while SDmode had problems on power6 if the GPR store was not first due to
6589;; the power6 not having an integer store operation.
6590;;
6591;;	LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
6592;;	STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
6593;;	MR           MT<x>      MF<x>       NOP
6594
6595(define_insn "movsf_hardfloat"
6596  [(set (match_operand:SF 0 "nonimmediate_operand"
6597	 "=!r,       f,         wb,         wu,        m,         wY,
6598	  Z,         m,         ww,         !r,        f,         ww,
6599	  !r,        *c*l,      !r,         *h")
6600	(match_operand:SF 1 "input_operand"
6601	 "m,         m,         wY,         Z,         f,         wb,
6602	  wu,        r,         j,          j,         f,         ww,
6603	  r,         r,         *h,         0"))]
6604  "(register_operand (operands[0], SFmode)
6605   || register_operand (operands[1], SFmode))
6606   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
6607  "@
6608   lwz%U1%X1 %0,%1
6609   lfs%U1%X1 %0,%1
6610   lxssp %0,%1
6611   lxsspx %x0,%y1
6612   stfs%U0%X0 %1,%0
6613   stxssp %1,%0
6614   stxsspx %x1,%y0
6615   stw%U0%X0 %1,%0
6616   xxlxor %x0,%x0,%x0
6617   li %0,0
6618   fmr %0,%1
6619   xscpsgndp %x0,%x1,%x1
6620   mr %0,%1
6621   mt%0 %1
6622   mf%1 %0
6623   nop"
6624  [(set_attr "type"
6625	"load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
6626	 fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
6627	 *,          mtjmpr,    mfjmpr,     *")])
6628
6629;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
6630;;	FMR          MR         MT%0       MF%1       NOP
6631(define_insn "movsd_hardfloat"
6632  [(set (match_operand:SD 0 "nonimmediate_operand"
6633	 "=!r,       wz,        m,         Z,         ?wh,       ?r,
6634	  f,         !r,        *c*l,      !r,        *h")
6635	(match_operand:SD 1 "input_operand"
6636	 "m,         Z,         r,         wx,        r,         wh,
6637	  f,         r,         r,         *h,        0"))]
6638  "(register_operand (operands[0], SDmode)
6639   || register_operand (operands[1], SDmode))
6640   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
6641  "@
6642   lwz%U1%X1 %0,%1
6643   lfiwzx %0,%y1
6644   stw%U0%X0 %1,%0
6645   stfiwx %1,%y0
6646   mtvsrwz %x0,%1
6647   mfvsrwz %0,%x1
6648   fmr %0,%1
6649   mr %0,%1
6650   mt%0 %1
6651   mf%1 %0
6652   nop"
6653  [(set_attr "type"
6654	"load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
6655	 fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
6656
6657(define_insn "*mov<mode>_softfloat"
6658  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6659	(match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6660  "(gpc_reg_operand (operands[0], <MODE>mode)
6661   || gpc_reg_operand (operands[1], <MODE>mode))
6662   && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6663  "@
6664   mr %0,%1
6665   mt%0 %1
6666   mf%1 %0
6667   lwz%U1%X1 %0,%1
6668   stw%U0%X0 %1,%0
6669   li %0,%1
6670   lis %0,%v1
6671   #
6672   #
6673   nop"
6674  [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6675   (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6676
6677
6678;; Move 64-bit binary/decimal floating point
6679(define_expand "mov<mode>"
6680  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6681	(match_operand:FMOVE64 1 "any_operand" ""))]
6682  ""
6683  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6684
6685(define_split
6686  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6687	(match_operand:FMOVE64 1 "const_int_operand" ""))]
6688  "! TARGET_POWERPC64 && reload_completed
6689   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6690       || (GET_CODE (operands[0]) == SUBREG
6691	   && GET_CODE (SUBREG_REG (operands[0])) == REG
6692	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
6693  [(set (match_dup 2) (match_dup 4))
6694   (set (match_dup 3) (match_dup 1))]
6695  "
6696{
6697  int endian = (WORDS_BIG_ENDIAN == 0);
6698  HOST_WIDE_INT value = INTVAL (operands[1]);
6699
6700  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6701  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6702  operands[4] = GEN_INT (value >> 32);
6703  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6704}")
6705
6706(define_split
6707  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6708	(match_operand:FMOVE64 1 "const_double_operand" ""))]
6709  "! TARGET_POWERPC64 && reload_completed
6710   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6711       || (GET_CODE (operands[0]) == SUBREG
6712	   && GET_CODE (SUBREG_REG (operands[0])) == REG
6713	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
6714  [(set (match_dup 2) (match_dup 4))
6715   (set (match_dup 3) (match_dup 5))]
6716  "
6717{
6718  int endian = (WORDS_BIG_ENDIAN == 0);
6719  long l[2];
6720
6721  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6722
6723  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6724  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6725  operands[4] = gen_int_mode (l[endian], SImode);
6726  operands[5] = gen_int_mode (l[1 - endian], SImode);
6727}")
6728
6729(define_split
6730  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6731	(match_operand:FMOVE64 1 "const_double_operand" ""))]
6732  "TARGET_POWERPC64 && reload_completed
6733   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6734       || (GET_CODE (operands[0]) == SUBREG
6735	   && GET_CODE (SUBREG_REG (operands[0])) == REG
6736	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
6737  [(set (match_dup 2) (match_dup 3))]
6738  "
6739{
6740  int endian = (WORDS_BIG_ENDIAN == 0);
6741  long l[2];
6742  HOST_WIDE_INT val;
6743
6744  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6745
6746  operands[2] = gen_lowpart (DImode, operands[0]);
6747  /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6748  val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6749         | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6750
6751  operands[3] = gen_int_mode (val, DImode);
6752}")
6753
6754;; Don't have reload use general registers to load a constant.  It is
6755;; less efficient than loading the constant into an FP register, since
6756;; it will probably be used there.
6757
6758;; The move constraints are ordered to prefer floating point registers before
6759;; general purpose registers to avoid doing a store and a load to get the value
6760;; into a floating point register when it is needed for a floating point
6761;; operation.  Prefer traditional floating point registers over VSX registers,
6762;; since the D-form version of the memory instructions does not need a GPR for
6763;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6764;; registers.
6765
6766;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6767;; except for 0.0 which can be created on VSX with an xor instruction.
6768
6769(define_insn "*mov<mode>_hardfloat32"
6770  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6771	(match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
6772  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6773   && (gpc_reg_operand (operands[0], <MODE>mode)
6774       || gpc_reg_operand (operands[1], <MODE>mode))"
6775  "@
6776   stfd%U0%X0 %1,%0
6777   lfd%U1%X1 %0,%1
6778   fmr %0,%1
6779   lxsd %0,%1
6780   stxsd %1,%0
6781   lxsd%U1x %x0,%y1
6782   stxsd%U0x %x1,%y0
6783   xxlor %x0,%x1,%x1
6784   xxlxor %x0,%x0,%x0
6785   #
6786   #
6787   #
6788   #"
6789  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
6790   (set_attr "size" "64")
6791   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6792
6793(define_insn "*mov<mode>_softfloat32"
6794  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6795	(match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6796  "! TARGET_POWERPC64
6797   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6798       || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6799       || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6800   && (gpc_reg_operand (operands[0], <MODE>mode)
6801       || gpc_reg_operand (operands[1], <MODE>mode))"
6802  "#"
6803  [(set_attr "type" "store,load,two,*,*,*")
6804   (set_attr "length" "8,8,8,8,12,16")])
6805
6806; ld/std require word-aligned displacements -> 'Y' constraint.
6807; List Y->r and r->Y before r->r for reload.
6808(define_insn "*mov<mode>_hardfloat64"
6809  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,o,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6810	(match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6811  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6812   && (gpc_reg_operand (operands[0], <MODE>mode)
6813       || gpc_reg_operand (operands[1], <MODE>mode))"
6814  "@
6815   stfd%U0%X0 %1,%0
6816   lfd%U1%X1 %0,%1
6817   fmr %0,%1
6818   lxsd %0,%1
6819   stxsd %1,%0
6820   lxsd%U1x %x0,%y1
6821   stxsd%U0x %x1,%y0
6822   xxlor %x0,%x1,%x1
6823   xxlxor %x0,%x0,%x0
6824   li %0,0
6825   std%U0%X0 %1,%0
6826   ld%U1%X1 %0,%1
6827   mr %0,%1
6828   mt%0 %1
6829   mf%1 %0
6830   nop
6831   mftgpr %0,%1
6832   mffgpr %0,%1
6833   mfvsrd %0,%x1
6834   mtvsrd %x0,%1"
6835  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6836   (set_attr "size" "64")
6837   (set_attr "length" "4")])
6838
6839(define_insn "*mov<mode>_softfloat64"
6840  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6841	(match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6842  "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6843   && (gpc_reg_operand (operands[0], <MODE>mode)
6844       || gpc_reg_operand (operands[1], <MODE>mode))"
6845  "@
6846   std%U0%X0 %1,%0
6847   ld%U1%X1 %0,%1
6848   mr %0,%1
6849   mt%0 %1
6850   mf%1 %0
6851   #
6852   #
6853   #
6854   nop"
6855  [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6856   (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6857
6858(define_expand "mov<mode>"
6859  [(set (match_operand:FMOVE128 0 "general_operand" "")
6860	(match_operand:FMOVE128 1 "any_operand" ""))]
6861  ""
6862  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6863
6864;; It's important to list Y->r and r->Y before r->r because otherwise
6865;; reload, given m->r, will try to pick r->r and reload it, which
6866;; doesn't make progress.
6867
6868;; We can't split little endian direct moves of TDmode, because the words are
6869;; not swapped like they are for TImode or TFmode.  Subregs therefore are
6870;; problematical.  Don't allow direct move for this case.
6871
6872(define_insn_and_split "*mov<mode>_64bit_dm"
6873  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
6874	(match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
6875  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6876   && FLOAT128_2REG_P (<MODE>mode)
6877   && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6878   && (gpc_reg_operand (operands[0], <MODE>mode)
6879       || gpc_reg_operand (operands[1], <MODE>mode))"
6880  "#"
6881  "&& reload_completed"
6882  [(pc)]
6883{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6884  [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6885
6886(define_insn_and_split "*movtd_64bit_nodm"
6887  [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
6888	(match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
6889  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6890   && (gpc_reg_operand (operands[0], TDmode)
6891       || gpc_reg_operand (operands[1], TDmode))"
6892  "#"
6893  "&& reload_completed"
6894  [(pc)]
6895{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6896  [(set_attr "length" "8,8,8,12,12,8")])
6897
6898(define_insn_and_split "*mov<mode>_32bit"
6899  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
6900	(match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
6901  "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6902   && (FLOAT128_2REG_P (<MODE>mode)
6903       || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6904       || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6905   && (gpc_reg_operand (operands[0], <MODE>mode)
6906       || gpc_reg_operand (operands[1], <MODE>mode))"
6907  "#"
6908  "&& reload_completed"
6909  [(pc)]
6910{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6911  [(set_attr "length" "8,8,8,8,20,20,16")])
6912
6913(define_insn_and_split "*mov<mode>_softfloat"
6914  [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6915	(match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6916  "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6917   && (gpc_reg_operand (operands[0], <MODE>mode)
6918       || gpc_reg_operand (operands[1], <MODE>mode))"
6919  "#"
6920  "&& reload_completed"
6921  [(pc)]
6922{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6923  [(set_attr "length" "20,20,16")])
6924
6925(define_expand "extenddf<mode>2"
6926  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6927	(float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6928  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6929   && TARGET_LONG_DOUBLE_128"
6930{
6931  if (FLOAT128_IEEE_P (<MODE>mode))
6932    rs6000_expand_float128_convert (operands[0], operands[1], false);
6933  else if (TARGET_E500_DOUBLE)
6934    {
6935      gcc_assert (<MODE>mode == TFmode);
6936      emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6937    }
6938  else if (TARGET_VSX)
6939    {
6940      if (<MODE>mode == TFmode)
6941	emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
6942      else if (<MODE>mode == IFmode)
6943	emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
6944      else
6945	gcc_unreachable ();
6946    }
6947   else
6948    {
6949      rtx zero = gen_reg_rtx (DFmode);
6950      rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
6951
6952      if (<MODE>mode == TFmode)
6953	emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
6954      else if (<MODE>mode == IFmode)
6955	emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
6956      else
6957	gcc_unreachable ();
6958    }
6959  DONE;
6960})
6961
6962;; Allow memory operands for the source to be created by the combiner.
6963(define_insn_and_split "extenddf<mode>2_fprs"
6964  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
6965	(float_extend:IBM128
6966	 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
6967   (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
6968  "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6969   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6970  "#"
6971  "&& reload_completed"
6972  [(set (match_dup 3) (match_dup 1))
6973   (set (match_dup 4) (match_dup 2))]
6974{
6975  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6976  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6977
6978  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6979  operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6980})
6981
6982(define_insn_and_split "extenddf<mode>2_vsx"
6983  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
6984	(float_extend:IBM128
6985	 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
6986  "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
6987  "#"
6988  "&& reload_completed"
6989  [(set (match_dup 2) (match_dup 1))
6990   (set (match_dup 3) (match_dup 4))]
6991{
6992  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6993  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6994
6995  operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6996  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6997  operands[4] = CONST0_RTX (DFmode);
6998})
6999
7000(define_expand "extendsf<mode>2"
7001  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7002	(float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7003  "TARGET_HARD_FLOAT
7004   && (TARGET_FPRS || TARGET_E500_DOUBLE)
7005   && TARGET_LONG_DOUBLE_128"
7006{
7007  if (FLOAT128_IEEE_P (<MODE>mode))
7008    rs6000_expand_float128_convert (operands[0], operands[1], false);
7009  else
7010    {
7011      rtx tmp = gen_reg_rtx (DFmode);
7012      emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7013      emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7014    }
7015  DONE;
7016})
7017
7018(define_expand "trunc<mode>df2"
7019  [(set (match_operand:DF 0 "gpc_reg_operand" "")
7020	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7021  "TARGET_HARD_FLOAT
7022   && (TARGET_FPRS || TARGET_E500_DOUBLE)
7023   && TARGET_LONG_DOUBLE_128"
7024{
7025  if (FLOAT128_IEEE_P (<MODE>mode))
7026    {
7027      rs6000_expand_float128_convert (operands[0], operands[1], false);
7028      DONE;
7029    }
7030})
7031
7032(define_insn_and_split "trunc<mode>df2_internal1"
7033  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7034	(float_truncate:DF
7035	 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7036  "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7037   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7038  "@
7039   #
7040   fmr %0,%1"
7041  "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7042  [(const_int 0)]
7043{
7044  emit_note (NOTE_INSN_DELETED);
7045  DONE;
7046}
7047  [(set_attr "type" "fpsimple")])
7048
7049(define_insn "trunc<mode>df2_internal2"
7050  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7051	(float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7052  "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7053   && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7054  "fadd %0,%1,%L1"
7055  [(set_attr "type" "fp")
7056   (set_attr "fp_type" "fp_addsub_d")])
7057
7058(define_expand "trunc<mode>sf2"
7059  [(set (match_operand:SF 0 "gpc_reg_operand" "")
7060	(float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7061  "TARGET_HARD_FLOAT
7062   && (TARGET_FPRS || TARGET_E500_DOUBLE)
7063   && TARGET_LONG_DOUBLE_128"
7064{
7065  if (FLOAT128_IEEE_P (<MODE>mode))
7066    rs6000_expand_float128_convert (operands[0], operands[1], false);
7067  else if (TARGET_E500_DOUBLE)
7068    {
7069      gcc_assert (<MODE>mode == TFmode);
7070      emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7071    }
7072  else if (<MODE>mode == TFmode)
7073    emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7074  else if (<MODE>mode == IFmode)
7075    emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7076  else
7077    gcc_unreachable ();
7078  DONE;
7079})
7080
7081(define_insn_and_split "trunc<mode>sf2_fprs"
7082  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7083	(float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7084   (clobber (match_scratch:DF 2 "=d"))]
7085  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7086   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7087  "#"
7088  "&& reload_completed"
7089  [(set (match_dup 2)
7090	(float_truncate:DF (match_dup 1)))
7091   (set (match_dup 0)
7092	(float_truncate:SF (match_dup 2)))]
7093  "")
7094
7095(define_expand "floatsi<mode>2"
7096  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7097        (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7098  "TARGET_HARD_FLOAT
7099   && (TARGET_FPRS || TARGET_E500_DOUBLE)
7100   && TARGET_LONG_DOUBLE_128"
7101{
7102  if (FLOAT128_IEEE_P (<MODE>mode))
7103    rs6000_expand_float128_convert (operands[0], operands[1], false);
7104  else
7105    {
7106      rtx tmp = gen_reg_rtx (DFmode);
7107      expand_float (tmp, operands[1], false);
7108      if (<MODE>mode == TFmode)
7109	emit_insn (gen_extenddftf2 (operands[0], tmp));
7110      else if (<MODE>mode == IFmode)
7111	emit_insn (gen_extenddfif2 (operands[0], tmp));
7112      else
7113	gcc_unreachable ();
7114    }
7115  DONE;
7116})
7117
7118; fadd, but rounding towards zero.
7119; This is probably not the optimal code sequence.
7120(define_insn "fix_trunc_helper<mode>"
7121  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7122	(unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7123		   UNSPEC_FIX_TRUNC_TF))
7124   (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7125  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7126   && FLOAT128_IBM_P (<MODE>mode)"
7127  "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7128  [(set_attr "type" "fp")
7129   (set_attr "length" "20")])
7130
7131(define_expand "fix_trunc<mode>si2"
7132  [(set (match_operand:SI 0 "gpc_reg_operand" "")
7133	(fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7134  "TARGET_HARD_FLOAT
7135   && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7136{
7137  if (FLOAT128_IEEE_P (<MODE>mode))
7138    rs6000_expand_float128_convert (operands[0], operands[1], false);
7139  else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7140    emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7141  else if (<MODE>mode == TFmode)
7142    emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7143  else if (<MODE>mode == IFmode)
7144    emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7145  else
7146    gcc_unreachable ();
7147  DONE;
7148})
7149
7150(define_expand "fix_trunc<mode>si2_fprs"
7151  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7152		   (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7153	      (clobber (match_dup 2))
7154	      (clobber (match_dup 3))
7155	      (clobber (match_dup 4))
7156	      (clobber (match_dup 5))])]
7157  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7158{
7159  operands[2] = gen_reg_rtx (DFmode);
7160  operands[3] = gen_reg_rtx (DFmode);
7161  operands[4] = gen_reg_rtx (DImode);
7162  operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7163})
7164
7165(define_insn_and_split "*fix_trunc<mode>si2_internal"
7166  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7167        (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7168   (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7169   (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7170   (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7171   (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7172  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7173  "#"
7174  ""
7175  [(pc)]
7176{
7177  rtx lowword;
7178  emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7179					 operands[3]));
7180
7181  gcc_assert (MEM_P (operands[5]));
7182  lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7183
7184  emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7185  emit_move_insn (operands[5], operands[4]);
7186  emit_move_insn (operands[0], lowword);
7187  DONE;
7188})
7189
7190(define_expand "fix_trunc<mode>di2"
7191  [(set (match_operand:DI 0 "gpc_reg_operand" "")
7192	(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7193  "TARGET_FLOAT128"
7194{
7195  rs6000_expand_float128_convert (operands[0], operands[1], false);
7196  DONE;
7197})
7198
7199(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7200  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7201	(unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7202  "TARGET_FLOAT128"
7203{
7204  rs6000_expand_float128_convert (operands[0], operands[1], true);
7205  DONE;
7206})
7207
7208(define_expand "floatdi<mode>2"
7209  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7210	(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7211  "TARGET_FLOAT128"
7212{
7213  rs6000_expand_float128_convert (operands[0], operands[1], false);
7214  DONE;
7215})
7216
7217(define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7218  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7219	(unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7220  "TARGET_FLOAT128"
7221{
7222  rs6000_expand_float128_convert (operands[0], operands[1], true);
7223  DONE;
7224})
7225
7226(define_expand "neg<mode>2"
7227  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7228	(neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7229  "FLOAT128_IEEE_P (<MODE>mode)
7230   || (FLOAT128_IBM_P (<MODE>mode)
7231       && TARGET_HARD_FLOAT
7232       && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7233  "
7234{
7235  if (FLOAT128_IEEE_P (<MODE>mode))
7236    {
7237      if (TARGET_FLOAT128_HW)
7238	{
7239	  if (<MODE>mode == TFmode)
7240	    emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7241	  else if (<MODE>mode == KFmode)
7242	    emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7243	  else
7244	    gcc_unreachable ();
7245	}
7246      else if (TARGET_FLOAT128)
7247	{
7248	  if (<MODE>mode == TFmode)
7249	    emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7250	  else if (<MODE>mode == KFmode)
7251	    emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7252	  else
7253	    gcc_unreachable ();
7254	}
7255      else
7256	{
7257	  rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7258	  rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7259						<MODE>mode, 1,
7260						operands[1], <MODE>mode);
7261
7262	  if (target && !rtx_equal_p (target, operands[0]))
7263	    emit_move_insn (operands[0], target);
7264	}
7265      DONE;
7266    }
7267}")
7268
7269(define_insn "neg<mode>2_internal"
7270  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7271	(neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7272  "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7273  "*
7274{
7275  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7276    return \"fneg %L0,%L1\;fneg %0,%1\";
7277  else
7278    return \"fneg %0,%1\;fneg %L0,%L1\";
7279}"
7280  [(set_attr "type" "fpsimple")
7281   (set_attr "length" "8")])
7282
7283(define_expand "abs<mode>2"
7284  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7285	(abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7286  "FLOAT128_IEEE_P (<MODE>mode)
7287   || (FLOAT128_IBM_P (<MODE>mode)
7288       && TARGET_HARD_FLOAT
7289       && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7290  "
7291{
7292  rtx label;
7293
7294  if (FLOAT128_IEEE_P (<MODE>mode))
7295    {
7296      if (TARGET_FLOAT128_HW)
7297	{
7298	  if (<MODE>mode == TFmode)
7299	    emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7300	  else if (<MODE>mode == KFmode)
7301	    emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7302	  else
7303	    FAIL;
7304	  DONE;
7305	}
7306      else if (TARGET_FLOAT128)
7307	{
7308	  if (<MODE>mode == TFmode)
7309	    emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7310	  else if (<MODE>mode == KFmode)
7311	    emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7312	  else
7313	    FAIL;
7314	  DONE;
7315	}
7316      else
7317	FAIL;
7318    }
7319
7320  label = gen_label_rtx ();
7321  if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7322    {
7323      if (flag_finite_math_only && !flag_trapping_math)
7324	emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7325      else
7326	emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7327    }
7328  else if (<MODE>mode == TFmode)
7329    emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7330  else if (<MODE>mode == TFmode)
7331    emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7332  else
7333    FAIL;
7334  emit_label (label);
7335  DONE;
7336}")
7337
7338(define_expand "abs<mode>2_internal"
7339  [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7340	(match_operand:IBM128 1 "gpc_reg_operand" ""))
7341   (set (match_dup 3) (match_dup 5))
7342   (set (match_dup 5) (abs:DF (match_dup 5)))
7343   (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7344   (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7345			   (label_ref (match_operand 2 "" ""))
7346			   (pc)))
7347   (set (match_dup 6) (neg:DF (match_dup 6)))]
7348  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7349   && TARGET_LONG_DOUBLE_128"
7350  "
7351{
7352  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7353  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7354  operands[3] = gen_reg_rtx (DFmode);
7355  operands[4] = gen_reg_rtx (CCFPmode);
7356  operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7357  operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7358}")
7359
7360
7361;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7362;; register
7363
7364(define_expand "ieee_128bit_negative_zero"
7365  [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7366  "TARGET_FLOAT128"
7367{
7368  rtvec v = rtvec_alloc (16);
7369  int i, high;
7370
7371  for (i = 0; i < 16; i++)
7372    RTVEC_ELT (v, i) = const0_rtx;
7373
7374  high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7375  RTVEC_ELT (v, high) = GEN_INT (0x80);
7376
7377  rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7378  DONE;
7379})
7380
7381;; IEEE 128-bit negate
7382
7383;; We have 2 insns here for negate and absolute value.  The first uses
7384;; match_scratch so that phases like combine can recognize neg/abs as generic
7385;; insns, and second insn after the first split pass loads up the bit to
7386;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7387;; neg/abs to create the constant just once.
7388
7389(define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7390  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7391	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7392   (clobber (match_scratch:V16QI 2 "=v"))]
7393  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7394  "#"
7395  "&& 1"
7396  [(parallel [(set (match_dup 0)
7397		   (neg:IEEE128 (match_dup 1)))
7398	      (use (match_dup 2))])]
7399{
7400  if (GET_CODE (operands[2]) == SCRATCH)
7401    operands[2] = gen_reg_rtx (V16QImode);
7402
7403  operands[3] = gen_reg_rtx (V16QImode);
7404  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7405}
7406  [(set_attr "length" "8")
7407   (set_attr "type" "vecsimple")])
7408
7409(define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7410  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7411	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7412   (use (match_operand:V16QI 2 "register_operand" "v"))]
7413  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7414  "xxlxor %x0,%x1,%x2"
7415  [(set_attr "type" "veclogical")])
7416
7417;; IEEE 128-bit absolute value
7418(define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7419  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7420	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7421   (clobber (match_scratch:V16QI 2 "=v"))]
7422  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7423  "#"
7424  "&& 1"
7425  [(parallel [(set (match_dup 0)
7426		   (abs:IEEE128 (match_dup 1)))
7427	      (use (match_dup 2))])]
7428{
7429  if (GET_CODE (operands[2]) == SCRATCH)
7430    operands[2] = gen_reg_rtx (V16QImode);
7431
7432  operands[3] = gen_reg_rtx (V16QImode);
7433  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7434}
7435  [(set_attr "length" "8")
7436   (set_attr "type" "vecsimple")])
7437
7438(define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7439  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7440	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7441   (use (match_operand:V16QI 2 "register_operand" "v"))]
7442  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7443  "xxlandc %x0,%x1,%x2"
7444  [(set_attr "type" "veclogical")])
7445
7446;; IEEE 128-bit negative absolute value
7447(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7448  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7449	(neg:IEEE128
7450	 (abs:IEEE128
7451	  (match_operand:IEEE128 1 "register_operand" "wa"))))
7452   (clobber (match_scratch:V16QI 2 "=v"))]
7453  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7454  "#"
7455  "&& 1"
7456  [(parallel [(set (match_dup 0)
7457		   (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
7458	      (use (match_dup 2))])]
7459{
7460  if (GET_CODE (operands[2]) == SCRATCH)
7461    operands[2] = gen_reg_rtx (V16QImode);
7462
7463  operands[3] = gen_reg_rtx (V16QImode);
7464  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7465}
7466  [(set_attr "length" "8")
7467   (set_attr "type" "vecsimple")])
7468
7469(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7470  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7471	(neg:IEEE128
7472	 (abs:IEEE128
7473	  (match_operand:IEEE128 1 "register_operand" "wa"))))
7474   (use (match_operand:V16QI 2 "register_operand" "v"))]
7475  "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7476  "xxlor %x0,%x1,%x2"
7477  [(set_attr "type" "veclogical")])
7478
7479;; Float128 conversion functions.  These expand to library function calls.
7480;; We use expand to convert from IBM double double to IEEE 128-bit
7481;; and trunc for the opposite.
7482(define_expand "extendiftf2"
7483  [(set (match_operand:TF 0 "gpc_reg_operand" "")
7484	(float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7485  "TARGET_FLOAT128"
7486{
7487  rs6000_expand_float128_convert (operands[0], operands[1], false);
7488  DONE;
7489})
7490
7491(define_expand "extendifkf2"
7492  [(set (match_operand:KF 0 "gpc_reg_operand" "")
7493	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7494  "TARGET_FLOAT128"
7495{
7496  rs6000_expand_float128_convert (operands[0], operands[1], false);
7497  DONE;
7498})
7499
7500(define_expand "extendtfkf2"
7501  [(set (match_operand:KF 0 "gpc_reg_operand" "")
7502	(float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7503  "TARGET_FLOAT128"
7504{
7505  rs6000_expand_float128_convert (operands[0], operands[1], false);
7506  DONE;
7507})
7508
7509(define_expand "trunciftf2"
7510  [(set (match_operand:IF 0 "gpc_reg_operand" "")
7511	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7512  "TARGET_FLOAT128"
7513{
7514  rs6000_expand_float128_convert (operands[0], operands[1], false);
7515  DONE;
7516})
7517
7518(define_expand "truncifkf2"
7519  [(set (match_operand:IF 0 "gpc_reg_operand" "")
7520	(float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7521  "TARGET_FLOAT128"
7522{
7523  rs6000_expand_float128_convert (operands[0], operands[1], false);
7524  DONE;
7525})
7526
7527(define_expand "trunckftf2"
7528  [(set (match_operand:TF 0 "gpc_reg_operand" "")
7529	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7530  "TARGET_FLOAT128"
7531{
7532  rs6000_expand_float128_convert (operands[0], operands[1], false);
7533  DONE;
7534})
7535
7536(define_expand "trunctfif2"
7537  [(set (match_operand:IF 0 "gpc_reg_operand" "")
7538	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7539  "TARGET_FLOAT128"
7540{
7541  rs6000_expand_float128_convert (operands[0], operands[1], false);
7542  DONE;
7543})
7544
7545
7546;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7547;; must have 3 arguments, and scratch register constraint must be a single
7548;; constraint.
7549
7550;; Reload patterns to support gpr load/store with misaligned mem.
7551;; and multiple gpr load/store at offset >= 0xfffc
7552(define_expand "reload_<mode>_store"
7553  [(parallel [(match_operand 0 "memory_operand" "=m")
7554              (match_operand 1 "gpc_reg_operand" "r")
7555              (match_operand:GPR 2 "register_operand" "=&b")])]
7556  ""
7557{
7558  rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7559  DONE;
7560})
7561
7562(define_expand "reload_<mode>_load"
7563  [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7564              (match_operand 1 "memory_operand" "m")
7565              (match_operand:GPR 2 "register_operand" "=b")])]
7566  ""
7567{
7568  rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7569  DONE;
7570})
7571
7572
7573;; Reload patterns for various types using the vector registers.  We may need
7574;; an additional base register to convert the reg+offset addressing to reg+reg
7575;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7576;; index register for gpr registers.
7577(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7578  [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7579              (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7580              (match_operand:P 2 "register_operand" "=b")])]
7581  "<P:tptrsize>"
7582{
7583  rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7584  DONE;
7585})
7586
7587(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7588  [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7589              (match_operand:RELOAD 1 "memory_operand" "m")
7590              (match_operand:P 2 "register_operand" "=b")])]
7591  "<P:tptrsize>"
7592{
7593  rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7594  DONE;
7595})
7596
7597
7598;; Reload sometimes tries to move the address to a GPR, and can generate
7599;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7600;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7601
7602(define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7603  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7604	(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7605		       (match_operand:P 2 "reg_or_cint_operand" "rI"))
7606	       (const_int -16)))]
7607  "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7608  "#"
7609  "&& reload_completed"
7610  [(set (match_dup 0)
7611	(plus:P (match_dup 1)
7612		(match_dup 2)))
7613   (set (match_dup 0)
7614	(and:P (match_dup 0)
7615	       (const_int -16)))])
7616
7617;; Power8 merge instructions to allow direct move to/from floating point
7618;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7619;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7620;; value, since it is allocated in reload and not all of the flow information
7621;; is setup for it.  We have two patterns to do the two moves between gprs and
7622;; fprs.  There isn't a dependancy between the two, but we could potentially
7623;; schedule other instructions between the two instructions.
7624
7625(define_insn "p8_fmrgow_<mode>"
7626  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7627	(unspec:FMOVE64X [
7628		(match_operand:DF 1 "register_operand" "d")
7629		(match_operand:DF 2 "register_operand" "d")]
7630			 UNSPEC_P8V_FMRGOW))]
7631  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7632  "fmrgow %0,%1,%2"
7633  [(set_attr "type" "fpsimple")])
7634
7635(define_insn "p8_mtvsrwz"
7636  [(set (match_operand:DF 0 "register_operand" "=d")
7637	(unspec:DF [(match_operand:SI 1 "register_operand" "r")]
7638		   UNSPEC_P8V_MTVSRWZ))]
7639  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7640  "mtvsrwz %x0,%1"
7641  [(set_attr "type" "mftgpr")])
7642
7643(define_insn_and_split "reload_fpr_from_gpr<mode>"
7644  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7645	(unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7646			 UNSPEC_P8V_RELOAD_FROM_GPR))
7647   (clobber (match_operand:IF 2 "register_operand" "=d"))]
7648  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7649  "#"
7650  "&& reload_completed"
7651  [(const_int 0)]
7652{
7653  rtx dest = operands[0];
7654  rtx src = operands[1];
7655  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7656  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7657  rtx gpr_hi_reg = gen_highpart (SImode, src);
7658  rtx gpr_lo_reg = gen_lowpart (SImode, src);
7659
7660  emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
7661  emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
7662  emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
7663  DONE;
7664}
7665  [(set_attr "length" "12")
7666   (set_attr "type" "three")])
7667
7668;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7669(define_insn "p8_mtvsrd_df"
7670  [(set (match_operand:DF 0 "register_operand" "=wa")
7671	(unspec:DF [(match_operand:DI 1 "register_operand" "r")]
7672		   UNSPEC_P8V_MTVSRD))]
7673  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7674  "mtvsrd %x0,%1"
7675  [(set_attr "type" "mftgpr")])
7676
7677(define_insn "p8_xxpermdi_<mode>"
7678  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7679	(unspec:FMOVE128_GPR [
7680		(match_operand:DF 1 "register_operand" "wa")
7681		(match_operand:DF 2 "register_operand" "wa")]
7682		UNSPEC_P8V_XXPERMDI))]
7683  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7684  "xxpermdi %x0,%x1,%x2,0"
7685  [(set_attr "type" "vecperm")])
7686
7687(define_insn_and_split "reload_vsx_from_gpr<mode>"
7688  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7689	(unspec:FMOVE128_GPR
7690	 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7691	 UNSPEC_P8V_RELOAD_FROM_GPR))
7692   (clobber (match_operand:IF 2 "register_operand" "=wa"))]
7693  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7694  "#"
7695  "&& reload_completed"
7696  [(const_int 0)]
7697{
7698  rtx dest = operands[0];
7699  rtx src = operands[1];
7700  /* You might think that we could use op0 as one temp and a DF clobber
7701     as op2, but you'd be wrong.  Secondary reload move patterns don't
7702     check for overlap of the clobber and the destination.  */
7703  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
7704  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
7705  rtx gpr_hi_reg = gen_highpart (DImode, src);
7706  rtx gpr_lo_reg = gen_lowpart (DImode, src);
7707
7708  emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
7709  emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
7710  emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
7711  DONE;
7712}
7713  [(set_attr "length" "12")
7714   (set_attr "type" "three")])
7715
7716(define_split
7717  [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7718	(match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7719  "reload_completed
7720   && (int_reg_operand (operands[0], <MODE>mode)
7721       || int_reg_operand (operands[1], <MODE>mode))
7722   && (!TARGET_DIRECT_MOVE_128
7723       || (!vsx_register_operand (operands[0], <MODE>mode)
7724           && !vsx_register_operand (operands[1], <MODE>mode)))"
7725  [(pc)]
7726{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7727
7728;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7729;; type is stored internally as double precision in the VSX registers, we have
7730;; to convert it from the vector format.
7731(define_insn "p8_mtvsrd_sf"
7732  [(set (match_operand:SF 0 "register_operand" "=wa")
7733	(unspec:SF [(match_operand:DI 1 "register_operand" "r")]
7734		   UNSPEC_P8V_MTVSRD))]
7735  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7736  "mtvsrd %x0,%1"
7737  [(set_attr "type" "mftgpr")])
7738
7739(define_insn_and_split "reload_vsx_from_gprsf"
7740  [(set (match_operand:SF 0 "register_operand" "=wa")
7741	(unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7742		   UNSPEC_P8V_RELOAD_FROM_GPR))
7743   (clobber (match_operand:DI 2 "register_operand" "=r"))]
7744  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7745  "#"
7746  "&& reload_completed"
7747  [(const_int 0)]
7748{
7749  rtx op0 = operands[0];
7750  rtx op1 = operands[1];
7751  rtx op2 = operands[2];
7752  rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7753
7754  /* Move SF value to upper 32-bits for xscvspdpn.  */
7755  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7756  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7757  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7758  DONE;
7759}
7760  [(set_attr "length" "8")
7761   (set_attr "type" "two")])
7762
7763;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7764;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7765;; and then doing a move of that.
7766(define_insn "p8_mfvsrd_3_<mode>"
7767  [(set (match_operand:DF 0 "register_operand" "=r")
7768	(unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7769		   UNSPEC_P8V_RELOAD_FROM_VSX))]
7770  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7771  "mfvsrd %0,%x1"
7772  [(set_attr "type" "mftgpr")])
7773
7774(define_insn_and_split "reload_gpr_from_vsx<mode>"
7775  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7776	(unspec:FMOVE128_GPR
7777	 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7778	 UNSPEC_P8V_RELOAD_FROM_VSX))
7779   (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7780  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7781  "#"
7782  "&& reload_completed"
7783  [(const_int 0)]
7784{
7785  rtx dest = operands[0];
7786  rtx src = operands[1];
7787  rtx tmp = operands[2];
7788  rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7789  rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7790
7791  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7792  emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
7793  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7794  DONE;
7795}
7796  [(set_attr "length" "12")
7797   (set_attr "type" "three")])
7798
7799;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7800;; type is stored internally as double precision, we have to convert it to the
7801;; vector format.
7802
7803(define_insn_and_split "reload_gpr_from_vsxsf"
7804  [(set (match_operand:SF 0 "register_operand" "=r")
7805	(unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7806		   UNSPEC_P8V_RELOAD_FROM_VSX))
7807   (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7808  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7809  "#"
7810  "&& reload_completed"
7811  [(const_int 0)]
7812{
7813  rtx op0 = operands[0];
7814  rtx op1 = operands[1];
7815  rtx op2 = operands[2];
7816  rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7817
7818  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7819  emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7820  emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7821  DONE;
7822}
7823  [(set_attr "length" "12")
7824   (set_attr "type" "three")])
7825
7826(define_insn "p8_mfvsrd_4_disf"
7827  [(set (match_operand:DI 0 "register_operand" "=r")
7828	(unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7829		   UNSPEC_P8V_RELOAD_FROM_VSX))]
7830  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7831  "mfvsrd %0,%x1"
7832  [(set_attr "type" "mftgpr")])
7833
7834
7835;; Next come the multi-word integer load and store and the load and store
7836;; multiple insns.
7837
7838;; List r->r after r->Y, otherwise reload will try to reload a
7839;; non-offsettable address by using r->r which won't make progress.
7840;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7841;; a gpr into a fpr instead of reloading an invalid 'Y' address
7842(define_insn "*movdi_internal32"
7843  [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7844	(match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7845  "! TARGET_POWERPC64
7846   && (gpc_reg_operand (operands[0], DImode)
7847       || gpc_reg_operand (operands[1], DImode))"
7848  "@
7849   #
7850   #
7851   #
7852   stfd%U0%X0 %1,%0
7853   lfd%U1%X1 %0,%1
7854   fmr %0,%1
7855   #"
7856  [(set_attr "type" "store,load,*,fpstore,fpload,fpsimple,*")
7857   (set_attr "size" "64")])
7858
7859(define_split
7860  [(set (match_operand:DI 0 "gpc_reg_operand" "")
7861	(match_operand:DI 1 "const_int_operand" ""))]
7862  "! TARGET_POWERPC64 && reload_completed
7863   && gpr_or_gpr_p (operands[0], operands[1])
7864   && !direct_move_p (operands[0], operands[1])"
7865  [(set (match_dup 2) (match_dup 4))
7866   (set (match_dup 3) (match_dup 1))]
7867  "
7868{
7869  HOST_WIDE_INT value = INTVAL (operands[1]);
7870  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7871				       DImode);
7872  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7873				       DImode);
7874  operands[4] = GEN_INT (value >> 32);
7875  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7876}")
7877
7878(define_split
7879  [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7880        (match_operand:DIFD 1 "input_operand" ""))]
7881  "reload_completed && !TARGET_POWERPC64
7882   && gpr_or_gpr_p (operands[0], operands[1])
7883   && !direct_move_p (operands[0], operands[1])"
7884  [(pc)]
7885{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7886
7887(define_insn "*movdi_internal64"
7888  [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7889	(match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7890  "TARGET_POWERPC64
7891   && (gpc_reg_operand (operands[0], DImode)
7892       || gpc_reg_operand (operands[1], DImode))"
7893  "@
7894   std%U0%X0 %1,%0
7895   ld%U1%X1 %0,%1
7896   mr %0,%1
7897   li %0,%1
7898   lis %0,%v1
7899   #
7900   stfd%U0%X0 %1,%0
7901   lfd%U1%X1 %0,%1
7902   fmr %0,%1
7903   mf%1 %0
7904   mt%0 %1
7905   nop
7906   mftgpr %0,%1
7907   mffgpr %0,%1
7908   mfvsrd %0,%x1
7909   mtvsrd %x0,%1
7910   xxlxor %x0,%x0,%x0"
7911  [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fpsimple,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,veclogical")
7912   (set_attr "size" "64")
7913   (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7914
7915; Some DImode loads are best done as a load of -1 followed by a mask
7916; instruction.
7917(define_split
7918  [(set (match_operand:DI 0 "gpc_reg_operand")
7919	(match_operand:DI 1 "const_int_operand"))]
7920  "TARGET_POWERPC64
7921   && num_insns_constant (operands[1], DImode) > 1
7922   && rs6000_is_valid_and_mask (operands[1], DImode)"
7923  [(set (match_dup 0)
7924	(const_int -1))
7925   (set (match_dup 0)
7926	(and:DI (match_dup 0)
7927		(match_dup 1)))]
7928  "")
7929
7930;; Split a load of a large constant into the appropriate five-instruction
7931;; sequence.  Handle anything in a constant number of insns.
7932;; When non-easy constants can go in the TOC, this should use
7933;; easy_fp_constant predicate.
7934(define_split
7935  [(set (match_operand:DI 0 "gpc_reg_operand" "")
7936	(match_operand:DI 1 "const_int_operand" ""))]
7937  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7938  [(set (match_dup 0) (match_dup 2))
7939   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7940  "
7941{
7942  if (rs6000_emit_set_const (operands[0], operands[1]))
7943    DONE;
7944  else
7945    FAIL;
7946}")
7947
7948(define_split
7949  [(set (match_operand:DI 0 "gpc_reg_operand" "")
7950	(match_operand:DI 1 "const_scalar_int_operand" ""))]
7951  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7952  [(set (match_dup 0) (match_dup 2))
7953   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7954  "
7955{
7956  if (rs6000_emit_set_const (operands[0], operands[1]))
7957    DONE;
7958  else
7959    FAIL;
7960}")
7961
7962;; TImode/PTImode is similar, except that we usually want to compute the
7963;; address into a register and use lsi/stsi (the exception is during reload).
7964
7965(define_insn "*mov<mode>_string"
7966  [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7967	(match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7968  "! TARGET_POWERPC64
7969   && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7970   && (gpc_reg_operand (operands[0], <MODE>mode)
7971       || gpc_reg_operand (operands[1], <MODE>mode))"
7972  "*
7973{
7974  switch (which_alternative)
7975    {
7976    default:
7977      gcc_unreachable ();
7978    case 0:
7979      if (TARGET_STRING)
7980        return \"stswi %1,%P0,16\";
7981    case 1:
7982      return \"#\";
7983    case 2:
7984      /* If the address is not used in the output, we can use lsi.  Otherwise,
7985	 fall through to generating four loads.  */
7986      if (TARGET_STRING
7987          && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7988	return \"lswi %0,%P1,16\";
7989      /* ... fall through ...  */
7990    case 3:
7991    case 4:
7992    case 5:
7993      return \"#\";
7994    }
7995}"
7996  [(set_attr "type" "store,store,load,load,*,*")
7997   (set_attr "update" "yes")
7998   (set_attr "indexed" "yes")
7999   (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8000   			                  (const_string "always")
8001					  (const_string "conditional")))])
8002
8003(define_insn "*mov<mode>_ppc64"
8004  [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8005	(match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8006  "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8007   && (gpc_reg_operand (operands[0], <MODE>mode)
8008       || gpc_reg_operand (operands[1], <MODE>mode)))"
8009{
8010  return rs6000_output_move_128bit (operands);
8011}
8012  [(set_attr "type" "store,store,load,load,*,*")
8013   (set_attr "length" "8")])
8014
8015(define_split
8016  [(set (match_operand:TI2 0 "int_reg_operand" "")
8017	(match_operand:TI2 1 "const_scalar_int_operand" ""))]
8018  "TARGET_POWERPC64
8019   && (VECTOR_MEM_NONE_P (<MODE>mode)
8020       || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8021  [(set (match_dup 2) (match_dup 4))
8022   (set (match_dup 3) (match_dup 5))]
8023  "
8024{
8025  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8026				       <MODE>mode);
8027  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8028				       <MODE>mode);
8029  if (CONST_WIDE_INT_P (operands[1]))
8030    {
8031      operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8032      operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8033    }
8034  else if (CONST_INT_P (operands[1]))
8035    {
8036      operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8037      operands[5] = operands[1];
8038    }
8039  else
8040    FAIL;
8041}")
8042
8043(define_split
8044  [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8045        (match_operand:TI2 1 "input_operand" ""))]
8046  "reload_completed
8047   && gpr_or_gpr_p (operands[0], operands[1])
8048   && !direct_move_p (operands[0], operands[1])
8049   && !quad_load_store_p (operands[0], operands[1])"
8050  [(pc)]
8051{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8052
8053(define_expand "load_multiple"
8054  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8055			  (match_operand:SI 1 "" ""))
8056		     (use (match_operand:SI 2 "" ""))])]
8057  "TARGET_STRING && !TARGET_POWERPC64"
8058  "
8059{
8060  int regno;
8061  int count;
8062  rtx op1;
8063  int i;
8064
8065  /* Support only loading a constant number of fixed-point registers from
8066     memory and only bother with this if more than two; the machine
8067     doesn't support more than eight.  */
8068  if (GET_CODE (operands[2]) != CONST_INT
8069      || INTVAL (operands[2]) <= 2
8070      || INTVAL (operands[2]) > 8
8071      || GET_CODE (operands[1]) != MEM
8072      || GET_CODE (operands[0]) != REG
8073      || REGNO (operands[0]) >= 32)
8074    FAIL;
8075
8076  count = INTVAL (operands[2]);
8077  regno = REGNO (operands[0]);
8078
8079  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8080  op1 = replace_equiv_address (operands[1],
8081			       force_reg (SImode, XEXP (operands[1], 0)));
8082
8083  for (i = 0; i < count; i++)
8084    XVECEXP (operands[3], 0, i)
8085      = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8086		     adjust_address_nv (op1, SImode, i * 4));
8087}")
8088
8089(define_insn "*ldmsi8"
8090  [(match_parallel 0 "load_multiple_operation"
8091    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8092          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8093     (set (match_operand:SI 3 "gpc_reg_operand" "")
8094          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8095     (set (match_operand:SI 4 "gpc_reg_operand" "")
8096          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8097     (set (match_operand:SI 5 "gpc_reg_operand" "")
8098          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8099     (set (match_operand:SI 6 "gpc_reg_operand" "")
8100          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8101     (set (match_operand:SI 7 "gpc_reg_operand" "")
8102          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8103     (set (match_operand:SI 8 "gpc_reg_operand" "")
8104          (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8105     (set (match_operand:SI 9 "gpc_reg_operand" "")
8106          (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8107  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8108  "*
8109{ return rs6000_output_load_multiple (operands); }"
8110  [(set_attr "type" "load")
8111   (set_attr "update" "yes")
8112   (set_attr "indexed" "yes")
8113   (set_attr "length" "32")])
8114
8115(define_insn "*ldmsi7"
8116  [(match_parallel 0 "load_multiple_operation"
8117    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8118          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8119     (set (match_operand:SI 3 "gpc_reg_operand" "")
8120          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8121     (set (match_operand:SI 4 "gpc_reg_operand" "")
8122          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8123     (set (match_operand:SI 5 "gpc_reg_operand" "")
8124          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8125     (set (match_operand:SI 6 "gpc_reg_operand" "")
8126          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8127     (set (match_operand:SI 7 "gpc_reg_operand" "")
8128          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8129     (set (match_operand:SI 8 "gpc_reg_operand" "")
8130          (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8131  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8132  "*
8133{ return rs6000_output_load_multiple (operands); }"
8134  [(set_attr "type" "load")
8135   (set_attr "update" "yes")
8136   (set_attr "indexed" "yes")
8137   (set_attr "length" "32")])
8138
8139(define_insn "*ldmsi6"
8140  [(match_parallel 0 "load_multiple_operation"
8141    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8142          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8143     (set (match_operand:SI 3 "gpc_reg_operand" "")
8144          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8145     (set (match_operand:SI 4 "gpc_reg_operand" "")
8146          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8147     (set (match_operand:SI 5 "gpc_reg_operand" "")
8148          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8149     (set (match_operand:SI 6 "gpc_reg_operand" "")
8150          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8151     (set (match_operand:SI 7 "gpc_reg_operand" "")
8152          (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8153  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8154  "*
8155{ return rs6000_output_load_multiple (operands); }"
8156  [(set_attr "type" "load")
8157   (set_attr "update" "yes")
8158   (set_attr "indexed" "yes")
8159   (set_attr "length" "32")])
8160
8161(define_insn "*ldmsi5"
8162  [(match_parallel 0 "load_multiple_operation"
8163    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8164          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8165     (set (match_operand:SI 3 "gpc_reg_operand" "")
8166          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8167     (set (match_operand:SI 4 "gpc_reg_operand" "")
8168          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8169     (set (match_operand:SI 5 "gpc_reg_operand" "")
8170          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8171     (set (match_operand:SI 6 "gpc_reg_operand" "")
8172          (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8173  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8174  "*
8175{ return rs6000_output_load_multiple (operands); }"
8176  [(set_attr "type" "load")
8177   (set_attr "update" "yes")
8178   (set_attr "indexed" "yes")
8179   (set_attr "length" "32")])
8180
8181(define_insn "*ldmsi4"
8182  [(match_parallel 0 "load_multiple_operation"
8183    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8184          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8185     (set (match_operand:SI 3 "gpc_reg_operand" "")
8186          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8187     (set (match_operand:SI 4 "gpc_reg_operand" "")
8188          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8189     (set (match_operand:SI 5 "gpc_reg_operand" "")
8190          (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8191  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8192  "*
8193{ return rs6000_output_load_multiple (operands); }"
8194  [(set_attr "type" "load")
8195   (set_attr "update" "yes")
8196   (set_attr "indexed" "yes")
8197   (set_attr "length" "32")])
8198
8199(define_insn "*ldmsi3"
8200  [(match_parallel 0 "load_multiple_operation"
8201    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8202          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8203     (set (match_operand:SI 3 "gpc_reg_operand" "")
8204          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8205     (set (match_operand:SI 4 "gpc_reg_operand" "")
8206          (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8207  "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8208  "*
8209{ return rs6000_output_load_multiple (operands); }"
8210  [(set_attr "type" "load")
8211   (set_attr "update" "yes")
8212   (set_attr "indexed" "yes")
8213   (set_attr "length" "32")])
8214
8215(define_expand "store_multiple"
8216  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8217			  (match_operand:SI 1 "" ""))
8218		     (clobber (scratch:SI))
8219		     (use (match_operand:SI 2 "" ""))])]
8220  "TARGET_STRING && !TARGET_POWERPC64"
8221  "
8222{
8223  int regno;
8224  int count;
8225  rtx to;
8226  rtx op0;
8227  int i;
8228
8229  /* Support only storing a constant number of fixed-point registers to
8230     memory and only bother with this if more than two; the machine
8231     doesn't support more than eight.  */
8232  if (GET_CODE (operands[2]) != CONST_INT
8233      || INTVAL (operands[2]) <= 2
8234      || INTVAL (operands[2]) > 8
8235      || GET_CODE (operands[0]) != MEM
8236      || GET_CODE (operands[1]) != REG
8237      || REGNO (operands[1]) >= 32)
8238    FAIL;
8239
8240  count = INTVAL (operands[2]);
8241  regno = REGNO (operands[1]);
8242
8243  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8244  to = force_reg (SImode, XEXP (operands[0], 0));
8245  op0 = replace_equiv_address (operands[0], to);
8246
8247  XVECEXP (operands[3], 0, 0)
8248    = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8249  XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8250						 gen_rtx_SCRATCH (SImode));
8251
8252  for (i = 1; i < count; i++)
8253    XVECEXP (operands[3], 0, i + 1)
8254      = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8255		     gen_rtx_REG (SImode, regno + i));
8256}")
8257
8258(define_insn "*stmsi8"
8259  [(match_parallel 0 "store_multiple_operation"
8260    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8261	  (match_operand:SI 2 "gpc_reg_operand" "r"))
8262     (clobber (match_scratch:SI 3 "=X"))
8263     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8264	  (match_operand:SI 4 "gpc_reg_operand" "r"))
8265     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8266	  (match_operand:SI 5 "gpc_reg_operand" "r"))
8267     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8268	  (match_operand:SI 6 "gpc_reg_operand" "r"))
8269     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8270	  (match_operand:SI 7 "gpc_reg_operand" "r"))
8271     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8272	  (match_operand:SI 8 "gpc_reg_operand" "r"))
8273     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8274	  (match_operand:SI 9 "gpc_reg_operand" "r"))
8275     (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8276	  (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8277  "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8278  "stswi %2,%1,%O0"
8279  [(set_attr "type" "store")
8280   (set_attr "update" "yes")
8281   (set_attr "indexed" "yes")
8282   (set_attr "cell_micro" "always")])
8283
8284(define_insn "*stmsi7"
8285  [(match_parallel 0 "store_multiple_operation"
8286    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8287	  (match_operand:SI 2 "gpc_reg_operand" "r"))
8288     (clobber (match_scratch:SI 3 "=X"))
8289     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8290	  (match_operand:SI 4 "gpc_reg_operand" "r"))
8291     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8292	  (match_operand:SI 5 "gpc_reg_operand" "r"))
8293     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8294	  (match_operand:SI 6 "gpc_reg_operand" "r"))
8295     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8296	  (match_operand:SI 7 "gpc_reg_operand" "r"))
8297     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8298	  (match_operand:SI 8 "gpc_reg_operand" "r"))
8299     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8300	  (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8301  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8302  "stswi %2,%1,%O0"
8303  [(set_attr "type" "store")
8304   (set_attr "update" "yes")
8305   (set_attr "indexed" "yes")
8306   (set_attr "cell_micro" "always")])
8307
8308(define_insn "*stmsi6"
8309  [(match_parallel 0 "store_multiple_operation"
8310    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8311	  (match_operand:SI 2 "gpc_reg_operand" "r"))
8312     (clobber (match_scratch:SI 3 "=X"))
8313     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8314	  (match_operand:SI 4 "gpc_reg_operand" "r"))
8315     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8316	  (match_operand:SI 5 "gpc_reg_operand" "r"))
8317     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8318	  (match_operand:SI 6 "gpc_reg_operand" "r"))
8319     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8320	  (match_operand:SI 7 "gpc_reg_operand" "r"))
8321     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8322	  (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8323  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8324  "stswi %2,%1,%O0"
8325  [(set_attr "type" "store")
8326   (set_attr "update" "yes")
8327   (set_attr "indexed" "yes")
8328   (set_attr "cell_micro" "always")])
8329
8330(define_insn "*stmsi5"
8331  [(match_parallel 0 "store_multiple_operation"
8332    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8333	  (match_operand:SI 2 "gpc_reg_operand" "r"))
8334     (clobber (match_scratch:SI 3 "=X"))
8335     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8336	  (match_operand:SI 4 "gpc_reg_operand" "r"))
8337     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8338	  (match_operand:SI 5 "gpc_reg_operand" "r"))
8339     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8340	  (match_operand:SI 6 "gpc_reg_operand" "r"))
8341     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8342	  (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8343  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8344  "stswi %2,%1,%O0"
8345  [(set_attr "type" "store")
8346   (set_attr "update" "yes")
8347   (set_attr "indexed" "yes")
8348   (set_attr "cell_micro" "always")])
8349
8350(define_insn "*stmsi4"
8351  [(match_parallel 0 "store_multiple_operation"
8352    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8353	  (match_operand:SI 2 "gpc_reg_operand" "r"))
8354     (clobber (match_scratch:SI 3 "=X"))
8355     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8356	  (match_operand:SI 4 "gpc_reg_operand" "r"))
8357     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8358	  (match_operand:SI 5 "gpc_reg_operand" "r"))
8359     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8360	  (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8361  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8362  "stswi %2,%1,%O0"
8363  [(set_attr "type" "store")
8364   (set_attr "update" "yes")
8365   (set_attr "indexed" "yes")
8366   (set_attr "cell_micro" "always")])
8367
8368(define_insn "*stmsi3"
8369  [(match_parallel 0 "store_multiple_operation"
8370    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8371	  (match_operand:SI 2 "gpc_reg_operand" "r"))
8372     (clobber (match_scratch:SI 3 "=X"))
8373     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8374	  (match_operand:SI 4 "gpc_reg_operand" "r"))
8375     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8376	  (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8377  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8378  "stswi %2,%1,%O0"
8379  [(set_attr "type" "store")
8380   (set_attr "update" "yes")
8381   (set_attr "indexed" "yes")
8382   (set_attr "cell_micro" "always")])
8383
8384(define_expand "setmemsi"
8385  [(parallel [(set (match_operand:BLK 0 "" "")
8386		   (match_operand 2 "const_int_operand" ""))
8387	      (use (match_operand:SI 1 "" ""))
8388	      (use (match_operand:SI 3 "" ""))])]
8389  ""
8390  "
8391{
8392  /* If value to set is not zero, use the library routine.  */
8393  if (operands[2] != const0_rtx)
8394    FAIL;
8395
8396  if (expand_block_clear (operands))
8397    DONE;
8398  else
8399    FAIL;
8400}")
8401
8402;; String/block move insn.
8403;; Argument 0 is the destination
8404;; Argument 1 is the source
8405;; Argument 2 is the length
8406;; Argument 3 is the alignment
8407
8408(define_expand "movmemsi"
8409  [(parallel [(set (match_operand:BLK 0 "" "")
8410		   (match_operand:BLK 1 "" ""))
8411	      (use (match_operand:SI 2 "" ""))
8412	      (use (match_operand:SI 3 "" ""))])]
8413  ""
8414  "
8415{
8416  if (expand_block_move (operands))
8417    DONE;
8418  else
8419    FAIL;
8420}")
8421
8422;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8423;; register allocator doesn't have a clue about allocating 8 word registers.
8424;; rD/rS = r5 is preferred, efficient form.
8425(define_expand "movmemsi_8reg"
8426  [(parallel [(set (match_operand 0 "" "")
8427		   (match_operand 1 "" ""))
8428	      (use (match_operand 2 "" ""))
8429	      (use (match_operand 3 "" ""))
8430	      (clobber (reg:SI  5))
8431	      (clobber (reg:SI  6))
8432	      (clobber (reg:SI  7))
8433	      (clobber (reg:SI  8))
8434	      (clobber (reg:SI  9))
8435	      (clobber (reg:SI 10))
8436	      (clobber (reg:SI 11))
8437	      (clobber (reg:SI 12))
8438	      (clobber (match_scratch:SI 4 ""))])]
8439  "TARGET_STRING"
8440  "")
8441
8442(define_insn ""
8443  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8444	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8445   (use (match_operand:SI 2 "immediate_operand" "i"))
8446   (use (match_operand:SI 3 "immediate_operand" "i"))
8447   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8448   (clobber (reg:SI  6))
8449   (clobber (reg:SI  7))
8450   (clobber (reg:SI  8))
8451   (clobber (reg:SI  9))
8452   (clobber (reg:SI 10))
8453   (clobber (reg:SI 11))
8454   (clobber (reg:SI 12))
8455   (clobber (match_scratch:SI 5 "=X"))]
8456  "TARGET_STRING
8457   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8458       || INTVAL (operands[2]) == 0)
8459   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8460   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8461   && REGNO (operands[4]) == 5"
8462  "lswi %4,%1,%2\;stswi %4,%0,%2"
8463  [(set_attr "type" "store")
8464   (set_attr "update" "yes")
8465   (set_attr "indexed" "yes")
8466   (set_attr "cell_micro" "always")
8467   (set_attr "length" "8")])
8468
8469;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8470;; register allocator doesn't have a clue about allocating 6 word registers.
8471;; rD/rS = r5 is preferred, efficient form.
8472(define_expand "movmemsi_6reg"
8473  [(parallel [(set (match_operand 0 "" "")
8474		   (match_operand 1 "" ""))
8475	      (use (match_operand 2 "" ""))
8476	      (use (match_operand 3 "" ""))
8477	      (clobber (reg:SI  5))
8478	      (clobber (reg:SI  6))
8479	      (clobber (reg:SI  7))
8480	      (clobber (reg:SI  8))
8481	      (clobber (reg:SI  9))
8482	      (clobber (reg:SI 10))
8483	      (clobber (match_scratch:SI 4 ""))])]
8484  "TARGET_STRING"
8485  "")
8486
8487(define_insn ""
8488  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8489	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8490   (use (match_operand:SI 2 "immediate_operand" "i"))
8491   (use (match_operand:SI 3 "immediate_operand" "i"))
8492   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8493   (clobber (reg:SI  6))
8494   (clobber (reg:SI  7))
8495   (clobber (reg:SI  8))
8496   (clobber (reg:SI  9))
8497   (clobber (reg:SI 10))
8498   (clobber (match_scratch:SI 5 "=X"))]
8499  "TARGET_STRING
8500   && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8501   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8502   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8503   && REGNO (operands[4]) == 5"
8504  "lswi %4,%1,%2\;stswi %4,%0,%2"
8505  [(set_attr "type" "store")
8506   (set_attr "update" "yes")
8507   (set_attr "indexed" "yes")
8508   (set_attr "cell_micro" "always")
8509   (set_attr "length" "8")])
8510
8511;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8512;; problems with TImode.
8513;; rD/rS = r5 is preferred, efficient form.
8514(define_expand "movmemsi_4reg"
8515  [(parallel [(set (match_operand 0 "" "")
8516		   (match_operand 1 "" ""))
8517	      (use (match_operand 2 "" ""))
8518	      (use (match_operand 3 "" ""))
8519	      (clobber (reg:SI 5))
8520	      (clobber (reg:SI 6))
8521	      (clobber (reg:SI 7))
8522	      (clobber (reg:SI 8))
8523	      (clobber (match_scratch:SI 4 ""))])]
8524  "TARGET_STRING"
8525  "")
8526
8527(define_insn ""
8528  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8529	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8530   (use (match_operand:SI 2 "immediate_operand" "i"))
8531   (use (match_operand:SI 3 "immediate_operand" "i"))
8532   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8533   (clobber (reg:SI 6))
8534   (clobber (reg:SI 7))
8535   (clobber (reg:SI 8))
8536   (clobber (match_scratch:SI 5 "=X"))]
8537  "TARGET_STRING
8538   && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8539   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8540   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8541   && REGNO (operands[4]) == 5"
8542  "lswi %4,%1,%2\;stswi %4,%0,%2"
8543  [(set_attr "type" "store")
8544   (set_attr "update" "yes")
8545   (set_attr "indexed" "yes")
8546   (set_attr "cell_micro" "always")
8547   (set_attr "length" "8")])
8548
8549;; Move up to 8 bytes at a time.
8550(define_expand "movmemsi_2reg"
8551  [(parallel [(set (match_operand 0 "" "")
8552		   (match_operand 1 "" ""))
8553	      (use (match_operand 2 "" ""))
8554	      (use (match_operand 3 "" ""))
8555	      (clobber (match_scratch:DI 4 ""))
8556	      (clobber (match_scratch:SI 5 ""))])]
8557  "TARGET_STRING && ! TARGET_POWERPC64"
8558  "")
8559
8560(define_insn ""
8561  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8562	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8563   (use (match_operand:SI 2 "immediate_operand" "i"))
8564   (use (match_operand:SI 3 "immediate_operand" "i"))
8565   (clobber (match_scratch:DI 4 "=&r"))
8566   (clobber (match_scratch:SI 5 "=X"))]
8567  "TARGET_STRING && ! TARGET_POWERPC64
8568   && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8569  "lswi %4,%1,%2\;stswi %4,%0,%2"
8570  [(set_attr "type" "store")
8571   (set_attr "update" "yes")
8572   (set_attr "indexed" "yes")
8573   (set_attr "cell_micro" "always")
8574   (set_attr "length" "8")])
8575
8576;; Move up to 4 bytes at a time.
8577(define_expand "movmemsi_1reg"
8578  [(parallel [(set (match_operand 0 "" "")
8579		   (match_operand 1 "" ""))
8580	      (use (match_operand 2 "" ""))
8581	      (use (match_operand 3 "" ""))
8582	      (clobber (match_scratch:SI 4 ""))
8583	      (clobber (match_scratch:SI 5 ""))])]
8584  "TARGET_STRING"
8585  "")
8586
8587(define_insn ""
8588  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8589	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8590   (use (match_operand:SI 2 "immediate_operand" "i"))
8591   (use (match_operand:SI 3 "immediate_operand" "i"))
8592   (clobber (match_scratch:SI 4 "=&r"))
8593   (clobber (match_scratch:SI 5 "=X"))]
8594  "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8595  "lswi %4,%1,%2\;stswi %4,%0,%2"
8596  [(set_attr "type" "store")
8597   (set_attr "update" "yes")
8598   (set_attr "indexed" "yes")
8599   (set_attr "cell_micro" "always")
8600   (set_attr "length" "8")])
8601
8602;; Define insns that do load or store with update.  Some of these we can
8603;; get by using pre-decrement or pre-increment, but the hardware can also
8604;; do cases where the increment is not the size of the object.
8605;;
8606;; In all these cases, we use operands 0 and 1 for the register being
8607;; incremented because those are the operands that local-alloc will
8608;; tie and these are the pair most likely to be tieable (and the ones
8609;; that will benefit the most).
8610
8611(define_insn "*movdi_update1"
8612  [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8613	(mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8614			 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8615   (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8616	(plus:DI (match_dup 1) (match_dup 2)))]
8617  "TARGET_POWERPC64 && TARGET_UPDATE
8618   && (!avoiding_indexed_address_p (DImode)
8619       || !gpc_reg_operand (operands[2], DImode))"
8620  "@
8621   ldux %3,%0,%2
8622   ldu %3,%2(%0)"
8623  [(set_attr "type" "load")
8624   (set_attr "update" "yes")
8625   (set_attr "indexed" "yes,no")])
8626
8627(define_insn "movdi_<mode>_update"
8628  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8629			 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8630	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
8631   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8632	(plus:P (match_dup 1) (match_dup 2)))]
8633  "TARGET_POWERPC64 && TARGET_UPDATE
8634   && (!avoiding_indexed_address_p (Pmode)
8635       || !gpc_reg_operand (operands[2], Pmode)
8636       || (REG_P (operands[0])
8637	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8638  "@
8639   stdux %3,%0,%2
8640   stdu %3,%2(%0)"
8641  [(set_attr "type" "store")
8642   (set_attr "update" "yes")
8643   (set_attr "indexed" "yes,no")])
8644
8645;; This pattern is only conditional on TARGET_POWERPC64, as it is
8646;; needed for stack allocation, even if the user passes -mno-update.
8647(define_insn "movdi_<mode>_update_stack"
8648  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8649			 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8650	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
8651   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8652	(plus:P (match_dup 1) (match_dup 2)))]
8653  "TARGET_POWERPC64"
8654  "@
8655   stdux %3,%0,%2
8656   stdu %3,%2(%0)"
8657  [(set_attr "type" "store")
8658   (set_attr "update" "yes")
8659   (set_attr "indexed" "yes,no")])
8660
8661(define_insn "*movsi_update1"
8662  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8663	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8664			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8665   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8666	(plus:SI (match_dup 1) (match_dup 2)))]
8667  "TARGET_UPDATE
8668   && (!avoiding_indexed_address_p (SImode)
8669       || !gpc_reg_operand (operands[2], SImode))"
8670  "@
8671   lwzux %3,%0,%2
8672   lwzu %3,%2(%0)"
8673  [(set_attr "type" "load")
8674   (set_attr "update" "yes")
8675   (set_attr "indexed" "yes,no")])
8676
8677(define_insn "*movsi_update2"
8678  [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8679	(sign_extend:DI
8680	 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8681			  (match_operand:DI 2 "gpc_reg_operand" "r")))))
8682   (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8683	(plus:DI (match_dup 1) (match_dup 2)))]
8684  "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8685   && !avoiding_indexed_address_p (DImode)"
8686  "lwaux %3,%0,%2"
8687  [(set_attr "type" "load")
8688   (set_attr "sign_extend" "yes")
8689   (set_attr "update" "yes")
8690   (set_attr "indexed" "yes")])
8691
8692(define_insn "movsi_update"
8693  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8694			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8695	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
8696   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8697	(plus:SI (match_dup 1) (match_dup 2)))]
8698  "TARGET_UPDATE
8699   && (!avoiding_indexed_address_p (SImode)
8700       || !gpc_reg_operand (operands[2], SImode)
8701       || (REG_P (operands[0])
8702	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8703  "@
8704   stwux %3,%0,%2
8705   stwu %3,%2(%0)"
8706  [(set_attr "type" "store")
8707   (set_attr "update" "yes")
8708   (set_attr "indexed" "yes,no")])
8709
8710;; This is an unconditional pattern; needed for stack allocation, even
8711;; if the user passes -mno-update.
8712(define_insn "movsi_update_stack"
8713  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8714			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8715	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
8716   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8717	(plus:SI (match_dup 1) (match_dup 2)))]
8718  ""
8719  "@
8720   stwux %3,%0,%2
8721   stwu %3,%2(%0)"
8722  [(set_attr "type" "store")
8723   (set_attr "update" "yes")
8724   (set_attr "indexed" "yes,no")])
8725
8726(define_insn "*movhi_update1"
8727  [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8728	(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8729			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8730   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8731	(plus:SI (match_dup 1) (match_dup 2)))]
8732  "TARGET_UPDATE
8733   && (!avoiding_indexed_address_p (SImode)
8734       || !gpc_reg_operand (operands[2], SImode))"
8735  "@
8736   lhzux %3,%0,%2
8737   lhzu %3,%2(%0)"
8738  [(set_attr "type" "load")
8739   (set_attr "update" "yes")
8740   (set_attr "indexed" "yes,no")])
8741
8742(define_insn "*movhi_update2"
8743  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8744	(zero_extend:SI
8745	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8746			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8747   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8748	(plus:SI (match_dup 1) (match_dup 2)))]
8749  "TARGET_UPDATE
8750   && (!avoiding_indexed_address_p (SImode)
8751       || !gpc_reg_operand (operands[2], SImode))"
8752  "@
8753   lhzux %3,%0,%2
8754   lhzu %3,%2(%0)"
8755  [(set_attr "type" "load")
8756   (set_attr "update" "yes")
8757   (set_attr "indexed" "yes,no")])
8758
8759(define_insn "*movhi_update3"
8760  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8761	(sign_extend:SI
8762	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8763			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8764   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8765	(plus:SI (match_dup 1) (match_dup 2)))]
8766  "TARGET_UPDATE && rs6000_gen_cell_microcode
8767   && (!avoiding_indexed_address_p (SImode)
8768       || !gpc_reg_operand (operands[2], SImode))"
8769  "@
8770   lhaux %3,%0,%2
8771   lhau %3,%2(%0)"
8772  [(set_attr "type" "load")
8773   (set_attr "sign_extend" "yes")
8774   (set_attr "update" "yes")
8775   (set_attr "indexed" "yes,no")])
8776
8777(define_insn "*movhi_update4"
8778  [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8779			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8780	(match_operand:HI 3 "gpc_reg_operand" "r,r"))
8781   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8782	(plus:SI (match_dup 1) (match_dup 2)))]
8783  "TARGET_UPDATE
8784   && (!avoiding_indexed_address_p (SImode)
8785       || !gpc_reg_operand (operands[2], SImode))"
8786  "@
8787   sthux %3,%0,%2
8788   sthu %3,%2(%0)"
8789  [(set_attr "type" "store")
8790   (set_attr "update" "yes")
8791   (set_attr "indexed" "yes,no")])
8792
8793(define_insn "*movqi_update1"
8794  [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8795	(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8796			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8797   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8798	(plus:SI (match_dup 1) (match_dup 2)))]
8799  "TARGET_UPDATE
8800   && (!avoiding_indexed_address_p (SImode)
8801       || !gpc_reg_operand (operands[2], SImode))"
8802  "@
8803   lbzux %3,%0,%2
8804   lbzu %3,%2(%0)"
8805  [(set_attr "type" "load")
8806   (set_attr "update" "yes")
8807   (set_attr "indexed" "yes,no")])
8808
8809(define_insn "*movqi_update2"
8810  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8811	(zero_extend:SI
8812	 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8813			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8814   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8815	(plus:SI (match_dup 1) (match_dup 2)))]
8816  "TARGET_UPDATE
8817   && (!avoiding_indexed_address_p (SImode)
8818       || !gpc_reg_operand (operands[2], SImode))"
8819  "@
8820   lbzux %3,%0,%2
8821   lbzu %3,%2(%0)"
8822  [(set_attr "type" "load")
8823   (set_attr "update" "yes")
8824   (set_attr "indexed" "yes,no")])
8825
8826(define_insn "*movqi_update3"
8827  [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8828			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8829	(match_operand:QI 3 "gpc_reg_operand" "r,r"))
8830   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8831	(plus:SI (match_dup 1) (match_dup 2)))]
8832  "TARGET_UPDATE
8833   && (!avoiding_indexed_address_p (SImode)
8834       || !gpc_reg_operand (operands[2], SImode))"
8835  "@
8836   stbux %3,%0,%2
8837   stbu %3,%2(%0)"
8838  [(set_attr "type" "store")
8839   (set_attr "update" "yes")
8840   (set_attr "indexed" "yes,no")])
8841
8842(define_insn "*movsf_update1"
8843  [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8844	(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8845			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8846   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8847	(plus:SI (match_dup 1) (match_dup 2)))]
8848  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8849   && (!avoiding_indexed_address_p (SImode)
8850       || !gpc_reg_operand (operands[2], SImode))"
8851  "@
8852   lfsux %3,%0,%2
8853   lfsu %3,%2(%0)"
8854  [(set_attr "type" "fpload")
8855   (set_attr "update" "yes")
8856   (set_attr "indexed" "yes,no")])
8857
8858(define_insn "*movsf_update2"
8859  [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8860			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8861	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
8862   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8863	(plus:SI (match_dup 1) (match_dup 2)))]
8864  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8865   && (!avoiding_indexed_address_p (SImode)
8866       || !gpc_reg_operand (operands[2], SImode))"
8867  "@
8868   stfsux %3,%0,%2
8869   stfsu %3,%2(%0)"
8870  [(set_attr "type" "fpstore")
8871   (set_attr "update" "yes")
8872   (set_attr "indexed" "yes,no")])
8873
8874(define_insn "*movsf_update3"
8875  [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8876	(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8877			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8878   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8879	(plus:SI (match_dup 1) (match_dup 2)))]
8880  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8881   && (!avoiding_indexed_address_p (SImode)
8882       || !gpc_reg_operand (operands[2], SImode))"
8883  "@
8884   lwzux %3,%0,%2
8885   lwzu %3,%2(%0)"
8886  [(set_attr "type" "load")
8887   (set_attr "update" "yes")
8888   (set_attr "indexed" "yes,no")])
8889
8890(define_insn "*movsf_update4"
8891  [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8892			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8893	(match_operand:SF 3 "gpc_reg_operand" "r,r"))
8894   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8895	(plus:SI (match_dup 1) (match_dup 2)))]
8896  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8897   && (!avoiding_indexed_address_p (SImode)
8898       || !gpc_reg_operand (operands[2], SImode))"
8899  "@
8900   stwux %3,%0,%2
8901   stwu %3,%2(%0)"
8902  [(set_attr "type" "store")
8903   (set_attr "update" "yes")
8904   (set_attr "indexed" "yes,no")])
8905
8906(define_insn "*movdf_update1"
8907  [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8908	(mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8909			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8910   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8911	(plus:SI (match_dup 1) (match_dup 2)))]
8912  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8913   && (!avoiding_indexed_address_p (SImode)
8914       || !gpc_reg_operand (operands[2], SImode))"
8915  "@
8916   lfdux %3,%0,%2
8917   lfdu %3,%2(%0)"
8918  [(set_attr "type" "fpload")
8919   (set_attr "update" "yes")
8920   (set_attr "indexed" "yes,no")
8921   (set_attr "size" "64")])
8922
8923(define_insn "*movdf_update2"
8924  [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8925			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8926	(match_operand:DF 3 "gpc_reg_operand" "d,d"))
8927   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8928	(plus:SI (match_dup 1) (match_dup 2)))]
8929  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8930   && (!avoiding_indexed_address_p (SImode)
8931       || !gpc_reg_operand (operands[2], SImode))"
8932  "@
8933   stfdux %3,%0,%2
8934   stfdu %3,%2(%0)"
8935  [(set_attr "type" "fpstore")
8936   (set_attr "update" "yes")
8937   (set_attr "indexed" "yes,no")])
8938
8939
8940;; After inserting conditional returns we can sometimes have
8941;; unnecessary register moves.  Unfortunately we cannot have a
8942;; modeless peephole here, because some single SImode sets have early
8943;; clobber outputs.  Although those sets expand to multi-ppc-insn
8944;; sequences, using get_attr_length here will smash the operands
8945;; array.  Neither is there an early_cobbler_p predicate.
8946;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8947;; Also this optimization interferes with scalars going into
8948;; altivec registers (the code does reloading through the FPRs).
8949(define_peephole2
8950  [(set (match_operand:DF 0 "gpc_reg_operand" "")
8951	(match_operand:DF 1 "any_operand" ""))
8952   (set (match_operand:DF 2 "gpc_reg_operand" "")
8953	(match_dup 0))]
8954  "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8955   && !TARGET_UPPER_REGS_DF
8956   && peep2_reg_dead_p (2, operands[0])"
8957  [(set (match_dup 2) (match_dup 1))])
8958
8959(define_peephole2
8960  [(set (match_operand:SF 0 "gpc_reg_operand" "")
8961	(match_operand:SF 1 "any_operand" ""))
8962   (set (match_operand:SF 2 "gpc_reg_operand" "")
8963	(match_dup 0))]
8964  "!TARGET_UPPER_REGS_SF
8965   && peep2_reg_dead_p (2, operands[0])"
8966  [(set (match_dup 2) (match_dup 1))])
8967
8968
8969;; TLS support.
8970
8971;; Mode attributes for different ABIs.
8972(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8973(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8974(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8975(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8976
8977(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8978  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8979        (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8980	      (match_operand 4 "" "g")))
8981   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8982	 	    (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8983		   UNSPEC_TLSGD)
8984   (clobber (reg:SI LR_REGNO))]
8985  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8986{
8987  if (TARGET_CMODEL != CMODEL_SMALL)
8988    return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8989	   "bl %z3\;nop";
8990  else
8991    return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8992}
8993  "&& TARGET_TLS_MARKERS"
8994  [(set (match_dup 0)
8995	(unspec:TLSmode [(match_dup 1)
8996			 (match_dup 2)]
8997			UNSPEC_TLSGD))
8998   (parallel [(set (match_dup 0)
8999   	     	   (call (mem:TLSmode (match_dup 3))
9000		   	 (match_dup 4)))
9001	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9002	      (clobber (reg:SI LR_REGNO))])]
9003  ""
9004  [(set_attr "type" "two")
9005   (set (attr "length")
9006     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9007     		   (const_int 16)
9008     		   (const_int 12)))])
9009
9010(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9011  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9012        (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9013	      (match_operand 4 "" "g")))
9014   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9015	 	    (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9016		   UNSPEC_TLSGD)
9017   (clobber (reg:SI LR_REGNO))]
9018  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9019{
9020  if (flag_pic)
9021    {
9022      if (TARGET_SECURE_PLT && flag_pic == 2)
9023	return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9024      else
9025	return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9026    }
9027  else
9028    return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9029}
9030  "&& TARGET_TLS_MARKERS"
9031  [(set (match_dup 0)
9032	(unspec:TLSmode [(match_dup 1)
9033			 (match_dup 2)]
9034			UNSPEC_TLSGD))
9035   (parallel [(set (match_dup 0)
9036   	     	   (call (mem:TLSmode (match_dup 3))
9037		   	 (match_dup 4)))
9038	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9039	      (clobber (reg:SI LR_REGNO))])]
9040  ""
9041  [(set_attr "type" "two")
9042   (set_attr "length" "8")])
9043
9044(define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9045  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9046	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9047			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9048			UNSPEC_TLSGD))]
9049  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9050  "addi %0,%1,%2@got@tlsgd"
9051  "&& TARGET_CMODEL != CMODEL_SMALL"
9052  [(set (match_dup 3)
9053  	(high:TLSmode
9054	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9055   (set (match_dup 0)
9056   	(lo_sum:TLSmode (match_dup 3)
9057	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9058  "
9059{
9060  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9061}"
9062  [(set (attr "length")
9063     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9064     		   (const_int 8)
9065     		   (const_int 4)))])
9066
9067(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9068  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9069     (high:TLSmode
9070       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9071			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9072		       UNSPEC_TLSGD)))]
9073  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9074  "addis %0,%1,%2@got@tlsgd@ha"
9075  [(set_attr "length" "4")])
9076
9077(define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9078  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9079     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9080       (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9081			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9082		       UNSPEC_TLSGD)))]
9083  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9084  "addi %0,%1,%2@got@tlsgd@l"
9085  [(set_attr "length" "4")])
9086
9087(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9088  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9089        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9090	      (match_operand 2 "" "g")))
9091   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9092		   UNSPEC_TLSGD)
9093   (clobber (reg:SI LR_REGNO))]
9094  "HAVE_AS_TLS && TARGET_TLS_MARKERS
9095   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9096  "bl %z1(%3@tlsgd)\;nop"
9097  [(set_attr "type" "branch")
9098   (set_attr "length" "8")])
9099
9100(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9101  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9102        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9103	      (match_operand 2 "" "g")))
9104   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9105		   UNSPEC_TLSGD)
9106   (clobber (reg:SI LR_REGNO))]
9107  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9108{
9109  if (flag_pic)
9110    {
9111      if (TARGET_SECURE_PLT && flag_pic == 2)
9112	return "bl %z1+32768(%3@tlsgd)@plt";
9113      return "bl %z1(%3@tlsgd)@plt";
9114    }
9115  return "bl %z1(%3@tlsgd)";
9116}
9117  [(set_attr "type" "branch")
9118   (set_attr "length" "4")])
9119
9120(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9121  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9122        (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9123	      (match_operand 3 "" "g")))
9124   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9125		   UNSPEC_TLSLD)
9126   (clobber (reg:SI LR_REGNO))]
9127  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9128{
9129  if (TARGET_CMODEL != CMODEL_SMALL)
9130    return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9131	   "bl %z2\;nop";
9132  else
9133    return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9134}
9135  "&& TARGET_TLS_MARKERS"
9136  [(set (match_dup 0)
9137	(unspec:TLSmode [(match_dup 1)]
9138			UNSPEC_TLSLD))
9139   (parallel [(set (match_dup 0)
9140   	     	   (call (mem:TLSmode (match_dup 2))
9141		   	 (match_dup 3)))
9142	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9143	      (clobber (reg:SI LR_REGNO))])]
9144  ""
9145  [(set_attr "type" "two")
9146   (set (attr "length")
9147     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9148     		   (const_int 16)
9149     		   (const_int 12)))])
9150
9151(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9152  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9153        (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9154	      (match_operand 3 "" "g")))
9155   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9156		   UNSPEC_TLSLD)
9157   (clobber (reg:SI LR_REGNO))]
9158  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9159{
9160  if (flag_pic)
9161    {
9162      if (TARGET_SECURE_PLT && flag_pic == 2)
9163	return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9164      else
9165	return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9166    }
9167  else
9168    return "addi %0,%1,%&@got@tlsld\;bl %z2";
9169}
9170  "&& TARGET_TLS_MARKERS"
9171  [(set (match_dup 0)
9172	(unspec:TLSmode [(match_dup 1)]
9173			UNSPEC_TLSLD))
9174   (parallel [(set (match_dup 0)
9175   	     	   (call (mem:TLSmode (match_dup 2))
9176		   	 (match_dup 3)))
9177	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9178	      (clobber (reg:SI LR_REGNO))])]
9179  ""
9180  [(set_attr "length" "8")])
9181
9182(define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9183  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9184	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9185			UNSPEC_TLSLD))]
9186  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9187  "addi %0,%1,%&@got@tlsld"
9188  "&& TARGET_CMODEL != CMODEL_SMALL"
9189  [(set (match_dup 2)
9190  	(high:TLSmode
9191	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9192   (set (match_dup 0)
9193   	(lo_sum:TLSmode (match_dup 2)
9194	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9195  "
9196{
9197  operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9198}"
9199  [(set (attr "length")
9200     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9201     		   (const_int 8)
9202     		   (const_int 4)))])
9203
9204(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9205  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9206     (high:TLSmode
9207       (unspec:TLSmode [(const_int 0)
9208			(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9209		       UNSPEC_TLSLD)))]
9210  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9211  "addis %0,%1,%&@got@tlsld@ha"
9212  [(set_attr "length" "4")])
9213
9214(define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9215  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9216     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9217       (unspec:TLSmode [(const_int 0)
9218                        (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9219                       UNSPEC_TLSLD)))]
9220  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9221  "addi %0,%1,%&@got@tlsld@l"
9222  [(set_attr "length" "4")])
9223
9224(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9225  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9226        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9227	      (match_operand 2 "" "g")))
9228   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9229   (clobber (reg:SI LR_REGNO))]
9230  "HAVE_AS_TLS && TARGET_TLS_MARKERS
9231   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9232  "bl %z1(%&@tlsld)\;nop"
9233  [(set_attr "type" "branch")
9234   (set_attr "length" "8")])
9235
9236(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9237  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9238        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9239	      (match_operand 2 "" "g")))
9240   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9241   (clobber (reg:SI LR_REGNO))]
9242  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9243{
9244  if (flag_pic)
9245    {
9246      if (TARGET_SECURE_PLT && flag_pic == 2)
9247	return "bl %z1+32768(%&@tlsld)@plt";
9248      return "bl %z1(%&@tlsld)@plt";
9249    }
9250  return "bl %z1(%&@tlsld)";
9251}
9252  [(set_attr "type" "branch")
9253   (set_attr "length" "4")])
9254
9255(define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9256  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9257	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9258			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9259			UNSPEC_TLSDTPREL))]
9260  "HAVE_AS_TLS"
9261  "addi %0,%1,%2@dtprel")
9262
9263(define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9264  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9265	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9266			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9267			UNSPEC_TLSDTPRELHA))]
9268  "HAVE_AS_TLS"
9269  "addis %0,%1,%2@dtprel@ha")
9270
9271(define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9272  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9273	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9274			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9275			UNSPEC_TLSDTPRELLO))]
9276  "HAVE_AS_TLS"
9277  "addi %0,%1,%2@dtprel@l")
9278
9279(define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9280  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9281	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9282			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9283			UNSPEC_TLSGOTDTPREL))]
9284  "HAVE_AS_TLS"
9285  "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9286  "&& TARGET_CMODEL != CMODEL_SMALL"
9287  [(set (match_dup 3)
9288	(high:TLSmode
9289	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9290   (set (match_dup 0)
9291	(lo_sum:TLSmode (match_dup 3)
9292	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9293  "
9294{
9295  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9296}"
9297  [(set (attr "length")
9298     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9299     		   (const_int 8)
9300     		   (const_int 4)))])
9301
9302(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9303  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9304     (high:TLSmode
9305       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9306			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9307		       UNSPEC_TLSGOTDTPREL)))]
9308  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9309  "addis %0,%1,%2@got@dtprel@ha"
9310  [(set_attr "length" "4")])
9311
9312(define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9313  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9314     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9315	 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9316			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9317			 UNSPEC_TLSGOTDTPREL)))]
9318  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9319  "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9320  [(set_attr "length" "4")])
9321
9322(define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9323  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9324	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9325			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9326			UNSPEC_TLSTPREL))]
9327  "HAVE_AS_TLS"
9328  "addi %0,%1,%2@tprel")
9329
9330(define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9331  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9332	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9333			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9334			UNSPEC_TLSTPRELHA))]
9335  "HAVE_AS_TLS"
9336  "addis %0,%1,%2@tprel@ha")
9337
9338(define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9339  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9340	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9341			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9342			UNSPEC_TLSTPRELLO))]
9343  "HAVE_AS_TLS"
9344  "addi %0,%1,%2@tprel@l")
9345
9346;; "b" output constraint here and on tls_tls input to support linker tls
9347;; optimization.  The linker may edit the instructions emitted by a
9348;; tls_got_tprel/tls_tls pair to addis,addi.
9349(define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9350  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9351	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9352			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9353			UNSPEC_TLSGOTTPREL))]
9354  "HAVE_AS_TLS"
9355  "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9356  "&& TARGET_CMODEL != CMODEL_SMALL"
9357  [(set (match_dup 3)
9358	(high:TLSmode
9359	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9360   (set (match_dup 0)
9361	(lo_sum:TLSmode (match_dup 3)
9362	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9363  "
9364{
9365  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9366}"
9367  [(set (attr "length")
9368     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9369     		   (const_int 8)
9370     		   (const_int 4)))])
9371
9372(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9373  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9374     (high:TLSmode
9375       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9376			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9377		       UNSPEC_TLSGOTTPREL)))]
9378  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9379  "addis %0,%1,%2@got@tprel@ha"
9380  [(set_attr "length" "4")])
9381
9382(define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9383  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9384     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9385	 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9386			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9387			 UNSPEC_TLSGOTTPREL)))]
9388  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9389  "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9390  [(set_attr "length" "4")])
9391
9392(define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9393  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9394	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9395			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9396			UNSPEC_TLSTLS))]
9397  "TARGET_ELF && HAVE_AS_TLS"
9398  "add %0,%1,%2@tls")
9399
9400(define_expand "tls_get_tpointer"
9401  [(set (match_operand:SI 0 "gpc_reg_operand" "")
9402	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9403  "TARGET_XCOFF && HAVE_AS_TLS"
9404  "
9405{
9406  emit_insn (gen_tls_get_tpointer_internal ());
9407  emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9408  DONE;
9409}")
9410
9411(define_insn "tls_get_tpointer_internal"
9412  [(set (reg:SI 3)
9413	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9414   (clobber (reg:SI LR_REGNO))]
9415  "TARGET_XCOFF && HAVE_AS_TLS"
9416  "bla __get_tpointer")
9417
9418(define_expand "tls_get_addr<mode>"
9419  [(set (match_operand:P 0 "gpc_reg_operand" "")
9420	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9421                   (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9422  "TARGET_XCOFF && HAVE_AS_TLS"
9423  "
9424{
9425  emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9426  emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9427  emit_insn (gen_tls_get_addr_internal<mode> ());
9428  emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9429  DONE;
9430}")
9431
9432(define_insn "tls_get_addr_internal<mode>"
9433  [(set (reg:P 3)
9434	(unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9435   (clobber (reg:P 0))
9436   (clobber (reg:P 4))
9437   (clobber (reg:P 5))
9438   (clobber (reg:P 11))
9439   (clobber (reg:CC CR0_REGNO))
9440   (clobber (reg:P LR_REGNO))]
9441  "TARGET_XCOFF && HAVE_AS_TLS"
9442  "bla __tls_get_addr")
9443
9444;; Next come insns related to the calling sequence.
9445;;
9446;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9447;; We move the back-chain and decrement the stack pointer.
9448
9449(define_expand "allocate_stack"
9450  [(set (match_operand 0 "gpc_reg_operand" "")
9451	(minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9452   (set (reg 1)
9453	(minus (reg 1) (match_dup 1)))]
9454  ""
9455  "
9456{ rtx chain = gen_reg_rtx (Pmode);
9457  rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9458  rtx neg_op0;
9459  rtx insn, par, set, mem;
9460
9461  emit_move_insn (chain, stack_bot);
9462
9463  /* Check stack bounds if necessary.  */
9464  if (crtl->limit_stack)
9465    {
9466      rtx available;
9467      available = expand_binop (Pmode, sub_optab,
9468				stack_pointer_rtx, stack_limit_rtx,
9469				NULL_RTX, 1, OPTAB_WIDEN);
9470      emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9471    }
9472
9473  if (GET_CODE (operands[1]) != CONST_INT
9474      || INTVAL (operands[1]) < -32767
9475      || INTVAL (operands[1]) > 32768)
9476    {
9477      neg_op0 = gen_reg_rtx (Pmode);
9478      if (TARGET_32BIT)
9479	emit_insn (gen_negsi2 (neg_op0, operands[1]));
9480      else
9481	emit_insn (gen_negdi2 (neg_op0, operands[1]));
9482    }
9483  else
9484    neg_op0 = GEN_INT (- INTVAL (operands[1]));
9485
9486  insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9487				       : gen_movdi_di_update_stack))
9488			(stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9489			 chain));
9490  /* Since we didn't use gen_frame_mem to generate the MEM, grab
9491     it now and set the alias set/attributes. The above gen_*_update
9492     calls will generate a PARALLEL with the MEM set being the first
9493     operation. */
9494  par = PATTERN (insn);
9495  gcc_assert (GET_CODE (par) == PARALLEL);
9496  set = XVECEXP (par, 0, 0);
9497  gcc_assert (GET_CODE (set) == SET);
9498  mem = SET_DEST (set);
9499  gcc_assert (MEM_P (mem));
9500  MEM_NOTRAP_P (mem) = 1;
9501  set_mem_alias_set (mem, get_frame_alias_set ());
9502
9503  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9504  DONE;
9505}")
9506
9507;; These patterns say how to save and restore the stack pointer.  We need not
9508;; save the stack pointer at function level since we are careful to
9509;; preserve the backchain.  At block level, we have to restore the backchain
9510;; when we restore the stack pointer.
9511;;
9512;; For nonlocal gotos, we must save both the stack pointer and its
9513;; backchain and restore both.  Note that in the nonlocal case, the
9514;; save area is a memory location.
9515
9516(define_expand "save_stack_function"
9517  [(match_operand 0 "any_operand" "")
9518   (match_operand 1 "any_operand" "")]
9519  ""
9520  "DONE;")
9521
9522(define_expand "restore_stack_function"
9523  [(match_operand 0 "any_operand" "")
9524   (match_operand 1 "any_operand" "")]
9525  ""
9526  "DONE;")
9527
9528;; Adjust stack pointer (op0) to a new value (op1).
9529;; First copy old stack backchain to new location, and ensure that the
9530;; scheduler won't reorder the sp assignment before the backchain write.
9531(define_expand "restore_stack_block"
9532  [(set (match_dup 2) (match_dup 3))
9533   (set (match_dup 4) (match_dup 2))
9534   (match_dup 5)
9535   (set (match_operand 0 "register_operand" "")
9536	(match_operand 1 "register_operand" ""))]
9537  ""
9538  "
9539{
9540  rtvec p;
9541
9542  operands[1] = force_reg (Pmode, operands[1]);
9543  operands[2] = gen_reg_rtx (Pmode);
9544  operands[3] = gen_frame_mem (Pmode, operands[0]);
9545  operands[4] = gen_frame_mem (Pmode, operands[1]);
9546  p = rtvec_alloc (1);
9547  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9548				  const0_rtx);
9549  operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9550}")
9551
9552(define_expand "save_stack_nonlocal"
9553  [(set (match_dup 3) (match_dup 4))
9554   (set (match_operand 0 "memory_operand" "") (match_dup 3))
9555   (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9556  ""
9557  "
9558{
9559  int units_per_word = (TARGET_32BIT) ? 4 : 8;
9560
9561  /* Copy the backchain to the first word, sp to the second.  */
9562  operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9563  operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9564  operands[3] = gen_reg_rtx (Pmode);
9565  operands[4] = gen_frame_mem (Pmode, operands[1]);
9566}")
9567
9568(define_expand "restore_stack_nonlocal"
9569  [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9570   (set (match_dup 3) (match_dup 4))
9571   (set (match_dup 5) (match_dup 2))
9572   (match_dup 6)
9573   (set (match_operand 0 "register_operand" "") (match_dup 3))]
9574  ""
9575  "
9576{
9577  int units_per_word = (TARGET_32BIT) ? 4 : 8;
9578  rtvec p;
9579
9580  /* Restore the backchain from the first word, sp from the second.  */
9581  operands[2] = gen_reg_rtx (Pmode);
9582  operands[3] = gen_reg_rtx (Pmode);
9583  operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9584  operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9585  operands[5] = gen_frame_mem (Pmode, operands[3]);
9586  p = rtvec_alloc (1);
9587  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9588				  const0_rtx);
9589  operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9590}")
9591
9592;; TOC register handling.
9593
9594;; Code to initialize the TOC register...
9595
9596(define_insn "load_toc_aix_si"
9597  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9598		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
9599	      (use (reg:SI 2))])]
9600  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9601  "*
9602{
9603  char buf[30];
9604  extern int need_toc_init;
9605  need_toc_init = 1;
9606  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9607  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9608  operands[2] = gen_rtx_REG (Pmode, 2);
9609  return \"lwz %0,%1(%2)\";
9610}"
9611  [(set_attr "type" "load")
9612   (set_attr "update" "no")
9613   (set_attr "indexed" "no")])
9614
9615(define_insn "load_toc_aix_di"
9616  [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9617		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
9618	      (use (reg:DI 2))])]
9619  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9620  "*
9621{
9622  char buf[30];
9623  extern int need_toc_init;
9624  need_toc_init = 1;
9625#ifdef TARGET_RELOCATABLE
9626  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9627			       !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9628#else
9629  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9630#endif
9631  if (TARGET_ELF)
9632    strcat (buf, \"@toc\");
9633  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9634  operands[2] = gen_rtx_REG (Pmode, 2);
9635  return \"ld %0,%1(%2)\";
9636}"
9637  [(set_attr "type" "load")
9638   (set_attr "update" "no")
9639   (set_attr "indexed" "no")])
9640
9641(define_insn "load_toc_v4_pic_si"
9642  [(set (reg:SI LR_REGNO)
9643	(unspec:SI [(const_int 0)] UNSPEC_TOC))]
9644  "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9645  "bl _GLOBAL_OFFSET_TABLE_@local-4"
9646  [(set_attr "type" "branch")
9647   (set_attr "length" "4")])
9648
9649(define_expand "load_toc_v4_PIC_1"
9650  [(parallel [(set (reg:SI LR_REGNO)
9651		   (match_operand:SI 0 "immediate_operand" "s"))
9652	      (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9653  "TARGET_ELF && DEFAULT_ABI == ABI_V4
9654   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9655  "")
9656
9657(define_insn "load_toc_v4_PIC_1_normal"
9658  [(set (reg:SI LR_REGNO)
9659	(match_operand:SI 0 "immediate_operand" "s"))
9660   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9661  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9662   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9663  "bcl 20,31,%0\\n%0:"
9664  [(set_attr "type" "branch")
9665   (set_attr "length" "4")
9666   (set_attr "cannot_copy" "yes")])
9667
9668(define_insn "load_toc_v4_PIC_1_476"
9669  [(set (reg:SI LR_REGNO)
9670	(match_operand:SI 0 "immediate_operand" "s"))
9671   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9672  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9673   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9674  "*
9675{
9676  char name[32];
9677  static char templ[32];
9678
9679  get_ppc476_thunk_name (name);
9680  sprintf (templ, \"bl %s\\n%%0:\", name);
9681  return templ;
9682}"
9683  [(set_attr "type" "branch")
9684   (set_attr "length" "4")
9685   (set_attr "cannot_copy" "yes")])
9686
9687(define_expand "load_toc_v4_PIC_1b"
9688  [(parallel [(set (reg:SI LR_REGNO)
9689		   (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9690			       (label_ref (match_operand 1 "" ""))]
9691		           UNSPEC_TOCPTR))
9692	      (match_dup 1)])]
9693  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9694  "")
9695
9696(define_insn "load_toc_v4_PIC_1b_normal"
9697  [(set (reg:SI LR_REGNO)
9698	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9699		    (label_ref (match_operand 1 "" ""))]
9700		UNSPEC_TOCPTR))
9701   (match_dup 1)]
9702  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9703  "bcl 20,31,$+8\;.long %0-$"
9704  [(set_attr "type" "branch")
9705   (set_attr "length" "8")])
9706
9707(define_insn "load_toc_v4_PIC_1b_476"
9708  [(set (reg:SI LR_REGNO)
9709	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9710		    (label_ref (match_operand 1 "" ""))]
9711		UNSPEC_TOCPTR))
9712   (match_dup 1)]
9713  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9714  "*
9715{
9716  char name[32];
9717  static char templ[32];
9718
9719  get_ppc476_thunk_name (name);
9720  sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9721  return templ;
9722}"
9723  [(set_attr "type" "branch")
9724   (set_attr "length" "16")])
9725
9726(define_insn "load_toc_v4_PIC_2"
9727  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9728	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9729		   (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9730			     (match_operand:SI 3 "immediate_operand" "s")))))]
9731  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9732  "lwz %0,%2-%3(%1)"
9733  [(set_attr "type" "load")])
9734
9735(define_insn "load_toc_v4_PIC_3b"
9736  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9737	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9738		 (high:SI
9739		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9740			     (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9741  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9742  "addis %0,%1,%2-%3@ha")
9743
9744(define_insn "load_toc_v4_PIC_3c"
9745  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9746	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9747		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9748			     (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9749  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9750  "addi %0,%1,%2-%3@l")
9751
9752;; If the TOC is shared over a translation unit, as happens with all
9753;; the kinds of PIC that we support, we need to restore the TOC
9754;; pointer only when jumping over units of translation.
9755;; On Darwin, we need to reload the picbase.
9756
9757(define_expand "builtin_setjmp_receiver"
9758  [(use (label_ref (match_operand 0 "" "")))]
9759  "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9760   || (TARGET_TOC && TARGET_MINIMAL_TOC)
9761   || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9762  "
9763{
9764#if TARGET_MACHO
9765  if (DEFAULT_ABI == ABI_DARWIN)
9766    {
9767      rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9768      rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9769      rtx tmplabrtx;
9770      char tmplab[20];
9771
9772      crtl->uses_pic_offset_table = 1;
9773      ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9774				  CODE_LABEL_NUMBER (operands[0]));
9775      tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9776
9777      emit_insn (gen_load_macho_picbase (tmplabrtx));
9778      emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9779      emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9780    }
9781  else
9782#endif
9783    rs6000_emit_load_toc_table (FALSE);
9784  DONE;
9785}")
9786
9787;; Largetoc support
9788(define_insn "*largetoc_high"
9789  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9790        (high:DI
9791	  (unspec [(match_operand:DI 1 "" "")
9792		   (match_operand:DI 2 "gpc_reg_operand" "b")]
9793		  UNSPEC_TOCREL)))]
9794   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9795   "addis %0,%2,%1@toc@ha")
9796
9797(define_insn "*largetoc_high_aix<mode>"
9798  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9799        (high:P
9800	  (unspec [(match_operand:P 1 "" "")
9801		   (match_operand:P 2 "gpc_reg_operand" "b")]
9802		  UNSPEC_TOCREL)))]
9803   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9804   "addis %0,%1@u(%2)")
9805
9806(define_insn "*largetoc_high_plus"
9807  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9808        (high:DI
9809	  (plus:DI
9810	    (unspec [(match_operand:DI 1 "" "")
9811		     (match_operand:DI 2 "gpc_reg_operand" "b")]
9812		    UNSPEC_TOCREL)
9813	    (match_operand:DI 3 "add_cint_operand" "n"))))]
9814   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9815   "addis %0,%2,%1+%3@toc@ha")
9816
9817(define_insn "*largetoc_high_plus_aix<mode>"
9818  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9819        (high:P
9820	  (plus:P
9821	    (unspec [(match_operand:P 1 "" "")
9822		     (match_operand:P 2 "gpc_reg_operand" "b")]
9823		    UNSPEC_TOCREL)
9824	    (match_operand:P 3 "add_cint_operand" "n"))))]
9825   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9826   "addis %0,%1+%3@u(%2)")
9827
9828(define_insn "*largetoc_low"
9829  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9830        (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9831	           (match_operand:DI 2 "" "")))]
9832   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9833   "addi %0,%1,%2@l")
9834
9835(define_insn "*largetoc_low_aix<mode>"
9836  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9837        (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9838	           (match_operand:P 2 "" "")))]
9839   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9840   "la %0,%2@l(%1)")
9841
9842(define_insn_and_split "*tocref<mode>"
9843  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9844	(match_operand:P 1 "small_toc_ref" "R"))]
9845   "TARGET_TOC"
9846   "la %0,%a1"
9847   "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9848  [(set (match_dup 0) (high:P (match_dup 1)))
9849   (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9850
9851;; Elf specific ways of loading addresses for non-PIC code.
9852;; The output of this could be r0, but we make a very strong
9853;; preference for a base register because it will usually
9854;; be needed there.
9855(define_insn "elf_high"
9856  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9857	(high:SI (match_operand 1 "" "")))]
9858  "TARGET_ELF && ! TARGET_64BIT"
9859  "lis %0,%1@ha")
9860
9861(define_insn "elf_low"
9862  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9863	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9864		   (match_operand 2 "" "")))]
9865   "TARGET_ELF && ! TARGET_64BIT"
9866   "la %0,%2@l(%1)")
9867
9868;; Call and call_value insns
9869(define_expand "call"
9870  [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9871		    (match_operand 1 "" ""))
9872	      (use (match_operand 2 "" ""))
9873	      (clobber (reg:SI LR_REGNO))])]
9874  ""
9875  "
9876{
9877#if TARGET_MACHO
9878  if (MACHOPIC_INDIRECT)
9879    operands[0] = machopic_indirect_call_target (operands[0]);
9880#endif
9881
9882  gcc_assert (GET_CODE (operands[0]) == MEM);
9883  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9884
9885  operands[0] = XEXP (operands[0], 0);
9886
9887  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9888    {
9889      rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9890      DONE;
9891    }
9892
9893  if (GET_CODE (operands[0]) != SYMBOL_REF
9894      || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9895    {
9896      if (INTVAL (operands[2]) & CALL_LONG)
9897	operands[0] = rs6000_longcall_ref (operands[0]);
9898
9899      switch (DEFAULT_ABI)
9900        {
9901	case ABI_V4:
9902	case ABI_DARWIN:
9903	  operands[0] = force_reg (Pmode, operands[0]);
9904	  break;
9905
9906	default:
9907	  gcc_unreachable ();
9908	}
9909    }
9910}")
9911
9912(define_expand "call_value"
9913  [(parallel [(set (match_operand 0 "" "")
9914		   (call (mem:SI (match_operand 1 "address_operand" ""))
9915			 (match_operand 2 "" "")))
9916	      (use (match_operand 3 "" ""))
9917	      (clobber (reg:SI LR_REGNO))])]
9918  ""
9919  "
9920{
9921#if TARGET_MACHO
9922  if (MACHOPIC_INDIRECT)
9923    operands[1] = machopic_indirect_call_target (operands[1]);
9924#endif
9925
9926  gcc_assert (GET_CODE (operands[1]) == MEM);
9927  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9928
9929  operands[1] = XEXP (operands[1], 0);
9930
9931  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9932    {
9933      rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9934      DONE;
9935    }
9936
9937  if (GET_CODE (operands[1]) != SYMBOL_REF
9938      || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9939    {
9940      if (INTVAL (operands[3]) & CALL_LONG)
9941	operands[1] = rs6000_longcall_ref (operands[1]);
9942
9943      switch (DEFAULT_ABI)
9944        {
9945	case ABI_V4:
9946	case ABI_DARWIN:
9947	  operands[1] = force_reg (Pmode, operands[1]);
9948	  break;
9949
9950	default:
9951	  gcc_unreachable ();
9952	}
9953    }
9954}")
9955
9956;; Call to function in current module.  No TOC pointer reload needed.
9957;; Operand2 is nonzero if we are using the V.4 calling sequence and
9958;; either the function was not prototyped, or it was prototyped as a
9959;; variable argument function.  It is > 0 if FP registers were passed
9960;; and < 0 if they were not.
9961
9962(define_insn "*call_local32"
9963  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9964	 (match_operand 1 "" "g,g"))
9965   (use (match_operand:SI 2 "immediate_operand" "O,n"))
9966   (clobber (reg:SI LR_REGNO))]
9967  "(INTVAL (operands[2]) & CALL_LONG) == 0"
9968  "*
9969{
9970  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9971    output_asm_insn (\"crxor 6,6,6\", operands);
9972
9973  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9974    output_asm_insn (\"creqv 6,6,6\", operands);
9975
9976  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9977}"
9978  [(set_attr "type" "branch")
9979   (set_attr "length" "4,8")])
9980
9981(define_insn "*call_local64"
9982  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9983	 (match_operand 1 "" "g,g"))
9984   (use (match_operand:SI 2 "immediate_operand" "O,n"))
9985   (clobber (reg:SI LR_REGNO))]
9986  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9987  "*
9988{
9989  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9990    output_asm_insn (\"crxor 6,6,6\", operands);
9991
9992  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9993    output_asm_insn (\"creqv 6,6,6\", operands);
9994
9995  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9996}"
9997  [(set_attr "type" "branch")
9998   (set_attr "length" "4,8")])
9999
10000(define_insn "*call_value_local32"
10001  [(set (match_operand 0 "" "")
10002	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10003	      (match_operand 2 "" "g,g")))
10004   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10005   (clobber (reg:SI LR_REGNO))]
10006  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10007  "*
10008{
10009  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10010    output_asm_insn (\"crxor 6,6,6\", operands);
10011
10012  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10013    output_asm_insn (\"creqv 6,6,6\", operands);
10014
10015  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10016}"
10017  [(set_attr "type" "branch")
10018   (set_attr "length" "4,8")])
10019
10020
10021(define_insn "*call_value_local64"
10022  [(set (match_operand 0 "" "")
10023	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10024	      (match_operand 2 "" "g,g")))
10025   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10026   (clobber (reg:SI LR_REGNO))]
10027  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10028  "*
10029{
10030  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10031    output_asm_insn (\"crxor 6,6,6\", operands);
10032
10033  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10034    output_asm_insn (\"creqv 6,6,6\", operands);
10035
10036  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10037}"
10038  [(set_attr "type" "branch")
10039   (set_attr "length" "4,8")])
10040
10041
10042;; A function pointer under System V is just a normal pointer
10043;; operands[0] is the function pointer
10044;; operands[1] is the stack size to clean up
10045;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10046;; which indicates how to set cr1
10047
10048(define_insn "*call_indirect_nonlocal_sysv<mode>"
10049  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10050	 (match_operand 1 "" "g,g,g,g"))
10051   (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10052   (clobber (reg:SI LR_REGNO))]
10053  "DEFAULT_ABI == ABI_V4
10054   || DEFAULT_ABI == ABI_DARWIN"
10055{
10056  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10057    output_asm_insn ("crxor 6,6,6", operands);
10058
10059  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10060    output_asm_insn ("creqv 6,6,6", operands);
10061
10062  return "b%T0l";
10063}
10064  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10065   (set_attr "length" "4,4,8,8")])
10066
10067(define_insn_and_split "*call_nonlocal_sysv<mode>"
10068  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10069	 (match_operand 1 "" "g,g"))
10070   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10071   (clobber (reg:SI LR_REGNO))]
10072  "(DEFAULT_ABI == ABI_DARWIN
10073   || (DEFAULT_ABI == ABI_V4
10074       && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10075{
10076  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10077    output_asm_insn ("crxor 6,6,6", operands);
10078
10079  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10080    output_asm_insn ("creqv 6,6,6", operands);
10081
10082#if TARGET_MACHO
10083  return output_call(insn, operands, 0, 2);
10084#else
10085  if (DEFAULT_ABI == ABI_V4 && flag_pic)
10086    {
10087      gcc_assert (!TARGET_SECURE_PLT);
10088      return "bl %z0@plt";
10089    }
10090  else
10091    return "bl %z0";
10092#endif
10093}
10094  "DEFAULT_ABI == ABI_V4
10095   && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10096   && (INTVAL (operands[2]) & CALL_LONG) == 0"
10097  [(parallel [(call (mem:SI (match_dup 0))
10098		    (match_dup 1))
10099	      (use (match_dup 2))
10100	      (use (match_dup 3))
10101	      (clobber (reg:SI LR_REGNO))])]
10102{
10103  operands[3] = pic_offset_table_rtx;
10104}
10105  [(set_attr "type" "branch,branch")
10106   (set_attr "length" "4,8")])
10107
10108(define_insn "*call_nonlocal_sysv_secure<mode>"
10109  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10110	 (match_operand 1 "" "g,g"))
10111   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10112   (use (match_operand:SI 3 "register_operand" "r,r"))
10113   (clobber (reg:SI LR_REGNO))]
10114  "(DEFAULT_ABI == ABI_V4
10115    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10116    && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10117{
10118  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10119    output_asm_insn ("crxor 6,6,6", operands);
10120
10121  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10122    output_asm_insn ("creqv 6,6,6", operands);
10123
10124  if (flag_pic == 2)
10125    /* The magic 32768 offset here and in the other sysv call insns
10126       corresponds to the offset of r30 in .got2, as given by LCTOC1.
10127       See sysv4.h:toc_section.  */
10128    return "bl %z0+32768@plt";
10129  else
10130    return "bl %z0@plt";
10131}
10132  [(set_attr "type" "branch,branch")
10133   (set_attr "length" "4,8")])
10134
10135(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10136  [(set (match_operand 0 "" "")
10137	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10138	      (match_operand 2 "" "g,g,g,g")))
10139   (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10140   (clobber (reg:SI LR_REGNO))]
10141  "DEFAULT_ABI == ABI_V4
10142   || DEFAULT_ABI == ABI_DARWIN"
10143{
10144  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10145    output_asm_insn ("crxor 6,6,6", operands);
10146
10147  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10148    output_asm_insn ("creqv 6,6,6", operands);
10149
10150  return "b%T1l";
10151}
10152  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10153   (set_attr "length" "4,4,8,8")])
10154
10155(define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10156  [(set (match_operand 0 "" "")
10157	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10158	      (match_operand 2 "" "g,g")))
10159   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10160   (clobber (reg:SI LR_REGNO))]
10161  "(DEFAULT_ABI == ABI_DARWIN
10162   || (DEFAULT_ABI == ABI_V4
10163       && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10164{
10165  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10166    output_asm_insn ("crxor 6,6,6", operands);
10167
10168  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10169    output_asm_insn ("creqv 6,6,6", operands);
10170
10171#if TARGET_MACHO
10172  return output_call(insn, operands, 1, 3);
10173#else
10174  if (DEFAULT_ABI == ABI_V4 && flag_pic)
10175    {
10176      gcc_assert (!TARGET_SECURE_PLT);
10177      return "bl %z1@plt";
10178    }
10179  else
10180    return "bl %z1";
10181#endif
10182}
10183  "DEFAULT_ABI == ABI_V4
10184   && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10185   && (INTVAL (operands[3]) & CALL_LONG) == 0"
10186  [(parallel [(set (match_dup 0)
10187		   (call (mem:SI (match_dup 1))
10188			 (match_dup 2)))
10189	      (use (match_dup 3))
10190	      (use (match_dup 4))
10191	      (clobber (reg:SI LR_REGNO))])]
10192{
10193  operands[4] = pic_offset_table_rtx;
10194}
10195  [(set_attr "type" "branch,branch")
10196   (set_attr "length" "4,8")])
10197
10198(define_insn "*call_value_nonlocal_sysv_secure<mode>"
10199  [(set (match_operand 0 "" "")
10200	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10201	      (match_operand 2 "" "g,g")))
10202   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10203   (use (match_operand:SI 4 "register_operand" "r,r"))
10204   (clobber (reg:SI LR_REGNO))]
10205  "(DEFAULT_ABI == ABI_V4
10206    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10207    && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10208{
10209  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10210    output_asm_insn ("crxor 6,6,6", operands);
10211
10212  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10213    output_asm_insn ("creqv 6,6,6", operands);
10214
10215  if (flag_pic == 2)
10216    return "bl %z1+32768@plt";
10217  else
10218    return "bl %z1@plt";
10219}
10220  [(set_attr "type" "branch,branch")
10221   (set_attr "length" "4,8")])
10222
10223
10224;; Call to AIX abi function in the same module.
10225
10226(define_insn "*call_local_aix<mode>"
10227  [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10228	 (match_operand 1 "" "g"))
10229   (clobber (reg:P LR_REGNO))]
10230  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10231  "bl %z0"
10232  [(set_attr "type" "branch")
10233   (set_attr "length" "4")])
10234
10235(define_insn "*call_value_local_aix<mode>"
10236  [(set (match_operand 0 "" "")
10237	(call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10238	      (match_operand 2 "" "g")))
10239   (clobber (reg:P LR_REGNO))]
10240  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10241  "bl %z1"
10242  [(set_attr "type" "branch")
10243   (set_attr "length" "4")])
10244
10245;; Call to AIX abi function which may be in another module.
10246;; Restore the TOC pointer (r2) after the call.
10247
10248(define_insn "*call_nonlocal_aix<mode>"
10249  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10250	 (match_operand 1 "" "g"))
10251   (clobber (reg:P LR_REGNO))]
10252  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10253  "bl %z0\;nop"
10254  [(set_attr "type" "branch")
10255   (set_attr "length" "8")])
10256
10257(define_insn "*call_value_nonlocal_aix<mode>"
10258  [(set (match_operand 0 "" "")
10259	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10260	      (match_operand 2 "" "g")))
10261   (clobber (reg:P LR_REGNO))]
10262  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10263  "bl %z1\;nop"
10264  [(set_attr "type" "branch")
10265   (set_attr "length" "8")])
10266
10267;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10268;; Operand0 is the addresss of the function to call
10269;; Operand2 is the location in the function descriptor to load r2 from
10270;; Operand3 is the offset of the stack location holding the current TOC pointer
10271
10272(define_insn "*call_indirect_aix<mode>"
10273  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10274	 (match_operand 1 "" "g,g"))
10275   (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10276   (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10277   (clobber (reg:P LR_REGNO))]
10278  "DEFAULT_ABI == ABI_AIX"
10279  "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10280  [(set_attr "type" "jmpreg")
10281   (set_attr "length" "12")])
10282
10283(define_insn "*call_value_indirect_aix<mode>"
10284  [(set (match_operand 0 "" "")
10285	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10286	      (match_operand 2 "" "g,g")))
10287   (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10288   (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10289   (clobber (reg:P LR_REGNO))]
10290  "DEFAULT_ABI == ABI_AIX"
10291  "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10292  [(set_attr "type" "jmpreg")
10293   (set_attr "length" "12")])
10294
10295;; Call to indirect functions with the ELFv2 ABI.
10296;; Operand0 is the addresss of the function to call
10297;; Operand2 is the offset of the stack location holding the current TOC pointer
10298
10299(define_insn "*call_indirect_elfv2<mode>"
10300  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10301	 (match_operand 1 "" "g,g"))
10302   (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10303   (clobber (reg:P LR_REGNO))]
10304  "DEFAULT_ABI == ABI_ELFv2"
10305  "b%T0l\;<ptrload> 2,%2(1)"
10306  [(set_attr "type" "jmpreg")
10307   (set_attr "length" "8")])
10308
10309(define_insn "*call_value_indirect_elfv2<mode>"
10310  [(set (match_operand 0 "" "")
10311	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10312	      (match_operand 2 "" "g,g")))
10313   (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10314   (clobber (reg:P LR_REGNO))]
10315  "DEFAULT_ABI == ABI_ELFv2"
10316  "b%T1l\;<ptrload> 2,%3(1)"
10317  [(set_attr "type" "jmpreg")
10318   (set_attr "length" "8")])
10319
10320
10321;; Call subroutine returning any type.
10322(define_expand "untyped_call"
10323  [(parallel [(call (match_operand 0 "" "")
10324		    (const_int 0))
10325	      (match_operand 1 "" "")
10326	      (match_operand 2 "" "")])]
10327  ""
10328  "
10329{
10330  int i;
10331
10332  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10333
10334  for (i = 0; i < XVECLEN (operands[2], 0); i++)
10335    {
10336      rtx set = XVECEXP (operands[2], 0, i);
10337      emit_move_insn (SET_DEST (set), SET_SRC (set));
10338    }
10339
10340  /* The optimizer does not know that the call sets the function value
10341     registers we stored in the result block.  We avoid problems by
10342     claiming that all hard registers are used and clobbered at this
10343     point.  */
10344  emit_insn (gen_blockage ());
10345
10346  DONE;
10347}")
10348
10349;; sibling call patterns
10350(define_expand "sibcall"
10351  [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10352		    (match_operand 1 "" ""))
10353	      (use (match_operand 2 "" ""))
10354	      (use (reg:SI LR_REGNO))
10355	      (simple_return)])]
10356  ""
10357  "
10358{
10359#if TARGET_MACHO
10360  if (MACHOPIC_INDIRECT)
10361    operands[0] = machopic_indirect_call_target (operands[0]);
10362#endif
10363
10364  gcc_assert (GET_CODE (operands[0]) == MEM);
10365  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10366
10367  operands[0] = XEXP (operands[0], 0);
10368
10369  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10370    {
10371      rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10372      DONE;
10373    }
10374}")
10375
10376(define_expand "sibcall_value"
10377  [(parallel [(set (match_operand 0 "register_operand" "")
10378		(call (mem:SI (match_operand 1 "address_operand" ""))
10379		      (match_operand 2 "" "")))
10380	      (use (match_operand 3 "" ""))
10381	      (use (reg:SI LR_REGNO))
10382	      (simple_return)])]
10383  ""
10384  "
10385{
10386#if TARGET_MACHO
10387  if (MACHOPIC_INDIRECT)
10388    operands[1] = machopic_indirect_call_target (operands[1]);
10389#endif
10390
10391  gcc_assert (GET_CODE (operands[1]) == MEM);
10392  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10393
10394  operands[1] = XEXP (operands[1], 0);
10395
10396  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10397    {
10398      rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10399      DONE;
10400    }
10401}")
10402
10403;; this and similar patterns must be marked as using LR, otherwise
10404;; dataflow will try to delete the store into it.  This is true
10405;; even when the actual reg to jump to is in CTR, when LR was
10406;; saved and restored around the PIC-setting BCL.
10407(define_insn "*sibcall_local32"
10408  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10409	 (match_operand 1 "" "g,g"))
10410   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10411   (use (reg:SI LR_REGNO))
10412   (simple_return)]
10413  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10414  "*
10415{
10416  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10417    output_asm_insn (\"crxor 6,6,6\", operands);
10418
10419  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10420    output_asm_insn (\"creqv 6,6,6\", operands);
10421
10422  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10423}"
10424  [(set_attr "type" "branch")
10425   (set_attr "length" "4,8")])
10426
10427(define_insn "*sibcall_local64"
10428  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10429	 (match_operand 1 "" "g,g"))
10430   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10431   (use (reg:SI LR_REGNO))
10432   (simple_return)]
10433  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10434  "*
10435{
10436  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10437    output_asm_insn (\"crxor 6,6,6\", operands);
10438
10439  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10440    output_asm_insn (\"creqv 6,6,6\", operands);
10441
10442  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10443}"
10444  [(set_attr "type" "branch")
10445   (set_attr "length" "4,8")])
10446
10447(define_insn "*sibcall_value_local32"
10448  [(set (match_operand 0 "" "")
10449	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10450	      (match_operand 2 "" "g,g")))
10451   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10452   (use (reg:SI LR_REGNO))
10453   (simple_return)]
10454  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10455  "*
10456{
10457  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10458    output_asm_insn (\"crxor 6,6,6\", operands);
10459
10460  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10461    output_asm_insn (\"creqv 6,6,6\", operands);
10462
10463  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10464}"
10465  [(set_attr "type" "branch")
10466   (set_attr "length" "4,8")])
10467
10468(define_insn "*sibcall_value_local64"
10469  [(set (match_operand 0 "" "")
10470	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10471	      (match_operand 2 "" "g,g")))
10472   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10473   (use (reg:SI LR_REGNO))
10474   (simple_return)]
10475  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10476  "*
10477{
10478  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10479    output_asm_insn (\"crxor 6,6,6\", operands);
10480
10481  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10482    output_asm_insn (\"creqv 6,6,6\", operands);
10483
10484  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10485}"
10486  [(set_attr "type" "branch")
10487   (set_attr "length" "4,8")])
10488
10489(define_insn "*sibcall_nonlocal_sysv<mode>"
10490  [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10491	 (match_operand 1 "" ""))
10492   (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10493   (use (reg:SI LR_REGNO))
10494   (simple_return)]
10495  "(DEFAULT_ABI == ABI_DARWIN
10496    || DEFAULT_ABI == ABI_V4)
10497   && (INTVAL (operands[2]) & CALL_LONG) == 0"
10498  "*
10499{
10500  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10501    output_asm_insn (\"crxor 6,6,6\", operands);
10502
10503  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10504    output_asm_insn (\"creqv 6,6,6\", operands);
10505
10506  if (which_alternative >= 2)
10507    return \"b%T0\";
10508  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10509    {
10510      gcc_assert (!TARGET_SECURE_PLT);
10511      return \"b %z0@plt\";
10512    }
10513  else
10514    return \"b %z0\";
10515}"
10516  [(set_attr "type" "branch")
10517   (set_attr "length" "4,8,4,8")])
10518
10519(define_insn "*sibcall_value_nonlocal_sysv<mode>"
10520  [(set (match_operand 0 "" "")
10521	(call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10522	      (match_operand 2 "" "")))
10523   (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10524   (use (reg:SI LR_REGNO))
10525   (simple_return)]
10526  "(DEFAULT_ABI == ABI_DARWIN
10527    || DEFAULT_ABI == ABI_V4)
10528   && (INTVAL (operands[3]) & CALL_LONG) == 0"
10529  "*
10530{
10531  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10532    output_asm_insn (\"crxor 6,6,6\", operands);
10533
10534  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10535    output_asm_insn (\"creqv 6,6,6\", operands);
10536
10537  if (which_alternative >= 2)
10538    return \"b%T1\";
10539  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10540    {
10541      gcc_assert (!TARGET_SECURE_PLT);
10542      return \"b %z1@plt\";
10543    }
10544  else
10545    return \"b %z1\";
10546}"
10547  [(set_attr "type" "branch")
10548   (set_attr "length" "4,8,4,8")])
10549
10550;; AIX ABI sibling call patterns.
10551
10552(define_insn "*sibcall_aix<mode>"
10553  [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10554	 (match_operand 1 "" "g,g"))
10555   (simple_return)]
10556  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10557  "@
10558   b %z0
10559   b%T0"
10560  [(set_attr "type" "branch")
10561   (set_attr "length" "4")])
10562
10563(define_insn "*sibcall_value_aix<mode>"
10564  [(set (match_operand 0 "" "")
10565	(call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10566	      (match_operand 2 "" "g,g")))
10567   (simple_return)]
10568  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10569  "@
10570   b %z1
10571   b%T1"
10572  [(set_attr "type" "branch")
10573   (set_attr "length" "4")])
10574
10575(define_expand "sibcall_epilogue"
10576  [(use (const_int 0))]
10577  ""
10578{
10579  if (!TARGET_SCHED_PROLOG)
10580    emit_insn (gen_blockage ());
10581  rs6000_emit_epilogue (TRUE);
10582  DONE;
10583})
10584
10585;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10586;; all of memory.  This blocks insns from being moved across this point.
10587
10588(define_insn "blockage"
10589  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10590  ""
10591  "")
10592
10593(define_expand "probe_stack_address"
10594  [(use (match_operand 0 "address_operand"))]
10595  ""
10596{
10597  operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10598  MEM_VOLATILE_P (operands[0]) = 1;
10599
10600  if (TARGET_64BIT)
10601    emit_insn (gen_probe_stack_di (operands[0]));
10602  else
10603    emit_insn (gen_probe_stack_si (operands[0]));
10604  DONE;
10605})
10606
10607(define_insn "probe_stack_<mode>"
10608  [(set (match_operand:P 0 "memory_operand" "=m")
10609        (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10610  ""
10611{
10612  operands[1] = gen_rtx_REG (Pmode, 0);
10613  return "st<wd>%U0%X0 %1,%0";
10614}
10615  [(set_attr "type" "store")
10616   (set (attr "update")
10617	(if_then_else (match_operand 0 "update_address_mem")
10618		      (const_string "yes")
10619		      (const_string "no")))
10620   (set (attr "indexed")
10621	(if_then_else (match_operand 0 "indexed_address_mem")
10622		      (const_string "yes")
10623		      (const_string "no")))
10624   (set_attr "length" "4")])
10625
10626(define_insn "probe_stack_range<P:mode>"
10627  [(set (match_operand:P 0 "register_operand" "=r")
10628	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10629			    (match_operand:P 2 "register_operand" "r")]
10630			   UNSPECV_PROBE_STACK_RANGE))]
10631  ""
10632  "* return output_probe_stack_range (operands[0], operands[2]);"
10633  [(set_attr "type" "three")])
10634
10635;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10636;; signed & unsigned, and one type of branch.
10637;;
10638;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10639;; insns, and branches.
10640
10641(define_expand "cbranch<mode>4"
10642  [(use (match_operator 0 "rs6000_cbranch_operator"
10643         [(match_operand:GPR 1 "gpc_reg_operand" "")
10644          (match_operand:GPR 2 "reg_or_short_operand" "")]))
10645   (use (match_operand 3 ""))]
10646  ""
10647  "
10648{
10649  /* Take care of the possibility that operands[2] might be negative but
10650     this might be a logical operation.  That insn doesn't exist.  */
10651  if (GET_CODE (operands[2]) == CONST_INT
10652      && INTVAL (operands[2]) < 0)
10653    {
10654      operands[2] = force_reg (<MODE>mode, operands[2]);
10655      operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10656				    GET_MODE (operands[0]),
10657				    operands[1], operands[2]);
10658   }
10659
10660  rs6000_emit_cbranch (<MODE>mode, operands);
10661  DONE;
10662}")
10663
10664(define_expand "cbranch<mode>4"
10665  [(use (match_operator 0 "rs6000_cbranch_operator"
10666         [(match_operand:FP 1 "gpc_reg_operand" "")
10667          (match_operand:FP 2 "gpc_reg_operand" "")]))
10668   (use (match_operand 3 ""))]
10669  ""
10670  "
10671{
10672  rs6000_emit_cbranch (<MODE>mode, operands);
10673  DONE;
10674}")
10675
10676(define_expand "cstore<mode>4_signed"
10677  [(use (match_operator 1 "signed_comparison_operator"
10678         [(match_operand:P 2 "gpc_reg_operand")
10679          (match_operand:P 3 "gpc_reg_operand")]))
10680   (clobber (match_operand:P 0 "gpc_reg_operand"))]
10681  ""
10682{
10683  enum rtx_code cond_code = GET_CODE (operands[1]);
10684
10685  rtx op0 = operands[0];
10686  rtx op1 = operands[2];
10687  rtx op2 = operands[3];
10688
10689  if (cond_code == GE || cond_code == LT)
10690    {
10691      cond_code = swap_condition (cond_code);
10692      std::swap (op1, op2);
10693    }
10694
10695  rtx tmp1 = gen_reg_rtx (<MODE>mode);
10696  rtx tmp2 = gen_reg_rtx (<MODE>mode);
10697  rtx tmp3 = gen_reg_rtx (<MODE>mode);
10698
10699  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10700  emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10701  emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10702
10703  emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10704
10705  if (cond_code == LE)
10706    emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10707  else
10708    {
10709      rtx tmp4 = gen_reg_rtx (<MODE>mode);
10710      emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10711      emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10712    }
10713
10714  DONE;
10715})
10716
10717(define_expand "cstore<mode>4_unsigned"
10718  [(use (match_operator 1 "unsigned_comparison_operator"
10719         [(match_operand:P 2 "gpc_reg_operand")
10720          (match_operand:P 3 "reg_or_short_operand")]))
10721   (clobber (match_operand:P 0 "gpc_reg_operand"))]
10722  ""
10723{
10724  enum rtx_code cond_code = GET_CODE (operands[1]);
10725
10726  rtx op0 = operands[0];
10727  rtx op1 = operands[2];
10728  rtx op2 = operands[3];
10729
10730  if (cond_code == GEU || cond_code == LTU)
10731    {
10732      cond_code = swap_condition (cond_code);
10733      std::swap (op1, op2);
10734    }
10735
10736  if (!gpc_reg_operand (op1, <MODE>mode))
10737    op1 = force_reg (<MODE>mode, op1);
10738  if (!reg_or_short_operand (op2, <MODE>mode))
10739    op2 = force_reg (<MODE>mode, op2);
10740
10741  rtx tmp = gen_reg_rtx (<MODE>mode);
10742  rtx tmp2 = gen_reg_rtx (<MODE>mode);
10743
10744  emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10745  emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10746
10747  if (cond_code == LEU)
10748    emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10749  else
10750    emit_insn (gen_neg<mode>2 (op0, tmp2));
10751
10752  DONE;
10753})
10754
10755(define_expand "cstore_si_as_di"
10756  [(use (match_operator 1 "unsigned_comparison_operator"
10757         [(match_operand:SI 2 "gpc_reg_operand")
10758          (match_operand:SI 3 "reg_or_short_operand")]))
10759   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10760  ""
10761{
10762  int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10763  enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10764
10765  operands[2] = force_reg (SImode, operands[2]);
10766  operands[3] = force_reg (SImode, operands[3]);
10767  rtx op1 = gen_reg_rtx (DImode);
10768  rtx op2 = gen_reg_rtx (DImode);
10769  convert_move (op1, operands[2], uns_flag);
10770  convert_move (op2, operands[3], uns_flag);
10771
10772  if (cond_code == GT || cond_code == LE)
10773    {
10774      cond_code = swap_condition (cond_code);
10775      std::swap (op1, op2);
10776    }
10777
10778  rtx tmp = gen_reg_rtx (DImode);
10779  rtx tmp2 = gen_reg_rtx (DImode);
10780  emit_insn (gen_subdi3 (tmp, op1, op2));
10781  emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10782
10783  rtx tmp3;
10784  switch (cond_code)
10785    {
10786    default:
10787      gcc_unreachable ();
10788    case LT:
10789      tmp3 = tmp2;
10790      break;
10791    case GE:
10792      tmp3 = gen_reg_rtx (DImode);
10793      emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10794      break;
10795    }
10796
10797  convert_move (operands[0], tmp3, 1);
10798
10799  DONE;
10800})
10801
10802(define_expand "cstore<mode>4_signed_imm"
10803  [(use (match_operator 1 "signed_comparison_operator"
10804         [(match_operand:GPR 2 "gpc_reg_operand")
10805          (match_operand:GPR 3 "immediate_operand")]))
10806   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10807  ""
10808{
10809  bool invert = false;
10810
10811  enum rtx_code cond_code = GET_CODE (operands[1]);
10812
10813  rtx op0 = operands[0];
10814  rtx op1 = operands[2];
10815  HOST_WIDE_INT val = INTVAL (operands[3]);
10816
10817  if (cond_code == GE || cond_code == GT)
10818    {
10819      cond_code = reverse_condition (cond_code);
10820      invert = true;
10821    }
10822
10823  if (cond_code == LE)
10824    val++;
10825
10826  rtx tmp = gen_reg_rtx (<MODE>mode);
10827  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10828  rtx x = gen_reg_rtx (<MODE>mode);
10829  if (val < 0)
10830    emit_insn (gen_and<mode>3 (x, op1, tmp));
10831  else
10832    emit_insn (gen_ior<mode>3 (x, op1, tmp));
10833
10834  if (invert)
10835    {
10836      rtx tmp = gen_reg_rtx (<MODE>mode);
10837      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10838      x = tmp;
10839    }
10840
10841  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10842  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10843
10844  DONE;
10845})
10846
10847(define_expand "cstore<mode>4_unsigned_imm"
10848  [(use (match_operator 1 "unsigned_comparison_operator"
10849         [(match_operand:GPR 2 "gpc_reg_operand")
10850          (match_operand:GPR 3 "immediate_operand")]))
10851   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10852  ""
10853{
10854  bool invert = false;
10855
10856  enum rtx_code cond_code = GET_CODE (operands[1]);
10857
10858  rtx op0 = operands[0];
10859  rtx op1 = operands[2];
10860  HOST_WIDE_INT val = INTVAL (operands[3]);
10861
10862  if (cond_code == GEU || cond_code == GTU)
10863    {
10864      cond_code = reverse_condition (cond_code);
10865      invert = true;
10866    }
10867
10868  if (cond_code == LEU)
10869    val++;
10870
10871  rtx tmp = gen_reg_rtx (<MODE>mode);
10872  rtx tmp2 = gen_reg_rtx (<MODE>mode);
10873  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10874  emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10875  rtx x = gen_reg_rtx (<MODE>mode);
10876  if (val < 0)
10877    emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10878  else
10879    emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10880
10881  if (invert)
10882    {
10883      rtx tmp = gen_reg_rtx (<MODE>mode);
10884      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10885      x = tmp;
10886    }
10887
10888  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10889  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10890
10891  DONE;
10892})
10893
10894(define_expand "cstore<mode>4"
10895  [(use (match_operator 1 "rs6000_cbranch_operator"
10896         [(match_operand:GPR 2 "gpc_reg_operand")
10897          (match_operand:GPR 3 "reg_or_short_operand")]))
10898   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10899  ""
10900{
10901  /* Use ISEL if the user asked for it.  */
10902  if (TARGET_ISEL)
10903    rs6000_emit_sISEL (<MODE>mode, operands);
10904
10905  /* Expanding EQ and NE directly to some machine instructions does not help
10906     but does hurt combine.  So don't.  */
10907  else if (GET_CODE (operands[1]) == EQ)
10908    emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10909  else if (<MODE>mode == Pmode
10910	   && GET_CODE (operands[1]) == NE)
10911    emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10912  else if (GET_CODE (operands[1]) == NE)
10913    {
10914      rtx tmp = gen_reg_rtx (<MODE>mode);
10915      emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10916      emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10917    }
10918
10919  /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10920     etc. combinations magically work out just right.  */
10921  else if (<MODE>mode == Pmode
10922	   && unsigned_comparison_operator (operands[1], VOIDmode))
10923    emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10924					   operands[2], operands[3]));
10925
10926  /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
10927  else if (<MODE>mode == SImode && Pmode == DImode)
10928    emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
10929				    operands[2], operands[3]));
10930
10931  /* For signed comparisons against a constant, we can do some simple
10932     bit-twiddling.  */
10933  else if (signed_comparison_operator (operands[1], VOIDmode)
10934	   && CONST_INT_P (operands[3]))
10935    emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10936					     operands[2], operands[3]));
10937
10938  /* And similarly for unsigned comparisons.  */
10939  else if (unsigned_comparison_operator (operands[1], VOIDmode)
10940	   && CONST_INT_P (operands[3]))
10941    emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10942					       operands[2], operands[3]));
10943
10944  /* We also do not want to use mfcr for signed comparisons.  */
10945  else if (<MODE>mode == Pmode
10946	   && signed_comparison_operator (operands[1], VOIDmode))
10947    emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
10948					 operands[2], operands[3]));
10949
10950  /* Everything else, use the mfcr brute force.  */
10951  else
10952    rs6000_emit_sCOND (<MODE>mode, operands);
10953
10954  DONE;
10955})
10956
10957(define_expand "cstore<mode>4"
10958  [(use (match_operator 1 "rs6000_cbranch_operator"
10959         [(match_operand:FP 2 "gpc_reg_operand")
10960          (match_operand:FP 3 "gpc_reg_operand")]))
10961   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10962  ""
10963{
10964  rs6000_emit_sCOND (<MODE>mode, operands);
10965  DONE;
10966})
10967
10968
10969(define_expand "stack_protect_set"
10970  [(match_operand 0 "memory_operand" "")
10971   (match_operand 1 "memory_operand" "")]
10972  ""
10973{
10974#ifdef TARGET_THREAD_SSP_OFFSET
10975  rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10976  rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10977  operands[1] = gen_rtx_MEM (Pmode, addr);
10978#endif
10979  if (TARGET_64BIT)
10980    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10981  else
10982    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10983  DONE;
10984})
10985
10986(define_insn "stack_protect_setsi"
10987  [(set (match_operand:SI 0 "memory_operand" "=m")
10988	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10989   (set (match_scratch:SI 2 "=&r") (const_int 0))]
10990  "TARGET_32BIT"
10991  "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10992  [(set_attr "type" "three")
10993   (set_attr "length" "12")])
10994
10995(define_insn "stack_protect_setdi"
10996  [(set (match_operand:DI 0 "memory_operand" "=Y")
10997	(unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10998   (set (match_scratch:DI 2 "=&r") (const_int 0))]
10999  "TARGET_64BIT"
11000  "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11001  [(set_attr "type" "three")
11002   (set_attr "length" "12")])
11003
11004(define_expand "stack_protect_test"
11005  [(match_operand 0 "memory_operand" "")
11006   (match_operand 1 "memory_operand" "")
11007   (match_operand 2 "" "")]
11008  ""
11009{
11010  rtx test, op0, op1;
11011#ifdef TARGET_THREAD_SSP_OFFSET
11012  rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11013  rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11014  operands[1] = gen_rtx_MEM (Pmode, addr);
11015#endif
11016  op0 = operands[0];
11017  op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11018  test = gen_rtx_EQ (VOIDmode, op0, op1);
11019  emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11020  DONE;
11021})
11022
11023(define_insn "stack_protect_testsi"
11024  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11025        (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11026		      (match_operand:SI 2 "memory_operand" "m,m")]
11027		     UNSPEC_SP_TEST))
11028   (set (match_scratch:SI 4 "=r,r") (const_int 0))
11029   (clobber (match_scratch:SI 3 "=&r,&r"))]
11030  "TARGET_32BIT"
11031  "@
11032   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11033   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11034  [(set_attr "length" "16,20")])
11035
11036(define_insn "stack_protect_testdi"
11037  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11038        (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11039		      (match_operand:DI 2 "memory_operand" "Y,Y")]
11040		     UNSPEC_SP_TEST))
11041   (set (match_scratch:DI 4 "=r,r") (const_int 0))
11042   (clobber (match_scratch:DI 3 "=&r,&r"))]
11043  "TARGET_64BIT"
11044  "@
11045   ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11046   ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11047  [(set_attr "length" "16,20")])
11048
11049
11050;; Here are the actual compare insns.
11051(define_insn "*cmp<mode>_signed"
11052  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11053	(compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11054		    (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11055  ""
11056  "cmp<wd>%I2 %0,%1,%2"
11057  [(set_attr "type" "cmp")])
11058
11059(define_insn "*cmp<mode>_unsigned"
11060  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11061	(compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11062		       (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11063  ""
11064  "cmpl<wd>%I2 %0,%1,%2"
11065  [(set_attr "type" "cmp")])
11066
11067;; If we are comparing a register for equality with a large constant,
11068;; we can do this with an XOR followed by a compare.  But this is profitable
11069;; only if the large constant is only used for the comparison (and in this
11070;; case we already have a register to reuse as scratch).
11071;;
11072;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11073;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11074
11075(define_peephole2
11076  [(set (match_operand:SI 0 "register_operand")
11077        (match_operand:SI 1 "logical_const_operand" ""))
11078   (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11079		       [(match_dup 0)
11080			(match_operand:SI 2 "logical_const_operand" "")]))
11081   (set (match_operand:CC 4 "cc_reg_operand" "")
11082        (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11083                    (match_dup 0)))
11084   (set (pc)
11085        (if_then_else (match_operator 6 "equality_operator"
11086                       [(match_dup 4) (const_int 0)])
11087                      (match_operand 7 "" "")
11088                      (match_operand 8 "" "")))]
11089  "peep2_reg_dead_p (3, operands[0])
11090   && peep2_reg_dead_p (4, operands[4])
11091   && REGNO (operands[0]) != REGNO (operands[5])"
11092 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11093  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11094  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11095
11096{
11097  /* Get the constant we are comparing against, and see what it looks like
11098     when sign-extended from 16 to 32 bits.  Then see what constant we could
11099     XOR with SEXTC to get the sign-extended value.  */
11100  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11101					      SImode,
11102					      operands[1], operands[2]);
11103  HOST_WIDE_INT c = INTVAL (cnst);
11104  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11105  HOST_WIDE_INT xorv = c ^ sextc;
11106
11107  operands[9] = GEN_INT (xorv);
11108  operands[10] = GEN_INT (sextc);
11109})
11110
11111;; The following two insns don't exist as single insns, but if we provide
11112;; them, we can swap an add and compare, which will enable us to overlap more
11113;; of the required delay between a compare and branch.  We generate code for
11114;; them by splitting.
11115
11116(define_insn ""
11117  [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11118	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11119		    (match_operand:SI 2 "short_cint_operand" "i")))
11120   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11121	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11122  ""
11123  "#"
11124  [(set_attr "length" "8")])
11125
11126(define_insn ""
11127  [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11128	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11129		       (match_operand:SI 2 "u_short_cint_operand" "i")))
11130   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11131	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11132  ""
11133  "#"
11134  [(set_attr "length" "8")])
11135
11136(define_split
11137  [(set (match_operand:CC 3 "cc_reg_operand" "")
11138	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11139		    (match_operand:SI 2 "short_cint_operand" "")))
11140   (set (match_operand:SI 0 "gpc_reg_operand" "")
11141	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11142  ""
11143  [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11144   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11145
11146(define_split
11147  [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11148	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11149		       (match_operand:SI 2 "u_short_cint_operand" "")))
11150   (set (match_operand:SI 0 "gpc_reg_operand" "")
11151	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11152  ""
11153  [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11154   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11155
11156;; Only need to compare second words if first words equal
11157(define_insn "*cmp<mode>_internal1"
11158  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11159	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11160		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11161  "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11162   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11163  "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11164  [(set_attr "type" "fpcompare")
11165   (set_attr "length" "12")])
11166
11167(define_insn_and_split "*cmp<mode>_internal2"
11168  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11169	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11170		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11171    (clobber (match_scratch:DF 3 "=d"))
11172    (clobber (match_scratch:DF 4 "=d"))
11173    (clobber (match_scratch:DF 5 "=d"))
11174    (clobber (match_scratch:DF 6 "=d"))
11175    (clobber (match_scratch:DF 7 "=d"))
11176    (clobber (match_scratch:DF 8 "=d"))
11177    (clobber (match_scratch:DF 9 "=d"))
11178    (clobber (match_scratch:DF 10 "=d"))
11179    (clobber (match_scratch:GPR 11 "=b"))]
11180  "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11181   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11182  "#"
11183  "&& reload_completed"
11184  [(set (match_dup 3) (match_dup 14))
11185   (set (match_dup 4) (match_dup 15))
11186   (set (match_dup 9) (abs:DF (match_dup 5)))
11187   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11188   (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11189			   (label_ref (match_dup 12))
11190			   (pc)))
11191   (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11192   (set (pc) (label_ref (match_dup 13)))
11193   (match_dup 12)
11194   (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11195   (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11196   (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11197   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11198   (match_dup 13)]
11199{
11200  REAL_VALUE_TYPE rv;
11201  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11202  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11203
11204  operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11205  operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11206  operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11207  operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11208  operands[12] = gen_label_rtx ();
11209  operands[13] = gen_label_rtx ();
11210  real_inf (&rv);
11211  operands[14] = force_const_mem (DFmode,
11212				  const_double_from_real_value (rv, DFmode));
11213  operands[15] = force_const_mem (DFmode,
11214				  const_double_from_real_value (dconst0,
11215								DFmode));
11216  if (TARGET_TOC)
11217    {
11218      rtx tocref;
11219      tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11220      operands[14] = gen_const_mem (DFmode, tocref);
11221      tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11222      operands[15] = gen_const_mem (DFmode, tocref);
11223      set_mem_alias_set (operands[14], get_TOC_alias_set ());
11224      set_mem_alias_set (operands[15], get_TOC_alias_set ());
11225    }
11226})
11227
11228;; Now we have the scc insns.  We can do some combinations because of the
11229;; way the machine works.
11230;;
11231;; Note that this is probably faster if we can put an insn between the
11232;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11233;; cases the insns below which don't use an intermediate CR field will
11234;; be used instead.
11235(define_insn ""
11236  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11237	(match_operator:SI 1 "scc_comparison_operator"
11238			   [(match_operand 2 "cc_reg_operand" "y")
11239			    (const_int 0)]))]
11240  ""
11241  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11242  [(set (attr "type")
11243     (cond [(match_test "TARGET_MFCRF")
11244		(const_string "mfcrf")
11245	   ]
11246	(const_string "mfcr")))
11247   (set_attr "length" "8")])
11248
11249;; Same as above, but get the GT bit.
11250(define_insn "move_from_CR_gt_bit"
11251  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11252	(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11253  "TARGET_HARD_FLOAT && !TARGET_FPRS"
11254  "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11255  [(set_attr "type" "mfcr")
11256   (set_attr "length" "8")])
11257
11258;; Same as above, but get the OV/ORDERED bit.
11259(define_insn "move_from_CR_ov_bit"
11260  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11261	(unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11262		   UNSPEC_MV_CR_OV))]
11263  "TARGET_ISEL"
11264  "mfcr %0\;rlwinm %0,%0,%t1,1"
11265  [(set_attr "type" "mfcr")
11266   (set_attr "length" "8")])
11267
11268(define_insn ""
11269  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11270	(match_operator:DI 1 "scc_comparison_operator"
11271			   [(match_operand 2 "cc_reg_operand" "y")
11272			    (const_int 0)]))]
11273  "TARGET_POWERPC64"
11274  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11275  [(set (attr "type")
11276     (cond [(match_test "TARGET_MFCRF")
11277		(const_string "mfcrf")
11278	   ]
11279	(const_string "mfcr")))
11280   (set_attr "length" "8")])
11281
11282(define_insn ""
11283  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11284	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
11285				       [(match_operand 2 "cc_reg_operand" "y,y")
11286					(const_int 0)])
11287		    (const_int 0)))
11288   (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11289	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11290  "TARGET_32BIT"
11291  "@
11292   mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11293   #"
11294  [(set_attr "type" "shift")
11295   (set_attr "dot" "yes")
11296   (set_attr "length" "8,16")])
11297
11298(define_split
11299  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11300	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
11301				       [(match_operand 2 "cc_reg_operand" "")
11302					(const_int 0)])
11303		    (const_int 0)))
11304   (set (match_operand:SI 3 "gpc_reg_operand" "")
11305	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11306  "TARGET_32BIT && reload_completed"
11307  [(set (match_dup 3)
11308	(match_op_dup 1 [(match_dup 2) (const_int 0)]))
11309   (set (match_dup 0)
11310	(compare:CC (match_dup 3)
11311		    (const_int 0)))]
11312  "")
11313
11314(define_insn ""
11315  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11316	(ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11317				      [(match_operand 2 "cc_reg_operand" "y")
11318				       (const_int 0)])
11319		   (match_operand:SI 3 "const_int_operand" "n")))]
11320  ""
11321  "*
11322{
11323  int is_bit = ccr_bit (operands[1], 1);
11324  int put_bit = 31 - (INTVAL (operands[3]) & 31);
11325  int count;
11326
11327  if (is_bit >= put_bit)
11328    count = is_bit - put_bit;
11329  else
11330    count = 32 - (put_bit - is_bit);
11331
11332  operands[4] = GEN_INT (count);
11333  operands[5] = GEN_INT (put_bit);
11334
11335  return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11336}"
11337  [(set (attr "type")
11338     (cond [(match_test "TARGET_MFCRF")
11339		(const_string "mfcrf")
11340	   ]
11341	(const_string "mfcr")))
11342   (set_attr "length" "8")])
11343
11344(define_insn ""
11345  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11346	(compare:CC
11347	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11348				       [(match_operand 2 "cc_reg_operand" "y,y")
11349					(const_int 0)])
11350		    (match_operand:SI 3 "const_int_operand" "n,n"))
11351	 (const_int 0)))
11352   (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11353	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11354		   (match_dup 3)))]
11355  ""
11356  "*
11357{
11358  int is_bit = ccr_bit (operands[1], 1);
11359  int put_bit = 31 - (INTVAL (operands[3]) & 31);
11360  int count;
11361
11362  /* Force split for non-cc0 compare.  */
11363  if (which_alternative == 1)
11364     return \"#\";
11365
11366  if (is_bit >= put_bit)
11367    count = is_bit - put_bit;
11368  else
11369    count = 32 - (put_bit - is_bit);
11370
11371  operands[5] = GEN_INT (count);
11372  operands[6] = GEN_INT (put_bit);
11373
11374  return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11375}"
11376  [(set_attr "type" "shift")
11377   (set_attr "dot" "yes")
11378   (set_attr "length" "8,16")])
11379
11380(define_split
11381  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11382	(compare:CC
11383	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11384				       [(match_operand 2 "cc_reg_operand" "")
11385					(const_int 0)])
11386		    (match_operand:SI 3 "const_int_operand" ""))
11387	 (const_int 0)))
11388   (set (match_operand:SI 4 "gpc_reg_operand" "")
11389	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11390		   (match_dup 3)))]
11391  "reload_completed"
11392  [(set (match_dup 4)
11393	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11394		   (match_dup 3)))
11395   (set (match_dup 0)
11396	(compare:CC (match_dup 4)
11397		    (const_int 0)))]
11398  "")
11399
11400;; There is a 3 cycle delay between consecutive mfcr instructions
11401;; so it is useful to combine 2 scc instructions to use only one mfcr.
11402
11403(define_peephole
11404  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11405	(match_operator:SI 1 "scc_comparison_operator"
11406			   [(match_operand 2 "cc_reg_operand" "y")
11407			    (const_int 0)]))
11408   (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11409	(match_operator:SI 4 "scc_comparison_operator"
11410			   [(match_operand 5 "cc_reg_operand" "y")
11411			    (const_int 0)]))]
11412  "REGNO (operands[2]) != REGNO (operands[5])"
11413  "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11414  [(set_attr "type" "mfcr")
11415   (set_attr "length" "12")])
11416
11417(define_peephole
11418  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11419	(match_operator:DI 1 "scc_comparison_operator"
11420			   [(match_operand 2 "cc_reg_operand" "y")
11421			    (const_int 0)]))
11422   (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11423	(match_operator:DI 4 "scc_comparison_operator"
11424			   [(match_operand 5 "cc_reg_operand" "y")
11425			    (const_int 0)]))]
11426  "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11427  "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11428  [(set_attr "type" "mfcr")
11429   (set_attr "length" "12")])
11430
11431
11432(define_mode_attr scc_eq_op2 [(SI "rKLI")
11433			      (DI "rKJI")])
11434
11435(define_insn_and_split "eq<mode>3"
11436  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11437	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11438		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11439   (clobber (match_scratch:GPR 3 "=r"))
11440   (clobber (match_scratch:GPR 4 "=r"))]
11441  ""
11442  "#"
11443  ""
11444  [(set (match_dup 4)
11445	(clz:GPR (match_dup 3)))
11446   (set (match_dup 0)
11447	(lshiftrt:GPR (match_dup 4)
11448		      (match_dup 5)))]
11449{
11450  operands[3] = rs6000_emit_eqne (<MODE>mode,
11451				  operands[1], operands[2], operands[3]);
11452
11453  if (GET_CODE (operands[4]) == SCRATCH)
11454    operands[4] = gen_reg_rtx (<MODE>mode);
11455
11456  operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11457}
11458  [(set (attr "length")
11459	(if_then_else (match_test "operands[2] == const0_rtx")
11460		      (const_string "8")
11461		      (const_string "12")))])
11462
11463(define_insn_and_split "ne<mode>3"
11464  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11465	(ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11466	      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11467   (clobber (match_scratch:P 3 "=r"))
11468   (clobber (match_scratch:P 4 "=r"))
11469   (clobber (reg:P CA_REGNO))]
11470  "!TARGET_ISEL"
11471  "#"
11472  ""
11473  [(parallel [(set (match_dup 4)
11474		   (plus:P (match_dup 3)
11475			   (const_int -1)))
11476	      (set (reg:P CA_REGNO)
11477		   (ne:P (match_dup 3)
11478			 (const_int 0)))])
11479   (parallel [(set (match_dup 0)
11480		   (plus:P (plus:P (not:P (match_dup 4))
11481				   (reg:P CA_REGNO))
11482			   (match_dup 3)))
11483	      (clobber (reg:P CA_REGNO))])]
11484{
11485  operands[3] = rs6000_emit_eqne (<MODE>mode,
11486				  operands[1], operands[2], operands[3]);
11487
11488  if (GET_CODE (operands[4]) == SCRATCH)
11489    operands[4] = gen_reg_rtx (<MODE>mode);
11490}
11491  [(set (attr "length")
11492	(if_then_else (match_test "operands[2] == const0_rtx")
11493		      (const_string "8")
11494		      (const_string "12")))])
11495
11496(define_insn_and_split "*neg_eq_<mode>"
11497  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11498	(neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11499		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11500   (clobber (match_scratch:P 3 "=r"))
11501   (clobber (match_scratch:P 4 "=r"))
11502   (clobber (reg:P CA_REGNO))]
11503  ""
11504  "#"
11505  ""
11506  [(parallel [(set (match_dup 4)
11507		   (plus:P (match_dup 3)
11508			   (const_int -1)))
11509	      (set (reg:P CA_REGNO)
11510		   (ne:P (match_dup 3)
11511			 (const_int 0)))])
11512   (parallel [(set (match_dup 0)
11513		   (plus:P (reg:P CA_REGNO)
11514			   (const_int -1)))
11515	      (clobber (reg:P CA_REGNO))])]
11516{
11517  operands[3] = rs6000_emit_eqne (<MODE>mode,
11518				  operands[1], operands[2], operands[3]);
11519
11520  if (GET_CODE (operands[4]) == SCRATCH)
11521    operands[4] = gen_reg_rtx (<MODE>mode);
11522}
11523  [(set (attr "length")
11524	(if_then_else (match_test "operands[2] == const0_rtx")
11525		      (const_string "8")
11526		      (const_string "12")))])
11527
11528(define_insn_and_split "*neg_ne_<mode>"
11529  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11530	(neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11531		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11532   (clobber (match_scratch:P 3 "=r"))
11533   (clobber (match_scratch:P 4 "=r"))
11534   (clobber (reg:P CA_REGNO))]
11535  ""
11536  "#"
11537  ""
11538  [(parallel [(set (match_dup 4)
11539		   (neg:P (match_dup 3)))
11540	      (set (reg:P CA_REGNO)
11541		   (eq:P (match_dup 3)
11542			 (const_int 0)))])
11543   (parallel [(set (match_dup 0)
11544		   (plus:P (reg:P CA_REGNO)
11545			   (const_int -1)))
11546	      (clobber (reg:P CA_REGNO))])]
11547{
11548  operands[3] = rs6000_emit_eqne (<MODE>mode,
11549				  operands[1], operands[2], operands[3]);
11550
11551  if (GET_CODE (operands[4]) == SCRATCH)
11552    operands[4] = gen_reg_rtx (<MODE>mode);
11553}
11554  [(set (attr "length")
11555	(if_then_else (match_test "operands[2] == const0_rtx")
11556		      (const_string "8")
11557		      (const_string "12")))])
11558
11559(define_insn_and_split "*plus_eq_<mode>"
11560  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11561	(plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11562		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11563		(match_operand:P 3 "gpc_reg_operand" "r")))
11564   (clobber (match_scratch:P 4 "=r"))
11565   (clobber (match_scratch:P 5 "=r"))
11566   (clobber (reg:P CA_REGNO))]
11567  ""
11568  "#"
11569  ""
11570  [(parallel [(set (match_dup 5)
11571		   (neg:P (match_dup 4)))
11572	      (set (reg:P CA_REGNO)
11573		   (eq:P (match_dup 4)
11574			 (const_int 0)))])
11575   (parallel [(set (match_dup 0)
11576		   (plus:P (match_dup 3)
11577			   (reg:P CA_REGNO)))
11578	      (clobber (reg:P CA_REGNO))])]
11579{
11580  operands[4] = rs6000_emit_eqne (<MODE>mode,
11581				  operands[1], operands[2], operands[4]);
11582
11583  if (GET_CODE (operands[5]) == SCRATCH)
11584    operands[5] = gen_reg_rtx (<MODE>mode);
11585}
11586  [(set (attr "length")
11587	(if_then_else (match_test "operands[2] == const0_rtx")
11588		      (const_string "8")
11589		      (const_string "12")))])
11590
11591(define_insn_and_split "*plus_ne_<mode>"
11592  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11593	(plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11594		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11595		(match_operand:P 3 "gpc_reg_operand" "r")))
11596   (clobber (match_scratch:P 4 "=r"))
11597   (clobber (match_scratch:P 5 "=r"))
11598   (clobber (reg:P CA_REGNO))]
11599  ""
11600  "#"
11601  ""
11602  [(parallel [(set (match_dup 5)
11603		   (plus:P (match_dup 4)
11604			   (const_int -1)))
11605	      (set (reg:P CA_REGNO)
11606		   (ne:P (match_dup 4)
11607			 (const_int 0)))])
11608   (parallel [(set (match_dup 0)
11609		   (plus:P (match_dup 3)
11610			   (reg:P CA_REGNO)))
11611	      (clobber (reg:P CA_REGNO))])]
11612{
11613  operands[4] = rs6000_emit_eqne (<MODE>mode,
11614				  operands[1], operands[2], operands[4]);
11615
11616  if (GET_CODE (operands[5]) == SCRATCH)
11617    operands[5] = gen_reg_rtx (<MODE>mode);
11618}
11619  [(set (attr "length")
11620	(if_then_else (match_test "operands[2] == const0_rtx")
11621		      (const_string "8")
11622		      (const_string "12")))])
11623
11624(define_insn_and_split "*minus_eq_<mode>"
11625  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11626	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11627		 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11628		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11629   (clobber (match_scratch:P 4 "=r"))
11630   (clobber (match_scratch:P 5 "=r"))
11631   (clobber (reg:P CA_REGNO))]
11632  ""
11633  "#"
11634  ""
11635  [(parallel [(set (match_dup 5)
11636		   (plus:P (match_dup 4)
11637			   (const_int -1)))
11638	      (set (reg:P CA_REGNO)
11639		   (ne:P (match_dup 4)
11640			 (const_int 0)))])
11641   (parallel [(set (match_dup 0)
11642		   (plus:P (plus:P (match_dup 3)
11643				   (reg:P CA_REGNO))
11644			   (const_int -1)))
11645	      (clobber (reg:P CA_REGNO))])]
11646{
11647  operands[4] = rs6000_emit_eqne (<MODE>mode,
11648				  operands[1], operands[2], operands[4]);
11649
11650  if (GET_CODE (operands[5]) == SCRATCH)
11651    operands[5] = gen_reg_rtx (<MODE>mode);
11652}
11653  [(set (attr "length")
11654	(if_then_else (match_test "operands[2] == const0_rtx")
11655		      (const_string "8")
11656		      (const_string "12")))])
11657
11658(define_insn_and_split "*minus_ne_<mode>"
11659  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11660	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11661		 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11662		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11663   (clobber (match_scratch:P 4 "=r"))
11664   (clobber (match_scratch:P 5 "=r"))
11665   (clobber (reg:P CA_REGNO))]
11666  ""
11667  "#"
11668  ""
11669  [(parallel [(set (match_dup 5)
11670		   (neg:P (match_dup 4)))
11671	      (set (reg:P CA_REGNO)
11672		   (eq:P (match_dup 4)
11673			 (const_int 0)))])
11674   (parallel [(set (match_dup 0)
11675		   (plus:P (plus:P (match_dup 3)
11676				   (reg:P CA_REGNO))
11677			   (const_int -1)))
11678	      (clobber (reg:P CA_REGNO))])]
11679{
11680  operands[4] = rs6000_emit_eqne (<MODE>mode,
11681				  operands[1], operands[2], operands[4]);
11682
11683  if (GET_CODE (operands[5]) == SCRATCH)
11684    operands[5] = gen_reg_rtx (<MODE>mode);
11685}
11686  [(set (attr "length")
11687	(if_then_else (match_test "operands[2] == const0_rtx")
11688		      (const_string "8")
11689		      (const_string "12")))])
11690
11691(define_insn_and_split "*eqsi3_ext<mode>"
11692  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11693	(eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11694		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11695   (clobber (match_scratch:SI 3 "=r"))
11696   (clobber (match_scratch:SI 4 "=r"))]
11697  ""
11698  "#"
11699  ""
11700  [(set (match_dup 4)
11701	(clz:SI (match_dup 3)))
11702   (set (match_dup 0)
11703	(zero_extend:EXTSI
11704	  (lshiftrt:SI (match_dup 4)
11705		       (const_int 5))))]
11706{
11707  operands[3] = rs6000_emit_eqne (SImode,
11708				  operands[1], operands[2], operands[3]);
11709
11710  if (GET_CODE (operands[4]) == SCRATCH)
11711    operands[4] = gen_reg_rtx (SImode);
11712}
11713  [(set (attr "length")
11714	(if_then_else (match_test "operands[2] == const0_rtx")
11715		      (const_string "8")
11716		      (const_string "12")))])
11717
11718(define_insn_and_split "*nesi3_ext<mode>"
11719  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11720	(ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11721		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11722   (clobber (match_scratch:SI 3 "=r"))
11723   (clobber (match_scratch:SI 4 "=r"))
11724   (clobber (match_scratch:EXTSI 5 "=r"))]
11725  ""
11726  "#"
11727  ""
11728  [(set (match_dup 4)
11729	(clz:SI (match_dup 3)))
11730   (set (match_dup 5)
11731	(zero_extend:EXTSI
11732	  (lshiftrt:SI (match_dup 4)
11733		       (const_int 5))))
11734   (set (match_dup 0)
11735	(xor:EXTSI (match_dup 5)
11736		   (const_int 1)))]
11737{
11738  operands[3] = rs6000_emit_eqne (SImode,
11739				  operands[1], operands[2], operands[3]);
11740
11741  if (GET_CODE (operands[4]) == SCRATCH)
11742    operands[4] = gen_reg_rtx (SImode);
11743  if (GET_CODE (operands[5]) == SCRATCH)
11744    operands[5] = gen_reg_rtx (<MODE>mode);
11745}
11746  [(set (attr "length")
11747	(if_then_else (match_test "operands[2] == const0_rtx")
11748		      (const_string "12")
11749		      (const_string "16")))])
11750
11751;; Define both directions of branch and return.  If we need a reload
11752;; register, we'd rather use CR0 since it is much easier to copy a
11753;; register CC value to there.
11754
11755(define_insn ""
11756  [(set (pc)
11757	(if_then_else (match_operator 1 "branch_comparison_operator"
11758				      [(match_operand 2
11759						      "cc_reg_operand" "y")
11760				       (const_int 0)])
11761		      (label_ref (match_operand 0 "" ""))
11762		      (pc)))]
11763  ""
11764  "*
11765{
11766  return output_cbranch (operands[1], \"%l0\", 0, insn);
11767}"
11768  [(set_attr "type" "branch")])
11769
11770(define_insn ""
11771  [(set (pc)
11772	(if_then_else (match_operator 0 "branch_comparison_operator"
11773				      [(match_operand 1
11774						      "cc_reg_operand" "y")
11775				       (const_int 0)])
11776		      (any_return)
11777		      (pc)))]
11778  "<return_pred>"
11779  "*
11780{
11781  return output_cbranch (operands[0], NULL, 0, insn);
11782}"
11783  [(set_attr "type" "jmpreg")
11784   (set_attr "length" "4")])
11785
11786(define_insn ""
11787  [(set (pc)
11788	(if_then_else (match_operator 1 "branch_comparison_operator"
11789				      [(match_operand 2
11790						      "cc_reg_operand" "y")
11791				       (const_int 0)])
11792		      (pc)
11793		      (label_ref (match_operand 0 "" ""))))]
11794  ""
11795  "*
11796{
11797  return output_cbranch (operands[1], \"%l0\", 1, insn);
11798}"
11799  [(set_attr "type" "branch")])
11800
11801(define_insn ""
11802  [(set (pc)
11803	(if_then_else (match_operator 0 "branch_comparison_operator"
11804				      [(match_operand 1
11805						      "cc_reg_operand" "y")
11806				       (const_int 0)])
11807		      (pc)
11808		      (any_return)))]
11809  "<return_pred>"
11810  "*
11811{
11812  return output_cbranch (operands[0], NULL, 1, insn);
11813}"
11814  [(set_attr "type" "jmpreg")
11815   (set_attr "length" "4")])
11816
11817;; Logic on condition register values.
11818
11819; This pattern matches things like
11820; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11821;					   (eq:SI (reg:CCFP 68) (const_int 0)))
11822;				   (const_int 1)))
11823; which are generated by the branch logic.
11824; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11825
11826(define_insn "*cceq_ior_compare"
11827  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11828        (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11829	                [(match_operator:SI 2
11830				      "branch_positive_comparison_operator"
11831				      [(match_operand 3
11832						      "cc_reg_operand" "y,y")
11833				       (const_int 0)])
11834	                 (match_operator:SI 4
11835				      "branch_positive_comparison_operator"
11836				      [(match_operand 5
11837						      "cc_reg_operand" "0,y")
11838				       (const_int 0)])])
11839		      (const_int 1)))]
11840  ""
11841  "cr%q1 %E0,%j2,%j4"
11842  [(set_attr "type" "cr_logical,delayed_cr")])
11843
11844; Why is the constant -1 here, but 1 in the previous pattern?
11845; Because ~1 has all but the low bit set.
11846(define_insn ""
11847  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11848        (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11849	                [(not:SI (match_operator:SI 2
11850				      "branch_positive_comparison_operator"
11851				      [(match_operand 3
11852						      "cc_reg_operand" "y,y")
11853				       (const_int 0)]))
11854	                 (match_operator:SI 4
11855				"branch_positive_comparison_operator"
11856				[(match_operand 5
11857						"cc_reg_operand" "0,y")
11858				 (const_int 0)])])
11859		      (const_int -1)))]
11860  ""
11861  "cr%q1 %E0,%j2,%j4"
11862  [(set_attr "type" "cr_logical,delayed_cr")])
11863
11864(define_insn "*cceq_rev_compare"
11865  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11866	(compare:CCEQ (match_operator:SI 1
11867				      "branch_positive_comparison_operator"
11868				      [(match_operand 2
11869						      "cc_reg_operand" "0,y")
11870				       (const_int 0)])
11871		      (const_int 0)))]
11872  ""
11873  "crnot %E0,%j1"
11874  [(set_attr "type" "cr_logical,delayed_cr")])
11875
11876;; If we are comparing the result of two comparisons, this can be done
11877;; using creqv or crxor.
11878
11879(define_insn_and_split ""
11880  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11881	(compare:CCEQ (match_operator 1 "branch_comparison_operator"
11882			      [(match_operand 2 "cc_reg_operand" "y")
11883			       (const_int 0)])
11884		      (match_operator 3 "branch_comparison_operator"
11885			      [(match_operand 4 "cc_reg_operand" "y")
11886			       (const_int 0)])))]
11887  ""
11888  "#"
11889  ""
11890  [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11891				    (match_dup 5)))]
11892  "
11893{
11894  int positive_1, positive_2;
11895
11896  positive_1 = branch_positive_comparison_operator (operands[1],
11897						    GET_MODE (operands[1]));
11898  positive_2 = branch_positive_comparison_operator (operands[3],
11899						    GET_MODE (operands[3]));
11900
11901  if (! positive_1)
11902    operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11903							    GET_CODE (operands[1])),
11904				  SImode,
11905				  operands[2], const0_rtx);
11906  else if (GET_MODE (operands[1]) != SImode)
11907    operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11908				  operands[2], const0_rtx);
11909
11910  if (! positive_2)
11911    operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11912							    GET_CODE (operands[3])),
11913				  SImode,
11914				  operands[4], const0_rtx);
11915  else if (GET_MODE (operands[3]) != SImode)
11916    operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11917				  operands[4], const0_rtx);
11918
11919  if (positive_1 == positive_2)
11920    {
11921      operands[1] = gen_rtx_NOT (SImode, operands[1]);
11922      operands[5] = constm1_rtx;
11923    }
11924  else
11925    {
11926      operands[5] = const1_rtx;
11927    }
11928}")
11929
11930;; Unconditional branch and return.
11931
11932(define_insn "jump"
11933  [(set (pc)
11934	(label_ref (match_operand 0 "" "")))]
11935  ""
11936  "b %l0"
11937  [(set_attr "type" "branch")])
11938
11939(define_insn "<return_str>return"
11940  [(any_return)]
11941  "<return_pred>"
11942  "blr"
11943  [(set_attr "type" "jmpreg")])
11944
11945(define_expand "indirect_jump"
11946  [(set (pc) (match_operand 0 "register_operand" ""))])
11947
11948(define_insn "*indirect_jump<mode>"
11949  [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11950  ""
11951  "@
11952   bctr
11953   blr"
11954  [(set_attr "type" "jmpreg")])
11955
11956;; Table jump for switch statements:
11957(define_expand "tablejump"
11958  [(use (match_operand 0 "" ""))
11959   (use (label_ref (match_operand 1 "" "")))]
11960  ""
11961  "
11962{
11963  if (TARGET_32BIT)
11964    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11965  else
11966    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11967  DONE;
11968}")
11969
11970(define_expand "tablejumpsi"
11971  [(set (match_dup 3)
11972	(plus:SI (match_operand:SI 0 "" "")
11973		 (match_dup 2)))
11974   (parallel [(set (pc) (match_dup 3))
11975	      (use (label_ref (match_operand 1 "" "")))])]
11976  "TARGET_32BIT"
11977  "
11978{ operands[0] = force_reg (SImode, operands[0]);
11979  operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11980  operands[3] = gen_reg_rtx (SImode);
11981}")
11982
11983(define_expand "tablejumpdi"
11984  [(set (match_dup 4)
11985        (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11986   (set (match_dup 3)
11987	(plus:DI (match_dup 4)
11988		 (match_dup 2)))
11989   (parallel [(set (pc) (match_dup 3))
11990	      (use (label_ref (match_operand 1 "" "")))])]
11991  "TARGET_64BIT"
11992  "
11993{ operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11994  operands[3] = gen_reg_rtx (DImode);
11995  operands[4] = gen_reg_rtx (DImode);
11996}")
11997
11998(define_insn "*tablejump<mode>_internal1"
11999  [(set (pc)
12000	(match_operand:P 0 "register_operand" "c,*l"))
12001   (use (label_ref (match_operand 1 "" "")))]
12002  ""
12003  "@
12004   bctr
12005   blr"
12006  [(set_attr "type" "jmpreg")])
12007
12008(define_insn "nop"
12009  [(unspec [(const_int 0)] UNSPEC_NOP)]
12010  ""
12011  "nop")
12012
12013(define_insn "group_ending_nop"
12014  [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12015  ""
12016  "*
12017{
12018  if (rs6000_cpu_attr == CPU_POWER6)
12019    return \"ori 1,1,0\";
12020  return \"ori 2,2,0\";
12021}")
12022
12023;; Define the subtract-one-and-jump insns, starting with the template
12024;; so loop.c knows what to generate.
12025
12026(define_expand "doloop_end"
12027  [(use (match_operand 0 "" ""))	; loop pseudo
12028   (use (match_operand 1 "" ""))]	; label
12029  ""
12030  "
12031{
12032  if (TARGET_64BIT)
12033    {
12034      if (GET_MODE (operands[0]) != DImode)
12035	FAIL;
12036      emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12037    }
12038  else
12039    {
12040      if (GET_MODE (operands[0]) != SImode)
12041	FAIL;
12042      emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12043    }
12044  DONE;
12045}")
12046
12047(define_expand "ctr<mode>"
12048  [(parallel [(set (pc)
12049		   (if_then_else (ne (match_operand:P 0 "register_operand" "")
12050				     (const_int 1))
12051				 (label_ref (match_operand 1 "" ""))
12052				 (pc)))
12053	      (set (match_dup 0)
12054		   (plus:P (match_dup 0)
12055			    (const_int -1)))
12056	      (unspec [(const_int 0)] UNSPEC_DOLOOP)
12057	      (clobber (match_scratch:CC 2 ""))
12058	      (clobber (match_scratch:P 3 ""))])]
12059  ""
12060  "")
12061
12062;; We need to be able to do this for any operand, including MEM, or we
12063;; will cause reload to blow up since we don't allow output reloads on
12064;; JUMP_INSNs.
12065;; For the length attribute to be calculated correctly, the
12066;; label MUST be operand 0.
12067;; The UNSPEC is present to prevent combine creating this pattern.
12068
12069(define_insn "*ctr<mode>_internal1"
12070  [(set (pc)
12071	(if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12072			  (const_int 1))
12073		      (label_ref (match_operand 0 "" ""))
12074		      (pc)))
12075   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12076	(plus:P (match_dup 1)
12077		 (const_int -1)))
12078   (unspec [(const_int 0)] UNSPEC_DOLOOP)
12079   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12080   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12081  ""
12082  "*
12083{
12084  if (which_alternative != 0)
12085    return \"#\";
12086  else if (get_attr_length (insn) == 4)
12087    return \"bdnz %l0\";
12088  else
12089    return \"bdz $+8\;b %l0\";
12090}"
12091  [(set_attr "type" "branch")
12092   (set_attr "length" "*,16,20,20")])
12093
12094(define_insn "*ctr<mode>_internal2"
12095  [(set (pc)
12096	(if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12097			  (const_int 1))
12098		      (pc)
12099		      (label_ref (match_operand 0 "" ""))))
12100   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12101	(plus:P (match_dup 1)
12102		 (const_int -1)))
12103   (unspec [(const_int 0)] UNSPEC_DOLOOP)
12104   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12105   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12106  ""
12107  "*
12108{
12109  if (which_alternative != 0)
12110    return \"#\";
12111  else if (get_attr_length (insn) == 4)
12112    return \"bdz %l0\";
12113  else
12114    return \"bdnz $+8\;b %l0\";
12115}"
12116  [(set_attr "type" "branch")
12117   (set_attr "length" "*,16,20,20")])
12118
12119;; Similar but use EQ
12120
12121(define_insn "*ctr<mode>_internal5"
12122  [(set (pc)
12123	(if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12124			  (const_int 1))
12125		      (label_ref (match_operand 0 "" ""))
12126		      (pc)))
12127   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12128	(plus:P (match_dup 1)
12129		 (const_int -1)))
12130   (unspec [(const_int 0)] UNSPEC_DOLOOP)
12131   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12132   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12133  ""
12134  "*
12135{
12136  if (which_alternative != 0)
12137    return \"#\";
12138  else if (get_attr_length (insn) == 4)
12139    return \"bdz %l0\";
12140  else
12141    return \"bdnz $+8\;b %l0\";
12142}"
12143  [(set_attr "type" "branch")
12144   (set_attr "length" "*,16,20,20")])
12145
12146(define_insn "*ctr<mode>_internal6"
12147  [(set (pc)
12148	(if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12149			  (const_int 1))
12150		      (pc)
12151		      (label_ref (match_operand 0 "" ""))))
12152   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12153	(plus:P (match_dup 1)
12154		 (const_int -1)))
12155   (unspec [(const_int 0)] UNSPEC_DOLOOP)
12156   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12157   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12158  ""
12159  "*
12160{
12161  if (which_alternative != 0)
12162    return \"#\";
12163  else if (get_attr_length (insn) == 4)
12164    return \"bdnz %l0\";
12165  else
12166    return \"bdz $+8\;b %l0\";
12167}"
12168  [(set_attr "type" "branch")
12169   (set_attr "length" "*,16,20,20")])
12170
12171;; Now the splitters if we could not allocate the CTR register
12172
12173(define_split
12174  [(set (pc)
12175	(if_then_else (match_operator 2 "comparison_operator"
12176				      [(match_operand:P 1 "gpc_reg_operand" "")
12177				       (const_int 1)])
12178		      (match_operand 5 "" "")
12179		      (match_operand 6 "" "")))
12180   (set (match_operand:P 0 "int_reg_operand" "")
12181	(plus:P (match_dup 1) (const_int -1)))
12182   (unspec [(const_int 0)] UNSPEC_DOLOOP)
12183   (clobber (match_scratch:CC 3 ""))
12184   (clobber (match_scratch:P 4 ""))]
12185  "reload_completed"
12186  [(set (match_dup 3)
12187	(compare:CC (match_dup 1)
12188		    (const_int 1)))
12189   (set (match_dup 0)
12190	(plus:P (match_dup 1)
12191		(const_int -1)))
12192   (set (pc) (if_then_else (match_dup 7)
12193			   (match_dup 5)
12194			   (match_dup 6)))]
12195  "
12196{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12197				operands[3], const0_rtx); }")
12198
12199(define_split
12200  [(set (pc)
12201	(if_then_else (match_operator 2 "comparison_operator"
12202				      [(match_operand:P 1 "gpc_reg_operand" "")
12203				       (const_int 1)])
12204		      (match_operand 5 "" "")
12205		      (match_operand 6 "" "")))
12206   (set (match_operand:P 0 "nonimmediate_operand" "")
12207	(plus:P (match_dup 1) (const_int -1)))
12208   (unspec [(const_int 0)] UNSPEC_DOLOOP)
12209   (clobber (match_scratch:CC 3 ""))
12210   (clobber (match_scratch:P 4 ""))]
12211  "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12212  [(set (match_dup 3)
12213	(compare:CC (match_dup 1)
12214		    (const_int 1)))
12215   (set (match_dup 4)
12216	(plus:P (match_dup 1)
12217		(const_int -1)))
12218   (set (match_dup 0)
12219	(match_dup 4))
12220   (set (pc) (if_then_else (match_dup 7)
12221			   (match_dup 5)
12222			   (match_dup 6)))]
12223  "
12224{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12225				operands[3], const0_rtx); }")
12226
12227(define_insn "trap"
12228  [(trap_if (const_int 1) (const_int 0))]
12229  ""
12230  "trap"
12231  [(set_attr "type" "trap")])
12232
12233(define_expand "ctrap<mode>4"
12234  [(trap_if (match_operator 0 "ordered_comparison_operator"
12235			    [(match_operand:GPR 1 "register_operand")
12236			     (match_operand:GPR 2 "reg_or_short_operand")])
12237	    (match_operand 3 "zero_constant" ""))]
12238  ""
12239  "")
12240
12241(define_insn ""
12242  [(trap_if (match_operator 0 "ordered_comparison_operator"
12243                            [(match_operand:GPR 1 "register_operand" "r")
12244                             (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12245	    (const_int 0))]
12246  ""
12247  "t<wd>%V0%I2 %1,%2"
12248  [(set_attr "type" "trap")])
12249
12250;; Insns related to generating the function prologue and epilogue.
12251
12252(define_expand "prologue"
12253  [(use (const_int 0))]
12254  ""
12255{
12256  rs6000_emit_prologue ();
12257  if (!TARGET_SCHED_PROLOG)
12258    emit_insn (gen_blockage ());
12259  DONE;
12260})
12261
12262(define_insn "*movesi_from_cr_one"
12263  [(match_parallel 0 "mfcr_operation"
12264		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12265			 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12266				     (match_operand 3 "immediate_operand" "n")]
12267			  UNSPEC_MOVESI_FROM_CR))])]
12268  "TARGET_MFCRF"
12269  "*
12270{
12271  int mask = 0;
12272  int i;
12273  for (i = 0; i < XVECLEN (operands[0], 0); i++)
12274  {
12275    mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12276    operands[4] = GEN_INT (mask);
12277    output_asm_insn (\"mfcr %1,%4\", operands);
12278  }
12279  return \"\";
12280}"
12281  [(set_attr "type" "mfcrf")])
12282
12283(define_insn "movesi_from_cr"
12284  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12285        (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12286		    (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12287		    (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12288		    (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12289		   UNSPEC_MOVESI_FROM_CR))]
12290  ""
12291  "mfcr %0"
12292  [(set_attr "type" "mfcr")])
12293
12294(define_insn "*crsave"
12295  [(match_parallel 0 "crsave_operation"
12296		   [(set (match_operand:SI 1 "memory_operand" "=m")
12297			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12298  ""
12299  "stw %2,%1"
12300  [(set_attr "type" "store")])
12301
12302(define_insn "*stmw"
12303  [(match_parallel 0 "stmw_operation"
12304		   [(set (match_operand:SI 1 "memory_operand" "=m")
12305       			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12306  "TARGET_MULTIPLE"
12307  "stmw %2,%1"
12308  [(set_attr "type" "store")
12309   (set_attr "update" "yes")
12310   (set_attr "indexed" "yes")])
12311
12312; The following comment applies to:
12313;     save_gpregs_*
12314;     save_fpregs_*
12315;     restore_gpregs*
12316;     return_and_restore_gpregs*
12317;     return_and_restore_fpregs*
12318;     return_and_restore_fpregs_aix*
12319;
12320; The out-of-line save / restore functions expects one input argument.
12321; Since those are not standard call_insn's, we must avoid using
12322; MATCH_OPERAND for that argument. That way the register rename
12323; optimization will not try to rename this register.
12324; Each pattern is repeated for each possible register number used in
12325; various ABIs (r11, r1, and for some functions r12)
12326
12327(define_insn "*save_gpregs_<mode>_r11"
12328  [(match_parallel 0 "any_parallel_operand"
12329		   [(clobber (reg:P 65))
12330		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12331                    (use (reg:P 11))
12332		    (set (match_operand:P 2 "memory_operand" "=m")
12333			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12334  ""
12335  "bl %1"
12336  [(set_attr "type" "branch")
12337   (set_attr "length" "4")])
12338
12339(define_insn "*save_gpregs_<mode>_r12"
12340  [(match_parallel 0 "any_parallel_operand"
12341		   [(clobber (reg:P 65))
12342		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12343                    (use (reg:P 12))
12344		    (set (match_operand:P 2 "memory_operand" "=m")
12345			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12346  ""
12347  "bl %1"
12348  [(set_attr "type" "branch")
12349   (set_attr "length" "4")])
12350
12351(define_insn "*save_gpregs_<mode>_r1"
12352  [(match_parallel 0 "any_parallel_operand"
12353		   [(clobber (reg:P 65))
12354		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12355                    (use (reg:P 1))
12356		    (set (match_operand:P 2 "memory_operand" "=m")
12357			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12358  ""
12359  "bl %1"
12360  [(set_attr "type" "branch")
12361   (set_attr "length" "4")])
12362
12363(define_insn "*save_fpregs_<mode>_r11"
12364  [(match_parallel 0 "any_parallel_operand"
12365		   [(clobber (reg:P 65))
12366		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12367                    (use (reg:P 11))
12368		    (set (match_operand:DF 2 "memory_operand" "=m")
12369			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12370  ""
12371  "bl %1"
12372  [(set_attr "type" "branch")
12373   (set_attr "length" "4")])
12374
12375(define_insn "*save_fpregs_<mode>_r12"
12376  [(match_parallel 0 "any_parallel_operand"
12377		   [(clobber (reg:P 65))
12378		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12379                    (use (reg:P 12))
12380		    (set (match_operand:DF 2 "memory_operand" "=m")
12381			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12382  ""
12383  "bl %1"
12384  [(set_attr "type" "branch")
12385   (set_attr "length" "4")])
12386
12387(define_insn "*save_fpregs_<mode>_r1"
12388  [(match_parallel 0 "any_parallel_operand"
12389		   [(clobber (reg:P 65))
12390		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12391                    (use (reg:P 1))
12392		    (set (match_operand:DF 2 "memory_operand" "=m")
12393			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12394  ""
12395  "bl %1"
12396  [(set_attr "type" "branch")
12397   (set_attr "length" "4")])
12398
12399; This is to explain that changes to the stack pointer should
12400; not be moved over loads from or stores to stack memory.
12401(define_insn "stack_tie"
12402  [(match_parallel 0 "tie_operand"
12403		   [(set (mem:BLK (reg 1)) (const_int 0))])]
12404  ""
12405  ""
12406  [(set_attr "length" "0")])
12407
12408(define_expand "epilogue"
12409  [(use (const_int 0))]
12410  ""
12411{
12412  if (!TARGET_SCHED_PROLOG)
12413    emit_insn (gen_blockage ());
12414  rs6000_emit_epilogue (FALSE);
12415  DONE;
12416})
12417
12418; On some processors, doing the mtcrf one CC register at a time is
12419; faster (like on the 604e).  On others, doing them all at once is
12420; faster; for instance, on the 601 and 750.
12421
12422(define_expand "movsi_to_cr_one"
12423  [(set (match_operand:CC 0 "cc_reg_operand" "")
12424        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12425		    (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12426  ""
12427  "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12428
12429(define_insn "*movsi_to_cr"
12430  [(match_parallel 0 "mtcrf_operation"
12431		   [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12432			 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12433				     (match_operand 3 "immediate_operand" "n")]
12434				    UNSPEC_MOVESI_TO_CR))])]
12435 ""
12436 "*
12437{
12438  int mask = 0;
12439  int i;
12440  for (i = 0; i < XVECLEN (operands[0], 0); i++)
12441    mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12442  operands[4] = GEN_INT (mask);
12443  return \"mtcrf %4,%2\";
12444}"
12445  [(set_attr "type" "mtcr")])
12446
12447(define_insn "*mtcrfsi"
12448  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12449        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12450		    (match_operand 2 "immediate_operand" "n")]
12451		   UNSPEC_MOVESI_TO_CR))]
12452  "GET_CODE (operands[0]) == REG
12453   && CR_REGNO_P (REGNO (operands[0]))
12454   && GET_CODE (operands[2]) == CONST_INT
12455   && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12456  "mtcrf %R0,%1"
12457  [(set_attr "type" "mtcr")])
12458
12459; The load-multiple instructions have similar properties.
12460; Note that "load_multiple" is a name known to the machine-independent
12461; code that actually corresponds to the PowerPC load-string.
12462
12463(define_insn "*lmw"
12464  [(match_parallel 0 "lmw_operation"
12465		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12466       			 (match_operand:SI 2 "memory_operand" "m"))])]
12467  "TARGET_MULTIPLE"
12468  "lmw %1,%2"
12469  [(set_attr "type" "load")
12470   (set_attr "update" "yes")
12471   (set_attr "indexed" "yes")
12472   (set_attr "cell_micro" "always")])
12473
12474(define_insn "*return_internal_<mode>"
12475  [(simple_return)
12476   (use (match_operand:P 0 "register_operand" "lc"))]
12477  ""
12478  "b%T0"
12479  [(set_attr "type" "jmpreg")])
12480
12481; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12482; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12483
12484; The following comment applies to:
12485;     save_gpregs_*
12486;     save_fpregs_*
12487;     restore_gpregs*
12488;     return_and_restore_gpregs*
12489;     return_and_restore_fpregs*
12490;     return_and_restore_fpregs_aix*
12491;
12492; The out-of-line save / restore functions expects one input argument.
12493; Since those are not standard call_insn's, we must avoid using
12494; MATCH_OPERAND for that argument. That way the register rename
12495; optimization will not try to rename this register.
12496; Each pattern is repeated for each possible register number used in
12497; various ABIs (r11, r1, and for some functions r12)
12498
12499(define_insn "*restore_gpregs_<mode>_r11"
12500 [(match_parallel 0 "any_parallel_operand"
12501                  [(clobber (match_operand:P 1 "register_operand" "=l"))
12502                   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12503                   (use (reg:P 11))
12504		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
12505			(match_operand:P 4 "memory_operand" "m"))])]
12506 ""
12507 "bl %2"
12508 [(set_attr "type" "branch")
12509  (set_attr "length" "4")])
12510
12511(define_insn "*restore_gpregs_<mode>_r12"
12512 [(match_parallel 0 "any_parallel_operand"
12513                  [(clobber (match_operand:P 1 "register_operand" "=l"))
12514                   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12515                   (use (reg:P 12))
12516		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
12517			(match_operand:P 4 "memory_operand" "m"))])]
12518 ""
12519 "bl %2"
12520 [(set_attr "type" "branch")
12521  (set_attr "length" "4")])
12522
12523(define_insn "*restore_gpregs_<mode>_r1"
12524 [(match_parallel 0 "any_parallel_operand"
12525                  [(clobber (match_operand:P 1 "register_operand" "=l"))
12526                   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12527                   (use (reg:P 1))
12528		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
12529			(match_operand:P 4 "memory_operand" "m"))])]
12530 ""
12531 "bl %2"
12532 [(set_attr "type" "branch")
12533  (set_attr "length" "4")])
12534
12535(define_insn "*return_and_restore_gpregs_<mode>_r11"
12536 [(match_parallel 0 "any_parallel_operand"
12537                  [(return)
12538		   (clobber (match_operand:P 1 "register_operand" "=l"))
12539		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12540                   (use (reg:P 11))
12541		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
12542			(match_operand:P 4 "memory_operand" "m"))])]
12543 ""
12544 "b %2"
12545 [(set_attr "type" "branch")
12546  (set_attr "length" "4")])
12547
12548(define_insn "*return_and_restore_gpregs_<mode>_r12"
12549 [(match_parallel 0 "any_parallel_operand"
12550                  [(return)
12551		   (clobber (match_operand:P 1 "register_operand" "=l"))
12552		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12553                   (use (reg:P 12))
12554		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
12555			(match_operand:P 4 "memory_operand" "m"))])]
12556 ""
12557 "b %2"
12558 [(set_attr "type" "branch")
12559  (set_attr "length" "4")])
12560
12561(define_insn "*return_and_restore_gpregs_<mode>_r1"
12562 [(match_parallel 0 "any_parallel_operand"
12563                  [(return)
12564		   (clobber (match_operand:P 1 "register_operand" "=l"))
12565		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12566                   (use (reg:P 1))
12567		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
12568			(match_operand:P 4 "memory_operand" "m"))])]
12569 ""
12570 "b %2"
12571 [(set_attr "type" "branch")
12572  (set_attr "length" "4")])
12573
12574(define_insn "*return_and_restore_fpregs_<mode>_r11"
12575 [(match_parallel 0 "any_parallel_operand"
12576                  [(return)
12577		   (clobber (match_operand:P 1 "register_operand" "=l"))
12578		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12579                   (use (reg:P 11))
12580		   (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12581			(match_operand:DF 4 "memory_operand" "m"))])]
12582 ""
12583 "b %2"
12584 [(set_attr "type" "branch")
12585  (set_attr "length" "4")])
12586
12587(define_insn "*return_and_restore_fpregs_<mode>_r12"
12588 [(match_parallel 0 "any_parallel_operand"
12589                  [(return)
12590		   (clobber (match_operand:P 1 "register_operand" "=l"))
12591		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12592                   (use (reg:P 12))
12593		   (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12594			(match_operand:DF 4 "memory_operand" "m"))])]
12595 ""
12596 "b %2"
12597 [(set_attr "type" "branch")
12598  (set_attr "length" "4")])
12599
12600(define_insn "*return_and_restore_fpregs_<mode>_r1"
12601 [(match_parallel 0 "any_parallel_operand"
12602                  [(return)
12603		   (clobber (match_operand:P 1 "register_operand" "=l"))
12604		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12605                   (use (reg:P 1))
12606		   (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12607			(match_operand:DF 4 "memory_operand" "m"))])]
12608 ""
12609 "b %2"
12610 [(set_attr "type" "branch")
12611  (set_attr "length" "4")])
12612
12613(define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12614 [(match_parallel 0 "any_parallel_operand"
12615		  [(return)
12616		   (use (match_operand:P 1 "register_operand" "l"))
12617		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12618		   (use (reg:P 11))
12619		   (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12620			(match_operand:DF 4 "memory_operand" "m"))])]
12621 ""
12622 "b %2"
12623 [(set_attr "type" "branch")
12624  (set_attr "length" "4")])
12625
12626(define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12627 [(match_parallel 0 "any_parallel_operand"
12628		  [(return)
12629		   (use (match_operand:P 1 "register_operand" "l"))
12630		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
12631		   (use (reg:P 1))
12632		   (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12633			(match_operand:DF 4 "memory_operand" "m"))])]
12634 ""
12635 "b %2"
12636 [(set_attr "type" "branch")
12637  (set_attr "length" "4")])
12638
12639; This is used in compiling the unwind routines.
12640(define_expand "eh_return"
12641  [(use (match_operand 0 "general_operand" ""))]
12642  ""
12643  "
12644{
12645  if (TARGET_32BIT)
12646    emit_insn (gen_eh_set_lr_si (operands[0]));
12647  else
12648    emit_insn (gen_eh_set_lr_di (operands[0]));
12649  DONE;
12650}")
12651
12652; We can't expand this before we know where the link register is stored.
12653(define_insn "eh_set_lr_<mode>"
12654  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12655  		    UNSPECV_EH_RR)
12656   (clobber (match_scratch:P 1 "=&b"))]
12657  ""
12658  "#")
12659
12660(define_split
12661  [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12662   (clobber (match_scratch 1 ""))]
12663  "reload_completed"
12664  [(const_int 0)]
12665  "
12666{
12667  rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12668  DONE;
12669}")
12670
12671(define_insn "prefetch"
12672  [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12673	     (match_operand:SI 1 "const_int_operand" "n")
12674	     (match_operand:SI 2 "const_int_operand" "n"))]
12675  ""
12676  "*
12677{
12678  if (GET_CODE (operands[0]) == REG)
12679    return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12680  return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12681}"
12682  [(set_attr "type" "load")])
12683
12684;; Handle -fsplit-stack.
12685
12686(define_expand "split_stack_prologue"
12687  [(const_int 0)]
12688  ""
12689{
12690  rs6000_expand_split_stack_prologue ();
12691  DONE;
12692})
12693
12694(define_expand "load_split_stack_limit"
12695  [(set (match_operand 0)
12696	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12697  ""
12698{
12699  emit_insn (gen_rtx_SET (operands[0],
12700			  gen_rtx_UNSPEC (Pmode,
12701					  gen_rtvec (1, const0_rtx),
12702					  UNSPEC_STACK_CHECK)));
12703  DONE;
12704})
12705
12706(define_insn "load_split_stack_limit_di"
12707  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12708	(unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12709  "TARGET_64BIT"
12710  "ld %0,-0x7040(13)"
12711  [(set_attr "type" "load")
12712   (set_attr "update" "no")
12713   (set_attr "indexed" "no")])
12714
12715(define_insn "load_split_stack_limit_si"
12716  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12717	(unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12718  "!TARGET_64BIT"
12719  "lwz %0,-0x7020(2)"
12720  [(set_attr "type" "load")
12721   (set_attr "update" "no")
12722   (set_attr "indexed" "no")])
12723
12724;; A return instruction which the middle-end doesn't see.
12725;; Use r0 to stop regrename twiddling with lr restore insns emitted
12726;; after the call to __morestack.
12727(define_insn "split_stack_return"
12728  [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
12729  ""
12730  "blr"
12731  [(set_attr "type" "jmpreg")])
12732
12733;; If there are operand 0 bytes available on the stack, jump to
12734;; operand 1.
12735(define_expand "split_stack_space_check"
12736  [(set (match_dup 2)
12737	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12738   (set (match_dup 3)
12739	(minus (reg STACK_POINTER_REGNUM)
12740	       (match_operand 0)))
12741   (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12742   (set (pc) (if_then_else
12743	      (geu (match_dup 4) (const_int 0))
12744	      (label_ref (match_operand 1))
12745	      (pc)))]
12746  ""
12747{
12748  rs6000_split_stack_space_check (operands[0], operands[1]);
12749  DONE;
12750})
12751
12752(define_insn "bpermd_<mode>"
12753  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12754	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12755		   (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12756  "TARGET_POPCNTD"
12757  "bpermd %0,%1,%2"
12758  [(set_attr "type" "popcnt")])
12759
12760
12761;; Builtin fma support.  Handle
12762;; Note that the conditions for expansion are in the FMA_F iterator.
12763
12764(define_expand "fma<mode>4"
12765  [(set (match_operand:FMA_F 0 "register_operand" "")
12766	(fma:FMA_F
12767	  (match_operand:FMA_F 1 "register_operand" "")
12768	  (match_operand:FMA_F 2 "register_operand" "")
12769	  (match_operand:FMA_F 3 "register_operand" "")))]
12770  ""
12771  "")
12772
12773(define_insn "*fma<mode>4_fpr"
12774  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12775	(fma:SFDF
12776	  (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12777	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12778	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12779  "TARGET_<MODE>_FPR"
12780  "@
12781   fmadd<Ftrad> %0,%1,%2,%3
12782   xsmadda<Fvsx> %x0,%x1,%x2
12783   xsmaddm<Fvsx> %x0,%x1,%x3"
12784  [(set_attr "type" "fp")
12785   (set_attr "fp_type" "fp_maddsub_<Fs>")])
12786
12787; Altivec only has fma and nfms.
12788(define_expand "fms<mode>4"
12789  [(set (match_operand:FMA_F 0 "register_operand" "")
12790	(fma:FMA_F
12791	  (match_operand:FMA_F 1 "register_operand" "")
12792	  (match_operand:FMA_F 2 "register_operand" "")
12793	  (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12794  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12795  "")
12796
12797(define_insn "*fms<mode>4_fpr"
12798  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12799	(fma:SFDF
12800	 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12801	 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12802	 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12803  "TARGET_<MODE>_FPR"
12804  "@
12805   fmsub<Ftrad> %0,%1,%2,%3
12806   xsmsuba<Fvsx> %x0,%x1,%x2
12807   xsmsubm<Fvsx> %x0,%x1,%x3"
12808  [(set_attr "type" "fp")
12809   (set_attr "fp_type" "fp_maddsub_<Fs>")])
12810
12811;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12812(define_expand "fnma<mode>4"
12813  [(set (match_operand:FMA_F 0 "register_operand" "")
12814	(neg:FMA_F
12815	  (fma:FMA_F
12816	    (match_operand:FMA_F 1 "register_operand" "")
12817	    (match_operand:FMA_F 2 "register_operand" "")
12818	    (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12819  "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12820  "")
12821
12822;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12823(define_expand "fnms<mode>4"
12824  [(set (match_operand:FMA_F 0 "register_operand" "")
12825	(neg:FMA_F
12826	  (fma:FMA_F
12827	    (match_operand:FMA_F 1 "register_operand" "")
12828	    (match_operand:FMA_F 2 "register_operand" "")
12829	    (match_operand:FMA_F 3 "register_operand" ""))))]
12830  "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12831  "")
12832
12833; Not an official optab name, but used from builtins.
12834(define_expand "nfma<mode>4"
12835  [(set (match_operand:FMA_F 0 "register_operand" "")
12836	(neg:FMA_F
12837	  (fma:FMA_F
12838	    (match_operand:FMA_F 1 "register_operand" "")
12839	    (match_operand:FMA_F 2 "register_operand" "")
12840	    (match_operand:FMA_F 3 "register_operand" ""))))]
12841  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12842  "")
12843
12844(define_insn "*nfma<mode>4_fpr"
12845  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12846	(neg:SFDF
12847	 (fma:SFDF
12848	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12849	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12850	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12851  "TARGET_<MODE>_FPR"
12852  "@
12853   fnmadd<Ftrad> %0,%1,%2,%3
12854   xsnmadda<Fvsx> %x0,%x1,%x2
12855   xsnmaddm<Fvsx> %x0,%x1,%x3"
12856  [(set_attr "type" "fp")
12857   (set_attr "fp_type" "fp_maddsub_<Fs>")])
12858
12859; Not an official optab name, but used from builtins.
12860(define_expand "nfms<mode>4"
12861  [(set (match_operand:FMA_F 0 "register_operand" "")
12862	(neg:FMA_F
12863	  (fma:FMA_F
12864	    (match_operand:FMA_F 1 "register_operand" "")
12865	    (match_operand:FMA_F 2 "register_operand" "")
12866	    (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12867  ""
12868  "")
12869
12870(define_insn "*nfmssf4_fpr"
12871  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12872	(neg:SFDF
12873	 (fma:SFDF
12874	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12875	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12876	  (neg:SFDF
12877	   (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
12878  "TARGET_<MODE>_FPR"
12879  "@
12880   fnmsub<Ftrad> %0,%1,%2,%3
12881   xsnmsuba<Fvsx> %x0,%x1,%x2
12882   xsnmsubm<Fvsx> %x0,%x1,%x3"
12883  [(set_attr "type" "fp")
12884   (set_attr "fp_type" "fp_maddsub_<Fs>")])
12885
12886
12887(define_expand "rs6000_get_timebase"
12888  [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12889  ""
12890{
12891  if (TARGET_POWERPC64)
12892    emit_insn (gen_rs6000_mftb_di (operands[0]));
12893  else
12894    emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12895  DONE;
12896})
12897
12898(define_insn "rs6000_get_timebase_ppc32"
12899  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12900        (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12901   (clobber (match_scratch:SI 1 "=r"))
12902   (clobber (match_scratch:CC 2 "=y"))]
12903  "!TARGET_POWERPC64"
12904{
12905  if (WORDS_BIG_ENDIAN)
12906    if (TARGET_MFCRF)
12907      {
12908        return "mfspr %0,269\;"
12909	       "mfspr %L0,268\;"
12910	       "mfspr %1,269\;"
12911	       "cmpw %2,%0,%1\;"
12912	       "bne- %2,$-16";
12913      }
12914    else
12915      {
12916        return "mftbu %0\;"
12917	       "mftb %L0\;"
12918	       "mftbu %1\;"
12919	       "cmpw %2,%0,%1\;"
12920	       "bne- %2,$-16";
12921      }
12922  else
12923    if (TARGET_MFCRF)
12924      {
12925        return "mfspr %L0,269\;"
12926	       "mfspr %0,268\;"
12927	       "mfspr %1,269\;"
12928	       "cmpw %2,%L0,%1\;"
12929	       "bne- %2,$-16";
12930      }
12931    else
12932      {
12933        return "mftbu %L0\;"
12934	       "mftb %0\;"
12935	       "mftbu %1\;"
12936	       "cmpw %2,%L0,%1\;"
12937	       "bne- %2,$-16";
12938      }
12939}
12940  [(set_attr "length" "20")])
12941
12942(define_insn "rs6000_mftb_<mode>"
12943  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12944        (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12945  ""
12946{
12947  if (TARGET_MFCRF)
12948    return "mfspr %0,268";
12949  else
12950    return "mftb %0";
12951})
12952
12953
12954(define_insn "rs6000_mffs"
12955  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12956	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12957  "TARGET_HARD_FLOAT && TARGET_FPRS"
12958  "mffs %0")
12959
12960(define_insn "rs6000_mtfsf"
12961  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12962		     (match_operand:DF 1 "gpc_reg_operand" "d")]
12963		    UNSPECV_MTFSF)]
12964  "TARGET_HARD_FLOAT && TARGET_FPRS"
12965  "mtfsf %0,%1")
12966
12967
12968;; Power8 fusion support for fusing an addis instruction with a D-form load of
12969;; a GPR.  The addis instruction must be adjacent to the load, and use the same
12970;; register that is being loaded.  The fused ops must be physically adjacent.
12971
12972;; There are two parts to addis fusion.  The support for fused TOCs occur
12973;; before register allocation, and is meant to reduce the lifetime for the
12974;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
12975;; to use the register that is being load.  The peephole2 then gathers any
12976;; other fused possibilities that it can find after register allocation.  If
12977;; power9 fusion is selected, we also fuse floating point loads/stores.
12978
12979;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
12980;; before register allocation, so that we can avoid allocating a temporary base
12981;; register that won't be used, and that we try to load into base registers,
12982;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
12983;; (addis followed by load) even on power8.
12984
12985(define_split
12986  [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
12987	(match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
12988  "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
12989  [(parallel [(set (match_dup 0) (match_dup 2))
12990	      (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12991	      (use (match_dup 3))
12992	      (clobber (scratch:DI))])]
12993{
12994  operands[2] = fusion_wrap_memory_address (operands[1]);
12995  operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
12996})
12997
12998(define_insn "*toc_fusionload_<mode>"
12999  [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13000	(match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13001   (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13002   (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13003   (clobber (match_scratch:DI 3 "=X,&b"))]
13004  "TARGET_TOC_FUSION_INT"
13005{
13006  if (base_reg_operand (operands[0], <MODE>mode))
13007    return emit_fusion_gpr_load (operands[0], operands[1]);
13008
13009  return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13010}
13011  [(set_attr "type" "load")
13012   (set_attr "length" "8")])
13013
13014(define_insn "*toc_fusionload_di"
13015  [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13016	(match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13017   (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13018   (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13019   (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13020  "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13021   && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13022{
13023  if (base_reg_operand (operands[0], DImode))
13024    return emit_fusion_gpr_load (operands[0], operands[1]);
13025
13026  return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13027}
13028  [(set_attr "type" "load")
13029   (set_attr "length" "8")])
13030
13031
13032;; Find cases where the addis that feeds into a load instruction is either used
13033;; once or is the same as the target register, and replace it with the fusion
13034;; insn
13035
13036(define_peephole2
13037  [(set (match_operand:P 0 "base_reg_operand" "")
13038	(match_operand:P 1 "fusion_gpr_addis" ""))
13039   (set (match_operand:INT1 2 "base_reg_operand" "")
13040	(match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13041  "TARGET_P8_FUSION
13042   && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13043			 operands[3])"
13044  [(const_int 0)]
13045{
13046  expand_fusion_gpr_load (operands);
13047  DONE;
13048})
13049
13050;; Fusion insn, created by the define_peephole2 above (and eventually by
13051;; reload)
13052
13053(define_insn "fusion_gpr_load_<mode>"
13054  [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13055	(unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13056		     UNSPEC_FUSION_GPR))]
13057  "TARGET_P8_FUSION"
13058{
13059  return emit_fusion_gpr_load (operands[0], operands[1]);
13060}
13061  [(set_attr "type" "load")
13062   (set_attr "length" "8")])
13063
13064
13065;; ISA 3.0 (power9) fusion support
13066;; Merge addis with floating load/store to FPRs (or GPRs).
13067(define_peephole2
13068  [(set (match_operand:P 0 "base_reg_operand" "")
13069	(match_operand:P 1 "fusion_gpr_addis" ""))
13070   (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13071	(match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13072  "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13073   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13074  [(const_int 0)]
13075{
13076  expand_fusion_p9_load (operands);
13077  DONE;
13078})
13079
13080(define_peephole2
13081  [(set (match_operand:P 0 "base_reg_operand" "")
13082	(match_operand:P 1 "fusion_gpr_addis" ""))
13083   (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13084	(match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13085  "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13086   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13087   && !rtx_equal_p (operands[0], operands[3])"
13088  [(const_int 0)]
13089{
13090  expand_fusion_p9_store (operands);
13091  DONE;
13092})
13093
13094(define_peephole2
13095  [(set (match_operand:SDI 0 "int_reg_operand" "")
13096	(match_operand:SDI 1 "upper16_cint_operand" ""))
13097   (set (match_dup 0)
13098	(ior:SDI (match_dup 0)
13099		 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13100  "TARGET_P9_FUSION"
13101  [(set (match_dup 0)
13102	(unspec:SDI [(match_dup 1)
13103		     (match_dup 2)] UNSPEC_FUSION_P9))])
13104
13105(define_peephole2
13106  [(set (match_operand:SDI 0 "int_reg_operand" "")
13107	(match_operand:SDI 1 "upper16_cint_operand" ""))
13108   (set (match_operand:SDI 2 "int_reg_operand" "")
13109	(ior:SDI (match_dup 0)
13110		 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13111  "TARGET_P9_FUSION
13112   && !rtx_equal_p (operands[0], operands[2])
13113   && peep2_reg_dead_p (2, operands[0])"
13114  [(set (match_dup 2)
13115	(unspec:SDI [(match_dup 1)
13116		     (match_dup 3)] UNSPEC_FUSION_P9))])
13117
13118;; Fusion insns, created by the define_peephole2 above (and eventually by
13119;; reload).  Because we want to eventually have secondary_reload generate
13120;; these, they have to have a single alternative that gives the register
13121;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13122(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13123  [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13124	(unspec:GPR_FUSION
13125	 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13126	 UNSPEC_FUSION_P9))
13127   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13128  "TARGET_P9_FUSION"
13129{
13130  /* This insn is a secondary reload insn, which cannot have alternatives.
13131     If we are not loading up register 0, use the power8 fusion instead.  */
13132  if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13133    return emit_fusion_gpr_load (operands[0], operands[1]);
13134
13135  return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13136}
13137  [(set_attr "type" "load")
13138   (set_attr "length" "8")])
13139
13140(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13141  [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13142	(unspec:GPR_FUSION
13143	 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13144	 UNSPEC_FUSION_P9))
13145   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13146  "TARGET_P9_FUSION"
13147{
13148  return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13149}
13150  [(set_attr "type" "store")
13151   (set_attr "length" "8")])
13152
13153(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13154  [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13155	(unspec:FPR_FUSION
13156	 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13157	 UNSPEC_FUSION_P9))
13158   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13159  "TARGET_P9_FUSION"
13160{
13161  return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13162}
13163  [(set_attr "type" "fpload")
13164   (set_attr "length" "8")])
13165
13166(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13167  [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13168	(unspec:FPR_FUSION
13169	 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13170	 UNSPEC_FUSION_P9))
13171   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13172  "TARGET_P9_FUSION"
13173{
13174  return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13175}
13176  [(set_attr "type" "fpstore")
13177   (set_attr "length" "8")])
13178
13179(define_insn "*fusion_p9_<mode>_constant"
13180  [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13181	(unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13182		     (match_operand:SDI 2 "u_short_cint_operand" "K")]
13183		    UNSPEC_FUSION_P9))]
13184  "TARGET_P9_FUSION"
13185{
13186  emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13187  return "ori %0,%0,%2";
13188}
13189  [(set_attr "type" "two")
13190   (set_attr "length" "8")])
13191
13192
13193;; Optimize cases where we want to do a D-form load (register+offset) on
13194;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13195;; has generated:
13196;;	load fpr
13197;;	move fpr->altivec
13198
13199(define_peephole2
13200  [(match_scratch:P 0 "b")
13201   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13202	(match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13203   (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13204	(match_dup 1))]
13205  "TARGET_VSX && TARGET_UPPER_REGS_<MODE> && !TARGET_P9_DFORM_SCALAR
13206   && peep2_reg_dead_p (2, operands[1])"
13207  [(set (match_dup 0)
13208	(match_dup 4))
13209   (set (match_dup 3)
13210	(match_dup 5))]
13211{
13212  rtx tmp_reg = operands[0];
13213  rtx mem = operands[2];
13214  rtx addr = XEXP (mem, 0);
13215  rtx add_op0, add_op1, new_addr;
13216
13217  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13218  add_op0 = XEXP (addr, 0);
13219  add_op1 = XEXP (addr, 1);
13220  gcc_assert (REG_P (add_op0));
13221  new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13222
13223  operands[4] = add_op1;
13224  operands[5] = change_address (mem, <MODE>mode, new_addr);
13225})
13226
13227;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13228;; Altivec register, and the register allocator has generated:
13229;;	move altivec->fpr
13230;;	store fpr
13231
13232(define_peephole2
13233  [(match_scratch:P 0 "b")
13234   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13235	(match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13236   (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13237	(match_dup 1))]
13238  "TARGET_VSX && TARGET_UPPER_REGS_<MODE> && !TARGET_P9_DFORM_SCALAR
13239   && peep2_reg_dead_p (2, operands[1])"
13240  [(set (match_dup 0)
13241	(match_dup 4))
13242   (set (match_dup 5)
13243	(match_dup 2))]
13244{
13245  rtx tmp_reg = operands[0];
13246  rtx mem = operands[3];
13247  rtx addr = XEXP (mem, 0);
13248  rtx add_op0, add_op1, new_addr;
13249
13250  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13251  add_op0 = XEXP (addr, 0);
13252  add_op1 = XEXP (addr, 1);
13253  gcc_assert (REG_P (add_op0));
13254  new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13255
13256  operands[4] = add_op1;
13257  operands[5] = change_address (mem, <MODE>mode, new_addr);
13258})
13259
13260
13261;; Miscellaneous ISA 2.06 (power7) instructions
13262(define_insn "addg6s"
13263  [(set (match_operand:SI 0 "register_operand" "=r")
13264	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
13265		    (match_operand:SI 2 "register_operand" "r")]
13266		   UNSPEC_ADDG6S))]
13267  "TARGET_POPCNTD"
13268  "addg6s %0,%1,%2"
13269  [(set_attr "type" "integer")
13270   (set_attr "length" "4")])
13271
13272(define_insn "cdtbcd"
13273  [(set (match_operand:SI 0 "register_operand" "=r")
13274	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13275		   UNSPEC_CDTBCD))]
13276  "TARGET_POPCNTD"
13277  "cdtbcd %0,%1"
13278  [(set_attr "type" "integer")
13279   (set_attr "length" "4")])
13280
13281(define_insn "cbcdtd"
13282  [(set (match_operand:SI 0 "register_operand" "=r")
13283	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13284		   UNSPEC_CBCDTD))]
13285  "TARGET_POPCNTD"
13286  "cbcdtd %0,%1"
13287  [(set_attr "type" "integer")
13288   (set_attr "length" "4")])
13289
13290(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13291					UNSPEC_DIVEU])
13292
13293(define_int_attr div_extend [(UNSPEC_DIVE	"e")
13294			     (UNSPEC_DIVEU	"eu")])
13295
13296(define_insn "div<div_extend>_<mode>"
13297  [(set (match_operand:GPR 0 "register_operand" "=r")
13298	(unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13299		     (match_operand:GPR 2 "register_operand" "r")]
13300		    UNSPEC_DIV_EXTEND))]
13301  "TARGET_POPCNTD"
13302  "div<wd><div_extend> %0,%1,%2"
13303  [(set_attr "type" "div")
13304   (set_attr "size" "<bits>")])
13305
13306
13307;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13308
13309; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13310(define_mode_attr FP128_64 [(TF "DF")
13311			    (IF "DF")
13312			    (TD "DI")
13313			    (KF "DI")])
13314
13315(define_expand "unpack<mode>"
13316  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13317	(unspec:<FP128_64>
13318	 [(match_operand:FMOVE128 1 "register_operand" "")
13319	  (match_operand:QI 2 "const_0_to_1_operand" "")]
13320	 UNSPEC_UNPACK_128BIT))]
13321  "FLOAT128_2REG_P (<MODE>mode)"
13322  "")
13323
13324(define_insn_and_split "unpack<mode>_dm"
13325  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13326	(unspec:<FP128_64>
13327	 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13328	  (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13329	 UNSPEC_UNPACK_128BIT))]
13330  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13331  "#"
13332  "&& reload_completed"
13333  [(set (match_dup 0) (match_dup 3))]
13334{
13335  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13336
13337  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13338    {
13339      emit_note (NOTE_INSN_DELETED);
13340      DONE;
13341    }
13342
13343  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13344}
13345  [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13346   (set_attr "length" "4")])
13347
13348(define_insn_and_split "unpack<mode>_nodm"
13349  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13350	(unspec:<FP128_64>
13351	 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13352	  (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13353	 UNSPEC_UNPACK_128BIT))]
13354  "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13355  "#"
13356  "&& reload_completed"
13357  [(set (match_dup 0) (match_dup 3))]
13358{
13359  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13360
13361  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13362    {
13363      emit_note (NOTE_INSN_DELETED);
13364      DONE;
13365    }
13366
13367  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13368}
13369  [(set_attr "type" "fp,fpstore")
13370   (set_attr "length" "4")])
13371
13372(define_insn_and_split "pack<mode>"
13373  [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13374	(unspec:FMOVE128
13375	 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13376	  (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13377	 UNSPEC_PACK_128BIT))]
13378  "FLOAT128_2REG_P (<MODE>mode)"
13379  "@
13380   fmr %L0,%2
13381   #"
13382  "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13383  [(set (match_dup 3) (match_dup 1))
13384   (set (match_dup 4) (match_dup 2))]
13385{
13386  unsigned dest_hi = REGNO (operands[0]);
13387  unsigned dest_lo = dest_hi + 1;
13388
13389  gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13390  gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13391
13392  operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13393  operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13394}
13395  [(set_attr "type" "fpsimple,fp")
13396   (set_attr "length" "4,8")])
13397
13398(define_insn "unpack<mode>"
13399  [(set (match_operand:DI 0 "register_operand" "=d,d")
13400	(unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13401		    (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13402	 UNSPEC_UNPACK_128BIT))]
13403  "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13404{
13405  if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13406    return ASM_COMMENT_START " xxpermdi to same register";
13407
13408  operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13409  return "xxpermdi %x0,%x1,%x1,%3";
13410}
13411  [(set_attr "type" "vecperm")])
13412
13413(define_insn "pack<mode>"
13414  [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13415	(unspec:FMOVE128_VSX
13416	 [(match_operand:DI 1 "register_operand" "d")
13417	  (match_operand:DI 2 "register_operand" "d")]
13418	 UNSPEC_PACK_128BIT))]
13419  "TARGET_VSX"
13420  "xxpermdi %x0,%x1,%x2,0"
13421  [(set_attr "type" "vecperm")])
13422
13423
13424
13425;; ISA 2.08 IEEE 128-bit floating point support.
13426
13427(define_insn "add<mode>3"
13428  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13429	(plus:IEEE128
13430	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13431	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13432  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13433  "xsaddqp %0,%1,%2"
13434  [(set_attr "type" "vecfloat")
13435   (set_attr "size" "128")])
13436
13437(define_insn "sub<mode>3"
13438  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13439	(minus:IEEE128
13440	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13441	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13442  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13443  "xssubqp %0,%1,%2"
13444  [(set_attr "type" "vecfloat")
13445   (set_attr "size" "128")])
13446
13447(define_insn "mul<mode>3"
13448  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13449	(mult:IEEE128
13450	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13451	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13452  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13453  "xsmulqp %0,%1,%2"
13454  [(set_attr "type" "vecfloat")
13455   (set_attr "size" "128")])
13456
13457(define_insn "div<mode>3"
13458  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13459	(div:IEEE128
13460	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13461	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13462  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13463  "xsdivqp %0,%1,%2"
13464  [(set_attr "type" "vecdiv")
13465   (set_attr "size" "128")])
13466
13467(define_insn "sqrt<mode>2"
13468  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13469	(sqrt:IEEE128
13470	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13471  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13472   "xssqrtqp %0,%1"
13473  [(set_attr "type" "vecdiv")
13474   (set_attr "size" "128")])
13475
13476(define_expand "copysign<mode>3"
13477  [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13478   (use (match_operand:IEEE128 1 "altivec_register_operand"))
13479   (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13480  "FLOAT128_IEEE_P (<MODE>mode)"
13481{
13482  if (TARGET_FLOAT128_HW)
13483    emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13484					 operands[2]));
13485  else
13486    {
13487      rtx tmp = gen_reg_rtx (<MODE>mode);
13488      emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13489					   operands[2], tmp));
13490    }
13491  DONE;
13492})
13493
13494(define_insn "copysign<mode>3_hard"
13495  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13496	(unspec:IEEE128
13497	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13498	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13499	 UNSPEC_COPYSIGN))]
13500  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13501   "xscpsgnqp %0,%2,%1"
13502  [(set_attr "type" "vecmove")
13503   (set_attr "size" "128")])
13504
13505(define_insn "copysign<mode>3_soft"
13506  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13507	(unspec:IEEE128
13508	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13509	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
13510	  (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
13511	 UNSPEC_COPYSIGN))]
13512  "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13513   "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13514  [(set_attr "type" "veccomplex")
13515   (set_attr "length" "8")])
13516
13517(define_insn "neg<mode>2_hw"
13518  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13519	(neg:IEEE128
13520	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13521  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13522  "xsnegqp %0,%1"
13523  [(set_attr "type" "vecmove")
13524   (set_attr "size" "128")])
13525
13526
13527(define_insn "abs<mode>2_hw"
13528  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13529	(abs:IEEE128
13530	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13531  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13532  "xsabsqp %0,%1"
13533  [(set_attr "type" "vecmove")
13534   (set_attr "size" "128")])
13535
13536
13537(define_insn "*nabs<mode>2_hw"
13538  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13539	(neg:IEEE128
13540	 (abs:IEEE128
13541	  (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13542  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13543  "xsnabsqp %0,%1"
13544  [(set_attr "type" "vecmove")
13545   (set_attr "size" "128")])
13546
13547;; Initially don't worry about doing fusion
13548(define_insn "*fma<mode>4_hw"
13549  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13550	(fma:IEEE128
13551	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13552	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13553	 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13554  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13555  "xsmaddqp %0,%1,%2"
13556  [(set_attr "type" "vecfloat")
13557   (set_attr "size" "128")])
13558
13559(define_insn "*fms<mode>4_hw"
13560  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13561	(fma:IEEE128
13562	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13563	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13564	 (neg:IEEE128
13565	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13566  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13567  "xsmsubqp %0,%1,%2"
13568  [(set_attr "type" "vecfloat")
13569   (set_attr "size" "128")])
13570
13571(define_insn "*nfma<mode>4_hw"
13572  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13573	(neg:IEEE128
13574	 (fma:IEEE128
13575	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13576	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
13577	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13578  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13579  "xsnmaddqp %0,%1,%2"
13580  [(set_attr "type" "vecfloat")
13581   (set_attr "size" "128")])
13582
13583(define_insn "*nfms<mode>4_hw"
13584  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13585	(neg:IEEE128
13586	 (fma:IEEE128
13587	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13588	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
13589	  (neg:IEEE128
13590	   (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13591  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13592  "xsnmsubqp %0,%1,%2"
13593  [(set_attr "type" "vecfloat")
13594   (set_attr "size" "128")])
13595
13596(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13597  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13598	(float_extend:IEEE128
13599	 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13600  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13601  "xscvdpqp %0,%1"
13602  [(set_attr "type" "vecfloat")
13603   (set_attr "size" "128")])
13604
13605;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13606;; point is a simple copy.
13607(define_insn_and_split "extendkftf2"
13608  [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13609	(float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13610  "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13611  "@
13612   #
13613   xxlor %x0,%x1,%x1"
13614  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13615  [(const_int 0)]
13616{
13617  emit_note (NOTE_INSN_DELETED);
13618  DONE;
13619}
13620  [(set_attr "type" "*,veclogical")
13621   (set_attr "length" "0,4")])
13622
13623(define_insn_and_split "trunctfkf2"
13624  [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13625	(float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13626  "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13627  "@
13628   #
13629   xxlor %x0,%x1,%x1"
13630  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13631  [(const_int 0)]
13632{
13633  emit_note (NOTE_INSN_DELETED);
13634  DONE;
13635}
13636  [(set_attr "type" "*,veclogical")
13637   (set_attr "length" "0,4")])
13638
13639(define_insn "trunc<mode>df2_hw"
13640  [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13641	(float_truncate:DF
13642	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13643  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13644  "xscvqpdp %0,%1"
13645  [(set_attr "type" "vecfloat")
13646   (set_attr "size" "128")])
13647
13648;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13649;; the KFmode -> DFmode conversion using round to odd rather than the normal
13650;; conversion
13651(define_insn_and_split "trunc<mode>sf2_hw"
13652  [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13653	(float_truncate:SF
13654	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13655   (clobber (match_scratch:DF 2 "=v"))]
13656  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13657  "#"
13658  "&& 1"
13659  [(set (match_dup 2)
13660	(unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13661   (set (match_dup 0)
13662	(float_truncate:SF (match_dup 2)))]
13663{
13664  if (GET_CODE (operands[2]) == SCRATCH)
13665    operands[2] = gen_reg_rtx (DFmode);
13666}
13667  [(set_attr "type" "vecfloat")
13668   (set_attr "length" "8")])
13669
13670;; At present SImode is not allowed in VSX registers at all, and DImode is only
13671;; allowed in the traditional floating point registers. Use V2DImode so that
13672;; we can get a value in an Altivec register.
13673
13674(define_insn_and_split "fix<uns>_<mode>si2_hw"
13675  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13676	(any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13677   (clobber (match_scratch:V2DI 2 "=v,v"))]
13678  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13679  "#"
13680  "&& 1"
13681  [(pc)]
13682{
13683  convert_float128_to_int (operands, <CODE>);
13684  DONE;
13685}
13686  [(set_attr "length" "8")
13687   (set_attr "type" "mftgpr,fpstore")])
13688
13689(define_insn_and_split "fix<uns>_<mode>di2_hw"
13690  [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13691	(any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13692   (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13693  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13694  "#"
13695  "&& 1"
13696  [(pc)]
13697{
13698  convert_float128_to_int (operands, <CODE>);
13699  DONE;
13700}
13701  [(set_attr "length" "8")
13702   (set_attr "type" "mftgpr,vecsimple,fpstore")])
13703
13704(define_insn_and_split "float<uns>_<mode>si2_hw"
13705  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13706	(any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13707   (clobber (match_scratch:V2DI 2 "=v,v"))]
13708  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13709  "#"
13710  "&& 1"
13711  [(pc)]
13712{
13713  convert_int_to_float128 (operands, <CODE>);
13714  DONE;
13715}
13716  [(set_attr "length" "8")
13717   (set_attr "type" "vecfloat")])
13718
13719(define_insn_and_split "float<uns>_<mode>di2_hw"
13720  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13721	(any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13722   (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13723  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13724  "#"
13725  "&& 1"
13726  [(pc)]
13727{
13728  convert_int_to_float128 (operands, <CODE>);
13729  DONE;
13730}
13731  [(set_attr "length" "8")
13732   (set_attr "type" "vecfloat")])
13733
13734;; Integer conversion instructions, using V2DImode to get an Altivec register
13735(define_insn "*xscvqp<su>wz_<mode>"
13736  [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13737	(unspec:V2DI
13738	 [(any_fix:SI
13739	   (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13740	 UNSPEC_IEEE128_CONVERT))]
13741  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13742  "xscvqp<su>wz %0,%1"
13743  [(set_attr "type" "vecfloat")
13744   (set_attr "size" "128")])
13745
13746(define_insn "*xscvqp<su>dz_<mode>"
13747  [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13748	(unspec:V2DI
13749	 [(any_fix:DI
13750	   (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13751	 UNSPEC_IEEE128_CONVERT))]
13752  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13753  "xscvqp<su>dz %0,%1"
13754  [(set_attr "type" "vecfloat")
13755   (set_attr "size" "128")])
13756
13757(define_insn "*xscv<su>dqp_<mode>"
13758  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13759	(any_float:IEEE128
13760	 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13761		    UNSPEC_IEEE128_CONVERT)))]
13762  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13763  "xscv<su>dqp %0,%1"
13764  [(set_attr "type" "vecfloat")
13765   (set_attr "size" "128")])
13766
13767(define_insn "*ieee128_mfvsrd_64bit"
13768  [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13769	(unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13770		   UNSPEC_IEEE128_MOVE))]
13771  "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13772  "@
13773   mfvsrd %0,%x1
13774   stxsdx %x1,%y0
13775   xxlor %x0,%x1,%x1"
13776  [(set_attr "type" "mftgpr,fpstore,veclogical")])
13777
13778
13779(define_insn "*ieee128_mfvsrd_32bit"
13780  [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13781	(unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13782		   UNSPEC_IEEE128_MOVE))]
13783  "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13784  "@
13785   stxsdx %x1,%y0
13786   xxlor %x0,%x1,%x1"
13787  [(set_attr "type" "fpstore,veclogical")])
13788
13789(define_insn "*ieee128_mfvsrwz"
13790  [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13791	(unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13792		   UNSPEC_IEEE128_MOVE))]
13793  "TARGET_FLOAT128_HW"
13794  "@
13795   mfvsrwz %0,%x1
13796   stxsiwx %x1,%y0"
13797  [(set_attr "type" "mftgpr,fpstore")])
13798
13799;; 0 says do sign-extension, 1 says zero-extension
13800(define_insn "*ieee128_mtvsrw"
13801  [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13802	(unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13803		      (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13804		     UNSPEC_IEEE128_MOVE))]
13805  "TARGET_FLOAT128_HW"
13806  "@
13807   mtvsrwa %x0,%1
13808   lxsiwax %x0,%y1
13809   mtvsrwz %x0,%1
13810   lxsiwzx %x0,%y1"
13811  [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13812
13813
13814(define_insn "*ieee128_mtvsrd_64bit"
13815  [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13816	(unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13817		     UNSPEC_IEEE128_MOVE))]
13818  "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13819  "@
13820   mtvsrd %x0,%1
13821   lxsdx %x0,%y1
13822   xxlor %x0,%x1,%x1"
13823  [(set_attr "type" "mffgpr,fpload,veclogical")])
13824
13825(define_insn "*ieee128_mtvsrd_32bit"
13826  [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13827	(unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13828		     UNSPEC_IEEE128_MOVE))]
13829  "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13830  "@
13831   lxsdx %x0,%y1
13832   xxlor %x0,%x1,%x1"
13833  [(set_attr "type" "fpload,veclogical")])
13834
13835;; IEEE 128-bit instructions with round to odd semantics
13836(define_insn "*trunc<mode>df2_odd"
13837  [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13838	(unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13839		   UNSPEC_ROUND_TO_ODD))]
13840  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13841  "xscvqpdpo %0,%1"
13842  [(set_attr "type" "vecfloat")
13843   (set_attr "size" "128")])
13844
13845;; IEEE 128-bit comparisons
13846(define_insn "*cmp<mode>_hw"
13847  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13848	(compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13849		      (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13850  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13851   "xscmpuqp %0,%1,%2"
13852  [(set_attr "type" "veccmp")
13853   (set_attr "size" "128")])
13854
13855
13856
13857(include "sync.md")
13858(include "vector.md")
13859(include "vsx.md")
13860(include "altivec.md")
13861(include "spe.md")
13862(include "dfp.md")
13863(include "paired.md")
13864(include "crypto.md")
13865(include "htm.md")
13866