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_CMPB
121   UNSPEC_FCTIW
122   UNSPEC_FCTID
123   UNSPEC_LFIWAX
124   UNSPEC_LFIWZX
125   UNSPEC_FCTIWUZ
126   UNSPEC_NOP
127   UNSPEC_GRP_END_NOP
128   UNSPEC_P8V_FMRGOW
129   UNSPEC_P8V_MTVSRWZ
130   UNSPEC_P8V_RELOAD_FROM_GPR
131   UNSPEC_P8V_MTVSRD
132   UNSPEC_P8V_XXPERMDI
133   UNSPEC_P8V_RELOAD_FROM_VSX
134   UNSPEC_ADDG6S
135   UNSPEC_CDTBCD
136   UNSPEC_CBCDTD
137   UNSPEC_DIVE
138   UNSPEC_DIVEO
139   UNSPEC_DIVEU
140   UNSPEC_DIVEUO
141   UNSPEC_UNPACK_128BIT
142   UNSPEC_PACK_128BIT
143   UNSPEC_LSQ
144   UNSPEC_FUSION_GPR
145   UNSPEC_STACK_CHECK
146   UNSPEC_FUSION_P9
147   UNSPEC_FUSION_ADDIS
148   UNSPEC_ROUND_TO_ODD
149   UNSPEC_SIGNBIT
150   UNSPEC_SF_FROM_SI
151   UNSPEC_SI_FROM_SF
152  ])
153
154;;
155;; UNSPEC_VOLATILE usage
156;;
157
158(define_c_enum "unspecv"
159  [UNSPECV_BLOCK
160   UNSPECV_LL			; load-locked
161   UNSPECV_SC			; store-conditional
162   UNSPECV_PROBE_STACK_RANGE	; probe range of stack addresses
163   UNSPECV_EH_RR		; eh_reg_restore
164   UNSPECV_ISYNC		; isync instruction
165   UNSPECV_MFTB			; move from time base
166   UNSPECV_NLGR			; non-local goto receiver
167   UNSPECV_MFFS			; Move from FPSCR
168   UNSPECV_MTFSF		; Move to FPSCR Fields
169   UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
170  ])
171
172
173;; Define an insn type attribute.  This is used in function unit delay
174;; computations.
175(define_attr "type"
176  "integer,two,three,
177   add,logical,shift,insert,
178   mul,halfmul,div,
179   exts,cntlz,popcnt,isel,
180   load,store,fpload,fpstore,vecload,vecstore,
181   cmp,
182   branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183   cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
184   fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
185   brinc,
186   vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187   vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188   veclogical,veccmpfx,vecexts,vecmove,
189   htm,htmsimple,dfp"
190  (const_string "integer"))
191
192;; What data size does this instruction work on?
193;; This is used for insert, mul and others as necessary.
194(define_attr "size" "8,16,32,64,128" (const_string "32"))
195
196;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197;; This is used for add, logical, shift, exts, mul.
198(define_attr "dot" "no,yes" (const_string "no"))
199
200;; Does this instruction sign-extend its result?
201;; This is used for load insns.
202(define_attr "sign_extend" "no,yes" (const_string "no"))
203
204;; Does this instruction use indexed (that is, reg+reg) addressing?
205;; This is used for load and store insns.  If operand 0 or 1 is a MEM
206;; it is automatically set based on that.  If a load or store instruction
207;; has fewer than two operands it needs to set this attribute manually
208;; or the compiler will crash.
209(define_attr "indexed" "no,yes"
210  (if_then_else (ior (match_operand 0 "indexed_address_mem")
211		     (match_operand 1 "indexed_address_mem"))
212		(const_string "yes")
213		(const_string "no")))
214
215;; Does this instruction use update addressing?
216;; This is used for load and store insns.  See the comments for "indexed".
217(define_attr "update" "no,yes"
218  (if_then_else (ior (match_operand 0 "update_address_mem")
219		     (match_operand 1 "update_address_mem"))
220		(const_string "yes")
221		(const_string "no")))
222
223;; Is this instruction using operands[2] as shift amount, and can that be a
224;; register?
225;; This is used for shift insns.
226(define_attr "maybe_var_shift" "no,yes" (const_string "no"))
227
228;; Is this instruction using a shift amount from a register?
229;; This is used for shift insns.
230(define_attr "var_shift" "no,yes"
231  (if_then_else (and (eq_attr "type" "shift")
232		     (eq_attr "maybe_var_shift" "yes"))
233		(if_then_else (match_operand 2 "gpc_reg_operand")
234			      (const_string "yes")
235			      (const_string "no"))
236		(const_string "no")))
237
238;; Is copying of this instruction disallowed?
239(define_attr "cannot_copy" "no,yes" (const_string "no"))
240
241;; Define floating point instruction sub-types for use with Xfpu.md
242(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"))
243
244;; Length (in bytes).
245; '(pc)' in the following doesn't include the instruction itself; it is
246; calculated as if the instruction had zero size.
247(define_attr "length" ""
248  (if_then_else (eq_attr "type" "branch")
249		(if_then_else (and (ge (minus (match_dup 0) (pc))
250				       (const_int -32768))
251				   (lt (minus (match_dup 0) (pc))
252				       (const_int 32764)))
253			      (const_int 4)
254			      (const_int 8))
255		(const_int 4)))
256
257;; Processor type -- this attribute must exactly match the processor_type
258;; enumeration in rs6000-opts.h.
259(define_attr "cpu"
260  "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261   ppc750,ppc7400,ppc7450,
262   ppc403,ppc405,ppc440,ppc476,
263   ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264   power4,power5,power6,power7,power8,power9,
265   rs64a,mpccore,cell,ppca2,titan"
266  (const (symbol_ref "rs6000_cpu_attr")))
267
268
269;; If this instruction is microcoded on the CELL processor
270; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271(define_attr "cell_micro" "not,conditional,always"
272  (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273			  (eq_attr "dot" "yes"))
274		     (and (eq_attr "type" "load")
275			  (eq_attr "sign_extend" "yes"))
276		     (and (eq_attr "type" "shift")
277			  (eq_attr "var_shift" "yes")))
278		(const_string "always")
279		(const_string "not")))
280
281(automata_option "ndfa")
282
283(include "rs64.md")
284(include "mpc.md")
285(include "40x.md")
286(include "440.md")
287(include "476.md")
288(include "601.md")
289(include "603.md")
290(include "6xx.md")
291(include "7xx.md")
292(include "7450.md")
293(include "8540.md")
294(include "e300c2c3.md")
295(include "e500mc.md")
296(include "e500mc64.md")
297(include "e5500.md")
298(include "e6500.md")
299(include "power4.md")
300(include "power5.md")
301(include "power6.md")
302(include "power7.md")
303(include "power8.md")
304(include "power9.md")
305(include "cell.md")
306(include "xfpu.md")
307(include "a2.md")
308(include "titan.md")
309
310(include "predicates.md")
311(include "constraints.md")
312
313(include "darwin.md")
314
315
316;; Mode iterators
317
318; This mode iterator allows :GPR to be used to indicate the allowable size
319; of whole values in GPRs.
320(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
321
322; Any supported integer mode.
323(define_mode_iterator INT [QI HI SI DI TI PTI])
324
325; Any supported integer mode that fits in one register.
326(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
327
328; Integer modes supported in VSX registers with ISA 3.0 instructions
329(define_mode_iterator INT_ISA3 [QI HI SI DI])
330
331; Everything we can extend QImode to.
332(define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
333
334; Everything we can extend HImode to.
335(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
336
337; Everything we can extend SImode to.
338(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
339
340; QImode or HImode for small integer moves and small atomic ops
341(define_mode_iterator QHI [QI HI])
342
343; QImode, HImode, SImode for fused ops only for GPR loads
344(define_mode_iterator QHSI [QI HI SI])
345
346; HImode or SImode for sign extended fusion ops
347(define_mode_iterator HSI [HI SI])
348
349; SImode or DImode, even if DImode doesn't fit in GPRs.
350(define_mode_iterator SDI [SI DI])
351
352; Types that can be fused with an ADDIS instruction to load or store a GPR
353; register that has reg+offset addressing.
354(define_mode_iterator GPR_FUSION [QI
355				  HI
356				  SI
357				  (DI	"TARGET_POWERPC64")
358				  SF
359				  (DF	"TARGET_POWERPC64")])
360
361; Types that can be fused with an ADDIS instruction to load or store a FPR
362; register that has reg+offset addressing.
363(define_mode_iterator FPR_FUSION [DI SF DF])
364
365; The size of a pointer.  Also, the size of the value that a record-condition
366; (one with a '.') will compare; and the size used for arithmetic carries.
367(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
368
369; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
370; PTImode is GPR only)
371(define_mode_iterator TI2 [TI PTI])
372
373; Any hardware-supported floating-point mode
374(define_mode_iterator FP [
375  (SF "TARGET_HARD_FLOAT
376   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
377  (DF "TARGET_HARD_FLOAT
378   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
379  (TF "TARGET_HARD_FLOAT
380   && (TARGET_FPRS || TARGET_E500_DOUBLE)
381   && TARGET_LONG_DOUBLE_128")
382  (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
383  (KF "TARGET_FLOAT128_TYPE")
384  (DD "TARGET_DFP")
385  (TD "TARGET_DFP")])
386
387; Any fma capable floating-point mode.
388(define_mode_iterator FMA_F [
389  (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
390  (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
391       || VECTOR_UNIT_VSX_P (DFmode)")
392  (V2SF "TARGET_PAIRED_FLOAT")
393  (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
394  (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
395  (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
396  (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
397  ])
398
399; Floating point move iterators to combine binary and decimal moves
400(define_mode_iterator FMOVE32 [SF SD])
401(define_mode_iterator FMOVE64 [DF DD])
402(define_mode_iterator FMOVE64X [DI DF DD])
403(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
404				(IF "FLOAT128_IBM_P (IFmode)")
405				(TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
406
407(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
408				    (IF "FLOAT128_2REG_P (IFmode)")
409				    (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
410
411; Iterators for 128 bit types for direct move
412(define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
413				    (V16QI "")
414				    (V8HI  "")
415				    (V4SI  "")
416				    (V4SF  "")
417				    (V2DI  "")
418				    (V2DF  "")
419				    (V1TI  "")
420				    (KF    "FLOAT128_VECTOR_P (KFmode)")
421				    (TF    "FLOAT128_VECTOR_P (TFmode)")])
422
423; Iterator for 128-bit VSX types for pack/unpack
424(define_mode_iterator FMOVE128_VSX [V1TI KF])
425
426; Whether a floating point move is ok, don't allow SD without hardware FP
427(define_mode_attr fmove_ok [(SF "")
428			    (DF "")
429			    (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
430			    (DD "")])
431
432; Convert REAL_VALUE to the appropriate bits
433(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
434					(DF "REAL_VALUE_TO_TARGET_DOUBLE")
435					(SD "REAL_VALUE_TO_TARGET_DECIMAL32")
436					(DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
437
438; Whether 0.0 has an all-zero bit pattern
439(define_mode_attr zero_fp [(SF "j")
440			   (DF "j")
441			   (TF "j")
442			   (IF "j")
443			   (KF "j")
444			   (SD "wn")
445			   (DD "wn")
446			   (TD "wn")])
447
448; Definitions for 64-bit VSX
449(define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
450
451; Definitions for 64-bit direct move
452(define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
453
454; Definitions for 64-bit use of altivec registers
455(define_mode_attr f64_av  [(DF "wv") (DD "wn")])
456
457; Definitions for 64-bit access to ISA 3.0 (power9) vector
458(define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
459
460; These modes do not fit in integer registers in 32-bit mode.
461; but on e500v2, the gpr are 64 bit registers
462(define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
463
464; Iterator for reciprocal estimate instructions
465(define_mode_iterator RECIPF [SF DF V4SF V2DF])
466
467; Iterator for just SF/DF
468(define_mode_iterator SFDF [SF DF])
469
470; Like SFDF, but a different name to match conditional move where the
471; comparison operands may be a different mode than the input operands.
472(define_mode_iterator SFDF2 [SF DF])
473
474; Iterator for 128-bit floating point that uses the IBM double-double format
475(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
476			      (TF "FLOAT128_IBM_P (TFmode)")])
477
478; Iterator for 128-bit floating point that uses IEEE 128-bit float
479(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
480			       (TF "FLOAT128_IEEE_P (TFmode)")])
481
482; Iterator for 128-bit floating point
483(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
484				(IF "TARGET_FLOAT128_TYPE")
485				(TF "TARGET_LONG_DOUBLE_128")])
486
487; Iterator for signbit on 64-bit machines with direct move
488(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
489			       (TF "FLOAT128_VECTOR_P (TFmode)")])
490
491; Iterator for ISA 3.0 supported floating point types
492(define_mode_iterator FP_ISA3 [SF DF])
493
494; SF/DF suffix for traditional floating instructions
495(define_mode_attr Ftrad		[(SF "s") (DF "")])
496
497; SF/DF suffix for VSX instructions
498(define_mode_attr Fvsx		[(SF "sp") (DF	"dp")])
499
500; SF/DF constraint for arithmetic on traditional floating point registers
501(define_mode_attr Ff		[(SF "f") (DF "d") (DI "d")])
502
503; SF/DF constraint for arithmetic on VSX registers using instructions added in
504; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
505; but are used on SFmode, since internally SFmode values are kept in the DFmode
506; format.
507(define_mode_attr Fv		[(SF "ww") (DF "ws") (DI "wi")])
508
509; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
510; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
511; instructions added in ISA 2.07 (power8)
512(define_mode_attr Fv2		[(SF "wy") (DF "ws") (DI "wi")])
513
514; SF/DF constraint for arithmetic on altivec registers
515(define_mode_attr Fa		[(SF "wu") (DF "wv")])
516
517; s/d suffix for things like fp_addsub_s/fp_addsub_d
518(define_mode_attr Fs		[(SF "s")  (DF "d")])
519
520; FRE/FRES support
521(define_mode_attr Ffre		[(SF "fres") (DF "fre")])
522(define_mode_attr FFRE		[(SF "FRES") (DF "FRE")])
523
524; Conditional returns.
525(define_code_iterator any_return [return simple_return])
526(define_code_attr return_pred [(return "direct_return ()")
527			       (simple_return "1")])
528(define_code_attr return_str [(return "") (simple_return "simple_")])
529
530; Logical operators.
531(define_code_iterator iorxor		[ior xor])
532(define_code_iterator and_ior_xor	[and ior xor])
533
534; Signed/unsigned variants of ops.
535(define_code_iterator any_extend	[sign_extend zero_extend])
536(define_code_iterator any_fix		[fix unsigned_fix])
537(define_code_iterator any_float		[float unsigned_float])
538
539(define_code_attr u  [(sign_extend	"")
540		      (zero_extend	"u")
541		      (fix		"")
542		      (unsigned_fix	"u")])
543
544(define_code_attr su [(sign_extend	"s")
545		      (zero_extend	"u")
546		      (fix		"s")
547		      (unsigned_fix	"s")
548		      (float		"s")
549		      (unsigned_float	"u")])
550
551(define_code_attr az [(sign_extend	"a")
552		      (zero_extend	"z")
553		      (fix		"a")
554		      (unsigned_fix	"z")
555		      (float		"a")
556		      (unsigned_float	"z")])
557
558(define_code_attr uns [(fix		"")
559		       (unsigned_fix	"uns")
560		       (float		"")
561		       (unsigned_float	"uns")])
562
563; Various instructions that come in SI and DI forms.
564; A generic w/d attribute, for things like cmpw/cmpd.
565(define_mode_attr wd [(QI    "b")
566		      (HI    "h")
567		      (SI    "w")
568		      (DI    "d")
569		      (V16QI "b")
570		      (V8HI  "h")
571		      (V4SI  "w")
572		      (V2DI  "d")
573		      (V1TI  "q")
574		      (TI    "q")])
575
576;; How many bits in this mode?
577(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
578
579; DImode bits
580(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
581
582;; ISEL/ISEL64 target selection
583(define_mode_attr sel [(SI "") (DI "64")])
584
585;; Bitmask for shift instructions
586(define_mode_attr hH [(SI "h") (DI "H")])
587
588;; A mode twice the size of the given mode
589(define_mode_attr dmode [(SI "di") (DI "ti")])
590(define_mode_attr DMODE [(SI "DI") (DI "TI")])
591
592;; Suffix for reload patterns
593(define_mode_attr ptrsize [(SI "32bit")
594			   (DI "64bit")])
595
596(define_mode_attr tptrsize [(SI "TARGET_32BIT")
597			    (DI "TARGET_64BIT")])
598
599(define_mode_attr mptrsize [(SI "si")
600			    (DI "di")])
601
602(define_mode_attr ptrload [(SI "lwz")
603			   (DI "ld")])
604
605(define_mode_attr ptrm [(SI "m")
606			(DI "Y")])
607
608(define_mode_attr rreg [(SF   "f")
609			(DF   "ws")
610			(TF   "f")
611			(TD   "f")
612			(V4SF "wf")
613			(V2DF "wd")])
614
615(define_mode_attr rreg2 [(SF   "f")
616			 (DF   "d")])
617
618(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
619				 (DF "TARGET_FCFID")])
620
621(define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
622				(DF "TARGET_E500_DOUBLE")])
623
624(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
625				(DF "TARGET_DOUBLE_FLOAT")])
626
627;; Mode iterator for logical operations on 128-bit types
628(define_mode_iterator BOOL_128		[TI
629					 PTI
630					 (V16QI	"TARGET_ALTIVEC")
631					 (V8HI	"TARGET_ALTIVEC")
632					 (V4SI	"TARGET_ALTIVEC")
633					 (V4SF	"TARGET_ALTIVEC")
634					 (V2DI	"TARGET_ALTIVEC")
635					 (V2DF	"TARGET_ALTIVEC")
636					 (V1TI  "TARGET_ALTIVEC")])
637
638;; For the GPRs we use 3 constraints for register outputs, two that are the
639;; same as the output register, and a third where the output register is an
640;; early clobber, so we don't have to deal with register overlaps.  For the
641;; vector types, we prefer to use the vector registers.  For TI mode, allow
642;; either.
643
644;; Mode attribute for boolean operation register constraints for output
645(define_mode_attr BOOL_REGS_OUTPUT	[(TI	"&r,r,r,wt,v")
646					 (PTI	"&r,r,r")
647					 (V16QI	"wa,v,&?r,?r,?r")
648					 (V8HI	"wa,v,&?r,?r,?r")
649					 (V4SI	"wa,v,&?r,?r,?r")
650					 (V4SF	"wa,v,&?r,?r,?r")
651					 (V2DI	"wa,v,&?r,?r,?r")
652					 (V2DF	"wa,v,&?r,?r,?r")
653					 (V1TI	"wa,v,&?r,?r,?r")])
654
655;; Mode attribute for boolean operation register constraints for operand1
656(define_mode_attr BOOL_REGS_OP1		[(TI	"r,0,r,wt,v")
657					 (PTI	"r,0,r")
658					 (V16QI	"wa,v,r,0,r")
659					 (V8HI	"wa,v,r,0,r")
660					 (V4SI	"wa,v,r,0,r")
661					 (V4SF	"wa,v,r,0,r")
662					 (V2DI	"wa,v,r,0,r")
663					 (V2DF	"wa,v,r,0,r")
664					 (V1TI	"wa,v,r,0,r")])
665
666;; Mode attribute for boolean operation register constraints for operand2
667(define_mode_attr BOOL_REGS_OP2		[(TI	"r,r,0,wt,v")
668					 (PTI	"r,r,0")
669					 (V16QI	"wa,v,r,r,0")
670					 (V8HI	"wa,v,r,r,0")
671					 (V4SI	"wa,v,r,r,0")
672					 (V4SF	"wa,v,r,r,0")
673					 (V2DI	"wa,v,r,r,0")
674					 (V2DF	"wa,v,r,r,0")
675					 (V1TI	"wa,v,r,r,0")])
676
677;; Mode attribute for boolean operation register constraints for operand1
678;; for one_cmpl.  To simplify things, we repeat the constraint where 0
679;; is used for operand1 or operand2
680(define_mode_attr BOOL_REGS_UNARY	[(TI	"r,0,0,wt,v")
681					 (PTI	"r,0,0")
682					 (V16QI	"wa,v,r,0,0")
683					 (V8HI	"wa,v,r,0,0")
684					 (V4SI	"wa,v,r,0,0")
685					 (V4SF	"wa,v,r,0,0")
686					 (V2DI	"wa,v,r,0,0")
687					 (V2DF	"wa,v,r,0,0")
688					 (V1TI	"wa,v,r,0,0")])
689
690;; Reload iterator for creating the function to allocate a base register to
691;; supplement addressing modes.
692(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
693			      SF SD SI DF DD DI TI PTI KF IF TF])
694
695;; Iterate over smin, smax
696(define_code_iterator fp_minmax	[smin smax])
697
698(define_code_attr     minmax	[(smin "min")
699				 (smax "max")])
700
701(define_code_attr     SMINMAX	[(smin "SMIN")
702				 (smax "SMAX")])
703
704;; Iterator to optimize the following cases:
705;;	D-form load to FPR register & move to Altivec register
706;;	Move Altivec register to FPR register and store
707(define_mode_iterator ALTIVEC_DFORM [DI DF SF])
708
709
710;; Start with fixed-point load and store insns.  Here we put only the more
711;; complex forms.  Basic data transfer is done later.
712
713(define_insn "zero_extendqi<mode>2"
714  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
715	(zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
716  ""
717  "@
718   lbz%U1%X1 %0,%1
719   rlwinm %0,%1,0,0xff
720   lxsibzx %x0,%y1
721   vextractub %0,%1,7"
722  [(set_attr "type" "load,shift,fpload,vecperm")])
723
724(define_insn_and_split "*zero_extendqi<mode>2_dot"
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   (clobber (match_scratch:EXTQI 0 "=r,r"))]
729  "rs6000_gen_cell_microcode"
730  "@
731   andi. %0,%1,0xff
732   #"
733  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
734  [(set (match_dup 0)
735	(zero_extend:EXTQI (match_dup 1)))
736   (set (match_dup 2)
737	(compare:CC (match_dup 0)
738		    (const_int 0)))]
739  ""
740  [(set_attr "type" "logical")
741   (set_attr "dot" "yes")
742   (set_attr "length" "4,8")])
743
744(define_insn_and_split "*zero_extendqi<mode>2_dot2"
745  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
746	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
747		    (const_int 0)))
748   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
749	(zero_extend:EXTQI (match_dup 1)))]
750  "rs6000_gen_cell_microcode"
751  "@
752   andi. %0,%1,0xff
753   #"
754  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
755  [(set (match_dup 0)
756	(zero_extend:EXTQI (match_dup 1)))
757   (set (match_dup 2)
758	(compare:CC (match_dup 0)
759		    (const_int 0)))]
760  ""
761  [(set_attr "type" "logical")
762   (set_attr "dot" "yes")
763   (set_attr "length" "4,8")])
764
765
766(define_insn "zero_extendhi<mode>2"
767  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
768	(zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
769  ""
770  "@
771   lhz%U1%X1 %0,%1
772   rlwinm %0,%1,0,0xffff
773   lxsihzx %x0,%y1
774   vextractuh %0,%1,6"
775  [(set_attr "type" "load,shift,fpload,vecperm")])
776
777(define_insn_and_split "*zero_extendhi<mode>2_dot"
778  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
779	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
780		    (const_int 0)))
781   (clobber (match_scratch:EXTHI 0 "=r,r"))]
782  "rs6000_gen_cell_microcode"
783  "@
784   andi. %0,%1,0xffff
785   #"
786  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
787  [(set (match_dup 0)
788	(zero_extend:EXTHI (match_dup 1)))
789   (set (match_dup 2)
790	(compare:CC (match_dup 0)
791		    (const_int 0)))]
792  ""
793  [(set_attr "type" "logical")
794   (set_attr "dot" "yes")
795   (set_attr "length" "4,8")])
796
797(define_insn_and_split "*zero_extendhi<mode>2_dot2"
798  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
799	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
800		    (const_int 0)))
801   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
802	(zero_extend:EXTHI (match_dup 1)))]
803  "rs6000_gen_cell_microcode"
804  "@
805   andi. %0,%1,0xffff
806   #"
807  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
808  [(set (match_dup 0)
809	(zero_extend:EXTHI (match_dup 1)))
810   (set (match_dup 2)
811	(compare:CC (match_dup 0)
812		    (const_int 0)))]
813  ""
814  [(set_attr "type" "logical")
815   (set_attr "dot" "yes")
816   (set_attr "length" "4,8")])
817
818
819(define_insn "zero_extendsi<mode>2"
820  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
821	(zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
822  ""
823  "@
824   lwz%U1%X1 %0,%1
825   rldicl %0,%1,0,32
826   lfiwzx %0,%y1
827   lxsiwzx %x0,%y1
828   mtvsrwz %x0,%1
829   mfvsrwz %0,%x1
830   xxextractuw %x0,%x1,4"
831  [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
832
833(define_insn_and_split "*zero_extendsi<mode>2_dot"
834  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
835	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
836		    (const_int 0)))
837   (clobber (match_scratch:EXTSI 0 "=r,r"))]
838  "rs6000_gen_cell_microcode"
839  "@
840   rldicl. %0,%1,0,32
841   #"
842  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
843  [(set (match_dup 0)
844	(zero_extend:DI (match_dup 1)))
845   (set (match_dup 2)
846	(compare:CC (match_dup 0)
847		    (const_int 0)))]
848  ""
849  [(set_attr "type" "shift")
850   (set_attr "dot" "yes")
851   (set_attr "length" "4,8")])
852
853(define_insn_and_split "*zero_extendsi<mode>2_dot2"
854  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
855	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
856		    (const_int 0)))
857   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
858	(zero_extend:EXTSI (match_dup 1)))]
859  "rs6000_gen_cell_microcode"
860  "@
861   rldicl. %0,%1,0,32
862   #"
863  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
864  [(set (match_dup 0)
865	(zero_extend:EXTSI (match_dup 1)))
866   (set (match_dup 2)
867	(compare:CC (match_dup 0)
868		    (const_int 0)))]
869  ""
870  [(set_attr "type" "shift")
871   (set_attr "dot" "yes")
872   (set_attr "length" "4,8")])
873
874
875(define_insn "extendqi<mode>2"
876  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
877	(sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
878  ""
879  "@
880   extsb %0,%1
881   vextsb2d %0,%1"
882  [(set_attr "type" "exts,vecperm")])
883
884(define_insn_and_split "*extendqi<mode>2_dot"
885  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
886	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
887		    (const_int 0)))
888   (clobber (match_scratch:EXTQI 0 "=r,r"))]
889  "rs6000_gen_cell_microcode"
890  "@
891   extsb. %0,%1
892   #"
893  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
894  [(set (match_dup 0)
895	(sign_extend:EXTQI (match_dup 1)))
896   (set (match_dup 2)
897	(compare:CC (match_dup 0)
898		    (const_int 0)))]
899  ""
900  [(set_attr "type" "exts")
901   (set_attr "dot" "yes")
902   (set_attr "length" "4,8")])
903
904(define_insn_and_split "*extendqi<mode>2_dot2"
905  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
906	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
907		    (const_int 0)))
908   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
909	(sign_extend:EXTQI (match_dup 1)))]
910  "rs6000_gen_cell_microcode"
911  "@
912   extsb. %0,%1
913   #"
914  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
915  [(set (match_dup 0)
916	(sign_extend:EXTQI (match_dup 1)))
917   (set (match_dup 2)
918	(compare:CC (match_dup 0)
919		    (const_int 0)))]
920  ""
921  [(set_attr "type" "exts")
922   (set_attr "dot" "yes")
923   (set_attr "length" "4,8")])
924
925
926(define_expand "extendhi<mode>2"
927  [(set (match_operand:EXTHI 0 "gpc_reg_operand")
928	(sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
929  ""
930  "")
931
932(define_insn "*extendhi<mode>2"
933  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
934	(sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
935  "rs6000_gen_cell_microcode || TARGET_VSX_SMALL_INTEGER"
936  "@
937   lha%U1%X1 %0,%1
938   extsh %0,%1
939   #
940   vextsh2d %0,%1"
941  [(set_attr "type" "load,exts,fpload,vecperm")
942   (set_attr "sign_extend" "yes")
943   (set_attr "length" "4,4,8,4")])
944
945(define_split
946  [(set (match_operand:EXTHI 0 "altivec_register_operand")
947	(sign_extend:EXTHI
948	 (match_operand:HI 1 "indexed_or_indirect_operand")))]
949  "TARGET_P9_VECTOR && reload_completed"
950  [(set (match_dup 2)
951	(match_dup 1))
952   (set (match_dup 0)
953	(sign_extend:EXTHI (match_dup 2)))]
954{
955  operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
956})
957
958(define_insn "*extendhi<mode>2_noload"
959  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
960        (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
961  "!rs6000_gen_cell_microcode"
962  "extsh %0,%1"
963  [(set_attr "type" "exts")])
964
965(define_insn_and_split "*extendhi<mode>2_dot"
966  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
967	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
968		    (const_int 0)))
969   (clobber (match_scratch:EXTHI 0 "=r,r"))]
970  "rs6000_gen_cell_microcode"
971  "@
972   extsh. %0,%1
973   #"
974  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
975  [(set (match_dup 0)
976	(sign_extend:EXTHI (match_dup 1)))
977   (set (match_dup 2)
978	(compare:CC (match_dup 0)
979		    (const_int 0)))]
980  ""
981  [(set_attr "type" "exts")
982   (set_attr "dot" "yes")
983   (set_attr "length" "4,8")])
984
985(define_insn_and_split "*extendhi<mode>2_dot2"
986  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
987	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
988		    (const_int 0)))
989   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
990	(sign_extend:EXTHI (match_dup 1)))]
991  "rs6000_gen_cell_microcode"
992  "@
993   extsh. %0,%1
994   #"
995  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
996  [(set (match_dup 0)
997	(sign_extend:EXTHI (match_dup 1)))
998   (set (match_dup 2)
999	(compare:CC (match_dup 0)
1000		    (const_int 0)))]
1001  ""
1002  [(set_attr "type" "exts")
1003   (set_attr "dot" "yes")
1004   (set_attr "length" "4,8")])
1005
1006
1007(define_insn "extendsi<mode>2"
1008  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK,wH")
1009	(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))]
1010  ""
1011  "@
1012   lwa%U1%X1 %0,%1
1013   extsw %0,%1
1014   lfiwax %0,%y1
1015   lxsiwax %x0,%y1
1016   mtvsrwa %x0,%1
1017   vextsw2d %0,%1
1018   #"
1019  [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm")
1020   (set_attr "sign_extend" "yes")
1021   (set_attr "length" "4,4,4,4,4,4,8")])
1022
1023(define_split
1024  [(set (match_operand:DI 0 "altivec_register_operand")
1025	(sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1026  "TARGET_VSX_SMALL_INTEGER && TARGET_P8_VECTOR && !TARGET_P9_VECTOR
1027   && reload_completed"
1028  [(const_int 0)]
1029{
1030  rtx dest = operands[0];
1031  rtx src = operands[1];
1032  int dest_regno = REGNO (dest);
1033  int src_regno = REGNO (src);
1034  rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1035  rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1036
1037  if (VECTOR_ELT_ORDER_BIG)
1038    {
1039      emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1040      emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1041    }
1042  else
1043    {
1044      emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1045      emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1046    }
1047  DONE;
1048})
1049
1050(define_insn_and_split "*extendsi<mode>2_dot"
1051  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1052	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1053		    (const_int 0)))
1054   (clobber (match_scratch:EXTSI 0 "=r,r"))]
1055  "rs6000_gen_cell_microcode"
1056  "@
1057   extsw. %0,%1
1058   #"
1059  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1060  [(set (match_dup 0)
1061	(sign_extend:EXTSI (match_dup 1)))
1062   (set (match_dup 2)
1063	(compare:CC (match_dup 0)
1064		    (const_int 0)))]
1065  ""
1066  [(set_attr "type" "exts")
1067   (set_attr "dot" "yes")
1068   (set_attr "length" "4,8")])
1069
1070(define_insn_and_split "*extendsi<mode>2_dot2"
1071  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1072	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1073		    (const_int 0)))
1074   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1075	(sign_extend:EXTSI (match_dup 1)))]
1076  "rs6000_gen_cell_microcode"
1077  "@
1078   extsw. %0,%1
1079   #"
1080  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1081  [(set (match_dup 0)
1082	(sign_extend:EXTSI (match_dup 1)))
1083   (set (match_dup 2)
1084	(compare:CC (match_dup 0)
1085		    (const_int 0)))]
1086  ""
1087  [(set_attr "type" "exts")
1088   (set_attr "dot" "yes")
1089   (set_attr "length" "4,8")])
1090
1091;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1092
1093(define_insn "*macchwc"
1094  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1095        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1096                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1097                                       (const_int 16))
1098                                      (sign_extend:SI
1099                                       (match_operand:HI 1 "gpc_reg_operand" "r")))
1100                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1101                    (const_int 0)))
1102   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1103        (plus:SI (mult:SI (ashiftrt:SI
1104                           (match_dup 2)
1105                           (const_int 16))
1106                          (sign_extend:SI
1107                           (match_dup 1)))
1108                 (match_dup 4)))]
1109  "TARGET_MULHW"
1110  "macchw. %0,%1,%2"
1111  [(set_attr "type" "halfmul")])
1112
1113(define_insn "*macchw"
1114  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1115        (plus:SI (mult:SI (ashiftrt:SI
1116                           (match_operand:SI 2 "gpc_reg_operand" "r")
1117                           (const_int 16))
1118                          (sign_extend:SI
1119                           (match_operand:HI 1 "gpc_reg_operand" "r")))
1120                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1121  "TARGET_MULHW"
1122  "macchw %0,%1,%2"
1123  [(set_attr "type" "halfmul")])
1124
1125(define_insn "*macchwuc"
1126  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1127        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1128                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1129                                       (const_int 16))
1130                                      (zero_extend:SI
1131                                       (match_operand:HI 1 "gpc_reg_operand" "r")))
1132                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1133                    (const_int 0)))
1134   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1135        (plus:SI (mult:SI (lshiftrt:SI
1136                           (match_dup 2)
1137                           (const_int 16))
1138                          (zero_extend:SI
1139                           (match_dup 1)))
1140                 (match_dup 4)))]
1141  "TARGET_MULHW"
1142  "macchwu. %0,%1,%2"
1143  [(set_attr "type" "halfmul")])
1144
1145(define_insn "*macchwu"
1146  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1147        (plus:SI (mult:SI (lshiftrt:SI
1148                           (match_operand:SI 2 "gpc_reg_operand" "r")
1149                           (const_int 16))
1150                          (zero_extend:SI
1151                           (match_operand:HI 1 "gpc_reg_operand" "r")))
1152                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1153  "TARGET_MULHW"
1154  "macchwu %0,%1,%2"
1155  [(set_attr "type" "halfmul")])
1156
1157(define_insn "*machhwc"
1158  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1159        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1160                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
1161                                       (const_int 16))
1162                                      (ashiftrt:SI
1163                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1164                                       (const_int 16)))
1165                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1166                    (const_int 0)))
1167   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1168        (plus:SI (mult:SI (ashiftrt:SI
1169                           (match_dup 1)
1170                           (const_int 16))
1171                          (ashiftrt:SI
1172                           (match_dup 2)
1173                           (const_int 16)))
1174                 (match_dup 4)))]
1175  "TARGET_MULHW"
1176  "machhw. %0,%1,%2"
1177  [(set_attr "type" "halfmul")])
1178
1179(define_insn "*machhw"
1180  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1181        (plus:SI (mult:SI (ashiftrt:SI
1182                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1183                           (const_int 16))
1184                          (ashiftrt:SI
1185                           (match_operand:SI 2 "gpc_reg_operand" "r")
1186                           (const_int 16)))
1187                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1188  "TARGET_MULHW"
1189  "machhw %0,%1,%2"
1190  [(set_attr "type" "halfmul")])
1191
1192(define_insn "*machhwuc"
1193  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1194        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1195                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
1196                                       (const_int 16))
1197                                      (lshiftrt:SI
1198                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1199                                       (const_int 16)))
1200                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1201                    (const_int 0)))
1202   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1203        (plus:SI (mult:SI (lshiftrt:SI
1204                           (match_dup 1)
1205                           (const_int 16))
1206                          (lshiftrt:SI
1207                           (match_dup 2)
1208                           (const_int 16)))
1209                 (match_dup 4)))]
1210  "TARGET_MULHW"
1211  "machhwu. %0,%1,%2"
1212  [(set_attr "type" "halfmul")])
1213
1214(define_insn "*machhwu"
1215  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1216        (plus:SI (mult:SI (lshiftrt:SI
1217                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1218                           (const_int 16))
1219                          (lshiftrt:SI
1220                           (match_operand:SI 2 "gpc_reg_operand" "r")
1221                           (const_int 16)))
1222                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1223  "TARGET_MULHW"
1224  "machhwu %0,%1,%2"
1225  [(set_attr "type" "halfmul")])
1226
1227(define_insn "*maclhwc"
1228  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1229        (compare:CC (plus:SI (mult:SI (sign_extend:SI
1230                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1231                                      (sign_extend:SI
1232                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1233                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1234                    (const_int 0)))
1235   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1236        (plus:SI (mult:SI (sign_extend:SI
1237                           (match_dup 1))
1238                          (sign_extend:SI
1239                           (match_dup 2)))
1240                 (match_dup 4)))]
1241  "TARGET_MULHW"
1242  "maclhw. %0,%1,%2"
1243  [(set_attr "type" "halfmul")])
1244
1245(define_insn "*maclhw"
1246  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1247        (plus:SI (mult:SI (sign_extend:SI
1248                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1249                          (sign_extend:SI
1250                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1251                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1252  "TARGET_MULHW"
1253  "maclhw %0,%1,%2"
1254  [(set_attr "type" "halfmul")])
1255
1256(define_insn "*maclhwuc"
1257  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1258        (compare:CC (plus:SI (mult:SI (zero_extend:SI
1259                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1260                                      (zero_extend:SI
1261                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1262                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1263                    (const_int 0)))
1264   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265        (plus:SI (mult:SI (zero_extend:SI
1266                           (match_dup 1))
1267                          (zero_extend:SI
1268                           (match_dup 2)))
1269                 (match_dup 4)))]
1270  "TARGET_MULHW"
1271  "maclhwu. %0,%1,%2"
1272  [(set_attr "type" "halfmul")])
1273
1274(define_insn "*maclhwu"
1275  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1276        (plus:SI (mult:SI (zero_extend:SI
1277                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1278                          (zero_extend:SI
1279                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1280                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1281  "TARGET_MULHW"
1282  "maclhwu %0,%1,%2"
1283  [(set_attr "type" "halfmul")])
1284
1285(define_insn "*nmacchwc"
1286  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1287        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1288                              (mult:SI (ashiftrt:SI
1289                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1290                                        (const_int 16))
1291                                       (sign_extend:SI
1292                                        (match_operand:HI 1 "gpc_reg_operand" "r"))))
1293                    (const_int 0)))
1294   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1295        (minus:SI (match_dup 4)
1296                  (mult:SI (ashiftrt:SI
1297                            (match_dup 2)
1298                            (const_int 16))
1299                           (sign_extend:SI
1300                            (match_dup 1)))))]
1301  "TARGET_MULHW"
1302  "nmacchw. %0,%1,%2"
1303  [(set_attr "type" "halfmul")])
1304
1305(define_insn "*nmacchw"
1306  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1307        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
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  "nmacchw %0,%1,%2"
1315  [(set_attr "type" "halfmul")])
1316
1317(define_insn "*nmachhwc"
1318  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1319        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1320                              (mult:SI (ashiftrt:SI
1321                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1322                                        (const_int 16))
1323                                       (ashiftrt:SI
1324                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1325                                        (const_int 16))))
1326                    (const_int 0)))
1327   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328        (minus:SI (match_dup 4)
1329                  (mult:SI (ashiftrt:SI
1330                            (match_dup 1)
1331                            (const_int 16))
1332                           (ashiftrt:SI
1333                            (match_dup 2)
1334                            (const_int 16)))))]
1335  "TARGET_MULHW"
1336  "nmachhw. %0,%1,%2"
1337  [(set_attr "type" "halfmul")])
1338
1339(define_insn "*nmachhw"
1340  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1342                  (mult:SI (ashiftrt:SI
1343                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1344                            (const_int 16))
1345                           (ashiftrt:SI
1346                            (match_operand:SI 2 "gpc_reg_operand" "r")
1347                            (const_int 16)))))]
1348  "TARGET_MULHW"
1349  "nmachhw %0,%1,%2"
1350  [(set_attr "type" "halfmul")])
1351
1352(define_insn "*nmaclhwc"
1353  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1354        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1355                              (mult:SI (sign_extend:SI
1356                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1357                                       (sign_extend:SI
1358                                        (match_operand:HI 2 "gpc_reg_operand" "r"))))
1359                    (const_int 0)))
1360   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361        (minus:SI (match_dup 4)
1362                  (mult:SI (sign_extend:SI
1363                            (match_dup 1))
1364                           (sign_extend:SI
1365                            (match_dup 2)))))]
1366  "TARGET_MULHW"
1367  "nmaclhw. %0,%1,%2"
1368  [(set_attr "type" "halfmul")])
1369
1370(define_insn "*nmaclhw"
1371  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1372        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1373                  (mult:SI (sign_extend:SI
1374                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1375                           (sign_extend:SI
1376                            (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1377  "TARGET_MULHW"
1378  "nmaclhw %0,%1,%2"
1379  [(set_attr "type" "halfmul")])
1380
1381(define_insn "*mulchwc"
1382  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1383        (compare:CC (mult:SI (ashiftrt:SI
1384                              (match_operand:SI 2 "gpc_reg_operand" "r")
1385                              (const_int 16))
1386                             (sign_extend:SI
1387                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1388                    (const_int 0)))
1389   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390        (mult:SI (ashiftrt:SI
1391                  (match_dup 2)
1392                  (const_int 16))
1393                 (sign_extend:SI
1394                  (match_dup 1))))]
1395  "TARGET_MULHW"
1396  "mulchw. %0,%1,%2"
1397  [(set_attr "type" "halfmul")])
1398
1399(define_insn "*mulchw"
1400  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1401        (mult:SI (ashiftrt:SI
1402                  (match_operand:SI 2 "gpc_reg_operand" "r")
1403                  (const_int 16))
1404                 (sign_extend:SI
1405                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1406  "TARGET_MULHW"
1407  "mulchw %0,%1,%2"
1408  [(set_attr "type" "halfmul")])
1409
1410(define_insn "*mulchwuc"
1411  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1412        (compare:CC (mult:SI (lshiftrt:SI
1413                              (match_operand:SI 2 "gpc_reg_operand" "r")
1414                              (const_int 16))
1415                             (zero_extend:SI
1416                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1417                    (const_int 0)))
1418   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419        (mult:SI (lshiftrt:SI
1420                  (match_dup 2)
1421                  (const_int 16))
1422                 (zero_extend:SI
1423                  (match_dup 1))))]
1424  "TARGET_MULHW"
1425  "mulchwu. %0,%1,%2"
1426  [(set_attr "type" "halfmul")])
1427
1428(define_insn "*mulchwu"
1429  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1430        (mult:SI (lshiftrt:SI
1431                  (match_operand:SI 2 "gpc_reg_operand" "r")
1432                  (const_int 16))
1433                 (zero_extend:SI
1434                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1435  "TARGET_MULHW"
1436  "mulchwu %0,%1,%2"
1437  [(set_attr "type" "halfmul")])
1438
1439(define_insn "*mulhhwc"
1440  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1441        (compare:CC (mult:SI (ashiftrt:SI
1442                              (match_operand:SI 1 "gpc_reg_operand" "%r")
1443                              (const_int 16))
1444                             (ashiftrt:SI
1445                              (match_operand:SI 2 "gpc_reg_operand" "r")
1446                              (const_int 16)))
1447                    (const_int 0)))
1448   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449        (mult:SI (ashiftrt:SI
1450                  (match_dup 1)
1451                  (const_int 16))
1452                 (ashiftrt:SI
1453                  (match_dup 2)
1454                  (const_int 16))))]
1455  "TARGET_MULHW"
1456  "mulhhw. %0,%1,%2"
1457  [(set_attr "type" "halfmul")])
1458
1459(define_insn "*mulhhw"
1460  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1461        (mult:SI (ashiftrt:SI
1462                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1463                  (const_int 16))
1464                 (ashiftrt:SI
1465                  (match_operand:SI 2 "gpc_reg_operand" "r")
1466                  (const_int 16))))]
1467  "TARGET_MULHW"
1468  "mulhhw %0,%1,%2"
1469  [(set_attr "type" "halfmul")])
1470
1471(define_insn "*mulhhwuc"
1472  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1473        (compare:CC (mult:SI (lshiftrt:SI
1474                              (match_operand:SI 1 "gpc_reg_operand" "%r")
1475                              (const_int 16))
1476                             (lshiftrt:SI
1477                              (match_operand:SI 2 "gpc_reg_operand" "r")
1478                              (const_int 16)))
1479                    (const_int 0)))
1480   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1481        (mult:SI (lshiftrt:SI
1482                  (match_dup 1)
1483                  (const_int 16))
1484                 (lshiftrt:SI
1485                  (match_dup 2)
1486                  (const_int 16))))]
1487  "TARGET_MULHW"
1488  "mulhhwu. %0,%1,%2"
1489  [(set_attr "type" "halfmul")])
1490
1491(define_insn "*mulhhwu"
1492  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1493        (mult:SI (lshiftrt:SI
1494                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1495                  (const_int 16))
1496                 (lshiftrt:SI
1497                  (match_operand:SI 2 "gpc_reg_operand" "r")
1498                  (const_int 16))))]
1499  "TARGET_MULHW"
1500  "mulhhwu %0,%1,%2"
1501  [(set_attr "type" "halfmul")])
1502
1503(define_insn "*mullhwc"
1504  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1505        (compare:CC (mult:SI (sign_extend:SI
1506                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1507                             (sign_extend:SI
1508                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1509                    (const_int 0)))
1510   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1511        (mult:SI (sign_extend:SI
1512                  (match_dup 1))
1513                 (sign_extend:SI
1514                  (match_dup 2))))]
1515  "TARGET_MULHW"
1516  "mullhw. %0,%1,%2"
1517  [(set_attr "type" "halfmul")])
1518
1519(define_insn "*mullhw"
1520  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1521        (mult:SI (sign_extend:SI
1522                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1523                 (sign_extend:SI
1524                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1525  "TARGET_MULHW"
1526  "mullhw %0,%1,%2"
1527  [(set_attr "type" "halfmul")])
1528
1529(define_insn "*mullhwuc"
1530  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1531        (compare:CC (mult:SI (zero_extend:SI
1532                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1533                             (zero_extend:SI
1534                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1535                    (const_int 0)))
1536   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1537        (mult:SI (zero_extend:SI
1538                  (match_dup 1))
1539                 (zero_extend:SI
1540                  (match_dup 2))))]
1541  "TARGET_MULHW"
1542  "mullhwu. %0,%1,%2"
1543  [(set_attr "type" "halfmul")])
1544
1545(define_insn "*mullhwu"
1546  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1547        (mult:SI (zero_extend:SI
1548                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1549                 (zero_extend:SI
1550                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1551  "TARGET_MULHW"
1552  "mullhwu %0,%1,%2"
1553  [(set_attr "type" "halfmul")])
1554
1555;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1556(define_insn "dlmzb"
1557  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1558        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1559                    (match_operand:SI 2 "gpc_reg_operand" "r")]
1560                   UNSPEC_DLMZB_CR))
1561   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1562        (unspec:SI [(match_dup 1)
1563                    (match_dup 2)]
1564                   UNSPEC_DLMZB))]
1565  "TARGET_DLMZB"
1566  "dlmzb. %0,%1,%2")
1567
1568(define_expand "strlensi"
1569  [(set (match_operand:SI 0 "gpc_reg_operand" "")
1570        (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1571                    (match_operand:QI 2 "const_int_operand" "")
1572                    (match_operand 3 "const_int_operand" "")]
1573                   UNSPEC_DLMZB_STRLEN))
1574   (clobber (match_scratch:CC 4 "=x"))]
1575  "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1576{
1577  rtx result = operands[0];
1578  rtx src = operands[1];
1579  rtx search_char = operands[2];
1580  rtx align = operands[3];
1581  rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1582  rtx loop_label, end_label, mem, cr0, cond;
1583  if (search_char != const0_rtx
1584      || GET_CODE (align) != CONST_INT
1585      || INTVAL (align) < 8)
1586        FAIL;
1587  word1 = gen_reg_rtx (SImode);
1588  word2 = gen_reg_rtx (SImode);
1589  scratch_dlmzb = gen_reg_rtx (SImode);
1590  scratch_string = gen_reg_rtx (Pmode);
1591  loop_label = gen_label_rtx ();
1592  end_label = gen_label_rtx ();
1593  addr = force_reg (Pmode, XEXP (src, 0));
1594  emit_move_insn (scratch_string, addr);
1595  emit_label (loop_label);
1596  mem = change_address (src, SImode, scratch_string);
1597  emit_move_insn (word1, mem);
1598  emit_move_insn (word2, adjust_address (mem, SImode, 4));
1599  cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1600  emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1601  cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1602  emit_jump_insn (gen_rtx_SET (pc_rtx,
1603                               gen_rtx_IF_THEN_ELSE (VOIDmode,
1604                                                     cond,
1605                                                     gen_rtx_LABEL_REF
1606                                                       (VOIDmode,
1607                                                        end_label),
1608                                                     pc_rtx)));
1609  emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1610  emit_jump_insn (gen_rtx_SET (pc_rtx,
1611                               gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1612  emit_barrier ();
1613  emit_label (end_label);
1614  emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1615  emit_insn (gen_subsi3 (result, scratch_string, addr));
1616  emit_insn (gen_addsi3 (result, result, constm1_rtx));
1617  DONE;
1618})
1619
1620;; Fixed-point arithmetic insns.
1621
1622(define_expand "add<mode>3"
1623  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1624	(plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1625		  (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1626  ""
1627{
1628  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1629    {
1630      rtx lo0 = gen_lowpart (SImode, operands[0]);
1631      rtx lo1 = gen_lowpart (SImode, operands[1]);
1632      rtx lo2 = gen_lowpart (SImode, operands[2]);
1633      rtx hi0 = gen_highpart (SImode, operands[0]);
1634      rtx hi1 = gen_highpart (SImode, operands[1]);
1635      rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1636
1637      if (!reg_or_short_operand (lo2, SImode))
1638	lo2 = force_reg (SImode, lo2);
1639      if (!adde_operand (hi2, SImode))
1640	hi2 = force_reg (SImode, hi2);
1641
1642      emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1643      emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1644      DONE;
1645    }
1646
1647  if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1648    {
1649      rtx tmp = ((!can_create_pseudo_p ()
1650		  || rtx_equal_p (operands[0], operands[1]))
1651		 ? operands[0] : gen_reg_rtx (<MODE>mode));
1652
1653      HOST_WIDE_INT val = INTVAL (operands[2]);
1654      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1655      HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1656
1657      if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1658	FAIL;
1659
1660      /* The ordering here is important for the prolog expander.
1661	 When space is allocated from the stack, adding 'low' first may
1662	 produce a temporary deallocation (which would be bad).  */
1663      emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1664      emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1665      DONE;
1666    }
1667})
1668
1669(define_insn "*add<mode>3"
1670  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1671	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1672		  (match_operand:GPR 2 "add_operand" "r,I,L")))]
1673  ""
1674  "@
1675   add %0,%1,%2
1676   addi %0,%1,%2
1677   addis %0,%1,%v2"
1678  [(set_attr "type" "add")])
1679
1680(define_insn "addsi3_high"
1681  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1682        (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1683                 (high:SI (match_operand 2 "" ""))))]
1684  "TARGET_MACHO && !TARGET_64BIT"
1685  "addis %0,%1,ha16(%2)"
1686  [(set_attr "type" "add")])
1687
1688(define_insn_and_split "*add<mode>3_dot"
1689  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1690	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1691			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1692		    (const_int 0)))
1693   (clobber (match_scratch:GPR 0 "=r,r"))]
1694  "<MODE>mode == Pmode"
1695  "@
1696   add. %0,%1,%2
1697   #"
1698  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1699  [(set (match_dup 0)
1700	(plus:GPR (match_dup 1)
1701		 (match_dup 2)))
1702   (set (match_dup 3)
1703	(compare:CC (match_dup 0)
1704		    (const_int 0)))]
1705  ""
1706  [(set_attr "type" "add")
1707   (set_attr "dot" "yes")
1708   (set_attr "length" "4,8")])
1709
1710(define_insn_and_split "*add<mode>3_dot2"
1711  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1712	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1713			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1714		    (const_int 0)))
1715   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1716	(plus:GPR (match_dup 1)
1717		  (match_dup 2)))]
1718  "<MODE>mode == Pmode"
1719  "@
1720   add. %0,%1,%2
1721   #"
1722  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1723  [(set (match_dup 0)
1724	(plus:GPR (match_dup 1)
1725		  (match_dup 2)))
1726   (set (match_dup 3)
1727	(compare:CC (match_dup 0)
1728		    (const_int 0)))]
1729  ""
1730  [(set_attr "type" "add")
1731   (set_attr "dot" "yes")
1732   (set_attr "length" "4,8")])
1733
1734(define_insn_and_split "*add<mode>3_imm_dot"
1735  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1736	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1737			      (match_operand:GPR 2 "short_cint_operand" "I,I"))
1738		    (const_int 0)))
1739   (clobber (match_scratch:GPR 0 "=r,r"))
1740   (clobber (reg:GPR CA_REGNO))]
1741  "<MODE>mode == Pmode"
1742  "@
1743   addic. %0,%1,%2
1744   #"
1745  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1746  [(set (match_dup 0)
1747	(plus:GPR (match_dup 1)
1748		  (match_dup 2)))
1749   (set (match_dup 3)
1750	(compare:CC (match_dup 0)
1751		    (const_int 0)))]
1752  ""
1753  [(set_attr "type" "add")
1754   (set_attr "dot" "yes")
1755   (set_attr "length" "4,8")])
1756
1757(define_insn_and_split "*add<mode>3_imm_dot2"
1758  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1759	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1760			      (match_operand:GPR 2 "short_cint_operand" "I,I"))
1761		    (const_int 0)))
1762   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1763	(plus:GPR (match_dup 1)
1764		  (match_dup 2)))
1765   (clobber (reg:GPR CA_REGNO))]
1766  "<MODE>mode == Pmode"
1767  "@
1768   addic. %0,%1,%2
1769   #"
1770  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1771  [(set (match_dup 0)
1772	(plus:GPR (match_dup 1)
1773		  (match_dup 2)))
1774   (set (match_dup 3)
1775	(compare:CC (match_dup 0)
1776		    (const_int 0)))]
1777  ""
1778  [(set_attr "type" "add")
1779   (set_attr "dot" "yes")
1780   (set_attr "length" "4,8")])
1781
1782;; Split an add that we can't do in one insn into two insns, each of which
1783;; does one 16-bit part.  This is used by combine.  Note that the low-order
1784;; add should be last in case the result gets used in an address.
1785
1786(define_split
1787  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1788	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1789		  (match_operand:GPR 2 "non_add_cint_operand" "")))]
1790  ""
1791  [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1792   (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1793{
1794  HOST_WIDE_INT val = INTVAL (operands[2]);
1795  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1796  HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1797
1798  operands[4] = GEN_INT (low);
1799  if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1800    operands[3] = GEN_INT (rest);
1801  else if (can_create_pseudo_p ())
1802    {
1803      operands[3] = gen_reg_rtx (DImode);
1804      emit_move_insn (operands[3], operands[2]);
1805      emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1806      DONE;
1807    }
1808  else
1809    FAIL;
1810})
1811
1812
1813(define_insn "add<mode>3_carry"
1814  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1815	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1816		(match_operand:P 2 "reg_or_short_operand" "rI")))
1817   (set (reg:P CA_REGNO)
1818	(ltu:P (plus:P (match_dup 1)
1819		       (match_dup 2))
1820	       (match_dup 1)))]
1821  ""
1822  "add%I2c %0,%1,%2"
1823  [(set_attr "type" "add")])
1824
1825(define_insn "*add<mode>3_imm_carry_pos"
1826  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1827	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1828		(match_operand:P 2 "short_cint_operand" "n")))
1829   (set (reg:P CA_REGNO)
1830	(geu:P (match_dup 1)
1831	       (match_operand:P 3 "const_int_operand" "n")))]
1832  "INTVAL (operands[2]) > 0
1833   && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1834  "addic %0,%1,%2"
1835  [(set_attr "type" "add")])
1836
1837(define_insn "*add<mode>3_imm_carry_0"
1838  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1839	(match_operand:P 1 "gpc_reg_operand" "r"))
1840   (set (reg:P CA_REGNO)
1841	(const_int 0))]
1842  ""
1843  "addic %0,%1,0"
1844  [(set_attr "type" "add")])
1845
1846(define_insn "*add<mode>3_imm_carry_m1"
1847  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1848	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1849		(const_int -1)))
1850   (set (reg:P CA_REGNO)
1851	(ne:P (match_dup 1)
1852	      (const_int 0)))]
1853  ""
1854  "addic %0,%1,-1"
1855  [(set_attr "type" "add")])
1856
1857(define_insn "*add<mode>3_imm_carry_neg"
1858  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1859	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1860		(match_operand:P 2 "short_cint_operand" "n")))
1861   (set (reg:P CA_REGNO)
1862	(gtu:P (match_dup 1)
1863	       (match_operand:P 3 "const_int_operand" "n")))]
1864  "INTVAL (operands[2]) < 0
1865   && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1866  "addic %0,%1,%2"
1867  [(set_attr "type" "add")])
1868
1869
1870(define_expand "add<mode>3_carry_in"
1871  [(parallel [
1872     (set (match_operand:GPR 0 "gpc_reg_operand")
1873	  (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1874			      (match_operand:GPR 2 "adde_operand"))
1875		    (reg:GPR CA_REGNO)))
1876     (clobber (reg:GPR CA_REGNO))])]
1877  ""
1878{
1879  if (operands[2] == const0_rtx)
1880    {
1881      emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1882      DONE;
1883    }
1884  if (operands[2] == constm1_rtx)
1885    {
1886      emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1887      DONE;
1888    }
1889})
1890
1891(define_insn "*add<mode>3_carry_in_internal"
1892  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1893	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1894			    (match_operand:GPR 2 "gpc_reg_operand" "r"))
1895		  (reg:GPR CA_REGNO)))
1896   (clobber (reg:GPR CA_REGNO))]
1897  ""
1898  "adde %0,%1,%2"
1899  [(set_attr "type" "add")])
1900
1901(define_insn "add<mode>3_carry_in_0"
1902  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904		  (reg:GPR CA_REGNO)))
1905   (clobber (reg:GPR CA_REGNO))]
1906  ""
1907  "addze %0,%1"
1908  [(set_attr "type" "add")])
1909
1910(define_insn "add<mode>3_carry_in_m1"
1911  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1912	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1913			    (reg:GPR CA_REGNO))
1914		  (const_int -1)))
1915   (clobber (reg:GPR CA_REGNO))]
1916  ""
1917  "addme %0,%1"
1918  [(set_attr "type" "add")])
1919
1920
1921(define_expand "one_cmpl<mode>2"
1922  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1923	(not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1924  ""
1925{
1926  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1927    {
1928      rs6000_split_logical (operands, NOT, false, false, false);
1929      DONE;
1930    }
1931})
1932
1933(define_insn "*one_cmpl<mode>2"
1934  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1935	(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1936  ""
1937  "not %0,%1")
1938
1939(define_insn_and_split "*one_cmpl<mode>2_dot"
1940  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1941	(compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1942		    (const_int 0)))
1943   (clobber (match_scratch:GPR 0 "=r,r"))]
1944  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1945  "@
1946   not. %0,%1
1947   #"
1948  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1949  [(set (match_dup 0)
1950	(not:GPR (match_dup 1)))
1951   (set (match_dup 2)
1952	(compare:CC (match_dup 0)
1953		    (const_int 0)))]
1954  ""
1955  [(set_attr "type" "logical")
1956   (set_attr "dot" "yes")
1957   (set_attr "length" "4,8")])
1958
1959(define_insn_and_split "*one_cmpl<mode>2_dot2"
1960  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1961	(compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1962		    (const_int 0)))
1963   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1964	(not:GPR (match_dup 1)))]
1965  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1966  "@
1967   not. %0,%1
1968   #"
1969  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1970  [(set (match_dup 0)
1971	(not:GPR (match_dup 1)))
1972   (set (match_dup 2)
1973	(compare:CC (match_dup 0)
1974		    (const_int 0)))]
1975  ""
1976  [(set_attr "type" "logical")
1977   (set_attr "dot" "yes")
1978   (set_attr "length" "4,8")])
1979
1980
1981(define_expand "sub<mode>3"
1982  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1983	(minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1984		   (match_operand:SDI 2 "gpc_reg_operand" "")))]
1985  ""
1986{
1987  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1988    {
1989      rtx lo0 = gen_lowpart (SImode, operands[0]);
1990      rtx lo1 = gen_lowpart (SImode, operands[1]);
1991      rtx lo2 = gen_lowpart (SImode, operands[2]);
1992      rtx hi0 = gen_highpart (SImode, operands[0]);
1993      rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1994      rtx hi2 = gen_highpart (SImode, operands[2]);
1995
1996      if (!reg_or_short_operand (lo1, SImode))
1997	lo1 = force_reg (SImode, lo1);
1998      if (!adde_operand (hi1, SImode))
1999	hi1 = force_reg (SImode, hi1);
2000
2001      emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2002      emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2003      DONE;
2004    }
2005
2006  if (short_cint_operand (operands[1], <MODE>mode))
2007    {
2008      emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2009      DONE;
2010    }
2011})
2012
2013(define_insn "*subf<mode>3"
2014  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2015	(minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2016		   (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2017  ""
2018  "subf %0,%1,%2"
2019  [(set_attr "type" "add")])
2020
2021(define_insn_and_split "*subf<mode>3_dot"
2022  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2023	(compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2024			       (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2025		    (const_int 0)))
2026   (clobber (match_scratch:GPR 0 "=r,r"))]
2027  "<MODE>mode == Pmode"
2028  "@
2029   subf. %0,%1,%2
2030   #"
2031  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2032  [(set (match_dup 0)
2033	(minus:GPR (match_dup 2)
2034		   (match_dup 1)))
2035   (set (match_dup 3)
2036	(compare:CC (match_dup 0)
2037		    (const_int 0)))]
2038  ""
2039  [(set_attr "type" "add")
2040   (set_attr "dot" "yes")
2041   (set_attr "length" "4,8")])
2042
2043(define_insn_and_split "*subf<mode>3_dot2"
2044  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2045	(compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2046			       (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2047		    (const_int 0)))
2048   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2049	(minus:GPR (match_dup 2)
2050		   (match_dup 1)))]
2051  "<MODE>mode == Pmode"
2052  "@
2053   subf. %0,%1,%2
2054   #"
2055  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2056  [(set (match_dup 0)
2057	(minus:GPR (match_dup 2)
2058		   (match_dup 1)))
2059   (set (match_dup 3)
2060	(compare:CC (match_dup 0)
2061		    (const_int 0)))]
2062  ""
2063  [(set_attr "type" "add")
2064   (set_attr "dot" "yes")
2065   (set_attr "length" "4,8")])
2066
2067(define_insn "subf<mode>3_imm"
2068  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069	(minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2070		   (match_operand:GPR 1 "gpc_reg_operand" "r")))
2071   (clobber (reg:GPR CA_REGNO))]
2072  ""
2073  "subfic %0,%1,%2"
2074  [(set_attr "type" "add")])
2075
2076(define_insn_and_split "subf<mode>3_carry_dot2"
2077  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2078	(compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2079			       (match_operand:P 1 "gpc_reg_operand" "r,r"))
2080		    (const_int 0)))
2081   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2082	(minus:P (match_dup 2)
2083		   (match_dup 1)))
2084   (set (reg:P CA_REGNO)
2085	(leu:P (match_dup 1)
2086	       (match_dup 2)))]
2087  "<MODE>mode == Pmode"
2088  "@
2089   subfc. %0,%1,%2
2090   #"
2091  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2092  [(parallel [(set (match_dup 0)
2093                   (minus:P (match_dup 2)
2094                            (match_dup 1)))
2095              (set (reg:P CA_REGNO)
2096                   (leu:P (match_dup 1)
2097                          (match_dup 2)))])
2098   (set (match_dup 3)
2099        (compare:CC (match_dup 0)
2100                    (const_int 0)))]
2101  ""
2102  [(set_attr "type" "add")
2103   (set_attr "dot" "yes")
2104   (set_attr "length" "4,8")])
2105
2106(define_insn "subf<mode>3_carry"
2107  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2108	(minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2109		 (match_operand:P 1 "gpc_reg_operand" "r")))
2110   (set (reg:P CA_REGNO)
2111	(leu:P (match_dup 1)
2112	       (match_dup 2)))]
2113  ""
2114  "subf%I2c %0,%1,%2"
2115  [(set_attr "type" "add")])
2116
2117(define_insn "*subf<mode>3_imm_carry_0"
2118  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2119	(neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2120   (set (reg:P CA_REGNO)
2121	(eq:P (match_dup 1)
2122	      (const_int 0)))]
2123  ""
2124  "subfic %0,%1,0"
2125  [(set_attr "type" "add")])
2126
2127(define_insn "*subf<mode>3_imm_carry_m1"
2128  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2129	(not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2130   (set (reg:P CA_REGNO)
2131	(const_int 1))]
2132  ""
2133  "subfic %0,%1,-1"
2134  [(set_attr "type" "add")])
2135
2136
2137(define_expand "subf<mode>3_carry_in"
2138  [(parallel [
2139     (set (match_operand:GPR 0 "gpc_reg_operand")
2140	  (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2141			      (reg:GPR CA_REGNO))
2142		    (match_operand:GPR 2 "adde_operand")))
2143     (clobber (reg:GPR CA_REGNO))])]
2144  ""
2145{
2146  if (operands[2] == const0_rtx)
2147    {
2148      emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2149      DONE;
2150    }
2151  if (operands[2] == constm1_rtx)
2152    {
2153      emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2154      DONE;
2155    }
2156})
2157
2158(define_insn "*subf<mode>3_carry_in_internal"
2159  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2160	(plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2161			    (reg:GPR CA_REGNO))
2162		  (match_operand:GPR 2 "gpc_reg_operand" "r")))
2163   (clobber (reg:GPR CA_REGNO))]
2164  ""
2165  "subfe %0,%1,%2"
2166  [(set_attr "type" "add")])
2167
2168(define_insn "subf<mode>3_carry_in_0"
2169  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170	(plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2171		  (reg:GPR CA_REGNO)))
2172   (clobber (reg:GPR CA_REGNO))]
2173  ""
2174  "subfze %0,%1"
2175  [(set_attr "type" "add")])
2176
2177(define_insn "subf<mode>3_carry_in_m1"
2178  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2179	(plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2180			     (match_operand:GPR 1 "gpc_reg_operand" "r"))
2181		  (const_int -2)))
2182   (clobber (reg:GPR CA_REGNO))]
2183  ""
2184  "subfme %0,%1"
2185  [(set_attr "type" "add")])
2186
2187(define_insn "subf<mode>3_carry_in_xx"
2188  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189	(plus:GPR (reg:GPR CA_REGNO)
2190		  (const_int -1)))
2191   (clobber (reg:GPR CA_REGNO))]
2192  ""
2193  "subfe %0,%0,%0"
2194  [(set_attr "type" "add")])
2195
2196
2197(define_insn "neg<mode>2"
2198  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2200  ""
2201  "neg %0,%1"
2202  [(set_attr "type" "add")])
2203
2204(define_insn_and_split "*neg<mode>2_dot"
2205  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2206	(compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2207		    (const_int 0)))
2208   (clobber (match_scratch:GPR 0 "=r,r"))]
2209  "<MODE>mode == Pmode"
2210  "@
2211   neg. %0,%1
2212   #"
2213  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2214  [(set (match_dup 0)
2215	(neg:GPR (match_dup 1)))
2216   (set (match_dup 2)
2217	(compare:CC (match_dup 0)
2218		    (const_int 0)))]
2219  ""
2220  [(set_attr "type" "add")
2221   (set_attr "dot" "yes")
2222   (set_attr "length" "4,8")])
2223
2224(define_insn_and_split "*neg<mode>2_dot2"
2225  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2226	(compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2227		    (const_int 0)))
2228   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2229	(neg:GPR (match_dup 1)))]
2230  "<MODE>mode == Pmode"
2231  "@
2232   neg. %0,%1
2233   #"
2234  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2235  [(set (match_dup 0)
2236	(neg:GPR (match_dup 1)))
2237   (set (match_dup 2)
2238	(compare:CC (match_dup 0)
2239		    (const_int 0)))]
2240  ""
2241  [(set_attr "type" "add")
2242   (set_attr "dot" "yes")
2243   (set_attr "length" "4,8")])
2244
2245
2246(define_insn "clz<mode>2"
2247  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2248	(clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2249  ""
2250  "cntlz<wd> %0,%1"
2251  [(set_attr "type" "cntlz")])
2252
2253(define_expand "ctz<mode>2"
2254   [(set (match_operand:GPR 0 "gpc_reg_operand")
2255	 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2256  ""
2257{
2258  if (TARGET_CTZ)
2259    {
2260      emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2261      DONE;
2262    }
2263
2264  rtx tmp1 = gen_reg_rtx (<MODE>mode);
2265  rtx tmp2 = gen_reg_rtx (<MODE>mode);
2266  rtx tmp3 = gen_reg_rtx (<MODE>mode);
2267
2268  if (TARGET_POPCNTD)
2269    {
2270      emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2271      emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2272      emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2273      emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2274    }
2275  else
2276    {
2277      emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2278      emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2279      emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2280      emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2281    }
2282
2283  DONE;
2284})
2285
2286(define_insn "ctz<mode>2_hw"
2287  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2288	(ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2289  "TARGET_CTZ"
2290  "cnttz<wd> %0,%1"
2291  [(set_attr "type" "cntlz")])
2292
2293(define_expand "ffs<mode>2"
2294  [(set (match_operand:GPR 0 "gpc_reg_operand")
2295	(ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2296  ""
2297{
2298  rtx tmp1 = gen_reg_rtx (<MODE>mode);
2299  rtx tmp2 = gen_reg_rtx (<MODE>mode);
2300  rtx tmp3 = gen_reg_rtx (<MODE>mode);
2301  emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2302  emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2303  emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2304  emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2305  DONE;
2306})
2307
2308
2309(define_expand "popcount<mode>2"
2310  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2311	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2312  "TARGET_POPCNTB || TARGET_POPCNTD"
2313{
2314  rs6000_emit_popcount (operands[0], operands[1]);
2315  DONE;
2316})
2317
2318(define_insn "popcntb<mode>2"
2319  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2320	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2321		    UNSPEC_POPCNTB))]
2322  "TARGET_POPCNTB"
2323  "popcntb %0,%1"
2324  [(set_attr "type" "popcnt")])
2325
2326(define_insn "popcntd<mode>2"
2327  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2328	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2329  "TARGET_POPCNTD"
2330  "popcnt<wd> %0,%1"
2331  [(set_attr "type" "popcnt")])
2332
2333
2334(define_expand "parity<mode>2"
2335  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2336	(parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2337  "TARGET_POPCNTB"
2338{
2339  rs6000_emit_parity (operands[0], operands[1]);
2340  DONE;
2341})
2342
2343(define_insn "parity<mode>2_cmpb"
2344  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2345	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2346  "TARGET_CMPB && TARGET_POPCNTB"
2347  "prty<wd> %0,%1"
2348  [(set_attr "type" "popcnt")])
2349
2350(define_insn "cmpb<mode>3"
2351  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2352	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2353		     (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2354  "TARGET_CMPB"
2355  "cmpb %0,%1,%2"
2356  [(set_attr "type" "cmp")])
2357
2358;; Since the hardware zeros the upper part of the register, save generating the
2359;; AND immediate if we are converting to unsigned
2360(define_insn "*bswap<mode>2_extenddi"
2361  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2362	(zero_extend:DI
2363	 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2364  "TARGET_POWERPC64"
2365  "l<wd>brx %0,%y1"
2366  [(set_attr "length" "4")
2367   (set_attr "type" "load")])
2368
2369(define_insn "*bswaphi2_extendsi"
2370  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2371	(zero_extend:SI
2372	 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2373  ""
2374  "lhbrx %0,%y1"
2375  [(set_attr "length" "4")
2376   (set_attr "type" "load")])
2377
2378;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2379;; the register allocator from converting a gpr<-gpr swap into a store and then
2380;; load with byte swap, which can be slower than doing it in the registers.  It
2381;; also prevents certain failures with the RELOAD register allocator.
2382
2383(define_expand "bswap<mode>2"
2384  [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2385   (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2386  ""
2387{
2388  rtx dest = operands[0];
2389  rtx src = operands[1];
2390
2391  if (!REG_P (dest) && !REG_P (src))
2392    src = force_reg (<MODE>mode, src);
2393
2394  if (MEM_P (src))
2395    emit_insn (gen_bswap<mode>2_load (dest, src));
2396  else if (MEM_P (dest))
2397    emit_insn (gen_bswap<mode>2_store (dest, src));
2398  else
2399    emit_insn (gen_bswap<mode>2_reg (dest, src));
2400  DONE;
2401})
2402
2403(define_insn "bswap<mode>2_load"
2404  [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2405	(bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2406  ""
2407  "l<wd>brx %0,%y1"
2408  [(set_attr "type" "load")])
2409
2410(define_insn "bswap<mode>2_store"
2411  [(set (match_operand:HSI 0 "memory_operand" "=Z")
2412	(bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2413  ""
2414  "st<wd>brx %1,%y0"
2415  [(set_attr "type" "store")])
2416
2417(define_insn_and_split "bswaphi2_reg"
2418  [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2419	(bswap:HI
2420	 (match_operand:HI 1 "gpc_reg_operand" "r")))
2421   (clobber (match_scratch:SI 2 "=&r"))]
2422  ""
2423  "#"
2424  "reload_completed"
2425  [(set (match_dup 3)
2426	(and:SI (lshiftrt:SI (match_dup 4)
2427			     (const_int 8))
2428		(const_int 255)))
2429   (set (match_dup 2)
2430	(and:SI (ashift:SI (match_dup 4)
2431			   (const_int 8))
2432		(const_int 65280)))		;; 0xff00
2433   (set (match_dup 3)
2434	(ior:SI (match_dup 3)
2435		(match_dup 2)))]
2436{
2437  operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2438  operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2439}
2440  [(set_attr "length" "12")
2441   (set_attr "type" "*")])
2442
2443;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2444;; zero_extract insns do not change for -mlittle.
2445(define_insn_and_split "bswapsi2_reg"
2446  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2447	(bswap:SI
2448	 (match_operand:SI 1 "gpc_reg_operand" "r")))]
2449  ""
2450  "#"
2451  "reload_completed"
2452  [(set (match_dup 0)					; DABC
2453	(rotate:SI (match_dup 1)
2454		   (const_int 24)))
2455   (set (match_dup 0)					; DCBC
2456	(ior:SI (and:SI (ashift:SI (match_dup 1)
2457				   (const_int 8))
2458			(const_int 16711680))
2459		(and:SI (match_dup 0)
2460			(const_int -16711681))))
2461   (set (match_dup 0)					; DCBA
2462	(ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2463				     (const_int 24))
2464			(const_int 255))
2465		(and:SI (match_dup 0)
2466			(const_int -256))))]
2467  "")
2468
2469;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2470;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2471;; complex code.
2472
2473(define_expand "bswapdi2"
2474  [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2475		   (bswap:DI
2476		    (match_operand:DI 1 "reg_or_mem_operand" "")))
2477	      (clobber (match_scratch:DI 2 ""))
2478	      (clobber (match_scratch:DI 3 ""))])]
2479  ""
2480{
2481  rtx dest = operands[0];
2482  rtx src = operands[1];
2483
2484  if (!REG_P (dest) && !REG_P (src))
2485    operands[1] = src = force_reg (DImode, src);
2486
2487  if (TARGET_POWERPC64 && TARGET_LDBRX)
2488    {
2489      if (MEM_P (src))
2490	emit_insn (gen_bswapdi2_load (dest, src));
2491      else if (MEM_P (dest))
2492	emit_insn (gen_bswapdi2_store (dest, src));
2493      else
2494	emit_insn (gen_bswapdi2_reg (dest, src));
2495      DONE;
2496    }
2497
2498  if (!TARGET_POWERPC64)
2499    {
2500      /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2501	 that uses 64-bit registers needs the same scratch registers as 64-bit
2502	 mode.  */
2503      emit_insn (gen_bswapdi2_32bit (dest, src));
2504      DONE;
2505    }
2506})
2507
2508;; Power7/cell has ldbrx/stdbrx, so use it directly
2509(define_insn "bswapdi2_load"
2510  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2511	(bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2512  "TARGET_POWERPC64 && TARGET_LDBRX"
2513  "ldbrx %0,%y1"
2514  [(set_attr "type" "load")])
2515
2516(define_insn "bswapdi2_store"
2517  [(set (match_operand:DI 0 "memory_operand" "=Z")
2518	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2519  "TARGET_POWERPC64 && TARGET_LDBRX"
2520  "stdbrx %1,%y0"
2521  [(set_attr "type" "store")])
2522
2523(define_insn "bswapdi2_reg"
2524  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2525	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2526   (clobber (match_scratch:DI 2 "=&r"))
2527   (clobber (match_scratch:DI 3 "=&r"))]
2528  "TARGET_POWERPC64 && TARGET_LDBRX"
2529  "#"
2530  [(set_attr "length" "36")])
2531
2532;; Non-power7/cell, fall back to use lwbrx/stwbrx
2533(define_insn "*bswapdi2_64bit"
2534  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2535	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2536   (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2537   (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2538  "TARGET_POWERPC64 && !TARGET_LDBRX
2539   && (REG_P (operands[0]) || REG_P (operands[1]))
2540   && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2541   && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2542  "#"
2543  [(set_attr "length" "16,12,36")])
2544
2545(define_split
2546  [(set (match_operand:DI 0 "gpc_reg_operand" "")
2547	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2548   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2549   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2550  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2551  [(const_int 0)]
2552  "
2553{
2554  rtx dest   = operands[0];
2555  rtx src    = operands[1];
2556  rtx op2    = operands[2];
2557  rtx op3    = operands[3];
2558  rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2559				    BYTES_BIG_ENDIAN ? 4 : 0);
2560  rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2561				     BYTES_BIG_ENDIAN ? 4 : 0);
2562  rtx addr1;
2563  rtx addr2;
2564  rtx word1;
2565  rtx word2;
2566
2567  addr1 = XEXP (src, 0);
2568  if (GET_CODE (addr1) == PLUS)
2569    {
2570      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2571      if (TARGET_AVOID_XFORM)
2572	{
2573	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2574	  addr2 = op2;
2575	}
2576      else
2577	addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2578    }
2579  else if (TARGET_AVOID_XFORM)
2580    {
2581      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2582      addr2 = op2;
2583    }
2584  else
2585    {
2586      emit_move_insn (op2, GEN_INT (4));
2587      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2588    }
2589
2590  word1 = change_address (src, SImode, addr1);
2591  word2 = change_address (src, SImode, addr2);
2592
2593  if (BYTES_BIG_ENDIAN)
2594    {
2595      emit_insn (gen_bswapsi2 (op3_32, word2));
2596      emit_insn (gen_bswapsi2 (dest_32, word1));
2597    }
2598  else
2599    {
2600      emit_insn (gen_bswapsi2 (op3_32, word1));
2601      emit_insn (gen_bswapsi2 (dest_32, word2));
2602    }
2603
2604  emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2605  emit_insn (gen_iordi3 (dest, dest, op3));
2606  DONE;
2607}")
2608
2609(define_split
2610  [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2611	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2612   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2613   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2614  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2615  [(const_int 0)]
2616  "
2617{
2618  rtx dest   = operands[0];
2619  rtx src    = operands[1];
2620  rtx op2    = operands[2];
2621  rtx op3    = operands[3];
2622  rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2623				    BYTES_BIG_ENDIAN ? 4 : 0);
2624  rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2625				    BYTES_BIG_ENDIAN ? 4 : 0);
2626  rtx addr1;
2627  rtx addr2;
2628  rtx word1;
2629  rtx word2;
2630
2631  addr1 = XEXP (dest, 0);
2632  if (GET_CODE (addr1) == PLUS)
2633    {
2634      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2635      if (TARGET_AVOID_XFORM)
2636	{
2637	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2638	  addr2 = op2;
2639	}
2640      else
2641	addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2642    }
2643  else if (TARGET_AVOID_XFORM)
2644    {
2645      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2646      addr2 = op2;
2647    }
2648  else
2649    {
2650      emit_move_insn (op2, GEN_INT (4));
2651      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2652    }
2653
2654  word1 = change_address (dest, SImode, addr1);
2655  word2 = change_address (dest, SImode, addr2);
2656
2657  emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2658
2659  if (BYTES_BIG_ENDIAN)
2660    {
2661      emit_insn (gen_bswapsi2 (word1, src_si));
2662      emit_insn (gen_bswapsi2 (word2, op3_si));
2663    }
2664  else
2665    {
2666      emit_insn (gen_bswapsi2 (word2, src_si));
2667      emit_insn (gen_bswapsi2 (word1, op3_si));
2668    }
2669  DONE;
2670}")
2671
2672(define_split
2673  [(set (match_operand:DI 0 "gpc_reg_operand" "")
2674	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2675   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2676   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2677  "TARGET_POWERPC64 && reload_completed"
2678  [(const_int 0)]
2679  "
2680{
2681  rtx dest    = operands[0];
2682  rtx src     = operands[1];
2683  rtx op2     = operands[2];
2684  rtx op3     = operands[3];
2685  int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2686  rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2687  rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2688  rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2689  rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2690
2691  emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2692  emit_insn (gen_bswapsi2 (dest_si, src_si));
2693  emit_insn (gen_bswapsi2 (op3_si, op2_si));
2694  emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2695  emit_insn (gen_iordi3 (dest, dest, op3));
2696  DONE;
2697}")
2698
2699(define_insn "bswapdi2_32bit"
2700  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2701	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2702   (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2703  "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2704  "#"
2705  [(set_attr "length" "16,12,36")])
2706
2707(define_split
2708  [(set (match_operand:DI 0 "gpc_reg_operand" "")
2709	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2710   (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2711  "!TARGET_POWERPC64 && reload_completed"
2712  [(const_int 0)]
2713  "
2714{
2715  rtx dest  = operands[0];
2716  rtx src   = operands[1];
2717  rtx op2   = operands[2];
2718  rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2719  rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2720  rtx addr1;
2721  rtx addr2;
2722  rtx word1;
2723  rtx word2;
2724
2725  addr1 = XEXP (src, 0);
2726  if (GET_CODE (addr1) == PLUS)
2727    {
2728      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2729      if (TARGET_AVOID_XFORM
2730	  || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2731	{
2732	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2733	  addr2 = op2;
2734	}
2735      else
2736	addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2737    }
2738  else if (TARGET_AVOID_XFORM
2739	   || REGNO (addr1) == REGNO (dest2))
2740    {
2741      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2742      addr2 = op2;
2743    }
2744  else
2745    {
2746      emit_move_insn (op2, GEN_INT (4));
2747      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2748    }
2749
2750  word1 = change_address (src, SImode, addr1);
2751  word2 = change_address (src, SImode, addr2);
2752
2753  emit_insn (gen_bswapsi2 (dest2, word1));
2754  /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2755     thus allowing us to omit an early clobber on the output.  */
2756  emit_insn (gen_bswapsi2 (dest1, word2));
2757  DONE;
2758}")
2759
2760(define_split
2761  [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2762	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2763   (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2764  "!TARGET_POWERPC64 && reload_completed"
2765  [(const_int 0)]
2766  "
2767{
2768  rtx dest = operands[0];
2769  rtx src  = operands[1];
2770  rtx op2  = operands[2];
2771  rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2772  rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2773  rtx addr1;
2774  rtx addr2;
2775  rtx word1;
2776  rtx word2;
2777
2778  addr1 = XEXP (dest, 0);
2779  if (GET_CODE (addr1) == PLUS)
2780    {
2781      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2782      if (TARGET_AVOID_XFORM)
2783	{
2784	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2785	  addr2 = op2;
2786	}
2787      else
2788	addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2789    }
2790  else if (TARGET_AVOID_XFORM)
2791    {
2792      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2793      addr2 = op2;
2794    }
2795  else
2796    {
2797      emit_move_insn (op2, GEN_INT (4));
2798      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2799    }
2800
2801  word1 = change_address (dest, SImode, addr1);
2802  word2 = change_address (dest, SImode, addr2);
2803
2804  emit_insn (gen_bswapsi2 (word2, src1));
2805  emit_insn (gen_bswapsi2 (word1, src2));
2806  DONE;
2807}")
2808
2809(define_split
2810  [(set (match_operand:DI 0 "gpc_reg_operand" "")
2811	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2812   (clobber (match_operand:SI 2 "" ""))]
2813  "!TARGET_POWERPC64 && reload_completed"
2814  [(const_int 0)]
2815  "
2816{
2817  rtx dest  = operands[0];
2818  rtx src   = operands[1];
2819  rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2820  rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2821  rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2822  rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2823
2824  emit_insn (gen_bswapsi2 (dest1, src2));
2825  emit_insn (gen_bswapsi2 (dest2, src1));
2826  DONE;
2827}")
2828
2829
2830(define_insn "mul<mode>3"
2831  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2832	(mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2833		  (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2834  ""
2835  "@
2836   mull<wd> %0,%1,%2
2837   mulli %0,%1,%2"
2838   [(set_attr "type" "mul")
2839    (set (attr "size")
2840      (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2841		(const_string "8")
2842             (match_operand:GPR 2 "short_cint_operand" "")
2843		(const_string "16")]
2844	(const_string "<bits>")))])
2845
2846(define_insn_and_split "*mul<mode>3_dot"
2847  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2848	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2849			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2850		    (const_int 0)))
2851   (clobber (match_scratch:GPR 0 "=r,r"))]
2852  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2853  "@
2854   mull<wd>. %0,%1,%2
2855   #"
2856  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2857  [(set (match_dup 0)
2858	(mult:GPR (match_dup 1)
2859		  (match_dup 2)))
2860   (set (match_dup 3)
2861	(compare:CC (match_dup 0)
2862		    (const_int 0)))]
2863  ""
2864  [(set_attr "type" "mul")
2865   (set_attr "size" "<bits>")
2866   (set_attr "dot" "yes")
2867   (set_attr "length" "4,8")])
2868
2869(define_insn_and_split "*mul<mode>3_dot2"
2870  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2871	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2872			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2873		    (const_int 0)))
2874   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2875	(mult:GPR (match_dup 1)
2876		  (match_dup 2)))]
2877  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2878  "@
2879   mull<wd>. %0,%1,%2
2880   #"
2881  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2882  [(set (match_dup 0)
2883	(mult:GPR (match_dup 1)
2884		  (match_dup 2)))
2885   (set (match_dup 3)
2886	(compare:CC (match_dup 0)
2887		    (const_int 0)))]
2888  ""
2889  [(set_attr "type" "mul")
2890   (set_attr "size" "<bits>")
2891   (set_attr "dot" "yes")
2892   (set_attr "length" "4,8")])
2893
2894
2895(define_expand "<su>mul<mode>3_highpart"
2896  [(set (match_operand:GPR 0 "gpc_reg_operand")
2897	(subreg:GPR
2898	  (mult:<DMODE> (any_extend:<DMODE>
2899			  (match_operand:GPR 1 "gpc_reg_operand"))
2900			(any_extend:<DMODE>
2901			  (match_operand:GPR 2 "gpc_reg_operand")))
2902	 0))]
2903  ""
2904{
2905  if (<MODE>mode == SImode && TARGET_POWERPC64)
2906    {
2907      emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2908					     operands[2]));
2909      DONE;
2910    }
2911
2912  if (!WORDS_BIG_ENDIAN)
2913    {
2914      emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2915						 operands[2]));
2916      DONE;
2917    }
2918})
2919
2920(define_insn "*<su>mul<mode>3_highpart"
2921  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2922	(subreg:GPR
2923	  (mult:<DMODE> (any_extend:<DMODE>
2924			  (match_operand:GPR 1 "gpc_reg_operand" "r"))
2925			(any_extend:<DMODE>
2926			  (match_operand:GPR 2 "gpc_reg_operand" "r")))
2927	 0))]
2928  "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2929  "mulh<wd><u> %0,%1,%2"
2930  [(set_attr "type" "mul")
2931   (set_attr "size" "<bits>")])
2932
2933(define_insn "<su>mulsi3_highpart_le"
2934  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2935	(subreg:SI
2936	  (mult:DI (any_extend:DI
2937		     (match_operand:SI 1 "gpc_reg_operand" "r"))
2938		   (any_extend:DI
2939		     (match_operand:SI 2 "gpc_reg_operand" "r")))
2940	 4))]
2941  "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2942  "mulhw<u> %0,%1,%2"
2943  [(set_attr "type" "mul")])
2944
2945(define_insn "<su>muldi3_highpart_le"
2946  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2947	(subreg:DI
2948	  (mult:TI (any_extend:TI
2949		     (match_operand:DI 1 "gpc_reg_operand" "r"))
2950		   (any_extend:TI
2951		     (match_operand:DI 2 "gpc_reg_operand" "r")))
2952	 8))]
2953  "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2954  "mulhd<u> %0,%1,%2"
2955  [(set_attr "type" "mul")
2956   (set_attr "size" "64")])
2957
2958(define_insn "<su>mulsi3_highpart_64"
2959  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2960	(truncate:SI
2961	  (lshiftrt:DI
2962	    (mult:DI (any_extend:DI
2963		       (match_operand:SI 1 "gpc_reg_operand" "r"))
2964		     (any_extend:DI
2965		       (match_operand:SI 2 "gpc_reg_operand" "r")))
2966	    (const_int 32))))]
2967  "TARGET_POWERPC64"
2968  "mulhw<u> %0,%1,%2"
2969  [(set_attr "type" "mul")])
2970
2971(define_expand "<u>mul<mode><dmode>3"
2972  [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2973	(mult:<DMODE> (any_extend:<DMODE>
2974			(match_operand:GPR 1 "gpc_reg_operand"))
2975		      (any_extend:<DMODE>
2976			(match_operand:GPR 2 "gpc_reg_operand"))))]
2977  "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2978{
2979  rtx l = gen_reg_rtx (<MODE>mode);
2980  rtx h = gen_reg_rtx (<MODE>mode);
2981  emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2982  emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2983  emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2984  emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2985  DONE;
2986})
2987
2988(define_insn "*maddld4"
2989  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2990	(plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2991			  (match_operand:DI 2 "gpc_reg_operand" "r"))
2992		 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2993  "TARGET_MADDLD"
2994  "maddld %0,%1,%2,%3"
2995  [(set_attr "type" "mul")])
2996
2997(define_insn "udiv<mode>3"
2998  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2999        (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3000		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3001  ""
3002  "div<wd>u %0,%1,%2"
3003  [(set_attr "type" "div")
3004   (set_attr "size" "<bits>")])
3005
3006
3007;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3008;; modulus.  If it isn't a power of two, force operands into register and do
3009;; a normal divide.
3010(define_expand "div<mode>3"
3011  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3012	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3013		 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3014  ""
3015{
3016  if (CONST_INT_P (operands[2])
3017      && INTVAL (operands[2]) > 0
3018      && exact_log2 (INTVAL (operands[2])) >= 0)
3019    {
3020      emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3021      DONE;
3022    }
3023
3024  operands[2] = force_reg (<MODE>mode, operands[2]);
3025})
3026
3027(define_insn "*div<mode>3"
3028  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3029        (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3030		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3031  ""
3032  "div<wd> %0,%1,%2"
3033  [(set_attr "type" "div")
3034   (set_attr "size" "<bits>")])
3035
3036(define_insn "div<mode>3_sra"
3037  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3038	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3039		 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3040   (clobber (reg:GPR CA_REGNO))]
3041  ""
3042  "sra<wd>i %0,%1,%p2\;addze %0,%0"
3043  [(set_attr "type" "two")
3044   (set_attr "length" "8")])
3045
3046(define_insn_and_split "*div<mode>3_sra_dot"
3047  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3048	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3049			     (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3050		    (const_int 0)))
3051   (clobber (match_scratch:GPR 0 "=r,r"))
3052   (clobber (reg:GPR CA_REGNO))]
3053  "<MODE>mode == Pmode"
3054  "@
3055   sra<wd>i %0,%1,%p2\;addze. %0,%0
3056   #"
3057  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3058  [(parallel [(set (match_dup 0)
3059		   (div:GPR (match_dup 1)
3060			    (match_dup 2)))
3061	      (clobber (reg:GPR CA_REGNO))])
3062   (set (match_dup 3)
3063	(compare:CC (match_dup 0)
3064		    (const_int 0)))]
3065  ""
3066  [(set_attr "type" "two")
3067   (set_attr "length" "8,12")
3068   (set_attr "cell_micro" "not")])
3069
3070(define_insn_and_split "*div<mode>3_sra_dot2"
3071  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3072	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3073			     (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3074		    (const_int 0)))
3075   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3076	(div:GPR (match_dup 1)
3077		 (match_dup 2)))
3078   (clobber (reg:GPR CA_REGNO))]
3079  "<MODE>mode == Pmode"
3080  "@
3081   sra<wd>i %0,%1,%p2\;addze. %0,%0
3082   #"
3083  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3084  [(parallel [(set (match_dup 0)
3085		   (div:GPR (match_dup 1)
3086			    (match_dup 2)))
3087	      (clobber (reg:GPR CA_REGNO))])
3088   (set (match_dup 3)
3089	(compare:CC (match_dup 0)
3090		    (const_int 0)))]
3091  ""
3092  [(set_attr "type" "two")
3093   (set_attr "length" "8,12")
3094   (set_attr "cell_micro" "not")])
3095
3096(define_expand "mod<mode>3"
3097  [(set (match_operand:GPR 0 "gpc_reg_operand")
3098	(mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3099		 (match_operand:GPR 2 "reg_or_cint_operand")))]
3100  ""
3101{
3102  int i;
3103  rtx temp1;
3104  rtx temp2;
3105
3106  if (GET_CODE (operands[2]) != CONST_INT
3107      || INTVAL (operands[2]) <= 0
3108      || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3109    {
3110      if (!TARGET_MODULO)
3111	FAIL;
3112
3113      operands[2] = force_reg (<MODE>mode, operands[2]);
3114    }
3115  else
3116    {
3117      temp1 = gen_reg_rtx (<MODE>mode);
3118      temp2 = gen_reg_rtx (<MODE>mode);
3119
3120      emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3121      emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3122      emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3123      DONE;
3124    }
3125})
3126
3127;; In order to enable using a peephole2 for combining div/mod to eliminate the
3128;; mod, prefer putting the result of mod into a different register
3129(define_insn "*mod<mode>3"
3130  [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3131        (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3132		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3133  "TARGET_MODULO"
3134  "mods<wd> %0,%1,%2"
3135  [(set_attr "type" "div")
3136   (set_attr "size" "<bits>")])
3137
3138
3139(define_insn "umod<mode>3"
3140  [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3141        (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3142		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3143  "TARGET_MODULO"
3144  "modu<wd> %0,%1,%2"
3145  [(set_attr "type" "div")
3146   (set_attr "size" "<bits>")])
3147
3148;; On machines with modulo support, do a combined div/mod the old fashioned
3149;; method, since the multiply/subtract is faster than doing the mod instruction
3150;; after a divide.
3151
3152(define_peephole2
3153  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3154	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3155		 (match_operand:GPR 2 "gpc_reg_operand" "")))
3156   (set (match_operand:GPR 3 "gpc_reg_operand" "")
3157	(mod:GPR (match_dup 1)
3158		 (match_dup 2)))]
3159  "TARGET_MODULO
3160   && ! reg_mentioned_p (operands[0], operands[1])
3161   && ! reg_mentioned_p (operands[0], operands[2])
3162   && ! reg_mentioned_p (operands[3], operands[1])
3163   && ! reg_mentioned_p (operands[3], operands[2])"
3164  [(set (match_dup 0)
3165	(div:GPR (match_dup 1)
3166		 (match_dup 2)))
3167   (set (match_dup 3)
3168	(mult:GPR (match_dup 0)
3169		  (match_dup 2)))
3170   (set (match_dup 3)
3171	(minus:GPR (match_dup 1)
3172		   (match_dup 3)))])
3173
3174(define_peephole2
3175  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3176	(udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3177		  (match_operand:GPR 2 "gpc_reg_operand" "")))
3178   (set (match_operand:GPR 3 "gpc_reg_operand" "")
3179	(umod:GPR (match_dup 1)
3180		  (match_dup 2)))]
3181  "TARGET_MODULO
3182   && ! reg_mentioned_p (operands[0], operands[1])
3183   && ! reg_mentioned_p (operands[0], operands[2])
3184   && ! reg_mentioned_p (operands[3], operands[1])
3185   && ! reg_mentioned_p (operands[3], operands[2])"
3186  [(set (match_dup 0)
3187	(udiv:GPR (match_dup 1)
3188		  (match_dup 2)))
3189   (set (match_dup 3)
3190	(mult:GPR (match_dup 0)
3191		  (match_dup 2)))
3192   (set (match_dup 3)
3193	(minus:GPR (match_dup 1)
3194		   (match_dup 3)))])
3195
3196
3197;; Logical instructions
3198;; The logical instructions are mostly combined by using match_operator,
3199;; but the plain AND insns are somewhat different because there is no
3200;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3201;; those rotate-and-mask operations.  Thus, the AND insns come first.
3202
3203(define_expand "and<mode>3"
3204  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3205	(and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3206		 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3207  ""
3208{
3209  if (<MODE>mode == DImode && !TARGET_POWERPC64)
3210    {
3211      rs6000_split_logical (operands, AND, false, false, false);
3212      DONE;
3213    }
3214
3215  if (CONST_INT_P (operands[2]))
3216    {
3217      if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3218	{
3219	  emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3220	  DONE;
3221	}
3222
3223      if (logical_const_operand (operands[2], <MODE>mode)
3224	  && rs6000_gen_cell_microcode)
3225	{
3226	  emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3227	  DONE;
3228	}
3229
3230      if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3231	{
3232	  rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3233	  DONE;
3234	}
3235
3236      operands[2] = force_reg (<MODE>mode, operands[2]);
3237    }
3238})
3239
3240
3241(define_insn "and<mode>3_imm"
3242  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3243	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3244		 (match_operand:GPR 2 "logical_const_operand" "n")))
3245   (clobber (match_scratch:CC 3 "=x"))]
3246  "rs6000_gen_cell_microcode
3247   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3248  "andi%e2. %0,%1,%u2"
3249  [(set_attr "type" "logical")
3250   (set_attr "dot" "yes")])
3251
3252(define_insn_and_split "*and<mode>3_imm_dot"
3253  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3254	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3255			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3256		    (const_int 0)))
3257   (clobber (match_scratch:GPR 0 "=r,r"))
3258   (clobber (match_scratch:CC 4 "=X,x"))]
3259  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3260   && rs6000_gen_cell_microcode
3261   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3262  "@
3263   andi%e2. %0,%1,%u2
3264   #"
3265  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3266  [(parallel [(set (match_dup 0)
3267		   (and:GPR (match_dup 1)
3268			    (match_dup 2)))
3269	      (clobber (match_dup 4))])
3270   (set (match_dup 3)
3271	(compare:CC (match_dup 0)
3272		    (const_int 0)))]
3273  ""
3274  [(set_attr "type" "logical")
3275   (set_attr "dot" "yes")
3276   (set_attr "length" "4,8")])
3277
3278(define_insn_and_split "*and<mode>3_imm_dot2"
3279  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3280	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3281			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3282		    (const_int 0)))
3283   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3284	(and:GPR (match_dup 1)
3285		 (match_dup 2)))
3286   (clobber (match_scratch:CC 4 "=X,x"))]
3287  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3288   && rs6000_gen_cell_microcode
3289   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3290  "@
3291   andi%e2. %0,%1,%u2
3292   #"
3293  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3294  [(parallel [(set (match_dup 0)
3295		   (and:GPR (match_dup 1)
3296			    (match_dup 2)))
3297	      (clobber (match_dup 4))])
3298   (set (match_dup 3)
3299	(compare:CC (match_dup 0)
3300		    (const_int 0)))]
3301  ""
3302  [(set_attr "type" "logical")
3303   (set_attr "dot" "yes")
3304   (set_attr "length" "4,8")])
3305
3306(define_insn_and_split "*and<mode>3_imm_mask_dot"
3307  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3308	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3309			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3310		    (const_int 0)))
3311   (clobber (match_scratch:GPR 0 "=r,r"))]
3312  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3313   && rs6000_gen_cell_microcode
3314   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3315  "@
3316   andi%e2. %0,%1,%u2
3317   #"
3318  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319  [(set (match_dup 0)
3320	(and:GPR (match_dup 1)
3321		 (match_dup 2)))
3322   (set (match_dup 3)
3323	(compare:CC (match_dup 0)
3324		    (const_int 0)))]
3325  ""
3326  [(set_attr "type" "logical")
3327   (set_attr "dot" "yes")
3328   (set_attr "length" "4,8")])
3329
3330(define_insn_and_split "*and<mode>3_imm_mask_dot2"
3331  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3332	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3333			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3334		    (const_int 0)))
3335   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3336	(and:GPR (match_dup 1)
3337		 (match_dup 2)))]
3338  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3339   && rs6000_gen_cell_microcode
3340   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3341  "@
3342   andi%e2. %0,%1,%u2
3343   #"
3344  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3345  [(set (match_dup 0)
3346	(and:GPR (match_dup 1)
3347		 (match_dup 2)))
3348   (set (match_dup 3)
3349	(compare:CC (match_dup 0)
3350		    (const_int 0)))]
3351  ""
3352  [(set_attr "type" "logical")
3353   (set_attr "dot" "yes")
3354   (set_attr "length" "4,8")])
3355
3356(define_insn "*and<mode>3_imm_dot_shifted"
3357  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3358	(compare:CC
3359	  (and:GPR
3360	    (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3361			  (match_operand:SI 4 "const_int_operand" "n"))
3362	    (match_operand:GPR 2 "const_int_operand" "n"))
3363	  (const_int 0)))
3364   (clobber (match_scratch:GPR 0 "=r"))]
3365  "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3366				   << INTVAL (operands[4])),
3367			  DImode)
3368   && (<MODE>mode == Pmode
3369       || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3370   && rs6000_gen_cell_microcode"
3371{
3372  operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3373  return "andi%e2. %0,%1,%u2";
3374}
3375  [(set_attr "type" "logical")
3376   (set_attr "dot" "yes")])
3377
3378
3379(define_insn "and<mode>3_mask"
3380  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3381	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3382		 (match_operand:GPR 2 "const_int_operand" "n")))]
3383  "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3384{
3385  return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3386}
3387  [(set_attr "type" "shift")])
3388
3389(define_insn_and_split "*and<mode>3_mask_dot"
3390  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3391	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3392			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3393		    (const_int 0)))
3394   (clobber (match_scratch:GPR 0 "=r,r"))]
3395  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3396   && rs6000_gen_cell_microcode
3397   && !logical_const_operand (operands[2], <MODE>mode)
3398   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3399{
3400  if (which_alternative == 0)
3401    return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3402  else
3403    return "#";
3404}
3405  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3406  [(set (match_dup 0)
3407	(and:GPR (match_dup 1)
3408		 (match_dup 2)))
3409   (set (match_dup 3)
3410	(compare:CC (match_dup 0)
3411		    (const_int 0)))]
3412  ""
3413  [(set_attr "type" "shift")
3414   (set_attr "dot" "yes")
3415   (set_attr "length" "4,8")])
3416
3417(define_insn_and_split "*and<mode>3_mask_dot2"
3418  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3419	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3420			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3421		    (const_int 0)))
3422   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3423	(and:GPR (match_dup 1)
3424		 (match_dup 2)))]
3425  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3426   && rs6000_gen_cell_microcode
3427   && !logical_const_operand (operands[2], <MODE>mode)
3428   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3429{
3430  if (which_alternative == 0)
3431    return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3432  else
3433    return "#";
3434}
3435  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3436  [(set (match_dup 0)
3437	(and:GPR (match_dup 1)
3438		 (match_dup 2)))
3439   (set (match_dup 3)
3440	(compare:CC (match_dup 0)
3441		    (const_int 0)))]
3442  ""
3443  [(set_attr "type" "shift")
3444   (set_attr "dot" "yes")
3445   (set_attr "length" "4,8")])
3446
3447
3448(define_insn_and_split "*and<mode>3_2insn"
3449  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3450	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3451		 (match_operand:GPR 2 "const_int_operand" "n")))]
3452  "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3453   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3454	|| (logical_const_operand (operands[2], <MODE>mode)
3455	    && rs6000_gen_cell_microcode))"
3456  "#"
3457  "&& 1"
3458  [(pc)]
3459{
3460  rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3461  DONE;
3462}
3463  [(set_attr "type" "shift")
3464   (set_attr "length" "8")])
3465
3466(define_insn_and_split "*and<mode>3_2insn_dot"
3467  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3468	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3469			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3470		    (const_int 0)))
3471   (clobber (match_scratch:GPR 0 "=r,r"))]
3472  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3473   && rs6000_gen_cell_microcode
3474   && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3475   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3476	|| (logical_const_operand (operands[2], <MODE>mode)
3477	    && rs6000_gen_cell_microcode))"
3478  "#"
3479  "&& reload_completed"
3480  [(pc)]
3481{
3482  rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3483  DONE;
3484}
3485  [(set_attr "type" "shift")
3486   (set_attr "dot" "yes")
3487   (set_attr "length" "8,12")])
3488
3489(define_insn_and_split "*and<mode>3_2insn_dot2"
3490  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3491	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3492			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3493		    (const_int 0)))
3494   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3495	(and:GPR (match_dup 1)
3496		 (match_dup 2)))]
3497  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3498   && rs6000_gen_cell_microcode
3499   && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3500   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3501	|| (logical_const_operand (operands[2], <MODE>mode)
3502	    && rs6000_gen_cell_microcode))"
3503  "#"
3504  "&& reload_completed"
3505  [(pc)]
3506{
3507  rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3508  DONE;
3509}
3510  [(set_attr "type" "shift")
3511   (set_attr "dot" "yes")
3512   (set_attr "length" "8,12")])
3513
3514
3515(define_expand "<code><mode>3"
3516  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3517	(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3518		    (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3519  ""
3520{
3521  if (<MODE>mode == DImode && !TARGET_POWERPC64)
3522    {
3523      rs6000_split_logical (operands, <CODE>, false, false, false);
3524      DONE;
3525    }
3526
3527  if (non_logical_cint_operand (operands[2], <MODE>mode))
3528    {
3529      rtx tmp = ((!can_create_pseudo_p ()
3530		  || rtx_equal_p (operands[0], operands[1]))
3531		 ? operands[0] : gen_reg_rtx (<MODE>mode));
3532
3533      HOST_WIDE_INT value = INTVAL (operands[2]);
3534      HOST_WIDE_INT lo = value & 0xffff;
3535      HOST_WIDE_INT hi = value - lo;
3536
3537      emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3538      emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3539      DONE;
3540    }
3541
3542  if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3543    operands[2] = force_reg (<MODE>mode, operands[2]);
3544})
3545
3546(define_split
3547  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3548	(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3549		    (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3550  ""
3551  [(set (match_dup 3)
3552	(iorxor:GPR (match_dup 1)
3553		    (match_dup 4)))
3554   (set (match_dup 0)
3555	(iorxor:GPR (match_dup 3)
3556		    (match_dup 5)))]
3557{
3558  operands[3] = ((!can_create_pseudo_p ()
3559		  || rtx_equal_p (operands[0], operands[1]))
3560		 ? operands[0] : gen_reg_rtx (<MODE>mode));
3561
3562  HOST_WIDE_INT value = INTVAL (operands[2]);
3563  HOST_WIDE_INT lo = value & 0xffff;
3564  HOST_WIDE_INT hi = value - lo;
3565
3566  operands[4] = GEN_INT (hi);
3567  operands[5] = GEN_INT (lo);
3568})
3569
3570(define_insn "*bool<mode>3_imm"
3571  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3572	(match_operator:GPR 3 "boolean_or_operator"
3573	 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3574	  (match_operand:GPR 2 "logical_const_operand" "n")]))]
3575  ""
3576  "%q3i%e2 %0,%1,%u2"
3577  [(set_attr "type" "logical")])
3578
3579(define_insn "*bool<mode>3"
3580  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3581	(match_operator:GPR 3 "boolean_operator"
3582	 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3583	  (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3584  ""
3585  "%q3 %0,%1,%2"
3586  [(set_attr "type" "logical")])
3587
3588(define_insn_and_split "*bool<mode>3_dot"
3589  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3590	(compare:CC (match_operator:GPR 3 "boolean_operator"
3591	 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3592	  (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3593	 (const_int 0)))
3594   (clobber (match_scratch:GPR 0 "=r,r"))]
3595  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3596  "@
3597   %q3. %0,%1,%2
3598   #"
3599  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3600  [(set (match_dup 0)
3601	(match_dup 3))
3602   (set (match_dup 4)
3603	(compare:CC (match_dup 0)
3604		    (const_int 0)))]
3605  ""
3606  [(set_attr "type" "logical")
3607   (set_attr "dot" "yes")
3608   (set_attr "length" "4,8")])
3609
3610(define_insn_and_split "*bool<mode>3_dot2"
3611  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3612	(compare:CC (match_operator:GPR 3 "boolean_operator"
3613	 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3614	  (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3615	 (const_int 0)))
3616   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3617	(match_dup 3))]
3618  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3619  "@
3620   %q3. %0,%1,%2
3621   #"
3622  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3623  [(set (match_dup 0)
3624	(match_dup 3))
3625   (set (match_dup 4)
3626	(compare:CC (match_dup 0)
3627		    (const_int 0)))]
3628  ""
3629  [(set_attr "type" "logical")
3630   (set_attr "dot" "yes")
3631   (set_attr "length" "4,8")])
3632
3633
3634(define_insn "*boolc<mode>3"
3635  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3636	(match_operator:GPR 3 "boolean_operator"
3637	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3638	  (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3639  ""
3640  "%q3 %0,%1,%2"
3641  [(set_attr "type" "logical")])
3642
3643(define_insn_and_split "*boolc<mode>3_dot"
3644  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3645	(compare:CC (match_operator:GPR 3 "boolean_operator"
3646	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3647	  (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3648	 (const_int 0)))
3649   (clobber (match_scratch:GPR 0 "=r,r"))]
3650  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3651  "@
3652   %q3. %0,%1,%2
3653   #"
3654  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3655  [(set (match_dup 0)
3656	(match_dup 3))
3657   (set (match_dup 4)
3658	(compare:CC (match_dup 0)
3659		    (const_int 0)))]
3660  ""
3661  [(set_attr "type" "logical")
3662   (set_attr "dot" "yes")
3663   (set_attr "length" "4,8")])
3664
3665(define_insn_and_split "*boolc<mode>3_dot2"
3666  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3667	(compare:CC (match_operator:GPR 3 "boolean_operator"
3668	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3669	  (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3670	 (const_int 0)))
3671   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3672	(match_dup 3))]
3673  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3674  "@
3675   %q3. %0,%1,%2
3676   #"
3677  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3678  [(set (match_dup 0)
3679	(match_dup 3))
3680   (set (match_dup 4)
3681	(compare:CC (match_dup 0)
3682		    (const_int 0)))]
3683  ""
3684  [(set_attr "type" "logical")
3685   (set_attr "dot" "yes")
3686   (set_attr "length" "4,8")])
3687
3688
3689(define_insn "*boolcc<mode>3"
3690  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3691	(match_operator:GPR 3 "boolean_operator"
3692	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3693	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3694  ""
3695  "%q3 %0,%1,%2"
3696  [(set_attr "type" "logical")])
3697
3698(define_insn_and_split "*boolcc<mode>3_dot"
3699  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3700	(compare:CC (match_operator:GPR 3 "boolean_operator"
3701	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3702	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3703	 (const_int 0)))
3704   (clobber (match_scratch:GPR 0 "=r,r"))]
3705  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3706  "@
3707   %q3. %0,%1,%2
3708   #"
3709  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3710  [(set (match_dup 0)
3711	(match_dup 3))
3712   (set (match_dup 4)
3713	(compare:CC (match_dup 0)
3714		    (const_int 0)))]
3715  ""
3716  [(set_attr "type" "logical")
3717   (set_attr "dot" "yes")
3718   (set_attr "length" "4,8")])
3719
3720(define_insn_and_split "*boolcc<mode>3_dot2"
3721  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3722	(compare:CC (match_operator:GPR 3 "boolean_operator"
3723	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3724	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3725	 (const_int 0)))
3726   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3727	(match_dup 3))]
3728  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3729  "@
3730   %q3. %0,%1,%2
3731   #"
3732  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3733  [(set (match_dup 0)
3734	(match_dup 3))
3735   (set (match_dup 4)
3736	(compare:CC (match_dup 0)
3737		    (const_int 0)))]
3738  ""
3739  [(set_attr "type" "logical")
3740   (set_attr "dot" "yes")
3741   (set_attr "length" "4,8")])
3742
3743
3744;; TODO: Should have dots of this as well.
3745(define_insn "*eqv<mode>3"
3746  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3747	(not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3748			  (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3749  ""
3750  "eqv %0,%1,%2"
3751  [(set_attr "type" "logical")])
3752
3753;; Rotate-and-mask and insert.
3754
3755(define_insn "*rotl<mode>3_mask"
3756  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3757	(and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3758		  [(match_operand:GPR 1 "gpc_reg_operand" "r")
3759		   (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3760		 (match_operand:GPR 3 "const_int_operand" "n")))]
3761  "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3762{
3763  return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3764}
3765  [(set_attr "type" "shift")
3766   (set_attr "maybe_var_shift" "yes")])
3767
3768(define_insn_and_split "*rotl<mode>3_mask_dot"
3769  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3770	(compare:CC
3771	  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3772		    [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3773		     (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3774		   (match_operand:GPR 3 "const_int_operand" "n,n"))
3775	  (const_int 0)))
3776   (clobber (match_scratch:GPR 0 "=r,r"))]
3777  "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3778   && rs6000_gen_cell_microcode
3779   && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3780{
3781  if (which_alternative == 0)
3782    return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3783  else
3784    return "#";
3785}
3786  "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3787  [(set (match_dup 0)
3788	(and:GPR (match_dup 4)
3789		 (match_dup 3)))
3790   (set (match_dup 5)
3791	(compare:CC (match_dup 0)
3792		    (const_int 0)))]
3793  ""
3794  [(set_attr "type" "shift")
3795   (set_attr "maybe_var_shift" "yes")
3796   (set_attr "dot" "yes")
3797   (set_attr "length" "4,8")])
3798
3799(define_insn_and_split "*rotl<mode>3_mask_dot2"
3800  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3801	(compare:CC
3802	  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3803		    [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3804		     (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3805		   (match_operand:GPR 3 "const_int_operand" "n,n"))
3806	  (const_int 0)))
3807   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3808	(and:GPR (match_dup 4)
3809		 (match_dup 3)))]
3810  "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3811   && rs6000_gen_cell_microcode
3812   && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3813{
3814  if (which_alternative == 0)
3815    return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3816  else
3817    return "#";
3818}
3819  "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3820  [(set (match_dup 0)
3821	(and:GPR (match_dup 4)
3822		 (match_dup 3)))
3823   (set (match_dup 5)
3824	(compare:CC (match_dup 0)
3825		    (const_int 0)))]
3826  ""
3827  [(set_attr "type" "shift")
3828   (set_attr "maybe_var_shift" "yes")
3829   (set_attr "dot" "yes")
3830   (set_attr "length" "4,8")])
3831
3832; Special case for less-than-0.  We can do it with just one machine
3833; instruction, but the generic optimizers do not realise it is cheap.
3834(define_insn "*lt0_disi"
3835  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3836	(lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3837	       (const_int 0)))]
3838  "TARGET_POWERPC64"
3839  "rlwinm %0,%1,1,31,31"
3840  [(set_attr "type" "shift")])
3841
3842
3843
3844; Two forms for insert (the two arms of the IOR are not canonicalized,
3845; both are an AND so are the same precedence).
3846(define_insn "*rotl<mode>3_insert"
3847  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3848	(ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3849			   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3850			    (match_operand:SI 2 "const_int_operand" "n")])
3851			  (match_operand:GPR 3 "const_int_operand" "n"))
3852		 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3853			  (match_operand:GPR 6 "const_int_operand" "n"))))]
3854  "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3855   && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3856{
3857  return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3858}
3859  [(set_attr "type" "insert")])
3860; FIXME: this needs an attr "size", so that the scheduler can see the
3861; difference between rlwimi and rldimi.  We also might want dot forms,
3862; but not for rlwimi on POWER4 and similar processors.
3863
3864(define_insn "*rotl<mode>3_insert_2"
3865  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866	(ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3867			  (match_operand:GPR 6 "const_int_operand" "n"))
3868		 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3869			   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3870			    (match_operand:SI 2 "const_int_operand" "n")])
3871			  (match_operand:GPR 3 "const_int_operand" "n"))))]
3872  "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3873   && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3874{
3875  return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3876}
3877  [(set_attr "type" "insert")])
3878
3879; There are also some forms without one of the ANDs.
3880(define_insn "*rotl<mode>3_insert_3"
3881  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3882	(ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3883			  (match_operand:GPR 4 "const_int_operand" "n"))
3884		 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3885			     (match_operand:SI 2 "const_int_operand" "n"))))]
3886  "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3887{
3888  if (<MODE>mode == SImode)
3889    return "rlwimi %0,%1,%h2,0,31-%h2";
3890  else
3891    return "rldimi %0,%1,%H2,0";
3892}
3893  [(set_attr "type" "insert")])
3894
3895(define_insn "*rotl<mode>3_insert_4"
3896  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3897	(ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3898			  (match_operand:GPR 4 "const_int_operand" "n"))
3899		 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3900			       (match_operand:SI 2 "const_int_operand" "n"))))]
3901  "<MODE>mode == SImode &&
3902   GET_MODE_PRECISION (<MODE>mode)
3903   == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3904{
3905  operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3906			 - INTVAL (operands[2]));
3907  if (<MODE>mode == SImode)
3908    return "rlwimi %0,%1,%h2,32-%h2,31";
3909  else
3910    return "rldimi %0,%1,%H2,64-%H2";
3911}
3912  [(set_attr "type" "insert")])
3913
3914(define_insn "*rotlsi3_insert_5"
3915  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3916	(ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3917			(match_operand:SI 2 "const_int_operand" "n,n"))
3918		(and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3919			(match_operand:SI 4 "const_int_operand" "n,n"))))]
3920  "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3921   && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3922   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3923  "@
3924   rlwimi %0,%3,0,%4
3925   rlwimi %0,%1,0,%2"
3926  [(set_attr "type" "insert")])
3927
3928(define_insn "*rotldi3_insert_6"
3929  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3930	(ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3931			(match_operand:DI 2 "const_int_operand" "n"))
3932		(and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3933			(match_operand:DI 4 "const_int_operand" "n"))))]
3934  "exact_log2 (-UINTVAL (operands[2])) > 0
3935   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3936{
3937  operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3938  return "rldimi %0,%3,0,%5";
3939}
3940  [(set_attr "type" "insert")
3941   (set_attr "size" "64")])
3942
3943(define_insn "*rotldi3_insert_7"
3944  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3945	(ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3946			(match_operand:DI 4 "const_int_operand" "n"))
3947		(and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3948			(match_operand:DI 2 "const_int_operand" "n"))))]
3949  "exact_log2 (-UINTVAL (operands[2])) > 0
3950   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3951{
3952  operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3953  return "rldimi %0,%3,0,%5";
3954}
3955  [(set_attr "type" "insert")
3956   (set_attr "size" "64")])
3957
3958
3959; This handles the important case of multiple-precision shifts.  There is
3960; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3961(define_split
3962  [(set (match_operand:GPR 0 "gpc_reg_operand")
3963	(ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3964			     (match_operand:SI 3 "const_int_operand"))
3965		 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3966			       (match_operand:SI 4 "const_int_operand"))))]
3967  "can_create_pseudo_p ()
3968   && INTVAL (operands[3]) + INTVAL (operands[4])
3969      >= GET_MODE_PRECISION (<MODE>mode)"
3970  [(set (match_dup 5)
3971	(lshiftrt:GPR (match_dup 2)
3972		      (match_dup 4)))
3973   (set (match_dup 0)
3974	(ior:GPR (and:GPR (match_dup 5)
3975			  (match_dup 6))
3976		 (ashift:GPR (match_dup 1)
3977			     (match_dup 3))))]
3978{
3979  unsigned HOST_WIDE_INT mask = 1;
3980  mask = (mask << INTVAL (operands[3])) - 1;
3981  operands[5] = gen_reg_rtx (<MODE>mode);
3982  operands[6] = GEN_INT (mask);
3983})
3984
3985(define_split
3986  [(set (match_operand:GPR 0 "gpc_reg_operand")
3987	(ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3988			       (match_operand:SI 4 "const_int_operand"))
3989		 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3990			     (match_operand:SI 3 "const_int_operand"))))]
3991  "can_create_pseudo_p ()
3992   && INTVAL (operands[3]) + INTVAL (operands[4])
3993      >= GET_MODE_PRECISION (<MODE>mode)"
3994  [(set (match_dup 5)
3995	(lshiftrt:GPR (match_dup 2)
3996		      (match_dup 4)))
3997   (set (match_dup 0)
3998	(ior:GPR (and:GPR (match_dup 5)
3999			  (match_dup 6))
4000		 (ashift:GPR (match_dup 1)
4001			     (match_dup 3))))]
4002{
4003  unsigned HOST_WIDE_INT mask = 1;
4004  mask = (mask << INTVAL (operands[3])) - 1;
4005  operands[5] = gen_reg_rtx (<MODE>mode);
4006  operands[6] = GEN_INT (mask);
4007})
4008
4009
4010; Another important case is setting some bits to 1; we can do that with
4011; an insert instruction, in many cases.
4012(define_insn_and_split "*ior<mode>_mask"
4013  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4014	(ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4015		 (match_operand:GPR 2 "const_int_operand" "n")))
4016   (clobber (match_scratch:GPR 3 "=r"))]
4017  "!logical_const_operand (operands[2], <MODE>mode)
4018   && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4019  "#"
4020  "&& 1"
4021  [(set (match_dup 3)
4022	(const_int -1))
4023   (set (match_dup 0)
4024	(ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4025				      (match_dup 4))
4026			  (match_dup 2))
4027		 (and:GPR (match_dup 1)
4028			  (match_dup 5))))]
4029{
4030  int nb, ne;
4031  rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4032  if (GET_CODE (operands[3]) == SCRATCH)
4033    operands[3] = gen_reg_rtx (<MODE>mode);
4034  operands[4] = GEN_INT (ne);
4035  operands[5] = GEN_INT (~UINTVAL (operands[2]));
4036}
4037  [(set_attr "type" "two")
4038   (set_attr "length" "8")])
4039
4040
4041;; Now the simple shifts.
4042
4043(define_insn "rotl<mode>3"
4044  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4045	(rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4046		    (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4047  ""
4048  "rotl<wd>%I2 %0,%1,%<hH>2"
4049  [(set_attr "type" "shift")
4050   (set_attr "maybe_var_shift" "yes")])
4051
4052(define_insn "*rotlsi3_64"
4053  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4054	(zero_extend:DI
4055	    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4056		       (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4057  "TARGET_POWERPC64"
4058  "rotlw%I2 %0,%1,%h2"
4059  [(set_attr "type" "shift")
4060   (set_attr "maybe_var_shift" "yes")])
4061
4062(define_insn_and_split "*rotl<mode>3_dot"
4063  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4064	(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4065				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4066		    (const_int 0)))
4067   (clobber (match_scratch:GPR 0 "=r,r"))]
4068  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4069  "@
4070   rotl<wd>%I2. %0,%1,%<hH>2
4071   #"
4072  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4073  [(set (match_dup 0)
4074	(rotate:GPR (match_dup 1)
4075		    (match_dup 2)))
4076   (set (match_dup 3)
4077	(compare:CC (match_dup 0)
4078		    (const_int 0)))]
4079  ""
4080  [(set_attr "type" "shift")
4081   (set_attr "maybe_var_shift" "yes")
4082   (set_attr "dot" "yes")
4083   (set_attr "length" "4,8")])
4084
4085(define_insn_and_split "*rotl<mode>3_dot2"
4086  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4087	(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4088				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4089		    (const_int 0)))
4090   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4091	(rotate:GPR (match_dup 1)
4092		    (match_dup 2)))]
4093  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4094  "@
4095   rotl<wd>%I2. %0,%1,%<hH>2
4096   #"
4097  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4098  [(set (match_dup 0)
4099	(rotate:GPR (match_dup 1)
4100		    (match_dup 2)))
4101   (set (match_dup 3)
4102	(compare:CC (match_dup 0)
4103		    (const_int 0)))]
4104  ""
4105  [(set_attr "type" "shift")
4106   (set_attr "maybe_var_shift" "yes")
4107   (set_attr "dot" "yes")
4108   (set_attr "length" "4,8")])
4109
4110
4111(define_insn "ashl<mode>3"
4112  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4113	(ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4114		    (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4115  ""
4116  "sl<wd>%I2 %0,%1,%<hH>2"
4117  [(set_attr "type" "shift")
4118   (set_attr "maybe_var_shift" "yes")])
4119
4120(define_insn "*ashlsi3_64"
4121  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4122	(zero_extend:DI
4123	    (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4124		       (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4125  "TARGET_POWERPC64"
4126  "slw%I2 %0,%1,%h2"
4127  [(set_attr "type" "shift")
4128   (set_attr "maybe_var_shift" "yes")])
4129
4130(define_insn_and_split "*ashl<mode>3_dot"
4131  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4132	(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4133				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4134		    (const_int 0)))
4135   (clobber (match_scratch:GPR 0 "=r,r"))]
4136  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4137  "@
4138   sl<wd>%I2. %0,%1,%<hH>2
4139   #"
4140  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4141  [(set (match_dup 0)
4142	(ashift:GPR (match_dup 1)
4143		    (match_dup 2)))
4144   (set (match_dup 3)
4145	(compare:CC (match_dup 0)
4146		    (const_int 0)))]
4147  ""
4148  [(set_attr "type" "shift")
4149   (set_attr "maybe_var_shift" "yes")
4150   (set_attr "dot" "yes")
4151   (set_attr "length" "4,8")])
4152
4153(define_insn_and_split "*ashl<mode>3_dot2"
4154  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4155	(compare:CC (ashift: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   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4159	(ashift:GPR (match_dup 1)
4160		    (match_dup 2)))]
4161  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4162  "@
4163   sl<wd>%I2. %0,%1,%<hH>2
4164   #"
4165  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4166  [(set (match_dup 0)
4167	(ashift:GPR (match_dup 1)
4168		    (match_dup 2)))
4169   (set (match_dup 3)
4170	(compare:CC (match_dup 0)
4171		    (const_int 0)))]
4172  ""
4173  [(set_attr "type" "shift")
4174   (set_attr "maybe_var_shift" "yes")
4175   (set_attr "dot" "yes")
4176   (set_attr "length" "4,8")])
4177
4178;; Pretend we have a memory form of extswsli until register allocation is done
4179;; so that we use LWZ to load the value from memory, instead of LWA.
4180(define_insn_and_split "ashdi3_extswsli"
4181  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4182	(ashift:DI
4183	 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4184	 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4185  "TARGET_EXTSWSLI"
4186  "@
4187   extswsli %0,%1,%2
4188   #"
4189  "&& reload_completed && MEM_P (operands[1])"
4190  [(set (match_dup 3)
4191	(match_dup 1))
4192   (set (match_dup 0)
4193	(ashift:DI (sign_extend:DI (match_dup 3))
4194		   (match_dup 2)))]
4195{
4196  operands[3] = gen_lowpart (SImode, operands[0]);
4197}
4198  [(set_attr "type" "shift")
4199   (set_attr "maybe_var_shift" "no")])
4200
4201
4202(define_insn_and_split "ashdi3_extswsli_dot"
4203  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4204	(compare:CC
4205	 (ashift:DI
4206	  (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4207	  (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4208	 (const_int 0)))
4209   (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4210  "TARGET_EXTSWSLI"
4211  "@
4212   extswsli. %0,%1,%2
4213   #
4214   #
4215   #"
4216  "&& reload_completed
4217   && (cc_reg_not_cr0_operand (operands[3], CCmode)
4218       || memory_operand (operands[1], SImode))"
4219  [(pc)]
4220{
4221  rtx dest = operands[0];
4222  rtx src = operands[1];
4223  rtx shift = operands[2];
4224  rtx cr = operands[3];
4225  rtx src2;
4226
4227  if (!MEM_P (src))
4228    src2 = src;
4229  else
4230    {
4231      src2 = gen_lowpart (SImode, dest);
4232      emit_move_insn (src2, src);
4233    }
4234
4235  if (REGNO (cr) == CR0_REGNO)
4236    {
4237      emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4238      DONE;
4239    }
4240
4241  emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4242  emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4243  DONE;
4244}
4245  [(set_attr "type" "shift")
4246   (set_attr "maybe_var_shift" "no")
4247   (set_attr "dot" "yes")
4248   (set_attr "length" "4,8,8,12")])
4249
4250(define_insn_and_split "ashdi3_extswsli_dot2"
4251  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4252	(compare:CC
4253	 (ashift:DI
4254	  (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4255	  (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4256	 (const_int 0)))
4257   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4258	(ashift:DI (sign_extend:DI (match_dup 1))
4259		   (match_dup 2)))]
4260  "TARGET_EXTSWSLI"
4261  "@
4262   extswsli. %0,%1,%2
4263   #
4264   #
4265   #"
4266  "&& reload_completed
4267   && (cc_reg_not_cr0_operand (operands[3], CCmode)
4268       || memory_operand (operands[1], SImode))"
4269  [(pc)]
4270{
4271  rtx dest = operands[0];
4272  rtx src = operands[1];
4273  rtx shift = operands[2];
4274  rtx cr = operands[3];
4275  rtx src2;
4276
4277  if (!MEM_P (src))
4278    src2 = src;
4279  else
4280    {
4281      src2 = gen_lowpart (SImode, dest);
4282      emit_move_insn (src2, src);
4283    }
4284
4285  if (REGNO (cr) == CR0_REGNO)
4286    {
4287      emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4288      DONE;
4289    }
4290
4291  emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4292  emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4293  DONE;
4294}
4295  [(set_attr "type" "shift")
4296   (set_attr "maybe_var_shift" "no")
4297   (set_attr "dot" "yes")
4298   (set_attr "length" "4,8,8,12")])
4299
4300(define_insn "lshr<mode>3"
4301  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4302	(lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4303		      (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4304  ""
4305  "sr<wd>%I2 %0,%1,%<hH>2"
4306  [(set_attr "type" "shift")
4307   (set_attr "maybe_var_shift" "yes")])
4308
4309(define_insn "*lshrsi3_64"
4310  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4311	(zero_extend:DI
4312	    (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4313			 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4314  "TARGET_POWERPC64"
4315  "srw%I2 %0,%1,%h2"
4316  [(set_attr "type" "shift")
4317   (set_attr "maybe_var_shift" "yes")])
4318
4319(define_insn_and_split "*lshr<mode>3_dot"
4320  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4321	(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4322				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4323		    (const_int 0)))
4324   (clobber (match_scratch:GPR 0 "=r,r"))]
4325  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4326  "@
4327   sr<wd>%I2. %0,%1,%<hH>2
4328   #"
4329  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4330  [(set (match_dup 0)
4331	(lshiftrt:GPR (match_dup 1)
4332		      (match_dup 2)))
4333   (set (match_dup 3)
4334	(compare:CC (match_dup 0)
4335		    (const_int 0)))]
4336  ""
4337  [(set_attr "type" "shift")
4338   (set_attr "maybe_var_shift" "yes")
4339   (set_attr "dot" "yes")
4340   (set_attr "length" "4,8")])
4341
4342(define_insn_and_split "*lshr<mode>3_dot2"
4343  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4344	(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4345				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4346		    (const_int 0)))
4347   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4348	(lshiftrt:GPR (match_dup 1)
4349		      (match_dup 2)))]
4350  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4351  "@
4352   sr<wd>%I2. %0,%1,%<hH>2
4353   #"
4354  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4355  [(set (match_dup 0)
4356	(lshiftrt:GPR (match_dup 1)
4357		      (match_dup 2)))
4358   (set (match_dup 3)
4359	(compare:CC (match_dup 0)
4360		    (const_int 0)))]
4361  ""
4362  [(set_attr "type" "shift")
4363   (set_attr "maybe_var_shift" "yes")
4364   (set_attr "dot" "yes")
4365   (set_attr "length" "4,8")])
4366
4367
4368(define_insn "ashr<mode>3"
4369  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4370	(ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4371		      (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4372   (clobber (reg:GPR CA_REGNO))]
4373  ""
4374  "sra<wd>%I2 %0,%1,%<hH>2"
4375  [(set_attr "type" "shift")
4376   (set_attr "maybe_var_shift" "yes")])
4377
4378(define_insn "*ashrsi3_64"
4379  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4380	(sign_extend:DI
4381	    (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4382			 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4383   (clobber (reg:SI CA_REGNO))]
4384  "TARGET_POWERPC64"
4385  "sraw%I2 %0,%1,%h2"
4386  [(set_attr "type" "shift")
4387   (set_attr "maybe_var_shift" "yes")])
4388
4389(define_insn_and_split "*ashr<mode>3_dot"
4390  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4391	(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4392				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4393		    (const_int 0)))
4394   (clobber (match_scratch:GPR 0 "=r,r"))
4395   (clobber (reg:GPR CA_REGNO))]
4396  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4397  "@
4398   sra<wd>%I2. %0,%1,%<hH>2
4399   #"
4400  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4401  [(parallel [(set (match_dup 0)
4402		   (ashiftrt:GPR (match_dup 1)
4403				 (match_dup 2)))
4404	      (clobber (reg:GPR CA_REGNO))])
4405   (set (match_dup 3)
4406	(compare:CC (match_dup 0)
4407		    (const_int 0)))]
4408  ""
4409  [(set_attr "type" "shift")
4410   (set_attr "maybe_var_shift" "yes")
4411   (set_attr "dot" "yes")
4412   (set_attr "length" "4,8")])
4413
4414(define_insn_and_split "*ashr<mode>3_dot2"
4415  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4416	(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4417				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4418		    (const_int 0)))
4419   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4420	(ashiftrt:GPR (match_dup 1)
4421		      (match_dup 2)))
4422   (clobber (reg:GPR CA_REGNO))]
4423  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4424  "@
4425   sra<wd>%I2. %0,%1,%<hH>2
4426   #"
4427  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4428  [(parallel [(set (match_dup 0)
4429		   (ashiftrt:GPR (match_dup 1)
4430				 (match_dup 2)))
4431	      (clobber (reg:GPR CA_REGNO))])
4432   (set (match_dup 3)
4433	(compare:CC (match_dup 0)
4434		    (const_int 0)))]
4435  ""
4436  [(set_attr "type" "shift")
4437   (set_attr "maybe_var_shift" "yes")
4438   (set_attr "dot" "yes")
4439   (set_attr "length" "4,8")])
4440
4441;; Builtins to replace a division to generate FRE reciprocal estimate
4442;; instructions and the necessary fixup instructions
4443(define_expand "recip<mode>3"
4444  [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4445   (match_operand:RECIPF 1 "gpc_reg_operand" "")
4446   (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4447  "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4448{
4449   rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4450   DONE;
4451})
4452
4453;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4454;; hardware division.  This is only done before register allocation and with
4455;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4456;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4457;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4458(define_split
4459  [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4460	(div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4461		    (match_operand 2 "gpc_reg_operand" "")))]
4462  "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4463   && can_create_pseudo_p () && flag_finite_math_only
4464   && !flag_trapping_math && flag_reciprocal_math"
4465  [(const_int 0)]
4466{
4467  rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4468  DONE;
4469})
4470
4471;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4472;; appropriate fixup.
4473(define_expand "rsqrt<mode>2"
4474  [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4475   (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4476  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4477{
4478  rs6000_emit_swsqrt (operands[0], operands[1], 1);
4479  DONE;
4480})
4481
4482;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4483;; modes here, and also add in conditional vsx/power8-vector support to access
4484;; values in the traditional Altivec registers if the appropriate
4485;; -mupper-regs-{df,sf} option is enabled.
4486
4487(define_expand "abs<mode>2"
4488  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4489	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4490  "TARGET_<MODE>_INSN"
4491  "")
4492
4493(define_insn "*abs<mode>2_fpr"
4494  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4495	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4496  "TARGET_<MODE>_FPR"
4497  "@
4498   fabs %0,%1
4499   xsabsdp %x0,%x1"
4500  [(set_attr "type" "fpsimple")
4501   (set_attr "fp_type" "fp_addsub_<Fs>")])
4502
4503(define_insn "*nabs<mode>2_fpr"
4504  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4505	(neg:SFDF
4506	 (abs:SFDF
4507	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4508  "TARGET_<MODE>_FPR"
4509  "@
4510   fnabs %0,%1
4511   xsnabsdp %x0,%x1"
4512  [(set_attr "type" "fpsimple")
4513   (set_attr "fp_type" "fp_addsub_<Fs>")])
4514
4515(define_expand "neg<mode>2"
4516  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4517	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4518  "TARGET_<MODE>_INSN"
4519  "")
4520
4521(define_insn "*neg<mode>2_fpr"
4522  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4523	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4524  "TARGET_<MODE>_FPR"
4525  "@
4526   fneg %0,%1
4527   xsnegdp %x0,%x1"
4528  [(set_attr "type" "fpsimple")
4529   (set_attr "fp_type" "fp_addsub_<Fs>")])
4530
4531(define_expand "add<mode>3"
4532  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4533	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4534		   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4535  "TARGET_<MODE>_INSN"
4536  "")
4537
4538(define_insn "*add<mode>3_fpr"
4539  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4540	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4541		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4542  "TARGET_<MODE>_FPR"
4543  "@
4544   fadd<Ftrad> %0,%1,%2
4545   xsadd<Fvsx> %x0,%x1,%x2"
4546  [(set_attr "type" "fp")
4547   (set_attr "fp_type" "fp_addsub_<Fs>")])
4548
4549(define_expand "sub<mode>3"
4550  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4551	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4552		    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4553  "TARGET_<MODE>_INSN"
4554  "")
4555
4556(define_insn "*sub<mode>3_fpr"
4557  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4558	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4559		    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4560  "TARGET_<MODE>_FPR"
4561  "@
4562   fsub<Ftrad> %0,%1,%2
4563   xssub<Fvsx> %x0,%x1,%x2"
4564  [(set_attr "type" "fp")
4565   (set_attr "fp_type" "fp_addsub_<Fs>")])
4566
4567(define_expand "mul<mode>3"
4568  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4569	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4570		   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4571  "TARGET_<MODE>_INSN"
4572  "")
4573
4574(define_insn "*mul<mode>3_fpr"
4575  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4576	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4577		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4578  "TARGET_<MODE>_FPR"
4579  "@
4580   fmul<Ftrad> %0,%1,%2
4581   xsmul<Fvsx> %x0,%x1,%x2"
4582  [(set_attr "type" "dmul")
4583   (set_attr "fp_type" "fp_mul_<Fs>")])
4584
4585(define_expand "div<mode>3"
4586  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4587	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4588		  (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4589  "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4590{
4591  if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4592      && can_create_pseudo_p () && flag_finite_math_only
4593      && !flag_trapping_math && flag_reciprocal_math)
4594    {
4595      rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4596      DONE;
4597    }
4598})
4599
4600(define_insn "*div<mode>3_fpr"
4601  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4602	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4603		  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4604  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4605  "@
4606   fdiv<Ftrad> %0,%1,%2
4607   xsdiv<Fvsx> %x0,%x1,%x2"
4608  [(set_attr "type" "<Fs>div")
4609   (set_attr "fp_type" "fp_div_<Fs>")])
4610
4611(define_insn "*sqrt<mode>2_internal"
4612  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4613	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4614  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4615   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4616  "@
4617   fsqrt<Ftrad> %0,%1
4618   xssqrt<Fvsx> %x0,%x1"
4619  [(set_attr "type" "<Fs>sqrt")
4620   (set_attr "fp_type" "fp_sqrt_<Fs>")])
4621
4622(define_expand "sqrt<mode>2"
4623  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4624	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4625  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4626   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4627{
4628  if (<MODE>mode == SFmode
4629      && TARGET_RECIP_PRECISION
4630      && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4631      && !optimize_function_for_size_p (cfun)
4632      && flag_finite_math_only && !flag_trapping_math
4633      && flag_unsafe_math_optimizations)
4634    {
4635      rs6000_emit_swsqrt (operands[0], operands[1], 0);
4636      DONE;
4637    }
4638})
4639
4640;; Floating point reciprocal approximation
4641(define_insn "fre<Fs>"
4642  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4643	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4644		     UNSPEC_FRES))]
4645  "TARGET_<FFRE>"
4646  "@
4647   fre<Ftrad> %0,%1
4648   xsre<Fvsx> %x0,%x1"
4649  [(set_attr "type" "fp")])
4650
4651(define_insn "*rsqrt<mode>2"
4652  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4653	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4654		     UNSPEC_RSQRT))]
4655  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4656  "@
4657   frsqrte<Ftrad> %0,%1
4658   xsrsqrte<Fvsx> %x0,%x1"
4659  [(set_attr "type" "fp")])
4660
4661;; Floating point comparisons
4662(define_insn "*cmp<mode>_fpr"
4663  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4664	(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4665		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4666  "TARGET_<MODE>_FPR"
4667  "@
4668   fcmpu %0,%1,%2
4669   xscmpudp %0,%x1,%x2"
4670  [(set_attr "type" "fpcompare")])
4671
4672;; Floating point conversions
4673(define_expand "extendsfdf2"
4674  [(set (match_operand:DF 0 "gpc_reg_operand")
4675	(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand")))]
4676  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4677{
4678  if (HONOR_SNANS (SFmode))
4679    operands[1] = force_reg (SFmode, operands[1]);
4680})
4681
4682(define_insn_and_split "*extendsfdf2_fpr"
4683  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4684	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4685  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4686   && !HONOR_SNANS (SFmode)"
4687  "@
4688   #
4689   fmr %0,%1
4690   lfs%U1%X1 %0,%1
4691   #
4692   xscpsgndp %x0,%x1,%x1
4693   lxsspx %x0,%y1
4694   lxssp %0,%1"
4695  "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4696  [(const_int 0)]
4697{
4698  emit_note (NOTE_INSN_DELETED);
4699  DONE;
4700}
4701  [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4702
4703(define_insn "*extendsfdf2_snan"
4704  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4705	(float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4706  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4707   && HONOR_SNANS (SFmode)"
4708  "@
4709   frsp %0,%1
4710   xsrsp %x0,%x1"
4711  [(set_attr "type" "fp")])
4712
4713(define_expand "truncdfsf2"
4714  [(set (match_operand:SF 0 "gpc_reg_operand" "")
4715	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4716  "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4717  "")
4718
4719(define_insn "*truncdfsf2_fpr"
4720  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4721	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4722  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4723  "@
4724   frsp %0,%1
4725   xsrsp %x0,%x1"
4726  [(set_attr "type" "fp")])
4727
4728;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4729;; builtins.c and optabs.c that are not correct for IBM long double
4730;; when little-endian.
4731(define_expand "signbit<mode>2"
4732  [(set (match_dup 2)
4733	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4734   (set (match_dup 3)
4735   	(subreg:DI (match_dup 2) 0))
4736   (set (match_dup 4)
4737   	(match_dup 5))
4738   (set (match_operand:SI 0 "gpc_reg_operand" "")
4739  	(match_dup 6))]
4740  "TARGET_HARD_FLOAT
4741   && (TARGET_FPRS || TARGET_E500_DOUBLE)
4742   && (!FLOAT128_IEEE_P (<MODE>mode)
4743       || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4744{
4745  if (FLOAT128_IEEE_P (<MODE>mode))
4746    {
4747      if (<MODE>mode == KFmode)
4748	emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4749      else if (<MODE>mode == TFmode)
4750	emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4751      else
4752	gcc_unreachable ();
4753      DONE;
4754    }
4755  operands[2] = gen_reg_rtx (DFmode);
4756  operands[3] = gen_reg_rtx (DImode);
4757  if (TARGET_POWERPC64)
4758    {
4759      operands[4] = gen_reg_rtx (DImode);
4760      operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4761      operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4762				    WORDS_BIG_ENDIAN ? 4 : 0);
4763    }
4764  else
4765    {
4766      operands[4] = gen_reg_rtx (SImode);
4767      operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4768				    WORDS_BIG_ENDIAN ? 0 : 4);
4769      operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4770    }
4771})
4772
4773(define_expand "copysign<mode>3"
4774  [(set (match_dup 3)
4775        (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4776   (set (match_dup 4)
4777	(neg:SFDF (abs:SFDF (match_dup 1))))
4778   (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4779        (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4780			       (match_dup 5))
4781			 (match_dup 3)
4782			 (match_dup 4)))]
4783  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4784   && ((TARGET_PPC_GFXOPT
4785        && !HONOR_NANS (<MODE>mode)
4786        && !HONOR_SIGNED_ZEROS (<MODE>mode))
4787       || TARGET_CMPB
4788       || VECTOR_UNIT_VSX_P (<MODE>mode))"
4789{
4790  if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4791    {
4792      emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4793					     operands[2]));
4794      DONE;
4795    }
4796
4797   operands[3] = gen_reg_rtx (<MODE>mode);
4798   operands[4] = gen_reg_rtx (<MODE>mode);
4799   operands[5] = CONST0_RTX (<MODE>mode);
4800  })
4801
4802;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4803;; and load.
4804(define_insn_and_split "signbit<mode>2_dm"
4805  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4806	(unspec:SI
4807	 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4808	 UNSPEC_SIGNBIT))]
4809  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4810  "#"
4811  "&& reload_completed"
4812  [(const_int 0)]
4813{
4814  rs6000_split_signbit (operands[0], operands[1]);
4815  DONE;
4816}
4817 [(set_attr "length" "8,8,4")
4818  (set_attr "type" "mftgpr,load,integer")])
4819
4820(define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4821  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4822	(any_extend:DI
4823	 (unspec:SI
4824	  [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4825	  UNSPEC_SIGNBIT)))]
4826  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4827  "#"
4828  "&& reload_completed"
4829  [(const_int 0)]
4830{
4831  rs6000_split_signbit (operands[0], operands[1]);
4832  DONE;
4833}
4834 [(set_attr "length" "8,8,4")
4835  (set_attr "type" "mftgpr,load,integer")])
4836
4837;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
4838;; floating point types, which makes normal SUBREG's problematical.  Instead
4839;; use a special pattern to avoid using a normal movdi.
4840(define_insn "signbit<mode>2_dm2"
4841  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4842	(unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4843		    (const_int 0)]
4844		   UNSPEC_SIGNBIT))]
4845  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4846  "mfvsrd %0,%x1"
4847 [(set_attr "type" "mftgpr")])
4848
4849
4850;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4851;; compiler from optimizing -0.0
4852(define_insn "copysign<mode>3_fcpsgn"
4853  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4854	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4855		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4856		     UNSPEC_COPYSIGN))]
4857  "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4858  "@
4859   fcpsgn %0,%2,%1
4860   xscpsgndp %x0,%x2,%x1"
4861  [(set_attr "type" "fpsimple")])
4862
4863;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4864;; fsel instruction and some auxiliary computations.  Then we just have a
4865;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4866;; combine.
4867;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4868;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4869;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4870;; define_splits to make them if made by combine.  On VSX machines we have the
4871;; min/max instructions.
4872;;
4873;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4874;; to allow either DF/SF to use only traditional registers.
4875
4876(define_expand "s<minmax><mode>3"
4877  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4878	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4879			(match_operand:SFDF 2 "gpc_reg_operand" "")))]
4880  "TARGET_MINMAX_<MODE>"
4881{
4882  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4883  DONE;
4884})
4885
4886(define_insn "*s<minmax><mode>3_vsx"
4887  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4888	(fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4889			(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4890  "TARGET_VSX && TARGET_<MODE>_FPR"
4891{
4892  return (TARGET_P9_MINMAX
4893	  ? "xs<minmax>cdp %x0,%x1,%x2"
4894	  : "xs<minmax>dp %x0,%x1,%x2");
4895}
4896  [(set_attr "type" "fp")])
4897
4898;; The conditional move instructions allow us to perform max and min operations
4899;; even when we don't have the appropriate max/min instruction using the FSEL
4900;; instruction.
4901
4902(define_insn_and_split "*s<minmax><mode>3_fpr"
4903  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4904	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4905			(match_operand:SFDF 2 "gpc_reg_operand" "")))]
4906  "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4907  "#"
4908  "&& 1"
4909  [(const_int 0)]
4910{
4911  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4912  DONE;
4913})
4914
4915(define_expand "mov<mode>cc"
4916   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4917	 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4918			   (match_operand:GPR 2 "gpc_reg_operand" "")
4919			   (match_operand:GPR 3 "gpc_reg_operand" "")))]
4920  "TARGET_ISEL<sel>"
4921  "
4922{
4923  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4924    DONE;
4925  else
4926    FAIL;
4927}")
4928
4929;; We use the BASE_REGS for the isel input operands because, if rA is
4930;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4931;; because we may switch the operands and rB may end up being rA.
4932;;
4933;; We need 2 patterns: an unsigned and a signed pattern.  We could
4934;; leave out the mode in operand 4 and use one pattern, but reload can
4935;; change the mode underneath our feet and then gets confused trying
4936;; to reload the value.
4937(define_insn "isel_signed_<mode>"
4938  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4939	(if_then_else:GPR
4940	 (match_operator 1 "scc_comparison_operator"
4941			 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4942			  (const_int 0)])
4943	 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4944	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4945  "TARGET_ISEL<sel>"
4946  "*
4947{ return output_isel (operands); }"
4948  [(set_attr "type" "isel")
4949   (set_attr "length" "4")])
4950
4951(define_insn "isel_unsigned_<mode>"
4952  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4953	(if_then_else:GPR
4954	 (match_operator 1 "scc_comparison_operator"
4955			 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4956			  (const_int 0)])
4957	 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4958	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4959  "TARGET_ISEL<sel>"
4960  "*
4961{ return output_isel (operands); }"
4962  [(set_attr "type" "isel")
4963   (set_attr "length" "4")])
4964
4965;; These patterns can be useful for combine; they let combine know that
4966;; isel can handle reversed comparisons so long as the operands are
4967;; registers.
4968
4969(define_insn "*isel_reversed_signed_<mode>"
4970  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4971	(if_then_else:GPR
4972	 (match_operator 1 "scc_rev_comparison_operator"
4973			 [(match_operand:CC 4 "cc_reg_operand" "y")
4974			  (const_int 0)])
4975	 (match_operand:GPR 2 "gpc_reg_operand" "b")
4976	 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4977  "TARGET_ISEL<sel>"
4978  "*
4979{ return output_isel (operands); }"
4980  [(set_attr "type" "isel")
4981   (set_attr "length" "4")])
4982
4983(define_insn "*isel_reversed_unsigned_<mode>"
4984  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4985	(if_then_else:GPR
4986	 (match_operator 1 "scc_rev_comparison_operator"
4987			 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4988			  (const_int 0)])
4989	 (match_operand:GPR 2 "gpc_reg_operand" "b")
4990	 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4991  "TARGET_ISEL<sel>"
4992  "*
4993{ return output_isel (operands); }"
4994  [(set_attr "type" "isel")
4995   (set_attr "length" "4")])
4996
4997;; Floating point conditional move
4998(define_expand "mov<mode>cc"
4999   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5000	 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
5001			    (match_operand:SFDF 2 "gpc_reg_operand" "")
5002			    (match_operand:SFDF 3 "gpc_reg_operand" "")))]
5003  "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5004  "
5005{
5006  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5007    DONE;
5008  else
5009    FAIL;
5010}")
5011
5012(define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5013  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5014	(if_then_else:SFDF
5015	 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5016	     (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5017	 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5018	 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5019  "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5020  "fsel %0,%1,%2,%3"
5021  [(set_attr "type" "fp")])
5022
5023(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5024  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5025	(if_then_else:SFDF
5026	 (match_operator:CCFP 1 "fpmask_comparison_operator"
5027		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5028		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5029	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5030	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5031   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5032  "TARGET_P9_MINMAX"
5033  "#"
5034  ""
5035  [(set (match_dup 6)
5036	(if_then_else:V2DI (match_dup 1)
5037			   (match_dup 7)
5038			   (match_dup 8)))
5039   (set (match_dup 0)
5040	(if_then_else:SFDF (ne (match_dup 6)
5041			       (match_dup 8))
5042			   (match_dup 4)
5043			   (match_dup 5)))]
5044{
5045  if (GET_CODE (operands[6]) == SCRATCH)
5046    operands[6] = gen_reg_rtx (V2DImode);
5047
5048  operands[7] = CONSTM1_RTX (V2DImode);
5049  operands[8] = CONST0_RTX (V2DImode);
5050}
5051 [(set_attr "length" "8")
5052  (set_attr "type" "vecperm")])
5053
5054;; Handle inverting the fpmask comparisons.
5055(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5056  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5057	(if_then_else:SFDF
5058	 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5059		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5060		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5061	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5062	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5063   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5064  "TARGET_P9_MINMAX"
5065  "#"
5066  "&& 1"
5067  [(set (match_dup 6)
5068	(if_then_else:V2DI (match_dup 9)
5069			   (match_dup 7)
5070			   (match_dup 8)))
5071   (set (match_dup 0)
5072	(if_then_else:SFDF (ne (match_dup 6)
5073			       (match_dup 8))
5074			   (match_dup 5)
5075			   (match_dup 4)))]
5076{
5077  rtx op1 = operands[1];
5078  enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5079
5080  if (GET_CODE (operands[6]) == SCRATCH)
5081    operands[6] = gen_reg_rtx (V2DImode);
5082
5083  operands[7] = CONSTM1_RTX (V2DImode);
5084  operands[8] = CONST0_RTX (V2DImode);
5085
5086  operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5087}
5088 [(set_attr "length" "8")
5089  (set_attr "type" "vecperm")])
5090
5091(define_insn "*fpmask<mode>"
5092  [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5093	(if_then_else:V2DI
5094	 (match_operator:CCFP 1 "fpmask_comparison_operator"
5095		[(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5096		 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5097	 (match_operand:V2DI 4 "all_ones_constant" "")
5098	 (match_operand:V2DI 5 "zero_constant" "")))]
5099  "TARGET_P9_MINMAX"
5100  "xscmp%V1dp %x0,%x2,%x3"
5101  [(set_attr "type" "fpcompare")])
5102
5103(define_insn "*xxsel<mode>"
5104  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5105	(if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5106			       (match_operand:V2DI 2 "zero_constant" ""))
5107			   (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5108			   (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5109  "TARGET_P9_MINMAX"
5110  "xxsel %x0,%x4,%x3,%x1"
5111  [(set_attr "type" "vecmove")])
5112
5113
5114;; Conversions to and from floating-point.
5115
5116; We don't define lfiwax/lfiwzx with the normal definition, because we
5117; don't want to support putting SImode in FPR registers.
5118(define_insn "lfiwax"
5119  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5120	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5121		   UNSPEC_LFIWAX))]
5122  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5123  "@
5124   lfiwax %0,%y1
5125   lxsiwax %x0,%y1
5126   mtvsrwa %x0,%1
5127   vextsw2d %0,%1"
5128  [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5129
5130; This split must be run before register allocation because it allocates the
5131; memory slot that is needed to move values to/from the FPR.  We don't allocate
5132; it earlier to allow for the combiner to merge insns together where it might
5133; not be needed and also in case the insns are deleted as dead code.
5134
5135(define_insn_and_split "floatsi<mode>2_lfiwax"
5136  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5137	(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5138   (clobber (match_scratch:DI 2 "=wi"))]
5139  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5140   && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5141  "#"
5142  ""
5143  [(pc)]
5144  "
5145{
5146  rtx dest = operands[0];
5147  rtx src = operands[1];
5148  rtx tmp;
5149
5150  if (!MEM_P (src) && TARGET_POWERPC64
5151      && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5152    tmp = convert_to_mode (DImode, src, false);
5153  else
5154    {
5155      tmp = operands[2];
5156      if (GET_CODE (tmp) == SCRATCH)
5157	tmp = gen_reg_rtx (DImode);
5158      if (MEM_P (src))
5159	{
5160	  src = rs6000_address_for_fpconvert (src);
5161	  emit_insn (gen_lfiwax (tmp, src));
5162	}
5163      else
5164	{
5165	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5166	  emit_move_insn (stack, src);
5167	  emit_insn (gen_lfiwax (tmp, stack));
5168	}
5169    }
5170  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5171  DONE;
5172}"
5173  [(set_attr "length" "12")
5174   (set_attr "type" "fpload")])
5175
5176(define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5177  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5178	(float:SFDF
5179	 (sign_extend:DI
5180	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5181   (clobber (match_scratch:DI 2 "=wi"))]
5182  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5183   && <SI_CONVERT_FP>"
5184  "#"
5185  ""
5186  [(pc)]
5187  "
5188{
5189  operands[1] = rs6000_address_for_fpconvert (operands[1]);
5190  if (GET_CODE (operands[2]) == SCRATCH)
5191    operands[2] = gen_reg_rtx (DImode);
5192  if (TARGET_VSX_SMALL_INTEGER)
5193    emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5194  else
5195    emit_insn (gen_lfiwax (operands[2], operands[1]));
5196  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5197  DONE;
5198}"
5199  [(set_attr "length" "8")
5200   (set_attr "type" "fpload")])
5201
5202(define_insn "lfiwzx"
5203  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5204	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5205		   UNSPEC_LFIWZX))]
5206  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5207  "@
5208   lfiwzx %0,%y1
5209   lxsiwzx %x0,%y1
5210   mtvsrwz %x0,%1
5211   xxextractuw %x0,%x1,4"
5212  [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5213
5214(define_insn_and_split "floatunssi<mode>2_lfiwzx"
5215  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5216	(unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5217   (clobber (match_scratch:DI 2 "=wi"))]
5218  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5219   && <SI_CONVERT_FP>"
5220  "#"
5221  ""
5222  [(pc)]
5223  "
5224{
5225  rtx dest = operands[0];
5226  rtx src = operands[1];
5227  rtx tmp;
5228
5229  if (!MEM_P (src) && TARGET_POWERPC64
5230      && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5231    tmp = convert_to_mode (DImode, src, true);
5232  else
5233    {
5234      tmp = operands[2];
5235      if (GET_CODE (tmp) == SCRATCH)
5236	tmp = gen_reg_rtx (DImode);
5237      if (MEM_P (src))
5238	{
5239	  src = rs6000_address_for_fpconvert (src);
5240	  emit_insn (gen_lfiwzx (tmp, src));
5241	}
5242      else
5243	{
5244	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5245	  emit_move_insn (stack, src);
5246	  emit_insn (gen_lfiwzx (tmp, stack));
5247	}
5248    }
5249  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5250  DONE;
5251}"
5252  [(set_attr "length" "12")
5253   (set_attr "type" "fpload")])
5254
5255(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5256  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5257	(unsigned_float:SFDF
5258	 (zero_extend:DI
5259	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5260   (clobber (match_scratch:DI 2 "=wi"))]
5261  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5262   && <SI_CONVERT_FP>"
5263  "#"
5264  ""
5265  [(pc)]
5266  "
5267{
5268  operands[1] = rs6000_address_for_fpconvert (operands[1]);
5269  if (GET_CODE (operands[2]) == SCRATCH)
5270    operands[2] = gen_reg_rtx (DImode);
5271  if (TARGET_VSX_SMALL_INTEGER)
5272    emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5273  else
5274    emit_insn (gen_lfiwzx (operands[2], operands[1]));
5275  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5276  DONE;
5277}"
5278  [(set_attr "length" "8")
5279   (set_attr "type" "fpload")])
5280
5281; For each of these conversions, there is a define_expand, a define_insn
5282; with a '#' template, and a define_split (with C code).  The idea is
5283; to allow constant folding with the template of the define_insn,
5284; then to have the insns split later (between sched1 and final).
5285
5286(define_expand "floatsidf2"
5287  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5288		   (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5289	      (use (match_dup 2))
5290	      (use (match_dup 3))
5291	      (clobber (match_dup 4))
5292	      (clobber (match_dup 5))
5293	      (clobber (match_dup 6))])]
5294  "TARGET_HARD_FLOAT
5295   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5296  "
5297{
5298  if (TARGET_E500_DOUBLE)
5299    {
5300      if (!REG_P (operands[1]))
5301	operands[1] = force_reg (SImode, operands[1]);
5302      emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5303      DONE;
5304    }
5305  else if (TARGET_LFIWAX && TARGET_FCFID)
5306    {
5307      emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5308      DONE;
5309    }
5310  else if (TARGET_FCFID)
5311    {
5312      rtx dreg = operands[1];
5313      if (!REG_P (dreg))
5314	dreg = force_reg (SImode, dreg);
5315      dreg = convert_to_mode (DImode, dreg, false);
5316      emit_insn (gen_floatdidf2 (operands[0], dreg));
5317      DONE;
5318    }
5319
5320  if (!REG_P (operands[1]))
5321    operands[1] = force_reg (SImode, operands[1]);
5322  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5323  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5324  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5325  operands[5] = gen_reg_rtx (DFmode);
5326  operands[6] = gen_reg_rtx (SImode);
5327}")
5328
5329(define_insn_and_split "*floatsidf2_internal"
5330  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5331	(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5332   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5333   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5334   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5335   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5336   (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5337  "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5338  "#"
5339  ""
5340  [(pc)]
5341  "
5342{
5343  rtx lowword, highword;
5344  gcc_assert (MEM_P (operands[4]));
5345  highword = adjust_address (operands[4], SImode, 0);
5346  lowword = adjust_address (operands[4], SImode, 4);
5347  if (! WORDS_BIG_ENDIAN)
5348    std::swap (lowword, highword);
5349
5350  emit_insn (gen_xorsi3 (operands[6], operands[1],
5351			 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5352  emit_move_insn (lowword, operands[6]);
5353  emit_move_insn (highword, operands[2]);
5354  emit_move_insn (operands[5], operands[4]);
5355  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5356  DONE;
5357}"
5358  [(set_attr "length" "24")
5359   (set_attr "type" "fp")])
5360
5361;; If we don't have a direct conversion to single precision, don't enable this
5362;; conversion for 32-bit without fast math, because we don't have the insn to
5363;; generate the fixup swizzle to avoid double rounding problems.
5364(define_expand "floatunssisf2"
5365  [(set (match_operand:SF 0 "gpc_reg_operand" "")
5366        (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5367  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5368   && (!TARGET_FPRS
5369       || (TARGET_FPRS
5370	   && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5371	       || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5372		   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5373  "
5374{
5375  if (!TARGET_FPRS)
5376    {
5377      if (!REG_P (operands[1]))
5378	operands[1] = force_reg (SImode, operands[1]);
5379    }
5380  else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5381    {
5382      emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5383      DONE;
5384    }
5385  else
5386    {
5387      rtx dreg = operands[1];
5388      if (!REG_P (dreg))
5389	dreg = force_reg (SImode, dreg);
5390      dreg = convert_to_mode (DImode, dreg, true);
5391      emit_insn (gen_floatdisf2 (operands[0], dreg));
5392      DONE;
5393    }
5394}")
5395
5396(define_expand "floatunssidf2"
5397  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5398		   (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5399	      (use (match_dup 2))
5400	      (use (match_dup 3))
5401	      (clobber (match_dup 4))
5402	      (clobber (match_dup 5))])]
5403  "TARGET_HARD_FLOAT
5404   && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5405  "
5406{
5407  if (TARGET_E500_DOUBLE)
5408    {
5409      if (!REG_P (operands[1]))
5410	operands[1] = force_reg (SImode, operands[1]);
5411      emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5412      DONE;
5413    }
5414  else if (TARGET_LFIWZX && TARGET_FCFID)
5415    {
5416      emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5417      DONE;
5418    }
5419  else if (TARGET_FCFID)
5420    {
5421      rtx dreg = operands[1];
5422      if (!REG_P (dreg))
5423	dreg = force_reg (SImode, dreg);
5424      dreg = convert_to_mode (DImode, dreg, true);
5425      emit_insn (gen_floatdidf2 (operands[0], dreg));
5426      DONE;
5427    }
5428
5429  if (!REG_P (operands[1]))
5430    operands[1] = force_reg (SImode, operands[1]);
5431  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5432  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5433  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5434  operands[5] = gen_reg_rtx (DFmode);
5435}")
5436
5437(define_insn_and_split "*floatunssidf2_internal"
5438  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5439	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5440   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5441   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5442   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5443   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5444  "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5445   && !(TARGET_FCFID && TARGET_POWERPC64)"
5446  "#"
5447  ""
5448  [(pc)]
5449  "
5450{
5451  rtx lowword, highword;
5452  gcc_assert (MEM_P (operands[4]));
5453  highword = adjust_address (operands[4], SImode, 0);
5454  lowword = adjust_address (operands[4], SImode, 4);
5455  if (! WORDS_BIG_ENDIAN)
5456    std::swap (lowword, highword);
5457
5458  emit_move_insn (lowword, operands[1]);
5459  emit_move_insn (highword, operands[2]);
5460  emit_move_insn (operands[5], operands[4]);
5461  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5462  DONE;
5463}"
5464  [(set_attr "length" "20")
5465   (set_attr "type" "fp")])
5466
5467;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5468;; vector registers.  These insns favor doing the sign/zero extension in
5469;; the vector registers, rather then loading up a GPR, doing a sign/zero
5470;; extension and then a direct move.
5471
5472(define_expand "float<QHI:mode><FP_ISA3:mode>2"
5473  [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5474		   (float:FP_ISA3
5475		    (match_operand:QHI 1 "input_operand")))
5476	      (clobber (match_scratch:DI 2))
5477	      (clobber (match_scratch:DI 3))
5478	      (clobber (match_scratch:<QHI:MODE> 4))])]
5479  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5480   && TARGET_VSX_SMALL_INTEGER"
5481{
5482  if (MEM_P (operands[1]))
5483    operands[1] = rs6000_address_for_fpconvert (operands[1]);
5484})
5485
5486(define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5487  [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5488	(float:FP_ISA3
5489	 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5490   (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5491   (clobber (match_scratch:DI 3 "=X,r,X"))
5492   (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5493  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5494   && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5495  "#"
5496  "&& reload_completed"
5497  [(const_int 0)]
5498{
5499  rtx result = operands[0];
5500  rtx input = operands[1];
5501  rtx di = operands[2];
5502
5503  if (!MEM_P (input))
5504    {
5505      rtx tmp = operands[3];
5506      if (altivec_register_operand (input, <QHI:MODE>mode))
5507	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5508      else if (GET_CODE (tmp) == SCRATCH)
5509	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5510      else
5511	{
5512	  emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5513	  emit_move_insn (di, tmp);
5514	}
5515    }
5516  else
5517    {
5518      rtx tmp = operands[4];
5519      emit_move_insn (tmp, input);
5520      emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5521    }
5522
5523  emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5524  DONE;
5525})
5526
5527(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5528  [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5529		   (unsigned_float:FP_ISA3
5530		    (match_operand:QHI 1 "input_operand" "")))
5531	      (clobber (match_scratch:DI 2 ""))
5532	      (clobber (match_scratch:DI 3 ""))])]
5533  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5534   && TARGET_VSX_SMALL_INTEGER"
5535{
5536  if (MEM_P (operands[1]))
5537    operands[1] = rs6000_address_for_fpconvert (operands[1]);
5538})
5539
5540(define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5541  [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5542	(unsigned_float:FP_ISA3
5543	 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5544   (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5545   (clobber (match_scratch:DI 3 "=X,r,X"))]
5546  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5547   && TARGET_VSX_SMALL_INTEGER"
5548  "#"
5549  "&& reload_completed"
5550  [(const_int 0)]
5551{
5552  rtx result = operands[0];
5553  rtx input = operands[1];
5554  rtx di = operands[2];
5555
5556  if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5557    emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5558  else
5559    {
5560      rtx tmp = operands[3];
5561      if (GET_CODE (tmp) == SCRATCH)
5562	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5563      else
5564	{
5565	  emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5566	  emit_move_insn (di, tmp);
5567	}
5568    }
5569
5570  emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5571  DONE;
5572})
5573
5574(define_expand "fix_trunc<mode>si2"
5575  [(set (match_operand:SI 0 "gpc_reg_operand" "")
5576	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5577  "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5578  "
5579{
5580  if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5581    {
5582      rtx src = force_reg (<MODE>mode, operands[1]);
5583
5584      if (TARGET_STFIWX)
5585	emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5586      else
5587	{
5588	  rtx tmp = gen_reg_rtx (DImode);
5589	  rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5590	  emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5591						      tmp, stack));
5592	}
5593      DONE;
5594    }
5595}")
5596
5597; Like the convert to float patterns, this insn must be split before
5598; register allocation so that it can allocate the memory slot if it
5599; needed
5600(define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5601  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5602	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5603   (clobber (match_scratch:DI 2 "=d"))]
5604  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5605   && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5606   && TARGET_STFIWX && can_create_pseudo_p ()
5607   && !TARGET_VSX_SMALL_INTEGER"
5608  "#"
5609  ""
5610  [(pc)]
5611{
5612  rtx dest = operands[0];
5613  rtx src = operands[1];
5614  rtx tmp = operands[2];
5615
5616  if (GET_CODE (tmp) == SCRATCH)
5617    tmp = gen_reg_rtx (DImode);
5618
5619  emit_insn (gen_fctiwz_<mode> (tmp, src));
5620  if (MEM_P (dest))
5621    {
5622      dest = rs6000_address_for_fpconvert (dest);
5623      emit_insn (gen_stfiwx (dest, tmp));
5624      DONE;
5625    }
5626  else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5627    {
5628      dest = gen_lowpart (DImode, dest);
5629      emit_move_insn (dest, tmp);
5630      DONE;
5631    }
5632  else
5633    {
5634      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5635      emit_insn (gen_stfiwx (stack, tmp));
5636      emit_move_insn (dest, stack);
5637      DONE;
5638    }
5639}
5640  [(set_attr "length" "12")
5641   (set_attr "type" "fp")])
5642
5643(define_insn_and_split "fix_trunc<mode>si2_internal"
5644  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5645	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5646   (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5647   (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5648  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5649   && !TARGET_VSX_SMALL_INTEGER"
5650  "#"
5651  ""
5652  [(pc)]
5653  "
5654{
5655  rtx lowword;
5656  gcc_assert (MEM_P (operands[3]));
5657  lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5658
5659  emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5660  emit_move_insn (operands[3], operands[2]);
5661  emit_move_insn (operands[0], lowword);
5662  DONE;
5663}"
5664  [(set_attr "length" "16")
5665   (set_attr "type" "fp")])
5666
5667(define_expand "fix_trunc<mode>di2"
5668  [(set (match_operand:DI 0 "gpc_reg_operand" "")
5669	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5670  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5671   && TARGET_FCFID"
5672  "")
5673
5674(define_insn "*fix_trunc<mode>di2_fctidz"
5675  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5676	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5677  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5678    && TARGET_FCFID"
5679  "@
5680   fctidz %0,%1
5681   xscvdpsxds %x0,%x1"
5682  [(set_attr "type" "fp")])
5683
5684(define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5685  [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5686		   (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5687	      (clobber (match_scratch:DI 2))])]
5688  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5689   && TARGET_VSX_SMALL_INTEGER"
5690{
5691  if (MEM_P (operands[0]))
5692    operands[0] = rs6000_address_for_fpconvert (operands[0]);
5693})
5694
5695(define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5696  [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5697	(fix:QHI
5698	 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5699   (clobber (match_scratch:DI 2 "=X,wi"))]
5700  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5701   && TARGET_VSX_SMALL_INTEGER"
5702  "#"
5703  "&& reload_completed"
5704  [(const_int 0)]
5705{
5706  rtx dest = operands[0];
5707  rtx src = operands[1];
5708
5709  if (vsx_register_operand (dest, <QHI:MODE>mode))
5710    {
5711      rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5712      emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5713    }
5714  else
5715    {
5716      rtx tmp = operands[2];
5717      rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5718
5719      emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5720      emit_move_insn (dest, tmp2);
5721    }
5722  DONE;
5723})
5724
5725(define_expand "fixuns_trunc<mode>si2"
5726  [(set (match_operand:SI 0 "gpc_reg_operand" "")
5727	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5728  "TARGET_HARD_FLOAT
5729   && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5730       || <E500_CONVERT>)"
5731  "
5732{
5733  if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5734    {
5735      emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5736      DONE;
5737    }
5738}")
5739
5740(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5741  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5742	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5743   (clobber (match_scratch:DI 2 "=d"))]
5744  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5745   && TARGET_STFIWX && can_create_pseudo_p ()
5746   && !TARGET_VSX_SMALL_INTEGER"
5747  "#"
5748  ""
5749  [(pc)]
5750{
5751  rtx dest = operands[0];
5752  rtx src = operands[1];
5753  rtx tmp = operands[2];
5754
5755  if (GET_CODE (tmp) == SCRATCH)
5756    tmp = gen_reg_rtx (DImode);
5757
5758  emit_insn (gen_fctiwuz_<mode> (tmp, src));
5759  if (MEM_P (dest))
5760    {
5761      dest = rs6000_address_for_fpconvert (dest);
5762      emit_insn (gen_stfiwx (dest, tmp));
5763      DONE;
5764    }
5765  else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5766    {
5767      dest = gen_lowpart (DImode, dest);
5768      emit_move_insn (dest, tmp);
5769      DONE;
5770    }
5771  else
5772    {
5773      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5774      emit_insn (gen_stfiwx (stack, tmp));
5775      emit_move_insn (dest, stack);
5776      DONE;
5777    }
5778}
5779  [(set_attr "length" "12")
5780   (set_attr "type" "fp")])
5781
5782(define_insn "fixuns_trunc<mode>di2"
5783  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5784	(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5785  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
5786  "@
5787   fctiduz %0,%1
5788   xscvdpuxds %x0,%x1"
5789  [(set_attr "type" "fp")])
5790
5791(define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5792  [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5793		   (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5794	      (clobber (match_scratch:DI 2))])]
5795  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5796   && TARGET_VSX_SMALL_INTEGER"
5797{
5798  if (MEM_P (operands[0]))
5799    operands[0] = rs6000_address_for_fpconvert (operands[0]);
5800})
5801
5802(define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5803  [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5804	(unsigned_fix:QHI
5805	 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5806   (clobber (match_scratch:DI 2 "=X,wi"))]
5807  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5808   && TARGET_VSX_SMALL_INTEGER"
5809  "#"
5810  "&& reload_completed"
5811  [(const_int 0)]
5812{
5813  rtx dest = operands[0];
5814  rtx src = operands[1];
5815
5816  if (vsx_register_operand (dest, <QHI:MODE>mode))
5817    {
5818      rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5819      emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5820    }
5821  else
5822    {
5823      rtx tmp = operands[2];
5824      rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5825
5826      emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5827      emit_move_insn (dest, tmp2);
5828    }
5829  DONE;
5830})
5831
5832;; If -mvsx-small-integer, we can represent the FIX operation directly.  On
5833;; older machines, we have to use an UNSPEC to produce a SImode and move it
5834;; to another location, since SImode is not allowed in vector registers.
5835(define_insn "*fctiw<u>z_<mode>_smallint"
5836  [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5837	(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5838  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5839   && TARGET_VSX_SMALL_INTEGER"
5840  "@
5841   fctiw<u>z %0,%1
5842   xscvdp<su>xws %x0,%x1"
5843  [(set_attr "type" "fp")])
5844
5845;; Combiner pattern to prevent moving the result of converting a floating point
5846;; value to 32-bit integer to GPR in order to save it.
5847(define_insn_and_split "*fctiw<u>z_<mode>_mem"
5848  [(set (match_operand:SI 0 "memory_operand" "=Z")
5849	(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5850   (clobber (match_scratch:SI 2 "=wa"))]
5851  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5852   && TARGET_VSX_SMALL_INTEGER"
5853  "#"
5854  "&& reload_completed"
5855  [(set (match_dup 2)
5856	(any_fix:SI (match_dup 1)))
5857   (set (match_dup 0)
5858	(match_dup 2))])
5859
5860;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5861;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5862;; because the first makes it clear that operand 0 is not live
5863;; before the instruction.
5864(define_insn "fctiwz_<mode>"
5865  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5866	(unspec:DI [(fix:SI
5867		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5868		   UNSPEC_FCTIWZ))]
5869  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5870  "@
5871   fctiwz %0,%1
5872   xscvdpsxws %x0,%x1"
5873  [(set_attr "type" "fp")])
5874
5875(define_insn "fctiwuz_<mode>"
5876  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5877	(unspec:DI [(unsigned_fix:SI
5878		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5879		   UNSPEC_FCTIWUZ))]
5880  "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5881  "@
5882   fctiwuz %0,%1
5883   xscvdpuxws %x0,%x1"
5884  [(set_attr "type" "fp")])
5885
5886;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5887;; since the friz instruction does not truncate the value if the floating
5888;; point value is < LONG_MIN or > LONG_MAX.
5889(define_insn "*friz"
5890  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5891	(float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5892  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5893   && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5894  "@
5895   friz %0,%1
5896   xsrdpiz %x0,%x1"
5897  [(set_attr "type" "fp")])
5898
5899;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5900;; optimization prevents on ISA 2.06 systems and earlier having to store the
5901;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5902;; extend it, store it back on the stack from the GPR, load it back into the
5903;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5904;; disable using store and load to sign/zero extend the value.
5905(define_insn_and_split "*round32<mode>2_fprs"
5906  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5907	(float:SFDF
5908	 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5909   (clobber (match_scratch:DI 2 "=d"))
5910   (clobber (match_scratch:DI 3 "=d"))]
5911  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5912   && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5913   && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5914  "#"
5915  ""
5916  [(pc)]
5917{
5918  rtx dest = operands[0];
5919  rtx src = operands[1];
5920  rtx tmp1 = operands[2];
5921  rtx tmp2 = operands[3];
5922  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5923
5924  if (GET_CODE (tmp1) == SCRATCH)
5925    tmp1 = gen_reg_rtx (DImode);
5926  if (GET_CODE (tmp2) == SCRATCH)
5927    tmp2 = gen_reg_rtx (DImode);
5928
5929  emit_insn (gen_fctiwz_<mode> (tmp1, src));
5930  emit_insn (gen_stfiwx (stack, tmp1));
5931  emit_insn (gen_lfiwax (tmp2, stack));
5932  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5933  DONE;
5934}
5935  [(set_attr "type" "fpload")
5936   (set_attr "length" "16")])
5937
5938(define_insn_and_split "*roundu32<mode>2_fprs"
5939  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5940	(unsigned_float:SFDF
5941	 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5942   (clobber (match_scratch:DI 2 "=d"))
5943   (clobber (match_scratch:DI 3 "=d"))]
5944  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5945   && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5946   && can_create_pseudo_p ()"
5947  "#"
5948  ""
5949  [(pc)]
5950{
5951  rtx dest = operands[0];
5952  rtx src = operands[1];
5953  rtx tmp1 = operands[2];
5954  rtx tmp2 = operands[3];
5955  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5956
5957  if (GET_CODE (tmp1) == SCRATCH)
5958    tmp1 = gen_reg_rtx (DImode);
5959  if (GET_CODE (tmp2) == SCRATCH)
5960    tmp2 = gen_reg_rtx (DImode);
5961
5962  emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5963  emit_insn (gen_stfiwx (stack, tmp1));
5964  emit_insn (gen_lfiwzx (tmp2, stack));
5965  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5966  DONE;
5967}
5968  [(set_attr "type" "fpload")
5969   (set_attr "length" "16")])
5970
5971;; No VSX equivalent to fctid
5972(define_insn "lrint<mode>di2"
5973  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5974	(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5975		   UNSPEC_FCTID))]
5976  "TARGET_<MODE>_FPR && TARGET_FPRND"
5977  "fctid %0,%1"
5978  [(set_attr "type" "fp")])
5979
5980(define_insn "btrunc<mode>2"
5981  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5982	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5983		     UNSPEC_FRIZ))]
5984  "TARGET_<MODE>_FPR && TARGET_FPRND"
5985  "@
5986   friz %0,%1
5987   xsrdpiz %x0,%x1"
5988  [(set_attr "type" "fp")
5989   (set_attr "fp_type" "fp_addsub_<Fs>")])
5990
5991(define_insn "ceil<mode>2"
5992  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5993	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5994		     UNSPEC_FRIP))]
5995  "TARGET_<MODE>_FPR && TARGET_FPRND"
5996  "@
5997   frip %0,%1
5998   xsrdpip %x0,%x1"
5999  [(set_attr "type" "fp")
6000   (set_attr "fp_type" "fp_addsub_<Fs>")])
6001
6002(define_insn "floor<mode>2"
6003  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6004	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6005		     UNSPEC_FRIM))]
6006  "TARGET_<MODE>_FPR && TARGET_FPRND"
6007  "@
6008   frim %0,%1
6009   xsrdpim %x0,%x1"
6010  [(set_attr "type" "fp")
6011   (set_attr "fp_type" "fp_addsub_<Fs>")])
6012
6013;; No VSX equivalent to frin
6014(define_insn "round<mode>2"
6015  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6016	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6017		     UNSPEC_FRIN))]
6018  "TARGET_<MODE>_FPR && TARGET_FPRND"
6019  "frin %0,%1"
6020  [(set_attr "type" "fp")
6021   (set_attr "fp_type" "fp_addsub_<Fs>")])
6022
6023(define_insn "*xsrdpi<mode>2"
6024  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6025	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6026		     UNSPEC_XSRDPI))]
6027  "TARGET_<MODE>_FPR && TARGET_VSX"
6028  "xsrdpi %x0,%x1"
6029  [(set_attr "type" "fp")
6030   (set_attr "fp_type" "fp_addsub_<Fs>")])
6031
6032(define_expand "lround<mode>di2"
6033  [(set (match_dup 2)
6034	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6035		     UNSPEC_XSRDPI))
6036   (set (match_operand:DI 0 "gpc_reg_operand" "")
6037	(unspec:DI [(match_dup 2)]
6038		   UNSPEC_FCTID))]
6039  "TARGET_<MODE>_FPR && TARGET_VSX"
6040{
6041  operands[2] = gen_reg_rtx (<MODE>mode);
6042})
6043
6044; An UNSPEC is used so we don't have to support SImode in FP registers.
6045; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6046; is only generated for Power8 or later.
6047(define_insn "stfiwx"
6048  [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6049	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6050		   UNSPEC_STFIWX))]
6051  "TARGET_PPC_GFXOPT"
6052  "@
6053   stfiwx %1,%y0
6054   stxsiwx %x1,%y0"
6055  [(set_attr "type" "fpstore")])
6056
6057;; If we don't have a direct conversion to single precision, don't enable this
6058;; conversion for 32-bit without fast math, because we don't have the insn to
6059;; generate the fixup swizzle to avoid double rounding problems.
6060(define_expand "floatsisf2"
6061  [(set (match_operand:SF 0 "gpc_reg_operand" "")
6062        (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6063  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6064   && (!TARGET_FPRS
6065       || (TARGET_FPRS
6066	   && ((TARGET_FCFIDS && TARGET_LFIWAX)
6067	       || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6068		   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6069  "
6070{
6071  if (!TARGET_FPRS)
6072    {
6073      if (!REG_P (operands[1]))
6074	operands[1] = force_reg (SImode, operands[1]);
6075    }
6076  else if (TARGET_FCFIDS && TARGET_LFIWAX)
6077    {
6078      emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6079      DONE;
6080    }
6081  else if (TARGET_FCFID && TARGET_LFIWAX)
6082    {
6083      rtx dfreg = gen_reg_rtx (DFmode);
6084      emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6085      emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6086      DONE;
6087    }
6088  else
6089    {
6090      rtx dreg = operands[1];
6091      if (!REG_P (dreg))
6092	dreg = force_reg (SImode, dreg);
6093      dreg = convert_to_mode (DImode, dreg, false);
6094      emit_insn (gen_floatdisf2 (operands[0], dreg));
6095      DONE;
6096    }
6097}")
6098
6099(define_expand "floatdidf2"
6100  [(set (match_operand:DF 0 "gpc_reg_operand" "")
6101	(float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6102  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6103  "")
6104
6105(define_insn "*floatdidf2_fpr"
6106  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6107	(float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6108  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6109  "@
6110   fcfid %0,%1
6111   xscvsxddp %x0,%x1"
6112  [(set_attr "type" "fp")])
6113
6114; Allow the combiner to merge source memory operands to the conversion so that
6115; the optimizer/register allocator doesn't try to load the value too early in a
6116; GPR and then use store/load to move it to a FPR and suffer from a store-load
6117; hit.  We will split after reload to avoid the trip through the GPRs
6118
6119(define_insn_and_split "*floatdidf2_mem"
6120  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6121	(float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6122   (clobber (match_scratch:DI 2 "=d,wi"))]
6123  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6124  "#"
6125  "&& reload_completed"
6126  [(set (match_dup 2) (match_dup 1))
6127   (set (match_dup 0) (float:DF (match_dup 2)))]
6128  ""
6129  [(set_attr "length" "8")
6130   (set_attr "type" "fpload")])
6131
6132(define_expand "floatunsdidf2"
6133  [(set (match_operand:DF 0 "gpc_reg_operand" "")
6134	(unsigned_float:DF
6135	 (match_operand:DI 1 "gpc_reg_operand" "")))]
6136  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6137  "")
6138
6139(define_insn "*floatunsdidf2_fcfidu"
6140  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6141	(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6142  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6143  "@
6144   fcfidu %0,%1
6145   xscvuxddp %x0,%x1"
6146  [(set_attr "type" "fp")
6147   (set_attr "length" "4")])
6148
6149(define_insn_and_split "*floatunsdidf2_mem"
6150  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6151	(unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6152   (clobber (match_scratch:DI 2 "=d,wi"))]
6153  "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6154  "#"
6155  "&& reload_completed"
6156  [(set (match_dup 2) (match_dup 1))
6157   (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6158  ""
6159  [(set_attr "length" "8")
6160   (set_attr "type" "fpload")])
6161
6162(define_expand "floatdisf2"
6163  [(set (match_operand:SF 0 "gpc_reg_operand" "")
6164        (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6165  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6166   && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6167  "
6168{
6169  if (!TARGET_FCFIDS)
6170    {
6171      rtx val = operands[1];
6172      if (!flag_unsafe_math_optimizations)
6173	{
6174	  rtx label = gen_label_rtx ();
6175	  val = gen_reg_rtx (DImode);
6176	  emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6177	  emit_label (label);
6178	}
6179      emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6180      DONE;
6181    }
6182}")
6183
6184(define_insn "floatdisf2_fcfids"
6185  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6186	(float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6187  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6188   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6189  "@
6190   fcfids %0,%1
6191   xscvsxdsp %x0,%x1"
6192  [(set_attr "type" "fp")])
6193
6194(define_insn_and_split "*floatdisf2_mem"
6195  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6196	(float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6197   (clobber (match_scratch:DI 2 "=d,d,wi"))]
6198  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6199   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6200  "#"
6201  "&& reload_completed"
6202  [(pc)]
6203  "
6204{
6205  emit_move_insn (operands[2], operands[1]);
6206  emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6207  DONE;
6208}"
6209  [(set_attr "length" "8")])
6210
6211;; This is not IEEE compliant if rounding mode is "round to nearest".
6212;; If the DI->DF conversion is inexact, then it's possible to suffer
6213;; from double rounding.
6214;; Instead of creating a new cpu type for two FP operations, just use fp
6215(define_insn_and_split "floatdisf2_internal1"
6216  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6217        (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6218   (clobber (match_scratch:DF 2 "=d"))]
6219  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6220   && !TARGET_FCFIDS"
6221  "#"
6222  "&& reload_completed"
6223  [(set (match_dup 2)
6224        (float:DF (match_dup 1)))
6225   (set (match_dup 0)
6226        (float_truncate:SF (match_dup 2)))]
6227  ""
6228  [(set_attr "length" "8")
6229   (set_attr "type" "fp")])
6230
6231;; Twiddles bits to avoid double rounding.
6232;; Bits that might be truncated when converting to DFmode are replaced
6233;; by a bit that won't be lost at that stage, but is below the SFmode
6234;; rounding position.
6235(define_expand "floatdisf2_internal2"
6236  [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6237					      (const_int 53)))
6238	      (clobber (reg:DI CA_REGNO))])
6239   (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6240					   (const_int 2047)))
6241   (set (match_dup 3) (plus:DI (match_dup 3)
6242			       (const_int 1)))
6243   (set (match_dup 0) (plus:DI (match_dup 0)
6244			       (const_int 2047)))
6245   (set (match_dup 4) (compare:CCUNS (match_dup 3)
6246				     (const_int 2)))
6247   (set (match_dup 0) (ior:DI (match_dup 0)
6248			      (match_dup 1)))
6249   (set (match_dup 0) (and:DI (match_dup 0)
6250			      (const_int -2048)))
6251   (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6252			   (label_ref (match_operand:DI 2 "" ""))
6253			   (pc)))
6254   (set (match_dup 0) (match_dup 1))]
6255  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6256   && !TARGET_FCFIDS"
6257  "
6258{
6259  operands[3] = gen_reg_rtx (DImode);
6260  operands[4] = gen_reg_rtx (CCUNSmode);
6261}")
6262
6263(define_expand "floatunsdisf2"
6264  [(set (match_operand:SF 0 "gpc_reg_operand" "")
6265        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6266  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6267   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6268  "")
6269
6270(define_insn "floatunsdisf2_fcfidus"
6271  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6272        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6273  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6274   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6275  "@
6276   fcfidus %0,%1
6277   xscvuxdsp %x0,%x1"
6278  [(set_attr "type" "fp")])
6279
6280(define_insn_and_split "*floatunsdisf2_mem"
6281  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6282	(unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6283   (clobber (match_scratch:DI 2 "=d,d,wi"))]
6284  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6285   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6286  "#"
6287  "&& reload_completed"
6288  [(pc)]
6289  "
6290{
6291  emit_move_insn (operands[2], operands[1]);
6292  emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6293  DONE;
6294}"
6295  [(set_attr "length" "8")
6296   (set_attr "type" "fpload")])
6297
6298;; Define the TImode operations that can be done in a small number
6299;; of instructions.  The & constraints are to prevent the register
6300;; allocator from allocating registers that overlap with the inputs
6301;; (for example, having an input in 7,8 and an output in 6,7).  We
6302;; also allow for the output being the same as one of the inputs.
6303
6304(define_expand "addti3"
6305  [(set (match_operand:TI 0 "gpc_reg_operand" "")
6306	(plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6307		 (match_operand:TI 2 "reg_or_short_operand" "")))]
6308  "TARGET_64BIT"
6309{
6310  rtx lo0 = gen_lowpart (DImode, operands[0]);
6311  rtx lo1 = gen_lowpart (DImode, operands[1]);
6312  rtx lo2 = gen_lowpart (DImode, operands[2]);
6313  rtx hi0 = gen_highpart (DImode, operands[0]);
6314  rtx hi1 = gen_highpart (DImode, operands[1]);
6315  rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6316
6317  if (!reg_or_short_operand (lo2, DImode))
6318    lo2 = force_reg (DImode, lo2);
6319  if (!adde_operand (hi2, DImode))
6320    hi2 = force_reg (DImode, hi2);
6321
6322  emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6323  emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6324  DONE;
6325})
6326
6327(define_expand "subti3"
6328  [(set (match_operand:TI 0 "gpc_reg_operand" "")
6329	(minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6330		  (match_operand:TI 2 "gpc_reg_operand" "")))]
6331  "TARGET_64BIT"
6332{
6333  rtx lo0 = gen_lowpart (DImode, operands[0]);
6334  rtx lo1 = gen_lowpart (DImode, operands[1]);
6335  rtx lo2 = gen_lowpart (DImode, operands[2]);
6336  rtx hi0 = gen_highpart (DImode, operands[0]);
6337  rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6338  rtx hi2 = gen_highpart (DImode, operands[2]);
6339
6340  if (!reg_or_short_operand (lo1, DImode))
6341    lo1 = force_reg (DImode, lo1);
6342  if (!adde_operand (hi1, DImode))
6343    hi1 = force_reg (DImode, hi1);
6344
6345  emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6346  emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6347  DONE;
6348})
6349
6350;; 128-bit logical operations expanders
6351
6352(define_expand "and<mode>3"
6353  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6354	(and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6355		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6356  ""
6357  "")
6358
6359(define_expand "ior<mode>3"
6360  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6361        (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6362		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6363  ""
6364  "")
6365
6366(define_expand "xor<mode>3"
6367  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6368        (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6369		      (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6370  ""
6371  "")
6372
6373(define_expand "one_cmpl<mode>2"
6374  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6375        (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6376  ""
6377  "")
6378
6379(define_expand "nor<mode>3"
6380  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6381	(and:BOOL_128
6382	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6383	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6384  ""
6385  "")
6386
6387(define_expand "andc<mode>3"
6388  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6389        (and:BOOL_128
6390	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6391	 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6392  ""
6393  "")
6394
6395;; Power8 vector logical instructions.
6396(define_expand "eqv<mode>3"
6397  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6398	(not:BOOL_128
6399	 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6400		       (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6401  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6402  "")
6403
6404;; Rewrite nand into canonical form
6405(define_expand "nand<mode>3"
6406  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6407	(ior:BOOL_128
6408	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6409	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6410  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6411  "")
6412
6413;; The canonical form is to have the negated element first, so we need to
6414;; reverse arguments.
6415(define_expand "orc<mode>3"
6416  [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6417	(ior:BOOL_128
6418	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6419	 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6420  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6421  "")
6422
6423;; 128-bit logical operations insns and split operations
6424(define_insn_and_split "*and<mode>3_internal"
6425  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6426        (and:BOOL_128
6427	 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6428	 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6429  ""
6430{
6431  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6432    return "xxland %x0,%x1,%x2";
6433
6434  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6435    return "vand %0,%1,%2";
6436
6437  return "#";
6438}
6439  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6440  [(const_int 0)]
6441{
6442  rs6000_split_logical (operands, AND, false, false, false);
6443  DONE;
6444}
6445  [(set (attr "type")
6446      (if_then_else
6447	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6448	(const_string "veclogical")
6449	(const_string "integer")))
6450   (set (attr "length")
6451      (if_then_else
6452	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6453	(const_string "4")
6454	(if_then_else
6455	 (match_test "TARGET_POWERPC64")
6456	 (const_string "8")
6457	 (const_string "16"))))])
6458
6459;; 128-bit IOR/XOR
6460(define_insn_and_split "*bool<mode>3_internal"
6461  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6462	(match_operator:BOOL_128 3 "boolean_or_operator"
6463	 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6464	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6465  ""
6466{
6467  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6468    return "xxl%q3 %x0,%x1,%x2";
6469
6470  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6471    return "v%q3 %0,%1,%2";
6472
6473  return "#";
6474}
6475  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6476  [(const_int 0)]
6477{
6478  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6479  DONE;
6480}
6481  [(set (attr "type")
6482      (if_then_else
6483	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6484	(const_string "veclogical")
6485	(const_string "integer")))
6486   (set (attr "length")
6487      (if_then_else
6488	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6489	(const_string "4")
6490	(if_then_else
6491	 (match_test "TARGET_POWERPC64")
6492	 (const_string "8")
6493	 (const_string "16"))))])
6494
6495;; 128-bit ANDC/ORC
6496(define_insn_and_split "*boolc<mode>3_internal1"
6497  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6498	(match_operator:BOOL_128 3 "boolean_operator"
6499	 [(not:BOOL_128
6500	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6501	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6502  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6503{
6504  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6505    return "xxl%q3 %x0,%x1,%x2";
6506
6507  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6508    return "v%q3 %0,%1,%2";
6509
6510  return "#";
6511}
6512  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6513   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6514  [(const_int 0)]
6515{
6516  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6517  DONE;
6518}
6519  [(set (attr "type")
6520      (if_then_else
6521	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6522	(const_string "veclogical")
6523	(const_string "integer")))
6524   (set (attr "length")
6525      (if_then_else
6526	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6527	(const_string "4")
6528	(if_then_else
6529	 (match_test "TARGET_POWERPC64")
6530	 (const_string "8")
6531	 (const_string "16"))))])
6532
6533(define_insn_and_split "*boolc<mode>3_internal2"
6534  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6535	(match_operator:TI2 3 "boolean_operator"
6536	 [(not:TI2
6537	   (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6538	  (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6539  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6540  "#"
6541  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6542  [(const_int 0)]
6543{
6544  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6545  DONE;
6546}
6547  [(set_attr "type" "integer")
6548   (set (attr "length")
6549	(if_then_else
6550	 (match_test "TARGET_POWERPC64")
6551	 (const_string "8")
6552	 (const_string "16")))])
6553
6554;; 128-bit NAND/NOR
6555(define_insn_and_split "*boolcc<mode>3_internal1"
6556  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6557	(match_operator:BOOL_128 3 "boolean_operator"
6558	 [(not:BOOL_128
6559	   (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6560	  (not:BOOL_128
6561	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6562  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6563{
6564  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6565    return "xxl%q3 %x0,%x1,%x2";
6566
6567  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6568    return "v%q3 %0,%1,%2";
6569
6570  return "#";
6571}
6572  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6573   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6574  [(const_int 0)]
6575{
6576  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6577  DONE;
6578}
6579  [(set (attr "type")
6580      (if_then_else
6581	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6582	(const_string "veclogical")
6583	(const_string "integer")))
6584   (set (attr "length")
6585      (if_then_else
6586	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6587	(const_string "4")
6588	(if_then_else
6589	 (match_test "TARGET_POWERPC64")
6590	 (const_string "8")
6591	 (const_string "16"))))])
6592
6593(define_insn_and_split "*boolcc<mode>3_internal2"
6594  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6595	(match_operator:TI2 3 "boolean_operator"
6596	 [(not:TI2
6597	   (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6598	  (not:TI2
6599	   (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6600  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6601  "#"
6602  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6603  [(const_int 0)]
6604{
6605  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6606  DONE;
6607}
6608  [(set_attr "type" "integer")
6609   (set (attr "length")
6610	(if_then_else
6611	 (match_test "TARGET_POWERPC64")
6612	 (const_string "8")
6613	 (const_string "16")))])
6614
6615
6616;; 128-bit EQV
6617(define_insn_and_split "*eqv<mode>3_internal1"
6618  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6619	(not:BOOL_128
6620	 (xor:BOOL_128
6621	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6622	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6623  "TARGET_P8_VECTOR"
6624{
6625  if (vsx_register_operand (operands[0], <MODE>mode))
6626    return "xxleqv %x0,%x1,%x2";
6627
6628  return "#";
6629}
6630  "TARGET_P8_VECTOR && reload_completed
6631   && int_reg_operand (operands[0], <MODE>mode)"
6632  [(const_int 0)]
6633{
6634  rs6000_split_logical (operands, XOR, true, false, false);
6635  DONE;
6636}
6637  [(set (attr "type")
6638      (if_then_else
6639	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6640	(const_string "veclogical")
6641	(const_string "integer")))
6642   (set (attr "length")
6643      (if_then_else
6644	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6645	(const_string "4")
6646	(if_then_else
6647	 (match_test "TARGET_POWERPC64")
6648	 (const_string "8")
6649	 (const_string "16"))))])
6650
6651(define_insn_and_split "*eqv<mode>3_internal2"
6652  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6653	(not:TI2
6654	 (xor:TI2
6655	  (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6656	  (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6657  "!TARGET_P8_VECTOR"
6658  "#"
6659  "reload_completed && !TARGET_P8_VECTOR"
6660  [(const_int 0)]
6661{
6662  rs6000_split_logical (operands, XOR, true, false, false);
6663  DONE;
6664}
6665  [(set_attr "type" "integer")
6666   (set (attr "length")
6667	(if_then_else
6668	 (match_test "TARGET_POWERPC64")
6669	 (const_string "8")
6670	 (const_string "16")))])
6671
6672;; 128-bit one's complement
6673(define_insn_and_split "*one_cmpl<mode>3_internal"
6674  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6675	(not:BOOL_128
6676	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6677  ""
6678{
6679  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6680    return "xxlnor %x0,%x1,%x1";
6681
6682  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6683    return "vnor %0,%1,%1";
6684
6685  return "#";
6686}
6687  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6688  [(const_int 0)]
6689{
6690  rs6000_split_logical (operands, NOT, false, false, false);
6691  DONE;
6692}
6693  [(set (attr "type")
6694      (if_then_else
6695	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6696	(const_string "veclogical")
6697	(const_string "integer")))
6698   (set (attr "length")
6699      (if_then_else
6700	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6701	(const_string "4")
6702	(if_then_else
6703	 (match_test "TARGET_POWERPC64")
6704	 (const_string "8")
6705	 (const_string "16"))))])
6706
6707
6708;; Now define ways of moving data around.
6709
6710;; Set up a register with a value from the GOT table
6711
6712(define_expand "movsi_got"
6713  [(set (match_operand:SI 0 "gpc_reg_operand" "")
6714	(unspec:SI [(match_operand:SI 1 "got_operand" "")
6715		    (match_dup 2)] UNSPEC_MOVSI_GOT))]
6716  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6717  "
6718{
6719  if (GET_CODE (operands[1]) == CONST)
6720    {
6721      rtx offset = const0_rtx;
6722      HOST_WIDE_INT value;
6723
6724      operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6725      value = INTVAL (offset);
6726      if (value != 0)
6727	{
6728	  rtx tmp = (!can_create_pseudo_p ()
6729		     ? operands[0]
6730		     : gen_reg_rtx (Pmode));
6731	  emit_insn (gen_movsi_got (tmp, operands[1]));
6732	  emit_insn (gen_addsi3 (operands[0], tmp, offset));
6733	  DONE;
6734	}
6735    }
6736
6737  operands[2] = rs6000_got_register (operands[1]);
6738}")
6739
6740(define_insn "*movsi_got_internal"
6741  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6742	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6743		    (match_operand:SI 2 "gpc_reg_operand" "b")]
6744		   UNSPEC_MOVSI_GOT))]
6745  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6746  "lwz %0,%a1@got(%2)"
6747  [(set_attr "type" "load")])
6748
6749;; Used by sched, shorten_branches and final when the GOT pseudo reg
6750;; didn't get allocated to a hard register.
6751(define_split
6752  [(set (match_operand:SI 0 "gpc_reg_operand" "")
6753	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6754		    (match_operand:SI 2 "memory_operand" "")]
6755		   UNSPEC_MOVSI_GOT))]
6756  "DEFAULT_ABI == ABI_V4
6757    && flag_pic == 1
6758    && (reload_in_progress || reload_completed)"
6759  [(set (match_dup 0) (match_dup 2))
6760   (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6761				 UNSPEC_MOVSI_GOT))]
6762  "")
6763
6764;; For SI, we special-case integers that can't be loaded in one insn.  We
6765;; do the load 16-bits at a time.  We could do this by loading from memory,
6766;; and this is even supposed to be faster, but it is simpler not to get
6767;; integers in the TOC.
6768(define_insn "movsi_low"
6769  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6770        (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6771                           (match_operand 2 "" ""))))]
6772  "TARGET_MACHO && ! TARGET_64BIT"
6773  "lwz %0,lo16(%2)(%1)"
6774  [(set_attr "type" "load")
6775   (set_attr "length" "4")])
6776
6777;;		MR           LA           LWZ          LFIWZX       LXSIWZX
6778;;		STW          STFIWX       STXSIWX      LI           LIS
6779;;		#            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6780;;		XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6781;;		MF%1         MT%0         MT%0         NOP
6782(define_insn "*movsi_internal1"
6783  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6784		"=r,         r,           r,           ?*wI,        ?*wH,
6785		 m,          ?Z,          ?Z,          r,           r,
6786		 r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6787		 ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6788		 r,          *c*l,        *h,          *h")
6789
6790	(match_operand:SI 1 "input_operand"
6791		"r,          U,           m,           Z,           Z,
6792		 r,          wI,          wH,          I,           L,
6793		 n,          wIwH,        O,           wM,          wB,
6794		 O,          wM,          wS,          r,           wIwH,
6795		 *h,         r,           r,           0"))]
6796
6797  "!TARGET_SINGLE_FPU &&
6798   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6799  "@
6800   mr %0,%1
6801   la %0,%a1
6802   lwz%U1%X1 %0,%1
6803   lfiwzx %0,%y1
6804   lxsiwzx %x0,%y1
6805   stw%U0%X0 %1,%0
6806   stfiwx %1,%y0
6807   stxsiwx %x1,%y0
6808   li %0,%1
6809   lis %0,%v1
6810   #
6811   xxlor %x0,%x1,%x1
6812   xxspltib %x0,0
6813   xxspltib %x0,255
6814   vspltisw %0,%1
6815   xxlxor %x0,%x0,%x0
6816   xxlorc %x0,%x0,%x0
6817   #
6818   mtvsrwz %x0,%1
6819   mfvsrwz %0,%x1
6820   mf%1 %0
6821   mt%0 %1
6822   mt%0 %1
6823   nop"
6824  [(set_attr "type"
6825		"*,          *,           load,        fpload,      fpload,
6826		 store,      fpstore,     fpstore,     *,           *,
6827		 *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6828		 veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6829		 *,           *,           *,           *")
6830
6831   (set_attr "length"
6832		"4,          4,           4,           4,           4,
6833		 4,          4,           4,           4,           4,
6834		 8,          4,           4,           4,           4,
6835		 4,          4,           8,           4,           4,
6836		 4,          4,           4,           4")])
6837
6838(define_insn "*movsi_internal1_single"
6839  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6840        (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6841  "TARGET_SINGLE_FPU &&
6842   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6843  "@
6844   mr %0,%1
6845   la %0,%a1
6846   lwz%U1%X1 %0,%1
6847   stw%U0%X0 %1,%0
6848   li %0,%1
6849   lis %0,%v1
6850   #
6851   mf%1 %0
6852   mt%0 %1
6853   mt%0 %1
6854   nop
6855   stfs%U0%X0 %1,%0
6856   lfs%U1%X1 %0,%1"
6857  [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6858   (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6859
6860;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6861;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6862;;
6863;; Because SF values are actually stored as DF values within the vector
6864;; registers, we need to convert the value to the vector SF format when
6865;; we need to use the bits in a union or similar cases.  We only need
6866;; to do this transformation when the value is a vector register.  Loads,
6867;; stores, and transfers within GPRs are assumed to be safe.
6868;;
6869;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6870;; no alternatives, because the call is created as part of secondary_reload,
6871;; and operand #2's register class is used to allocate the temporary register.
6872;; This function is called before reload, and it creates the temporary as
6873;; needed.
6874
6875;;		MR           LWZ          LFIWZX       LXSIWZX   STW
6876;;		STFS         STXSSP       STXSSPX      VSX->GPR  MTVSRWZ
6877;;		VSX->VSX
6878
6879(define_insn_and_split "movsi_from_sf"
6880  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6881		"=r,         r,           ?*wI,        ?*wH,     m,
6882		 m,          wY,          Z,           r,        wIwH,
6883		 ?wK")
6884
6885	(unspec:SI [(match_operand:SF 1 "input_operand"
6886		"r,          m,           Z,           Z,        r,
6887		 f,          wb,          wu,          wIwH,     r,
6888		 wK")]
6889		    UNSPEC_SI_FROM_SF))
6890
6891   (clobber (match_scratch:V4SF 2
6892		"=X,         X,           X,           X,        X,
6893		 X,          X,           X,           wa,       X,
6894		 wa"))]
6895
6896  "TARGET_NO_SF_SUBREG
6897   && (register_operand (operands[0], SImode)
6898       || register_operand (operands[1], SFmode))"
6899  "@
6900   mr %0,%1
6901   lwz%U1%X1 %0,%1
6902   lfiwzx %0,%y1
6903   lxsiwzx %x0,%y1
6904   stw%U0%X0 %1,%0
6905   stfs%U0%X0 %1,%0
6906   stxssp %1,%0
6907   stxsspx %x1,%y0
6908   #
6909   mtvsrwz %x0,%1
6910   #"
6911  "&& reload_completed
6912   && register_operand (operands[0], SImode)
6913   && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6914  [(const_int 0)]
6915{
6916  rtx op0 = operands[0];
6917  rtx op1 = operands[1];
6918  rtx op2 = operands[2];
6919  rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6920
6921  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6922
6923  if (int_reg_operand (op0, SImode))
6924    {
6925      emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6926      emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6927    }
6928  else
6929    {
6930      rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6931      rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6932      emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6933    }
6934
6935  DONE;
6936}
6937  [(set_attr "type"
6938		"*,          load,        fpload,      fpload,   store,
6939		 fpstore,    fpstore,     fpstore,     mftgpr,   mffgpr,
6940		 veclogical")
6941
6942   (set_attr "length"
6943		"4,          4,           4,           4,        4,
6944		 4,          4,           4,           12,       4,
6945		 8")])
6946
6947;; movsi_from_sf with zero extension
6948;;
6949;;		RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6950;;		MTVSRWZ      VSX->VSX
6951
6952(define_insn_and_split "*movdi_from_sf_zero_ext"
6953  [(set (match_operand:DI 0 "gpc_reg_operand"
6954		"=r,         r,           ?*wI,        ?*wH,     r,
6955		wIwH,        ?wK")
6956
6957	(zero_extend:DI
6958	 (unspec:SI [(match_operand:SF 1 "input_operand"
6959		"r,          m,           Z,           Z,        wIwH,
6960		 r,          wK")]
6961		    UNSPEC_SI_FROM_SF)))
6962
6963   (clobber (match_scratch:V4SF 2
6964		"=X,         X,           X,           X,        wa,
6965		 X,          wa"))]
6966
6967  "TARGET_DIRECT_MOVE_64BIT
6968   && (register_operand (operands[0], DImode)
6969       || register_operand (operands[1], SImode))"
6970  "@
6971   rldicl %0,%1,0,32
6972   lwz%U1%X1 %0,%1
6973   lfiwzx %0,%y1
6974   lxsiwzx %x0,%y1
6975   #
6976   mtvsrwz %x0,%1
6977   #"
6978  "&& reload_completed
6979   && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6980  [(const_int 0)]
6981{
6982  rtx op0 = operands[0];
6983  rtx op1 = operands[1];
6984  rtx op2 = operands[2];
6985
6986  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6987
6988  if (int_reg_operand (op0, DImode))
6989    {
6990      emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6991      emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6992    }
6993  else
6994    {
6995      rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6996      rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6997      rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6998      emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6999    }
7000
7001  DONE;
7002}
7003  [(set_attr "type"
7004		"*,          load,        fpload,      fpload,  mftgpr,
7005		 mffgpr,     veclogical")
7006
7007   (set_attr "length"
7008		"4,          4,           4,           4,        12,
7009		 4,          8")])
7010
7011;; Split a load of a large constant into the appropriate two-insn
7012;; sequence.
7013
7014(define_split
7015  [(set (match_operand:SI 0 "gpc_reg_operand" "")
7016	(match_operand:SI 1 "const_int_operand" ""))]
7017  "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7018   && (INTVAL (operands[1]) & 0xffff) != 0"
7019  [(set (match_dup 0)
7020	(match_dup 2))
7021   (set (match_dup 0)
7022	(ior:SI (match_dup 0)
7023		(match_dup 3)))]
7024  "
7025{
7026  if (rs6000_emit_set_const (operands[0], operands[1]))
7027    DONE;
7028  else
7029    FAIL;
7030}")
7031
7032;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7033(define_split
7034  [(set (match_operand:DI 0 "altivec_register_operand")
7035	(match_operand:DI 1 "xxspltib_constant_split"))]
7036  "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
7037  [(const_int 0)]
7038{
7039  rtx op0 = operands[0];
7040  rtx op1 = operands[1];
7041  int r = REGNO (op0);
7042  rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7043
7044  emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7045  emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7046  DONE;
7047})
7048
7049(define_insn "*mov<mode>_internal2"
7050  [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7051	(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7052		    (const_int 0)))
7053   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7054  ""
7055  "@
7056   cmp<wd>i %2,%0,0
7057   mr. %0,%1
7058   #"
7059  [(set_attr "type" "cmp,logical,cmp")
7060   (set_attr "dot" "yes")
7061   (set_attr "length" "4,4,8")])
7062
7063(define_split
7064  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
7065	(compare:CC (match_operand:P 1 "gpc_reg_operand" "")
7066		    (const_int 0)))
7067   (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7068  "reload_completed"
7069  [(set (match_dup 0) (match_dup 1))
7070   (set (match_dup 2)
7071	(compare:CC (match_dup 0)
7072		    (const_int 0)))]
7073  "")
7074
7075(define_expand "mov<mode>"
7076  [(set (match_operand:INT 0 "general_operand" "")
7077	(match_operand:INT 1 "any_operand" ""))]
7078  ""
7079  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7080
7081;;		MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7082;;		XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7083;;		MTVSRWZ     MF%1       MT%1       NOP
7084(define_insn "*mov<mode>_internal"
7085  [(set (match_operand:QHI 0 "nonimmediate_operand"
7086		"=r,        r,         ?*wJwK,    m,         Z,         r,
7087		 ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7088		 ?*wJwK,    r,         *c*l,      *h")
7089
7090	(match_operand:QHI 1 "input_operand"
7091		"r,         m,         Z,         r,         wJwK,      i,
7092		 wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7093		 r,         *h,        r,         0"))]
7094
7095  "gpc_reg_operand (operands[0], <MODE>mode)
7096   || gpc_reg_operand (operands[1], <MODE>mode)"
7097  "@
7098   mr %0,%1
7099   l<wd>z%U1%X1 %0,%1
7100   lxsi<wd>zx %x0,%y1
7101   st<wd>%U0%X0 %1,%0
7102   stxsi<wd>x %x1,%y0
7103   li %0,%1
7104   xxlor %x0,%x1,%x1
7105   xxspltib %x0,0
7106   xxspltib %x0,255
7107   vspltis<wd> %0,%1
7108   #
7109   mfvsrwz %0,%x1
7110   mtvsrwz %x0,%1
7111   mf%1 %0
7112   mt%0 %1
7113   nop"
7114  [(set_attr "type"
7115		"*,         load,      fpload,    store,     fpstore,   *,
7116		 vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7117		 mffgpr,    mfjmpr,    mtjmpr,    *")
7118
7119   (set_attr "length"
7120		"4,         4,         4,         4,         4,         4,
7121		 4,         4,         4,         4,         8,         4,
7122		 4,         4,         4,         4")])
7123
7124
7125;; Here is how to move condition codes around.  When we store CC data in
7126;; an integer register or memory, we store just the high-order 4 bits.
7127;; This lets us not shift in the most common case of CR0.
7128(define_expand "movcc"
7129  [(set (match_operand:CC 0 "nonimmediate_operand" "")
7130	(match_operand:CC 1 "nonimmediate_operand" ""))]
7131  ""
7132  "")
7133
7134(define_insn "*movcc_internal1"
7135  [(set (match_operand:CC 0 "nonimmediate_operand"
7136			    "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7137	(match_operand:CC 1 "general_operand"
7138			    " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7139  "register_operand (operands[0], CCmode)
7140   || register_operand (operands[1], CCmode)"
7141  "@
7142   mcrf %0,%1
7143   mtcrf 128,%1
7144   rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7145   crxor %0,%0,%0
7146   mfcr %0%Q1
7147   mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7148   mr %0,%1
7149   li %0,%1
7150   mf%1 %0
7151   mt%0 %1
7152   lwz%U1%X1 %0,%1
7153   stw%U0%X0 %1,%0"
7154  [(set (attr "type")
7155     (cond [(eq_attr "alternative" "0,3")
7156		(const_string "cr_logical")
7157	    (eq_attr "alternative" "1,2")
7158		(const_string "mtcr")
7159	    (eq_attr "alternative" "6,7")
7160		(const_string "integer")
7161	    (eq_attr "alternative" "8")
7162		(const_string "mfjmpr")
7163	    (eq_attr "alternative" "9")
7164		(const_string "mtjmpr")
7165	    (eq_attr "alternative" "10")
7166		(const_string "load")
7167	    (eq_attr "alternative" "11")
7168		(const_string "store")
7169	    (match_test "TARGET_MFCRF")
7170		(const_string "mfcrf")
7171	   ]
7172	(const_string "mfcr")))
7173   (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7174
7175;; For floating-point, we normally deal with the floating-point registers
7176;; unless -msoft-float is used.  The sole exception is that parameter passing
7177;; can produce floating-point values in fixed-point registers.  Unless the
7178;; value is a simple constant or already in memory, we deal with this by
7179;; allocating memory and copying the value explicitly via that memory location.
7180
7181;; Move 32-bit binary/decimal floating point
7182(define_expand "mov<mode>"
7183  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7184	(match_operand:FMOVE32 1 "any_operand" ""))]
7185  "<fmove_ok>"
7186  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7187
7188(define_split
7189  [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7190	(match_operand:FMOVE32 1 "const_double_operand" ""))]
7191  "reload_completed
7192   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7193       || (GET_CODE (operands[0]) == SUBREG
7194	   && GET_CODE (SUBREG_REG (operands[0])) == REG
7195	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7196  [(set (match_dup 2) (match_dup 3))]
7197  "
7198{
7199  long l;
7200
7201  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7202
7203  if (! TARGET_POWERPC64)
7204    operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7205  else
7206    operands[2] = gen_lowpart (SImode, operands[0]);
7207
7208  operands[3] = gen_int_mode (l, SImode);
7209}")
7210
7211;; Originally, we tried to keep movsf and movsd common, but the differences
7212;; addressing was making it rather difficult to hide with mode attributes.  In
7213;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7214;; before the VSX stores meant that the register allocator would tend to do a
7215;; direct move to the GPR (which involves conversion from scalar to
7216;; vector/memory formats) to save values in the traditional Altivec registers,
7217;; while SDmode had problems on power6 if the GPR store was not first due to
7218;; the power6 not having an integer store operation.
7219;;
7220;;	LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7221;;	STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7222;;	MR           MT<x>      MF<x>       NOP
7223
7224(define_insn "movsf_hardfloat"
7225  [(set (match_operand:SF 0 "nonimmediate_operand"
7226	 "=!r,       f,         wb,         wu,        m,         wY,
7227	  Z,         m,         ww,         !r,        f,         ww,
7228	  !r,        *c*l,      !r,         *h")
7229	(match_operand:SF 1 "input_operand"
7230	 "m,         m,         wY,         Z,         f,         wb,
7231	  wu,        r,         j,          j,         f,         ww,
7232	  r,         r,         *h,         0"))]
7233  "(register_operand (operands[0], SFmode)
7234   || register_operand (operands[1], SFmode))
7235   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7236   && (TARGET_ALLOW_SF_SUBREG
7237       || valid_sf_si_move (operands[0], operands[1], SFmode))"
7238  "@
7239   lwz%U1%X1 %0,%1
7240   lfs%U1%X1 %0,%1
7241   lxssp %0,%1
7242   lxsspx %x0,%y1
7243   stfs%U0%X0 %1,%0
7244   stxssp %1,%0
7245   stxsspx %x1,%y0
7246   stw%U0%X0 %1,%0
7247   xxlxor %x0,%x0,%x0
7248   li %0,0
7249   fmr %0,%1
7250   xscpsgndp %x0,%x1,%x1
7251   mr %0,%1
7252   mt%0 %1
7253   mf%1 %0
7254   nop"
7255  [(set_attr "type"
7256	"load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7257	 fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7258	 *,          mtjmpr,    mfjmpr,     *")])
7259
7260;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7261;;	FMR          MR         MT%0       MF%1       NOP
7262(define_insn "movsd_hardfloat"
7263  [(set (match_operand:SD 0 "nonimmediate_operand"
7264	 "=!r,       wz,        m,         Z,         ?wh,       ?r,
7265	  f,         !r,        *c*l,      !r,        *h")
7266	(match_operand:SD 1 "input_operand"
7267	 "m,         Z,         r,         wx,        r,         wh,
7268	  f,         r,         r,         *h,        0"))]
7269  "(register_operand (operands[0], SDmode)
7270   || register_operand (operands[1], SDmode))
7271   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
7272  "@
7273   lwz%U1%X1 %0,%1
7274   lfiwzx %0,%y1
7275   stw%U0%X0 %1,%0
7276   stfiwx %1,%y0
7277   mtvsrwz %x0,%1
7278   mfvsrwz %0,%x1
7279   fmr %0,%1
7280   mr %0,%1
7281   mt%0 %1
7282   mf%1 %0
7283   nop"
7284  [(set_attr "type"
7285	"load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7286	 fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7287
7288(define_insn "*mov<mode>_softfloat"
7289  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7290	(match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7291  "(gpc_reg_operand (operands[0], <MODE>mode)
7292   || gpc_reg_operand (operands[1], <MODE>mode))
7293   && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7294  "@
7295   mr %0,%1
7296   mt%0 %1
7297   mf%1 %0
7298   lwz%U1%X1 %0,%1
7299   stw%U0%X0 %1,%0
7300   li %0,%1
7301   lis %0,%v1
7302   #
7303   #
7304   nop"
7305  [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7306   (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7307
7308;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7309;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7310;;
7311;; Because SF values are actually stored as DF values within the vector
7312;; registers, we need to convert the value to the vector SF format when
7313;; we need to use the bits in a union or similar cases.  We only need
7314;; to do this transformation when the value is a vector register.  Loads,
7315;; stores, and transfers within GPRs are assumed to be safe.
7316;;
7317;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7318;; no alternatives, because the call is created as part of secondary_reload,
7319;; and operand #2's register class is used to allocate the temporary register.
7320;; This function is called before reload, and it creates the temporary as
7321;; needed.
7322
7323;;	    LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7324;;	    STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7325(define_insn_and_split "movsf_from_si"
7326  [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7327	    "=!r,       f,         wb,        wu,        m,         Z,
7328	     Z,         wy,        ?r,        !r")
7329
7330	(unspec:SF [(match_operand:SI 1 "input_operand"
7331	    "m,         m,         wY,        Z,         r,         f,
7332	     wu,        r,         wy,        r")]
7333		   UNSPEC_SF_FROM_SI))
7334
7335   (clobber (match_scratch:DI 2
7336	    "=X,        X,         X,         X,         X,         X,
7337             X,         r,         X,         X"))]
7338
7339  "TARGET_NO_SF_SUBREG
7340   && (register_operand (operands[0], SFmode)
7341       || register_operand (operands[1], SImode))"
7342  "@
7343   lwz%U1%X1 %0,%1
7344   lfs%U1%X1 %0,%1
7345   lxssp %0,%1
7346   lxsspx %x0,%y1
7347   stw%U0%X0 %1,%0
7348   stfiwx %1,%y0
7349   stxsiwx %x1,%y0
7350   #
7351   mfvsrwz %0,%x1
7352   mr %0,%1"
7353
7354  "&& reload_completed
7355   && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7356   && int_reg_operand_not_pseudo (operands[1], SImode)"
7357  [(const_int 0)]
7358{
7359  rtx op0 = operands[0];
7360  rtx op1 = operands[1];
7361  rtx op2 = operands[2];
7362  rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7363
7364  /* Move SF value to upper 32-bits for xscvspdpn.  */
7365  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7366  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7367  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7368  DONE;
7369}
7370  [(set_attr "length"
7371	    "4,          4,         4,         4,         4,         4,
7372	     4,          12,        4,         4")
7373   (set_attr "type"
7374	    "load,       fpload,    fpload,    fpload,    store,     fpstore,
7375	     fpstore,    vecfloat,  mffgpr,    *")])
7376
7377
7378;; Move 64-bit binary/decimal floating point
7379(define_expand "mov<mode>"
7380  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7381	(match_operand:FMOVE64 1 "any_operand" ""))]
7382  ""
7383  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7384
7385(define_split
7386  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7387	(match_operand:FMOVE64 1 "const_int_operand" ""))]
7388  "! TARGET_POWERPC64 && reload_completed
7389   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7390       || (GET_CODE (operands[0]) == SUBREG
7391	   && GET_CODE (SUBREG_REG (operands[0])) == REG
7392	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7393  [(set (match_dup 2) (match_dup 4))
7394   (set (match_dup 3) (match_dup 1))]
7395  "
7396{
7397  int endian = (WORDS_BIG_ENDIAN == 0);
7398  HOST_WIDE_INT value = INTVAL (operands[1]);
7399
7400  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7401  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7402  operands[4] = GEN_INT (value >> 32);
7403  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7404}")
7405
7406(define_split
7407  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7408	(match_operand:FMOVE64 1 "const_double_operand" ""))]
7409  "! TARGET_POWERPC64 && reload_completed
7410   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7411       || (GET_CODE (operands[0]) == SUBREG
7412	   && GET_CODE (SUBREG_REG (operands[0])) == REG
7413	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7414  [(set (match_dup 2) (match_dup 4))
7415   (set (match_dup 3) (match_dup 5))]
7416  "
7417{
7418  int endian = (WORDS_BIG_ENDIAN == 0);
7419  long l[2];
7420
7421  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7422
7423  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7424  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7425  operands[4] = gen_int_mode (l[endian], SImode);
7426  operands[5] = gen_int_mode (l[1 - endian], SImode);
7427}")
7428
7429(define_split
7430  [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7431	(match_operand:FMOVE64 1 "const_double_operand" ""))]
7432  "TARGET_POWERPC64 && reload_completed
7433   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7434       || (GET_CODE (operands[0]) == SUBREG
7435	   && GET_CODE (SUBREG_REG (operands[0])) == REG
7436	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7437  [(set (match_dup 2) (match_dup 3))]
7438  "
7439{
7440  int endian = (WORDS_BIG_ENDIAN == 0);
7441  long l[2];
7442  HOST_WIDE_INT val;
7443
7444  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7445
7446  operands[2] = gen_lowpart (DImode, operands[0]);
7447  /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7448  val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7449         | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7450
7451  operands[3] = gen_int_mode (val, DImode);
7452}")
7453
7454;; Don't have reload use general registers to load a constant.  It is
7455;; less efficient than loading the constant into an FP register, since
7456;; it will probably be used there.
7457
7458;; The move constraints are ordered to prefer floating point registers before
7459;; general purpose registers to avoid doing a store and a load to get the value
7460;; into a floating point register when it is needed for a floating point
7461;; operation.  Prefer traditional floating point registers over VSX registers,
7462;; since the D-form version of the memory instructions does not need a GPR for
7463;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7464;; registers.
7465
7466;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7467;; except for 0.0 which can be created on VSX with an xor instruction.
7468
7469(define_insn "*mov<mode>_hardfloat32"
7470  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7471	(match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7472  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7473   && (gpc_reg_operand (operands[0], <MODE>mode)
7474       || gpc_reg_operand (operands[1], <MODE>mode))"
7475  "@
7476   stfd%U0%X0 %1,%0
7477   lfd%U1%X1 %0,%1
7478   fmr %0,%1
7479   lxsd%U1x %x0,%y1
7480   stxsd%U0x %x1,%y0
7481   lxsd %0,%1
7482   stxsd %1,%0
7483   xxlor %x0,%x1,%x1
7484   xxlxor %x0,%x0,%x0
7485   #
7486   #
7487   #
7488   #"
7489  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7490   (set_attr "size" "64")
7491   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7492
7493(define_insn "*mov<mode>_softfloat32"
7494  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7495	(match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7496  "! TARGET_POWERPC64
7497   && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
7498       || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7499       || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7500   && (gpc_reg_operand (operands[0], <MODE>mode)
7501       || gpc_reg_operand (operands[1], <MODE>mode))"
7502  "#"
7503  [(set_attr "type" "store,load,two,*,*,*")
7504   (set_attr "length" "8,8,8,8,12,16")])
7505
7506; ld/std require word-aligned displacements -> 'Y' constraint.
7507; List Y->r and r->Y before r->r for reload.
7508(define_insn "*mov<mode>_hardfloat64"
7509  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
7510	(match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
7511  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7512   && (gpc_reg_operand (operands[0], <MODE>mode)
7513       || gpc_reg_operand (operands[1], <MODE>mode))"
7514  "@
7515   stfd%U0%X0 %1,%0
7516   lfd%U1%X1 %0,%1
7517   fmr %0,%1
7518   lxsd %0,%1
7519   stxsd %1,%0
7520   lxsd%U1x %x0,%y1
7521   stxsd%U0x %x1,%y0
7522   xxlor %x0,%x1,%x1
7523   xxlxor %x0,%x0,%x0
7524   li %0,0
7525   std%U0%X0 %1,%0
7526   ld%U1%X1 %0,%1
7527   mr %0,%1
7528   mt%0 %1
7529   mf%1 %0
7530   nop
7531   mftgpr %0,%1
7532   mffgpr %0,%1
7533   mfvsrd %0,%x1
7534   mtvsrd %x0,%1"
7535  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7536   (set_attr "size" "64")
7537   (set_attr "length" "4")])
7538
7539(define_insn "*mov<mode>_softfloat64"
7540  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7541	(match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7542  "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7543   && (gpc_reg_operand (operands[0], <MODE>mode)
7544       || gpc_reg_operand (operands[1], <MODE>mode))"
7545  "@
7546   std%U0%X0 %1,%0
7547   ld%U1%X1 %0,%1
7548   mr %0,%1
7549   mt%0 %1
7550   mf%1 %0
7551   #
7552   #
7553   #
7554   nop"
7555  [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7556   (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7557
7558(define_expand "mov<mode>"
7559  [(set (match_operand:FMOVE128 0 "general_operand" "")
7560	(match_operand:FMOVE128 1 "any_operand" ""))]
7561  ""
7562  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7563
7564;; It's important to list Y->r and r->Y before r->r because otherwise
7565;; reload, given m->r, will try to pick r->r and reload it, which
7566;; doesn't make progress.
7567
7568;; We can't split little endian direct moves of TDmode, because the words are
7569;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7570;; problematical.  Don't allow direct move for this case.
7571
7572(define_insn_and_split "*mov<mode>_64bit_dm"
7573  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7574	(match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7575  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7576   && FLOAT128_2REG_P (<MODE>mode)
7577   && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7578   && (gpc_reg_operand (operands[0], <MODE>mode)
7579       || gpc_reg_operand (operands[1], <MODE>mode))"
7580  "#"
7581  "&& reload_completed"
7582  [(pc)]
7583{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7584  [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7585
7586(define_insn_and_split "*movtd_64bit_nodm"
7587  [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7588	(match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7589  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7590   && (gpc_reg_operand (operands[0], TDmode)
7591       || gpc_reg_operand (operands[1], TDmode))"
7592  "#"
7593  "&& reload_completed"
7594  [(pc)]
7595{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7596  [(set_attr "length" "8,8,8,12,12,8")])
7597
7598(define_insn_and_split "*mov<mode>_32bit"
7599  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7600	(match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7601  "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7602   && (FLOAT128_2REG_P (<MODE>mode)
7603       || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7604       || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7605   && (gpc_reg_operand (operands[0], <MODE>mode)
7606       || gpc_reg_operand (operands[1], <MODE>mode))"
7607  "#"
7608  "&& reload_completed"
7609  [(pc)]
7610{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7611  [(set_attr "length" "8,8,8,8,20,20,16")])
7612
7613(define_insn_and_split "*mov<mode>_softfloat"
7614  [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7615	(match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7616  "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7617   && (gpc_reg_operand (operands[0], <MODE>mode)
7618       || gpc_reg_operand (operands[1], <MODE>mode))"
7619  "#"
7620  "&& reload_completed"
7621  [(pc)]
7622{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7623  [(set_attr "length" "20,20,16")])
7624
7625(define_expand "extenddf<mode>2"
7626  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7627	(float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7628  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7629   && TARGET_LONG_DOUBLE_128"
7630{
7631  if (FLOAT128_IEEE_P (<MODE>mode))
7632    rs6000_expand_float128_convert (operands[0], operands[1], false);
7633  else if (TARGET_E500_DOUBLE)
7634    {
7635      gcc_assert (<MODE>mode == TFmode);
7636      emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7637    }
7638  else if (TARGET_VSX)
7639    {
7640      if (<MODE>mode == TFmode)
7641	emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7642      else if (<MODE>mode == IFmode)
7643	emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7644      else
7645	gcc_unreachable ();
7646    }
7647   else
7648    {
7649      rtx zero = gen_reg_rtx (DFmode);
7650      rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7651
7652      if (<MODE>mode == TFmode)
7653	emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7654      else if (<MODE>mode == IFmode)
7655	emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7656      else
7657	gcc_unreachable ();
7658    }
7659  DONE;
7660})
7661
7662;; Allow memory operands for the source to be created by the combiner.
7663(define_insn_and_split "extenddf<mode>2_fprs"
7664  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7665	(float_extend:IBM128
7666	 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7667   (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7668  "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7669   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7670  "#"
7671  "&& reload_completed"
7672  [(set (match_dup 3) (match_dup 1))
7673   (set (match_dup 4) (match_dup 2))]
7674{
7675  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7676  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7677
7678  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7679  operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7680})
7681
7682(define_insn_and_split "extenddf<mode>2_vsx"
7683  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7684	(float_extend:IBM128
7685	 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7686  "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7687  "#"
7688  "&& reload_completed"
7689  [(set (match_dup 2) (match_dup 1))
7690   (set (match_dup 3) (match_dup 4))]
7691{
7692  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7693  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7694
7695  operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7696  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7697  operands[4] = CONST0_RTX (DFmode);
7698})
7699
7700(define_expand "extendsf<mode>2"
7701  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7702	(float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7703  "TARGET_HARD_FLOAT
7704   && (TARGET_FPRS || TARGET_E500_DOUBLE)
7705   && TARGET_LONG_DOUBLE_128"
7706{
7707  if (FLOAT128_IEEE_P (<MODE>mode))
7708    rs6000_expand_float128_convert (operands[0], operands[1], false);
7709  else
7710    {
7711      rtx tmp = gen_reg_rtx (DFmode);
7712      emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7713      emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7714    }
7715  DONE;
7716})
7717
7718(define_expand "trunc<mode>df2"
7719  [(set (match_operand:DF 0 "gpc_reg_operand" "")
7720	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7721  "TARGET_HARD_FLOAT
7722   && (TARGET_FPRS || TARGET_E500_DOUBLE)
7723   && TARGET_LONG_DOUBLE_128"
7724{
7725  if (FLOAT128_IEEE_P (<MODE>mode))
7726    {
7727      rs6000_expand_float128_convert (operands[0], operands[1], false);
7728      DONE;
7729    }
7730})
7731
7732(define_insn_and_split "trunc<mode>df2_internal1"
7733  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7734	(float_truncate:DF
7735	 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7736  "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7737   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7738  "@
7739   #
7740   fmr %0,%1"
7741  "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7742  [(const_int 0)]
7743{
7744  emit_note (NOTE_INSN_DELETED);
7745  DONE;
7746}
7747  [(set_attr "type" "fpsimple")])
7748
7749(define_insn "trunc<mode>df2_internal2"
7750  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7751	(float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7752  "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7753   && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7754  "fadd %0,%1,%L1"
7755  [(set_attr "type" "fp")
7756   (set_attr "fp_type" "fp_addsub_d")])
7757
7758(define_expand "trunc<mode>sf2"
7759  [(set (match_operand:SF 0 "gpc_reg_operand" "")
7760	(float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7761  "TARGET_HARD_FLOAT
7762   && (TARGET_FPRS || TARGET_E500_DOUBLE)
7763   && TARGET_LONG_DOUBLE_128"
7764{
7765  if (FLOAT128_IEEE_P (<MODE>mode))
7766    rs6000_expand_float128_convert (operands[0], operands[1], false);
7767  else if (TARGET_E500_DOUBLE)
7768    {
7769      gcc_assert (<MODE>mode == TFmode);
7770      emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7771    }
7772  else if (<MODE>mode == TFmode)
7773    emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7774  else if (<MODE>mode == IFmode)
7775    emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7776  else
7777    gcc_unreachable ();
7778  DONE;
7779})
7780
7781(define_insn_and_split "trunc<mode>sf2_fprs"
7782  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7783	(float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7784   (clobber (match_scratch:DF 2 "=d"))]
7785  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7786   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7787  "#"
7788  "&& reload_completed"
7789  [(set (match_dup 2)
7790	(float_truncate:DF (match_dup 1)))
7791   (set (match_dup 0)
7792	(float_truncate:SF (match_dup 2)))]
7793  "")
7794
7795(define_expand "floatsi<mode>2"
7796  [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7797		   (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7798	      (clobber (match_scratch:DI 2))])]
7799  "TARGET_HARD_FLOAT
7800   && (TARGET_FPRS || TARGET_E500_DOUBLE)
7801   && TARGET_LONG_DOUBLE_128"
7802{
7803  rtx op0 = operands[0];
7804  rtx op1 = operands[1];
7805
7806  if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7807    ;
7808  else if (FLOAT128_IEEE_P (<MODE>mode))
7809    {
7810      rs6000_expand_float128_convert (op0, op1, false);
7811      DONE;
7812    }
7813  else
7814    {
7815      rtx tmp = gen_reg_rtx (DFmode);
7816      expand_float (tmp, op1, false);
7817      if (<MODE>mode == TFmode)
7818	emit_insn (gen_extenddftf2 (op0, tmp));
7819      else if (<MODE>mode == IFmode)
7820	emit_insn (gen_extenddfif2 (op0, tmp));
7821      else
7822	gcc_unreachable ();
7823      DONE;
7824    }
7825})
7826
7827; fadd, but rounding towards zero.
7828; This is probably not the optimal code sequence.
7829(define_insn "fix_trunc_helper<mode>"
7830  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7831	(unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7832		   UNSPEC_FIX_TRUNC_TF))
7833   (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7834  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7835   && FLOAT128_IBM_P (<MODE>mode)"
7836  "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7837  [(set_attr "type" "fp")
7838   (set_attr "length" "20")])
7839
7840(define_expand "fix_trunc<mode>si2"
7841  [(set (match_operand:SI 0 "gpc_reg_operand" "")
7842	(fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7843  "TARGET_HARD_FLOAT
7844   && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7845{
7846  rtx op0 = operands[0];
7847  rtx op1 = operands[1];
7848
7849  if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7850    ;
7851  else
7852    {
7853      if (FLOAT128_IEEE_P (<MODE>mode))
7854	rs6000_expand_float128_convert (op0, op1, false);
7855      else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7856	emit_insn (gen_spe_fix_trunctfsi2 (op0, op1));
7857      else if (<MODE>mode == TFmode)
7858	emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7859      else if (<MODE>mode == IFmode)
7860	emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7861      else
7862	gcc_unreachable ();
7863      DONE;
7864    }
7865})
7866
7867(define_expand "fix_trunc<mode>si2_fprs"
7868  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7869		   (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7870	      (clobber (match_dup 2))
7871	      (clobber (match_dup 3))
7872	      (clobber (match_dup 4))
7873	      (clobber (match_dup 5))])]
7874  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7875{
7876  operands[2] = gen_reg_rtx (DFmode);
7877  operands[3] = gen_reg_rtx (DFmode);
7878  operands[4] = gen_reg_rtx (DImode);
7879  operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7880})
7881
7882(define_insn_and_split "*fix_trunc<mode>si2_internal"
7883  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7884        (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7885   (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7886   (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7887   (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7888   (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7889  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7890  "#"
7891  ""
7892  [(pc)]
7893{
7894  rtx lowword;
7895  emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7896					 operands[3]));
7897
7898  gcc_assert (MEM_P (operands[5]));
7899  lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7900
7901  emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7902  emit_move_insn (operands[5], operands[4]);
7903  emit_move_insn (operands[0], lowword);
7904  DONE;
7905})
7906
7907(define_expand "fix_trunc<mode>di2"
7908  [(set (match_operand:DI 0 "gpc_reg_operand" "")
7909	(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7910  "TARGET_FLOAT128_TYPE"
7911{
7912  if (!TARGET_FLOAT128_HW)
7913    {
7914      rs6000_expand_float128_convert (operands[0], operands[1], false);
7915      DONE;
7916    }
7917})
7918
7919(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7920  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7921	(unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7922  "TARGET_FLOAT128_TYPE"
7923{
7924  rs6000_expand_float128_convert (operands[0], operands[1], true);
7925  DONE;
7926})
7927
7928(define_expand "floatdi<mode>2"
7929  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7930	(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7931  "TARGET_FLOAT128_TYPE"
7932{
7933  if (!TARGET_FLOAT128_HW)
7934    {
7935      rs6000_expand_float128_convert (operands[0], operands[1], false);
7936      DONE;
7937    }
7938})
7939
7940(define_expand "floatunsdi<IEEE128:mode>2"
7941  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7942	(unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7943  "TARGET_FLOAT128_TYPE"
7944{
7945  if (!TARGET_FLOAT128_HW)
7946    {
7947      rs6000_expand_float128_convert (operands[0], operands[1], true);
7948      DONE;
7949    }
7950})
7951
7952(define_expand "floatuns<IEEE128:mode>2"
7953  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7954	(unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7955  "TARGET_FLOAT128_TYPE"
7956{
7957  rtx op0 = operands[0];
7958  rtx op1 = operands[1];
7959
7960  if (TARGET_FLOAT128_HW)
7961    emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7962  else
7963    rs6000_expand_float128_convert (op0, op1, true);
7964  DONE;
7965})
7966
7967(define_expand "neg<mode>2"
7968  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7969	(neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7970  "FLOAT128_IEEE_P (<MODE>mode)
7971   || (FLOAT128_IBM_P (<MODE>mode)
7972       && TARGET_HARD_FLOAT
7973       && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7974  "
7975{
7976  if (FLOAT128_IEEE_P (<MODE>mode))
7977    {
7978      if (TARGET_FLOAT128_HW)
7979	{
7980	  if (<MODE>mode == TFmode)
7981	    emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7982	  else if (<MODE>mode == KFmode)
7983	    emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7984	  else
7985	    gcc_unreachable ();
7986	}
7987      else if (TARGET_FLOAT128_TYPE)
7988	{
7989	  if (<MODE>mode == TFmode)
7990	    emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7991	  else if (<MODE>mode == KFmode)
7992	    emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7993	  else
7994	    gcc_unreachable ();
7995	}
7996      else
7997	{
7998	  rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7999	  rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8000						<MODE>mode,
8001						operands[1], <MODE>mode);
8002
8003	  if (target && !rtx_equal_p (target, operands[0]))
8004	    emit_move_insn (operands[0], target);
8005	}
8006      DONE;
8007    }
8008}")
8009
8010(define_insn "neg<mode>2_internal"
8011  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8012	(neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8013  "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
8014  "*
8015{
8016  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8017    return \"fneg %L0,%L1\;fneg %0,%1\";
8018  else
8019    return \"fneg %0,%1\;fneg %L0,%L1\";
8020}"
8021  [(set_attr "type" "fpsimple")
8022   (set_attr "length" "8")])
8023
8024(define_expand "abs<mode>2"
8025  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
8026	(abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
8027  "FLOAT128_IEEE_P (<MODE>mode)
8028   || (FLOAT128_IBM_P (<MODE>mode)
8029       && TARGET_HARD_FLOAT
8030       && (TARGET_FPRS || TARGET_E500_DOUBLE))"
8031  "
8032{
8033  rtx label;
8034
8035  if (FLOAT128_IEEE_P (<MODE>mode))
8036    {
8037      if (TARGET_FLOAT128_HW)
8038	{
8039	  if (<MODE>mode == TFmode)
8040	    emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8041	  else if (<MODE>mode == KFmode)
8042	    emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8043	  else
8044	    FAIL;
8045	  DONE;
8046	}
8047      else if (TARGET_FLOAT128_TYPE)
8048	{
8049	  if (<MODE>mode == TFmode)
8050	    emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8051	  else if (<MODE>mode == KFmode)
8052	    emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8053	  else
8054	    FAIL;
8055	  DONE;
8056	}
8057      else
8058	FAIL;
8059    }
8060
8061  label = gen_label_rtx ();
8062  if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
8063    {
8064      if (flag_finite_math_only && !flag_trapping_math)
8065	emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
8066      else
8067	emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
8068    }
8069  else if (<MODE>mode == TFmode)
8070    emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8071  else if (<MODE>mode == TFmode)
8072    emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8073  else
8074    FAIL;
8075  emit_label (label);
8076  DONE;
8077}")
8078
8079(define_expand "abs<mode>2_internal"
8080  [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8081	(match_operand:IBM128 1 "gpc_reg_operand" ""))
8082   (set (match_dup 3) (match_dup 5))
8083   (set (match_dup 5) (abs:DF (match_dup 5)))
8084   (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8085   (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8086			   (label_ref (match_operand 2 "" ""))
8087			   (pc)))
8088   (set (match_dup 6) (neg:DF (match_dup 6)))]
8089  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8090   && TARGET_LONG_DOUBLE_128"
8091  "
8092{
8093  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8094  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8095  operands[3] = gen_reg_rtx (DFmode);
8096  operands[4] = gen_reg_rtx (CCFPmode);
8097  operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8098  operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8099}")
8100
8101
8102;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8103;; register
8104
8105(define_expand "ieee_128bit_negative_zero"
8106  [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8107  "TARGET_FLOAT128_TYPE"
8108{
8109  rtvec v = rtvec_alloc (16);
8110  int i, high;
8111
8112  for (i = 0; i < 16; i++)
8113    RTVEC_ELT (v, i) = const0_rtx;
8114
8115  high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8116  RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8117
8118  rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8119  DONE;
8120})
8121
8122;; IEEE 128-bit negate
8123
8124;; We have 2 insns here for negate and absolute value.  The first uses
8125;; match_scratch so that phases like combine can recognize neg/abs as generic
8126;; insns, and second insn after the first split pass loads up the bit to
8127;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8128;; neg/abs to create the constant just once.
8129
8130(define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8131  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8132	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8133   (clobber (match_scratch:V16QI 2 "=v"))]
8134  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8135  "#"
8136  "&& 1"
8137  [(parallel [(set (match_dup 0)
8138		   (neg:IEEE128 (match_dup 1)))
8139	      (use (match_dup 2))])]
8140{
8141  if (GET_CODE (operands[2]) == SCRATCH)
8142    operands[2] = gen_reg_rtx (V16QImode);
8143
8144  operands[3] = gen_reg_rtx (V16QImode);
8145  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8146}
8147  [(set_attr "length" "8")
8148   (set_attr "type" "vecsimple")])
8149
8150(define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8151  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8152	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8153   (use (match_operand:V16QI 2 "register_operand" "v"))]
8154  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8155  "xxlxor %x0,%x1,%x2"
8156  [(set_attr "type" "veclogical")])
8157
8158;; IEEE 128-bit absolute value
8159(define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8160  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8161	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8162   (clobber (match_scratch:V16QI 2 "=v"))]
8163  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8164  "#"
8165  "&& 1"
8166  [(parallel [(set (match_dup 0)
8167		   (abs:IEEE128 (match_dup 1)))
8168	      (use (match_dup 2))])]
8169{
8170  if (GET_CODE (operands[2]) == SCRATCH)
8171    operands[2] = gen_reg_rtx (V16QImode);
8172
8173  operands[3] = gen_reg_rtx (V16QImode);
8174  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8175}
8176  [(set_attr "length" "8")
8177   (set_attr "type" "vecsimple")])
8178
8179(define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8180  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8181	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8182   (use (match_operand:V16QI 2 "register_operand" "v"))]
8183  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8184  "xxlandc %x0,%x1,%x2"
8185  [(set_attr "type" "veclogical")])
8186
8187;; IEEE 128-bit negative absolute value
8188(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8189  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8190	(neg:IEEE128
8191	 (abs:IEEE128
8192	  (match_operand:IEEE128 1 "register_operand" "wa"))))
8193   (clobber (match_scratch:V16QI 2 "=v"))]
8194  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8195   && FLOAT128_IEEE_P (<MODE>mode)"
8196  "#"
8197  "&& 1"
8198  [(parallel [(set (match_dup 0)
8199		   (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8200	      (use (match_dup 2))])]
8201{
8202  if (GET_CODE (operands[2]) == SCRATCH)
8203    operands[2] = gen_reg_rtx (V16QImode);
8204
8205  operands[3] = gen_reg_rtx (V16QImode);
8206  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8207}
8208  [(set_attr "length" "8")
8209   (set_attr "type" "vecsimple")])
8210
8211(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8212  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8213	(neg:IEEE128
8214	 (abs:IEEE128
8215	  (match_operand:IEEE128 1 "register_operand" "wa"))))
8216   (use (match_operand:V16QI 2 "register_operand" "v"))]
8217  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8218  "xxlor %x0,%x1,%x2"
8219  [(set_attr "type" "veclogical")])
8220
8221;; Float128 conversion functions.  These expand to library function calls.
8222;; We use expand to convert from IBM double double to IEEE 128-bit
8223;; and trunc for the opposite.
8224(define_expand "extendiftf2"
8225  [(set (match_operand:TF 0 "gpc_reg_operand" "")
8226	(float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8227  "TARGET_FLOAT128_TYPE"
8228{
8229  rs6000_expand_float128_convert (operands[0], operands[1], false);
8230  DONE;
8231})
8232
8233(define_expand "extendifkf2"
8234  [(set (match_operand:KF 0 "gpc_reg_operand" "")
8235	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8236  "TARGET_FLOAT128_TYPE"
8237{
8238  rs6000_expand_float128_convert (operands[0], operands[1], false);
8239  DONE;
8240})
8241
8242(define_expand "extendtfkf2"
8243  [(set (match_operand:KF 0 "gpc_reg_operand" "")
8244	(float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8245  "TARGET_FLOAT128_TYPE"
8246{
8247  rs6000_expand_float128_convert (operands[0], operands[1], false);
8248  DONE;
8249})
8250
8251(define_expand "trunciftf2"
8252  [(set (match_operand:IF 0 "gpc_reg_operand" "")
8253	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8254  "TARGET_FLOAT128_TYPE"
8255{
8256  rs6000_expand_float128_convert (operands[0], operands[1], false);
8257  DONE;
8258})
8259
8260(define_expand "truncifkf2"
8261  [(set (match_operand:IF 0 "gpc_reg_operand" "")
8262	(float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8263  "TARGET_FLOAT128_TYPE"
8264{
8265  rs6000_expand_float128_convert (operands[0], operands[1], false);
8266  DONE;
8267})
8268
8269(define_expand "trunckftf2"
8270  [(set (match_operand:TF 0 "gpc_reg_operand" "")
8271	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8272  "TARGET_FLOAT128_TYPE"
8273{
8274  rs6000_expand_float128_convert (operands[0], operands[1], false);
8275  DONE;
8276})
8277
8278(define_expand "trunctfif2"
8279  [(set (match_operand:IF 0 "gpc_reg_operand" "")
8280	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8281  "TARGET_FLOAT128_TYPE"
8282{
8283  rs6000_expand_float128_convert (operands[0], operands[1], false);
8284  DONE;
8285})
8286
8287
8288;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8289;; must have 3 arguments, and scratch register constraint must be a single
8290;; constraint.
8291
8292;; Reload patterns to support gpr load/store with misaligned mem.
8293;; and multiple gpr load/store at offset >= 0xfffc
8294(define_expand "reload_<mode>_store"
8295  [(parallel [(match_operand 0 "memory_operand" "=m")
8296              (match_operand 1 "gpc_reg_operand" "r")
8297              (match_operand:GPR 2 "register_operand" "=&b")])]
8298  ""
8299{
8300  rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8301  DONE;
8302})
8303
8304(define_expand "reload_<mode>_load"
8305  [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8306              (match_operand 1 "memory_operand" "m")
8307              (match_operand:GPR 2 "register_operand" "=b")])]
8308  ""
8309{
8310  rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8311  DONE;
8312})
8313
8314
8315;; Reload patterns for various types using the vector registers.  We may need
8316;; an additional base register to convert the reg+offset addressing to reg+reg
8317;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8318;; index register for gpr registers.
8319(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8320  [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8321              (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8322              (match_operand:P 2 "register_operand" "=b")])]
8323  "<P:tptrsize>"
8324{
8325  rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8326  DONE;
8327})
8328
8329(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8330  [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8331              (match_operand:RELOAD 1 "memory_operand" "m")
8332              (match_operand:P 2 "register_operand" "=b")])]
8333  "<P:tptrsize>"
8334{
8335  rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8336  DONE;
8337})
8338
8339
8340;; Reload sometimes tries to move the address to a GPR, and can generate
8341;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8342;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8343
8344(define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8345  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8346	(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8347		       (match_operand:P 2 "reg_or_cint_operand" "rI"))
8348	       (const_int -16)))]
8349  "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8350  "#"
8351  "&& reload_completed"
8352  [(set (match_dup 0)
8353	(plus:P (match_dup 1)
8354		(match_dup 2)))
8355   (set (match_dup 0)
8356	(and:P (match_dup 0)
8357	       (const_int -16)))])
8358
8359;; Power8 merge instructions to allow direct move to/from floating point
8360;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8361;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8362;; value, since it is allocated in reload and not all of the flow information
8363;; is setup for it.  We have two patterns to do the two moves between gprs and
8364;; fprs.  There isn't a dependancy between the two, but we could potentially
8365;; schedule other instructions between the two instructions.
8366
8367(define_insn "p8_fmrgow_<mode>"
8368  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8369	(unspec:FMOVE64X [
8370		(match_operand:DF 1 "register_operand" "d")
8371		(match_operand:DF 2 "register_operand" "d")]
8372			 UNSPEC_P8V_FMRGOW))]
8373  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8374  "fmrgow %0,%1,%2"
8375  [(set_attr "type" "fpsimple")])
8376
8377(define_insn "p8_mtvsrwz"
8378  [(set (match_operand:DF 0 "register_operand" "=d")
8379	(unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8380		   UNSPEC_P8V_MTVSRWZ))]
8381  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8382  "mtvsrwz %x0,%1"
8383  [(set_attr "type" "mftgpr")])
8384
8385(define_insn_and_split "reload_fpr_from_gpr<mode>"
8386  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8387	(unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8388			 UNSPEC_P8V_RELOAD_FROM_GPR))
8389   (clobber (match_operand:IF 2 "register_operand" "=d"))]
8390  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8391  "#"
8392  "&& reload_completed"
8393  [(const_int 0)]
8394{
8395  rtx dest = operands[0];
8396  rtx src = operands[1];
8397  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8398  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8399  rtx gpr_hi_reg = gen_highpart (SImode, src);
8400  rtx gpr_lo_reg = gen_lowpart (SImode, src);
8401
8402  emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8403  emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8404  emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8405  DONE;
8406}
8407  [(set_attr "length" "12")
8408   (set_attr "type" "three")])
8409
8410;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8411(define_insn "p8_mtvsrd_df"
8412  [(set (match_operand:DF 0 "register_operand" "=wa")
8413	(unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8414		   UNSPEC_P8V_MTVSRD))]
8415  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8416  "mtvsrd %x0,%1"
8417  [(set_attr "type" "mftgpr")])
8418
8419(define_insn "p8_xxpermdi_<mode>"
8420  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8421	(unspec:FMOVE128_GPR [
8422		(match_operand:DF 1 "register_operand" "wa")
8423		(match_operand:DF 2 "register_operand" "wa")]
8424		UNSPEC_P8V_XXPERMDI))]
8425  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8426  "xxpermdi %x0,%x1,%x2,0"
8427  [(set_attr "type" "vecperm")])
8428
8429(define_insn_and_split "reload_vsx_from_gpr<mode>"
8430  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8431	(unspec:FMOVE128_GPR
8432	 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8433	 UNSPEC_P8V_RELOAD_FROM_GPR))
8434   (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8435  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8436  "#"
8437  "&& reload_completed"
8438  [(const_int 0)]
8439{
8440  rtx dest = operands[0];
8441  rtx src = operands[1];
8442  /* You might think that we could use op0 as one temp and a DF clobber
8443     as op2, but you'd be wrong.  Secondary reload move patterns don't
8444     check for overlap of the clobber and the destination.  */
8445  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8446  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8447  rtx gpr_hi_reg = gen_highpart (DImode, src);
8448  rtx gpr_lo_reg = gen_lowpart (DImode, src);
8449
8450  emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8451  emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8452  emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8453  DONE;
8454}
8455  [(set_attr "length" "12")
8456   (set_attr "type" "three")])
8457
8458(define_split
8459  [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8460	(match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8461  "reload_completed
8462   && (int_reg_operand (operands[0], <MODE>mode)
8463       || int_reg_operand (operands[1], <MODE>mode))
8464   && (!TARGET_DIRECT_MOVE_128
8465       || (!vsx_register_operand (operands[0], <MODE>mode)
8466           && !vsx_register_operand (operands[1], <MODE>mode)))"
8467  [(pc)]
8468{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8469
8470;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8471;; type is stored internally as double precision in the VSX registers, we have
8472;; to convert it from the vector format.
8473(define_insn "p8_mtvsrd_sf"
8474  [(set (match_operand:SF 0 "register_operand" "=wa")
8475	(unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8476		   UNSPEC_P8V_MTVSRD))]
8477  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8478  "mtvsrd %x0,%1"
8479  [(set_attr "type" "mftgpr")])
8480
8481(define_insn_and_split "reload_vsx_from_gprsf"
8482  [(set (match_operand:SF 0 "register_operand" "=wa")
8483	(unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8484		   UNSPEC_P8V_RELOAD_FROM_GPR))
8485   (clobber (match_operand:DI 2 "register_operand" "=r"))]
8486  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8487  "#"
8488  "&& reload_completed"
8489  [(const_int 0)]
8490{
8491  rtx op0 = operands[0];
8492  rtx op1 = operands[1];
8493  rtx op2 = operands[2];
8494  rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8495
8496  /* Move SF value to upper 32-bits for xscvspdpn.  */
8497  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8498  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8499  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8500  DONE;
8501}
8502  [(set_attr "length" "8")
8503   (set_attr "type" "two")])
8504
8505;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8506;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8507;; and then doing a move of that.
8508(define_insn "p8_mfvsrd_3_<mode>"
8509  [(set (match_operand:DF 0 "register_operand" "=r")
8510	(unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8511		   UNSPEC_P8V_RELOAD_FROM_VSX))]
8512  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8513  "mfvsrd %0,%x1"
8514  [(set_attr "type" "mftgpr")])
8515
8516(define_insn_and_split "reload_gpr_from_vsx<mode>"
8517  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8518	(unspec:FMOVE128_GPR
8519	 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8520	 UNSPEC_P8V_RELOAD_FROM_VSX))
8521   (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8522  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8523  "#"
8524  "&& reload_completed"
8525  [(const_int 0)]
8526{
8527  rtx dest = operands[0];
8528  rtx src = operands[1];
8529  rtx tmp = operands[2];
8530  rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8531  rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8532
8533  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8534  emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8535  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8536  DONE;
8537}
8538  [(set_attr "length" "12")
8539   (set_attr "type" "three")])
8540
8541;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8542;; type is stored internally as double precision, we have to convert it to the
8543;; vector format.
8544
8545(define_insn_and_split "reload_gpr_from_vsxsf"
8546  [(set (match_operand:SF 0 "register_operand" "=r")
8547	(unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8548		   UNSPEC_P8V_RELOAD_FROM_VSX))
8549   (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8550  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8551  "#"
8552  "&& reload_completed"
8553  [(const_int 0)]
8554{
8555  rtx op0 = operands[0];
8556  rtx op1 = operands[1];
8557  rtx op2 = operands[2];
8558  rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8559
8560  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8561  emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8562  emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8563  DONE;
8564}
8565  [(set_attr "length" "12")
8566   (set_attr "type" "three")])
8567
8568(define_insn "p8_mfvsrd_4_disf"
8569  [(set (match_operand:DI 0 "register_operand" "=r")
8570	(unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8571		   UNSPEC_P8V_RELOAD_FROM_VSX))]
8572  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8573  "mfvsrd %0,%x1"
8574  [(set_attr "type" "mftgpr")])
8575
8576
8577;; Next come the multi-word integer load and store and the load and store
8578;; multiple insns.
8579
8580;; List r->r after r->Y, otherwise reload will try to reload a
8581;; non-offsettable address by using r->r which won't make progress.
8582;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8583;; a gpr into a fpr instead of reloading an invalid 'Y' address
8584
8585;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8586;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8587;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8588;;        AVX const
8589
8590(define_insn "*movdi_internal32"
8591  [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8592         "=Y,        r,         r,         ^m,        ^d,         ^d,
8593          r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8594          *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8595          *wv")
8596
8597	(match_operand:DI 1 "input_operand"
8598          "r,        Y,         r,         d,         m,          d,
8599           IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8600           Oj,       wM,        OjwM,      Oj,        wM,         wS,
8601           wB"))]
8602
8603  "! TARGET_POWERPC64
8604   && (gpc_reg_operand (operands[0], DImode)
8605       || gpc_reg_operand (operands[1], DImode))"
8606  "@
8607   #
8608   #
8609   #
8610   stfd%U0%X0 %1,%0
8611   lfd%U1%X1 %0,%1
8612   fmr %0,%1
8613   #
8614   stxsd %1,%0
8615   stxsdx %x1,%y0
8616   lxsd %0,%1
8617   lxsdx %x0,%y1
8618   xxlor %x0,%x1,%x1
8619   xxspltib %x0,0
8620   xxspltib %x0,255
8621   vspltisw %0,%1
8622   xxlxor %x0,%x0,%x0
8623   xxlorc %x0,%x0,%x0
8624   #
8625   #"
8626  [(set_attr "type"
8627               "store,     load,      *,         fpstore,    fpload,     fpsimple,
8628                *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8629                vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8630                vecsimple")
8631   (set_attr "size" "64")])
8632
8633(define_split
8634  [(set (match_operand:DI 0 "gpc_reg_operand" "")
8635	(match_operand:DI 1 "const_int_operand" ""))]
8636  "! TARGET_POWERPC64 && reload_completed
8637   && gpr_or_gpr_p (operands[0], operands[1])
8638   && !direct_move_p (operands[0], operands[1])"
8639  [(set (match_dup 2) (match_dup 4))
8640   (set (match_dup 3) (match_dup 1))]
8641  "
8642{
8643  HOST_WIDE_INT value = INTVAL (operands[1]);
8644  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8645				       DImode);
8646  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8647				       DImode);
8648  operands[4] = GEN_INT (value >> 32);
8649  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8650}")
8651
8652(define_split
8653  [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8654        (match_operand:DIFD 1 "input_operand" ""))]
8655  "reload_completed && !TARGET_POWERPC64
8656   && gpr_or_gpr_p (operands[0], operands[1])
8657   && !direct_move_p (operands[0], operands[1])"
8658  [(pc)]
8659{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8660
8661;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8662;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8663;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8664;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8665;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8666(define_insn "*movdi_internal64"
8667  [(set (match_operand:DI 0 "nonimmediate_operand"
8668               "=Y,        r,         r,         r,         r,          r,
8669                ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8670                $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8671                *wi,       *wv,       *wv,       r,         *h,         *h,
8672                ?*r,       ?*wg,      ?*r,       ?*wj")
8673
8674	(match_operand:DI 1 "input_operand"
8675                "r,        Y,         r,         I,         L,          nF,
8676                 d,        m,         d,         wb,        wv,         wY,
8677                 Z,        wi,        Oj,        wM,        OjwM,       Oj,
8678                 wM,       wS,        wB,        *h,        r,          0,
8679                 wg,       r,         wj,        r"))]
8680
8681  "TARGET_POWERPC64
8682   && (gpc_reg_operand (operands[0], DImode)
8683       || gpc_reg_operand (operands[1], DImode))"
8684  "@
8685   std%U0%X0 %1,%0
8686   ld%U1%X1 %0,%1
8687   mr %0,%1
8688   li %0,%1
8689   lis %0,%v1
8690   #
8691   stfd%U0%X0 %1,%0
8692   lfd%U1%X1 %0,%1
8693   fmr %0,%1
8694   stxsd %1,%0
8695   stxsdx %x1,%y0
8696   lxsd %0,%1
8697   lxsdx %x0,%y1
8698   xxlor %x0,%x1,%x1
8699   xxspltib %x0,0
8700   xxspltib %x0,255
8701   #
8702   xxlxor %x0,%x0,%x0
8703   xxlorc %x0,%x0,%x0
8704   #
8705   #
8706   mf%1 %0
8707   mt%0 %1
8708   nop
8709   mftgpr %0,%1
8710   mffgpr %0,%1
8711   mfvsrd %0,%x1
8712   mtvsrd %x0,%1"
8713  [(set_attr "type"
8714               "store,      load,	*,         *,         *,         *,
8715                fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8716                fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8717                veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8718                mftgpr,     mffgpr,     mftgpr,    mffgpr")
8719
8720   (set_attr "size" "64")
8721   (set_attr "length"
8722               "4,         4,         4,         4,         4,          20,
8723                4,         4,         4,         4,         4,          4,
8724                4,         4,         4,         4,         4,          8,
8725                8,         4,         4,         4,         4,          4,
8726                4,         4,         4,         4")])
8727
8728; Some DImode loads are best done as a load of -1 followed by a mask
8729; instruction.
8730(define_split
8731  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8732	(match_operand:DI 1 "const_int_operand"))]
8733  "TARGET_POWERPC64
8734   && num_insns_constant (operands[1], DImode) > 1
8735   && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8736   && rs6000_is_valid_and_mask (operands[1], DImode)"
8737  [(set (match_dup 0)
8738	(const_int -1))
8739   (set (match_dup 0)
8740	(and:DI (match_dup 0)
8741		(match_dup 1)))]
8742  "")
8743
8744;; Split a load of a large constant into the appropriate five-instruction
8745;; sequence.  Handle anything in a constant number of insns.
8746;; When non-easy constants can go in the TOC, this should use
8747;; easy_fp_constant predicate.
8748(define_split
8749  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8750	(match_operand:DI 1 "const_int_operand" ""))]
8751  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8752  [(set (match_dup 0) (match_dup 2))
8753   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8754  "
8755{
8756  if (rs6000_emit_set_const (operands[0], operands[1]))
8757    DONE;
8758  else
8759    FAIL;
8760}")
8761
8762(define_split
8763  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8764	(match_operand:DI 1 "const_scalar_int_operand" ""))]
8765  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8766  [(set (match_dup 0) (match_dup 2))
8767   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8768  "
8769{
8770  if (rs6000_emit_set_const (operands[0], operands[1]))
8771    DONE;
8772  else
8773    FAIL;
8774}")
8775
8776(define_split
8777  [(set (match_operand:DI 0 "altivec_register_operand" "")
8778	(match_operand:DI 1 "s5bit_cint_operand" ""))]
8779  "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8780  [(const_int 0)]
8781{
8782  rtx op0 = operands[0];
8783  rtx op1 = operands[1];
8784  int r = REGNO (op0);
8785  rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8786
8787  emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8788  if (op1 != const0_rtx && op1 != constm1_rtx)
8789    {
8790      rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8791      emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8792    }
8793  DONE;
8794})
8795
8796;; Split integer constants that can be loaded with XXSPLTIB and a
8797;; sign extend operation.
8798(define_split
8799  [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8800	(match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8801  "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8802  [(const_int 0)]
8803{
8804  rtx op0 = operands[0];
8805  rtx op1 = operands[1];
8806  int r = REGNO (op0);
8807  rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8808
8809  emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8810  if (<MODE>mode == DImode)
8811    emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8812  else if (<MODE>mode == SImode)
8813    emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8814  else if (<MODE>mode == HImode)
8815    {
8816      rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8817      emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8818    }
8819  DONE;
8820})
8821
8822
8823;; TImode/PTImode is similar, except that we usually want to compute the
8824;; address into a register and use lsi/stsi (the exception is during reload).
8825
8826(define_insn "*mov<mode>_string"
8827  [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8828	(match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8829  "! TARGET_POWERPC64
8830   && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8831   && (gpc_reg_operand (operands[0], <MODE>mode)
8832       || gpc_reg_operand (operands[1], <MODE>mode))"
8833  "*
8834{
8835  switch (which_alternative)
8836    {
8837    default:
8838      gcc_unreachable ();
8839    case 0:
8840      if (TARGET_STRING)
8841        return \"stswi %1,%P0,16\";
8842      /* FALLTHRU */
8843    case 1:
8844      return \"#\";
8845    case 2:
8846      /* If the address is not used in the output, we can use lsi.  Otherwise,
8847	 fall through to generating four loads.  */
8848      if (TARGET_STRING
8849          && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8850	return \"lswi %0,%P1,16\";
8851      /* fall through */
8852    case 3:
8853    case 4:
8854    case 5:
8855      return \"#\";
8856    }
8857}"
8858  [(set_attr "type" "store,store,load,load,*,*")
8859   (set_attr "update" "yes")
8860   (set_attr "indexed" "yes")
8861   (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8862   			                  (const_string "always")
8863					  (const_string "conditional")))])
8864
8865(define_insn "*mov<mode>_ppc64"
8866  [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8867	(match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8868  "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8869   && (gpc_reg_operand (operands[0], <MODE>mode)
8870       || gpc_reg_operand (operands[1], <MODE>mode)))"
8871{
8872  return rs6000_output_move_128bit (operands);
8873}
8874  [(set_attr "type" "store,store,load,load,*,*")
8875   (set_attr "length" "8")])
8876
8877(define_split
8878  [(set (match_operand:TI2 0 "int_reg_operand" "")
8879	(match_operand:TI2 1 "const_scalar_int_operand" ""))]
8880  "TARGET_POWERPC64
8881   && (VECTOR_MEM_NONE_P (<MODE>mode)
8882       || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8883  [(set (match_dup 2) (match_dup 4))
8884   (set (match_dup 3) (match_dup 5))]
8885  "
8886{
8887  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8888				       <MODE>mode);
8889  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8890				       <MODE>mode);
8891  if (CONST_WIDE_INT_P (operands[1]))
8892    {
8893      operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8894      operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8895    }
8896  else if (CONST_INT_P (operands[1]))
8897    {
8898      operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8899      operands[5] = operands[1];
8900    }
8901  else
8902    FAIL;
8903}")
8904
8905(define_split
8906  [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8907        (match_operand:TI2 1 "input_operand" ""))]
8908  "reload_completed
8909   && gpr_or_gpr_p (operands[0], operands[1])
8910   && !direct_move_p (operands[0], operands[1])
8911   && !quad_load_store_p (operands[0], operands[1])"
8912  [(pc)]
8913{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8914
8915(define_expand "load_multiple"
8916  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8917			  (match_operand:SI 1 "" ""))
8918		     (use (match_operand:SI 2 "" ""))])]
8919  "TARGET_STRING && !TARGET_POWERPC64"
8920  "
8921{
8922  int regno;
8923  int count;
8924  rtx op1;
8925  int i;
8926
8927  /* Support only loading a constant number of fixed-point registers from
8928     memory and only bother with this if more than two; the machine
8929     doesn't support more than eight.  */
8930  if (GET_CODE (operands[2]) != CONST_INT
8931      || INTVAL (operands[2]) <= 2
8932      || INTVAL (operands[2]) > 8
8933      || GET_CODE (operands[1]) != MEM
8934      || GET_CODE (operands[0]) != REG
8935      || REGNO (operands[0]) >= 32)
8936    FAIL;
8937
8938  count = INTVAL (operands[2]);
8939  regno = REGNO (operands[0]);
8940
8941  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8942  op1 = replace_equiv_address (operands[1],
8943			       force_reg (SImode, XEXP (operands[1], 0)));
8944
8945  for (i = 0; i < count; i++)
8946    XVECEXP (operands[3], 0, i)
8947      = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8948		     adjust_address_nv (op1, SImode, i * 4));
8949}")
8950
8951(define_insn "*ldmsi8"
8952  [(match_parallel 0 "load_multiple_operation"
8953    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8954          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8955     (set (match_operand:SI 3 "gpc_reg_operand" "")
8956          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8957     (set (match_operand:SI 4 "gpc_reg_operand" "")
8958          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8959     (set (match_operand:SI 5 "gpc_reg_operand" "")
8960          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8961     (set (match_operand:SI 6 "gpc_reg_operand" "")
8962          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8963     (set (match_operand:SI 7 "gpc_reg_operand" "")
8964          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8965     (set (match_operand:SI 8 "gpc_reg_operand" "")
8966          (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8967     (set (match_operand:SI 9 "gpc_reg_operand" "")
8968          (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8969  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8970  "*
8971{ return rs6000_output_load_multiple (operands); }"
8972  [(set_attr "type" "load")
8973   (set_attr "update" "yes")
8974   (set_attr "indexed" "yes")
8975   (set_attr "length" "32")])
8976
8977(define_insn "*ldmsi7"
8978  [(match_parallel 0 "load_multiple_operation"
8979    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8980          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8981     (set (match_operand:SI 3 "gpc_reg_operand" "")
8982          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8983     (set (match_operand:SI 4 "gpc_reg_operand" "")
8984          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8985     (set (match_operand:SI 5 "gpc_reg_operand" "")
8986          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8987     (set (match_operand:SI 6 "gpc_reg_operand" "")
8988          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8989     (set (match_operand:SI 7 "gpc_reg_operand" "")
8990          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8991     (set (match_operand:SI 8 "gpc_reg_operand" "")
8992          (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8993  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8994  "*
8995{ return rs6000_output_load_multiple (operands); }"
8996  [(set_attr "type" "load")
8997   (set_attr "update" "yes")
8998   (set_attr "indexed" "yes")
8999   (set_attr "length" "32")])
9000
9001(define_insn "*ldmsi6"
9002  [(match_parallel 0 "load_multiple_operation"
9003    [(set (match_operand:SI 2 "gpc_reg_operand" "")
9004          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9005     (set (match_operand:SI 3 "gpc_reg_operand" "")
9006          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9007     (set (match_operand:SI 4 "gpc_reg_operand" "")
9008          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9009     (set (match_operand:SI 5 "gpc_reg_operand" "")
9010          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9011     (set (match_operand:SI 6 "gpc_reg_operand" "")
9012          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9013     (set (match_operand:SI 7 "gpc_reg_operand" "")
9014          (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
9015  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9016  "*
9017{ return rs6000_output_load_multiple (operands); }"
9018  [(set_attr "type" "load")
9019   (set_attr "update" "yes")
9020   (set_attr "indexed" "yes")
9021   (set_attr "length" "32")])
9022
9023(define_insn "*ldmsi5"
9024  [(match_parallel 0 "load_multiple_operation"
9025    [(set (match_operand:SI 2 "gpc_reg_operand" "")
9026          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9027     (set (match_operand:SI 3 "gpc_reg_operand" "")
9028          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9029     (set (match_operand:SI 4 "gpc_reg_operand" "")
9030          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9031     (set (match_operand:SI 5 "gpc_reg_operand" "")
9032          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9033     (set (match_operand:SI 6 "gpc_reg_operand" "")
9034          (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
9035  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9036  "*
9037{ return rs6000_output_load_multiple (operands); }"
9038  [(set_attr "type" "load")
9039   (set_attr "update" "yes")
9040   (set_attr "indexed" "yes")
9041   (set_attr "length" "32")])
9042
9043(define_insn "*ldmsi4"
9044  [(match_parallel 0 "load_multiple_operation"
9045    [(set (match_operand:SI 2 "gpc_reg_operand" "")
9046          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9047     (set (match_operand:SI 3 "gpc_reg_operand" "")
9048          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9049     (set (match_operand:SI 4 "gpc_reg_operand" "")
9050          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9051     (set (match_operand:SI 5 "gpc_reg_operand" "")
9052          (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
9053  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9054  "*
9055{ return rs6000_output_load_multiple (operands); }"
9056  [(set_attr "type" "load")
9057   (set_attr "update" "yes")
9058   (set_attr "indexed" "yes")
9059   (set_attr "length" "32")])
9060
9061(define_insn "*ldmsi3"
9062  [(match_parallel 0 "load_multiple_operation"
9063    [(set (match_operand:SI 2 "gpc_reg_operand" "")
9064          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9065     (set (match_operand:SI 3 "gpc_reg_operand" "")
9066          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9067     (set (match_operand:SI 4 "gpc_reg_operand" "")
9068          (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9069  "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9070  "*
9071{ return rs6000_output_load_multiple (operands); }"
9072  [(set_attr "type" "load")
9073   (set_attr "update" "yes")
9074   (set_attr "indexed" "yes")
9075   (set_attr "length" "32")])
9076
9077(define_expand "store_multiple"
9078  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9079			  (match_operand:SI 1 "" ""))
9080		     (clobber (scratch:SI))
9081		     (use (match_operand:SI 2 "" ""))])]
9082  "TARGET_STRING && !TARGET_POWERPC64"
9083  "
9084{
9085  int regno;
9086  int count;
9087  rtx to;
9088  rtx op0;
9089  int i;
9090
9091  /* Support only storing a constant number of fixed-point registers to
9092     memory and only bother with this if more than two; the machine
9093     doesn't support more than eight.  */
9094  if (GET_CODE (operands[2]) != CONST_INT
9095      || INTVAL (operands[2]) <= 2
9096      || INTVAL (operands[2]) > 8
9097      || GET_CODE (operands[0]) != MEM
9098      || GET_CODE (operands[1]) != REG
9099      || REGNO (operands[1]) >= 32)
9100    FAIL;
9101
9102  count = INTVAL (operands[2]);
9103  regno = REGNO (operands[1]);
9104
9105  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9106  to = force_reg (SImode, XEXP (operands[0], 0));
9107  op0 = replace_equiv_address (operands[0], to);
9108
9109  XVECEXP (operands[3], 0, 0)
9110    = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9111  XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9112						 gen_rtx_SCRATCH (SImode));
9113
9114  for (i = 1; i < count; i++)
9115    XVECEXP (operands[3], 0, i + 1)
9116      = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9117		     gen_rtx_REG (SImode, regno + i));
9118}")
9119
9120(define_insn "*stmsi8"
9121  [(match_parallel 0 "store_multiple_operation"
9122    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9123	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9124     (clobber (match_scratch:SI 3 "=X"))
9125     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9126	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9127     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9128	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9129     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9130	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9131     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9132	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9133     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9134	  (match_operand:SI 8 "gpc_reg_operand" "r"))
9135     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9136	  (match_operand:SI 9 "gpc_reg_operand" "r"))
9137     (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9138	  (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9139  "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9140  "stswi %2,%1,%O0"
9141  [(set_attr "type" "store")
9142   (set_attr "update" "yes")
9143   (set_attr "indexed" "yes")
9144   (set_attr "cell_micro" "always")])
9145
9146(define_insn "*stmsi7"
9147  [(match_parallel 0 "store_multiple_operation"
9148    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9149	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9150     (clobber (match_scratch:SI 3 "=X"))
9151     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9152	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9153     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9154	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9155     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9156	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9157     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9158	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9159     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9160	  (match_operand:SI 8 "gpc_reg_operand" "r"))
9161     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9162	  (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9163  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9164  "stswi %2,%1,%O0"
9165  [(set_attr "type" "store")
9166   (set_attr "update" "yes")
9167   (set_attr "indexed" "yes")
9168   (set_attr "cell_micro" "always")])
9169
9170(define_insn "*stmsi6"
9171  [(match_parallel 0 "store_multiple_operation"
9172    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9173	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9174     (clobber (match_scratch:SI 3 "=X"))
9175     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9176	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9177     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9178	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9179     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9180	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9181     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9182	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9183     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9184	  (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9185  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9186  "stswi %2,%1,%O0"
9187  [(set_attr "type" "store")
9188   (set_attr "update" "yes")
9189   (set_attr "indexed" "yes")
9190   (set_attr "cell_micro" "always")])
9191
9192(define_insn "*stmsi5"
9193  [(match_parallel 0 "store_multiple_operation"
9194    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9195	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9196     (clobber (match_scratch:SI 3 "=X"))
9197     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9198	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9199     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9200	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9201     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9202	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9203     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9204	  (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9205  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9206  "stswi %2,%1,%O0"
9207  [(set_attr "type" "store")
9208   (set_attr "update" "yes")
9209   (set_attr "indexed" "yes")
9210   (set_attr "cell_micro" "always")])
9211
9212(define_insn "*stmsi4"
9213  [(match_parallel 0 "store_multiple_operation"
9214    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9215	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9216     (clobber (match_scratch:SI 3 "=X"))
9217     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9218	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9219     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9220	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9221     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9222	  (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9223  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9224  "stswi %2,%1,%O0"
9225  [(set_attr "type" "store")
9226   (set_attr "update" "yes")
9227   (set_attr "indexed" "yes")
9228   (set_attr "cell_micro" "always")])
9229
9230(define_insn "*stmsi3"
9231  [(match_parallel 0 "store_multiple_operation"
9232    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9233	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9234     (clobber (match_scratch:SI 3 "=X"))
9235     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9236	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9237     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9238	  (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9239  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9240  "stswi %2,%1,%O0"
9241  [(set_attr "type" "store")
9242   (set_attr "update" "yes")
9243   (set_attr "indexed" "yes")
9244   (set_attr "cell_micro" "always")])
9245
9246(define_expand "setmemsi"
9247  [(parallel [(set (match_operand:BLK 0 "" "")
9248		   (match_operand 2 "const_int_operand" ""))
9249	      (use (match_operand:SI 1 "" ""))
9250	      (use (match_operand:SI 3 "" ""))])]
9251  ""
9252  "
9253{
9254  /* If value to set is not zero, use the library routine.  */
9255  if (operands[2] != const0_rtx)
9256    FAIL;
9257
9258  if (expand_block_clear (operands))
9259    DONE;
9260  else
9261    FAIL;
9262}")
9263
9264;; String compare N insn.
9265;; Argument 0 is the target (result)
9266;; Argument 1 is the destination
9267;; Argument 2 is the source
9268;; Argument 3 is the length
9269;; Argument 4 is the alignment
9270
9271(define_expand "cmpstrnsi"
9272  [(parallel [(set (match_operand:SI 0)
9273               (compare:SI (match_operand:BLK 1)
9274                           (match_operand:BLK 2)))
9275	      (use (match_operand:SI 3))
9276	      (use (match_operand:SI 4))])]
9277  "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9278{
9279  if (optimize_insn_for_size_p ())
9280    FAIL;
9281
9282  if (expand_strn_compare (operands, 0))
9283    DONE;
9284  else
9285    FAIL;
9286})
9287
9288;; String compare insn.
9289;; Argument 0 is the target (result)
9290;; Argument 1 is the destination
9291;; Argument 2 is the source
9292;; Argument 3 is the alignment
9293
9294(define_expand "cmpstrsi"
9295  [(parallel [(set (match_operand:SI 0)
9296               (compare:SI (match_operand:BLK 1)
9297                           (match_operand:BLK 2)))
9298	      (use (match_operand:SI 3))])]
9299  "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9300{
9301  if (optimize_insn_for_size_p ())
9302    FAIL;
9303
9304  if (expand_strn_compare (operands, 1))
9305    DONE;
9306  else
9307    FAIL;
9308})
9309
9310;; Block compare insn.
9311;; Argument 0 is the target (result)
9312;; Argument 1 is the destination
9313;; Argument 2 is the source
9314;; Argument 3 is the length
9315;; Argument 4 is the alignment
9316
9317(define_expand "cmpmemsi"
9318  [(parallel [(set (match_operand:SI 0)
9319               (compare:SI (match_operand:BLK 1)
9320                           (match_operand:BLK 2)))
9321	      (use (match_operand:SI 3))
9322	      (use (match_operand:SI 4))])]
9323  "TARGET_POPCNTD"
9324{
9325  if (expand_block_compare (operands))
9326    DONE;
9327  else
9328    FAIL;
9329})
9330
9331;; String/block move insn.
9332;; Argument 0 is the destination
9333;; Argument 1 is the source
9334;; Argument 2 is the length
9335;; Argument 3 is the alignment
9336
9337(define_expand "movmemsi"
9338  [(parallel [(set (match_operand:BLK 0 "" "")
9339		   (match_operand:BLK 1 "" ""))
9340	      (use (match_operand:SI 2 "" ""))
9341	      (use (match_operand:SI 3 "" ""))])]
9342  ""
9343  "
9344{
9345  if (expand_block_move (operands))
9346    DONE;
9347  else
9348    FAIL;
9349}")
9350
9351;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9352;; register allocator doesn't have a clue about allocating 8 word registers.
9353;; rD/rS = r5 is preferred, efficient form.
9354(define_expand "movmemsi_8reg"
9355  [(parallel [(set (match_operand 0 "" "")
9356		   (match_operand 1 "" ""))
9357	      (use (match_operand 2 "" ""))
9358	      (use (match_operand 3 "" ""))
9359	      (clobber (reg:SI  5))
9360	      (clobber (reg:SI  6))
9361	      (clobber (reg:SI  7))
9362	      (clobber (reg:SI  8))
9363	      (clobber (reg:SI  9))
9364	      (clobber (reg:SI 10))
9365	      (clobber (reg:SI 11))
9366	      (clobber (reg:SI 12))
9367	      (clobber (match_scratch:SI 4 ""))])]
9368  "TARGET_STRING"
9369  "")
9370
9371(define_insn ""
9372  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9373	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9374   (use (match_operand:SI 2 "immediate_operand" "i"))
9375   (use (match_operand:SI 3 "immediate_operand" "i"))
9376   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9377   (clobber (reg:SI  6))
9378   (clobber (reg:SI  7))
9379   (clobber (reg:SI  8))
9380   (clobber (reg:SI  9))
9381   (clobber (reg:SI 10))
9382   (clobber (reg:SI 11))
9383   (clobber (reg:SI 12))
9384   (clobber (match_scratch:SI 5 "=X"))]
9385  "TARGET_STRING
9386   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9387       || INTVAL (operands[2]) == 0)
9388   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9389   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9390   && REGNO (operands[4]) == 5"
9391  "lswi %4,%1,%2\;stswi %4,%0,%2"
9392  [(set_attr "type" "store")
9393   (set_attr "update" "yes")
9394   (set_attr "indexed" "yes")
9395   (set_attr "cell_micro" "always")
9396   (set_attr "length" "8")])
9397
9398;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9399;; register allocator doesn't have a clue about allocating 6 word registers.
9400;; rD/rS = r5 is preferred, efficient form.
9401(define_expand "movmemsi_6reg"
9402  [(parallel [(set (match_operand 0 "" "")
9403		   (match_operand 1 "" ""))
9404	      (use (match_operand 2 "" ""))
9405	      (use (match_operand 3 "" ""))
9406	      (clobber (reg:SI  5))
9407	      (clobber (reg:SI  6))
9408	      (clobber (reg:SI  7))
9409	      (clobber (reg:SI  8))
9410	      (clobber (reg:SI  9))
9411	      (clobber (reg:SI 10))
9412	      (clobber (match_scratch:SI 4 ""))])]
9413  "TARGET_STRING"
9414  "")
9415
9416(define_insn ""
9417  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9418	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9419   (use (match_operand:SI 2 "immediate_operand" "i"))
9420   (use (match_operand:SI 3 "immediate_operand" "i"))
9421   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9422   (clobber (reg:SI  6))
9423   (clobber (reg:SI  7))
9424   (clobber (reg:SI  8))
9425   (clobber (reg:SI  9))
9426   (clobber (reg:SI 10))
9427   (clobber (match_scratch:SI 5 "=X"))]
9428  "TARGET_STRING
9429   && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9430   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9431   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9432   && REGNO (operands[4]) == 5"
9433  "lswi %4,%1,%2\;stswi %4,%0,%2"
9434  [(set_attr "type" "store")
9435   (set_attr "update" "yes")
9436   (set_attr "indexed" "yes")
9437   (set_attr "cell_micro" "always")
9438   (set_attr "length" "8")])
9439
9440;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9441;; problems with TImode.
9442;; rD/rS = r5 is preferred, efficient form.
9443(define_expand "movmemsi_4reg"
9444  [(parallel [(set (match_operand 0 "" "")
9445		   (match_operand 1 "" ""))
9446	      (use (match_operand 2 "" ""))
9447	      (use (match_operand 3 "" ""))
9448	      (clobber (reg:SI 5))
9449	      (clobber (reg:SI 6))
9450	      (clobber (reg:SI 7))
9451	      (clobber (reg:SI 8))
9452	      (clobber (match_scratch:SI 4 ""))])]
9453  "TARGET_STRING"
9454  "")
9455
9456(define_insn ""
9457  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9458	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9459   (use (match_operand:SI 2 "immediate_operand" "i"))
9460   (use (match_operand:SI 3 "immediate_operand" "i"))
9461   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9462   (clobber (reg:SI 6))
9463   (clobber (reg:SI 7))
9464   (clobber (reg:SI 8))
9465   (clobber (match_scratch:SI 5 "=X"))]
9466  "TARGET_STRING
9467   && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9468   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9469   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9470   && REGNO (operands[4]) == 5"
9471  "lswi %4,%1,%2\;stswi %4,%0,%2"
9472  [(set_attr "type" "store")
9473   (set_attr "update" "yes")
9474   (set_attr "indexed" "yes")
9475   (set_attr "cell_micro" "always")
9476   (set_attr "length" "8")])
9477
9478;; Move up to 8 bytes at a time.
9479(define_expand "movmemsi_2reg"
9480  [(parallel [(set (match_operand 0 "" "")
9481		   (match_operand 1 "" ""))
9482	      (use (match_operand 2 "" ""))
9483	      (use (match_operand 3 "" ""))
9484	      (clobber (match_scratch:DI 4 ""))
9485	      (clobber (match_scratch:SI 5 ""))])]
9486  "TARGET_STRING && ! TARGET_POWERPC64"
9487  "")
9488
9489(define_insn ""
9490  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9491	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9492   (use (match_operand:SI 2 "immediate_operand" "i"))
9493   (use (match_operand:SI 3 "immediate_operand" "i"))
9494   (clobber (match_scratch:DI 4 "=&r"))
9495   (clobber (match_scratch:SI 5 "=X"))]
9496  "TARGET_STRING && ! TARGET_POWERPC64
9497   && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9498  "lswi %4,%1,%2\;stswi %4,%0,%2"
9499  [(set_attr "type" "store")
9500   (set_attr "update" "yes")
9501   (set_attr "indexed" "yes")
9502   (set_attr "cell_micro" "always")
9503   (set_attr "length" "8")])
9504
9505;; Move up to 4 bytes at a time.
9506(define_expand "movmemsi_1reg"
9507  [(parallel [(set (match_operand 0 "" "")
9508		   (match_operand 1 "" ""))
9509	      (use (match_operand 2 "" ""))
9510	      (use (match_operand 3 "" ""))
9511	      (clobber (match_scratch:SI 4 ""))
9512	      (clobber (match_scratch:SI 5 ""))])]
9513  "TARGET_STRING"
9514  "")
9515
9516(define_insn ""
9517  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9518	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9519   (use (match_operand:SI 2 "immediate_operand" "i"))
9520   (use (match_operand:SI 3 "immediate_operand" "i"))
9521   (clobber (match_scratch:SI 4 "=&r"))
9522   (clobber (match_scratch:SI 5 "=X"))]
9523  "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9524  "lswi %4,%1,%2\;stswi %4,%0,%2"
9525  [(set_attr "type" "store")
9526   (set_attr "update" "yes")
9527   (set_attr "indexed" "yes")
9528   (set_attr "cell_micro" "always")
9529   (set_attr "length" "8")])
9530
9531;; Define insns that do load or store with update.  Some of these we can
9532;; get by using pre-decrement or pre-increment, but the hardware can also
9533;; do cases where the increment is not the size of the object.
9534;;
9535;; In all these cases, we use operands 0 and 1 for the register being
9536;; incremented because those are the operands that local-alloc will
9537;; tie and these are the pair most likely to be tieable (and the ones
9538;; that will benefit the most).
9539
9540(define_insn "*movdi_update1"
9541  [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9542	(mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9543			 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9544   (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9545	(plus:DI (match_dup 1) (match_dup 2)))]
9546  "TARGET_POWERPC64 && TARGET_UPDATE
9547   && (!avoiding_indexed_address_p (DImode)
9548       || !gpc_reg_operand (operands[2], DImode))"
9549  "@
9550   ldux %3,%0,%2
9551   ldu %3,%2(%0)"
9552  [(set_attr "type" "load")
9553   (set_attr "update" "yes")
9554   (set_attr "indexed" "yes,no")])
9555
9556(define_insn "movdi_<mode>_update"
9557  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9558			 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9559	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
9560   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9561	(plus:P (match_dup 1) (match_dup 2)))]
9562  "TARGET_POWERPC64 && TARGET_UPDATE
9563   && (!avoiding_indexed_address_p (Pmode)
9564       || !gpc_reg_operand (operands[2], Pmode)
9565       || (REG_P (operands[0])
9566	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9567  "@
9568   stdux %3,%0,%2
9569   stdu %3,%2(%0)"
9570  [(set_attr "type" "store")
9571   (set_attr "update" "yes")
9572   (set_attr "indexed" "yes,no")])
9573
9574;; This pattern is only conditional on TARGET_POWERPC64, as it is
9575;; needed for stack allocation, even if the user passes -mno-update.
9576(define_insn "movdi_<mode>_update_stack"
9577  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9578			 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9579	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
9580   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9581	(plus:P (match_dup 1) (match_dup 2)))]
9582  "TARGET_POWERPC64"
9583  "@
9584   stdux %3,%0,%2
9585   stdu %3,%2(%0)"
9586  [(set_attr "type" "store")
9587   (set_attr "update" "yes")
9588   (set_attr "indexed" "yes,no")])
9589
9590(define_insn "*movsi_update1"
9591  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9592	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9593			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9594   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9595	(plus:SI (match_dup 1) (match_dup 2)))]
9596  "TARGET_UPDATE
9597   && (!avoiding_indexed_address_p (SImode)
9598       || !gpc_reg_operand (operands[2], SImode))"
9599  "@
9600   lwzux %3,%0,%2
9601   lwzu %3,%2(%0)"
9602  [(set_attr "type" "load")
9603   (set_attr "update" "yes")
9604   (set_attr "indexed" "yes,no")])
9605
9606(define_insn "*movsi_update2"
9607  [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9608	(sign_extend:DI
9609	 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9610			  (match_operand:DI 2 "gpc_reg_operand" "r")))))
9611   (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9612	(plus:DI (match_dup 1) (match_dup 2)))]
9613  "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9614   && !avoiding_indexed_address_p (DImode)"
9615  "lwaux %3,%0,%2"
9616  [(set_attr "type" "load")
9617   (set_attr "sign_extend" "yes")
9618   (set_attr "update" "yes")
9619   (set_attr "indexed" "yes")])
9620
9621(define_insn "movsi_update"
9622  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9623			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9624	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
9625   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9626	(plus:SI (match_dup 1) (match_dup 2)))]
9627  "TARGET_UPDATE
9628   && (!avoiding_indexed_address_p (SImode)
9629       || !gpc_reg_operand (operands[2], SImode)
9630       || (REG_P (operands[0])
9631	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9632  "@
9633   stwux %3,%0,%2
9634   stwu %3,%2(%0)"
9635  [(set_attr "type" "store")
9636   (set_attr "update" "yes")
9637   (set_attr "indexed" "yes,no")])
9638
9639;; This is an unconditional pattern; needed for stack allocation, even
9640;; if the user passes -mno-update.
9641(define_insn "movsi_update_stack"
9642  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9643			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9644	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
9645   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9646	(plus:SI (match_dup 1) (match_dup 2)))]
9647  ""
9648  "@
9649   stwux %3,%0,%2
9650   stwu %3,%2(%0)"
9651  [(set_attr "type" "store")
9652   (set_attr "update" "yes")
9653   (set_attr "indexed" "yes,no")])
9654
9655(define_insn "*movhi_update1"
9656  [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9657	(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9658			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9659   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9660	(plus:SI (match_dup 1) (match_dup 2)))]
9661  "TARGET_UPDATE
9662   && (!avoiding_indexed_address_p (SImode)
9663       || !gpc_reg_operand (operands[2], SImode))"
9664  "@
9665   lhzux %3,%0,%2
9666   lhzu %3,%2(%0)"
9667  [(set_attr "type" "load")
9668   (set_attr "update" "yes")
9669   (set_attr "indexed" "yes,no")])
9670
9671(define_insn "*movhi_update2"
9672  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9673	(zero_extend:SI
9674	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9675			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9676   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9677	(plus:SI (match_dup 1) (match_dup 2)))]
9678  "TARGET_UPDATE
9679   && (!avoiding_indexed_address_p (SImode)
9680       || !gpc_reg_operand (operands[2], SImode))"
9681  "@
9682   lhzux %3,%0,%2
9683   lhzu %3,%2(%0)"
9684  [(set_attr "type" "load")
9685   (set_attr "update" "yes")
9686   (set_attr "indexed" "yes,no")])
9687
9688(define_insn "*movhi_update3"
9689  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9690	(sign_extend:SI
9691	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9692			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9693   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9694	(plus:SI (match_dup 1) (match_dup 2)))]
9695  "TARGET_UPDATE && rs6000_gen_cell_microcode
9696   && (!avoiding_indexed_address_p (SImode)
9697       || !gpc_reg_operand (operands[2], SImode))"
9698  "@
9699   lhaux %3,%0,%2
9700   lhau %3,%2(%0)"
9701  [(set_attr "type" "load")
9702   (set_attr "sign_extend" "yes")
9703   (set_attr "update" "yes")
9704   (set_attr "indexed" "yes,no")])
9705
9706(define_insn "*movhi_update4"
9707  [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9708			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9709	(match_operand:HI 3 "gpc_reg_operand" "r,r"))
9710   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9711	(plus:SI (match_dup 1) (match_dup 2)))]
9712  "TARGET_UPDATE
9713   && (!avoiding_indexed_address_p (SImode)
9714       || !gpc_reg_operand (operands[2], SImode))"
9715  "@
9716   sthux %3,%0,%2
9717   sthu %3,%2(%0)"
9718  [(set_attr "type" "store")
9719   (set_attr "update" "yes")
9720   (set_attr "indexed" "yes,no")])
9721
9722(define_insn "*movqi_update1"
9723  [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9724	(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9725			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9726   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9727	(plus:SI (match_dup 1) (match_dup 2)))]
9728  "TARGET_UPDATE
9729   && (!avoiding_indexed_address_p (SImode)
9730       || !gpc_reg_operand (operands[2], SImode))"
9731  "@
9732   lbzux %3,%0,%2
9733   lbzu %3,%2(%0)"
9734  [(set_attr "type" "load")
9735   (set_attr "update" "yes")
9736   (set_attr "indexed" "yes,no")])
9737
9738(define_insn "*movqi_update2"
9739  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9740	(zero_extend:SI
9741	 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9742			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9743   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9744	(plus:SI (match_dup 1) (match_dup 2)))]
9745  "TARGET_UPDATE
9746   && (!avoiding_indexed_address_p (SImode)
9747       || !gpc_reg_operand (operands[2], SImode))"
9748  "@
9749   lbzux %3,%0,%2
9750   lbzu %3,%2(%0)"
9751  [(set_attr "type" "load")
9752   (set_attr "update" "yes")
9753   (set_attr "indexed" "yes,no")])
9754
9755(define_insn "*movqi_update3"
9756  [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9757			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9758	(match_operand:QI 3 "gpc_reg_operand" "r,r"))
9759   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9760	(plus:SI (match_dup 1) (match_dup 2)))]
9761  "TARGET_UPDATE
9762   && (!avoiding_indexed_address_p (SImode)
9763       || !gpc_reg_operand (operands[2], SImode))"
9764  "@
9765   stbux %3,%0,%2
9766   stbu %3,%2(%0)"
9767  [(set_attr "type" "store")
9768   (set_attr "update" "yes")
9769   (set_attr "indexed" "yes,no")])
9770
9771(define_insn "*movsf_update1"
9772  [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9773	(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9774			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9775   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9776	(plus:SI (match_dup 1) (match_dup 2)))]
9777  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9778   && (!avoiding_indexed_address_p (SImode)
9779       || !gpc_reg_operand (operands[2], SImode))"
9780  "@
9781   lfsux %3,%0,%2
9782   lfsu %3,%2(%0)"
9783  [(set_attr "type" "fpload")
9784   (set_attr "update" "yes")
9785   (set_attr "indexed" "yes,no")])
9786
9787(define_insn "*movsf_update2"
9788  [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9789			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9790	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
9791   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9792	(plus:SI (match_dup 1) (match_dup 2)))]
9793  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9794   && (!avoiding_indexed_address_p (SImode)
9795       || !gpc_reg_operand (operands[2], SImode))"
9796  "@
9797   stfsux %3,%0,%2
9798   stfsu %3,%2(%0)"
9799  [(set_attr "type" "fpstore")
9800   (set_attr "update" "yes")
9801   (set_attr "indexed" "yes,no")])
9802
9803(define_insn "*movsf_update3"
9804  [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9805	(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9806			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9807   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9808	(plus:SI (match_dup 1) (match_dup 2)))]
9809  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9810   && (!avoiding_indexed_address_p (SImode)
9811       || !gpc_reg_operand (operands[2], SImode))"
9812  "@
9813   lwzux %3,%0,%2
9814   lwzu %3,%2(%0)"
9815  [(set_attr "type" "load")
9816   (set_attr "update" "yes")
9817   (set_attr "indexed" "yes,no")])
9818
9819(define_insn "*movsf_update4"
9820  [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9821			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9822	(match_operand:SF 3 "gpc_reg_operand" "r,r"))
9823   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9824	(plus:SI (match_dup 1) (match_dup 2)))]
9825  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9826   && (!avoiding_indexed_address_p (SImode)
9827       || !gpc_reg_operand (operands[2], SImode))"
9828  "@
9829   stwux %3,%0,%2
9830   stwu %3,%2(%0)"
9831  [(set_attr "type" "store")
9832   (set_attr "update" "yes")
9833   (set_attr "indexed" "yes,no")])
9834
9835(define_insn "*movdf_update1"
9836  [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9837	(mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9838			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9839   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9840	(plus:SI (match_dup 1) (match_dup 2)))]
9841  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9842   && (!avoiding_indexed_address_p (SImode)
9843       || !gpc_reg_operand (operands[2], SImode))"
9844  "@
9845   lfdux %3,%0,%2
9846   lfdu %3,%2(%0)"
9847  [(set_attr "type" "fpload")
9848   (set_attr "update" "yes")
9849   (set_attr "indexed" "yes,no")
9850   (set_attr "size" "64")])
9851
9852(define_insn "*movdf_update2"
9853  [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9854			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9855	(match_operand:DF 3 "gpc_reg_operand" "d,d"))
9856   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9857	(plus:SI (match_dup 1) (match_dup 2)))]
9858  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9859   && (!avoiding_indexed_address_p (SImode)
9860       || !gpc_reg_operand (operands[2], SImode))"
9861  "@
9862   stfdux %3,%0,%2
9863   stfdu %3,%2(%0)"
9864  [(set_attr "type" "fpstore")
9865   (set_attr "update" "yes")
9866   (set_attr "indexed" "yes,no")])
9867
9868
9869;; After inserting conditional returns we can sometimes have
9870;; unnecessary register moves.  Unfortunately we cannot have a
9871;; modeless peephole here, because some single SImode sets have early
9872;; clobber outputs.  Although those sets expand to multi-ppc-insn
9873;; sequences, using get_attr_length here will smash the operands
9874;; array.  Neither is there an early_cobbler_p predicate.
9875;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9876;; Also this optimization interferes with scalars going into
9877;; altivec registers (the code does reloading through the FPRs).
9878(define_peephole2
9879  [(set (match_operand:DF 0 "gpc_reg_operand" "")
9880	(match_operand:DF 1 "any_operand" ""))
9881   (set (match_operand:DF 2 "gpc_reg_operand" "")
9882	(match_dup 0))]
9883  "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9884   && !TARGET_UPPER_REGS_DF
9885   && peep2_reg_dead_p (2, operands[0])"
9886  [(set (match_dup 2) (match_dup 1))])
9887
9888(define_peephole2
9889  [(set (match_operand:SF 0 "gpc_reg_operand" "")
9890	(match_operand:SF 1 "any_operand" ""))
9891   (set (match_operand:SF 2 "gpc_reg_operand" "")
9892	(match_dup 0))]
9893  "!TARGET_UPPER_REGS_SF
9894   && peep2_reg_dead_p (2, operands[0])"
9895  [(set (match_dup 2) (match_dup 1))])
9896
9897
9898;; TLS support.
9899
9900;; Mode attributes for different ABIs.
9901(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9902(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9903(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9904(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9905
9906(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9907  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9908        (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9909	      (match_operand 4 "" "g")))
9910   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9911	 	    (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9912		   UNSPEC_TLSGD)
9913   (clobber (reg:SI LR_REGNO))]
9914  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9915{
9916  if (TARGET_CMODEL != CMODEL_SMALL)
9917    return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9918	   "bl %z3\;nop";
9919  else
9920    return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9921}
9922  "&& TARGET_TLS_MARKERS"
9923  [(set (match_dup 0)
9924	(unspec:TLSmode [(match_dup 1)
9925			 (match_dup 2)]
9926			UNSPEC_TLSGD))
9927   (parallel [(set (match_dup 0)
9928   	     	   (call (mem:TLSmode (match_dup 3))
9929		   	 (match_dup 4)))
9930	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9931	      (clobber (reg:SI LR_REGNO))])]
9932  ""
9933  [(set_attr "type" "two")
9934   (set (attr "length")
9935     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9936     		   (const_int 16)
9937     		   (const_int 12)))])
9938
9939(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9940  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9941        (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9942	      (match_operand 4 "" "g")))
9943   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9944	 	    (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9945		   UNSPEC_TLSGD)
9946   (clobber (reg:SI LR_REGNO))]
9947  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9948{
9949  if (flag_pic)
9950    {
9951      if (TARGET_SECURE_PLT && flag_pic == 2)
9952	return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9953      else
9954	return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9955    }
9956  else
9957    return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9958}
9959  "&& TARGET_TLS_MARKERS"
9960  [(set (match_dup 0)
9961	(unspec:TLSmode [(match_dup 1)
9962			 (match_dup 2)]
9963			UNSPEC_TLSGD))
9964   (parallel [(set (match_dup 0)
9965   	     	   (call (mem:TLSmode (match_dup 3))
9966		   	 (match_dup 4)))
9967	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9968	      (clobber (reg:SI LR_REGNO))])]
9969  ""
9970  [(set_attr "type" "two")
9971   (set_attr "length" "8")])
9972
9973(define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9974  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9975	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9976			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9977			UNSPEC_TLSGD))]
9978  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9979  "addi %0,%1,%2@got@tlsgd"
9980  "&& TARGET_CMODEL != CMODEL_SMALL"
9981  [(set (match_dup 3)
9982  	(high:TLSmode
9983	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9984   (set (match_dup 0)
9985   	(lo_sum:TLSmode (match_dup 3)
9986	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9987  "
9988{
9989  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9990}"
9991  [(set (attr "length")
9992     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9993     		   (const_int 8)
9994     		   (const_int 4)))])
9995
9996(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9997  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9998     (high:TLSmode
9999       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10000			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10001		       UNSPEC_TLSGD)))]
10002  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10003  "addis %0,%1,%2@got@tlsgd@ha"
10004  [(set_attr "length" "4")])
10005
10006(define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
10007  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10008     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10009       (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10010			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10011		       UNSPEC_TLSGD)))]
10012  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10013  "addi %0,%1,%2@got@tlsgd@l"
10014  [(set_attr "length" "4")])
10015
10016(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
10017  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10018        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10019	      (match_operand 2 "" "g")))
10020   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10021		   UNSPEC_TLSGD)
10022   (clobber (reg:SI LR_REGNO))]
10023  "HAVE_AS_TLS && TARGET_TLS_MARKERS
10024   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10025  "bl %z1(%3@tlsgd)\;nop"
10026  [(set_attr "type" "branch")
10027   (set_attr "length" "8")])
10028
10029(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
10030  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10031        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10032	      (match_operand 2 "" "g")))
10033   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10034		   UNSPEC_TLSGD)
10035   (clobber (reg:SI LR_REGNO))]
10036  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10037{
10038  if (flag_pic)
10039    {
10040      if (TARGET_SECURE_PLT && flag_pic == 2)
10041	return "bl %z1+32768(%3@tlsgd)@plt";
10042      return "bl %z1(%3@tlsgd)@plt";
10043    }
10044  return "bl %z1(%3@tlsgd)";
10045}
10046  [(set_attr "type" "branch")
10047   (set_attr "length" "4")])
10048
10049(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
10050  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10051        (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10052	      (match_operand 3 "" "g")))
10053   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10054		   UNSPEC_TLSLD)
10055   (clobber (reg:SI LR_REGNO))]
10056  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10057{
10058  if (TARGET_CMODEL != CMODEL_SMALL)
10059    return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
10060	   "bl %z2\;nop";
10061  else
10062    return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
10063}
10064  "&& TARGET_TLS_MARKERS"
10065  [(set (match_dup 0)
10066	(unspec:TLSmode [(match_dup 1)]
10067			UNSPEC_TLSLD))
10068   (parallel [(set (match_dup 0)
10069   	     	   (call (mem:TLSmode (match_dup 2))
10070		   	 (match_dup 3)))
10071	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10072	      (clobber (reg:SI LR_REGNO))])]
10073  ""
10074  [(set_attr "type" "two")
10075   (set (attr "length")
10076     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10077     		   (const_int 16)
10078     		   (const_int 12)))])
10079
10080(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10081  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10082        (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10083	      (match_operand 3 "" "g")))
10084   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10085		   UNSPEC_TLSLD)
10086   (clobber (reg:SI LR_REGNO))]
10087  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10088{
10089  if (flag_pic)
10090    {
10091      if (TARGET_SECURE_PLT && flag_pic == 2)
10092	return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10093      else
10094	return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10095    }
10096  else
10097    return "addi %0,%1,%&@got@tlsld\;bl %z2";
10098}
10099  "&& TARGET_TLS_MARKERS"
10100  [(set (match_dup 0)
10101	(unspec:TLSmode [(match_dup 1)]
10102			UNSPEC_TLSLD))
10103   (parallel [(set (match_dup 0)
10104   	     	   (call (mem:TLSmode (match_dup 2))
10105		   	 (match_dup 3)))
10106	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10107	      (clobber (reg:SI LR_REGNO))])]
10108  ""
10109  [(set_attr "length" "8")])
10110
10111(define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10112  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10113	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10114			UNSPEC_TLSLD))]
10115  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10116  "addi %0,%1,%&@got@tlsld"
10117  "&& TARGET_CMODEL != CMODEL_SMALL"
10118  [(set (match_dup 2)
10119  	(high:TLSmode
10120	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10121   (set (match_dup 0)
10122   	(lo_sum:TLSmode (match_dup 2)
10123	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10124  "
10125{
10126  operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10127}"
10128  [(set (attr "length")
10129     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10130     		   (const_int 8)
10131     		   (const_int 4)))])
10132
10133(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10134  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10135     (high:TLSmode
10136       (unspec:TLSmode [(const_int 0)
10137			(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10138		       UNSPEC_TLSLD)))]
10139  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10140  "addis %0,%1,%&@got@tlsld@ha"
10141  [(set_attr "length" "4")])
10142
10143(define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10144  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10145     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10146       (unspec:TLSmode [(const_int 0)
10147                        (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10148                       UNSPEC_TLSLD)))]
10149  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10150  "addi %0,%1,%&@got@tlsld@l"
10151  [(set_attr "length" "4")])
10152
10153(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10154  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10155        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10156	      (match_operand 2 "" "g")))
10157   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10158   (clobber (reg:SI LR_REGNO))]
10159  "HAVE_AS_TLS && TARGET_TLS_MARKERS
10160   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10161  "bl %z1(%&@tlsld)\;nop"
10162  [(set_attr "type" "branch")
10163   (set_attr "length" "8")])
10164
10165(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10166  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10167        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10168	      (match_operand 2 "" "g")))
10169   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10170   (clobber (reg:SI LR_REGNO))]
10171  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10172{
10173  if (flag_pic)
10174    {
10175      if (TARGET_SECURE_PLT && flag_pic == 2)
10176	return "bl %z1+32768(%&@tlsld)@plt";
10177      return "bl %z1(%&@tlsld)@plt";
10178    }
10179  return "bl %z1(%&@tlsld)";
10180}
10181  [(set_attr "type" "branch")
10182   (set_attr "length" "4")])
10183
10184(define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10185  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10186	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10187			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10188			UNSPEC_TLSDTPREL))]
10189  "HAVE_AS_TLS"
10190  "addi %0,%1,%2@dtprel")
10191
10192(define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10193  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10194	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10195			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10196			UNSPEC_TLSDTPRELHA))]
10197  "HAVE_AS_TLS"
10198  "addis %0,%1,%2@dtprel@ha")
10199
10200(define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10201  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10202	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10203			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10204			UNSPEC_TLSDTPRELLO))]
10205  "HAVE_AS_TLS"
10206  "addi %0,%1,%2@dtprel@l")
10207
10208(define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10209  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10210	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10211			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10212			UNSPEC_TLSGOTDTPREL))]
10213  "HAVE_AS_TLS"
10214  "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10215  "&& TARGET_CMODEL != CMODEL_SMALL"
10216  [(set (match_dup 3)
10217	(high:TLSmode
10218	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10219   (set (match_dup 0)
10220	(lo_sum:TLSmode (match_dup 3)
10221	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10222  "
10223{
10224  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10225}"
10226  [(set (attr "length")
10227     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10228     		   (const_int 8)
10229     		   (const_int 4)))])
10230
10231(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10232  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10233     (high:TLSmode
10234       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10235			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10236		       UNSPEC_TLSGOTDTPREL)))]
10237  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10238  "addis %0,%1,%2@got@dtprel@ha"
10239  [(set_attr "length" "4")])
10240
10241(define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10242  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10243     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10244	 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10245			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10246			 UNSPEC_TLSGOTDTPREL)))]
10247  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10248  "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10249  [(set_attr "length" "4")])
10250
10251(define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10252  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10253	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10254			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10255			UNSPEC_TLSTPREL))]
10256  "HAVE_AS_TLS"
10257  "addi %0,%1,%2@tprel")
10258
10259(define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10260  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10261	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10262			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10263			UNSPEC_TLSTPRELHA))]
10264  "HAVE_AS_TLS"
10265  "addis %0,%1,%2@tprel@ha")
10266
10267(define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10268  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10269	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10270			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10271			UNSPEC_TLSTPRELLO))]
10272  "HAVE_AS_TLS"
10273  "addi %0,%1,%2@tprel@l")
10274
10275;; "b" output constraint here and on tls_tls input to support linker tls
10276;; optimization.  The linker may edit the instructions emitted by a
10277;; tls_got_tprel/tls_tls pair to addis,addi.
10278(define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10279  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10280	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10281			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10282			UNSPEC_TLSGOTTPREL))]
10283  "HAVE_AS_TLS"
10284  "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10285  "&& TARGET_CMODEL != CMODEL_SMALL"
10286  [(set (match_dup 3)
10287	(high:TLSmode
10288	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10289   (set (match_dup 0)
10290	(lo_sum:TLSmode (match_dup 3)
10291	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10292  "
10293{
10294  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10295}"
10296  [(set (attr "length")
10297     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10298     		   (const_int 8)
10299     		   (const_int 4)))])
10300
10301(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10302  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10303     (high:TLSmode
10304       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10305			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10306		       UNSPEC_TLSGOTTPREL)))]
10307  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10308  "addis %0,%1,%2@got@tprel@ha"
10309  [(set_attr "length" "4")])
10310
10311(define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10312  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10313     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10314	 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10315			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10316			 UNSPEC_TLSGOTTPREL)))]
10317  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10318  "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10319  [(set_attr "length" "4")])
10320
10321(define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10322  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10323	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10324			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10325			UNSPEC_TLSTLS))]
10326  "TARGET_ELF && HAVE_AS_TLS"
10327  "add %0,%1,%2@tls")
10328
10329(define_expand "tls_get_tpointer"
10330  [(set (match_operand:SI 0 "gpc_reg_operand" "")
10331	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10332  "TARGET_XCOFF && HAVE_AS_TLS"
10333  "
10334{
10335  emit_insn (gen_tls_get_tpointer_internal ());
10336  emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10337  DONE;
10338}")
10339
10340(define_insn "tls_get_tpointer_internal"
10341  [(set (reg:SI 3)
10342	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10343   (clobber (reg:SI LR_REGNO))]
10344  "TARGET_XCOFF && HAVE_AS_TLS"
10345  "bla __get_tpointer")
10346
10347(define_expand "tls_get_addr<mode>"
10348  [(set (match_operand:P 0 "gpc_reg_operand" "")
10349	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10350                   (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10351  "TARGET_XCOFF && HAVE_AS_TLS"
10352  "
10353{
10354  emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10355  emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10356  emit_insn (gen_tls_get_addr_internal<mode> ());
10357  emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10358  DONE;
10359}")
10360
10361(define_insn "tls_get_addr_internal<mode>"
10362  [(set (reg:P 3)
10363	(unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10364   (clobber (reg:P 0))
10365   (clobber (reg:P 4))
10366   (clobber (reg:P 5))
10367   (clobber (reg:P 11))
10368   (clobber (reg:CC CR0_REGNO))
10369   (clobber (reg:P LR_REGNO))]
10370  "TARGET_XCOFF && HAVE_AS_TLS"
10371  "bla __tls_get_addr")
10372
10373;; Next come insns related to the calling sequence.
10374;;
10375;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10376;; We move the back-chain and decrement the stack pointer.
10377
10378(define_expand "allocate_stack"
10379  [(set (match_operand 0 "gpc_reg_operand" "")
10380	(minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10381   (set (reg 1)
10382	(minus (reg 1) (match_dup 1)))]
10383  ""
10384  "
10385{ rtx chain = gen_reg_rtx (Pmode);
10386  rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10387  rtx neg_op0;
10388  rtx insn, par, set, mem;
10389
10390  emit_move_insn (chain, stack_bot);
10391
10392  /* Check stack bounds if necessary.  */
10393  if (crtl->limit_stack)
10394    {
10395      rtx available;
10396      available = expand_binop (Pmode, sub_optab,
10397				stack_pointer_rtx, stack_limit_rtx,
10398				NULL_RTX, 1, OPTAB_WIDEN);
10399      emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10400    }
10401
10402  if (GET_CODE (operands[1]) != CONST_INT
10403      || INTVAL (operands[1]) < -32767
10404      || INTVAL (operands[1]) > 32768)
10405    {
10406      neg_op0 = gen_reg_rtx (Pmode);
10407      if (TARGET_32BIT)
10408	emit_insn (gen_negsi2 (neg_op0, operands[1]));
10409      else
10410	emit_insn (gen_negdi2 (neg_op0, operands[1]));
10411    }
10412  else
10413    neg_op0 = GEN_INT (- INTVAL (operands[1]));
10414
10415  insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10416				       : gen_movdi_di_update_stack))
10417			(stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10418			 chain));
10419  /* Since we didn't use gen_frame_mem to generate the MEM, grab
10420     it now and set the alias set/attributes. The above gen_*_update
10421     calls will generate a PARALLEL with the MEM set being the first
10422     operation. */
10423  par = PATTERN (insn);
10424  gcc_assert (GET_CODE (par) == PARALLEL);
10425  set = XVECEXP (par, 0, 0);
10426  gcc_assert (GET_CODE (set) == SET);
10427  mem = SET_DEST (set);
10428  gcc_assert (MEM_P (mem));
10429  MEM_NOTRAP_P (mem) = 1;
10430  set_mem_alias_set (mem, get_frame_alias_set ());
10431
10432  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10433  DONE;
10434}")
10435
10436;; These patterns say how to save and restore the stack pointer.  We need not
10437;; save the stack pointer at function level since we are careful to
10438;; preserve the backchain.  At block level, we have to restore the backchain
10439;; when we restore the stack pointer.
10440;;
10441;; For nonlocal gotos, we must save both the stack pointer and its
10442;; backchain and restore both.  Note that in the nonlocal case, the
10443;; save area is a memory location.
10444
10445(define_expand "save_stack_function"
10446  [(match_operand 0 "any_operand" "")
10447   (match_operand 1 "any_operand" "")]
10448  ""
10449  "DONE;")
10450
10451(define_expand "restore_stack_function"
10452  [(match_operand 0 "any_operand" "")
10453   (match_operand 1 "any_operand" "")]
10454  ""
10455  "DONE;")
10456
10457;; Adjust stack pointer (op0) to a new value (op1).
10458;; First copy old stack backchain to new location, and ensure that the
10459;; scheduler won't reorder the sp assignment before the backchain write.
10460(define_expand "restore_stack_block"
10461  [(set (match_dup 2) (match_dup 3))
10462   (set (match_dup 4) (match_dup 2))
10463   (match_dup 5)
10464   (set (match_operand 0 "register_operand" "")
10465	(match_operand 1 "register_operand" ""))]
10466  ""
10467  "
10468{
10469  rtvec p;
10470
10471  operands[1] = force_reg (Pmode, operands[1]);
10472  operands[2] = gen_reg_rtx (Pmode);
10473  operands[3] = gen_frame_mem (Pmode, operands[0]);
10474  operands[4] = gen_frame_mem (Pmode, operands[1]);
10475  p = rtvec_alloc (1);
10476  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10477				  const0_rtx);
10478  operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10479}")
10480
10481(define_expand "save_stack_nonlocal"
10482  [(set (match_dup 3) (match_dup 4))
10483   (set (match_operand 0 "memory_operand" "") (match_dup 3))
10484   (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10485  ""
10486  "
10487{
10488  int units_per_word = (TARGET_32BIT) ? 4 : 8;
10489
10490  /* Copy the backchain to the first word, sp to the second.  */
10491  operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10492  operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10493  operands[3] = gen_reg_rtx (Pmode);
10494  operands[4] = gen_frame_mem (Pmode, operands[1]);
10495}")
10496
10497(define_expand "restore_stack_nonlocal"
10498  [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10499   (set (match_dup 3) (match_dup 4))
10500   (set (match_dup 5) (match_dup 2))
10501   (match_dup 6)
10502   (set (match_operand 0 "register_operand" "") (match_dup 3))]
10503  ""
10504  "
10505{
10506  int units_per_word = (TARGET_32BIT) ? 4 : 8;
10507  rtvec p;
10508
10509  /* Restore the backchain from the first word, sp from the second.  */
10510  operands[2] = gen_reg_rtx (Pmode);
10511  operands[3] = gen_reg_rtx (Pmode);
10512  operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10513  operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10514  operands[5] = gen_frame_mem (Pmode, operands[3]);
10515  p = rtvec_alloc (1);
10516  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10517				  const0_rtx);
10518  operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10519}")
10520
10521;; TOC register handling.
10522
10523;; Code to initialize the TOC register...
10524
10525(define_insn "load_toc_aix_si"
10526  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10527		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
10528	      (use (reg:SI 2))])]
10529  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10530  "*
10531{
10532  char buf[30];
10533  extern int need_toc_init;
10534  need_toc_init = 1;
10535  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10536  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10537  operands[2] = gen_rtx_REG (Pmode, 2);
10538  return \"lwz %0,%1(%2)\";
10539}"
10540  [(set_attr "type" "load")
10541   (set_attr "update" "no")
10542   (set_attr "indexed" "no")])
10543
10544(define_insn "load_toc_aix_di"
10545  [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10546		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
10547	      (use (reg:DI 2))])]
10548  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10549  "*
10550{
10551  char buf[30];
10552  extern int need_toc_init;
10553  need_toc_init = 1;
10554  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10555			       !TARGET_ELF || !TARGET_MINIMAL_TOC);
10556  if (TARGET_ELF)
10557    strcat (buf, \"@toc\");
10558  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10559  operands[2] = gen_rtx_REG (Pmode, 2);
10560  return \"ld %0,%1(%2)\";
10561}"
10562  [(set_attr "type" "load")
10563   (set_attr "update" "no")
10564   (set_attr "indexed" "no")])
10565
10566(define_insn "load_toc_v4_pic_si"
10567  [(set (reg:SI LR_REGNO)
10568	(unspec:SI [(const_int 0)] UNSPEC_TOC))]
10569  "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10570  "bl _GLOBAL_OFFSET_TABLE_@local-4"
10571  [(set_attr "type" "branch")
10572   (set_attr "length" "4")])
10573
10574(define_expand "load_toc_v4_PIC_1"
10575  [(parallel [(set (reg:SI LR_REGNO)
10576		   (match_operand:SI 0 "immediate_operand" "s"))
10577	      (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10578  "TARGET_ELF && DEFAULT_ABI == ABI_V4
10579   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10580  "")
10581
10582(define_insn "load_toc_v4_PIC_1_normal"
10583  [(set (reg:SI LR_REGNO)
10584	(match_operand:SI 0 "immediate_operand" "s"))
10585   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10586  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10587   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10588  "bcl 20,31,%0\\n%0:"
10589  [(set_attr "type" "branch")
10590   (set_attr "length" "4")
10591   (set_attr "cannot_copy" "yes")])
10592
10593(define_insn "load_toc_v4_PIC_1_476"
10594  [(set (reg:SI LR_REGNO)
10595	(match_operand:SI 0 "immediate_operand" "s"))
10596   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10597  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10598   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10599  "*
10600{
10601  char name[32];
10602  static char templ[32];
10603
10604  get_ppc476_thunk_name (name);
10605  sprintf (templ, \"bl %s\\n%%0:\", name);
10606  return templ;
10607}"
10608  [(set_attr "type" "branch")
10609   (set_attr "length" "4")
10610   (set_attr "cannot_copy" "yes")])
10611
10612(define_expand "load_toc_v4_PIC_1b"
10613  [(parallel [(set (reg:SI LR_REGNO)
10614		   (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10615			       (label_ref (match_operand 1 "" ""))]
10616		           UNSPEC_TOCPTR))
10617	      (match_dup 1)])]
10618  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10619  "")
10620
10621(define_insn "load_toc_v4_PIC_1b_normal"
10622  [(set (reg:SI LR_REGNO)
10623	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10624		    (label_ref (match_operand 1 "" ""))]
10625		UNSPEC_TOCPTR))
10626   (match_dup 1)]
10627  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10628  "bcl 20,31,$+8\;.long %0-$"
10629  [(set_attr "type" "branch")
10630   (set_attr "length" "8")])
10631
10632(define_insn "load_toc_v4_PIC_1b_476"
10633  [(set (reg:SI LR_REGNO)
10634	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10635		    (label_ref (match_operand 1 "" ""))]
10636		UNSPEC_TOCPTR))
10637   (match_dup 1)]
10638  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10639  "*
10640{
10641  char name[32];
10642  static char templ[32];
10643
10644  get_ppc476_thunk_name (name);
10645  sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10646  return templ;
10647}"
10648  [(set_attr "type" "branch")
10649   (set_attr "length" "16")])
10650
10651(define_insn "load_toc_v4_PIC_2"
10652  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10653	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10654		   (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10655			     (match_operand:SI 3 "immediate_operand" "s")))))]
10656  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10657  "lwz %0,%2-%3(%1)"
10658  [(set_attr "type" "load")])
10659
10660(define_insn "load_toc_v4_PIC_3b"
10661  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10662	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10663		 (high:SI
10664		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10665			     (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10666  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10667  "addis %0,%1,%2-%3@ha")
10668
10669(define_insn "load_toc_v4_PIC_3c"
10670  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10671	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10672		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10673			     (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10674  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10675  "addi %0,%1,%2-%3@l")
10676
10677;; If the TOC is shared over a translation unit, as happens with all
10678;; the kinds of PIC that we support, we need to restore the TOC
10679;; pointer only when jumping over units of translation.
10680;; On Darwin, we need to reload the picbase.
10681
10682(define_expand "builtin_setjmp_receiver"
10683  [(use (label_ref (match_operand 0 "" "")))]
10684  "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10685   || (TARGET_TOC && TARGET_MINIMAL_TOC)
10686   || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10687  "
10688{
10689#if TARGET_MACHO
10690  if (DEFAULT_ABI == ABI_DARWIN)
10691    {
10692      rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10693      rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10694      rtx tmplabrtx;
10695      char tmplab[20];
10696
10697      crtl->uses_pic_offset_table = 1;
10698      ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10699				  CODE_LABEL_NUMBER (operands[0]));
10700      tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10701
10702      emit_insn (gen_load_macho_picbase (tmplabrtx));
10703      emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10704      emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10705    }
10706  else
10707#endif
10708    rs6000_emit_load_toc_table (FALSE);
10709  DONE;
10710}")
10711
10712;; Largetoc support
10713(define_insn "*largetoc_high"
10714  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10715        (high:DI
10716	  (unspec [(match_operand:DI 1 "" "")
10717		   (match_operand:DI 2 "gpc_reg_operand" "b")]
10718		  UNSPEC_TOCREL)))]
10719   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10720   "addis %0,%2,%1@toc@ha")
10721
10722(define_insn "*largetoc_high_aix<mode>"
10723  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10724        (high:P
10725	  (unspec [(match_operand:P 1 "" "")
10726		   (match_operand:P 2 "gpc_reg_operand" "b")]
10727		  UNSPEC_TOCREL)))]
10728   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10729   "addis %0,%1@u(%2)")
10730
10731(define_insn "*largetoc_high_plus"
10732  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10733        (high:DI
10734	  (plus:DI
10735	    (unspec [(match_operand:DI 1 "" "")
10736		     (match_operand:DI 2 "gpc_reg_operand" "b")]
10737		    UNSPEC_TOCREL)
10738	    (match_operand:DI 3 "add_cint_operand" "n"))))]
10739   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10740   "addis %0,%2,%1+%3@toc@ha")
10741
10742(define_insn "*largetoc_high_plus_aix<mode>"
10743  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10744        (high:P
10745	  (plus:P
10746	    (unspec [(match_operand:P 1 "" "")
10747		     (match_operand:P 2 "gpc_reg_operand" "b")]
10748		    UNSPEC_TOCREL)
10749	    (match_operand:P 3 "add_cint_operand" "n"))))]
10750   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10751   "addis %0,%1+%3@u(%2)")
10752
10753(define_insn "*largetoc_low"
10754  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10755        (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10756	           (match_operand:DI 2 "" "")))]
10757   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10758   "addi %0,%1,%2@l")
10759
10760(define_insn "*largetoc_low_aix<mode>"
10761  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10762        (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10763	           (match_operand:P 2 "" "")))]
10764   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10765   "la %0,%2@l(%1)")
10766
10767(define_insn_and_split "*tocref<mode>"
10768  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10769	(match_operand:P 1 "small_toc_ref" "R"))]
10770   "TARGET_TOC"
10771   "la %0,%a1"
10772   "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10773  [(set (match_dup 0) (high:P (match_dup 1)))
10774   (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10775
10776;; Elf specific ways of loading addresses for non-PIC code.
10777;; The output of this could be r0, but we make a very strong
10778;; preference for a base register because it will usually
10779;; be needed there.
10780(define_insn "elf_high"
10781  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10782	(high:SI (match_operand 1 "" "")))]
10783  "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10784  "lis %0,%1@ha")
10785
10786(define_insn "elf_low"
10787  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10788	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10789		   (match_operand 2 "" "")))]
10790   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10791   "la %0,%2@l(%1)")
10792
10793;; Call and call_value insns
10794(define_expand "call"
10795  [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10796		    (match_operand 1 "" ""))
10797	      (use (match_operand 2 "" ""))
10798	      (clobber (reg:SI LR_REGNO))])]
10799  ""
10800  "
10801{
10802#if TARGET_MACHO
10803  if (MACHOPIC_INDIRECT)
10804    operands[0] = machopic_indirect_call_target (operands[0]);
10805#endif
10806
10807  gcc_assert (GET_CODE (operands[0]) == MEM);
10808  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10809
10810  operands[0] = XEXP (operands[0], 0);
10811
10812  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10813    {
10814      rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10815      DONE;
10816    }
10817
10818  if (GET_CODE (operands[0]) != SYMBOL_REF
10819      || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10820    {
10821      if (INTVAL (operands[2]) & CALL_LONG)
10822	operands[0] = rs6000_longcall_ref (operands[0]);
10823
10824      switch (DEFAULT_ABI)
10825        {
10826	case ABI_V4:
10827	case ABI_DARWIN:
10828	  operands[0] = force_reg (Pmode, operands[0]);
10829	  break;
10830
10831	default:
10832	  gcc_unreachable ();
10833	}
10834    }
10835}")
10836
10837(define_expand "call_value"
10838  [(parallel [(set (match_operand 0 "" "")
10839		   (call (mem:SI (match_operand 1 "address_operand" ""))
10840			 (match_operand 2 "" "")))
10841	      (use (match_operand 3 "" ""))
10842	      (clobber (reg:SI LR_REGNO))])]
10843  ""
10844  "
10845{
10846#if TARGET_MACHO
10847  if (MACHOPIC_INDIRECT)
10848    operands[1] = machopic_indirect_call_target (operands[1]);
10849#endif
10850
10851  gcc_assert (GET_CODE (operands[1]) == MEM);
10852  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10853
10854  operands[1] = XEXP (operands[1], 0);
10855
10856  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10857    {
10858      rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10859      DONE;
10860    }
10861
10862  if (GET_CODE (operands[1]) != SYMBOL_REF
10863      || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10864    {
10865      if (INTVAL (operands[3]) & CALL_LONG)
10866	operands[1] = rs6000_longcall_ref (operands[1]);
10867
10868      switch (DEFAULT_ABI)
10869        {
10870	case ABI_V4:
10871	case ABI_DARWIN:
10872	  operands[1] = force_reg (Pmode, operands[1]);
10873	  break;
10874
10875	default:
10876	  gcc_unreachable ();
10877	}
10878    }
10879}")
10880
10881;; Call to function in current module.  No TOC pointer reload needed.
10882;; Operand2 is nonzero if we are using the V.4 calling sequence and
10883;; either the function was not prototyped, or it was prototyped as a
10884;; variable argument function.  It is > 0 if FP registers were passed
10885;; and < 0 if they were not.
10886
10887(define_insn "*call_local32"
10888  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10889	 (match_operand 1 "" "g,g"))
10890   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10891   (clobber (reg:SI LR_REGNO))]
10892  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10893  "*
10894{
10895  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10896    output_asm_insn (\"crxor 6,6,6\", operands);
10897
10898  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10899    output_asm_insn (\"creqv 6,6,6\", operands);
10900
10901  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10902}"
10903  [(set_attr "type" "branch")
10904   (set_attr "length" "4,8")])
10905
10906(define_insn "*call_local64"
10907  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10908	 (match_operand 1 "" "g,g"))
10909   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10910   (clobber (reg:SI LR_REGNO))]
10911  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10912  "*
10913{
10914  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10915    output_asm_insn (\"crxor 6,6,6\", operands);
10916
10917  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10918    output_asm_insn (\"creqv 6,6,6\", operands);
10919
10920  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10921}"
10922  [(set_attr "type" "branch")
10923   (set_attr "length" "4,8")])
10924
10925(define_insn "*call_value_local32"
10926  [(set (match_operand 0 "" "")
10927	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10928	      (match_operand 2 "" "g,g")))
10929   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10930   (clobber (reg:SI LR_REGNO))]
10931  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10932  "*
10933{
10934  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10935    output_asm_insn (\"crxor 6,6,6\", operands);
10936
10937  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10938    output_asm_insn (\"creqv 6,6,6\", operands);
10939
10940  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10941}"
10942  [(set_attr "type" "branch")
10943   (set_attr "length" "4,8")])
10944
10945
10946(define_insn "*call_value_local64"
10947  [(set (match_operand 0 "" "")
10948	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10949	      (match_operand 2 "" "g,g")))
10950   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10951   (clobber (reg:SI LR_REGNO))]
10952  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10953  "*
10954{
10955  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10956    output_asm_insn (\"crxor 6,6,6\", operands);
10957
10958  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10959    output_asm_insn (\"creqv 6,6,6\", operands);
10960
10961  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10962}"
10963  [(set_attr "type" "branch")
10964   (set_attr "length" "4,8")])
10965
10966
10967;; A function pointer under System V is just a normal pointer
10968;; operands[0] is the function pointer
10969;; operands[1] is the stack size to clean up
10970;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10971;; which indicates how to set cr1
10972
10973(define_insn "*call_indirect_nonlocal_sysv<mode>"
10974  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10975	 (match_operand 1 "" "g,g,g,g"))
10976   (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10977   (clobber (reg:SI LR_REGNO))]
10978  "DEFAULT_ABI == ABI_V4
10979   || DEFAULT_ABI == ABI_DARWIN"
10980{
10981  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10982    output_asm_insn ("crxor 6,6,6", operands);
10983
10984  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10985    output_asm_insn ("creqv 6,6,6", operands);
10986
10987  return "b%T0l";
10988}
10989  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10990   (set_attr "length" "4,4,8,8")])
10991
10992(define_insn_and_split "*call_nonlocal_sysv<mode>"
10993  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10994	 (match_operand 1 "" "g,g"))
10995   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10996   (clobber (reg:SI LR_REGNO))]
10997  "(DEFAULT_ABI == ABI_DARWIN
10998   || (DEFAULT_ABI == ABI_V4
10999       && (INTVAL (operands[2]) & CALL_LONG) == 0))"
11000{
11001  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11002    output_asm_insn ("crxor 6,6,6", operands);
11003
11004  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11005    output_asm_insn ("creqv 6,6,6", operands);
11006
11007#if TARGET_MACHO
11008  return output_call(insn, operands, 0, 2);
11009#else
11010  if (DEFAULT_ABI == ABI_V4 && flag_pic)
11011    {
11012      gcc_assert (!TARGET_SECURE_PLT);
11013      return "bl %z0@plt";
11014    }
11015  else
11016    return "bl %z0";
11017#endif
11018}
11019  "DEFAULT_ABI == ABI_V4
11020   && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11021   && (INTVAL (operands[2]) & CALL_LONG) == 0"
11022  [(parallel [(call (mem:SI (match_dup 0))
11023		    (match_dup 1))
11024	      (use (match_dup 2))
11025	      (use (match_dup 3))
11026	      (clobber (reg:SI LR_REGNO))])]
11027{
11028  operands[3] = pic_offset_table_rtx;
11029}
11030  [(set_attr "type" "branch,branch")
11031   (set_attr "length" "4,8")])
11032
11033(define_insn "*call_nonlocal_sysv_secure<mode>"
11034  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11035	 (match_operand 1 "" "g,g"))
11036   (use (match_operand:SI 2 "immediate_operand" "O,n"))
11037   (use (match_operand:SI 3 "register_operand" "r,r"))
11038   (clobber (reg:SI LR_REGNO))]
11039  "(DEFAULT_ABI == ABI_V4
11040    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11041    && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11042{
11043  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11044    output_asm_insn ("crxor 6,6,6", operands);
11045
11046  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11047    output_asm_insn ("creqv 6,6,6", operands);
11048
11049  if (flag_pic == 2)
11050    /* The magic 32768 offset here and in the other sysv call insns
11051       corresponds to the offset of r30 in .got2, as given by LCTOC1.
11052       See sysv4.h:toc_section.  */
11053    return "bl %z0+32768@plt";
11054  else
11055    return "bl %z0@plt";
11056}
11057  [(set_attr "type" "branch,branch")
11058   (set_attr "length" "4,8")])
11059
11060(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11061  [(set (match_operand 0 "" "")
11062	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11063	      (match_operand 2 "" "g,g,g,g")))
11064   (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11065   (clobber (reg:SI LR_REGNO))]
11066  "DEFAULT_ABI == ABI_V4
11067   || DEFAULT_ABI == ABI_DARWIN"
11068{
11069  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11070    output_asm_insn ("crxor 6,6,6", operands);
11071
11072  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11073    output_asm_insn ("creqv 6,6,6", operands);
11074
11075  return "b%T1l";
11076}
11077  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11078   (set_attr "length" "4,4,8,8")])
11079
11080(define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11081  [(set (match_operand 0 "" "")
11082	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11083	      (match_operand 2 "" "g,g")))
11084   (use (match_operand:SI 3 "immediate_operand" "O,n"))
11085   (clobber (reg:SI LR_REGNO))]
11086  "(DEFAULT_ABI == ABI_DARWIN
11087   || (DEFAULT_ABI == ABI_V4
11088       && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11089{
11090  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11091    output_asm_insn ("crxor 6,6,6", operands);
11092
11093  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11094    output_asm_insn ("creqv 6,6,6", operands);
11095
11096#if TARGET_MACHO
11097  return output_call(insn, operands, 1, 3);
11098#else
11099  if (DEFAULT_ABI == ABI_V4 && flag_pic)
11100    {
11101      gcc_assert (!TARGET_SECURE_PLT);
11102      return "bl %z1@plt";
11103    }
11104  else
11105    return "bl %z1";
11106#endif
11107}
11108  "DEFAULT_ABI == ABI_V4
11109   && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11110   && (INTVAL (operands[3]) & CALL_LONG) == 0"
11111  [(parallel [(set (match_dup 0)
11112		   (call (mem:SI (match_dup 1))
11113			 (match_dup 2)))
11114	      (use (match_dup 3))
11115	      (use (match_dup 4))
11116	      (clobber (reg:SI LR_REGNO))])]
11117{
11118  operands[4] = pic_offset_table_rtx;
11119}
11120  [(set_attr "type" "branch,branch")
11121   (set_attr "length" "4,8")])
11122
11123(define_insn "*call_value_nonlocal_sysv_secure<mode>"
11124  [(set (match_operand 0 "" "")
11125	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11126	      (match_operand 2 "" "g,g")))
11127   (use (match_operand:SI 3 "immediate_operand" "O,n"))
11128   (use (match_operand:SI 4 "register_operand" "r,r"))
11129   (clobber (reg:SI LR_REGNO))]
11130  "(DEFAULT_ABI == ABI_V4
11131    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11132    && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11133{
11134  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11135    output_asm_insn ("crxor 6,6,6", operands);
11136
11137  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11138    output_asm_insn ("creqv 6,6,6", operands);
11139
11140  if (flag_pic == 2)
11141    return "bl %z1+32768@plt";
11142  else
11143    return "bl %z1@plt";
11144}
11145  [(set_attr "type" "branch,branch")
11146   (set_attr "length" "4,8")])
11147
11148
11149;; Call to AIX abi function in the same module.
11150
11151(define_insn "*call_local_aix<mode>"
11152  [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11153	 (match_operand 1 "" "g"))
11154   (clobber (reg:P LR_REGNO))]
11155  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11156  "bl %z0"
11157  [(set_attr "type" "branch")
11158   (set_attr "length" "4")])
11159
11160(define_insn "*call_value_local_aix<mode>"
11161  [(set (match_operand 0 "" "")
11162	(call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11163	      (match_operand 2 "" "g")))
11164   (clobber (reg:P LR_REGNO))]
11165  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11166  "bl %z1"
11167  [(set_attr "type" "branch")
11168   (set_attr "length" "4")])
11169
11170;; Call to AIX abi function which may be in another module.
11171;; Restore the TOC pointer (r2) after the call.
11172
11173(define_insn "*call_nonlocal_aix<mode>"
11174  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11175	 (match_operand 1 "" "g"))
11176   (clobber (reg:P LR_REGNO))]
11177  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11178  "bl %z0\;nop"
11179  [(set_attr "type" "branch")
11180   (set_attr "length" "8")])
11181
11182(define_insn "*call_value_nonlocal_aix<mode>"
11183  [(set (match_operand 0 "" "")
11184	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11185	      (match_operand 2 "" "g")))
11186   (clobber (reg:P LR_REGNO))]
11187  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11188  "bl %z1\;nop"
11189  [(set_attr "type" "branch")
11190   (set_attr "length" "8")])
11191
11192;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11193;; Operand0 is the addresss of the function to call
11194;; Operand2 is the location in the function descriptor to load r2 from
11195;; Operand3 is the offset of the stack location holding the current TOC pointer
11196
11197(define_insn "*call_indirect_aix<mode>"
11198  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11199	 (match_operand 1 "" "g,g"))
11200   (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11201   (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11202   (clobber (reg:P LR_REGNO))]
11203  "DEFAULT_ABI == ABI_AIX"
11204  "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11205  [(set_attr "type" "jmpreg")
11206   (set_attr "length" "12")])
11207
11208(define_insn "*call_value_indirect_aix<mode>"
11209  [(set (match_operand 0 "" "")
11210	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11211	      (match_operand 2 "" "g,g")))
11212   (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11213   (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11214   (clobber (reg:P LR_REGNO))]
11215  "DEFAULT_ABI == ABI_AIX"
11216  "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11217  [(set_attr "type" "jmpreg")
11218   (set_attr "length" "12")])
11219
11220;; Call to indirect functions with the ELFv2 ABI.
11221;; Operand0 is the addresss of the function to call
11222;; Operand2 is the offset of the stack location holding the current TOC pointer
11223
11224(define_insn "*call_indirect_elfv2<mode>"
11225  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11226	 (match_operand 1 "" "g,g"))
11227   (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11228   (clobber (reg:P LR_REGNO))]
11229  "DEFAULT_ABI == ABI_ELFv2"
11230  "b%T0l\;<ptrload> 2,%2(1)"
11231  [(set_attr "type" "jmpreg")
11232   (set_attr "length" "8")])
11233
11234(define_insn "*call_value_indirect_elfv2<mode>"
11235  [(set (match_operand 0 "" "")
11236	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11237	      (match_operand 2 "" "g,g")))
11238   (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11239   (clobber (reg:P LR_REGNO))]
11240  "DEFAULT_ABI == ABI_ELFv2"
11241  "b%T1l\;<ptrload> 2,%3(1)"
11242  [(set_attr "type" "jmpreg")
11243   (set_attr "length" "8")])
11244
11245
11246;; Call subroutine returning any type.
11247(define_expand "untyped_call"
11248  [(parallel [(call (match_operand 0 "" "")
11249		    (const_int 0))
11250	      (match_operand 1 "" "")
11251	      (match_operand 2 "" "")])]
11252  ""
11253  "
11254{
11255  int i;
11256
11257  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11258
11259  for (i = 0; i < XVECLEN (operands[2], 0); i++)
11260    {
11261      rtx set = XVECEXP (operands[2], 0, i);
11262      emit_move_insn (SET_DEST (set), SET_SRC (set));
11263    }
11264
11265  /* The optimizer does not know that the call sets the function value
11266     registers we stored in the result block.  We avoid problems by
11267     claiming that all hard registers are used and clobbered at this
11268     point.  */
11269  emit_insn (gen_blockage ());
11270
11271  DONE;
11272}")
11273
11274;; sibling call patterns
11275(define_expand "sibcall"
11276  [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11277		    (match_operand 1 "" ""))
11278	      (use (match_operand 2 "" ""))
11279	      (simple_return)])]
11280  ""
11281  "
11282{
11283#if TARGET_MACHO
11284  if (MACHOPIC_INDIRECT)
11285    operands[0] = machopic_indirect_call_target (operands[0]);
11286#endif
11287
11288  gcc_assert (GET_CODE (operands[0]) == MEM);
11289  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11290
11291  operands[0] = XEXP (operands[0], 0);
11292
11293  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11294    {
11295      rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11296      DONE;
11297    }
11298}")
11299
11300(define_expand "sibcall_value"
11301  [(parallel [(set (match_operand 0 "register_operand" "")
11302		(call (mem:SI (match_operand 1 "address_operand" ""))
11303		      (match_operand 2 "" "")))
11304	      (use (match_operand 3 "" ""))
11305	      (simple_return)])]
11306  ""
11307  "
11308{
11309#if TARGET_MACHO
11310  if (MACHOPIC_INDIRECT)
11311    operands[1] = machopic_indirect_call_target (operands[1]);
11312#endif
11313
11314  gcc_assert (GET_CODE (operands[1]) == MEM);
11315  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11316
11317  operands[1] = XEXP (operands[1], 0);
11318
11319  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11320    {
11321      rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11322      DONE;
11323    }
11324}")
11325
11326(define_insn "*sibcall_local32"
11327  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11328	 (match_operand 1 "" "g,g"))
11329   (use (match_operand:SI 2 "immediate_operand" "O,n"))
11330   (simple_return)]
11331  "(INTVAL (operands[2]) & CALL_LONG) == 0"
11332  "*
11333{
11334  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11335    output_asm_insn (\"crxor 6,6,6\", operands);
11336
11337  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11338    output_asm_insn (\"creqv 6,6,6\", operands);
11339
11340  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11341}"
11342  [(set_attr "type" "branch")
11343   (set_attr "length" "4,8")])
11344
11345(define_insn "*sibcall_local64"
11346  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11347	 (match_operand 1 "" "g,g"))
11348   (use (match_operand:SI 2 "immediate_operand" "O,n"))
11349   (simple_return)]
11350  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11351  "*
11352{
11353  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11354    output_asm_insn (\"crxor 6,6,6\", operands);
11355
11356  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11357    output_asm_insn (\"creqv 6,6,6\", operands);
11358
11359  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11360}"
11361  [(set_attr "type" "branch")
11362   (set_attr "length" "4,8")])
11363
11364(define_insn "*sibcall_value_local32"
11365  [(set (match_operand 0 "" "")
11366	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11367	      (match_operand 2 "" "g,g")))
11368   (use (match_operand:SI 3 "immediate_operand" "O,n"))
11369   (simple_return)]
11370  "(INTVAL (operands[3]) & CALL_LONG) == 0"
11371  "*
11372{
11373  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11374    output_asm_insn (\"crxor 6,6,6\", operands);
11375
11376  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11377    output_asm_insn (\"creqv 6,6,6\", operands);
11378
11379  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11380}"
11381  [(set_attr "type" "branch")
11382   (set_attr "length" "4,8")])
11383
11384(define_insn "*sibcall_value_local64"
11385  [(set (match_operand 0 "" "")
11386	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11387	      (match_operand 2 "" "g,g")))
11388   (use (match_operand:SI 3 "immediate_operand" "O,n"))
11389   (simple_return)]
11390  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11391  "*
11392{
11393  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11394    output_asm_insn (\"crxor 6,6,6\", operands);
11395
11396  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11397    output_asm_insn (\"creqv 6,6,6\", operands);
11398
11399  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11400}"
11401  [(set_attr "type" "branch")
11402   (set_attr "length" "4,8")])
11403
11404(define_insn "*sibcall_nonlocal_sysv<mode>"
11405  [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11406	 (match_operand 1 "" ""))
11407   (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11408   (simple_return)]
11409  "(DEFAULT_ABI == ABI_DARWIN
11410    || DEFAULT_ABI == ABI_V4)
11411   && (INTVAL (operands[2]) & CALL_LONG) == 0"
11412  "*
11413{
11414  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11415    output_asm_insn (\"crxor 6,6,6\", operands);
11416
11417  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11418    output_asm_insn (\"creqv 6,6,6\", operands);
11419
11420  if (which_alternative >= 2)
11421    return \"b%T0\";
11422  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11423    {
11424      gcc_assert (!TARGET_SECURE_PLT);
11425      return \"b %z0@plt\";
11426    }
11427  else
11428    return \"b %z0\";
11429}"
11430  [(set_attr "type" "branch")
11431   (set_attr "length" "4,8,4,8")])
11432
11433(define_insn "*sibcall_value_nonlocal_sysv<mode>"
11434  [(set (match_operand 0 "" "")
11435	(call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11436	      (match_operand 2 "" "")))
11437   (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11438   (simple_return)]
11439  "(DEFAULT_ABI == ABI_DARWIN
11440    || DEFAULT_ABI == ABI_V4)
11441   && (INTVAL (operands[3]) & CALL_LONG) == 0"
11442  "*
11443{
11444  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11445    output_asm_insn (\"crxor 6,6,6\", operands);
11446
11447  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11448    output_asm_insn (\"creqv 6,6,6\", operands);
11449
11450  if (which_alternative >= 2)
11451    return \"b%T1\";
11452  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11453    {
11454      gcc_assert (!TARGET_SECURE_PLT);
11455      return \"b %z1@plt\";
11456    }
11457  else
11458    return \"b %z1\";
11459}"
11460  [(set_attr "type" "branch")
11461   (set_attr "length" "4,8,4,8")])
11462
11463;; AIX ABI sibling call patterns.
11464
11465(define_insn "*sibcall_aix<mode>"
11466  [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11467	 (match_operand 1 "" "g,g"))
11468   (simple_return)]
11469  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11470  "@
11471   b %z0
11472   b%T0"
11473  [(set_attr "type" "branch")
11474   (set_attr "length" "4")])
11475
11476(define_insn "*sibcall_value_aix<mode>"
11477  [(set (match_operand 0 "" "")
11478	(call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11479	      (match_operand 2 "" "g,g")))
11480   (simple_return)]
11481  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11482  "@
11483   b %z1
11484   b%T1"
11485  [(set_attr "type" "branch")
11486   (set_attr "length" "4")])
11487
11488(define_expand "sibcall_epilogue"
11489  [(use (const_int 0))]
11490  ""
11491{
11492  if (!TARGET_SCHED_PROLOG)
11493    emit_insn (gen_blockage ());
11494  rs6000_emit_epilogue (TRUE);
11495  DONE;
11496})
11497
11498;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11499;; all of memory.  This blocks insns from being moved across this point.
11500
11501(define_insn "blockage"
11502  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11503  ""
11504  "")
11505
11506(define_expand "probe_stack_address"
11507  [(use (match_operand 0 "address_operand"))]
11508  ""
11509{
11510  operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11511  MEM_VOLATILE_P (operands[0]) = 1;
11512
11513  if (TARGET_64BIT)
11514    emit_insn (gen_probe_stack_di (operands[0]));
11515  else
11516    emit_insn (gen_probe_stack_si (operands[0]));
11517  DONE;
11518})
11519
11520(define_insn "probe_stack_<mode>"
11521  [(set (match_operand:P 0 "memory_operand" "=m")
11522        (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11523  ""
11524{
11525  operands[1] = gen_rtx_REG (Pmode, 0);
11526  return "st<wd>%U0%X0 %1,%0";
11527}
11528  [(set_attr "type" "store")
11529   (set (attr "update")
11530	(if_then_else (match_operand 0 "update_address_mem")
11531		      (const_string "yes")
11532		      (const_string "no")))
11533   (set (attr "indexed")
11534	(if_then_else (match_operand 0 "indexed_address_mem")
11535		      (const_string "yes")
11536		      (const_string "no")))
11537   (set_attr "length" "4")])
11538
11539(define_insn "probe_stack_range<P:mode>"
11540  [(set (match_operand:P 0 "register_operand" "=r")
11541	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11542			    (match_operand:P 2 "register_operand" "r")]
11543			   UNSPECV_PROBE_STACK_RANGE))]
11544  ""
11545  "* return output_probe_stack_range (operands[0], operands[2]);"
11546  [(set_attr "type" "three")])
11547
11548;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11549;; signed & unsigned, and one type of branch.
11550;;
11551;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11552;; insns, and branches.
11553
11554(define_expand "cbranch<mode>4"
11555  [(use (match_operator 0 "rs6000_cbranch_operator"
11556         [(match_operand:GPR 1 "gpc_reg_operand" "")
11557          (match_operand:GPR 2 "reg_or_short_operand" "")]))
11558   (use (match_operand 3 ""))]
11559  ""
11560  "
11561{
11562  /* Take care of the possibility that operands[2] might be negative but
11563     this might be a logical operation.  That insn doesn't exist.  */
11564  if (GET_CODE (operands[2]) == CONST_INT
11565      && INTVAL (operands[2]) < 0)
11566    {
11567      operands[2] = force_reg (<MODE>mode, operands[2]);
11568      operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11569				    GET_MODE (operands[0]),
11570				    operands[1], operands[2]);
11571   }
11572
11573  rs6000_emit_cbranch (<MODE>mode, operands);
11574  DONE;
11575}")
11576
11577(define_expand "cbranch<mode>4"
11578  [(use (match_operator 0 "rs6000_cbranch_operator"
11579         [(match_operand:FP 1 "gpc_reg_operand" "")
11580          (match_operand:FP 2 "gpc_reg_operand" "")]))
11581   (use (match_operand 3 ""))]
11582  ""
11583  "
11584{
11585  rs6000_emit_cbranch (<MODE>mode, operands);
11586  DONE;
11587}")
11588
11589(define_expand "cstore<mode>4_signed"
11590  [(use (match_operator 1 "signed_comparison_operator"
11591         [(match_operand:P 2 "gpc_reg_operand")
11592          (match_operand:P 3 "gpc_reg_operand")]))
11593   (clobber (match_operand:P 0 "gpc_reg_operand"))]
11594  ""
11595{
11596  enum rtx_code cond_code = GET_CODE (operands[1]);
11597
11598  rtx op0 = operands[0];
11599  rtx op1 = operands[2];
11600  rtx op2 = operands[3];
11601
11602  if (cond_code == GE || cond_code == LT)
11603    {
11604      cond_code = swap_condition (cond_code);
11605      std::swap (op1, op2);
11606    }
11607
11608  rtx tmp1 = gen_reg_rtx (<MODE>mode);
11609  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11610  rtx tmp3 = gen_reg_rtx (<MODE>mode);
11611
11612  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11613  emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11614  emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11615
11616  emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11617
11618  if (cond_code == LE)
11619    emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11620  else
11621    {
11622      rtx tmp4 = gen_reg_rtx (<MODE>mode);
11623      emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11624      emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11625    }
11626
11627  DONE;
11628})
11629
11630(define_expand "cstore<mode>4_unsigned"
11631  [(use (match_operator 1 "unsigned_comparison_operator"
11632         [(match_operand:P 2 "gpc_reg_operand")
11633          (match_operand:P 3 "reg_or_short_operand")]))
11634   (clobber (match_operand:P 0 "gpc_reg_operand"))]
11635  ""
11636{
11637  enum rtx_code cond_code = GET_CODE (operands[1]);
11638
11639  rtx op0 = operands[0];
11640  rtx op1 = operands[2];
11641  rtx op2 = operands[3];
11642
11643  if (cond_code == GEU || cond_code == LTU)
11644    {
11645      cond_code = swap_condition (cond_code);
11646      std::swap (op1, op2);
11647    }
11648
11649  if (!gpc_reg_operand (op1, <MODE>mode))
11650    op1 = force_reg (<MODE>mode, op1);
11651  if (!reg_or_short_operand (op2, <MODE>mode))
11652    op2 = force_reg (<MODE>mode, op2);
11653
11654  rtx tmp = gen_reg_rtx (<MODE>mode);
11655  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11656
11657  emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11658  emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11659
11660  if (cond_code == LEU)
11661    emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11662  else
11663    emit_insn (gen_neg<mode>2 (op0, tmp2));
11664
11665  DONE;
11666})
11667
11668(define_expand "cstore_si_as_di"
11669  [(use (match_operator 1 "unsigned_comparison_operator"
11670         [(match_operand:SI 2 "gpc_reg_operand")
11671          (match_operand:SI 3 "reg_or_short_operand")]))
11672   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11673  ""
11674{
11675  int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11676  enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11677
11678  operands[2] = force_reg (SImode, operands[2]);
11679  operands[3] = force_reg (SImode, operands[3]);
11680  rtx op1 = gen_reg_rtx (DImode);
11681  rtx op2 = gen_reg_rtx (DImode);
11682  convert_move (op1, operands[2], uns_flag);
11683  convert_move (op2, operands[3], uns_flag);
11684
11685  if (cond_code == GT || cond_code == LE)
11686    {
11687      cond_code = swap_condition (cond_code);
11688      std::swap (op1, op2);
11689    }
11690
11691  rtx tmp = gen_reg_rtx (DImode);
11692  rtx tmp2 = gen_reg_rtx (DImode);
11693  emit_insn (gen_subdi3 (tmp, op1, op2));
11694  emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11695
11696  rtx tmp3;
11697  switch (cond_code)
11698    {
11699    default:
11700      gcc_unreachable ();
11701    case LT:
11702      tmp3 = tmp2;
11703      break;
11704    case GE:
11705      tmp3 = gen_reg_rtx (DImode);
11706      emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11707      break;
11708    }
11709
11710  convert_move (operands[0], tmp3, 1);
11711
11712  DONE;
11713})
11714
11715(define_expand "cstore<mode>4_signed_imm"
11716  [(use (match_operator 1 "signed_comparison_operator"
11717         [(match_operand:GPR 2 "gpc_reg_operand")
11718          (match_operand:GPR 3 "immediate_operand")]))
11719   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11720  ""
11721{
11722  bool invert = false;
11723
11724  enum rtx_code cond_code = GET_CODE (operands[1]);
11725
11726  rtx op0 = operands[0];
11727  rtx op1 = operands[2];
11728  HOST_WIDE_INT val = INTVAL (operands[3]);
11729
11730  if (cond_code == GE || cond_code == GT)
11731    {
11732      cond_code = reverse_condition (cond_code);
11733      invert = true;
11734    }
11735
11736  if (cond_code == LE)
11737    val++;
11738
11739  rtx tmp = gen_reg_rtx (<MODE>mode);
11740  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11741  rtx x = gen_reg_rtx (<MODE>mode);
11742  if (val < 0)
11743    emit_insn (gen_and<mode>3 (x, op1, tmp));
11744  else
11745    emit_insn (gen_ior<mode>3 (x, op1, tmp));
11746
11747  if (invert)
11748    {
11749      rtx tmp = gen_reg_rtx (<MODE>mode);
11750      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11751      x = tmp;
11752    }
11753
11754  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11755  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11756
11757  DONE;
11758})
11759
11760(define_expand "cstore<mode>4_unsigned_imm"
11761  [(use (match_operator 1 "unsigned_comparison_operator"
11762         [(match_operand:GPR 2 "gpc_reg_operand")
11763          (match_operand:GPR 3 "immediate_operand")]))
11764   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11765  ""
11766{
11767  bool invert = false;
11768
11769  enum rtx_code cond_code = GET_CODE (operands[1]);
11770
11771  rtx op0 = operands[0];
11772  rtx op1 = operands[2];
11773  HOST_WIDE_INT val = INTVAL (operands[3]);
11774
11775  if (cond_code == GEU || cond_code == GTU)
11776    {
11777      cond_code = reverse_condition (cond_code);
11778      invert = true;
11779    }
11780
11781  if (cond_code == LEU)
11782    val++;
11783
11784  rtx tmp = gen_reg_rtx (<MODE>mode);
11785  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11786  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11787  emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11788  rtx x = gen_reg_rtx (<MODE>mode);
11789  if (val < 0)
11790    emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11791  else
11792    emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11793
11794  if (invert)
11795    {
11796      rtx tmp = gen_reg_rtx (<MODE>mode);
11797      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11798      x = tmp;
11799    }
11800
11801  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11802  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11803
11804  DONE;
11805})
11806
11807(define_expand "cstore<mode>4"
11808  [(use (match_operator 1 "rs6000_cbranch_operator"
11809         [(match_operand:GPR 2 "gpc_reg_operand")
11810          (match_operand:GPR 3 "reg_or_short_operand")]))
11811   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11812  ""
11813{
11814  /* Use ISEL if the user asked for it.  */
11815  if (TARGET_ISEL)
11816    rs6000_emit_sISEL (<MODE>mode, operands);
11817
11818  /* Expanding EQ and NE directly to some machine instructions does not help
11819     but does hurt combine.  So don't.  */
11820  else if (GET_CODE (operands[1]) == EQ)
11821    emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11822  else if (<MODE>mode == Pmode
11823	   && GET_CODE (operands[1]) == NE)
11824    emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11825  else if (GET_CODE (operands[1]) == NE)
11826    {
11827      rtx tmp = gen_reg_rtx (<MODE>mode);
11828      emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11829      emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11830    }
11831
11832  /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11833     etc. combinations magically work out just right.  */
11834  else if (<MODE>mode == Pmode
11835	   && unsigned_comparison_operator (operands[1], VOIDmode))
11836    emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11837					   operands[2], operands[3]));
11838
11839  /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11840  else if (<MODE>mode == SImode && Pmode == DImode)
11841    emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11842				    operands[2], operands[3]));
11843
11844  /* For signed comparisons against a constant, we can do some simple
11845     bit-twiddling.  */
11846  else if (signed_comparison_operator (operands[1], VOIDmode)
11847	   && CONST_INT_P (operands[3]))
11848    emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11849					     operands[2], operands[3]));
11850
11851  /* And similarly for unsigned comparisons.  */
11852  else if (unsigned_comparison_operator (operands[1], VOIDmode)
11853	   && CONST_INT_P (operands[3]))
11854    emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11855					       operands[2], operands[3]));
11856
11857  /* We also do not want to use mfcr for signed comparisons.  */
11858  else if (<MODE>mode == Pmode
11859	   && signed_comparison_operator (operands[1], VOIDmode))
11860    emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11861					 operands[2], operands[3]));
11862
11863  /* Everything else, use the mfcr brute force.  */
11864  else
11865    rs6000_emit_sCOND (<MODE>mode, operands);
11866
11867  DONE;
11868})
11869
11870(define_expand "cstore<mode>4"
11871  [(use (match_operator 1 "rs6000_cbranch_operator"
11872         [(match_operand:FP 2 "gpc_reg_operand")
11873          (match_operand:FP 3 "gpc_reg_operand")]))
11874   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11875  ""
11876{
11877  rs6000_emit_sCOND (<MODE>mode, operands);
11878  DONE;
11879})
11880
11881
11882(define_expand "stack_protect_set"
11883  [(match_operand 0 "memory_operand")
11884   (match_operand 1 "memory_operand")]
11885  ""
11886{
11887  if (rs6000_stack_protector_guard == SSP_TLS)
11888    {
11889      rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11890      rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11891      rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11892      operands[1] = gen_rtx_MEM (Pmode, addr);
11893    }
11894
11895  if (TARGET_64BIT)
11896    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11897  else
11898    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11899
11900  DONE;
11901})
11902
11903(define_insn "stack_protect_setsi"
11904  [(set (match_operand:SI 0 "memory_operand" "=m")
11905	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11906   (set (match_scratch:SI 2 "=&r") (const_int 0))]
11907  "TARGET_32BIT"
11908  "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11909  [(set_attr "type" "three")
11910   (set_attr "length" "12")])
11911
11912(define_insn "stack_protect_setdi"
11913  [(set (match_operand:DI 0 "memory_operand" "=Y")
11914	(unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11915   (set (match_scratch:DI 2 "=&r") (const_int 0))]
11916  "TARGET_64BIT"
11917  "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11918  [(set_attr "type" "three")
11919   (set_attr "length" "12")])
11920
11921(define_expand "stack_protect_test"
11922  [(match_operand 0 "memory_operand")
11923   (match_operand 1 "memory_operand")
11924   (match_operand 2 "")]
11925  ""
11926{
11927  rtx guard = operands[1];
11928
11929  if (rs6000_stack_protector_guard == SSP_TLS)
11930    {
11931      rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11932      rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11933      rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11934      guard = gen_rtx_MEM (Pmode, addr);
11935    }
11936
11937  operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11938  rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11939  rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11940  emit_jump_insn (jump);
11941
11942  DONE;
11943})
11944
11945(define_insn "stack_protect_testsi"
11946  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11947        (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11948		      (match_operand:SI 2 "memory_operand" "m,m")]
11949		     UNSPEC_SP_TEST))
11950   (set (match_scratch:SI 4 "=r,r") (const_int 0))
11951   (clobber (match_scratch:SI 3 "=&r,&r"))]
11952  "TARGET_32BIT"
11953  "@
11954   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11955   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11956  [(set_attr "length" "16,20")])
11957
11958(define_insn "stack_protect_testdi"
11959  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11960        (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11961		      (match_operand:DI 2 "memory_operand" "Y,Y")]
11962		     UNSPEC_SP_TEST))
11963   (set (match_scratch:DI 4 "=r,r") (const_int 0))
11964   (clobber (match_scratch:DI 3 "=&r,&r"))]
11965  "TARGET_64BIT"
11966  "@
11967   ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11968   ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11969  [(set_attr "length" "16,20")])
11970
11971
11972;; Here are the actual compare insns.
11973(define_insn "*cmp<mode>_signed"
11974  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11975	(compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11976		    (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11977  ""
11978  "cmp<wd>%I2 %0,%1,%2"
11979  [(set_attr "type" "cmp")])
11980
11981(define_insn "*cmp<mode>_unsigned"
11982  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11983	(compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11984		       (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11985  ""
11986  "cmpl<wd>%I2 %0,%1,%2"
11987  [(set_attr "type" "cmp")])
11988
11989;; If we are comparing a register for equality with a large constant,
11990;; we can do this with an XOR followed by a compare.  But this is profitable
11991;; only if the large constant is only used for the comparison (and in this
11992;; case we already have a register to reuse as scratch).
11993;;
11994;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11995;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11996
11997(define_peephole2
11998  [(set (match_operand:SI 0 "register_operand")
11999        (match_operand:SI 1 "logical_const_operand" ""))
12000   (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
12001		       [(match_dup 0)
12002			(match_operand:SI 2 "logical_const_operand" "")]))
12003   (set (match_operand:CC 4 "cc_reg_operand" "")
12004        (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
12005                    (match_dup 0)))
12006   (set (pc)
12007        (if_then_else (match_operator 6 "equality_operator"
12008                       [(match_dup 4) (const_int 0)])
12009                      (match_operand 7 "" "")
12010                      (match_operand 8 "" "")))]
12011  "peep2_reg_dead_p (3, operands[0])
12012   && peep2_reg_dead_p (4, operands[4])
12013   && REGNO (operands[0]) != REGNO (operands[5])"
12014 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12015  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12016  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12017
12018{
12019  /* Get the constant we are comparing against, and see what it looks like
12020     when sign-extended from 16 to 32 bits.  Then see what constant we could
12021     XOR with SEXTC to get the sign-extended value.  */
12022  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12023					      SImode,
12024					      operands[1], operands[2]);
12025  HOST_WIDE_INT c = INTVAL (cnst);
12026  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
12027  HOST_WIDE_INT xorv = c ^ sextc;
12028
12029  operands[9] = GEN_INT (xorv);
12030  operands[10] = GEN_INT (sextc);
12031})
12032
12033;; The following two insns don't exist as single insns, but if we provide
12034;; them, we can swap an add and compare, which will enable us to overlap more
12035;; of the required delay between a compare and branch.  We generate code for
12036;; them by splitting.
12037
12038(define_insn ""
12039  [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12040	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12041		    (match_operand:SI 2 "short_cint_operand" "i")))
12042   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12043	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12044  ""
12045  "#"
12046  [(set_attr "length" "8")])
12047
12048(define_insn ""
12049  [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12050	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12051		       (match_operand:SI 2 "u_short_cint_operand" "i")))
12052   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12053	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12054  ""
12055  "#"
12056  [(set_attr "length" "8")])
12057
12058(define_split
12059  [(set (match_operand:CC 3 "cc_reg_operand" "")
12060	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12061		    (match_operand:SI 2 "short_cint_operand" "")))
12062   (set (match_operand:SI 0 "gpc_reg_operand" "")
12063	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12064  ""
12065  [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12066   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12067
12068(define_split
12069  [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12070	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12071		       (match_operand:SI 2 "u_short_cint_operand" "")))
12072   (set (match_operand:SI 0 "gpc_reg_operand" "")
12073	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12074  ""
12075  [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12076   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12077
12078;; Only need to compare second words if first words equal
12079(define_insn "*cmp<mode>_internal1"
12080  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12081	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12082		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12083  "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12084   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12085  "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12086  [(set_attr "type" "fpcompare")
12087   (set_attr "length" "12")])
12088
12089(define_insn_and_split "*cmp<mode>_internal2"
12090  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12091	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12092		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12093    (clobber (match_scratch:DF 3 "=d"))
12094    (clobber (match_scratch:DF 4 "=d"))
12095    (clobber (match_scratch:DF 5 "=d"))
12096    (clobber (match_scratch:DF 6 "=d"))
12097    (clobber (match_scratch:DF 7 "=d"))
12098    (clobber (match_scratch:DF 8 "=d"))
12099    (clobber (match_scratch:DF 9 "=d"))
12100    (clobber (match_scratch:DF 10 "=d"))
12101    (clobber (match_scratch:GPR 11 "=b"))]
12102  "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12103   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12104  "#"
12105  "&& reload_completed"
12106  [(set (match_dup 3) (match_dup 14))
12107   (set (match_dup 4) (match_dup 15))
12108   (set (match_dup 9) (abs:DF (match_dup 5)))
12109   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12110   (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12111			   (label_ref (match_dup 12))
12112			   (pc)))
12113   (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12114   (set (pc) (label_ref (match_dup 13)))
12115   (match_dup 12)
12116   (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12117   (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12118   (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12119   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12120   (match_dup 13)]
12121{
12122  REAL_VALUE_TYPE rv;
12123  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12124  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12125
12126  operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12127  operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12128  operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12129  operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12130  operands[12] = gen_label_rtx ();
12131  operands[13] = gen_label_rtx ();
12132  real_inf (&rv);
12133  operands[14] = force_const_mem (DFmode,
12134				  const_double_from_real_value (rv, DFmode));
12135  operands[15] = force_const_mem (DFmode,
12136				  const_double_from_real_value (dconst0,
12137								DFmode));
12138  if (TARGET_TOC)
12139    {
12140      rtx tocref;
12141      tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12142      operands[14] = gen_const_mem (DFmode, tocref);
12143      tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12144      operands[15] = gen_const_mem (DFmode, tocref);
12145      set_mem_alias_set (operands[14], get_TOC_alias_set ());
12146      set_mem_alias_set (operands[15], get_TOC_alias_set ());
12147    }
12148})
12149
12150;; Now we have the scc insns.  We can do some combinations because of the
12151;; way the machine works.
12152;;
12153;; Note that this is probably faster if we can put an insn between the
12154;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
12155;; cases the insns below which don't use an intermediate CR field will
12156;; be used instead.
12157(define_insn ""
12158  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12159	(match_operator:SI 1 "scc_comparison_operator"
12160			   [(match_operand 2 "cc_reg_operand" "y")
12161			    (const_int 0)]))]
12162  ""
12163  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12164  [(set (attr "type")
12165     (cond [(match_test "TARGET_MFCRF")
12166		(const_string "mfcrf")
12167	   ]
12168	(const_string "mfcr")))
12169   (set_attr "length" "8")])
12170
12171;; Same as above, but get the GT bit.
12172(define_insn "move_from_CR_gt_bit"
12173  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12174	(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
12175  "TARGET_HARD_FLOAT && !TARGET_FPRS"
12176  "mfcr %0\;rlwinm %0,%0,%D1,31,31"
12177  [(set_attr "type" "mfcr")
12178   (set_attr "length" "8")])
12179
12180;; Same as above, but get the OV/ORDERED bit.
12181(define_insn "move_from_CR_ov_bit"
12182  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12183	(unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12184		   UNSPEC_MV_CR_OV))]
12185  "TARGET_ISEL"
12186  "mfcr %0\;rlwinm %0,%0,%t1,1"
12187  [(set_attr "type" "mfcr")
12188   (set_attr "length" "8")])
12189
12190(define_insn ""
12191  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12192	(match_operator:DI 1 "scc_comparison_operator"
12193			   [(match_operand 2 "cc_reg_operand" "y")
12194			    (const_int 0)]))]
12195  "TARGET_POWERPC64"
12196  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12197  [(set (attr "type")
12198     (cond [(match_test "TARGET_MFCRF")
12199		(const_string "mfcrf")
12200	   ]
12201	(const_string "mfcr")))
12202   (set_attr "length" "8")])
12203
12204(define_insn ""
12205  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12206	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
12207				       [(match_operand 2 "cc_reg_operand" "y,y")
12208					(const_int 0)])
12209		    (const_int 0)))
12210   (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12211	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12212  "TARGET_32BIT"
12213  "@
12214   mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12215   #"
12216  [(set_attr "type" "shift")
12217   (set_attr "dot" "yes")
12218   (set_attr "length" "8,16")])
12219
12220(define_split
12221  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12222	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
12223				       [(match_operand 2 "cc_reg_operand" "")
12224					(const_int 0)])
12225		    (const_int 0)))
12226   (set (match_operand:SI 3 "gpc_reg_operand" "")
12227	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12228  "TARGET_32BIT && reload_completed"
12229  [(set (match_dup 3)
12230	(match_op_dup 1 [(match_dup 2) (const_int 0)]))
12231   (set (match_dup 0)
12232	(compare:CC (match_dup 3)
12233		    (const_int 0)))]
12234  "")
12235
12236(define_insn ""
12237  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12238	(ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12239				      [(match_operand 2 "cc_reg_operand" "y")
12240				       (const_int 0)])
12241		   (match_operand:SI 3 "const_int_operand" "n")))]
12242  ""
12243  "*
12244{
12245  int is_bit = ccr_bit (operands[1], 1);
12246  int put_bit = 31 - (INTVAL (operands[3]) & 31);
12247  int count;
12248
12249  if (is_bit >= put_bit)
12250    count = is_bit - put_bit;
12251  else
12252    count = 32 - (put_bit - is_bit);
12253
12254  operands[4] = GEN_INT (count);
12255  operands[5] = GEN_INT (put_bit);
12256
12257  return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12258}"
12259  [(set (attr "type")
12260     (cond [(match_test "TARGET_MFCRF")
12261		(const_string "mfcrf")
12262	   ]
12263	(const_string "mfcr")))
12264   (set_attr "length" "8")])
12265
12266(define_insn ""
12267  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12268	(compare:CC
12269	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12270				       [(match_operand 2 "cc_reg_operand" "y,y")
12271					(const_int 0)])
12272		    (match_operand:SI 3 "const_int_operand" "n,n"))
12273	 (const_int 0)))
12274   (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12275	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12276		   (match_dup 3)))]
12277  ""
12278  "*
12279{
12280  int is_bit = ccr_bit (operands[1], 1);
12281  int put_bit = 31 - (INTVAL (operands[3]) & 31);
12282  int count;
12283
12284  /* Force split for non-cc0 compare.  */
12285  if (which_alternative == 1)
12286     return \"#\";
12287
12288  if (is_bit >= put_bit)
12289    count = is_bit - put_bit;
12290  else
12291    count = 32 - (put_bit - is_bit);
12292
12293  operands[5] = GEN_INT (count);
12294  operands[6] = GEN_INT (put_bit);
12295
12296  return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12297}"
12298  [(set_attr "type" "shift")
12299   (set_attr "dot" "yes")
12300   (set_attr "length" "8,16")])
12301
12302(define_split
12303  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12304	(compare:CC
12305	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12306				       [(match_operand 2 "cc_reg_operand" "")
12307					(const_int 0)])
12308		    (match_operand:SI 3 "const_int_operand" ""))
12309	 (const_int 0)))
12310   (set (match_operand:SI 4 "gpc_reg_operand" "")
12311	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12312		   (match_dup 3)))]
12313  "reload_completed"
12314  [(set (match_dup 4)
12315	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12316		   (match_dup 3)))
12317   (set (match_dup 0)
12318	(compare:CC (match_dup 4)
12319		    (const_int 0)))]
12320  "")
12321
12322
12323(define_mode_attr scc_eq_op2 [(SI "rKLI")
12324			      (DI "rKJI")])
12325
12326(define_insn_and_split "eq<mode>3"
12327  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12328	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12329		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12330   (clobber (match_scratch:GPR 3 "=r"))
12331   (clobber (match_scratch:GPR 4 "=r"))]
12332  ""
12333  "#"
12334  ""
12335  [(set (match_dup 4)
12336	(clz:GPR (match_dup 3)))
12337   (set (match_dup 0)
12338	(lshiftrt:GPR (match_dup 4)
12339		      (match_dup 5)))]
12340{
12341  operands[3] = rs6000_emit_eqne (<MODE>mode,
12342				  operands[1], operands[2], operands[3]);
12343
12344  if (GET_CODE (operands[4]) == SCRATCH)
12345    operands[4] = gen_reg_rtx (<MODE>mode);
12346
12347  operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12348}
12349  [(set (attr "length")
12350	(if_then_else (match_test "operands[2] == const0_rtx")
12351		      (const_string "8")
12352		      (const_string "12")))])
12353
12354(define_insn_and_split "ne<mode>3"
12355  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12356	(ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12357	      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12358   (clobber (match_scratch:P 3 "=r"))
12359   (clobber (match_scratch:P 4 "=r"))
12360   (clobber (reg:P CA_REGNO))]
12361  "!TARGET_ISEL"
12362  "#"
12363  ""
12364  [(parallel [(set (match_dup 4)
12365		   (plus:P (match_dup 3)
12366			   (const_int -1)))
12367	      (set (reg:P CA_REGNO)
12368		   (ne:P (match_dup 3)
12369			 (const_int 0)))])
12370   (parallel [(set (match_dup 0)
12371		   (plus:P (plus:P (not:P (match_dup 4))
12372				   (reg:P CA_REGNO))
12373			   (match_dup 3)))
12374	      (clobber (reg:P CA_REGNO))])]
12375{
12376  operands[3] = rs6000_emit_eqne (<MODE>mode,
12377				  operands[1], operands[2], operands[3]);
12378
12379  if (GET_CODE (operands[4]) == SCRATCH)
12380    operands[4] = gen_reg_rtx (<MODE>mode);
12381}
12382  [(set (attr "length")
12383	(if_then_else (match_test "operands[2] == const0_rtx")
12384		      (const_string "8")
12385		      (const_string "12")))])
12386
12387(define_insn_and_split "*neg_eq_<mode>"
12388  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12389	(neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12390		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12391   (clobber (match_scratch:P 3 "=r"))
12392   (clobber (match_scratch:P 4 "=r"))
12393   (clobber (reg:P CA_REGNO))]
12394  ""
12395  "#"
12396  ""
12397  [(parallel [(set (match_dup 4)
12398		   (plus:P (match_dup 3)
12399			   (const_int -1)))
12400	      (set (reg:P CA_REGNO)
12401		   (ne:P (match_dup 3)
12402			 (const_int 0)))])
12403   (parallel [(set (match_dup 0)
12404		   (plus:P (reg:P CA_REGNO)
12405			   (const_int -1)))
12406	      (clobber (reg:P CA_REGNO))])]
12407{
12408  operands[3] = rs6000_emit_eqne (<MODE>mode,
12409				  operands[1], operands[2], operands[3]);
12410
12411  if (GET_CODE (operands[4]) == SCRATCH)
12412    operands[4] = gen_reg_rtx (<MODE>mode);
12413}
12414  [(set (attr "length")
12415	(if_then_else (match_test "operands[2] == const0_rtx")
12416		      (const_string "8")
12417		      (const_string "12")))])
12418
12419(define_insn_and_split "*neg_ne_<mode>"
12420  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12421	(neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12422		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12423   (clobber (match_scratch:P 3 "=r"))
12424   (clobber (match_scratch:P 4 "=r"))
12425   (clobber (reg:P CA_REGNO))]
12426  ""
12427  "#"
12428  ""
12429  [(parallel [(set (match_dup 4)
12430		   (neg:P (match_dup 3)))
12431	      (set (reg:P CA_REGNO)
12432		   (eq:P (match_dup 3)
12433			 (const_int 0)))])
12434   (parallel [(set (match_dup 0)
12435		   (plus:P (reg:P CA_REGNO)
12436			   (const_int -1)))
12437	      (clobber (reg:P CA_REGNO))])]
12438{
12439  operands[3] = rs6000_emit_eqne (<MODE>mode,
12440				  operands[1], operands[2], operands[3]);
12441
12442  if (GET_CODE (operands[4]) == SCRATCH)
12443    operands[4] = gen_reg_rtx (<MODE>mode);
12444}
12445  [(set (attr "length")
12446	(if_then_else (match_test "operands[2] == const0_rtx")
12447		      (const_string "8")
12448		      (const_string "12")))])
12449
12450(define_insn_and_split "*plus_eq_<mode>"
12451  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12452	(plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12453		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12454		(match_operand:P 3 "gpc_reg_operand" "r")))
12455   (clobber (match_scratch:P 4 "=r"))
12456   (clobber (match_scratch:P 5 "=r"))
12457   (clobber (reg:P CA_REGNO))]
12458  ""
12459  "#"
12460  ""
12461  [(parallel [(set (match_dup 5)
12462		   (neg:P (match_dup 4)))
12463	      (set (reg:P CA_REGNO)
12464		   (eq:P (match_dup 4)
12465			 (const_int 0)))])
12466   (parallel [(set (match_dup 0)
12467		   (plus:P (match_dup 3)
12468			   (reg:P CA_REGNO)))
12469	      (clobber (reg:P CA_REGNO))])]
12470{
12471  operands[4] = rs6000_emit_eqne (<MODE>mode,
12472				  operands[1], operands[2], operands[4]);
12473
12474  if (GET_CODE (operands[5]) == SCRATCH)
12475    operands[5] = gen_reg_rtx (<MODE>mode);
12476}
12477  [(set (attr "length")
12478	(if_then_else (match_test "operands[2] == const0_rtx")
12479		      (const_string "8")
12480		      (const_string "12")))])
12481
12482(define_insn_and_split "*plus_ne_<mode>"
12483  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12484	(plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12485		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12486		(match_operand:P 3 "gpc_reg_operand" "r")))
12487   (clobber (match_scratch:P 4 "=r"))
12488   (clobber (match_scratch:P 5 "=r"))
12489   (clobber (reg:P CA_REGNO))]
12490  ""
12491  "#"
12492  ""
12493  [(parallel [(set (match_dup 5)
12494		   (plus:P (match_dup 4)
12495			   (const_int -1)))
12496	      (set (reg:P CA_REGNO)
12497		   (ne:P (match_dup 4)
12498			 (const_int 0)))])
12499   (parallel [(set (match_dup 0)
12500		   (plus:P (match_dup 3)
12501			   (reg:P CA_REGNO)))
12502	      (clobber (reg:P CA_REGNO))])]
12503{
12504  operands[4] = rs6000_emit_eqne (<MODE>mode,
12505				  operands[1], operands[2], operands[4]);
12506
12507  if (GET_CODE (operands[5]) == SCRATCH)
12508    operands[5] = gen_reg_rtx (<MODE>mode);
12509}
12510  [(set (attr "length")
12511	(if_then_else (match_test "operands[2] == const0_rtx")
12512		      (const_string "8")
12513		      (const_string "12")))])
12514
12515(define_insn_and_split "*minus_eq_<mode>"
12516  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12517	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12518		 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12519		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12520   (clobber (match_scratch:P 4 "=r"))
12521   (clobber (match_scratch:P 5 "=r"))
12522   (clobber (reg:P CA_REGNO))]
12523  ""
12524  "#"
12525  ""
12526  [(parallel [(set (match_dup 5)
12527		   (plus:P (match_dup 4)
12528			   (const_int -1)))
12529	      (set (reg:P CA_REGNO)
12530		   (ne:P (match_dup 4)
12531			 (const_int 0)))])
12532   (parallel [(set (match_dup 0)
12533		   (plus:P (plus:P (match_dup 3)
12534				   (reg:P CA_REGNO))
12535			   (const_int -1)))
12536	      (clobber (reg:P CA_REGNO))])]
12537{
12538  operands[4] = rs6000_emit_eqne (<MODE>mode,
12539				  operands[1], operands[2], operands[4]);
12540
12541  if (GET_CODE (operands[5]) == SCRATCH)
12542    operands[5] = gen_reg_rtx (<MODE>mode);
12543}
12544  [(set (attr "length")
12545	(if_then_else (match_test "operands[2] == const0_rtx")
12546		      (const_string "8")
12547		      (const_string "12")))])
12548
12549(define_insn_and_split "*minus_ne_<mode>"
12550  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12551	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12552		 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12553		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12554   (clobber (match_scratch:P 4 "=r"))
12555   (clobber (match_scratch:P 5 "=r"))
12556   (clobber (reg:P CA_REGNO))]
12557  ""
12558  "#"
12559  ""
12560  [(parallel [(set (match_dup 5)
12561		   (neg:P (match_dup 4)))
12562	      (set (reg:P CA_REGNO)
12563		   (eq:P (match_dup 4)
12564			 (const_int 0)))])
12565   (parallel [(set (match_dup 0)
12566		   (plus:P (plus:P (match_dup 3)
12567				   (reg:P CA_REGNO))
12568			   (const_int -1)))
12569	      (clobber (reg:P CA_REGNO))])]
12570{
12571  operands[4] = rs6000_emit_eqne (<MODE>mode,
12572				  operands[1], operands[2], operands[4]);
12573
12574  if (GET_CODE (operands[5]) == SCRATCH)
12575    operands[5] = gen_reg_rtx (<MODE>mode);
12576}
12577  [(set (attr "length")
12578	(if_then_else (match_test "operands[2] == const0_rtx")
12579		      (const_string "8")
12580		      (const_string "12")))])
12581
12582(define_insn_and_split "*eqsi3_ext<mode>"
12583  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12584	(eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12585		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12586   (clobber (match_scratch:SI 3 "=r"))
12587   (clobber (match_scratch:SI 4 "=r"))]
12588  ""
12589  "#"
12590  ""
12591  [(set (match_dup 4)
12592	(clz:SI (match_dup 3)))
12593   (set (match_dup 0)
12594	(zero_extend:EXTSI
12595	  (lshiftrt:SI (match_dup 4)
12596		       (const_int 5))))]
12597{
12598  operands[3] = rs6000_emit_eqne (SImode,
12599				  operands[1], operands[2], operands[3]);
12600
12601  if (GET_CODE (operands[4]) == SCRATCH)
12602    operands[4] = gen_reg_rtx (SImode);
12603}
12604  [(set (attr "length")
12605	(if_then_else (match_test "operands[2] == const0_rtx")
12606		      (const_string "8")
12607		      (const_string "12")))])
12608
12609(define_insn_and_split "*nesi3_ext<mode>"
12610  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12611	(ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12612		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12613   (clobber (match_scratch:SI 3 "=r"))
12614   (clobber (match_scratch:SI 4 "=r"))
12615   (clobber (match_scratch:EXTSI 5 "=r"))]
12616  ""
12617  "#"
12618  ""
12619  [(set (match_dup 4)
12620	(clz:SI (match_dup 3)))
12621   (set (match_dup 5)
12622	(zero_extend:EXTSI
12623	  (lshiftrt:SI (match_dup 4)
12624		       (const_int 5))))
12625   (set (match_dup 0)
12626	(xor:EXTSI (match_dup 5)
12627		   (const_int 1)))]
12628{
12629  operands[3] = rs6000_emit_eqne (SImode,
12630				  operands[1], operands[2], operands[3]);
12631
12632  if (GET_CODE (operands[4]) == SCRATCH)
12633    operands[4] = gen_reg_rtx (SImode);
12634  if (GET_CODE (operands[5]) == SCRATCH)
12635    operands[5] = gen_reg_rtx (<MODE>mode);
12636}
12637  [(set (attr "length")
12638	(if_then_else (match_test "operands[2] == const0_rtx")
12639		      (const_string "12")
12640		      (const_string "16")))])
12641
12642;; Define both directions of branch and return.  If we need a reload
12643;; register, we'd rather use CR0 since it is much easier to copy a
12644;; register CC value to there.
12645
12646(define_insn ""
12647  [(set (pc)
12648	(if_then_else (match_operator 1 "branch_comparison_operator"
12649				      [(match_operand 2
12650						      "cc_reg_operand" "y")
12651				       (const_int 0)])
12652		      (label_ref (match_operand 0 "" ""))
12653		      (pc)))]
12654  ""
12655  "*
12656{
12657  return output_cbranch (operands[1], \"%l0\", 0, insn);
12658}"
12659  [(set_attr "type" "branch")])
12660
12661(define_insn ""
12662  [(set (pc)
12663	(if_then_else (match_operator 0 "branch_comparison_operator"
12664				      [(match_operand 1
12665						      "cc_reg_operand" "y")
12666				       (const_int 0)])
12667		      (any_return)
12668		      (pc)))]
12669  "<return_pred>"
12670  "*
12671{
12672  return output_cbranch (operands[0], NULL, 0, insn);
12673}"
12674  [(set_attr "type" "jmpreg")
12675   (set_attr "length" "4")])
12676
12677(define_insn ""
12678  [(set (pc)
12679	(if_then_else (match_operator 1 "branch_comparison_operator"
12680				      [(match_operand 2
12681						      "cc_reg_operand" "y")
12682				       (const_int 0)])
12683		      (pc)
12684		      (label_ref (match_operand 0 "" ""))))]
12685  ""
12686  "*
12687{
12688  return output_cbranch (operands[1], \"%l0\", 1, insn);
12689}"
12690  [(set_attr "type" "branch")])
12691
12692(define_insn ""
12693  [(set (pc)
12694	(if_then_else (match_operator 0 "branch_comparison_operator"
12695				      [(match_operand 1
12696						      "cc_reg_operand" "y")
12697				       (const_int 0)])
12698		      (pc)
12699		      (any_return)))]
12700  "<return_pred>"
12701  "*
12702{
12703  return output_cbranch (operands[0], NULL, 1, insn);
12704}"
12705  [(set_attr "type" "jmpreg")
12706   (set_attr "length" "4")])
12707
12708;; Logic on condition register values.
12709
12710; This pattern matches things like
12711; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12712;					   (eq:SI (reg:CCFP 68) (const_int 0)))
12713;				   (const_int 1)))
12714; which are generated by the branch logic.
12715; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12716
12717(define_insn "*cceq_ior_compare"
12718  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12719        (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12720	                [(match_operator:SI 2
12721				      "branch_positive_comparison_operator"
12722				      [(match_operand 3
12723						      "cc_reg_operand" "y,y")
12724				       (const_int 0)])
12725	                 (match_operator:SI 4
12726				      "branch_positive_comparison_operator"
12727				      [(match_operand 5
12728						      "cc_reg_operand" "0,y")
12729				       (const_int 0)])])
12730		      (const_int 1)))]
12731  ""
12732  "cr%q1 %E0,%j2,%j4"
12733  [(set_attr "type" "cr_logical,delayed_cr")])
12734
12735; Why is the constant -1 here, but 1 in the previous pattern?
12736; Because ~1 has all but the low bit set.
12737(define_insn ""
12738  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12739        (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12740	                [(not:SI (match_operator:SI 2
12741				      "branch_positive_comparison_operator"
12742				      [(match_operand 3
12743						      "cc_reg_operand" "y,y")
12744				       (const_int 0)]))
12745	                 (match_operator:SI 4
12746				"branch_positive_comparison_operator"
12747				[(match_operand 5
12748						"cc_reg_operand" "0,y")
12749				 (const_int 0)])])
12750		      (const_int -1)))]
12751  ""
12752  "cr%q1 %E0,%j2,%j4"
12753  [(set_attr "type" "cr_logical,delayed_cr")])
12754
12755(define_insn "*cceq_rev_compare"
12756  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12757	(compare:CCEQ (match_operator:SI 1
12758				      "branch_positive_comparison_operator"
12759				      [(match_operand 2
12760						      "cc_reg_operand" "0,y")
12761				       (const_int 0)])
12762		      (const_int 0)))]
12763  ""
12764  "crnot %E0,%j1"
12765  [(set_attr "type" "cr_logical,delayed_cr")])
12766
12767;; If we are comparing the result of two comparisons, this can be done
12768;; using creqv or crxor.
12769
12770(define_insn_and_split ""
12771  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12772	(compare:CCEQ (match_operator 1 "branch_comparison_operator"
12773			      [(match_operand 2 "cc_reg_operand" "y")
12774			       (const_int 0)])
12775		      (match_operator 3 "branch_comparison_operator"
12776			      [(match_operand 4 "cc_reg_operand" "y")
12777			       (const_int 0)])))]
12778  ""
12779  "#"
12780  ""
12781  [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12782				    (match_dup 5)))]
12783  "
12784{
12785  int positive_1, positive_2;
12786
12787  positive_1 = branch_positive_comparison_operator (operands[1],
12788						    GET_MODE (operands[1]));
12789  positive_2 = branch_positive_comparison_operator (operands[3],
12790						    GET_MODE (operands[3]));
12791
12792  if (! positive_1)
12793    operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12794							    GET_CODE (operands[1])),
12795				  SImode,
12796				  operands[2], const0_rtx);
12797  else if (GET_MODE (operands[1]) != SImode)
12798    operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12799				  operands[2], const0_rtx);
12800
12801  if (! positive_2)
12802    operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12803							    GET_CODE (operands[3])),
12804				  SImode,
12805				  operands[4], const0_rtx);
12806  else if (GET_MODE (operands[3]) != SImode)
12807    operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12808				  operands[4], const0_rtx);
12809
12810  if (positive_1 == positive_2)
12811    {
12812      operands[1] = gen_rtx_NOT (SImode, operands[1]);
12813      operands[5] = constm1_rtx;
12814    }
12815  else
12816    {
12817      operands[5] = const1_rtx;
12818    }
12819}")
12820
12821;; Unconditional branch and return.
12822
12823(define_insn "jump"
12824  [(set (pc)
12825	(label_ref (match_operand 0 "" "")))]
12826  ""
12827  "b %l0"
12828  [(set_attr "type" "branch")])
12829
12830(define_insn "<return_str>return"
12831  [(any_return)]
12832  "<return_pred>"
12833  "blr"
12834  [(set_attr "type" "jmpreg")])
12835
12836(define_expand "indirect_jump"
12837  [(set (pc) (match_operand 0 "register_operand" ""))])
12838
12839(define_insn "*indirect_jump<mode>"
12840  [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12841  ""
12842  "@
12843   bctr
12844   blr"
12845  [(set_attr "type" "jmpreg")])
12846
12847;; Table jump for switch statements:
12848(define_expand "tablejump"
12849  [(use (match_operand 0 "" ""))
12850   (use (label_ref (match_operand 1 "" "")))]
12851  ""
12852  "
12853{
12854  if (TARGET_32BIT)
12855    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12856  else
12857    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12858  DONE;
12859}")
12860
12861(define_expand "tablejumpsi"
12862  [(set (match_dup 3)
12863	(plus:SI (match_operand:SI 0 "" "")
12864		 (match_dup 2)))
12865   (parallel [(set (pc) (match_dup 3))
12866	      (use (label_ref (match_operand 1 "" "")))])]
12867  "TARGET_32BIT"
12868  "
12869{ operands[0] = force_reg (SImode, operands[0]);
12870  operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12871  operands[3] = gen_reg_rtx (SImode);
12872}")
12873
12874(define_expand "tablejumpdi"
12875  [(set (match_dup 4)
12876        (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12877   (set (match_dup 3)
12878	(plus:DI (match_dup 4)
12879		 (match_dup 2)))
12880   (parallel [(set (pc) (match_dup 3))
12881	      (use (label_ref (match_operand 1 "" "")))])]
12882  "TARGET_64BIT"
12883  "
12884{ operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12885  operands[3] = gen_reg_rtx (DImode);
12886  operands[4] = gen_reg_rtx (DImode);
12887}")
12888
12889(define_insn "*tablejump<mode>_internal1"
12890  [(set (pc)
12891	(match_operand:P 0 "register_operand" "c,*l"))
12892   (use (label_ref (match_operand 1 "" "")))]
12893  ""
12894  "@
12895   bctr
12896   blr"
12897  [(set_attr "type" "jmpreg")])
12898
12899(define_insn "nop"
12900  [(unspec [(const_int 0)] UNSPEC_NOP)]
12901  ""
12902  "nop")
12903
12904(define_insn "group_ending_nop"
12905  [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12906  ""
12907  "*
12908{
12909  if (rs6000_cpu_attr == CPU_POWER6)
12910    return \"ori 1,1,0\";
12911  return \"ori 2,2,0\";
12912}")
12913
12914;; Define the subtract-one-and-jump insns, starting with the template
12915;; so loop.c knows what to generate.
12916
12917(define_expand "doloop_end"
12918  [(use (match_operand 0 "" ""))	; loop pseudo
12919   (use (match_operand 1 "" ""))]	; label
12920  ""
12921  "
12922{
12923  if (TARGET_64BIT)
12924    {
12925      if (GET_MODE (operands[0]) != DImode)
12926	FAIL;
12927      emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12928    }
12929  else
12930    {
12931      if (GET_MODE (operands[0]) != SImode)
12932	FAIL;
12933      emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12934    }
12935  DONE;
12936}")
12937
12938(define_expand "ctr<mode>"
12939  [(parallel [(set (pc)
12940		   (if_then_else (ne (match_operand:P 0 "register_operand" "")
12941				     (const_int 1))
12942				 (label_ref (match_operand 1 "" ""))
12943				 (pc)))
12944	      (set (match_dup 0)
12945		   (plus:P (match_dup 0)
12946			    (const_int -1)))
12947	      (clobber (match_scratch:CC 2 ""))
12948	      (clobber (match_scratch:P 3 ""))])]
12949  ""
12950  "")
12951
12952;; We need to be able to do this for any operand, including MEM, or we
12953;; will cause reload to blow up since we don't allow output reloads on
12954;; JUMP_INSNs.
12955;; For the length attribute to be calculated correctly, the
12956;; label MUST be operand 0.
12957;; rs6000_legitimate_combined_insn prevents combine creating any of
12958;; the ctr<mode> insns.
12959
12960(define_insn "ctr<mode>_internal1"
12961  [(set (pc)
12962	(if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12963			  (const_int 1))
12964		      (label_ref (match_operand 0 "" ""))
12965		      (pc)))
12966   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12967	(plus:P (match_dup 1)
12968		 (const_int -1)))
12969   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12970   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12971  ""
12972  "*
12973{
12974  if (which_alternative != 0)
12975    return \"#\";
12976  else if (get_attr_length (insn) == 4)
12977    return \"bdnz %l0\";
12978  else
12979    return \"bdz $+8\;b %l0\";
12980}"
12981  [(set_attr "type" "branch")
12982   (set_attr "length" "*,16,20,20")])
12983
12984(define_insn "ctr<mode>_internal2"
12985  [(set (pc)
12986	(if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12987			  (const_int 1))
12988		      (pc)
12989		      (label_ref (match_operand 0 "" ""))))
12990   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12991	(plus:P (match_dup 1)
12992		 (const_int -1)))
12993   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12994   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12995  ""
12996  "*
12997{
12998  if (which_alternative != 0)
12999    return \"#\";
13000  else if (get_attr_length (insn) == 4)
13001    return \"bdz %l0\";
13002  else
13003    return \"bdnz $+8\;b %l0\";
13004}"
13005  [(set_attr "type" "branch")
13006   (set_attr "length" "*,16,20,20")])
13007
13008;; Similar but use EQ
13009
13010(define_insn "ctr<mode>_internal3"
13011  [(set (pc)
13012	(if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13013			  (const_int 1))
13014		      (label_ref (match_operand 0 "" ""))
13015		      (pc)))
13016   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13017	(plus:P (match_dup 1)
13018		 (const_int -1)))
13019   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13020   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13021  ""
13022  "*
13023{
13024  if (which_alternative != 0)
13025    return \"#\";
13026  else if (get_attr_length (insn) == 4)
13027    return \"bdz %l0\";
13028  else
13029    return \"bdnz $+8\;b %l0\";
13030}"
13031  [(set_attr "type" "branch")
13032   (set_attr "length" "*,16,20,20")])
13033
13034(define_insn "ctr<mode>_internal4"
13035  [(set (pc)
13036	(if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13037			  (const_int 1))
13038		      (pc)
13039		      (label_ref (match_operand 0 "" ""))))
13040   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13041	(plus:P (match_dup 1)
13042		 (const_int -1)))
13043   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13044   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13045  ""
13046  "*
13047{
13048  if (which_alternative != 0)
13049    return \"#\";
13050  else if (get_attr_length (insn) == 4)
13051    return \"bdnz %l0\";
13052  else
13053    return \"bdz $+8\;b %l0\";
13054}"
13055  [(set_attr "type" "branch")
13056   (set_attr "length" "*,16,20,20")])
13057
13058;; Now the splitters if we could not allocate the CTR register
13059
13060(define_split
13061  [(set (pc)
13062	(if_then_else (match_operator 2 "comparison_operator"
13063				      [(match_operand:P 1 "gpc_reg_operand" "")
13064				       (const_int 1)])
13065		      (match_operand 5 "" "")
13066		      (match_operand 6 "" "")))
13067   (set (match_operand:P 0 "int_reg_operand" "")
13068	(plus:P (match_dup 1) (const_int -1)))
13069   (clobber (match_scratch:CC 3 ""))
13070   (clobber (match_scratch:P 4 ""))]
13071  "reload_completed"
13072  [(set (match_dup 3)
13073	(compare:CC (match_dup 1)
13074		    (const_int 1)))
13075   (set (match_dup 0)
13076	(plus:P (match_dup 1)
13077		(const_int -1)))
13078   (set (pc) (if_then_else (match_dup 7)
13079			   (match_dup 5)
13080			   (match_dup 6)))]
13081  "
13082{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13083				operands[3], const0_rtx); }")
13084
13085(define_split
13086  [(set (pc)
13087	(if_then_else (match_operator 2 "comparison_operator"
13088				      [(match_operand:P 1 "gpc_reg_operand" "")
13089				       (const_int 1)])
13090		      (match_operand 5 "" "")
13091		      (match_operand 6 "" "")))
13092   (set (match_operand:P 0 "nonimmediate_operand" "")
13093	(plus:P (match_dup 1) (const_int -1)))
13094   (clobber (match_scratch:CC 3 ""))
13095   (clobber (match_scratch:P 4 ""))]
13096  "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13097  [(set (match_dup 3)
13098	(compare:CC (match_dup 1)
13099		    (const_int 1)))
13100   (set (match_dup 4)
13101	(plus:P (match_dup 1)
13102		(const_int -1)))
13103   (set (match_dup 0)
13104	(match_dup 4))
13105   (set (pc) (if_then_else (match_dup 7)
13106			   (match_dup 5)
13107			   (match_dup 6)))]
13108  "
13109{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13110				operands[3], const0_rtx); }")
13111
13112(define_insn "trap"
13113  [(trap_if (const_int 1) (const_int 0))]
13114  ""
13115  "trap"
13116  [(set_attr "type" "trap")])
13117
13118(define_expand "ctrap<mode>4"
13119  [(trap_if (match_operator 0 "ordered_comparison_operator"
13120			    [(match_operand:GPR 1 "register_operand")
13121			     (match_operand:GPR 2 "reg_or_short_operand")])
13122	    (match_operand 3 "zero_constant" ""))]
13123  ""
13124  "")
13125
13126(define_insn ""
13127  [(trap_if (match_operator 0 "ordered_comparison_operator"
13128                            [(match_operand:GPR 1 "register_operand" "r")
13129                             (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13130	    (const_int 0))]
13131  ""
13132  "t<wd>%V0%I2 %1,%2"
13133  [(set_attr "type" "trap")])
13134
13135;; Insns related to generating the function prologue and epilogue.
13136
13137(define_expand "prologue"
13138  [(use (const_int 0))]
13139  ""
13140{
13141  rs6000_emit_prologue ();
13142  if (!TARGET_SCHED_PROLOG)
13143    emit_insn (gen_blockage ());
13144  DONE;
13145})
13146
13147(define_insn "*movesi_from_cr_one"
13148  [(match_parallel 0 "mfcr_operation"
13149		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13150			 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13151				     (match_operand 3 "immediate_operand" "n")]
13152			  UNSPEC_MOVESI_FROM_CR))])]
13153  "TARGET_MFCRF"
13154  "*
13155{
13156  int mask = 0;
13157  int i;
13158  for (i = 0; i < XVECLEN (operands[0], 0); i++)
13159  {
13160    mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13161    operands[4] = GEN_INT (mask);
13162    output_asm_insn (\"mfcr %1,%4\", operands);
13163  }
13164  return \"\";
13165}"
13166  [(set_attr "type" "mfcrf")])
13167
13168(define_insn "movesi_from_cr"
13169  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13170        (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13171		    (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13172		    (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13173		    (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13174		   UNSPEC_MOVESI_FROM_CR))]
13175  ""
13176  "mfcr %0"
13177  [(set_attr "type" "mfcr")])
13178
13179(define_insn "*crsave"
13180  [(match_parallel 0 "crsave_operation"
13181		   [(set (match_operand:SI 1 "memory_operand" "=m")
13182			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13183  ""
13184  "stw %2,%1"
13185  [(set_attr "type" "store")])
13186
13187(define_insn "*stmw"
13188  [(match_parallel 0 "stmw_operation"
13189		   [(set (match_operand:SI 1 "memory_operand" "=m")
13190       			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13191  "TARGET_MULTIPLE"
13192  "stmw %2,%1"
13193  [(set_attr "type" "store")
13194   (set_attr "update" "yes")
13195   (set_attr "indexed" "yes")])
13196
13197; The following comment applies to:
13198;     save_gpregs_*
13199;     save_fpregs_*
13200;     restore_gpregs*
13201;     return_and_restore_gpregs*
13202;     return_and_restore_fpregs*
13203;     return_and_restore_fpregs_aix*
13204;
13205; The out-of-line save / restore functions expects one input argument.
13206; Since those are not standard call_insn's, we must avoid using
13207; MATCH_OPERAND for that argument. That way the register rename
13208; optimization will not try to rename this register.
13209; Each pattern is repeated for each possible register number used in
13210; various ABIs (r11, r1, and for some functions r12)
13211
13212(define_insn "*save_gpregs_<mode>_r11"
13213  [(match_parallel 0 "any_parallel_operand"
13214		   [(clobber (reg:P LR_REGNO))
13215		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13216                    (use (reg:P 11))
13217		    (set (match_operand:P 2 "memory_operand" "=m")
13218			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13219  ""
13220  "bl %1"
13221  [(set_attr "type" "branch")
13222   (set_attr "length" "4")])
13223
13224(define_insn "*save_gpregs_<mode>_r12"
13225  [(match_parallel 0 "any_parallel_operand"
13226		   [(clobber (reg:P LR_REGNO))
13227		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13228                    (use (reg:P 12))
13229		    (set (match_operand:P 2 "memory_operand" "=m")
13230			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13231  ""
13232  "bl %1"
13233  [(set_attr "type" "branch")
13234   (set_attr "length" "4")])
13235
13236(define_insn "*save_gpregs_<mode>_r1"
13237  [(match_parallel 0 "any_parallel_operand"
13238		   [(clobber (reg:P LR_REGNO))
13239		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13240                    (use (reg:P 1))
13241		    (set (match_operand:P 2 "memory_operand" "=m")
13242			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13243  ""
13244  "bl %1"
13245  [(set_attr "type" "branch")
13246   (set_attr "length" "4")])
13247
13248(define_insn "*save_fpregs_<mode>_r11"
13249  [(match_parallel 0 "any_parallel_operand"
13250		   [(clobber (reg:P LR_REGNO))
13251		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13252                    (use (reg:P 11))
13253		    (set (match_operand:DF 2 "memory_operand" "=m")
13254			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13255  ""
13256  "bl %1"
13257  [(set_attr "type" "branch")
13258   (set_attr "length" "4")])
13259
13260(define_insn "*save_fpregs_<mode>_r12"
13261  [(match_parallel 0 "any_parallel_operand"
13262		   [(clobber (reg:P LR_REGNO))
13263		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13264                    (use (reg:P 12))
13265		    (set (match_operand:DF 2 "memory_operand" "=m")
13266			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13267  ""
13268  "bl %1"
13269  [(set_attr "type" "branch")
13270   (set_attr "length" "4")])
13271
13272(define_insn "*save_fpregs_<mode>_r1"
13273  [(match_parallel 0 "any_parallel_operand"
13274		   [(clobber (reg:P LR_REGNO))
13275		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13276                    (use (reg:P 1))
13277		    (set (match_operand:DF 2 "memory_operand" "=m")
13278			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13279  ""
13280  "bl %1"
13281  [(set_attr "type" "branch")
13282   (set_attr "length" "4")])
13283
13284; This is to explain that changes to the stack pointer should
13285; not be moved over loads from or stores to stack memory.
13286(define_insn "stack_tie"
13287  [(match_parallel 0 "tie_operand"
13288		   [(set (mem:BLK (reg 1)) (const_int 0))])]
13289  ""
13290  ""
13291  [(set_attr "length" "0")])
13292
13293; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13294; stay behind all restores from the stack, it cannot be reordered to before
13295; one.  See PR77687.  This insn is an add or mr, and a stack_tie on the
13296; operands of that.
13297(define_insn "stack_restore_tie"
13298  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13299	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13300		 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13301   (set (mem:BLK (match_dup 0)) (const_int 0))
13302   (set (mem:BLK (match_dup 1)) (const_int 0))]
13303  "TARGET_32BIT"
13304  "@
13305   mr %0,%1
13306   add%I2 %0,%1,%2"
13307  [(set_attr "type" "*,add")])
13308
13309(define_expand "epilogue"
13310  [(use (const_int 0))]
13311  ""
13312{
13313  if (!TARGET_SCHED_PROLOG)
13314    emit_insn (gen_blockage ());
13315  rs6000_emit_epilogue (FALSE);
13316  DONE;
13317})
13318
13319; On some processors, doing the mtcrf one CC register at a time is
13320; faster (like on the 604e).  On others, doing them all at once is
13321; faster; for instance, on the 601 and 750.
13322
13323(define_expand "movsi_to_cr_one"
13324  [(set (match_operand:CC 0 "cc_reg_operand" "")
13325        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13326		    (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13327  ""
13328  "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13329
13330(define_insn "*movsi_to_cr"
13331  [(match_parallel 0 "mtcrf_operation"
13332		   [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13333			 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13334				     (match_operand 3 "immediate_operand" "n")]
13335				    UNSPEC_MOVESI_TO_CR))])]
13336 ""
13337 "*
13338{
13339  int mask = 0;
13340  int i;
13341  for (i = 0; i < XVECLEN (operands[0], 0); i++)
13342    mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13343  operands[4] = GEN_INT (mask);
13344  return \"mtcrf %4,%2\";
13345}"
13346  [(set_attr "type" "mtcr")])
13347
13348(define_insn "*mtcrfsi"
13349  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13350        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13351		    (match_operand 2 "immediate_operand" "n")]
13352		   UNSPEC_MOVESI_TO_CR))]
13353  "GET_CODE (operands[0]) == REG
13354   && CR_REGNO_P (REGNO (operands[0]))
13355   && GET_CODE (operands[2]) == CONST_INT
13356   && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13357  "mtcrf %R0,%1"
13358  [(set_attr "type" "mtcr")])
13359
13360; The load-multiple instructions have similar properties.
13361; Note that "load_multiple" is a name known to the machine-independent
13362; code that actually corresponds to the PowerPC load-string.
13363
13364(define_insn "*lmw"
13365  [(match_parallel 0 "lmw_operation"
13366		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13367       			 (match_operand:SI 2 "memory_operand" "m"))])]
13368  "TARGET_MULTIPLE"
13369  "lmw %1,%2"
13370  [(set_attr "type" "load")
13371   (set_attr "update" "yes")
13372   (set_attr "indexed" "yes")
13373   (set_attr "cell_micro" "always")])
13374
13375; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13376; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13377
13378; The following comment applies to:
13379;     save_gpregs_*
13380;     save_fpregs_*
13381;     restore_gpregs*
13382;     return_and_restore_gpregs*
13383;     return_and_restore_fpregs*
13384;     return_and_restore_fpregs_aix*
13385;
13386; The out-of-line save / restore functions expects one input argument.
13387; Since those are not standard call_insn's, we must avoid using
13388; MATCH_OPERAND for that argument. That way the register rename
13389; optimization will not try to rename this register.
13390; Each pattern is repeated for each possible register number used in
13391; various ABIs (r11, r1, and for some functions r12)
13392
13393(define_insn "*restore_gpregs_<mode>_r11"
13394 [(match_parallel 0 "any_parallel_operand"
13395		  [(clobber (reg:P LR_REGNO))
13396		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13397		   (use (reg:P 11))
13398		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13399			(match_operand:P 3 "memory_operand" "m"))])]
13400 ""
13401 "bl %1"
13402 [(set_attr "type" "branch")
13403  (set_attr "length" "4")])
13404
13405(define_insn "*restore_gpregs_<mode>_r12"
13406 [(match_parallel 0 "any_parallel_operand"
13407		  [(clobber (reg:P LR_REGNO))
13408		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13409		   (use (reg:P 12))
13410		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13411			(match_operand:P 3 "memory_operand" "m"))])]
13412 ""
13413 "bl %1"
13414 [(set_attr "type" "branch")
13415  (set_attr "length" "4")])
13416
13417(define_insn "*restore_gpregs_<mode>_r1"
13418 [(match_parallel 0 "any_parallel_operand"
13419		  [(clobber (reg:P LR_REGNO))
13420		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13421		   (use (reg:P 1))
13422		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13423			(match_operand:P 3 "memory_operand" "m"))])]
13424 ""
13425 "bl %1"
13426 [(set_attr "type" "branch")
13427  (set_attr "length" "4")])
13428
13429(define_insn "*return_and_restore_gpregs_<mode>_r11"
13430 [(match_parallel 0 "any_parallel_operand"
13431		  [(return)
13432		   (clobber (reg:P LR_REGNO))
13433		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13434		   (use (reg:P 11))
13435		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13436			(match_operand:P 3 "memory_operand" "m"))])]
13437 ""
13438 "b %1"
13439 [(set_attr "type" "branch")
13440  (set_attr "length" "4")])
13441
13442(define_insn "*return_and_restore_gpregs_<mode>_r12"
13443 [(match_parallel 0 "any_parallel_operand"
13444		  [(return)
13445		   (clobber (reg:P LR_REGNO))
13446		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13447		   (use (reg:P 12))
13448		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13449			(match_operand:P 3 "memory_operand" "m"))])]
13450 ""
13451 "b %1"
13452 [(set_attr "type" "branch")
13453  (set_attr "length" "4")])
13454
13455(define_insn "*return_and_restore_gpregs_<mode>_r1"
13456 [(match_parallel 0 "any_parallel_operand"
13457		  [(return)
13458		   (clobber (reg:P LR_REGNO))
13459		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13460		   (use (reg:P 1))
13461		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13462			(match_operand:P 3 "memory_operand" "m"))])]
13463 ""
13464 "b %1"
13465 [(set_attr "type" "branch")
13466  (set_attr "length" "4")])
13467
13468(define_insn "*return_and_restore_fpregs_<mode>_r11"
13469 [(match_parallel 0 "any_parallel_operand"
13470		  [(return)
13471		   (clobber (reg:P LR_REGNO))
13472		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13473		   (use (reg:P 11))
13474		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13475			(match_operand:DF 3 "memory_operand" "m"))])]
13476 ""
13477 "b %1"
13478 [(set_attr "type" "branch")
13479  (set_attr "length" "4")])
13480
13481(define_insn "*return_and_restore_fpregs_<mode>_r12"
13482 [(match_parallel 0 "any_parallel_operand"
13483		  [(return)
13484		   (clobber (reg:P LR_REGNO))
13485		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13486		   (use (reg:P 12))
13487		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13488			(match_operand:DF 3 "memory_operand" "m"))])]
13489 ""
13490 "b %1"
13491 [(set_attr "type" "branch")
13492  (set_attr "length" "4")])
13493
13494(define_insn "*return_and_restore_fpregs_<mode>_r1"
13495 [(match_parallel 0 "any_parallel_operand"
13496		  [(return)
13497		   (clobber (reg:P LR_REGNO))
13498		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13499		   (use (reg:P 1))
13500		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13501			(match_operand:DF 3 "memory_operand" "m"))])]
13502 ""
13503 "b %1"
13504 [(set_attr "type" "branch")
13505  (set_attr "length" "4")])
13506
13507(define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13508 [(match_parallel 0 "any_parallel_operand"
13509		  [(return)
13510		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13511		   (use (reg:P 11))
13512		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13513			(match_operand:DF 3 "memory_operand" "m"))])]
13514 ""
13515 "b %1"
13516 [(set_attr "type" "branch")
13517  (set_attr "length" "4")])
13518
13519(define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13520 [(match_parallel 0 "any_parallel_operand"
13521		  [(return)
13522		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13523		   (use (reg:P 1))
13524		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13525			(match_operand:DF 3 "memory_operand" "m"))])]
13526 ""
13527 "b %1"
13528 [(set_attr "type" "branch")
13529  (set_attr "length" "4")])
13530
13531; This is used in compiling the unwind routines.
13532(define_expand "eh_return"
13533  [(use (match_operand 0 "general_operand" ""))]
13534  ""
13535  "
13536{
13537  if (TARGET_32BIT)
13538    emit_insn (gen_eh_set_lr_si (operands[0]));
13539  else
13540    emit_insn (gen_eh_set_lr_di (operands[0]));
13541  DONE;
13542}")
13543
13544; We can't expand this before we know where the link register is stored.
13545(define_insn "eh_set_lr_<mode>"
13546  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13547  		    UNSPECV_EH_RR)
13548   (clobber (match_scratch:P 1 "=&b"))]
13549  ""
13550  "#")
13551
13552(define_split
13553  [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13554   (clobber (match_scratch 1 ""))]
13555  "reload_completed"
13556  [(const_int 0)]
13557  "
13558{
13559  rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13560  DONE;
13561}")
13562
13563(define_insn "prefetch"
13564  [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13565	     (match_operand:SI 1 "const_int_operand" "n")
13566	     (match_operand:SI 2 "const_int_operand" "n"))]
13567  ""
13568  "*
13569{
13570  if (GET_CODE (operands[0]) == REG)
13571    return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13572  return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13573}"
13574  [(set_attr "type" "load")])
13575
13576;; Handle -fsplit-stack.
13577
13578(define_expand "split_stack_prologue"
13579  [(const_int 0)]
13580  ""
13581{
13582  rs6000_expand_split_stack_prologue ();
13583  DONE;
13584})
13585
13586(define_expand "load_split_stack_limit"
13587  [(set (match_operand 0)
13588	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13589  ""
13590{
13591  emit_insn (gen_rtx_SET (operands[0],
13592			  gen_rtx_UNSPEC (Pmode,
13593					  gen_rtvec (1, const0_rtx),
13594					  UNSPEC_STACK_CHECK)));
13595  DONE;
13596})
13597
13598(define_insn "load_split_stack_limit_di"
13599  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13600	(unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13601  "TARGET_64BIT"
13602  "ld %0,-0x7040(13)"
13603  [(set_attr "type" "load")
13604   (set_attr "update" "no")
13605   (set_attr "indexed" "no")])
13606
13607(define_insn "load_split_stack_limit_si"
13608  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13609	(unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13610  "!TARGET_64BIT"
13611  "lwz %0,-0x7020(2)"
13612  [(set_attr "type" "load")
13613   (set_attr "update" "no")
13614   (set_attr "indexed" "no")])
13615
13616;; A return instruction which the middle-end doesn't see.
13617;; Use r0 to stop regrename twiddling with lr restore insns emitted
13618;; after the call to __morestack.
13619(define_insn "split_stack_return"
13620  [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13621  ""
13622  "blr"
13623  [(set_attr "type" "jmpreg")])
13624
13625;; If there are operand 0 bytes available on the stack, jump to
13626;; operand 1.
13627(define_expand "split_stack_space_check"
13628  [(set (match_dup 2)
13629	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13630   (set (match_dup 3)
13631	(minus (reg STACK_POINTER_REGNUM)
13632	       (match_operand 0)))
13633   (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13634   (set (pc) (if_then_else
13635	      (geu (match_dup 4) (const_int 0))
13636	      (label_ref (match_operand 1))
13637	      (pc)))]
13638  ""
13639{
13640  rs6000_split_stack_space_check (operands[0], operands[1]);
13641  DONE;
13642})
13643
13644(define_insn "bpermd_<mode>"
13645  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13646	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13647		   (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13648  "TARGET_POPCNTD"
13649  "bpermd %0,%1,%2"
13650  [(set_attr "type" "popcnt")])
13651
13652
13653;; Builtin fma support.  Handle
13654;; Note that the conditions for expansion are in the FMA_F iterator.
13655
13656(define_expand "fma<mode>4"
13657  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13658	(fma:FMA_F
13659	  (match_operand:FMA_F 1 "gpc_reg_operand" "")
13660	  (match_operand:FMA_F 2 "gpc_reg_operand" "")
13661	  (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13662  ""
13663  "")
13664
13665(define_insn "*fma<mode>4_fpr"
13666  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13667	(fma:SFDF
13668	  (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13669	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13670	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13671  "TARGET_<MODE>_FPR"
13672  "@
13673   fmadd<Ftrad> %0,%1,%2,%3
13674   xsmadda<Fvsx> %x0,%x1,%x2
13675   xsmaddm<Fvsx> %x0,%x1,%x3"
13676  [(set_attr "type" "fp")
13677   (set_attr "fp_type" "fp_maddsub_<Fs>")])
13678
13679; Altivec only has fma and nfms.
13680(define_expand "fms<mode>4"
13681  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13682	(fma:FMA_F
13683	  (match_operand:FMA_F 1 "gpc_reg_operand" "")
13684	  (match_operand:FMA_F 2 "gpc_reg_operand" "")
13685	  (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13686  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13687  "")
13688
13689(define_insn "*fms<mode>4_fpr"
13690  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13691	(fma:SFDF
13692	 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13693	 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13694	 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13695  "TARGET_<MODE>_FPR"
13696  "@
13697   fmsub<Ftrad> %0,%1,%2,%3
13698   xsmsuba<Fvsx> %x0,%x1,%x2
13699   xsmsubm<Fvsx> %x0,%x1,%x3"
13700  [(set_attr "type" "fp")
13701   (set_attr "fp_type" "fp_maddsub_<Fs>")])
13702
13703;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13704(define_expand "fnma<mode>4"
13705  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13706	(neg:FMA_F
13707	  (fma:FMA_F
13708	    (match_operand:FMA_F 1 "gpc_reg_operand" "")
13709	    (match_operand:FMA_F 2 "gpc_reg_operand" "")
13710	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13711  "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13712  "")
13713
13714;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13715(define_expand "fnms<mode>4"
13716  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13717	(neg:FMA_F
13718	  (fma:FMA_F
13719	    (match_operand:FMA_F 1 "gpc_reg_operand" "")
13720	    (match_operand:FMA_F 2 "gpc_reg_operand" "")
13721	    (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13722  "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13723  "")
13724
13725; Not an official optab name, but used from builtins.
13726(define_expand "nfma<mode>4"
13727  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13728	(neg:FMA_F
13729	  (fma:FMA_F
13730	    (match_operand:FMA_F 1 "gpc_reg_operand" "")
13731	    (match_operand:FMA_F 2 "gpc_reg_operand" "")
13732	    (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13733  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13734  "")
13735
13736(define_insn "*nfma<mode>4_fpr"
13737  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13738	(neg:SFDF
13739	 (fma:SFDF
13740	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13741	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13742	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13743  "TARGET_<MODE>_FPR"
13744  "@
13745   fnmadd<Ftrad> %0,%1,%2,%3
13746   xsnmadda<Fvsx> %x0,%x1,%x2
13747   xsnmaddm<Fvsx> %x0,%x1,%x3"
13748  [(set_attr "type" "fp")
13749   (set_attr "fp_type" "fp_maddsub_<Fs>")])
13750
13751; Not an official optab name, but used from builtins.
13752(define_expand "nfms<mode>4"
13753  [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13754	(neg:FMA_F
13755	  (fma:FMA_F
13756	    (match_operand:FMA_F 1 "gpc_reg_operand" "")
13757	    (match_operand:FMA_F 2 "gpc_reg_operand" "")
13758	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13759  ""
13760  "")
13761
13762(define_insn "*nfmssf4_fpr"
13763  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13764	(neg:SFDF
13765	 (fma:SFDF
13766	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13767	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13768	  (neg:SFDF
13769	   (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13770  "TARGET_<MODE>_FPR"
13771  "@
13772   fnmsub<Ftrad> %0,%1,%2,%3
13773   xsnmsuba<Fvsx> %x0,%x1,%x2
13774   xsnmsubm<Fvsx> %x0,%x1,%x3"
13775  [(set_attr "type" "fp")
13776   (set_attr "fp_type" "fp_maddsub_<Fs>")])
13777
13778
13779(define_expand "rs6000_get_timebase"
13780  [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13781  ""
13782{
13783  if (TARGET_POWERPC64)
13784    emit_insn (gen_rs6000_mftb_di (operands[0]));
13785  else
13786    emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13787  DONE;
13788})
13789
13790(define_insn "rs6000_get_timebase_ppc32"
13791  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13792        (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13793   (clobber (match_scratch:SI 1 "=r"))
13794   (clobber (match_scratch:CC 2 "=y"))]
13795  "!TARGET_POWERPC64"
13796{
13797  if (WORDS_BIG_ENDIAN)
13798    if (TARGET_MFCRF)
13799      {
13800        return "mfspr %0,269\;"
13801	       "mfspr %L0,268\;"
13802	       "mfspr %1,269\;"
13803	       "cmpw %2,%0,%1\;"
13804	       "bne- %2,$-16";
13805      }
13806    else
13807      {
13808        return "mftbu %0\;"
13809	       "mftb %L0\;"
13810	       "mftbu %1\;"
13811	       "cmpw %2,%0,%1\;"
13812	       "bne- %2,$-16";
13813      }
13814  else
13815    if (TARGET_MFCRF)
13816      {
13817        return "mfspr %L0,269\;"
13818	       "mfspr %0,268\;"
13819	       "mfspr %1,269\;"
13820	       "cmpw %2,%L0,%1\;"
13821	       "bne- %2,$-16";
13822      }
13823    else
13824      {
13825        return "mftbu %L0\;"
13826	       "mftb %0\;"
13827	       "mftbu %1\;"
13828	       "cmpw %2,%L0,%1\;"
13829	       "bne- %2,$-16";
13830      }
13831}
13832  [(set_attr "length" "20")])
13833
13834(define_insn "rs6000_mftb_<mode>"
13835  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13836        (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13837  ""
13838{
13839  if (TARGET_MFCRF)
13840    return "mfspr %0,268";
13841  else
13842    return "mftb %0";
13843})
13844
13845
13846(define_insn "rs6000_mffs"
13847  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13848	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13849  "TARGET_HARD_FLOAT && TARGET_FPRS"
13850  "mffs %0")
13851
13852(define_insn "rs6000_mtfsf"
13853  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13854		     (match_operand:DF 1 "gpc_reg_operand" "d")]
13855		    UNSPECV_MTFSF)]
13856  "TARGET_HARD_FLOAT && TARGET_FPRS"
13857  "mtfsf %0,%1")
13858
13859
13860;; Power8 fusion support for fusing an addis instruction with a D-form load of
13861;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13862;; register that is being loaded.  The fused ops must be physically adjacent.
13863
13864;; There are two parts to addis fusion.  The support for fused TOCs occur
13865;; before register allocation, and is meant to reduce the lifetime for the
13866;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13867;; to use the register that is being load.  The peephole2 then gathers any
13868;; other fused possibilities that it can find after register allocation.  If
13869;; power9 fusion is selected, we also fuse floating point loads/stores.
13870
13871;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13872;; before register allocation, so that we can avoid allocating a temporary base
13873;; register that won't be used, and that we try to load into base registers,
13874;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13875;; (addis followed by load) even on power8.
13876
13877(define_split
13878  [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13879	(match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13880  "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13881  [(parallel [(set (match_dup 0) (match_dup 2))
13882	      (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13883	      (use (match_dup 3))
13884	      (clobber (scratch:DI))])]
13885{
13886  operands[2] = fusion_wrap_memory_address (operands[1]);
13887  operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13888})
13889
13890(define_insn "*toc_fusionload_<mode>"
13891  [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13892	(match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13893   (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13894   (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13895   (clobber (match_scratch:DI 3 "=X,&b"))]
13896  "TARGET_TOC_FUSION_INT"
13897{
13898  if (base_reg_operand (operands[0], <MODE>mode))
13899    return emit_fusion_gpr_load (operands[0], operands[1]);
13900
13901  return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13902}
13903  [(set_attr "type" "load")
13904   (set_attr "length" "8")])
13905
13906(define_insn "*toc_fusionload_di"
13907  [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13908	(match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13909   (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13910   (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13911   (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13912  "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13913   && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13914{
13915  if (base_reg_operand (operands[0], DImode))
13916    return emit_fusion_gpr_load (operands[0], operands[1]);
13917
13918  return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13919}
13920  [(set_attr "type" "load")
13921   (set_attr "length" "8")])
13922
13923
13924;; Find cases where the addis that feeds into a load instruction is either used
13925;; once or is the same as the target register, and replace it with the fusion
13926;; insn
13927
13928(define_peephole2
13929  [(set (match_operand:P 0 "base_reg_operand" "")
13930	(match_operand:P 1 "fusion_gpr_addis" ""))
13931   (set (match_operand:INT1 2 "base_reg_operand" "")
13932	(match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13933  "TARGET_P8_FUSION
13934   && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13935			 operands[3])"
13936  [(const_int 0)]
13937{
13938  expand_fusion_gpr_load (operands);
13939  DONE;
13940})
13941
13942;; Fusion insn, created by the define_peephole2 above (and eventually by
13943;; reload)
13944
13945(define_insn "fusion_gpr_load_<mode>"
13946  [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13947	(unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13948		     UNSPEC_FUSION_GPR))]
13949  "TARGET_P8_FUSION"
13950{
13951  return emit_fusion_gpr_load (operands[0], operands[1]);
13952}
13953  [(set_attr "type" "load")
13954   (set_attr "length" "8")])
13955
13956
13957;; ISA 3.0 (power9) fusion support
13958;; Merge addis with floating load/store to FPRs (or GPRs).
13959(define_peephole2
13960  [(set (match_operand:P 0 "base_reg_operand" "")
13961	(match_operand:P 1 "fusion_gpr_addis" ""))
13962   (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13963	(match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13964  "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13965   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13966  [(const_int 0)]
13967{
13968  expand_fusion_p9_load (operands);
13969  DONE;
13970})
13971
13972(define_peephole2
13973  [(set (match_operand:P 0 "base_reg_operand" "")
13974	(match_operand:P 1 "fusion_gpr_addis" ""))
13975   (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13976	(match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13977  "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13978   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13979   && !rtx_equal_p (operands[0], operands[3])"
13980  [(const_int 0)]
13981{
13982  expand_fusion_p9_store (operands);
13983  DONE;
13984})
13985
13986(define_peephole2
13987  [(set (match_operand:SDI 0 "int_reg_operand" "")
13988	(match_operand:SDI 1 "upper16_cint_operand" ""))
13989   (set (match_dup 0)
13990	(ior:SDI (match_dup 0)
13991		 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13992  "TARGET_P9_FUSION"
13993  [(set (match_dup 0)
13994	(unspec:SDI [(match_dup 1)
13995		     (match_dup 2)] UNSPEC_FUSION_P9))])
13996
13997(define_peephole2
13998  [(set (match_operand:SDI 0 "int_reg_operand" "")
13999	(match_operand:SDI 1 "upper16_cint_operand" ""))
14000   (set (match_operand:SDI 2 "int_reg_operand" "")
14001	(ior:SDI (match_dup 0)
14002		 (match_operand:SDI 3 "u_short_cint_operand" "")))]
14003  "TARGET_P9_FUSION
14004   && !rtx_equal_p (operands[0], operands[2])
14005   && peep2_reg_dead_p (2, operands[0])"
14006  [(set (match_dup 2)
14007	(unspec:SDI [(match_dup 1)
14008		     (match_dup 3)] UNSPEC_FUSION_P9))])
14009
14010;; Fusion insns, created by the define_peephole2 above (and eventually by
14011;; reload).  Because we want to eventually have secondary_reload generate
14012;; these, they have to have a single alternative that gives the register
14013;; classes.  This means we need to have separate gpr/fpr/altivec versions.
14014(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
14015  [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
14016	(unspec:GPR_FUSION
14017	 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14018	 UNSPEC_FUSION_P9))
14019   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14020  "TARGET_P9_FUSION"
14021{
14022  /* This insn is a secondary reload insn, which cannot have alternatives.
14023     If we are not loading up register 0, use the power8 fusion instead.  */
14024  if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
14025    return emit_fusion_gpr_load (operands[0], operands[1]);
14026
14027  return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14028}
14029  [(set_attr "type" "load")
14030   (set_attr "length" "8")])
14031
14032(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
14033  [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14034	(unspec:GPR_FUSION
14035	 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
14036	 UNSPEC_FUSION_P9))
14037   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14038  "TARGET_P9_FUSION"
14039{
14040  return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14041}
14042  [(set_attr "type" "store")
14043   (set_attr "length" "8")])
14044
14045(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
14046  [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
14047	(unspec:FPR_FUSION
14048	 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14049	 UNSPEC_FUSION_P9))
14050   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14051  "TARGET_P9_FUSION"
14052{
14053  return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14054}
14055  [(set_attr "type" "fpload")
14056   (set_attr "length" "8")])
14057
14058(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14059  [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14060	(unspec:FPR_FUSION
14061	 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14062	 UNSPEC_FUSION_P9))
14063   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14064  "TARGET_P9_FUSION"
14065{
14066  return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14067}
14068  [(set_attr "type" "fpstore")
14069   (set_attr "length" "8")])
14070
14071(define_insn "*fusion_p9_<mode>_constant"
14072  [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14073	(unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14074		     (match_operand:SDI 2 "u_short_cint_operand" "K")]
14075		    UNSPEC_FUSION_P9))]
14076  "TARGET_P9_FUSION"
14077{
14078  emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
14079  return "ori %0,%0,%2";
14080}
14081  [(set_attr "type" "two")
14082   (set_attr "length" "8")])
14083
14084
14085;; Optimize cases where we want to do a D-form load (register+offset) on
14086;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14087;; has generated:
14088;;	LFD 0,32(3)
14089;;	XXLOR 32,0,0
14090;;
14091;; and we change this to:
14092;;	LI 0,32
14093;;	LXSDX 32,3,9
14094
14095(define_peephole2
14096  [(match_scratch:DI 0 "b")
14097   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14098	(match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14099   (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14100	(match_dup 1))]
14101  "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE>
14102   && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])"
14103  [(set (match_dup 0)
14104	(match_dup 4))
14105   (set (match_dup 3)
14106	(match_dup 5))]
14107{
14108  rtx tmp_reg = operands[0];
14109  rtx mem = operands[2];
14110  rtx addr = XEXP (mem, 0);
14111  rtx add_op0, add_op1, new_addr;
14112
14113  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14114  add_op0 = XEXP (addr, 0);
14115  add_op1 = XEXP (addr, 1);
14116  gcc_assert (REG_P (add_op0));
14117  new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg);
14118
14119  operands[4] = add_op1;
14120  operands[5] = change_address (mem, <MODE>mode, new_addr);
14121})
14122
14123;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14124;; Altivec register, and the register allocator has generated:
14125;;	XXLOR 0,32,32
14126;;	STFD 0,32(3)
14127;;
14128;; and we change this to:
14129;;	LI 0,32
14130;;	STXSDX 32,3,9
14131
14132(define_peephole2
14133  [(match_scratch:DI 0 "b")
14134   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14135	(match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14136   (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14137	(match_dup 1))]
14138  "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE>
14139   && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])"
14140  [(set (match_dup 0)
14141	(match_dup 4))
14142   (set (match_dup 5)
14143	(match_dup 2))]
14144{
14145  rtx tmp_reg = operands[0];
14146  rtx mem = operands[3];
14147  rtx addr = XEXP (mem, 0);
14148  rtx add_op0, add_op1, new_addr;
14149
14150  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14151  add_op0 = XEXP (addr, 0);
14152  add_op1 = XEXP (addr, 1);
14153  gcc_assert (REG_P (add_op0));
14154  new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg);
14155
14156  operands[4] = add_op1;
14157  operands[5] = change_address (mem, <MODE>mode, new_addr);
14158})
14159
14160
14161;; Miscellaneous ISA 2.06 (power7) instructions
14162(define_insn "addg6s"
14163  [(set (match_operand:SI 0 "register_operand" "=r")
14164	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
14165		    (match_operand:SI 2 "register_operand" "r")]
14166		   UNSPEC_ADDG6S))]
14167  "TARGET_POPCNTD"
14168  "addg6s %0,%1,%2"
14169  [(set_attr "type" "integer")
14170   (set_attr "length" "4")])
14171
14172(define_insn "cdtbcd"
14173  [(set (match_operand:SI 0 "register_operand" "=r")
14174	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14175		   UNSPEC_CDTBCD))]
14176  "TARGET_POPCNTD"
14177  "cdtbcd %0,%1"
14178  [(set_attr "type" "integer")
14179   (set_attr "length" "4")])
14180
14181(define_insn "cbcdtd"
14182  [(set (match_operand:SI 0 "register_operand" "=r")
14183	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14184		   UNSPEC_CBCDTD))]
14185  "TARGET_POPCNTD"
14186  "cbcdtd %0,%1"
14187  [(set_attr "type" "integer")
14188   (set_attr "length" "4")])
14189
14190(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14191					UNSPEC_DIVEO
14192					UNSPEC_DIVEU
14193					UNSPEC_DIVEUO])
14194
14195(define_int_attr div_extend [(UNSPEC_DIVE	"e")
14196			     (UNSPEC_DIVEO	"eo")
14197			     (UNSPEC_DIVEU	"eu")
14198			     (UNSPEC_DIVEUO	"euo")])
14199
14200(define_insn "div<div_extend>_<mode>"
14201  [(set (match_operand:GPR 0 "register_operand" "=r")
14202	(unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14203		     (match_operand:GPR 2 "register_operand" "r")]
14204		    UNSPEC_DIV_EXTEND))]
14205  "TARGET_POPCNTD"
14206  "div<wd><div_extend> %0,%1,%2"
14207  [(set_attr "type" "div")
14208   (set_attr "size" "<bits>")])
14209
14210
14211;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14212
14213; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14214(define_mode_attr FP128_64 [(TF "DF")
14215			    (IF "DF")
14216			    (TD "DI")
14217			    (KF "DI")])
14218
14219(define_expand "unpack<mode>"
14220  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14221	(unspec:<FP128_64>
14222	 [(match_operand:FMOVE128 1 "register_operand" "")
14223	  (match_operand:QI 2 "const_0_to_1_operand" "")]
14224	 UNSPEC_UNPACK_128BIT))]
14225  "FLOAT128_2REG_P (<MODE>mode)"
14226  "")
14227
14228(define_insn_and_split "unpack<mode>_dm"
14229  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14230	(unspec:<FP128_64>
14231	 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14232	  (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14233	 UNSPEC_UNPACK_128BIT))]
14234  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14235  "#"
14236  "&& reload_completed"
14237  [(set (match_dup 0) (match_dup 3))]
14238{
14239  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14240
14241  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14242    {
14243      emit_note (NOTE_INSN_DELETED);
14244      DONE;
14245    }
14246
14247  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14248}
14249  [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14250   (set_attr "length" "4")])
14251
14252(define_insn_and_split "unpack<mode>_nodm"
14253  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14254	(unspec:<FP128_64>
14255	 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14256	  (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14257	 UNSPEC_UNPACK_128BIT))]
14258  "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14259  "#"
14260  "&& reload_completed"
14261  [(set (match_dup 0) (match_dup 3))]
14262{
14263  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14264
14265  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14266    {
14267      emit_note (NOTE_INSN_DELETED);
14268      DONE;
14269    }
14270
14271  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14272}
14273  [(set_attr "type" "fp,fpstore")
14274   (set_attr "length" "4")])
14275
14276(define_insn_and_split "pack<mode>"
14277  [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14278	(unspec:FMOVE128
14279	 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14280	  (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14281	 UNSPEC_PACK_128BIT))]
14282  "FLOAT128_2REG_P (<MODE>mode)"
14283  "@
14284   fmr %L0,%2
14285   #"
14286  "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14287  [(set (match_dup 3) (match_dup 1))
14288   (set (match_dup 4) (match_dup 2))]
14289{
14290  unsigned dest_hi = REGNO (operands[0]);
14291  unsigned dest_lo = dest_hi + 1;
14292
14293  gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14294  gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14295
14296  operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14297  operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14298}
14299  [(set_attr "type" "fpsimple,fp")
14300   (set_attr "length" "4,8")])
14301
14302(define_insn "unpack<mode>"
14303  [(set (match_operand:DI 0 "register_operand" "=d,d")
14304	(unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14305		    (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14306	 UNSPEC_UNPACK_128BIT))]
14307  "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14308{
14309  if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14310    return ASM_COMMENT_START " xxpermdi to same register";
14311
14312  operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14313  return "xxpermdi %x0,%x1,%x1,%3";
14314}
14315  [(set_attr "type" "vecperm")])
14316
14317(define_insn "pack<mode>"
14318  [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14319	(unspec:FMOVE128_VSX
14320	 [(match_operand:DI 1 "register_operand" "d")
14321	  (match_operand:DI 2 "register_operand" "d")]
14322	 UNSPEC_PACK_128BIT))]
14323  "TARGET_VSX"
14324  "xxpermdi %x0,%x1,%x2,0"
14325  [(set_attr "type" "vecperm")])
14326
14327
14328
14329;; ISA 2.08 IEEE 128-bit floating point support.
14330
14331(define_insn "add<mode>3"
14332  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14333	(plus:IEEE128
14334	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14335	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14336  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14337  "xsaddqp %0,%1,%2"
14338  [(set_attr "type" "vecfloat")
14339   (set_attr "size" "128")])
14340
14341(define_insn "sub<mode>3"
14342  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14343	(minus:IEEE128
14344	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14345	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14346  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14347  "xssubqp %0,%1,%2"
14348  [(set_attr "type" "vecfloat")
14349   (set_attr "size" "128")])
14350
14351(define_insn "mul<mode>3"
14352  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14353	(mult:IEEE128
14354	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14355	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14356  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14357  "xsmulqp %0,%1,%2"
14358  [(set_attr "type" "vecfloat")
14359   (set_attr "size" "128")])
14360
14361(define_insn "div<mode>3"
14362  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14363	(div:IEEE128
14364	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14365	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14366  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14367  "xsdivqp %0,%1,%2"
14368  [(set_attr "type" "vecdiv")
14369   (set_attr "size" "128")])
14370
14371(define_insn "sqrt<mode>2"
14372  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14373	(sqrt:IEEE128
14374	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14375  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14376   "xssqrtqp %0,%1"
14377  [(set_attr "type" "vecdiv")
14378   (set_attr "size" "128")])
14379
14380(define_expand "copysign<mode>3"
14381  [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14382   (use (match_operand:IEEE128 1 "altivec_register_operand"))
14383   (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14384  "FLOAT128_IEEE_P (<MODE>mode)"
14385{
14386  if (TARGET_FLOAT128_HW)
14387    emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14388					 operands[2]));
14389  else
14390    {
14391      rtx tmp = gen_reg_rtx (<MODE>mode);
14392      emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14393					   operands[2], tmp));
14394    }
14395  DONE;
14396})
14397
14398(define_insn "copysign<mode>3_hard"
14399  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14400	(unspec:IEEE128
14401	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14402	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14403	 UNSPEC_COPYSIGN))]
14404  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14405   "xscpsgnqp %0,%2,%1"
14406  [(set_attr "type" "vecmove")
14407   (set_attr "size" "128")])
14408
14409(define_insn "copysign<mode>3_soft"
14410  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14411	(unspec:IEEE128
14412	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14413	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14414	  (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14415	 UNSPEC_COPYSIGN))]
14416  "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14417   "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14418  [(set_attr "type" "veccomplex")
14419   (set_attr "length" "8")])
14420
14421(define_insn "neg<mode>2_hw"
14422  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14423	(neg:IEEE128
14424	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14425  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14426  "xsnegqp %0,%1"
14427  [(set_attr "type" "vecmove")
14428   (set_attr "size" "128")])
14429
14430
14431(define_insn "abs<mode>2_hw"
14432  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14433	(abs:IEEE128
14434	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14435  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14436  "xsabsqp %0,%1"
14437  [(set_attr "type" "vecmove")
14438   (set_attr "size" "128")])
14439
14440
14441(define_insn "*nabs<mode>2_hw"
14442  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14443	(neg:IEEE128
14444	 (abs:IEEE128
14445	  (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14446  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14447  "xsnabsqp %0,%1"
14448  [(set_attr "type" "vecmove")
14449   (set_attr "size" "128")])
14450
14451;; Initially don't worry about doing fusion
14452(define_insn "*fma<mode>4_hw"
14453  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14454	(fma:IEEE128
14455	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14456	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14457	 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14458  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14459  "xsmaddqp %0,%1,%2"
14460  [(set_attr "type" "vecfloat")
14461   (set_attr "size" "128")])
14462
14463(define_insn "*fms<mode>4_hw"
14464  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14465	(fma:IEEE128
14466	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14467	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14468	 (neg:IEEE128
14469	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14470  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14471  "xsmsubqp %0,%1,%2"
14472  [(set_attr "type" "vecfloat")
14473   (set_attr "size" "128")])
14474
14475(define_insn "*nfma<mode>4_hw"
14476  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14477	(neg:IEEE128
14478	 (fma:IEEE128
14479	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14480	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14481	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14482  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14483  "xsnmaddqp %0,%1,%2"
14484  [(set_attr "type" "vecfloat")
14485   (set_attr "size" "128")])
14486
14487(define_insn "*nfms<mode>4_hw"
14488  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14489	(neg:IEEE128
14490	 (fma:IEEE128
14491	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14492	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14493	  (neg:IEEE128
14494	   (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14495  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14496  "xsnmsubqp %0,%1,%2"
14497  [(set_attr "type" "vecfloat")
14498   (set_attr "size" "128")])
14499
14500(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14501  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14502	(float_extend:IEEE128
14503	 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14504  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14505  "xscvdpqp %0,%1"
14506  [(set_attr "type" "vecfloat")
14507   (set_attr "size" "128")])
14508
14509;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14510;; point is a simple copy.
14511(define_insn_and_split "extendkftf2"
14512  [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14513	(float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14514  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14515  "@
14516   #
14517   xxlor %x0,%x1,%x1"
14518  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14519  [(const_int 0)]
14520{
14521  emit_note (NOTE_INSN_DELETED);
14522  DONE;
14523}
14524  [(set_attr "type" "*,veclogical")
14525   (set_attr "length" "0,4")])
14526
14527(define_insn_and_split "trunctfkf2"
14528  [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14529	(float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14530  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14531  "@
14532   #
14533   xxlor %x0,%x1,%x1"
14534  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14535  [(const_int 0)]
14536{
14537  emit_note (NOTE_INSN_DELETED);
14538  DONE;
14539}
14540  [(set_attr "type" "*,veclogical")
14541   (set_attr "length" "0,4")])
14542
14543(define_insn "trunc<mode>df2_hw"
14544  [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14545	(float_truncate:DF
14546	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14547  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14548  "xscvqpdp %0,%1"
14549  [(set_attr "type" "vecfloat")
14550   (set_attr "size" "128")])
14551
14552;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14553;; the KFmode -> DFmode conversion using round to odd rather than the normal
14554;; conversion
14555(define_insn_and_split "trunc<mode>sf2_hw"
14556  [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14557	(float_truncate:SF
14558	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14559   (clobber (match_scratch:DF 2 "=v"))]
14560  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14561  "#"
14562  "&& 1"
14563  [(set (match_dup 2)
14564	(unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14565   (set (match_dup 0)
14566	(float_truncate:SF (match_dup 2)))]
14567{
14568  if (GET_CODE (operands[2]) == SCRATCH)
14569    operands[2] = gen_reg_rtx (DFmode);
14570}
14571  [(set_attr "type" "vecfloat")
14572   (set_attr "length" "8")])
14573
14574;; Conversion between IEEE 128-bit and integer types
14575(define_insn "fix_<mode>di2_hw"
14576  [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14577	(fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14578  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14579  "xscvqpsdz %0,%1"
14580  [(set_attr "type" "vecfloat")
14581   (set_attr "size" "128")])
14582
14583(define_insn "fixuns_<mode>di2_hw"
14584  [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14585	(unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14586  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14587  "xscvqpudz %0,%1"
14588  [(set_attr "type" "vecfloat")
14589   (set_attr "size" "128")])
14590
14591(define_insn "fix_<mode>si2_hw"
14592  [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14593	(fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14594  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14595  "xscvqpswz %0,%1"
14596  [(set_attr "type" "vecfloat")
14597   (set_attr "size" "128")])
14598
14599(define_insn "fixuns_<mode>si2_hw"
14600  [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14601	(unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14602  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14603  "xscvqpuwz %0,%1"
14604  [(set_attr "type" "vecfloat")
14605   (set_attr "size" "128")])
14606
14607;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14608;; floating point value to 32-bit integer to GPR in order to save it.
14609(define_insn_and_split "*fix<uns>_<mode>_mem"
14610  [(set (match_operand:SI 0 "memory_operand" "=Z")
14611	(any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14612   (clobber (match_scratch:SI 2 "=v"))]
14613  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14614  "#"
14615  "&& reload_completed"
14616  [(set (match_dup 2)
14617	(any_fix:SI (match_dup 1)))
14618   (set (match_dup 0)
14619	(match_dup 2))])
14620
14621(define_insn "float_<mode>di2_hw"
14622  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14623	(float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14624  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14625  "xscvsdqp %0,%1"
14626  [(set_attr "type" "vecfloat")
14627   (set_attr "size" "128")])
14628
14629(define_insn_and_split "float_<mode>si2_hw"
14630  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14631	(float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14632   (clobber (match_scratch:DI 2 "=v"))]
14633  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14634  "#"
14635  "&& 1"
14636  [(set (match_dup 2)
14637	(sign_extend:DI (match_dup 1)))
14638   (set (match_dup 0)
14639	(float:IEEE128 (match_dup 2)))]
14640{
14641  if (GET_CODE (operands[2]) == SCRATCH)
14642    operands[2] = gen_reg_rtx (DImode);
14643})
14644
14645(define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14646  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14647	(float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14648   (clobber (match_scratch:DI 2 "=X,r,X"))]
14649  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14650  "#"
14651  "&& reload_completed"
14652  [(const_int 0)]
14653{
14654  rtx dest = operands[0];
14655  rtx src = operands[1];
14656  rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14657
14658  if (altivec_register_operand (src, <QHI:MODE>mode))
14659    emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14660  else if (int_reg_operand (src, <QHI:MODE>mode))
14661    {
14662      rtx ext_di = operands[2];
14663      emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14664      emit_move_insn (dest_di, ext_di);
14665    }
14666  else if (MEM_P (src))
14667    {
14668      rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14669      emit_move_insn (dest_qhi, src);
14670      emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14671    }
14672  else
14673    gcc_unreachable ();
14674
14675  emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14676  DONE;
14677}
14678  [(set_attr "length" "8,12,12")
14679   (set_attr "type" "vecfloat")
14680   (set_attr "size" "128")])
14681
14682(define_insn "floatuns_<mode>di2_hw"
14683  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14684	(unsigned_float:IEEE128
14685	 (match_operand:DI 1 "altivec_register_operand" "v")))]
14686  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14687  "xscvudqp %0,%1"
14688  [(set_attr "type" "vecfloat")
14689   (set_attr "size" "128")])
14690
14691(define_insn_and_split "floatuns_<mode>si2_hw"
14692  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14693	(unsigned_float:IEEE128
14694	 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14695   (clobber (match_scratch:DI 2 "=v"))]
14696  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14697  "#"
14698  "&& 1"
14699  [(set (match_dup 2)
14700	(zero_extend:DI (match_dup 1)))
14701   (set (match_dup 0)
14702	(float:IEEE128 (match_dup 2)))]
14703{
14704  if (GET_CODE (operands[2]) == SCRATCH)
14705    operands[2] = gen_reg_rtx (DImode);
14706})
14707
14708(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14709  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14710	(unsigned_float:IEEE128
14711	 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14712   (clobber (match_scratch:DI 2 "=X,r,X"))]
14713  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14714  "#"
14715  "&& reload_completed"
14716  [(const_int 0)]
14717{
14718  rtx dest = operands[0];
14719  rtx src = operands[1];
14720  rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14721
14722  if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14723    emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14724  else if (int_reg_operand (src, <QHI:MODE>mode))
14725    {
14726      rtx ext_di = operands[2];
14727      emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14728      emit_move_insn (dest_di, ext_di);
14729    }
14730  else
14731    gcc_unreachable ();
14732
14733  emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14734  DONE;
14735}
14736  [(set_attr "length" "8,12,8")
14737   (set_attr "type" "vecfloat")
14738   (set_attr "size" "128")])
14739
14740;; IEEE 128-bit instructions with round to odd semantics
14741(define_insn "*trunc<mode>df2_odd"
14742  [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14743	(unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14744		   UNSPEC_ROUND_TO_ODD))]
14745  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14746  "xscvqpdpo %0,%1"
14747  [(set_attr "type" "vecfloat")
14748   (set_attr "size" "128")])
14749
14750;; IEEE 128-bit comparisons
14751(define_insn "*cmp<mode>_hw"
14752  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14753	(compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14754		      (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14755  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14756   "xscmpuqp %0,%1,%2"
14757  [(set_attr "type" "veccmp")
14758   (set_attr "size" "128")])
14759
14760
14761
14762(include "sync.md")
14763(include "vector.md")
14764(include "vsx.md")
14765(include "altivec.md")
14766(include "spe.md")
14767(include "dfp.md")
14768(include "paired.md")
14769(include "crypto.md")
14770(include "htm.md")
14771