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   (FRAME_POINTER_REGNUM	111)
54   (TFHAR_REGNO			112)
55   (TFIAR_REGNO			113)
56   (TEXASR_REGNO		114)
57  ])
58
59;;
60;; UNSPEC usage
61;;
62
63(define_c_enum "unspec"
64  [UNSPEC_FRSP			; frsp for POWER machines
65   UNSPEC_PROBE_STACK		; probe stack memory reference
66   UNSPEC_TOCPTR		; address of a word pointing to the TOC
67   UNSPEC_TOC			; address of the TOC (more-or-less)
68   UNSPEC_TOCSLOT		; offset from r1 of toc pointer save slot
69   UNSPEC_MOVSI_GOT
70   UNSPEC_MV_CR_OV		; move_from_CR_ov_bit
71   UNSPEC_FCTIWZ
72   UNSPEC_FRIM
73   UNSPEC_FRIN
74   UNSPEC_FRIP
75   UNSPEC_FRIZ
76   UNSPEC_XSRDPI
77   UNSPEC_LD_MPIC		; load_macho_picbase
78   UNSPEC_RELD_MPIC		; re-load_macho_picbase
79   UNSPEC_MPIC_CORRECT		; macho_correct_pic
80   UNSPEC_TLSGD
81   UNSPEC_TLSLD
82   UNSPEC_MOVESI_FROM_CR
83   UNSPEC_MOVESI_TO_CR
84   UNSPEC_TLSDTPREL
85   UNSPEC_TLSDTPRELHA
86   UNSPEC_TLSDTPRELLO
87   UNSPEC_TLSGOTDTPREL
88   UNSPEC_TLSTPREL
89   UNSPEC_TLSTPRELHA
90   UNSPEC_TLSTPRELLO
91   UNSPEC_TLSGOTTPREL
92   UNSPEC_TLSTLS
93   UNSPEC_FIX_TRUNC_TF		; fadd, rounding towards zero
94   UNSPEC_STFIWX
95   UNSPEC_POPCNTB
96   UNSPEC_FRES
97   UNSPEC_SP_SET
98   UNSPEC_SP_TEST
99   UNSPEC_SYNC
100   UNSPEC_LWSYNC
101   UNSPEC_SYNC_OP
102   UNSPEC_ATOMIC
103   UNSPEC_CMPXCHG
104   UNSPEC_XCHG
105   UNSPEC_AND
106   UNSPEC_DLMZB
107   UNSPEC_DLMZB_CR
108   UNSPEC_DLMZB_STRLEN
109   UNSPEC_RSQRT
110   UNSPEC_TOCREL
111   UNSPEC_MACHOPIC_OFFSET
112   UNSPEC_BPERM
113   UNSPEC_COPYSIGN
114   UNSPEC_PARITY
115   UNSPEC_CMPB
116   UNSPEC_FCTIW
117   UNSPEC_FCTID
118   UNSPEC_LFIWAX
119   UNSPEC_LFIWZX
120   UNSPEC_FCTIWUZ
121   UNSPEC_NOP
122   UNSPEC_GRP_END_NOP
123   UNSPEC_P8V_FMRGOW
124   UNSPEC_P8V_MTVSRWZ
125   UNSPEC_P8V_RELOAD_FROM_GPR
126   UNSPEC_P8V_MTVSRD
127   UNSPEC_P8V_XXPERMDI
128   UNSPEC_P8V_RELOAD_FROM_VSX
129   UNSPEC_ADDG6S
130   UNSPEC_CDTBCD
131   UNSPEC_CBCDTD
132   UNSPEC_DIVE
133   UNSPEC_DIVEU
134   UNSPEC_UNPACK_128BIT
135   UNSPEC_PACK_128BIT
136   UNSPEC_LSQ
137   UNSPEC_FUSION_GPR
138   UNSPEC_STACK_CHECK
139   UNSPEC_CMPRB
140   UNSPEC_CMPRB2
141   UNSPEC_CMPEQB
142   UNSPEC_FUSION_P9
143   UNSPEC_FUSION_ADDIS
144   UNSPEC_ADD_ROUND_TO_ODD
145   UNSPEC_SUB_ROUND_TO_ODD
146   UNSPEC_MUL_ROUND_TO_ODD
147   UNSPEC_DIV_ROUND_TO_ODD
148   UNSPEC_FMA_ROUND_TO_ODD
149   UNSPEC_SQRT_ROUND_TO_ODD
150   UNSPEC_TRUNC_ROUND_TO_ODD
151   UNSPEC_SIGNBIT
152   UNSPEC_SF_FROM_SI
153   UNSPEC_SI_FROM_SF
154  ])
155
156;;
157;; UNSPEC_VOLATILE usage
158;;
159
160(define_c_enum "unspecv"
161  [UNSPECV_BLOCK
162   UNSPECV_LL			; load-locked
163   UNSPECV_SC			; store-conditional
164   UNSPECV_PROBE_STACK_RANGE	; probe range of stack addresses
165   UNSPECV_EH_RR		; eh_reg_restore
166   UNSPECV_ISYNC		; isync instruction
167   UNSPECV_MFTB			; move from time base
168   UNSPECV_DARN			; darn 1 (deliver a random number)
169   UNSPECV_DARN_32		; darn 2
170   UNSPECV_DARN_RAW		; darn 0
171   UNSPECV_NLGR			; non-local goto receiver
172   UNSPECV_MFFS			; Move from FPSCR
173   UNSPECV_MTFSF		; Move to FPSCR Fields
174   UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
175   UNSPECV_SPEC_BARRIER         ; Speculation barrier
176  ])
177
178
179;; Define an insn type attribute.  This is used in function unit delay
180;; computations.
181(define_attr "type"
182  "integer,two,three,
183   add,logical,shift,insert,
184   mul,halfmul,div,
185   exts,cntlz,popcnt,isel,
186   load,store,fpload,fpstore,vecload,vecstore,
187   cmp,
188   branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
189   cr_logical,mfcr,mfcrf,mtcr,
190   fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
191   vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
192   vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
193   veclogical,veccmpfx,vecexts,vecmove,
194   htm,htmsimple,dfp"
195  (const_string "integer"))
196
197;; What data size does this instruction work on?
198;; This is used for insert, mul and others as necessary.
199(define_attr "size" "8,16,32,64,128" (const_string "32"))
200
201;; What is the insn_cost for this insn?  The target hook can still override
202;; this.  For optimizing for size the "length" attribute is used instead.
203(define_attr "cost" "" (const_int 0))
204
205;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
206;; This is used for add, logical, shift, exts, mul.
207(define_attr "dot" "no,yes" (const_string "no"))
208
209;; Does this instruction sign-extend its result?
210;; This is used for load insns.
211(define_attr "sign_extend" "no,yes" (const_string "no"))
212
213;; Does this cr_logical instruction have three operands?  That is, BT != BB.
214(define_attr "cr_logical_3op" "no,yes" (const_string "no"))
215
216;; Does this instruction use indexed (that is, reg+reg) addressing?
217;; This is used for load and store insns.  If operand 0 or 1 is a MEM
218;; it is automatically set based on that.  If a load or store instruction
219;; has fewer than two operands it needs to set this attribute manually
220;; or the compiler will crash.
221(define_attr "indexed" "no,yes"
222  (if_then_else (ior (match_operand 0 "indexed_address_mem")
223		     (match_operand 1 "indexed_address_mem"))
224		(const_string "yes")
225		(const_string "no")))
226
227;; Does this instruction use update addressing?
228;; This is used for load and store insns.  See the comments for "indexed".
229(define_attr "update" "no,yes"
230  (if_then_else (ior (match_operand 0 "update_address_mem")
231		     (match_operand 1 "update_address_mem"))
232		(const_string "yes")
233		(const_string "no")))
234
235;; Is this instruction using operands[2] as shift amount, and can that be a
236;; register?
237;; This is used for shift insns.
238(define_attr "maybe_var_shift" "no,yes" (const_string "no"))
239
240;; Is this instruction using a shift amount from a register?
241;; This is used for shift insns.
242(define_attr "var_shift" "no,yes"
243  (if_then_else (and (eq_attr "type" "shift")
244		     (eq_attr "maybe_var_shift" "yes"))
245		(if_then_else (match_operand 2 "gpc_reg_operand")
246			      (const_string "yes")
247			      (const_string "no"))
248		(const_string "no")))
249
250;; Is copying of this instruction disallowed?
251(define_attr "cannot_copy" "no,yes" (const_string "no"))
252
253;; Define floating point instruction sub-types for use with Xfpu.md
254(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"))
255
256;; Length (in bytes).
257; '(pc)' in the following doesn't include the instruction itself; it is
258; calculated as if the instruction had zero size.
259(define_attr "length" ""
260  (if_then_else (eq_attr "type" "branch")
261		(if_then_else (and (ge (minus (match_dup 0) (pc))
262				       (const_int -32768))
263				   (lt (minus (match_dup 0) (pc))
264				       (const_int 32764)))
265			      (const_int 4)
266			      (const_int 8))
267		(const_int 4)))
268
269;; Processor type -- this attribute must exactly match the processor_type
270;; enumeration in rs6000-opts.h.
271(define_attr "cpu"
272  "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
273   ppc750,ppc7400,ppc7450,
274   ppc403,ppc405,ppc440,ppc476,
275   ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
276   power4,power5,power6,power7,power8,power9,
277   rs64a,mpccore,cell,ppca2,titan"
278  (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
279
280
281;; If this instruction is microcoded on the CELL processor
282; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
283(define_attr "cell_micro" "not,conditional,always"
284  (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
285			  (eq_attr "dot" "yes"))
286		     (and (eq_attr "type" "load")
287			  (eq_attr "sign_extend" "yes"))
288		     (and (eq_attr "type" "shift")
289			  (eq_attr "var_shift" "yes")))
290		(const_string "always")
291		(const_string "not")))
292
293(automata_option "ndfa")
294
295(include "rs64.md")
296(include "mpc.md")
297(include "40x.md")
298(include "440.md")
299(include "476.md")
300(include "601.md")
301(include "603.md")
302(include "6xx.md")
303(include "7xx.md")
304(include "7450.md")
305(include "8540.md")
306(include "e300c2c3.md")
307(include "e500mc.md")
308(include "e500mc64.md")
309(include "e5500.md")
310(include "e6500.md")
311(include "power4.md")
312(include "power5.md")
313(include "power6.md")
314(include "power7.md")
315(include "power8.md")
316(include "power9.md")
317(include "cell.md")
318(include "xfpu.md")
319(include "a2.md")
320(include "titan.md")
321
322(include "predicates.md")
323(include "constraints.md")
324
325(include "darwin.md")
326
327
328;; Mode iterators
329
330; This mode iterator allows :GPR to be used to indicate the allowable size
331; of whole values in GPRs.
332(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
333
334; And again, for patterns that need two (potentially) different integer modes.
335(define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
336
337; Any supported integer mode.
338(define_mode_iterator INT [QI HI SI DI TI PTI])
339
340; Any supported integer mode that fits in one register.
341(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
342
343; Integer modes supported in VSX registers with ISA 3.0 instructions
344(define_mode_iterator INT_ISA3 [QI HI SI DI])
345
346; Everything we can extend QImode to.
347(define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
348
349; Everything we can extend HImode to.
350(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
351
352; Everything we can extend SImode to.
353(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
354
355; QImode or HImode for small integer moves and small atomic ops
356(define_mode_iterator QHI [QI HI])
357
358; QImode, HImode, SImode for fused ops only for GPR loads
359(define_mode_iterator QHSI [QI HI SI])
360
361; HImode or SImode for sign extended fusion ops
362(define_mode_iterator HSI [HI SI])
363
364; SImode or DImode, even if DImode doesn't fit in GPRs.
365(define_mode_iterator SDI [SI DI])
366
367; Types that can be fused with an ADDIS instruction to load or store a GPR
368; register that has reg+offset addressing.
369(define_mode_iterator GPR_FUSION [QI
370				  HI
371				  SI
372				  (DI	"TARGET_POWERPC64")
373				  SF
374				  (DF	"TARGET_POWERPC64")])
375
376; Types that can be fused with an ADDIS instruction to load or store a FPR
377; register that has reg+offset addressing.
378(define_mode_iterator FPR_FUSION [DI SF DF])
379
380; The size of a pointer.  Also, the size of the value that a record-condition
381; (one with a '.') will compare; and the size used for arithmetic carries.
382(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
383
384; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
385; PTImode is GPR only)
386(define_mode_iterator TI2 [TI PTI])
387
388; Any hardware-supported floating-point mode
389(define_mode_iterator FP [
390  (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
391  (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
392  (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
393  (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
394  (KF "TARGET_FLOAT128_TYPE")
395  (DD "TARGET_DFP")
396  (TD "TARGET_DFP")])
397
398; Any fma capable floating-point mode.
399(define_mode_iterator FMA_F [
400  (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
401  (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
402       || VECTOR_UNIT_VSX_P (DFmode)")
403  (V2SF "TARGET_PAIRED_FLOAT")
404  (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
405  (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
406  (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
407  (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
408  ])
409
410; Floating point move iterators to combine binary and decimal moves
411(define_mode_iterator FMOVE32 [SF SD])
412(define_mode_iterator FMOVE64 [DF DD])
413(define_mode_iterator FMOVE64X [DI DF DD])
414(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
415				(IF "FLOAT128_IBM_P (IFmode)")
416				(TD "TARGET_HARD_FLOAT")])
417
418(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
419				    (IF "FLOAT128_2REG_P (IFmode)")
420				    (TD "TARGET_HARD_FLOAT")])
421
422; Iterators for 128 bit types for direct move
423(define_mode_iterator FMOVE128_GPR [TI
424				    V16QI
425				    V8HI
426				    V4SI
427				    V4SF
428				    V2DI
429				    V2DF
430				    V1TI
431				    (KF    "FLOAT128_VECTOR_P (KFmode)")
432				    (TF    "FLOAT128_VECTOR_P (TFmode)")])
433
434; Iterator for 128-bit VSX types for pack/unpack
435(define_mode_iterator FMOVE128_VSX [V1TI KF])
436
437; Iterators for converting to/from TFmode
438(define_mode_iterator IFKF [IF KF])
439
440; Constraints for moving IF/KFmode.
441(define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
442
443; Whether a floating point move is ok, don't allow SD without hardware FP
444(define_mode_attr fmove_ok [(SF "")
445			    (DF "")
446			    (SD "TARGET_HARD_FLOAT")
447			    (DD "")])
448
449; Convert REAL_VALUE to the appropriate bits
450(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
451					(DF "REAL_VALUE_TO_TARGET_DOUBLE")
452					(SD "REAL_VALUE_TO_TARGET_DECIMAL32")
453					(DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
454
455; Whether 0.0 has an all-zero bit pattern
456(define_mode_attr zero_fp [(SF "j")
457			   (DF "j")
458			   (TF "j")
459			   (IF "j")
460			   (KF "j")
461			   (SD "wn")
462			   (DD "wn")
463			   (TD "wn")])
464
465; Definitions for 64-bit VSX
466(define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
467
468; Definitions for 64-bit direct move
469(define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
470
471; Definitions for 64-bit use of altivec registers
472(define_mode_attr f64_av  [(DF "wv") (DD "wn")])
473
474; Definitions for 64-bit access to ISA 3.0 (power9) vector
475(define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
476
477; These modes do not fit in integer registers in 32-bit mode.
478(define_mode_iterator DIFD [DI DF DD])
479
480; Iterator for reciprocal estimate instructions
481(define_mode_iterator RECIPF [SF DF V4SF V2DF])
482
483; Iterator for just SF/DF
484(define_mode_iterator SFDF [SF DF])
485
486; Like SFDF, but a different name to match conditional move where the
487; comparison operands may be a different mode than the input operands.
488(define_mode_iterator SFDF2 [SF DF])
489
490; Iterator for 128-bit floating point that uses the IBM double-double format
491(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
492			      (TF "FLOAT128_IBM_P (TFmode)")])
493
494; Iterator for 128-bit floating point that uses IEEE 128-bit float
495(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
496			       (TF "FLOAT128_IEEE_P (TFmode)")])
497
498; Iterator for 128-bit floating point
499(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
500				(IF "TARGET_FLOAT128_TYPE")
501				(TF "TARGET_LONG_DOUBLE_128")])
502
503; Iterator for signbit on 64-bit machines with direct move
504(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
505			       (TF "FLOAT128_VECTOR_P (TFmode)")])
506
507; Iterator for ISA 3.0 supported floating point types
508(define_mode_iterator FP_ISA3 [SF DF])
509
510; SF/DF suffix for traditional floating instructions
511(define_mode_attr Ftrad		[(SF "s") (DF "")])
512
513; SF/DF suffix for VSX instructions
514(define_mode_attr Fvsx		[(SF "sp") (DF	"dp")])
515
516; SF/DF constraint for arithmetic on traditional floating point registers
517(define_mode_attr Ff		[(SF "f") (DF "d") (DI "d")])
518
519; SF/DF constraint for arithmetic on VSX registers using instructions added in
520; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
521; but are used on SFmode, since internally SFmode values are kept in the DFmode
522; format.
523(define_mode_attr Fv		[(SF "ww") (DF "ws") (DI "wi")])
524
525; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
526; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
527; instructions added in ISA 2.07 (power8)
528(define_mode_attr Fv2		[(SF "wy") (DF "ws") (DI "wi")])
529
530; SF/DF constraint for arithmetic on altivec registers
531(define_mode_attr Fa		[(SF "wu") (DF "wv")])
532
533; s/d suffix for things like fp_addsub_s/fp_addsub_d
534(define_mode_attr Fs		[(SF "s")  (DF "d")])
535
536; FRE/FRES support
537(define_mode_attr Ffre		[(SF "fres") (DF "fre")])
538(define_mode_attr FFRE		[(SF "FRES") (DF "FRE")])
539
540; Conditional returns.
541(define_code_iterator any_return [return simple_return])
542(define_code_attr return_pred [(return "direct_return ()")
543			       (simple_return "1")])
544(define_code_attr return_str [(return "") (simple_return "simple_")])
545
546; Logical operators.
547(define_code_iterator iorxor		[ior xor])
548(define_code_iterator and_ior_xor	[and ior xor])
549
550; Signed/unsigned variants of ops.
551(define_code_iterator any_extend	[sign_extend zero_extend])
552(define_code_iterator any_fix		[fix unsigned_fix])
553(define_code_iterator any_float		[float unsigned_float])
554
555(define_code_attr u  [(sign_extend	"")
556		      (zero_extend	"u")
557		      (fix		"")
558		      (unsigned_fix	"u")])
559
560(define_code_attr su [(sign_extend	"s")
561		      (zero_extend	"u")
562		      (fix		"s")
563		      (unsigned_fix	"u")
564		      (float		"s")
565		      (unsigned_float	"u")])
566
567(define_code_attr az [(sign_extend	"a")
568		      (zero_extend	"z")
569		      (fix		"a")
570		      (unsigned_fix	"z")
571		      (float		"a")
572		      (unsigned_float	"z")])
573
574(define_code_attr uns [(fix		"")
575		       (unsigned_fix	"uns")
576		       (float		"")
577		       (unsigned_float	"uns")])
578
579; Various instructions that come in SI and DI forms.
580; A generic w/d attribute, for things like cmpw/cmpd.
581(define_mode_attr wd [(QI    "b")
582		      (HI    "h")
583		      (SI    "w")
584		      (DI    "d")
585		      (V16QI "b")
586		      (V8HI  "h")
587		      (V4SI  "w")
588		      (V2DI  "d")
589		      (V1TI  "q")
590		      (TI    "q")])
591
592;; How many bits in this mode?
593(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
594
595; DImode bits
596(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
597
598;; Bitmask for shift instructions
599(define_mode_attr hH [(SI "h") (DI "H")])
600
601;; A mode twice the size of the given mode
602(define_mode_attr dmode [(SI "di") (DI "ti")])
603(define_mode_attr DMODE [(SI "DI") (DI "TI")])
604
605;; Suffix for reload patterns
606(define_mode_attr ptrsize [(SI "32bit")
607			   (DI "64bit")])
608
609(define_mode_attr tptrsize [(SI "TARGET_32BIT")
610			    (DI "TARGET_64BIT")])
611
612(define_mode_attr mptrsize [(SI "si")
613			    (DI "di")])
614
615(define_mode_attr ptrload [(SI "lwz")
616			   (DI "ld")])
617
618(define_mode_attr ptrm [(SI "m")
619			(DI "Y")])
620
621(define_mode_attr rreg [(SF   "f")
622			(DF   "ws")
623			(TF   "f")
624			(TD   "f")
625			(V4SF "wf")
626			(V2DF "wd")])
627
628(define_mode_attr rreg2 [(SF   "f")
629			 (DF   "d")])
630
631(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
632				 (DF "TARGET_FCFID")])
633
634(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
635				(DF "TARGET_DOUBLE_FLOAT")])
636
637;; Mode iterator for logical operations on 128-bit types
638(define_mode_iterator BOOL_128		[TI
639					 PTI
640					 (V16QI	"TARGET_ALTIVEC")
641					 (V8HI	"TARGET_ALTIVEC")
642					 (V4SI	"TARGET_ALTIVEC")
643					 (V4SF	"TARGET_ALTIVEC")
644					 (V2DI	"TARGET_ALTIVEC")
645					 (V2DF	"TARGET_ALTIVEC")
646					 (V1TI  "TARGET_ALTIVEC")])
647
648;; For the GPRs we use 3 constraints for register outputs, two that are the
649;; same as the output register, and a third where the output register is an
650;; early clobber, so we don't have to deal with register overlaps.  For the
651;; vector types, we prefer to use the vector registers.  For TI mode, allow
652;; either.
653
654;; Mode attribute for boolean operation register constraints for output
655(define_mode_attr BOOL_REGS_OUTPUT	[(TI	"&r,r,r,wt,v")
656					 (PTI	"&r,r,r")
657					 (V16QI	"wa,v,&?r,?r,?r")
658					 (V8HI	"wa,v,&?r,?r,?r")
659					 (V4SI	"wa,v,&?r,?r,?r")
660					 (V4SF	"wa,v,&?r,?r,?r")
661					 (V2DI	"wa,v,&?r,?r,?r")
662					 (V2DF	"wa,v,&?r,?r,?r")
663					 (V1TI	"wa,v,&?r,?r,?r")])
664
665;; Mode attribute for boolean operation register constraints for operand1
666(define_mode_attr BOOL_REGS_OP1		[(TI	"r,0,r,wt,v")
667					 (PTI	"r,0,r")
668					 (V16QI	"wa,v,r,0,r")
669					 (V8HI	"wa,v,r,0,r")
670					 (V4SI	"wa,v,r,0,r")
671					 (V4SF	"wa,v,r,0,r")
672					 (V2DI	"wa,v,r,0,r")
673					 (V2DF	"wa,v,r,0,r")
674					 (V1TI	"wa,v,r,0,r")])
675
676;; Mode attribute for boolean operation register constraints for operand2
677(define_mode_attr BOOL_REGS_OP2		[(TI	"r,r,0,wt,v")
678					 (PTI	"r,r,0")
679					 (V16QI	"wa,v,r,r,0")
680					 (V8HI	"wa,v,r,r,0")
681					 (V4SI	"wa,v,r,r,0")
682					 (V4SF	"wa,v,r,r,0")
683					 (V2DI	"wa,v,r,r,0")
684					 (V2DF	"wa,v,r,r,0")
685					 (V1TI	"wa,v,r,r,0")])
686
687;; Mode attribute for boolean operation register constraints for operand1
688;; for one_cmpl.  To simplify things, we repeat the constraint where 0
689;; is used for operand1 or operand2
690(define_mode_attr BOOL_REGS_UNARY	[(TI	"r,0,0,wt,v")
691					 (PTI	"r,0,0")
692					 (V16QI	"wa,v,r,0,0")
693					 (V8HI	"wa,v,r,0,0")
694					 (V4SI	"wa,v,r,0,0")
695					 (V4SF	"wa,v,r,0,0")
696					 (V2DI	"wa,v,r,0,0")
697					 (V2DF	"wa,v,r,0,0")
698					 (V1TI	"wa,v,r,0,0")])
699
700;; Reload iterator for creating the function to allocate a base register to
701;; supplement addressing modes.
702(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
703			      SF SD SI DF DD DI TI PTI KF IF TF])
704
705;; Iterate over smin, smax
706(define_code_iterator fp_minmax	[smin smax])
707
708(define_code_attr     minmax	[(smin "min")
709				 (smax "max")])
710
711(define_code_attr     SMINMAX	[(smin "SMIN")
712				 (smax "SMAX")])
713
714;; Iterator to optimize the following cases:
715;;	D-form load to FPR register & move to Altivec register
716;;	Move Altivec register to FPR register and store
717(define_mode_iterator ALTIVEC_DFORM [DF
718				     (SF "TARGET_P8_VECTOR")
719				     (DI "TARGET_POWERPC64")])
720
721
722;; Start with fixed-point load and store insns.  Here we put only the more
723;; complex forms.  Basic data transfer is done later.
724
725(define_insn "zero_extendqi<mode>2"
726  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
727	(zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
728  ""
729  "@
730   lbz%U1%X1 %0,%1
731   rlwinm %0,%1,0,0xff
732   lxsibzx %x0,%y1
733   vextractub %0,%1,7"
734  [(set_attr "type" "load,shift,fpload,vecperm")])
735
736(define_insn_and_split "*zero_extendqi<mode>2_dot"
737  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
738	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
739		    (const_int 0)))
740   (clobber (match_scratch:EXTQI 0 "=r,r"))]
741  ""
742  "@
743   andi. %0,%1,0xff
744   #"
745  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
746  [(set (match_dup 0)
747	(zero_extend:EXTQI (match_dup 1)))
748   (set (match_dup 2)
749	(compare:CC (match_dup 0)
750		    (const_int 0)))]
751  ""
752  [(set_attr "type" "logical")
753   (set_attr "dot" "yes")
754   (set_attr "length" "4,8")])
755
756(define_insn_and_split "*zero_extendqi<mode>2_dot2"
757  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
758	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
759		    (const_int 0)))
760   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
761	(zero_extend:EXTQI (match_dup 1)))]
762  ""
763  "@
764   andi. %0,%1,0xff
765   #"
766  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
767  [(set (match_dup 0)
768	(zero_extend:EXTQI (match_dup 1)))
769   (set (match_dup 2)
770	(compare:CC (match_dup 0)
771		    (const_int 0)))]
772  ""
773  [(set_attr "type" "logical")
774   (set_attr "dot" "yes")
775   (set_attr "length" "4,8")])
776
777
778(define_insn "zero_extendhi<mode>2"
779  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
780	(zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
781  ""
782  "@
783   lhz%U1%X1 %0,%1
784   rlwinm %0,%1,0,0xffff
785   lxsihzx %x0,%y1
786   vextractuh %0,%1,6"
787  [(set_attr "type" "load,shift,fpload,vecperm")])
788
789(define_insn_and_split "*zero_extendhi<mode>2_dot"
790  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
791	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
792		    (const_int 0)))
793   (clobber (match_scratch:EXTHI 0 "=r,r"))]
794  ""
795  "@
796   andi. %0,%1,0xffff
797   #"
798  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
799  [(set (match_dup 0)
800	(zero_extend:EXTHI (match_dup 1)))
801   (set (match_dup 2)
802	(compare:CC (match_dup 0)
803		    (const_int 0)))]
804  ""
805  [(set_attr "type" "logical")
806   (set_attr "dot" "yes")
807   (set_attr "length" "4,8")])
808
809(define_insn_and_split "*zero_extendhi<mode>2_dot2"
810  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
811	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
812		    (const_int 0)))
813   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
814	(zero_extend:EXTHI (match_dup 1)))]
815  ""
816  "@
817   andi. %0,%1,0xffff
818   #"
819  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
820  [(set (match_dup 0)
821	(zero_extend:EXTHI (match_dup 1)))
822   (set (match_dup 2)
823	(compare:CC (match_dup 0)
824		    (const_int 0)))]
825  ""
826  [(set_attr "type" "logical")
827   (set_attr "dot" "yes")
828   (set_attr "length" "4,8")])
829
830
831(define_insn "zero_extendsi<mode>2"
832  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
833	(zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
834  ""
835  "@
836   lwz%U1%X1 %0,%1
837   rldicl %0,%1,0,32
838   lfiwzx %0,%y1
839   lxsiwzx %x0,%y1
840   mtvsrwz %x0,%1
841   mfvsrwz %0,%x1
842   xxextractuw %x0,%x1,4"
843  [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
844
845(define_insn_and_split "*zero_extendsi<mode>2_dot"
846  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
847	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
848		    (const_int 0)))
849   (clobber (match_scratch:EXTSI 0 "=r,r"))]
850  ""
851  "@
852   rldicl. %0,%1,0,32
853   #"
854  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
855  [(set (match_dup 0)
856	(zero_extend:DI (match_dup 1)))
857   (set (match_dup 2)
858	(compare:CC (match_dup 0)
859		    (const_int 0)))]
860  ""
861  [(set_attr "type" "shift")
862   (set_attr "dot" "yes")
863   (set_attr "length" "4,8")])
864
865(define_insn_and_split "*zero_extendsi<mode>2_dot2"
866  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
867	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
868		    (const_int 0)))
869   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
870	(zero_extend:EXTSI (match_dup 1)))]
871  ""
872  "@
873   rldicl. %0,%1,0,32
874   #"
875  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
876  [(set (match_dup 0)
877	(zero_extend:EXTSI (match_dup 1)))
878   (set (match_dup 2)
879	(compare:CC (match_dup 0)
880		    (const_int 0)))]
881  ""
882  [(set_attr "type" "shift")
883   (set_attr "dot" "yes")
884   (set_attr "length" "4,8")])
885
886
887(define_insn "extendqi<mode>2"
888  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
889	(sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
890  ""
891  "@
892   extsb %0,%1
893   vextsb2d %0,%1"
894  [(set_attr "type" "exts,vecperm")])
895
896(define_insn_and_split "*extendqi<mode>2_dot"
897  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
898	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
899		    (const_int 0)))
900   (clobber (match_scratch:EXTQI 0 "=r,r"))]
901  ""
902  "@
903   extsb. %0,%1
904   #"
905  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
906  [(set (match_dup 0)
907	(sign_extend:EXTQI (match_dup 1)))
908   (set (match_dup 2)
909	(compare:CC (match_dup 0)
910		    (const_int 0)))]
911  ""
912  [(set_attr "type" "exts")
913   (set_attr "dot" "yes")
914   (set_attr "length" "4,8")])
915
916(define_insn_and_split "*extendqi<mode>2_dot2"
917  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
918	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
919		    (const_int 0)))
920   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
921	(sign_extend:EXTQI (match_dup 1)))]
922  ""
923  "@
924   extsb. %0,%1
925   #"
926  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
927  [(set (match_dup 0)
928	(sign_extend:EXTQI (match_dup 1)))
929   (set (match_dup 2)
930	(compare:CC (match_dup 0)
931		    (const_int 0)))]
932  ""
933  [(set_attr "type" "exts")
934   (set_attr "dot" "yes")
935   (set_attr "length" "4,8")])
936
937
938(define_expand "extendhi<mode>2"
939  [(set (match_operand:EXTHI 0 "gpc_reg_operand")
940	(sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
941  ""
942  "")
943
944(define_insn "*extendhi<mode>2"
945  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
946	(sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
947  ""
948  "@
949   lha%U1%X1 %0,%1
950   extsh %0,%1
951   #
952   vextsh2d %0,%1"
953  [(set_attr "type" "load,exts,fpload,vecperm")
954   (set_attr "sign_extend" "yes")
955   (set_attr "length" "4,4,8,4")])
956
957(define_split
958  [(set (match_operand:EXTHI 0 "altivec_register_operand")
959	(sign_extend:EXTHI
960	 (match_operand:HI 1 "indexed_or_indirect_operand")))]
961  "TARGET_P9_VECTOR && reload_completed"
962  [(set (match_dup 2)
963	(match_dup 1))
964   (set (match_dup 0)
965	(sign_extend:EXTHI (match_dup 2)))]
966{
967  operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
968})
969
970(define_insn_and_split "*extendhi<mode>2_dot"
971  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
972	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
973		    (const_int 0)))
974   (clobber (match_scratch:EXTHI 0 "=r,r"))]
975  ""
976  "@
977   extsh. %0,%1
978   #"
979  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
980  [(set (match_dup 0)
981	(sign_extend:EXTHI (match_dup 1)))
982   (set (match_dup 2)
983	(compare:CC (match_dup 0)
984		    (const_int 0)))]
985  ""
986  [(set_attr "type" "exts")
987   (set_attr "dot" "yes")
988   (set_attr "length" "4,8")])
989
990(define_insn_and_split "*extendhi<mode>2_dot2"
991  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
992	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
993		    (const_int 0)))
994   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
995	(sign_extend:EXTHI (match_dup 1)))]
996  ""
997  "@
998   extsh. %0,%1
999   #"
1000  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1001  [(set (match_dup 0)
1002	(sign_extend:EXTHI (match_dup 1)))
1003   (set (match_dup 2)
1004	(compare:CC (match_dup 0)
1005		    (const_int 0)))]
1006  ""
1007  [(set_attr "type" "exts")
1008   (set_attr "dot" "yes")
1009   (set_attr "length" "4,8")])
1010
1011
1012(define_insn "extendsi<mode>2"
1013  [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1014		     "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
1015
1016	(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1017		     "YZ, r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
1018  ""
1019  "@
1020   lwa%U1%X1 %0,%1
1021   extsw %0,%1
1022   lfiwax %0,%y1
1023   lxsiwax %x0,%y1
1024   mtvsrwa %x0,%1
1025   vextsw2d %0,%1
1026   #
1027   #"
1028  [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1029   (set_attr "sign_extend" "yes")
1030   (set_attr "length" "4,4,4,4,4,4,8,8")])
1031
1032(define_split
1033  [(set (match_operand:EXTSI 0 "int_reg_operand")
1034	(sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1035  "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1036  [(set (match_dup 2)
1037	(match_dup 1))
1038   (set (match_dup 0)
1039	(sign_extend:DI (match_dup 2)))]
1040{
1041  operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1042})
1043
1044(define_split
1045  [(set (match_operand:DI 0 "altivec_register_operand")
1046	(sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1047  "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1048  [(const_int 0)]
1049{
1050  rtx dest = operands[0];
1051  rtx src = operands[1];
1052  int dest_regno = REGNO (dest);
1053  int src_regno = REGNO (src);
1054  rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1055  rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1056
1057  if (VECTOR_ELT_ORDER_BIG)
1058    {
1059      emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1060      emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1061    }
1062  else
1063    {
1064      emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1065      emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1066    }
1067  DONE;
1068})
1069
1070(define_insn_and_split "*extendsi<mode>2_dot"
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   (clobber (match_scratch:EXTSI 0 "=r,r"))]
1075  ""
1076  "@
1077   extsw. %0,%1
1078   #"
1079  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1080  [(set (match_dup 0)
1081	(sign_extend:EXTSI (match_dup 1)))
1082   (set (match_dup 2)
1083	(compare:CC (match_dup 0)
1084		    (const_int 0)))]
1085  ""
1086  [(set_attr "type" "exts")
1087   (set_attr "dot" "yes")
1088   (set_attr "length" "4,8")])
1089
1090(define_insn_and_split "*extendsi<mode>2_dot2"
1091  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1092	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1093		    (const_int 0)))
1094   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1095	(sign_extend:EXTSI (match_dup 1)))]
1096  ""
1097  "@
1098   extsw. %0,%1
1099   #"
1100  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1101  [(set (match_dup 0)
1102	(sign_extend:EXTSI (match_dup 1)))
1103   (set (match_dup 2)
1104	(compare:CC (match_dup 0)
1105		    (const_int 0)))]
1106  ""
1107  [(set_attr "type" "exts")
1108   (set_attr "dot" "yes")
1109   (set_attr "length" "4,8")])
1110
1111;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1112
1113(define_insn "*macchwc"
1114  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1115        (compare:CC (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 4 "gpc_reg_operand" "0"))
1121                    (const_int 0)))
1122   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1123        (plus:SI (mult:SI (ashiftrt:SI
1124                           (match_dup 2)
1125                           (const_int 16))
1126                          (sign_extend:SI
1127                           (match_dup 1)))
1128                 (match_dup 4)))]
1129  "TARGET_MULHW"
1130  "macchw. %0,%1,%2"
1131  [(set_attr "type" "halfmul")])
1132
1133(define_insn "*macchw"
1134  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1135        (plus:SI (mult:SI (ashiftrt:SI
1136                           (match_operand:SI 2 "gpc_reg_operand" "r")
1137                           (const_int 16))
1138                          (sign_extend:SI
1139                           (match_operand:HI 1 "gpc_reg_operand" "r")))
1140                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1141  "TARGET_MULHW"
1142  "macchw %0,%1,%2"
1143  [(set_attr "type" "halfmul")])
1144
1145(define_insn "*macchwuc"
1146  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1147        (compare:CC (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 4 "gpc_reg_operand" "0"))
1153                    (const_int 0)))
1154   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1155        (plus:SI (mult:SI (lshiftrt:SI
1156                           (match_dup 2)
1157                           (const_int 16))
1158                          (zero_extend:SI
1159                           (match_dup 1)))
1160                 (match_dup 4)))]
1161  "TARGET_MULHW"
1162  "macchwu. %0,%1,%2"
1163  [(set_attr "type" "halfmul")])
1164
1165(define_insn "*macchwu"
1166  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1167        (plus:SI (mult:SI (lshiftrt:SI
1168                           (match_operand:SI 2 "gpc_reg_operand" "r")
1169                           (const_int 16))
1170                          (zero_extend:SI
1171                           (match_operand:HI 1 "gpc_reg_operand" "r")))
1172                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1173  "TARGET_MULHW"
1174  "macchwu %0,%1,%2"
1175  [(set_attr "type" "halfmul")])
1176
1177(define_insn "*machhwc"
1178  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1179        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1180                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
1181                                       (const_int 16))
1182                                      (ashiftrt:SI
1183                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1184                                       (const_int 16)))
1185                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1186                    (const_int 0)))
1187   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1188        (plus:SI (mult:SI (ashiftrt:SI
1189                           (match_dup 1)
1190                           (const_int 16))
1191                          (ashiftrt:SI
1192                           (match_dup 2)
1193                           (const_int 16)))
1194                 (match_dup 4)))]
1195  "TARGET_MULHW"
1196  "machhw. %0,%1,%2"
1197  [(set_attr "type" "halfmul")])
1198
1199(define_insn "*machhw"
1200  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1201        (plus:SI (mult:SI (ashiftrt:SI
1202                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1203                           (const_int 16))
1204                          (ashiftrt:SI
1205                           (match_operand:SI 2 "gpc_reg_operand" "r")
1206                           (const_int 16)))
1207                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1208  "TARGET_MULHW"
1209  "machhw %0,%1,%2"
1210  [(set_attr "type" "halfmul")])
1211
1212(define_insn "*machhwuc"
1213  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1214        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1215                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
1216                                       (const_int 16))
1217                                      (lshiftrt:SI
1218                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1219                                       (const_int 16)))
1220                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1221                    (const_int 0)))
1222   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1223        (plus:SI (mult:SI (lshiftrt:SI
1224                           (match_dup 1)
1225                           (const_int 16))
1226                          (lshiftrt:SI
1227                           (match_dup 2)
1228                           (const_int 16)))
1229                 (match_dup 4)))]
1230  "TARGET_MULHW"
1231  "machhwu. %0,%1,%2"
1232  [(set_attr "type" "halfmul")])
1233
1234(define_insn "*machhwu"
1235  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1236        (plus:SI (mult:SI (lshiftrt:SI
1237                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1238                           (const_int 16))
1239                          (lshiftrt:SI
1240                           (match_operand:SI 2 "gpc_reg_operand" "r")
1241                           (const_int 16)))
1242                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1243  "TARGET_MULHW"
1244  "machhwu %0,%1,%2"
1245  [(set_attr "type" "halfmul")])
1246
1247(define_insn "*maclhwc"
1248  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1249        (compare:CC (plus:SI (mult:SI (sign_extend:SI
1250                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1251                                      (sign_extend:SI
1252                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1253                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1254                    (const_int 0)))
1255   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256        (plus:SI (mult:SI (sign_extend:SI
1257                           (match_dup 1))
1258                          (sign_extend:SI
1259                           (match_dup 2)))
1260                 (match_dup 4)))]
1261  "TARGET_MULHW"
1262  "maclhw. %0,%1,%2"
1263  [(set_attr "type" "halfmul")])
1264
1265(define_insn "*maclhw"
1266  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1267        (plus:SI (mult:SI (sign_extend:SI
1268                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1269                          (sign_extend:SI
1270                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1271                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1272  "TARGET_MULHW"
1273  "maclhw %0,%1,%2"
1274  [(set_attr "type" "halfmul")])
1275
1276(define_insn "*maclhwuc"
1277  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1278        (compare:CC (plus:SI (mult:SI (zero_extend:SI
1279                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1280                                      (zero_extend:SI
1281                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1282                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1283                    (const_int 0)))
1284   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1285        (plus:SI (mult:SI (zero_extend:SI
1286                           (match_dup 1))
1287                          (zero_extend:SI
1288                           (match_dup 2)))
1289                 (match_dup 4)))]
1290  "TARGET_MULHW"
1291  "maclhwu. %0,%1,%2"
1292  [(set_attr "type" "halfmul")])
1293
1294(define_insn "*maclhwu"
1295  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1296        (plus:SI (mult:SI (zero_extend:SI
1297                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1298                          (zero_extend:SI
1299                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1300                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1301  "TARGET_MULHW"
1302  "maclhwu %0,%1,%2"
1303  [(set_attr "type" "halfmul")])
1304
1305(define_insn "*nmacchwc"
1306  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1307        (compare:CC (minus:SI (match_operand:SI 4 "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                    (const_int 0)))
1314   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1315        (minus:SI (match_dup 4)
1316                  (mult:SI (ashiftrt:SI
1317                            (match_dup 2)
1318                            (const_int 16))
1319                           (sign_extend:SI
1320                            (match_dup 1)))))]
1321  "TARGET_MULHW"
1322  "nmacchw. %0,%1,%2"
1323  [(set_attr "type" "halfmul")])
1324
1325(define_insn "*nmacchw"
1326  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1327        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1328                  (mult:SI (ashiftrt:SI
1329                            (match_operand:SI 2 "gpc_reg_operand" "r")
1330                            (const_int 16))
1331                           (sign_extend:SI
1332                            (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1333  "TARGET_MULHW"
1334  "nmacchw %0,%1,%2"
1335  [(set_attr "type" "halfmul")])
1336
1337(define_insn "*nmachhwc"
1338  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1339        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1340                              (mult:SI (ashiftrt:SI
1341                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1342                                        (const_int 16))
1343                                       (ashiftrt:SI
1344                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1345                                        (const_int 16))))
1346                    (const_int 0)))
1347   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1348        (minus:SI (match_dup 4)
1349                  (mult:SI (ashiftrt:SI
1350                            (match_dup 1)
1351                            (const_int 16))
1352                           (ashiftrt:SI
1353                            (match_dup 2)
1354                            (const_int 16)))))]
1355  "TARGET_MULHW"
1356  "nmachhw. %0,%1,%2"
1357  [(set_attr "type" "halfmul")])
1358
1359(define_insn "*nmachhw"
1360  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1362                  (mult:SI (ashiftrt:SI
1363                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1364                            (const_int 16))
1365                           (ashiftrt:SI
1366                            (match_operand:SI 2 "gpc_reg_operand" "r")
1367                            (const_int 16)))))]
1368  "TARGET_MULHW"
1369  "nmachhw %0,%1,%2"
1370  [(set_attr "type" "halfmul")])
1371
1372(define_insn "*nmaclhwc"
1373  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1374        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1375                              (mult:SI (sign_extend:SI
1376                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1377                                       (sign_extend:SI
1378                                        (match_operand:HI 2 "gpc_reg_operand" "r"))))
1379                    (const_int 0)))
1380   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1381        (minus:SI (match_dup 4)
1382                  (mult:SI (sign_extend:SI
1383                            (match_dup 1))
1384                           (sign_extend:SI
1385                            (match_dup 2)))))]
1386  "TARGET_MULHW"
1387  "nmaclhw. %0,%1,%2"
1388  [(set_attr "type" "halfmul")])
1389
1390(define_insn "*nmaclhw"
1391  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1392        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1393                  (mult:SI (sign_extend:SI
1394                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1395                           (sign_extend:SI
1396                            (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1397  "TARGET_MULHW"
1398  "nmaclhw %0,%1,%2"
1399  [(set_attr "type" "halfmul")])
1400
1401(define_insn "*mulchwc"
1402  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1403        (compare:CC (mult:SI (ashiftrt:SI
1404                              (match_operand:SI 2 "gpc_reg_operand" "r")
1405                              (const_int 16))
1406                             (sign_extend:SI
1407                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1408                    (const_int 0)))
1409   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1410        (mult:SI (ashiftrt:SI
1411                  (match_dup 2)
1412                  (const_int 16))
1413                 (sign_extend:SI
1414                  (match_dup 1))))]
1415  "TARGET_MULHW"
1416  "mulchw. %0,%1,%2"
1417  [(set_attr "type" "halfmul")])
1418
1419(define_insn "*mulchw"
1420  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1421        (mult:SI (ashiftrt:SI
1422                  (match_operand:SI 2 "gpc_reg_operand" "r")
1423                  (const_int 16))
1424                 (sign_extend:SI
1425                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1426  "TARGET_MULHW"
1427  "mulchw %0,%1,%2"
1428  [(set_attr "type" "halfmul")])
1429
1430(define_insn "*mulchwuc"
1431  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1432        (compare:CC (mult:SI (lshiftrt:SI
1433                              (match_operand:SI 2 "gpc_reg_operand" "r")
1434                              (const_int 16))
1435                             (zero_extend:SI
1436                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1437                    (const_int 0)))
1438   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1439        (mult:SI (lshiftrt:SI
1440                  (match_dup 2)
1441                  (const_int 16))
1442                 (zero_extend:SI
1443                  (match_dup 1))))]
1444  "TARGET_MULHW"
1445  "mulchwu. %0,%1,%2"
1446  [(set_attr "type" "halfmul")])
1447
1448(define_insn "*mulchwu"
1449  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1450        (mult:SI (lshiftrt:SI
1451                  (match_operand:SI 2 "gpc_reg_operand" "r")
1452                  (const_int 16))
1453                 (zero_extend:SI
1454                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1455  "TARGET_MULHW"
1456  "mulchwu %0,%1,%2"
1457  [(set_attr "type" "halfmul")])
1458
1459(define_insn "*mulhhwc"
1460  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1461        (compare:CC (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                    (const_int 0)))
1468   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1469        (mult:SI (ashiftrt:SI
1470                  (match_dup 1)
1471                  (const_int 16))
1472                 (ashiftrt:SI
1473                  (match_dup 2)
1474                  (const_int 16))))]
1475  "TARGET_MULHW"
1476  "mulhhw. %0,%1,%2"
1477  [(set_attr "type" "halfmul")])
1478
1479(define_insn "*mulhhw"
1480  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1481        (mult:SI (ashiftrt:SI
1482                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1483                  (const_int 16))
1484                 (ashiftrt:SI
1485                  (match_operand:SI 2 "gpc_reg_operand" "r")
1486                  (const_int 16))))]
1487  "TARGET_MULHW"
1488  "mulhhw %0,%1,%2"
1489  [(set_attr "type" "halfmul")])
1490
1491(define_insn "*mulhhwuc"
1492  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1493        (compare:CC (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                    (const_int 0)))
1500   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1501        (mult:SI (lshiftrt:SI
1502                  (match_dup 1)
1503                  (const_int 16))
1504                 (lshiftrt:SI
1505                  (match_dup 2)
1506                  (const_int 16))))]
1507  "TARGET_MULHW"
1508  "mulhhwu. %0,%1,%2"
1509  [(set_attr "type" "halfmul")])
1510
1511(define_insn "*mulhhwu"
1512  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1513        (mult:SI (lshiftrt:SI
1514                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1515                  (const_int 16))
1516                 (lshiftrt:SI
1517                  (match_operand:SI 2 "gpc_reg_operand" "r")
1518                  (const_int 16))))]
1519  "TARGET_MULHW"
1520  "mulhhwu %0,%1,%2"
1521  [(set_attr "type" "halfmul")])
1522
1523(define_insn "*mullhwc"
1524  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1525        (compare:CC (mult:SI (sign_extend:SI
1526                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1527                             (sign_extend:SI
1528                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1529                    (const_int 0)))
1530   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1531        (mult:SI (sign_extend:SI
1532                  (match_dup 1))
1533                 (sign_extend:SI
1534                  (match_dup 2))))]
1535  "TARGET_MULHW"
1536  "mullhw. %0,%1,%2"
1537  [(set_attr "type" "halfmul")])
1538
1539(define_insn "*mullhw"
1540  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1541        (mult:SI (sign_extend:SI
1542                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1543                 (sign_extend:SI
1544                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1545  "TARGET_MULHW"
1546  "mullhw %0,%1,%2"
1547  [(set_attr "type" "halfmul")])
1548
1549(define_insn "*mullhwuc"
1550  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1551        (compare:CC (mult:SI (zero_extend:SI
1552                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1553                             (zero_extend:SI
1554                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1555                    (const_int 0)))
1556   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1557        (mult:SI (zero_extend:SI
1558                  (match_dup 1))
1559                 (zero_extend:SI
1560                  (match_dup 2))))]
1561  "TARGET_MULHW"
1562  "mullhwu. %0,%1,%2"
1563  [(set_attr "type" "halfmul")])
1564
1565(define_insn "*mullhwu"
1566  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1567        (mult:SI (zero_extend:SI
1568                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1569                 (zero_extend:SI
1570                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1571  "TARGET_MULHW"
1572  "mullhwu %0,%1,%2"
1573  [(set_attr "type" "halfmul")])
1574
1575;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1576(define_insn "dlmzb"
1577  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1578        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1579                    (match_operand:SI 2 "gpc_reg_operand" "r")]
1580                   UNSPEC_DLMZB_CR))
1581   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1582        (unspec:SI [(match_dup 1)
1583                    (match_dup 2)]
1584                   UNSPEC_DLMZB))]
1585  "TARGET_DLMZB"
1586  "dlmzb. %0,%1,%2")
1587
1588(define_expand "strlensi"
1589  [(set (match_operand:SI 0 "gpc_reg_operand")
1590        (unspec:SI [(match_operand:BLK 1 "general_operand")
1591                    (match_operand:QI 2 "const_int_operand")
1592                    (match_operand 3 "const_int_operand")]
1593                   UNSPEC_DLMZB_STRLEN))
1594   (clobber (match_scratch:CC 4))]
1595  "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1596{
1597  rtx result = operands[0];
1598  rtx src = operands[1];
1599  rtx search_char = operands[2];
1600  rtx align = operands[3];
1601  rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1602  rtx loop_label, end_label, mem, cr0, cond;
1603  if (search_char != const0_rtx
1604      || GET_CODE (align) != CONST_INT
1605      || INTVAL (align) < 8)
1606        FAIL;
1607  word1 = gen_reg_rtx (SImode);
1608  word2 = gen_reg_rtx (SImode);
1609  scratch_dlmzb = gen_reg_rtx (SImode);
1610  scratch_string = gen_reg_rtx (Pmode);
1611  loop_label = gen_label_rtx ();
1612  end_label = gen_label_rtx ();
1613  addr = force_reg (Pmode, XEXP (src, 0));
1614  emit_move_insn (scratch_string, addr);
1615  emit_label (loop_label);
1616  mem = change_address (src, SImode, scratch_string);
1617  emit_move_insn (word1, mem);
1618  emit_move_insn (word2, adjust_address (mem, SImode, 4));
1619  cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1620  emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1621  cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1622  emit_jump_insn (gen_rtx_SET (pc_rtx,
1623                               gen_rtx_IF_THEN_ELSE (VOIDmode,
1624                                                     cond,
1625                                                     gen_rtx_LABEL_REF
1626                                                       (VOIDmode,
1627                                                        end_label),
1628                                                     pc_rtx)));
1629  emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1630  emit_jump_insn (gen_rtx_SET (pc_rtx,
1631                               gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1632  emit_barrier ();
1633  emit_label (end_label);
1634  emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1635  emit_insn (gen_subsi3 (result, scratch_string, addr));
1636  emit_insn (gen_addsi3 (result, result, constm1_rtx));
1637  DONE;
1638})
1639
1640;; Fixed-point arithmetic insns.
1641
1642(define_expand "add<mode>3"
1643  [(set (match_operand:SDI 0 "gpc_reg_operand")
1644	(plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1645		  (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1646  ""
1647{
1648  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1649    {
1650      rtx lo0 = gen_lowpart (SImode, operands[0]);
1651      rtx lo1 = gen_lowpart (SImode, operands[1]);
1652      rtx lo2 = gen_lowpart (SImode, operands[2]);
1653      rtx hi0 = gen_highpart (SImode, operands[0]);
1654      rtx hi1 = gen_highpart (SImode, operands[1]);
1655      rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1656
1657      if (!reg_or_short_operand (lo2, SImode))
1658	lo2 = force_reg (SImode, lo2);
1659      if (!adde_operand (hi2, SImode))
1660	hi2 = force_reg (SImode, hi2);
1661
1662      emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1663      emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1664      DONE;
1665    }
1666
1667  if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1668    {
1669      rtx tmp = ((!can_create_pseudo_p ()
1670		  || rtx_equal_p (operands[0], operands[1]))
1671		 ? operands[0] : gen_reg_rtx (<MODE>mode));
1672
1673      /* Adding a constant to r0 is not a valid insn, so use a different
1674	 strategy in that case.  */
1675      if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1676	{
1677	  if (operands[0] == operands[1])
1678	    FAIL;
1679	  rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1680	  emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1681	  DONE;
1682	}
1683
1684      HOST_WIDE_INT val = INTVAL (operands[2]);
1685      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1686      HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1687
1688      if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1689	FAIL;
1690
1691      /* The ordering here is important for the prolog expander.
1692	 When space is allocated from the stack, adding 'low' first may
1693	 produce a temporary deallocation (which would be bad).  */
1694      emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1695      emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1696      DONE;
1697    }
1698})
1699
1700(define_insn "*add<mode>3"
1701  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1702	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1703		  (match_operand:GPR 2 "add_operand" "r,I,L")))]
1704  ""
1705  "@
1706   add %0,%1,%2
1707   addi %0,%1,%2
1708   addis %0,%1,%v2"
1709  [(set_attr "type" "add")])
1710
1711(define_insn "addsi3_high"
1712  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1713        (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1714                 (high:SI (match_operand 2 "" ""))))]
1715  "TARGET_MACHO && !TARGET_64BIT"
1716  "addis %0,%1,ha16(%2)"
1717  [(set_attr "type" "add")])
1718
1719(define_insn_and_split "*add<mode>3_dot"
1720  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1721	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1722			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1723		    (const_int 0)))
1724   (clobber (match_scratch:GPR 0 "=r,r"))]
1725  "<MODE>mode == Pmode"
1726  "@
1727   add. %0,%1,%2
1728   #"
1729  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1730  [(set (match_dup 0)
1731	(plus:GPR (match_dup 1)
1732		 (match_dup 2)))
1733   (set (match_dup 3)
1734	(compare:CC (match_dup 0)
1735		    (const_int 0)))]
1736  ""
1737  [(set_attr "type" "add")
1738   (set_attr "dot" "yes")
1739   (set_attr "length" "4,8")])
1740
1741(define_insn_and_split "*add<mode>3_dot2"
1742  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1743	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1744			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1745		    (const_int 0)))
1746   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1747	(plus:GPR (match_dup 1)
1748		  (match_dup 2)))]
1749  "<MODE>mode == Pmode"
1750  "@
1751   add. %0,%1,%2
1752   #"
1753  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1754  [(set (match_dup 0)
1755	(plus:GPR (match_dup 1)
1756		  (match_dup 2)))
1757   (set (match_dup 3)
1758	(compare:CC (match_dup 0)
1759		    (const_int 0)))]
1760  ""
1761  [(set_attr "type" "add")
1762   (set_attr "dot" "yes")
1763   (set_attr "length" "4,8")])
1764
1765(define_insn_and_split "*add<mode>3_imm_dot"
1766  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1767	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1768			      (match_operand:GPR 2 "short_cint_operand" "I,I"))
1769		    (const_int 0)))
1770   (clobber (match_scratch:GPR 0 "=r,r"))
1771   (clobber (reg:GPR CA_REGNO))]
1772  "<MODE>mode == Pmode"
1773  "@
1774   addic. %0,%1,%2
1775   #"
1776  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1777  [(set (match_dup 0)
1778	(plus:GPR (match_dup 1)
1779		  (match_dup 2)))
1780   (set (match_dup 3)
1781	(compare:CC (match_dup 0)
1782		    (const_int 0)))]
1783  ""
1784  [(set_attr "type" "add")
1785   (set_attr "dot" "yes")
1786   (set_attr "length" "4,8")])
1787
1788(define_insn_and_split "*add<mode>3_imm_dot2"
1789  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1790	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1791			      (match_operand:GPR 2 "short_cint_operand" "I,I"))
1792		    (const_int 0)))
1793   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1794	(plus:GPR (match_dup 1)
1795		  (match_dup 2)))
1796   (clobber (reg:GPR CA_REGNO))]
1797  "<MODE>mode == Pmode"
1798  "@
1799   addic. %0,%1,%2
1800   #"
1801  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1802  [(set (match_dup 0)
1803	(plus:GPR (match_dup 1)
1804		  (match_dup 2)))
1805   (set (match_dup 3)
1806	(compare:CC (match_dup 0)
1807		    (const_int 0)))]
1808  ""
1809  [(set_attr "type" "add")
1810   (set_attr "dot" "yes")
1811   (set_attr "length" "4,8")])
1812
1813;; Split an add that we can't do in one insn into two insns, each of which
1814;; does one 16-bit part.  This is used by combine.  Note that the low-order
1815;; add should be last in case the result gets used in an address.
1816
1817(define_split
1818  [(set (match_operand:GPR 0 "gpc_reg_operand")
1819	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1820		  (match_operand:GPR 2 "non_add_cint_operand")))]
1821  ""
1822  [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1823   (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1824{
1825  HOST_WIDE_INT val = INTVAL (operands[2]);
1826  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1827  HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1828
1829  operands[4] = GEN_INT (low);
1830  if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1831    operands[3] = GEN_INT (rest);
1832  else if (can_create_pseudo_p ())
1833    {
1834      operands[3] = gen_reg_rtx (DImode);
1835      emit_move_insn (operands[3], operands[2]);
1836      emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1837      DONE;
1838    }
1839  else
1840    FAIL;
1841})
1842
1843
1844(define_insn "add<mode>3_carry"
1845  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1846	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1847		(match_operand:P 2 "reg_or_short_operand" "rI")))
1848   (set (reg:P CA_REGNO)
1849	(ltu:P (plus:P (match_dup 1)
1850		       (match_dup 2))
1851	       (match_dup 1)))]
1852  ""
1853  "add%I2c %0,%1,%2"
1854  [(set_attr "type" "add")])
1855
1856(define_insn "*add<mode>3_imm_carry_pos"
1857  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1858	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1859		(match_operand:P 2 "short_cint_operand" "n")))
1860   (set (reg:P CA_REGNO)
1861	(geu:P (match_dup 1)
1862	       (match_operand:P 3 "const_int_operand" "n")))]
1863  "INTVAL (operands[2]) > 0
1864   && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1865  "addic %0,%1,%2"
1866  [(set_attr "type" "add")])
1867
1868(define_insn "*add<mode>3_imm_carry_0"
1869  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1870	(match_operand:P 1 "gpc_reg_operand" "r"))
1871   (set (reg:P CA_REGNO)
1872	(const_int 0))]
1873  ""
1874  "addic %0,%1,0"
1875  [(set_attr "type" "add")])
1876
1877(define_insn "*add<mode>3_imm_carry_m1"
1878  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1879	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1880		(const_int -1)))
1881   (set (reg:P CA_REGNO)
1882	(ne:P (match_dup 1)
1883	      (const_int 0)))]
1884  ""
1885  "addic %0,%1,-1"
1886  [(set_attr "type" "add")])
1887
1888(define_insn "*add<mode>3_imm_carry_neg"
1889  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1890	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1891		(match_operand:P 2 "short_cint_operand" "n")))
1892   (set (reg:P CA_REGNO)
1893	(gtu:P (match_dup 1)
1894	       (match_operand:P 3 "const_int_operand" "n")))]
1895  "INTVAL (operands[2]) < 0
1896   && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1897  "addic %0,%1,%2"
1898  [(set_attr "type" "add")])
1899
1900
1901(define_expand "add<mode>3_carry_in"
1902  [(parallel [
1903     (set (match_operand:GPR 0 "gpc_reg_operand")
1904	  (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1905			      (match_operand:GPR 2 "adde_operand"))
1906		    (reg:GPR CA_REGNO)))
1907     (clobber (reg:GPR CA_REGNO))])]
1908  ""
1909{
1910  if (operands[2] == const0_rtx)
1911    {
1912      emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1913      DONE;
1914    }
1915  if (operands[2] == constm1_rtx)
1916    {
1917      emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1918      DONE;
1919    }
1920})
1921
1922(define_insn "*add<mode>3_carry_in_internal"
1923  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1924	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1925			    (match_operand:GPR 2 "gpc_reg_operand" "r"))
1926		  (reg:GPR CA_REGNO)))
1927   (clobber (reg:GPR CA_REGNO))]
1928  ""
1929  "adde %0,%1,%2"
1930  [(set_attr "type" "add")])
1931
1932(define_insn "*add<mode>3_carry_in_internal2"
1933  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1934	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1935			    (reg:GPR CA_REGNO))
1936		  (match_operand:GPR 2 "gpc_reg_operand" "r")))
1937   (clobber (reg:GPR CA_REGNO))]
1938  ""
1939  "adde %0,%1,%2"
1940  [(set_attr "type" "add")])
1941
1942(define_insn "add<mode>3_carry_in_0"
1943  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1944	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1945		  (reg:GPR CA_REGNO)))
1946   (clobber (reg:GPR CA_REGNO))]
1947  ""
1948  "addze %0,%1"
1949  [(set_attr "type" "add")])
1950
1951(define_insn "add<mode>3_carry_in_m1"
1952  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1953	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1954			    (reg:GPR CA_REGNO))
1955		  (const_int -1)))
1956   (clobber (reg:GPR CA_REGNO))]
1957  ""
1958  "addme %0,%1"
1959  [(set_attr "type" "add")])
1960
1961
1962(define_expand "one_cmpl<mode>2"
1963  [(set (match_operand:SDI 0 "gpc_reg_operand")
1964	(not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1965  ""
1966{
1967  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1968    {
1969      rs6000_split_logical (operands, NOT, false, false, false);
1970      DONE;
1971    }
1972})
1973
1974(define_insn "*one_cmpl<mode>2"
1975  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1976	(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1977  ""
1978  "not %0,%1")
1979
1980(define_insn_and_split "*one_cmpl<mode>2_dot"
1981  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1982	(compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1983		    (const_int 0)))
1984   (clobber (match_scratch:GPR 0 "=r,r"))]
1985  "<MODE>mode == Pmode"
1986  "@
1987   not. %0,%1
1988   #"
1989  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1990  [(set (match_dup 0)
1991	(not:GPR (match_dup 1)))
1992   (set (match_dup 2)
1993	(compare:CC (match_dup 0)
1994		    (const_int 0)))]
1995  ""
1996  [(set_attr "type" "logical")
1997   (set_attr "dot" "yes")
1998   (set_attr "length" "4,8")])
1999
2000(define_insn_and_split "*one_cmpl<mode>2_dot2"
2001  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2002	(compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2003		    (const_int 0)))
2004   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2005	(not:GPR (match_dup 1)))]
2006  "<MODE>mode == Pmode"
2007  "@
2008   not. %0,%1
2009   #"
2010  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2011  [(set (match_dup 0)
2012	(not:GPR (match_dup 1)))
2013   (set (match_dup 2)
2014	(compare:CC (match_dup 0)
2015		    (const_int 0)))]
2016  ""
2017  [(set_attr "type" "logical")
2018   (set_attr "dot" "yes")
2019   (set_attr "length" "4,8")])
2020
2021
2022(define_expand "sub<mode>3"
2023  [(set (match_operand:SDI 0 "gpc_reg_operand")
2024	(minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2025		   (match_operand:SDI 2 "gpc_reg_operand")))]
2026  ""
2027{
2028  if (<MODE>mode == DImode && !TARGET_POWERPC64)
2029    {
2030      rtx lo0 = gen_lowpart (SImode, operands[0]);
2031      rtx lo1 = gen_lowpart (SImode, operands[1]);
2032      rtx lo2 = gen_lowpart (SImode, operands[2]);
2033      rtx hi0 = gen_highpart (SImode, operands[0]);
2034      rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2035      rtx hi2 = gen_highpart (SImode, operands[2]);
2036
2037      if (!reg_or_short_operand (lo1, SImode))
2038	lo1 = force_reg (SImode, lo1);
2039      if (!adde_operand (hi1, SImode))
2040	hi1 = force_reg (SImode, hi1);
2041
2042      emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2043      emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2044      DONE;
2045    }
2046
2047  if (short_cint_operand (operands[1], <MODE>mode))
2048    {
2049      emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2050      DONE;
2051    }
2052})
2053
2054(define_insn "*subf<mode>3"
2055  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2056	(minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2057		   (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2058  ""
2059  "subf %0,%1,%2"
2060  [(set_attr "type" "add")])
2061
2062(define_insn_and_split "*subf<mode>3_dot"
2063  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2064	(compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2065			       (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2066		    (const_int 0)))
2067   (clobber (match_scratch:GPR 0 "=r,r"))]
2068  "<MODE>mode == Pmode"
2069  "@
2070   subf. %0,%1,%2
2071   #"
2072  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2073  [(set (match_dup 0)
2074	(minus:GPR (match_dup 2)
2075		   (match_dup 1)))
2076   (set (match_dup 3)
2077	(compare:CC (match_dup 0)
2078		    (const_int 0)))]
2079  ""
2080  [(set_attr "type" "add")
2081   (set_attr "dot" "yes")
2082   (set_attr "length" "4,8")])
2083
2084(define_insn_and_split "*subf<mode>3_dot2"
2085  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2086	(compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2087			       (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2088		    (const_int 0)))
2089   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2090	(minus:GPR (match_dup 2)
2091		   (match_dup 1)))]
2092  "<MODE>mode == Pmode"
2093  "@
2094   subf. %0,%1,%2
2095   #"
2096  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2097  [(set (match_dup 0)
2098	(minus:GPR (match_dup 2)
2099		   (match_dup 1)))
2100   (set (match_dup 3)
2101	(compare:CC (match_dup 0)
2102		    (const_int 0)))]
2103  ""
2104  [(set_attr "type" "add")
2105   (set_attr "dot" "yes")
2106   (set_attr "length" "4,8")])
2107
2108(define_insn "subf<mode>3_imm"
2109  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2110	(minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2111		   (match_operand:GPR 1 "gpc_reg_operand" "r")))
2112   (clobber (reg:GPR CA_REGNO))]
2113  ""
2114  "subfic %0,%1,%2"
2115  [(set_attr "type" "add")])
2116
2117(define_insn_and_split "subf<mode>3_carry_dot2"
2118  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2119	(compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2120			       (match_operand:P 1 "gpc_reg_operand" "r,r"))
2121		    (const_int 0)))
2122   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2123	(minus:P (match_dup 2)
2124		   (match_dup 1)))
2125   (set (reg:P CA_REGNO)
2126	(leu:P (match_dup 1)
2127	       (match_dup 2)))]
2128  "<MODE>mode == Pmode"
2129  "@
2130   subfc. %0,%1,%2
2131   #"
2132  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2133  [(parallel [(set (match_dup 0)
2134                   (minus:P (match_dup 2)
2135                            (match_dup 1)))
2136              (set (reg:P CA_REGNO)
2137                   (leu:P (match_dup 1)
2138                          (match_dup 2)))])
2139   (set (match_dup 3)
2140        (compare:CC (match_dup 0)
2141                    (const_int 0)))]
2142  ""
2143  [(set_attr "type" "add")
2144   (set_attr "dot" "yes")
2145   (set_attr "length" "4,8")])
2146
2147(define_insn "subf<mode>3_carry"
2148  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2149	(minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2150		 (match_operand:P 1 "gpc_reg_operand" "r")))
2151   (set (reg:P CA_REGNO)
2152	(leu:P (match_dup 1)
2153	       (match_dup 2)))]
2154  ""
2155  "subf%I2c %0,%1,%2"
2156  [(set_attr "type" "add")])
2157
2158(define_insn "*subf<mode>3_imm_carry_0"
2159  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2160	(neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2161   (set (reg:P CA_REGNO)
2162	(eq:P (match_dup 1)
2163	      (const_int 0)))]
2164  ""
2165  "subfic %0,%1,0"
2166  [(set_attr "type" "add")])
2167
2168(define_insn "*subf<mode>3_imm_carry_m1"
2169  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2170	(not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2171   (set (reg:P CA_REGNO)
2172	(const_int 1))]
2173  ""
2174  "subfic %0,%1,-1"
2175  [(set_attr "type" "add")])
2176
2177
2178(define_expand "subf<mode>3_carry_in"
2179  [(parallel [
2180     (set (match_operand:GPR 0 "gpc_reg_operand")
2181	  (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2182			      (reg:GPR CA_REGNO))
2183		    (match_operand:GPR 2 "adde_operand")))
2184     (clobber (reg:GPR CA_REGNO))])]
2185  ""
2186{
2187  if (operands[2] == const0_rtx)
2188    {
2189      emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2190      DONE;
2191    }
2192  if (operands[2] == constm1_rtx)
2193    {
2194      emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2195      DONE;
2196    }
2197})
2198
2199(define_insn "*subf<mode>3_carry_in_internal"
2200  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2201	(plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2202			    (reg:GPR CA_REGNO))
2203		  (match_operand:GPR 2 "gpc_reg_operand" "r")))
2204   (clobber (reg:GPR CA_REGNO))]
2205  ""
2206  "subfe %0,%1,%2"
2207  [(set_attr "type" "add")])
2208
2209(define_insn "subf<mode>3_carry_in_0"
2210  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2211	(plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2212		  (reg:GPR CA_REGNO)))
2213   (clobber (reg:GPR CA_REGNO))]
2214  ""
2215  "subfze %0,%1"
2216  [(set_attr "type" "add")])
2217
2218(define_insn "subf<mode>3_carry_in_m1"
2219  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2220	(plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2221			     (match_operand:GPR 1 "gpc_reg_operand" "r"))
2222		  (const_int -2)))
2223   (clobber (reg:GPR CA_REGNO))]
2224  ""
2225  "subfme %0,%1"
2226  [(set_attr "type" "add")])
2227
2228(define_insn "subf<mode>3_carry_in_xx"
2229  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2230	(plus:GPR (reg:GPR CA_REGNO)
2231		  (const_int -1)))
2232   (clobber (reg:GPR CA_REGNO))]
2233  ""
2234  "subfe %0,%0,%0"
2235  [(set_attr "type" "add")])
2236
2237
2238(define_insn "neg<mode>2"
2239  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2240	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2241  ""
2242  "neg %0,%1"
2243  [(set_attr "type" "add")])
2244
2245(define_insn_and_split "*neg<mode>2_dot"
2246  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2247	(compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2248		    (const_int 0)))
2249   (clobber (match_scratch:GPR 0 "=r,r"))]
2250  "<MODE>mode == Pmode"
2251  "@
2252   neg. %0,%1
2253   #"
2254  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2255  [(set (match_dup 0)
2256	(neg:GPR (match_dup 1)))
2257   (set (match_dup 2)
2258	(compare:CC (match_dup 0)
2259		    (const_int 0)))]
2260  ""
2261  [(set_attr "type" "add")
2262   (set_attr "dot" "yes")
2263   (set_attr "length" "4,8")])
2264
2265(define_insn_and_split "*neg<mode>2_dot2"
2266  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2267	(compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2268		    (const_int 0)))
2269   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2270	(neg:GPR (match_dup 1)))]
2271  "<MODE>mode == Pmode"
2272  "@
2273   neg. %0,%1
2274   #"
2275  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2276  [(set (match_dup 0)
2277	(neg:GPR (match_dup 1)))
2278   (set (match_dup 2)
2279	(compare:CC (match_dup 0)
2280		    (const_int 0)))]
2281  ""
2282  [(set_attr "type" "add")
2283   (set_attr "dot" "yes")
2284   (set_attr "length" "4,8")])
2285
2286
2287(define_insn "clz<mode>2"
2288  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2289	(clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2290  ""
2291  "cntlz<wd> %0,%1"
2292  [(set_attr "type" "cntlz")])
2293
2294(define_expand "ctz<mode>2"
2295   [(set (match_operand:GPR 0 "gpc_reg_operand")
2296	 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2297  ""
2298{
2299  if (TARGET_CTZ)
2300    {
2301      emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2302      DONE;
2303    }
2304
2305  rtx tmp1 = gen_reg_rtx (<MODE>mode);
2306  rtx tmp2 = gen_reg_rtx (<MODE>mode);
2307  rtx tmp3 = gen_reg_rtx (<MODE>mode);
2308
2309  if (TARGET_POPCNTD)
2310    {
2311      emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2312      emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2313      emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2314      emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2315    }
2316  else
2317    {
2318      emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2319      emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2320      emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2321      emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2322    }
2323
2324  DONE;
2325})
2326
2327(define_insn "ctz<mode>2_hw"
2328  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2329	(ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2330  "TARGET_CTZ"
2331  "cnttz<wd> %0,%1"
2332  [(set_attr "type" "cntlz")])
2333
2334(define_expand "ffs<mode>2"
2335  [(set (match_operand:GPR 0 "gpc_reg_operand")
2336	(ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2337  ""
2338{
2339  rtx tmp1 = gen_reg_rtx (<MODE>mode);
2340  rtx tmp2 = gen_reg_rtx (<MODE>mode);
2341  rtx tmp3 = gen_reg_rtx (<MODE>mode);
2342  emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2343  emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2344  emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2345  emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2346  DONE;
2347})
2348
2349
2350(define_expand "popcount<mode>2"
2351  [(set (match_operand:GPR 0 "gpc_reg_operand")
2352	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2353  "TARGET_POPCNTB || TARGET_POPCNTD"
2354{
2355  rs6000_emit_popcount (operands[0], operands[1]);
2356  DONE;
2357})
2358
2359(define_insn "popcntb<mode>2"
2360  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2361	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2362		    UNSPEC_POPCNTB))]
2363  "TARGET_POPCNTB"
2364  "popcntb %0,%1"
2365  [(set_attr "type" "popcnt")])
2366
2367(define_insn "popcntd<mode>2"
2368  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2369	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2370  "TARGET_POPCNTD"
2371  "popcnt<wd> %0,%1"
2372  [(set_attr "type" "popcnt")])
2373
2374
2375(define_expand "parity<mode>2"
2376  [(set (match_operand:GPR 0 "gpc_reg_operand")
2377	(parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2378  "TARGET_POPCNTB"
2379{
2380  rs6000_emit_parity (operands[0], operands[1]);
2381  DONE;
2382})
2383
2384(define_insn "parity<mode>2_cmpb"
2385  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2386	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2387  "TARGET_CMPB && TARGET_POPCNTB"
2388  "prty<wd> %0,%1"
2389  [(set_attr "type" "popcnt")])
2390
2391(define_insn "cmpb<mode>3"
2392  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2393	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2394		     (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2395  "TARGET_CMPB"
2396  "cmpb %0,%1,%2"
2397  [(set_attr "type" "cmp")])
2398
2399;; Since the hardware zeros the upper part of the register, save generating the
2400;; AND immediate if we are converting to unsigned
2401(define_insn "*bswap<mode>2_extenddi"
2402  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2403	(zero_extend:DI
2404	 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2405  "TARGET_POWERPC64"
2406  "l<wd>brx %0,%y1"
2407  [(set_attr "length" "4")
2408   (set_attr "type" "load")])
2409
2410(define_insn "*bswaphi2_extendsi"
2411  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2412	(zero_extend:SI
2413	 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2414  ""
2415  "lhbrx %0,%y1"
2416  [(set_attr "length" "4")
2417   (set_attr "type" "load")])
2418
2419;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2420;; the register allocator from converting a gpr<-gpr swap into a store and then
2421;; load with byte swap, which can be slower than doing it in the registers.  It
2422;; also prevents certain failures with the RELOAD register allocator.
2423
2424(define_expand "bswap<mode>2"
2425  [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2426   (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2427  ""
2428{
2429  rtx dest = operands[0];
2430  rtx src = operands[1];
2431
2432  if (!REG_P (dest) && !REG_P (src))
2433    src = force_reg (<MODE>mode, src);
2434
2435  if (MEM_P (src))
2436    emit_insn (gen_bswap<mode>2_load (dest, src));
2437  else if (MEM_P (dest))
2438    emit_insn (gen_bswap<mode>2_store (dest, src));
2439  else
2440    emit_insn (gen_bswap<mode>2_reg (dest, src));
2441  DONE;
2442})
2443
2444(define_insn "bswap<mode>2_load"
2445  [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2446	(bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2447  ""
2448  "l<wd>brx %0,%y1"
2449  [(set_attr "type" "load")])
2450
2451(define_insn "bswap<mode>2_store"
2452  [(set (match_operand:HSI 0 "memory_operand" "=Z")
2453	(bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2454  ""
2455  "st<wd>brx %1,%y0"
2456  [(set_attr "type" "store")])
2457
2458(define_insn_and_split "bswaphi2_reg"
2459  [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2460	(bswap:HI
2461	 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2462   (clobber (match_scratch:SI 2 "=&r,X"))]
2463  ""
2464  "@
2465   #
2466   xxbrh %x0,%x1"
2467  "reload_completed && int_reg_operand (operands[0], HImode)"
2468  [(set (match_dup 3)
2469	(and:SI (lshiftrt:SI (match_dup 4)
2470			     (const_int 8))
2471		(const_int 255)))
2472   (set (match_dup 2)
2473	(and:SI (ashift:SI (match_dup 4)
2474			   (const_int 8))
2475		(const_int 65280)))		;; 0xff00
2476   (set (match_dup 3)
2477	(ior:SI (match_dup 3)
2478		(match_dup 2)))]
2479{
2480  operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2481  operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2482}
2483  [(set_attr "length" "12,4")
2484   (set_attr "type" "*,vecperm")])
2485
2486;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2487;; zero_extract insns do not change for -mlittle.
2488(define_insn_and_split "bswapsi2_reg"
2489  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2490	(bswap:SI
2491	 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2492  ""
2493  "@
2494   #
2495   xxbrw %x0,%x1"
2496  "reload_completed && int_reg_operand (operands[0], SImode)"
2497  [(set (match_dup 0)					; DABC
2498	(rotate:SI (match_dup 1)
2499		   (const_int 24)))
2500   (set (match_dup 0)					; DCBC
2501	(ior:SI (and:SI (ashift:SI (match_dup 1)
2502				   (const_int 8))
2503			(const_int 16711680))
2504		(and:SI (match_dup 0)
2505			(const_int -16711681))))
2506   (set (match_dup 0)					; DCBA
2507	(ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2508				     (const_int 24))
2509			(const_int 255))
2510		(and:SI (match_dup 0)
2511			(const_int -256))))]
2512  ""
2513  [(set_attr "length" "12,4")
2514   (set_attr "type" "*,vecperm")])
2515
2516;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2517;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2518;; complex code.
2519
2520(define_expand "bswapdi2"
2521  [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2522		   (bswap:DI
2523		    (match_operand:DI 1 "reg_or_mem_operand")))
2524	      (clobber (match_scratch:DI 2))
2525	      (clobber (match_scratch:DI 3))])]
2526  ""
2527{
2528  rtx dest = operands[0];
2529  rtx src = operands[1];
2530
2531  if (!REG_P (dest) && !REG_P (src))
2532    operands[1] = src = force_reg (DImode, src);
2533
2534  if (TARGET_POWERPC64 && TARGET_LDBRX)
2535    {
2536      if (MEM_P (src))
2537	emit_insn (gen_bswapdi2_load (dest, src));
2538      else if (MEM_P (dest))
2539	emit_insn (gen_bswapdi2_store (dest, src));
2540      else if (TARGET_P9_VECTOR)
2541	emit_insn (gen_bswapdi2_xxbrd (dest, src));
2542      else
2543	emit_insn (gen_bswapdi2_reg (dest, src));
2544      DONE;
2545    }
2546
2547  if (!TARGET_POWERPC64)
2548    {
2549      /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2550	 that uses 64-bit registers needs the same scratch registers as 64-bit
2551	 mode.  */
2552      emit_insn (gen_bswapdi2_32bit (dest, src));
2553      DONE;
2554    }
2555})
2556
2557;; Power7/cell has ldbrx/stdbrx, so use it directly
2558(define_insn "bswapdi2_load"
2559  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2560	(bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2561  "TARGET_POWERPC64 && TARGET_LDBRX"
2562  "ldbrx %0,%y1"
2563  [(set_attr "type" "load")])
2564
2565(define_insn "bswapdi2_store"
2566  [(set (match_operand:DI 0 "memory_operand" "=Z")
2567	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2568  "TARGET_POWERPC64 && TARGET_LDBRX"
2569  "stdbrx %1,%y0"
2570  [(set_attr "type" "store")])
2571
2572(define_insn "bswapdi2_xxbrd"
2573  [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2574	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2575  "TARGET_P9_VECTOR"
2576  "xxbrd %x0,%x1"
2577  [(set_attr "type" "vecperm")])
2578
2579(define_insn "bswapdi2_reg"
2580  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2581	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2582   (clobber (match_scratch:DI 2 "=&r"))
2583   (clobber (match_scratch:DI 3 "=&r"))]
2584  "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2585  "#"
2586  [(set_attr "length" "36")])
2587
2588;; Non-power7/cell, fall back to use lwbrx/stwbrx
2589(define_insn "*bswapdi2_64bit"
2590  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2591	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2592   (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2593   (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2594  "TARGET_POWERPC64 && !TARGET_LDBRX
2595   && (REG_P (operands[0]) || REG_P (operands[1]))
2596   && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2597   && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2598  "#"
2599  [(set_attr "length" "16,12,36")])
2600
2601(define_split
2602  [(set (match_operand:DI 0 "gpc_reg_operand")
2603	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2604   (clobber (match_operand:DI 2 "gpc_reg_operand"))
2605   (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2606  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2607  [(const_int 0)]
2608{
2609  rtx dest   = operands[0];
2610  rtx src    = operands[1];
2611  rtx op2    = operands[2];
2612  rtx op3    = operands[3];
2613  rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2614				    BYTES_BIG_ENDIAN ? 4 : 0);
2615  rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2616				     BYTES_BIG_ENDIAN ? 4 : 0);
2617  rtx addr1;
2618  rtx addr2;
2619  rtx word1;
2620  rtx word2;
2621
2622  addr1 = XEXP (src, 0);
2623  if (GET_CODE (addr1) == PLUS)
2624    {
2625      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2626      if (TARGET_AVOID_XFORM)
2627	{
2628	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2629	  addr2 = op2;
2630	}
2631      else
2632	addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2633    }
2634  else if (TARGET_AVOID_XFORM)
2635    {
2636      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2637      addr2 = op2;
2638    }
2639  else
2640    {
2641      emit_move_insn (op2, GEN_INT (4));
2642      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2643    }
2644
2645  word1 = change_address (src, SImode, addr1);
2646  word2 = change_address (src, SImode, addr2);
2647
2648  if (BYTES_BIG_ENDIAN)
2649    {
2650      emit_insn (gen_bswapsi2 (op3_32, word2));
2651      emit_insn (gen_bswapsi2 (dest_32, word1));
2652    }
2653  else
2654    {
2655      emit_insn (gen_bswapsi2 (op3_32, word1));
2656      emit_insn (gen_bswapsi2 (dest_32, word2));
2657    }
2658
2659  emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2660  emit_insn (gen_iordi3 (dest, dest, op3));
2661  DONE;
2662})
2663
2664(define_split
2665  [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2666	(bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2667   (clobber (match_operand:DI 2 "gpc_reg_operand"))
2668   (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2669  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2670  [(const_int 0)]
2671{
2672  rtx dest   = operands[0];
2673  rtx src    = operands[1];
2674  rtx op2    = operands[2];
2675  rtx op3    = operands[3];
2676  rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2677				    BYTES_BIG_ENDIAN ? 4 : 0);
2678  rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2679				    BYTES_BIG_ENDIAN ? 4 : 0);
2680  rtx addr1;
2681  rtx addr2;
2682  rtx word1;
2683  rtx word2;
2684
2685  addr1 = XEXP (dest, 0);
2686  if (GET_CODE (addr1) == PLUS)
2687    {
2688      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2689      if (TARGET_AVOID_XFORM)
2690	{
2691	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2692	  addr2 = op2;
2693	}
2694      else
2695	addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2696    }
2697  else if (TARGET_AVOID_XFORM)
2698    {
2699      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2700      addr2 = op2;
2701    }
2702  else
2703    {
2704      emit_move_insn (op2, GEN_INT (4));
2705      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2706    }
2707
2708  word1 = change_address (dest, SImode, addr1);
2709  word2 = change_address (dest, SImode, addr2);
2710
2711  emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2712
2713  if (BYTES_BIG_ENDIAN)
2714    {
2715      emit_insn (gen_bswapsi2 (word1, src_si));
2716      emit_insn (gen_bswapsi2 (word2, op3_si));
2717    }
2718  else
2719    {
2720      emit_insn (gen_bswapsi2 (word2, src_si));
2721      emit_insn (gen_bswapsi2 (word1, op3_si));
2722    }
2723  DONE;
2724})
2725
2726(define_split
2727  [(set (match_operand:DI 0 "gpc_reg_operand")
2728	(bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2729   (clobber (match_operand:DI 2 "gpc_reg_operand"))
2730   (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2731  "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2732  [(const_int 0)]
2733{
2734  rtx dest    = operands[0];
2735  rtx src     = operands[1];
2736  rtx op2     = operands[2];
2737  rtx op3     = operands[3];
2738  int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2739  rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2740  rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2741  rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2742  rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2743
2744  emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2745  emit_insn (gen_bswapsi2 (dest_si, src_si));
2746  emit_insn (gen_bswapsi2 (op3_si, op2_si));
2747  emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2748  emit_insn (gen_iordi3 (dest, dest, op3));
2749  DONE;
2750})
2751
2752(define_insn "bswapdi2_32bit"
2753  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2754	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2755   (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2756  "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2757  "#"
2758  [(set_attr "length" "16,12,36")])
2759
2760(define_split
2761  [(set (match_operand:DI 0 "gpc_reg_operand")
2762	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2763   (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2764  "!TARGET_POWERPC64 && reload_completed"
2765  [(const_int 0)]
2766{
2767  rtx dest  = operands[0];
2768  rtx src   = operands[1];
2769  rtx op2   = operands[2];
2770  rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2771  rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2772  rtx addr1;
2773  rtx addr2;
2774  rtx word1;
2775  rtx word2;
2776
2777  addr1 = XEXP (src, 0);
2778  if (GET_CODE (addr1) == PLUS)
2779    {
2780      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2781      if (TARGET_AVOID_XFORM
2782	  || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
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	   || REGNO (addr1) == REGNO (dest2))
2792    {
2793      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2794      addr2 = op2;
2795    }
2796  else
2797    {
2798      emit_move_insn (op2, GEN_INT (4));
2799      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2800    }
2801
2802  word1 = change_address (src, SImode, addr1);
2803  word2 = change_address (src, SImode, addr2);
2804
2805  emit_insn (gen_bswapsi2 (dest2, word1));
2806  /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2807     thus allowing us to omit an early clobber on the output.  */
2808  emit_insn (gen_bswapsi2 (dest1, word2));
2809  DONE;
2810})
2811
2812(define_split
2813  [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2814	(bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2815   (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2816  "!TARGET_POWERPC64 && reload_completed"
2817  [(const_int 0)]
2818{
2819  rtx dest = operands[0];
2820  rtx src  = operands[1];
2821  rtx op2  = operands[2];
2822  rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2823  rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2824  rtx addr1;
2825  rtx addr2;
2826  rtx word1;
2827  rtx word2;
2828
2829  addr1 = XEXP (dest, 0);
2830  if (GET_CODE (addr1) == PLUS)
2831    {
2832      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2833      if (TARGET_AVOID_XFORM)
2834	{
2835	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2836	  addr2 = op2;
2837	}
2838      else
2839	addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2840    }
2841  else if (TARGET_AVOID_XFORM)
2842    {
2843      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2844      addr2 = op2;
2845    }
2846  else
2847    {
2848      emit_move_insn (op2, GEN_INT (4));
2849      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2850    }
2851
2852  word1 = change_address (dest, SImode, addr1);
2853  word2 = change_address (dest, SImode, addr2);
2854
2855  emit_insn (gen_bswapsi2 (word2, src1));
2856  emit_insn (gen_bswapsi2 (word1, src2));
2857  DONE;
2858})
2859
2860(define_split
2861  [(set (match_operand:DI 0 "gpc_reg_operand")
2862	(bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2863   (clobber (match_operand:SI 2 ""))]
2864  "!TARGET_POWERPC64 && reload_completed"
2865  [(const_int 0)]
2866{
2867  rtx dest  = operands[0];
2868  rtx src   = operands[1];
2869  rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2870  rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2871  rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2872  rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2873
2874  emit_insn (gen_bswapsi2 (dest1, src2));
2875  emit_insn (gen_bswapsi2 (dest2, src1));
2876  DONE;
2877})
2878
2879
2880(define_insn "mul<mode>3"
2881  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2882	(mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2883		  (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2884  ""
2885  "@
2886   mull<wd> %0,%1,%2
2887   mulli %0,%1,%2"
2888   [(set_attr "type" "mul")
2889    (set (attr "size")
2890      (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2891		(const_string "8")
2892             (match_operand:GPR 2 "short_cint_operand")
2893		(const_string "16")]
2894	(const_string "<bits>")))])
2895
2896(define_insn_and_split "*mul<mode>3_dot"
2897  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2898	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2899			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2900		    (const_int 0)))
2901   (clobber (match_scratch:GPR 0 "=r,r"))]
2902  "<MODE>mode == Pmode"
2903  "@
2904   mull<wd>. %0,%1,%2
2905   #"
2906  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2907  [(set (match_dup 0)
2908	(mult:GPR (match_dup 1)
2909		  (match_dup 2)))
2910   (set (match_dup 3)
2911	(compare:CC (match_dup 0)
2912		    (const_int 0)))]
2913  ""
2914  [(set_attr "type" "mul")
2915   (set_attr "size" "<bits>")
2916   (set_attr "dot" "yes")
2917   (set_attr "length" "4,8")])
2918
2919(define_insn_and_split "*mul<mode>3_dot2"
2920  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2921	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2922			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2923		    (const_int 0)))
2924   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2925	(mult:GPR (match_dup 1)
2926		  (match_dup 2)))]
2927  "<MODE>mode == Pmode"
2928  "@
2929   mull<wd>. %0,%1,%2
2930   #"
2931  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2932  [(set (match_dup 0)
2933	(mult:GPR (match_dup 1)
2934		  (match_dup 2)))
2935   (set (match_dup 3)
2936	(compare:CC (match_dup 0)
2937		    (const_int 0)))]
2938  ""
2939  [(set_attr "type" "mul")
2940   (set_attr "size" "<bits>")
2941   (set_attr "dot" "yes")
2942   (set_attr "length" "4,8")])
2943
2944
2945(define_expand "<su>mul<mode>3_highpart"
2946  [(set (match_operand:GPR 0 "gpc_reg_operand")
2947	(subreg:GPR
2948	  (mult:<DMODE> (any_extend:<DMODE>
2949			  (match_operand:GPR 1 "gpc_reg_operand"))
2950			(any_extend:<DMODE>
2951			  (match_operand:GPR 2 "gpc_reg_operand")))
2952	 0))]
2953  ""
2954{
2955  if (<MODE>mode == SImode && TARGET_POWERPC64)
2956    {
2957      emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2958					     operands[2]));
2959      DONE;
2960    }
2961
2962  if (!WORDS_BIG_ENDIAN)
2963    {
2964      emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2965						 operands[2]));
2966      DONE;
2967    }
2968})
2969
2970(define_insn "*<su>mul<mode>3_highpart"
2971  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2972	(subreg:GPR
2973	  (mult:<DMODE> (any_extend:<DMODE>
2974			  (match_operand:GPR 1 "gpc_reg_operand" "r"))
2975			(any_extend:<DMODE>
2976			  (match_operand:GPR 2 "gpc_reg_operand" "r")))
2977	 0))]
2978  "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2979  "mulh<wd><u> %0,%1,%2"
2980  [(set_attr "type" "mul")
2981   (set_attr "size" "<bits>")])
2982
2983(define_insn "<su>mulsi3_highpart_le"
2984  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2985	(subreg:SI
2986	  (mult:DI (any_extend:DI
2987		     (match_operand:SI 1 "gpc_reg_operand" "r"))
2988		   (any_extend:DI
2989		     (match_operand:SI 2 "gpc_reg_operand" "r")))
2990	 4))]
2991  "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2992  "mulhw<u> %0,%1,%2"
2993  [(set_attr "type" "mul")])
2994
2995(define_insn "<su>muldi3_highpart_le"
2996  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2997	(subreg:DI
2998	  (mult:TI (any_extend:TI
2999		     (match_operand:DI 1 "gpc_reg_operand" "r"))
3000		   (any_extend:TI
3001		     (match_operand:DI 2 "gpc_reg_operand" "r")))
3002	 8))]
3003  "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3004  "mulhd<u> %0,%1,%2"
3005  [(set_attr "type" "mul")
3006   (set_attr "size" "64")])
3007
3008(define_insn "<su>mulsi3_highpart_64"
3009  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3010	(truncate:SI
3011	  (lshiftrt:DI
3012	    (mult:DI (any_extend:DI
3013		       (match_operand:SI 1 "gpc_reg_operand" "r"))
3014		     (any_extend:DI
3015		       (match_operand:SI 2 "gpc_reg_operand" "r")))
3016	    (const_int 32))))]
3017  "TARGET_POWERPC64"
3018  "mulhw<u> %0,%1,%2"
3019  [(set_attr "type" "mul")])
3020
3021(define_expand "<u>mul<mode><dmode>3"
3022  [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3023	(mult:<DMODE> (any_extend:<DMODE>
3024			(match_operand:GPR 1 "gpc_reg_operand"))
3025		      (any_extend:<DMODE>
3026			(match_operand:GPR 2 "gpc_reg_operand"))))]
3027  "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3028{
3029  rtx l = gen_reg_rtx (<MODE>mode);
3030  rtx h = gen_reg_rtx (<MODE>mode);
3031  emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3032  emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3033  emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3034  emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3035  DONE;
3036})
3037
3038(define_insn "*maddld4"
3039  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3040	(plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3041			  (match_operand:DI 2 "gpc_reg_operand" "r"))
3042		 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3043  "TARGET_MADDLD"
3044  "maddld %0,%1,%2,%3"
3045  [(set_attr "type" "mul")])
3046
3047(define_insn "udiv<mode>3"
3048  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3049        (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3050		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3051  ""
3052  "div<wd>u %0,%1,%2"
3053  [(set_attr "type" "div")
3054   (set_attr "size" "<bits>")])
3055
3056
3057;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3058;; modulus.  If it isn't a power of two, force operands into register and do
3059;; a normal divide.
3060(define_expand "div<mode>3"
3061  [(set (match_operand:GPR 0 "gpc_reg_operand")
3062	(div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3063		 (match_operand:GPR 2 "reg_or_cint_operand")))]
3064  ""
3065{
3066  if (CONST_INT_P (operands[2])
3067      && INTVAL (operands[2]) > 0
3068      && exact_log2 (INTVAL (operands[2])) >= 0)
3069    {
3070      emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3071      DONE;
3072    }
3073
3074  operands[2] = force_reg (<MODE>mode, operands[2]);
3075})
3076
3077(define_insn "*div<mode>3"
3078  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3079        (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3080		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3081  ""
3082  "div<wd> %0,%1,%2"
3083  [(set_attr "type" "div")
3084   (set_attr "size" "<bits>")])
3085
3086(define_insn "div<mode>3_sra"
3087  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3088	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3089		 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3090   (clobber (reg:GPR CA_REGNO))]
3091  ""
3092  "sra<wd>i %0,%1,%p2\;addze %0,%0"
3093  [(set_attr "type" "two")
3094   (set_attr "length" "8")])
3095
3096(define_insn_and_split "*div<mode>3_sra_dot"
3097  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3098	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3099			     (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3100		    (const_int 0)))
3101   (clobber (match_scratch:GPR 0 "=r,r"))
3102   (clobber (reg:GPR CA_REGNO))]
3103  "<MODE>mode == Pmode"
3104  "@
3105   sra<wd>i %0,%1,%p2\;addze. %0,%0
3106   #"
3107  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3108  [(parallel [(set (match_dup 0)
3109		   (div:GPR (match_dup 1)
3110			    (match_dup 2)))
3111	      (clobber (reg:GPR CA_REGNO))])
3112   (set (match_dup 3)
3113	(compare:CC (match_dup 0)
3114		    (const_int 0)))]
3115  ""
3116  [(set_attr "type" "two")
3117   (set_attr "length" "8,12")
3118   (set_attr "cell_micro" "not")])
3119
3120(define_insn_and_split "*div<mode>3_sra_dot2"
3121  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3122	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3123			     (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3124		    (const_int 0)))
3125   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3126	(div:GPR (match_dup 1)
3127		 (match_dup 2)))
3128   (clobber (reg:GPR CA_REGNO))]
3129  "<MODE>mode == Pmode"
3130  "@
3131   sra<wd>i %0,%1,%p2\;addze. %0,%0
3132   #"
3133  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3134  [(parallel [(set (match_dup 0)
3135		   (div:GPR (match_dup 1)
3136			    (match_dup 2)))
3137	      (clobber (reg:GPR CA_REGNO))])
3138   (set (match_dup 3)
3139	(compare:CC (match_dup 0)
3140		    (const_int 0)))]
3141  ""
3142  [(set_attr "type" "two")
3143   (set_attr "length" "8,12")
3144   (set_attr "cell_micro" "not")])
3145
3146(define_expand "mod<mode>3"
3147  [(set (match_operand:GPR 0 "gpc_reg_operand")
3148	(mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3149		 (match_operand:GPR 2 "reg_or_cint_operand")))]
3150  ""
3151{
3152  int i;
3153  rtx temp1;
3154  rtx temp2;
3155
3156  if (GET_CODE (operands[2]) != CONST_INT
3157      || INTVAL (operands[2]) <= 0
3158      || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3159    {
3160      if (!TARGET_MODULO)
3161	FAIL;
3162
3163      operands[2] = force_reg (<MODE>mode, operands[2]);
3164    }
3165  else
3166    {
3167      temp1 = gen_reg_rtx (<MODE>mode);
3168      temp2 = gen_reg_rtx (<MODE>mode);
3169
3170      emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3171      emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3172      emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3173      DONE;
3174    }
3175})
3176
3177;; In order to enable using a peephole2 for combining div/mod to eliminate the
3178;; mod, prefer putting the result of mod into a different register
3179(define_insn "*mod<mode>3"
3180  [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3181        (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3182		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3183  "TARGET_MODULO"
3184  "mods<wd> %0,%1,%2"
3185  [(set_attr "type" "div")
3186   (set_attr "size" "<bits>")])
3187
3188
3189(define_insn "umod<mode>3"
3190  [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3191        (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3192		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3193  "TARGET_MODULO"
3194  "modu<wd> %0,%1,%2"
3195  [(set_attr "type" "div")
3196   (set_attr "size" "<bits>")])
3197
3198;; On machines with modulo support, do a combined div/mod the old fashioned
3199;; method, since the multiply/subtract is faster than doing the mod instruction
3200;; after a divide.
3201
3202(define_peephole2
3203  [(set (match_operand:GPR 0 "gpc_reg_operand")
3204	(div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3205		 (match_operand:GPR 2 "gpc_reg_operand")))
3206   (set (match_operand:GPR 3 "gpc_reg_operand")
3207	(mod:GPR (match_dup 1)
3208		 (match_dup 2)))]
3209  "TARGET_MODULO
3210   && ! reg_mentioned_p (operands[0], operands[1])
3211   && ! reg_mentioned_p (operands[0], operands[2])
3212   && ! reg_mentioned_p (operands[3], operands[1])
3213   && ! reg_mentioned_p (operands[3], operands[2])"
3214  [(set (match_dup 0)
3215	(div:GPR (match_dup 1)
3216		 (match_dup 2)))
3217   (set (match_dup 3)
3218	(mult:GPR (match_dup 0)
3219		  (match_dup 2)))
3220   (set (match_dup 3)
3221	(minus:GPR (match_dup 1)
3222		   (match_dup 3)))])
3223
3224(define_peephole2
3225  [(set (match_operand:GPR 0 "gpc_reg_operand")
3226	(udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3227		  (match_operand:GPR 2 "gpc_reg_operand")))
3228   (set (match_operand:GPR 3 "gpc_reg_operand")
3229	(umod:GPR (match_dup 1)
3230		  (match_dup 2)))]
3231  "TARGET_MODULO
3232   && ! reg_mentioned_p (operands[0], operands[1])
3233   && ! reg_mentioned_p (operands[0], operands[2])
3234   && ! reg_mentioned_p (operands[3], operands[1])
3235   && ! reg_mentioned_p (operands[3], operands[2])"
3236  [(set (match_dup 0)
3237	(udiv:GPR (match_dup 1)
3238		  (match_dup 2)))
3239   (set (match_dup 3)
3240	(mult:GPR (match_dup 0)
3241		  (match_dup 2)))
3242   (set (match_dup 3)
3243	(minus:GPR (match_dup 1)
3244		   (match_dup 3)))])
3245
3246
3247;; Logical instructions
3248;; The logical instructions are mostly combined by using match_operator,
3249;; but the plain AND insns are somewhat different because there is no
3250;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3251;; those rotate-and-mask operations.  Thus, the AND insns come first.
3252
3253(define_expand "and<mode>3"
3254  [(set (match_operand:SDI 0 "gpc_reg_operand")
3255	(and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3256		 (match_operand:SDI 2 "reg_or_cint_operand")))]
3257  ""
3258{
3259  if (<MODE>mode == DImode && !TARGET_POWERPC64)
3260    {
3261      rs6000_split_logical (operands, AND, false, false, false);
3262      DONE;
3263    }
3264
3265  if (CONST_INT_P (operands[2]))
3266    {
3267      if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3268	{
3269	  emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3270	  DONE;
3271	}
3272
3273      if (logical_const_operand (operands[2], <MODE>mode))
3274	{
3275	  emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3276	  DONE;
3277	}
3278
3279      if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3280	{
3281	  rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3282	  DONE;
3283	}
3284
3285      operands[2] = force_reg (<MODE>mode, operands[2]);
3286    }
3287})
3288
3289
3290(define_insn "and<mode>3_imm"
3291  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3292	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3293		 (match_operand:GPR 2 "logical_const_operand" "n")))
3294   (clobber (match_scratch:CC 3 "=x"))]
3295  "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3296  "andi%e2. %0,%1,%u2"
3297  [(set_attr "type" "logical")
3298   (set_attr "dot" "yes")])
3299
3300(define_insn_and_split "*and<mode>3_imm_dot"
3301  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3302	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3303			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3304		    (const_int 0)))
3305   (clobber (match_scratch:GPR 0 "=r,r"))
3306   (clobber (match_scratch:CC 4 "=X,x"))]
3307  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3308   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3309  "@
3310   andi%e2. %0,%1,%u2
3311   #"
3312  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3313  [(parallel [(set (match_dup 0)
3314		   (and:GPR (match_dup 1)
3315			    (match_dup 2)))
3316	      (clobber (match_dup 4))])
3317   (set (match_dup 3)
3318	(compare:CC (match_dup 0)
3319		    (const_int 0)))]
3320  ""
3321  [(set_attr "type" "logical")
3322   (set_attr "dot" "yes")
3323   (set_attr "length" "4,8")])
3324
3325(define_insn_and_split "*and<mode>3_imm_dot2"
3326  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3327	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3328			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3329		    (const_int 0)))
3330   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3331	(and:GPR (match_dup 1)
3332		 (match_dup 2)))
3333   (clobber (match_scratch:CC 4 "=X,x"))]
3334  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3335   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3336  "@
3337   andi%e2. %0,%1,%u2
3338   #"
3339  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3340  [(parallel [(set (match_dup 0)
3341		   (and:GPR (match_dup 1)
3342			    (match_dup 2)))
3343	      (clobber (match_dup 4))])
3344   (set (match_dup 3)
3345	(compare:CC (match_dup 0)
3346		    (const_int 0)))]
3347  ""
3348  [(set_attr "type" "logical")
3349   (set_attr "dot" "yes")
3350   (set_attr "length" "4,8")])
3351
3352(define_insn_and_split "*and<mode>3_imm_mask_dot"
3353  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3354	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3355			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3356		    (const_int 0)))
3357   (clobber (match_scratch:GPR 0 "=r,r"))]
3358  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3359   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3360  "@
3361   andi%e2. %0,%1,%u2
3362   #"
3363  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3364  [(set (match_dup 0)
3365	(and:GPR (match_dup 1)
3366		 (match_dup 2)))
3367   (set (match_dup 3)
3368	(compare:CC (match_dup 0)
3369		    (const_int 0)))]
3370  ""
3371  [(set_attr "type" "logical")
3372   (set_attr "dot" "yes")
3373   (set_attr "length" "4,8")])
3374
3375(define_insn_and_split "*and<mode>3_imm_mask_dot2"
3376  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3377	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3378			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3379		    (const_int 0)))
3380   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3381	(and:GPR (match_dup 1)
3382		 (match_dup 2)))]
3383  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3384   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3385  "@
3386   andi%e2. %0,%1,%u2
3387   #"
3388  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3389  [(set (match_dup 0)
3390	(and:GPR (match_dup 1)
3391		 (match_dup 2)))
3392   (set (match_dup 3)
3393	(compare:CC (match_dup 0)
3394		    (const_int 0)))]
3395  ""
3396  [(set_attr "type" "logical")
3397   (set_attr "dot" "yes")
3398   (set_attr "length" "4,8")])
3399
3400(define_insn "*and<mode>3_imm_dot_shifted"
3401  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3402	(compare:CC
3403	  (and:GPR
3404	    (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3405			  (match_operand:SI 4 "const_int_operand" "n"))
3406	    (match_operand:GPR 2 "const_int_operand" "n"))
3407	  (const_int 0)))
3408   (clobber (match_scratch:GPR 0 "=r"))]
3409  "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3410				   << INTVAL (operands[4])),
3411			  DImode)
3412   && (<MODE>mode == Pmode
3413       || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3414{
3415  operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3416  return "andi%e2. %0,%1,%u2";
3417}
3418  [(set_attr "type" "logical")
3419   (set_attr "dot" "yes")])
3420
3421
3422(define_insn "and<mode>3_mask"
3423  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3424	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3425		 (match_operand:GPR 2 "const_int_operand" "n")))]
3426  "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3427{
3428  return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3429}
3430  [(set_attr "type" "shift")])
3431
3432(define_insn_and_split "*and<mode>3_mask_dot"
3433  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3434	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3435			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3436		    (const_int 0)))
3437   (clobber (match_scratch:GPR 0 "=r,r"))]
3438  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3439   && !logical_const_operand (operands[2], <MODE>mode)
3440   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3441{
3442  if (which_alternative == 0)
3443    return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3444  else
3445    return "#";
3446}
3447  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3448  [(set (match_dup 0)
3449	(and:GPR (match_dup 1)
3450		 (match_dup 2)))
3451   (set (match_dup 3)
3452	(compare:CC (match_dup 0)
3453		    (const_int 0)))]
3454  ""
3455  [(set_attr "type" "shift")
3456   (set_attr "dot" "yes")
3457   (set_attr "length" "4,8")])
3458
3459(define_insn_and_split "*and<mode>3_mask_dot2"
3460  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3461	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3462			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3463		    (const_int 0)))
3464   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3465	(and:GPR (match_dup 1)
3466		 (match_dup 2)))]
3467  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3468   && !logical_const_operand (operands[2], <MODE>mode)
3469   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3470{
3471  if (which_alternative == 0)
3472    return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3473  else
3474    return "#";
3475}
3476  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3477  [(set (match_dup 0)
3478	(and:GPR (match_dup 1)
3479		 (match_dup 2)))
3480   (set (match_dup 3)
3481	(compare:CC (match_dup 0)
3482		    (const_int 0)))]
3483  ""
3484  [(set_attr "type" "shift")
3485   (set_attr "dot" "yes")
3486   (set_attr "length" "4,8")])
3487
3488
3489(define_insn_and_split "*and<mode>3_2insn"
3490  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3491	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3492		 (match_operand:GPR 2 "const_int_operand" "n")))]
3493  "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3494   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3495	|| logical_const_operand (operands[2], <MODE>mode))"
3496  "#"
3497  "&& 1"
3498  [(pc)]
3499{
3500  rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3501  DONE;
3502}
3503  [(set_attr "type" "shift")
3504   (set_attr "length" "8")])
3505
3506(define_insn_and_split "*and<mode>3_2insn_dot"
3507  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3508	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3509			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3510		    (const_int 0)))
3511   (clobber (match_scratch:GPR 0 "=r,r"))]
3512  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3513   && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3514   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3515	|| logical_const_operand (operands[2], <MODE>mode))"
3516  "#"
3517  "&& reload_completed"
3518  [(pc)]
3519{
3520  rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3521  DONE;
3522}
3523  [(set_attr "type" "shift")
3524   (set_attr "dot" "yes")
3525   (set_attr "length" "8,12")])
3526
3527(define_insn_and_split "*and<mode>3_2insn_dot2"
3528  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3529	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3530			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3531		    (const_int 0)))
3532   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3533	(and:GPR (match_dup 1)
3534		 (match_dup 2)))]
3535  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3536   && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3537   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3538	|| logical_const_operand (operands[2], <MODE>mode))"
3539  "#"
3540  "&& reload_completed"
3541  [(pc)]
3542{
3543  rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3544  DONE;
3545}
3546  [(set_attr "type" "shift")
3547   (set_attr "dot" "yes")
3548   (set_attr "length" "8,12")])
3549
3550
3551(define_expand "<code><mode>3"
3552  [(set (match_operand:SDI 0 "gpc_reg_operand")
3553	(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3554		    (match_operand:SDI 2 "reg_or_cint_operand")))]
3555  ""
3556{
3557  if (<MODE>mode == DImode && !TARGET_POWERPC64)
3558    {
3559      rs6000_split_logical (operands, <CODE>, false, false, false);
3560      DONE;
3561    }
3562
3563  if (non_logical_cint_operand (operands[2], <MODE>mode))
3564    {
3565      rtx tmp = ((!can_create_pseudo_p ()
3566		  || rtx_equal_p (operands[0], operands[1]))
3567		 ? operands[0] : gen_reg_rtx (<MODE>mode));
3568
3569      HOST_WIDE_INT value = INTVAL (operands[2]);
3570      HOST_WIDE_INT lo = value & 0xffff;
3571      HOST_WIDE_INT hi = value - lo;
3572
3573      emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3574      emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3575      DONE;
3576    }
3577
3578  if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3579    operands[2] = force_reg (<MODE>mode, operands[2]);
3580})
3581
3582(define_split
3583  [(set (match_operand:GPR 0 "gpc_reg_operand")
3584	(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3585		    (match_operand:GPR 2 "non_logical_cint_operand")))]
3586  ""
3587  [(set (match_dup 3)
3588	(iorxor:GPR (match_dup 1)
3589		    (match_dup 4)))
3590   (set (match_dup 0)
3591	(iorxor:GPR (match_dup 3)
3592		    (match_dup 5)))]
3593{
3594  operands[3] = ((!can_create_pseudo_p ()
3595		  || rtx_equal_p (operands[0], operands[1]))
3596		 ? operands[0] : gen_reg_rtx (<MODE>mode));
3597
3598  HOST_WIDE_INT value = INTVAL (operands[2]);
3599  HOST_WIDE_INT lo = value & 0xffff;
3600  HOST_WIDE_INT hi = value - lo;
3601
3602  operands[4] = GEN_INT (hi);
3603  operands[5] = GEN_INT (lo);
3604})
3605
3606(define_insn "*bool<mode>3_imm"
3607  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3608	(match_operator:GPR 3 "boolean_or_operator"
3609	 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3610	  (match_operand:GPR 2 "logical_const_operand" "n")]))]
3611  ""
3612  "%q3i%e2 %0,%1,%u2"
3613  [(set_attr "type" "logical")])
3614
3615(define_insn "*bool<mode>3"
3616  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3617	(match_operator:GPR 3 "boolean_operator"
3618	 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3619	  (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3620  ""
3621  "%q3 %0,%1,%2"
3622  [(set_attr "type" "logical")])
3623
3624(define_insn_and_split "*bool<mode>3_dot"
3625  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3626	(compare:CC (match_operator:GPR 3 "boolean_operator"
3627	 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3628	  (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3629	 (const_int 0)))
3630   (clobber (match_scratch:GPR 0 "=r,r"))]
3631  "<MODE>mode == Pmode"
3632  "@
3633   %q3. %0,%1,%2
3634   #"
3635  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3636  [(set (match_dup 0)
3637	(match_dup 3))
3638   (set (match_dup 4)
3639	(compare:CC (match_dup 0)
3640		    (const_int 0)))]
3641  ""
3642  [(set_attr "type" "logical")
3643   (set_attr "dot" "yes")
3644   (set_attr "length" "4,8")])
3645
3646(define_insn_and_split "*bool<mode>3_dot2"
3647  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3648	(compare:CC (match_operator:GPR 3 "boolean_operator"
3649	 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3650	  (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3651	 (const_int 0)))
3652   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3653	(match_dup 3))]
3654  "<MODE>mode == Pmode"
3655  "@
3656   %q3. %0,%1,%2
3657   #"
3658  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3659  [(set (match_dup 0)
3660	(match_dup 3))
3661   (set (match_dup 4)
3662	(compare:CC (match_dup 0)
3663		    (const_int 0)))]
3664  ""
3665  [(set_attr "type" "logical")
3666   (set_attr "dot" "yes")
3667   (set_attr "length" "4,8")])
3668
3669
3670(define_insn "*boolc<mode>3"
3671  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3672	(match_operator:GPR 3 "boolean_operator"
3673	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3674	  (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3675  ""
3676  "%q3 %0,%1,%2"
3677  [(set_attr "type" "logical")])
3678
3679(define_insn_and_split "*boolc<mode>3_dot"
3680  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3681	(compare:CC (match_operator:GPR 3 "boolean_operator"
3682	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3683	  (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3684	 (const_int 0)))
3685   (clobber (match_scratch:GPR 0 "=r,r"))]
3686  "<MODE>mode == Pmode"
3687  "@
3688   %q3. %0,%1,%2
3689   #"
3690  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3691  [(set (match_dup 0)
3692	(match_dup 3))
3693   (set (match_dup 4)
3694	(compare:CC (match_dup 0)
3695		    (const_int 0)))]
3696  ""
3697  [(set_attr "type" "logical")
3698   (set_attr "dot" "yes")
3699   (set_attr "length" "4,8")])
3700
3701(define_insn_and_split "*boolc<mode>3_dot2"
3702  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3703	(compare:CC (match_operator:GPR 3 "boolean_operator"
3704	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3705	  (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3706	 (const_int 0)))
3707   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3708	(match_dup 3))]
3709  "<MODE>mode == Pmode"
3710  "@
3711   %q3. %0,%1,%2
3712   #"
3713  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3714  [(set (match_dup 0)
3715	(match_dup 3))
3716   (set (match_dup 4)
3717	(compare:CC (match_dup 0)
3718		    (const_int 0)))]
3719  ""
3720  [(set_attr "type" "logical")
3721   (set_attr "dot" "yes")
3722   (set_attr "length" "4,8")])
3723
3724
3725(define_insn "*boolcc<mode>3"
3726  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3727	(match_operator:GPR 3 "boolean_operator"
3728	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3729	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3730  ""
3731  "%q3 %0,%1,%2"
3732  [(set_attr "type" "logical")])
3733
3734(define_insn_and_split "*boolcc<mode>3_dot"
3735  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3736	(compare:CC (match_operator:GPR 3 "boolean_operator"
3737	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3738	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3739	 (const_int 0)))
3740   (clobber (match_scratch:GPR 0 "=r,r"))]
3741  "<MODE>mode == Pmode"
3742  "@
3743   %q3. %0,%1,%2
3744   #"
3745  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3746  [(set (match_dup 0)
3747	(match_dup 3))
3748   (set (match_dup 4)
3749	(compare:CC (match_dup 0)
3750		    (const_int 0)))]
3751  ""
3752  [(set_attr "type" "logical")
3753   (set_attr "dot" "yes")
3754   (set_attr "length" "4,8")])
3755
3756(define_insn_and_split "*boolcc<mode>3_dot2"
3757  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3758	(compare:CC (match_operator:GPR 3 "boolean_operator"
3759	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3760	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3761	 (const_int 0)))
3762   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3763	(match_dup 3))]
3764  "<MODE>mode == Pmode"
3765  "@
3766   %q3. %0,%1,%2
3767   #"
3768  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3769  [(set (match_dup 0)
3770	(match_dup 3))
3771   (set (match_dup 4)
3772	(compare:CC (match_dup 0)
3773		    (const_int 0)))]
3774  ""
3775  [(set_attr "type" "logical")
3776   (set_attr "dot" "yes")
3777   (set_attr "length" "4,8")])
3778
3779
3780;; TODO: Should have dots of this as well.
3781(define_insn "*eqv<mode>3"
3782  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3783	(not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3784			  (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3785  ""
3786  "eqv %0,%1,%2"
3787  [(set_attr "type" "logical")])
3788
3789;; Rotate-and-mask and insert.
3790
3791(define_insn "*rotl<mode>3_mask"
3792  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3793	(and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3794		  [(match_operand:GPR 1 "gpc_reg_operand" "r")
3795		   (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3796		 (match_operand:GPR 3 "const_int_operand" "n")))]
3797  "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3798{
3799  return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3800}
3801  [(set_attr "type" "shift")
3802   (set_attr "maybe_var_shift" "yes")])
3803
3804(define_insn_and_split "*rotl<mode>3_mask_dot"
3805  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3806	(compare:CC
3807	  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3808		    [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3809		     (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3810		   (match_operand:GPR 3 "const_int_operand" "n,n"))
3811	  (const_int 0)))
3812   (clobber (match_scratch:GPR 0 "=r,r"))]
3813  "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3814   && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3815{
3816  if (which_alternative == 0)
3817    return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3818  else
3819    return "#";
3820}
3821  "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3822  [(set (match_dup 0)
3823	(and:GPR (match_dup 4)
3824		 (match_dup 3)))
3825   (set (match_dup 5)
3826	(compare:CC (match_dup 0)
3827		    (const_int 0)))]
3828  ""
3829  [(set_attr "type" "shift")
3830   (set_attr "maybe_var_shift" "yes")
3831   (set_attr "dot" "yes")
3832   (set_attr "length" "4,8")])
3833
3834(define_insn_and_split "*rotl<mode>3_mask_dot2"
3835  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3836	(compare:CC
3837	  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3838		    [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3839		     (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3840		   (match_operand:GPR 3 "const_int_operand" "n,n"))
3841	  (const_int 0)))
3842   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3843	(and:GPR (match_dup 4)
3844		 (match_dup 3)))]
3845  "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3846   && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3847{
3848  if (which_alternative == 0)
3849    return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3850  else
3851    return "#";
3852}
3853  "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3854  [(set (match_dup 0)
3855	(and:GPR (match_dup 4)
3856		 (match_dup 3)))
3857   (set (match_dup 5)
3858	(compare:CC (match_dup 0)
3859		    (const_int 0)))]
3860  ""
3861  [(set_attr "type" "shift")
3862   (set_attr "maybe_var_shift" "yes")
3863   (set_attr "dot" "yes")
3864   (set_attr "length" "4,8")])
3865
3866; Special case for less-than-0.  We can do it with just one machine
3867; instruction, but the generic optimizers do not realise it is cheap.
3868(define_insn "*lt0_<mode>di"
3869  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3870	(lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3871		(const_int 0)))]
3872  "TARGET_POWERPC64"
3873  "srdi %0,%1,63"
3874  [(set_attr "type" "shift")])
3875
3876(define_insn "*lt0_<mode>si"
3877  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3878	(lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3879		(const_int 0)))]
3880  ""
3881  "rlwinm %0,%1,1,31,31"
3882  [(set_attr "type" "shift")])
3883
3884
3885
3886; Two forms for insert (the two arms of the IOR are not canonicalized,
3887; both are an AND so are the same precedence).
3888(define_insn "*rotl<mode>3_insert"
3889  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3890	(ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3891			   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3892			    (match_operand:SI 2 "const_int_operand" "n")])
3893			  (match_operand:GPR 3 "const_int_operand" "n"))
3894		 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3895			  (match_operand:GPR 6 "const_int_operand" "n"))))]
3896  "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3897   && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3898{
3899  return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3900}
3901  [(set_attr "type" "insert")])
3902; FIXME: this needs an attr "size", so that the scheduler can see the
3903; difference between rlwimi and rldimi.  We also might want dot forms,
3904; but not for rlwimi on POWER4 and similar processors.
3905
3906(define_insn "*rotl<mode>3_insert_2"
3907  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3908	(ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3909			  (match_operand:GPR 6 "const_int_operand" "n"))
3910		 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3911			   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3912			    (match_operand:SI 2 "const_int_operand" "n")])
3913			  (match_operand:GPR 3 "const_int_operand" "n"))))]
3914  "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3915   && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3916{
3917  return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3918}
3919  [(set_attr "type" "insert")])
3920
3921; There are also some forms without one of the ANDs.
3922(define_insn "*rotl<mode>3_insert_3"
3923  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3924	(ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3925			  (match_operand:GPR 4 "const_int_operand" "n"))
3926		 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3927			     (match_operand:SI 2 "const_int_operand" "n"))))]
3928  "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3929{
3930  if (<MODE>mode == SImode)
3931    return "rlwimi %0,%1,%h2,0,31-%h2";
3932  else
3933    return "rldimi %0,%1,%H2,0";
3934}
3935  [(set_attr "type" "insert")])
3936
3937(define_insn "*rotl<mode>3_insert_4"
3938  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3939	(ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3940			  (match_operand:GPR 4 "const_int_operand" "n"))
3941		 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3942			       (match_operand:SI 2 "const_int_operand" "n"))))]
3943  "<MODE>mode == SImode &&
3944   GET_MODE_PRECISION (<MODE>mode)
3945   == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3946{
3947  operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3948			 - INTVAL (operands[2]));
3949  if (<MODE>mode == SImode)
3950    return "rlwimi %0,%1,%h2,32-%h2,31";
3951  else
3952    return "rldimi %0,%1,%H2,64-%H2";
3953}
3954  [(set_attr "type" "insert")])
3955
3956(define_insn "*rotlsi3_insert_5"
3957  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3958	(ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3959			(match_operand:SI 2 "const_int_operand" "n,n"))
3960		(and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3961			(match_operand:SI 4 "const_int_operand" "n,n"))))]
3962  "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3963   && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3964   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3965  "@
3966   rlwimi %0,%3,0,%4
3967   rlwimi %0,%1,0,%2"
3968  [(set_attr "type" "insert")])
3969
3970(define_insn "*rotldi3_insert_6"
3971  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3972	(ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3973			(match_operand:DI 2 "const_int_operand" "n"))
3974		(and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3975			(match_operand:DI 4 "const_int_operand" "n"))))]
3976  "exact_log2 (-UINTVAL (operands[2])) > 0
3977   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3978{
3979  operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3980  return "rldimi %0,%3,0,%5";
3981}
3982  [(set_attr "type" "insert")
3983   (set_attr "size" "64")])
3984
3985(define_insn "*rotldi3_insert_7"
3986  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3987	(ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3988			(match_operand:DI 4 "const_int_operand" "n"))
3989		(and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3990			(match_operand:DI 2 "const_int_operand" "n"))))]
3991  "exact_log2 (-UINTVAL (operands[2])) > 0
3992   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3993{
3994  operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3995  return "rldimi %0,%3,0,%5";
3996}
3997  [(set_attr "type" "insert")
3998   (set_attr "size" "64")])
3999
4000
4001; This handles the important case of multiple-precision shifts.  There is
4002; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4003(define_split
4004  [(set (match_operand:GPR 0 "gpc_reg_operand")
4005	(ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4006			     (match_operand:SI 3 "const_int_operand"))
4007		 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4008			       (match_operand:SI 4 "const_int_operand"))))]
4009  "can_create_pseudo_p ()
4010   && INTVAL (operands[3]) + INTVAL (operands[4])
4011      >= GET_MODE_PRECISION (<MODE>mode)"
4012  [(set (match_dup 5)
4013	(lshiftrt:GPR (match_dup 2)
4014		      (match_dup 4)))
4015   (set (match_dup 0)
4016	(ior:GPR (and:GPR (match_dup 5)
4017			  (match_dup 6))
4018		 (ashift:GPR (match_dup 1)
4019			     (match_dup 3))))]
4020{
4021  unsigned HOST_WIDE_INT mask = 1;
4022  mask = (mask << INTVAL (operands[3])) - 1;
4023  operands[5] = gen_reg_rtx (<MODE>mode);
4024  operands[6] = GEN_INT (mask);
4025})
4026
4027(define_split
4028  [(set (match_operand:GPR 0 "gpc_reg_operand")
4029	(ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4030			       (match_operand:SI 4 "const_int_operand"))
4031		 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4032			     (match_operand:SI 3 "const_int_operand"))))]
4033  "can_create_pseudo_p ()
4034   && INTVAL (operands[3]) + INTVAL (operands[4])
4035      >= GET_MODE_PRECISION (<MODE>mode)"
4036  [(set (match_dup 5)
4037	(lshiftrt:GPR (match_dup 2)
4038		      (match_dup 4)))
4039   (set (match_dup 0)
4040	(ior:GPR (and:GPR (match_dup 5)
4041			  (match_dup 6))
4042		 (ashift:GPR (match_dup 1)
4043			     (match_dup 3))))]
4044{
4045  unsigned HOST_WIDE_INT mask = 1;
4046  mask = (mask << INTVAL (operands[3])) - 1;
4047  operands[5] = gen_reg_rtx (<MODE>mode);
4048  operands[6] = GEN_INT (mask);
4049})
4050
4051
4052; Another important case is setting some bits to 1; we can do that with
4053; an insert instruction, in many cases.
4054(define_insn_and_split "*ior<mode>_mask"
4055  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4056	(ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4057		 (match_operand:GPR 2 "const_int_operand" "n")))
4058   (clobber (match_scratch:GPR 3 "=r"))]
4059  "!logical_const_operand (operands[2], <MODE>mode)
4060   && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4061  "#"
4062  "&& 1"
4063  [(set (match_dup 3)
4064	(const_int -1))
4065   (set (match_dup 0)
4066	(ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4067				      (match_dup 4))
4068			  (match_dup 2))
4069		 (and:GPR (match_dup 1)
4070			  (match_dup 5))))]
4071{
4072  int nb, ne;
4073  rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4074  if (GET_CODE (operands[3]) == SCRATCH)
4075    operands[3] = gen_reg_rtx (<MODE>mode);
4076  operands[4] = GEN_INT (ne);
4077  operands[5] = GEN_INT (~UINTVAL (operands[2]));
4078}
4079  [(set_attr "type" "two")
4080   (set_attr "length" "8")])
4081
4082
4083;; Now the simple shifts.
4084
4085(define_insn "rotl<mode>3"
4086  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4087	(rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4088		    (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4089  ""
4090  "rotl<wd>%I2 %0,%1,%<hH>2"
4091  [(set_attr "type" "shift")
4092   (set_attr "maybe_var_shift" "yes")])
4093
4094(define_insn "*rotlsi3_64"
4095  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4096	(zero_extend:DI
4097	    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4098		       (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4099  "TARGET_POWERPC64"
4100  "rotlw%I2 %0,%1,%h2"
4101  [(set_attr "type" "shift")
4102   (set_attr "maybe_var_shift" "yes")])
4103
4104(define_insn_and_split "*rotl<mode>3_dot"
4105  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4106	(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4107				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4108		    (const_int 0)))
4109   (clobber (match_scratch:GPR 0 "=r,r"))]
4110  "<MODE>mode == Pmode"
4111  "@
4112   rotl<wd>%I2. %0,%1,%<hH>2
4113   #"
4114  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4115  [(set (match_dup 0)
4116	(rotate:GPR (match_dup 1)
4117		    (match_dup 2)))
4118   (set (match_dup 3)
4119	(compare:CC (match_dup 0)
4120		    (const_int 0)))]
4121  ""
4122  [(set_attr "type" "shift")
4123   (set_attr "maybe_var_shift" "yes")
4124   (set_attr "dot" "yes")
4125   (set_attr "length" "4,8")])
4126
4127(define_insn_and_split "*rotl<mode>3_dot2"
4128  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4129	(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4130				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4131		    (const_int 0)))
4132   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4133	(rotate:GPR (match_dup 1)
4134		    (match_dup 2)))]
4135  "<MODE>mode == Pmode"
4136  "@
4137   rotl<wd>%I2. %0,%1,%<hH>2
4138   #"
4139  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4140  [(set (match_dup 0)
4141	(rotate:GPR (match_dup 1)
4142		    (match_dup 2)))
4143   (set (match_dup 3)
4144	(compare:CC (match_dup 0)
4145		    (const_int 0)))]
4146  ""
4147  [(set_attr "type" "shift")
4148   (set_attr "maybe_var_shift" "yes")
4149   (set_attr "dot" "yes")
4150   (set_attr "length" "4,8")])
4151
4152
4153(define_insn "ashl<mode>3"
4154  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4155	(ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4156		    (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4157  ""
4158  "sl<wd>%I2 %0,%1,%<hH>2"
4159  [(set_attr "type" "shift")
4160   (set_attr "maybe_var_shift" "yes")])
4161
4162(define_insn "*ashlsi3_64"
4163  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4164	(zero_extend:DI
4165	    (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4166		       (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4167  "TARGET_POWERPC64"
4168  "slw%I2 %0,%1,%h2"
4169  [(set_attr "type" "shift")
4170   (set_attr "maybe_var_shift" "yes")])
4171
4172(define_insn_and_split "*ashl<mode>3_dot"
4173  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4174	(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4175				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4176		    (const_int 0)))
4177   (clobber (match_scratch:GPR 0 "=r,r"))]
4178  "<MODE>mode == Pmode"
4179  "@
4180   sl<wd>%I2. %0,%1,%<hH>2
4181   #"
4182  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4183  [(set (match_dup 0)
4184	(ashift:GPR (match_dup 1)
4185		    (match_dup 2)))
4186   (set (match_dup 3)
4187	(compare:CC (match_dup 0)
4188		    (const_int 0)))]
4189  ""
4190  [(set_attr "type" "shift")
4191   (set_attr "maybe_var_shift" "yes")
4192   (set_attr "dot" "yes")
4193   (set_attr "length" "4,8")])
4194
4195(define_insn_and_split "*ashl<mode>3_dot2"
4196  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4197	(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4198				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4199		    (const_int 0)))
4200   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4201	(ashift:GPR (match_dup 1)
4202		    (match_dup 2)))]
4203  "<MODE>mode == Pmode"
4204  "@
4205   sl<wd>%I2. %0,%1,%<hH>2
4206   #"
4207  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4208  [(set (match_dup 0)
4209	(ashift:GPR (match_dup 1)
4210		    (match_dup 2)))
4211   (set (match_dup 3)
4212	(compare:CC (match_dup 0)
4213		    (const_int 0)))]
4214  ""
4215  [(set_attr "type" "shift")
4216   (set_attr "maybe_var_shift" "yes")
4217   (set_attr "dot" "yes")
4218   (set_attr "length" "4,8")])
4219
4220;; Pretend we have a memory form of extswsli until register allocation is done
4221;; so that we use LWZ to load the value from memory, instead of LWA.
4222(define_insn_and_split "ashdi3_extswsli"
4223  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4224	(ashift:DI
4225	 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4226	 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4227  "TARGET_EXTSWSLI"
4228  "@
4229   extswsli %0,%1,%2
4230   #"
4231  "&& reload_completed && MEM_P (operands[1])"
4232  [(set (match_dup 3)
4233	(match_dup 1))
4234   (set (match_dup 0)
4235	(ashift:DI (sign_extend:DI (match_dup 3))
4236		   (match_dup 2)))]
4237{
4238  operands[3] = gen_lowpart (SImode, operands[0]);
4239}
4240  [(set_attr "type" "shift")
4241   (set_attr "maybe_var_shift" "no")])
4242
4243
4244(define_insn_and_split "ashdi3_extswsli_dot"
4245  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4246	(compare:CC
4247	 (ashift:DI
4248	  (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4249	  (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4250	 (const_int 0)))
4251   (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4252  "TARGET_EXTSWSLI"
4253  "@
4254   extswsli. %0,%1,%2
4255   #
4256   #
4257   #"
4258  "&& reload_completed
4259   && (cc_reg_not_cr0_operand (operands[3], CCmode)
4260       || memory_operand (operands[1], SImode))"
4261  [(pc)]
4262{
4263  rtx dest = operands[0];
4264  rtx src = operands[1];
4265  rtx shift = operands[2];
4266  rtx cr = operands[3];
4267  rtx src2;
4268
4269  if (!MEM_P (src))
4270    src2 = src;
4271  else
4272    {
4273      src2 = gen_lowpart (SImode, dest);
4274      emit_move_insn (src2, src);
4275    }
4276
4277  if (REGNO (cr) == CR0_REGNO)
4278    {
4279      emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4280      DONE;
4281    }
4282
4283  emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4284  emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4285  DONE;
4286}
4287  [(set_attr "type" "shift")
4288   (set_attr "maybe_var_shift" "no")
4289   (set_attr "dot" "yes")
4290   (set_attr "length" "4,8,8,12")])
4291
4292(define_insn_and_split "ashdi3_extswsli_dot2"
4293  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4294	(compare:CC
4295	 (ashift:DI
4296	  (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4297	  (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4298	 (const_int 0)))
4299   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4300	(ashift:DI (sign_extend:DI (match_dup 1))
4301		   (match_dup 2)))]
4302  "TARGET_EXTSWSLI"
4303  "@
4304   extswsli. %0,%1,%2
4305   #
4306   #
4307   #"
4308  "&& reload_completed
4309   && (cc_reg_not_cr0_operand (operands[3], CCmode)
4310       || memory_operand (operands[1], SImode))"
4311  [(pc)]
4312{
4313  rtx dest = operands[0];
4314  rtx src = operands[1];
4315  rtx shift = operands[2];
4316  rtx cr = operands[3];
4317  rtx src2;
4318
4319  if (!MEM_P (src))
4320    src2 = src;
4321  else
4322    {
4323      src2 = gen_lowpart (SImode, dest);
4324      emit_move_insn (src2, src);
4325    }
4326
4327  if (REGNO (cr) == CR0_REGNO)
4328    {
4329      emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4330      DONE;
4331    }
4332
4333  emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4334  emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4335  DONE;
4336}
4337  [(set_attr "type" "shift")
4338   (set_attr "maybe_var_shift" "no")
4339   (set_attr "dot" "yes")
4340   (set_attr "length" "4,8,8,12")])
4341
4342(define_insn "lshr<mode>3"
4343  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4344	(lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4345		      (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4346  ""
4347  "sr<wd>%I2 %0,%1,%<hH>2"
4348  [(set_attr "type" "shift")
4349   (set_attr "maybe_var_shift" "yes")])
4350
4351(define_insn "*lshrsi3_64"
4352  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4353	(zero_extend:DI
4354	    (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4355			 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4356  "TARGET_POWERPC64"
4357  "srw%I2 %0,%1,%h2"
4358  [(set_attr "type" "shift")
4359   (set_attr "maybe_var_shift" "yes")])
4360
4361(define_insn_and_split "*lshr<mode>3_dot"
4362  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4363	(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4364				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4365		    (const_int 0)))
4366   (clobber (match_scratch:GPR 0 "=r,r"))]
4367  "<MODE>mode == Pmode"
4368  "@
4369   sr<wd>%I2. %0,%1,%<hH>2
4370   #"
4371  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4372  [(set (match_dup 0)
4373	(lshiftrt:GPR (match_dup 1)
4374		      (match_dup 2)))
4375   (set (match_dup 3)
4376	(compare:CC (match_dup 0)
4377		    (const_int 0)))]
4378  ""
4379  [(set_attr "type" "shift")
4380   (set_attr "maybe_var_shift" "yes")
4381   (set_attr "dot" "yes")
4382   (set_attr "length" "4,8")])
4383
4384(define_insn_and_split "*lshr<mode>3_dot2"
4385  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4386	(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4387				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4388		    (const_int 0)))
4389   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4390	(lshiftrt:GPR (match_dup 1)
4391		      (match_dup 2)))]
4392  "<MODE>mode == Pmode"
4393  "@
4394   sr<wd>%I2. %0,%1,%<hH>2
4395   #"
4396  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4397  [(set (match_dup 0)
4398	(lshiftrt:GPR (match_dup 1)
4399		      (match_dup 2)))
4400   (set (match_dup 3)
4401	(compare:CC (match_dup 0)
4402		    (const_int 0)))]
4403  ""
4404  [(set_attr "type" "shift")
4405   (set_attr "maybe_var_shift" "yes")
4406   (set_attr "dot" "yes")
4407   (set_attr "length" "4,8")])
4408
4409
4410(define_insn "ashr<mode>3"
4411  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4412	(ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4413		      (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4414   (clobber (reg:GPR CA_REGNO))]
4415  ""
4416  "sra<wd>%I2 %0,%1,%<hH>2"
4417  [(set_attr "type" "shift")
4418   (set_attr "maybe_var_shift" "yes")])
4419
4420(define_insn "*ashrsi3_64"
4421  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4422	(sign_extend:DI
4423	    (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4424			 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4425   (clobber (reg:SI CA_REGNO))]
4426  "TARGET_POWERPC64"
4427  "sraw%I2 %0,%1,%h2"
4428  [(set_attr "type" "shift")
4429   (set_attr "maybe_var_shift" "yes")])
4430
4431(define_insn_and_split "*ashr<mode>3_dot"
4432  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4433	(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4434				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4435		    (const_int 0)))
4436   (clobber (match_scratch:GPR 0 "=r,r"))
4437   (clobber (reg:GPR CA_REGNO))]
4438  "<MODE>mode == Pmode"
4439  "@
4440   sra<wd>%I2. %0,%1,%<hH>2
4441   #"
4442  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4443  [(parallel [(set (match_dup 0)
4444		   (ashiftrt:GPR (match_dup 1)
4445				 (match_dup 2)))
4446	      (clobber (reg:GPR CA_REGNO))])
4447   (set (match_dup 3)
4448	(compare:CC (match_dup 0)
4449		    (const_int 0)))]
4450  ""
4451  [(set_attr "type" "shift")
4452   (set_attr "maybe_var_shift" "yes")
4453   (set_attr "dot" "yes")
4454   (set_attr "length" "4,8")])
4455
4456(define_insn_and_split "*ashr<mode>3_dot2"
4457  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4458	(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4459				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4460		    (const_int 0)))
4461   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4462	(ashiftrt:GPR (match_dup 1)
4463		      (match_dup 2)))
4464   (clobber (reg:GPR CA_REGNO))]
4465  "<MODE>mode == Pmode"
4466  "@
4467   sra<wd>%I2. %0,%1,%<hH>2
4468   #"
4469  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4470  [(parallel [(set (match_dup 0)
4471		   (ashiftrt:GPR (match_dup 1)
4472				 (match_dup 2)))
4473	      (clobber (reg:GPR CA_REGNO))])
4474   (set (match_dup 3)
4475	(compare:CC (match_dup 0)
4476		    (const_int 0)))]
4477  ""
4478  [(set_attr "type" "shift")
4479   (set_attr "maybe_var_shift" "yes")
4480   (set_attr "dot" "yes")
4481   (set_attr "length" "4,8")])
4482
4483;; Builtins to replace a division to generate FRE reciprocal estimate
4484;; instructions and the necessary fixup instructions
4485(define_expand "recip<mode>3"
4486  [(match_operand:RECIPF 0 "gpc_reg_operand")
4487   (match_operand:RECIPF 1 "gpc_reg_operand")
4488   (match_operand:RECIPF 2 "gpc_reg_operand")]
4489  "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4490{
4491   rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4492   DONE;
4493})
4494
4495;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4496;; hardware division.  This is only done before register allocation and with
4497;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4498;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4499;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4500(define_split
4501  [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4502	(div:RECIPF (match_operand 1 "gpc_reg_operand")
4503		    (match_operand 2 "gpc_reg_operand")))]
4504  "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4505   && can_create_pseudo_p () && flag_finite_math_only
4506   && !flag_trapping_math && flag_reciprocal_math"
4507  [(const_int 0)]
4508{
4509  rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4510  DONE;
4511})
4512
4513;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4514;; appropriate fixup.
4515(define_expand "rsqrt<mode>2"
4516  [(match_operand:RECIPF 0 "gpc_reg_operand")
4517   (match_operand:RECIPF 1 "gpc_reg_operand")]
4518  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4519{
4520  rs6000_emit_swsqrt (operands[0], operands[1], 1);
4521  DONE;
4522})
4523
4524;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4525;; modes here, and also add in conditional vsx/power8-vector support to access
4526;; values in the traditional Altivec registers if the appropriate
4527;; -mupper-regs-{df,sf} option is enabled.
4528
4529(define_expand "abs<mode>2"
4530  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4531	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4532  "TARGET_<MODE>_INSN"
4533  "")
4534
4535(define_insn "*abs<mode>2_fpr"
4536  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4537	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4538  "TARGET_<MODE>_FPR"
4539  "@
4540   fabs %0,%1
4541   xsabsdp %x0,%x1"
4542  [(set_attr "type" "fpsimple")
4543   (set_attr "fp_type" "fp_addsub_<Fs>")])
4544
4545(define_insn "*nabs<mode>2_fpr"
4546  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4547	(neg:SFDF
4548	 (abs:SFDF
4549	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4550  "TARGET_<MODE>_FPR"
4551  "@
4552   fnabs %0,%1
4553   xsnabsdp %x0,%x1"
4554  [(set_attr "type" "fpsimple")
4555   (set_attr "fp_type" "fp_addsub_<Fs>")])
4556
4557(define_expand "neg<mode>2"
4558  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4559	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4560  "TARGET_<MODE>_INSN"
4561  "")
4562
4563(define_insn "*neg<mode>2_fpr"
4564  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4565	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4566  "TARGET_<MODE>_FPR"
4567  "@
4568   fneg %0,%1
4569   xsnegdp %x0,%x1"
4570  [(set_attr "type" "fpsimple")
4571   (set_attr "fp_type" "fp_addsub_<Fs>")])
4572
4573(define_expand "add<mode>3"
4574  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4575	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4576		   (match_operand:SFDF 2 "gpc_reg_operand")))]
4577  "TARGET_<MODE>_INSN"
4578  "")
4579
4580(define_insn "*add<mode>3_fpr"
4581  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4582	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4583		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4584  "TARGET_<MODE>_FPR"
4585  "@
4586   fadd<Ftrad> %0,%1,%2
4587   xsadd<Fvsx> %x0,%x1,%x2"
4588  [(set_attr "type" "fp")
4589   (set_attr "fp_type" "fp_addsub_<Fs>")])
4590
4591(define_expand "sub<mode>3"
4592  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4593	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4594		    (match_operand:SFDF 2 "gpc_reg_operand")))]
4595  "TARGET_<MODE>_INSN"
4596  "")
4597
4598(define_insn "*sub<mode>3_fpr"
4599  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4600	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4601		    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4602  "TARGET_<MODE>_FPR"
4603  "@
4604   fsub<Ftrad> %0,%1,%2
4605   xssub<Fvsx> %x0,%x1,%x2"
4606  [(set_attr "type" "fp")
4607   (set_attr "fp_type" "fp_addsub_<Fs>")])
4608
4609(define_expand "mul<mode>3"
4610  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4611	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4612		   (match_operand:SFDF 2 "gpc_reg_operand")))]
4613  "TARGET_<MODE>_INSN"
4614  "")
4615
4616(define_insn "*mul<mode>3_fpr"
4617  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4618	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4619		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4620  "TARGET_<MODE>_FPR"
4621  "@
4622   fmul<Ftrad> %0,%1,%2
4623   xsmul<Fvsx> %x0,%x1,%x2"
4624  [(set_attr "type" "dmul")
4625   (set_attr "fp_type" "fp_mul_<Fs>")])
4626
4627(define_expand "div<mode>3"
4628  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4629	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4630		  (match_operand:SFDF 2 "gpc_reg_operand")))]
4631  "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4632{
4633  if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4634      && can_create_pseudo_p () && flag_finite_math_only
4635      && !flag_trapping_math && flag_reciprocal_math)
4636    {
4637      rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4638      DONE;
4639    }
4640})
4641
4642(define_insn "*div<mode>3_fpr"
4643  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4644	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4645		  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4646  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4647  "@
4648   fdiv<Ftrad> %0,%1,%2
4649   xsdiv<Fvsx> %x0,%x1,%x2"
4650  [(set_attr "type" "<Fs>div")
4651   (set_attr "fp_type" "fp_div_<Fs>")])
4652
4653(define_insn "*sqrt<mode>2_internal"
4654  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4655	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4656  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4657   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4658  "@
4659   fsqrt<Ftrad> %0,%1
4660   xssqrt<Fvsx> %x0,%x1"
4661  [(set_attr "type" "<Fs>sqrt")
4662   (set_attr "fp_type" "fp_sqrt_<Fs>")])
4663
4664(define_expand "sqrt<mode>2"
4665  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4666	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4667  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4668   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4669{
4670  if (<MODE>mode == SFmode
4671      && TARGET_RECIP_PRECISION
4672      && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4673      && !optimize_function_for_size_p (cfun)
4674      && flag_finite_math_only && !flag_trapping_math
4675      && flag_unsafe_math_optimizations)
4676    {
4677      rs6000_emit_swsqrt (operands[0], operands[1], 0);
4678      DONE;
4679    }
4680})
4681
4682;; Floating point reciprocal approximation
4683(define_insn "fre<Fs>"
4684  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4685	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4686		     UNSPEC_FRES))]
4687  "TARGET_<FFRE>"
4688  "@
4689   fre<Ftrad> %0,%1
4690   xsre<Fvsx> %x0,%x1"
4691  [(set_attr "type" "fp")])
4692
4693(define_insn "*rsqrt<mode>2"
4694  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4695	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4696		     UNSPEC_RSQRT))]
4697  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4698  "@
4699   frsqrte<Ftrad> %0,%1
4700   xsrsqrte<Fvsx> %x0,%x1"
4701  [(set_attr "type" "fp")])
4702
4703;; Floating point comparisons
4704(define_insn "*cmp<mode>_fpr"
4705  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4706	(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4707		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4708  "TARGET_<MODE>_FPR"
4709  "@
4710   fcmpu %0,%1,%2
4711   xscmpudp %0,%x1,%x2"
4712  [(set_attr "type" "fpcompare")])
4713
4714;; Floating point conversions
4715(define_expand "extendsfdf2"
4716  [(set (match_operand:DF 0 "gpc_reg_operand")
4717	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4718  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4719{
4720  if (HONOR_SNANS (SFmode))
4721    operands[1] = force_reg (SFmode, operands[1]);
4722})
4723
4724(define_insn_and_split "*extendsfdf2_fpr"
4725  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4726	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4727  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4728  "@
4729   #
4730   fmr %0,%1
4731   lfs%U1%X1 %0,%1
4732   #
4733   xscpsgndp %x0,%x1,%x1
4734   lxsspx %x0,%y1
4735   lxssp %0,%1"
4736  "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4737  [(const_int 0)]
4738{
4739  emit_note (NOTE_INSN_DELETED);
4740  DONE;
4741}
4742  [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4743
4744(define_insn "*extendsfdf2_snan"
4745  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4746	(float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4747  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4748  "@
4749   frsp %0,%1
4750   xsrsp %x0,%x1"
4751  [(set_attr "type" "fp")])
4752
4753(define_expand "truncdfsf2"
4754  [(set (match_operand:SF 0 "gpc_reg_operand")
4755	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4756  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4757  "")
4758
4759(define_insn "*truncdfsf2_fpr"
4760  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4761	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4762  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4763  "@
4764   frsp %0,%1
4765   xsrsp %x0,%x1"
4766  [(set_attr "type" "fp")])
4767
4768;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4769;; builtins.c and optabs.c that are not correct for IBM long double
4770;; when little-endian.
4771(define_expand "signbit<mode>2"
4772  [(set (match_dup 2)
4773	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4774   (set (match_dup 3)
4775   	(subreg:DI (match_dup 2) 0))
4776   (set (match_dup 4)
4777   	(match_dup 5))
4778   (set (match_operand:SI 0 "gpc_reg_operand")
4779  	(match_dup 6))]
4780  "TARGET_HARD_FLOAT
4781   && (!FLOAT128_IEEE_P (<MODE>mode)
4782       || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4783{
4784  if (FLOAT128_IEEE_P (<MODE>mode))
4785    {
4786      rtx dest = operands[0];
4787      rtx src = operands[1];
4788      rtx tmp = gen_reg_rtx (DImode);
4789      rtx dest_di = gen_lowpart (DImode, dest);
4790
4791      if (<MODE>mode == KFmode)
4792	emit_insn (gen_signbitkf2_dm (tmp, src));
4793      else if (<MODE>mode == TFmode)
4794	emit_insn (gen_signbittf2_dm (tmp, src));
4795      else
4796	gcc_unreachable ();
4797
4798      emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4799      DONE;
4800    }
4801  operands[2] = gen_reg_rtx (DFmode);
4802  operands[3] = gen_reg_rtx (DImode);
4803  if (TARGET_POWERPC64)
4804    {
4805      operands[4] = gen_reg_rtx (DImode);
4806      operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4807      operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4808				    WORDS_BIG_ENDIAN ? 4 : 0);
4809    }
4810  else
4811    {
4812      operands[4] = gen_reg_rtx (SImode);
4813      operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4814				    WORDS_BIG_ENDIAN ? 0 : 4);
4815      operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4816    }
4817})
4818
4819;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4820;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4821;; register allocator would typically move the entire _Float128 item to GPRs (2
4822;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4823;;
4824;; After register allocation, if the _Float128 had originally been in GPRs, the
4825;; split allows the post reload phases to eliminate the move, and do the shift
4826;; directly with the register that contains the signbit.
4827(define_insn_and_split "signbit<mode>2_dm"
4828  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4829	(unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4830		   UNSPEC_SIGNBIT))]
4831  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4832  "@
4833   mfvsrd %0,%x1
4834   #"
4835  "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4836  [(set (match_dup 0)
4837	(match_dup 2))]
4838{
4839  operands[2] = gen_highpart (DImode, operands[1]);
4840}
4841 [(set_attr "type" "mftgpr,*")])
4842
4843;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4844;; register and then doing a direct move if the value comes from memory.  On
4845;; little endian, we have to load the 2nd double-word to get the sign bit.
4846(define_insn_and_split "*signbit<mode>2_dm_mem"
4847  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4848	(unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4849		   UNSPEC_SIGNBIT))]
4850  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4851  "#"
4852  "&& 1"
4853  [(set (match_dup 0)
4854	(match_dup 2))]
4855{
4856  rtx dest = operands[0];
4857  rtx src = operands[1];
4858  rtx addr = XEXP (src, 0);
4859
4860  if (WORDS_BIG_ENDIAN)
4861    operands[2] = adjust_address (src, DImode, 0);
4862
4863  else if (REG_P (addr) || SUBREG_P (addr))
4864    operands[2] = adjust_address (src, DImode, 8);
4865
4866  else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4867	   && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4868    operands[2] = adjust_address (src, DImode, 8);
4869
4870  else
4871    {
4872      rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4873      emit_insn (gen_rtx_SET (tmp, addr));
4874      operands[2] = change_address (src, DImode,
4875				    gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4876    }
4877})
4878
4879(define_expand "copysign<mode>3"
4880  [(set (match_dup 3)
4881        (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4882   (set (match_dup 4)
4883	(neg:SFDF (abs:SFDF (match_dup 1))))
4884   (set (match_operand:SFDF 0 "gpc_reg_operand")
4885        (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4886			       (match_dup 5))
4887			 (match_dup 3)
4888			 (match_dup 4)))]
4889  "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4890   && ((TARGET_PPC_GFXOPT
4891        && !HONOR_NANS (<MODE>mode)
4892        && !HONOR_SIGNED_ZEROS (<MODE>mode))
4893       || TARGET_CMPB
4894       || VECTOR_UNIT_VSX_P (<MODE>mode))"
4895{
4896  if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4897    {
4898      emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4899					     operands[2]));
4900      DONE;
4901    }
4902
4903   operands[3] = gen_reg_rtx (<MODE>mode);
4904   operands[4] = gen_reg_rtx (<MODE>mode);
4905   operands[5] = CONST0_RTX (<MODE>mode);
4906  })
4907
4908;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4909;; compiler from optimizing -0.0
4910(define_insn "copysign<mode>3_fcpsgn"
4911  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4912	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4913		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4914		     UNSPEC_COPYSIGN))]
4915  "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4916  "@
4917   fcpsgn %0,%2,%1
4918   xscpsgndp %x0,%x2,%x1"
4919  [(set_attr "type" "fpsimple")])
4920
4921;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4922;; fsel instruction and some auxiliary computations.  Then we just have a
4923;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4924;; combine.
4925;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4926;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4927;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4928;; define_splits to make them if made by combine.  On VSX machines we have the
4929;; min/max instructions.
4930;;
4931;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4932;; to allow either DF/SF to use only traditional registers.
4933
4934(define_expand "s<minmax><mode>3"
4935  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4936	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4937			(match_operand:SFDF 2 "gpc_reg_operand")))]
4938  "TARGET_MINMAX_<MODE>"
4939{
4940  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4941  DONE;
4942})
4943
4944(define_insn "*s<minmax><mode>3_vsx"
4945  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4946	(fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4947			(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4948  "TARGET_VSX && TARGET_<MODE>_FPR"
4949{
4950  return (TARGET_P9_MINMAX
4951	  ? "xs<minmax>cdp %x0,%x1,%x2"
4952	  : "xs<minmax>dp %x0,%x1,%x2");
4953}
4954  [(set_attr "type" "fp")])
4955
4956;; The conditional move instructions allow us to perform max and min operations
4957;; even when we don't have the appropriate max/min instruction using the FSEL
4958;; instruction.
4959
4960(define_insn_and_split "*s<minmax><mode>3_fpr"
4961  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4962	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4963			(match_operand:SFDF 2 "gpc_reg_operand")))]
4964  "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4965  "#"
4966  "&& 1"
4967  [(const_int 0)]
4968{
4969  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4970  DONE;
4971})
4972
4973(define_expand "mov<mode>cc"
4974   [(set (match_operand:GPR 0 "gpc_reg_operand")
4975	 (if_then_else:GPR (match_operand 1 "comparison_operator")
4976			   (match_operand:GPR 2 "gpc_reg_operand")
4977			   (match_operand:GPR 3 "gpc_reg_operand")))]
4978  "TARGET_ISEL"
4979{
4980  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4981    DONE;
4982  else
4983    FAIL;
4984})
4985
4986;; We use the BASE_REGS for the isel input operands because, if rA is
4987;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4988;; because we may switch the operands and rB may end up being rA.
4989;;
4990;; We need 2 patterns: an unsigned and a signed pattern.  We could
4991;; leave out the mode in operand 4 and use one pattern, but reload can
4992;; change the mode underneath our feet and then gets confused trying
4993;; to reload the value.
4994(define_insn "isel_signed_<mode>"
4995  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4996	(if_then_else:GPR
4997	 (match_operator 1 "scc_comparison_operator"
4998			 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4999			  (const_int 0)])
5000	 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5001	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5002  "TARGET_ISEL"
5003  "isel %0,%2,%3,%j1"
5004  [(set_attr "type" "isel")])
5005
5006(define_insn "isel_unsigned_<mode>"
5007  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5008	(if_then_else:GPR
5009	 (match_operator 1 "scc_comparison_operator"
5010			 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5011			  (const_int 0)])
5012	 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5013	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5014  "TARGET_ISEL"
5015  "isel %0,%2,%3,%j1"
5016  [(set_attr "type" "isel")])
5017
5018;; These patterns can be useful for combine; they let combine know that
5019;; isel can handle reversed comparisons so long as the operands are
5020;; registers.
5021
5022(define_insn "*isel_reversed_signed_<mode>"
5023  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5024	(if_then_else:GPR
5025	 (match_operator 1 "scc_rev_comparison_operator"
5026			 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5027			  (const_int 0)])
5028	 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5029	 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5030  "TARGET_ISEL"
5031{
5032  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5033  return "isel %0,%3,%2,%j1";
5034}
5035  [(set_attr "type" "isel")])
5036
5037(define_insn "*isel_reversed_unsigned_<mode>"
5038  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5039	(if_then_else:GPR
5040	 (match_operator 1 "scc_rev_comparison_operator"
5041			 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5042			  (const_int 0)])
5043	 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5044	 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5045  "TARGET_ISEL"
5046{
5047  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5048  return "isel %0,%3,%2,%j1";
5049}
5050  [(set_attr "type" "isel")])
5051
5052;; Floating point conditional move
5053(define_expand "mov<mode>cc"
5054   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5055	 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5056			    (match_operand:SFDF 2 "gpc_reg_operand")
5057			    (match_operand:SFDF 3 "gpc_reg_operand")))]
5058  "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5059{
5060  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5061    DONE;
5062  else
5063    FAIL;
5064})
5065
5066(define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5067  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5068	(if_then_else:SFDF
5069	 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5070	     (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5071	 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5072	 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5073  "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5074  "fsel %0,%1,%2,%3"
5075  [(set_attr "type" "fp")])
5076
5077(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5078  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5079	(if_then_else:SFDF
5080	 (match_operator:CCFP 1 "fpmask_comparison_operator"
5081		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5082		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5083	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5084	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5085   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5086  "TARGET_P9_MINMAX"
5087  "#"
5088  ""
5089  [(set (match_dup 6)
5090	(if_then_else:V2DI (match_dup 1)
5091			   (match_dup 7)
5092			   (match_dup 8)))
5093   (set (match_dup 0)
5094	(if_then_else:SFDF (ne (match_dup 6)
5095			       (match_dup 8))
5096			   (match_dup 4)
5097			   (match_dup 5)))]
5098{
5099  if (GET_CODE (operands[6]) == SCRATCH)
5100    operands[6] = gen_reg_rtx (V2DImode);
5101
5102  operands[7] = CONSTM1_RTX (V2DImode);
5103  operands[8] = CONST0_RTX (V2DImode);
5104}
5105 [(set_attr "length" "8")
5106  (set_attr "type" "vecperm")])
5107
5108;; Handle inverting the fpmask comparisons.
5109(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5110  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5111	(if_then_else:SFDF
5112	 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5113		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5114		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5115	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5116	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5117   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5118  "TARGET_P9_MINMAX"
5119  "#"
5120  "&& 1"
5121  [(set (match_dup 6)
5122	(if_then_else:V2DI (match_dup 9)
5123			   (match_dup 7)
5124			   (match_dup 8)))
5125   (set (match_dup 0)
5126	(if_then_else:SFDF (ne (match_dup 6)
5127			       (match_dup 8))
5128			   (match_dup 5)
5129			   (match_dup 4)))]
5130{
5131  rtx op1 = operands[1];
5132  enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5133
5134  if (GET_CODE (operands[6]) == SCRATCH)
5135    operands[6] = gen_reg_rtx (V2DImode);
5136
5137  operands[7] = CONSTM1_RTX (V2DImode);
5138  operands[8] = CONST0_RTX (V2DImode);
5139
5140  operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5141}
5142 [(set_attr "length" "8")
5143  (set_attr "type" "vecperm")])
5144
5145(define_insn "*fpmask<mode>"
5146  [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5147	(if_then_else:V2DI
5148	 (match_operator:CCFP 1 "fpmask_comparison_operator"
5149		[(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5150		 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5151	 (match_operand:V2DI 4 "all_ones_constant" "")
5152	 (match_operand:V2DI 5 "zero_constant" "")))]
5153  "TARGET_P9_MINMAX"
5154  "xscmp%V1dp %x0,%x2,%x3"
5155  [(set_attr "type" "fpcompare")])
5156
5157(define_insn "*xxsel<mode>"
5158  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5159	(if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5160			       (match_operand:V2DI 2 "zero_constant" ""))
5161			   (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5162			   (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5163  "TARGET_P9_MINMAX"
5164  "xxsel %x0,%x4,%x3,%x1"
5165  [(set_attr "type" "vecmove")])
5166
5167
5168;; Conversions to and from floating-point.
5169
5170; We don't define lfiwax/lfiwzx with the normal definition, because we
5171; don't want to support putting SImode in FPR registers.
5172(define_insn "lfiwax"
5173  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5174	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5175		   UNSPEC_LFIWAX))]
5176  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5177  "@
5178   lfiwax %0,%y1
5179   lxsiwax %x0,%y1
5180   mtvsrwa %x0,%1
5181   vextsw2d %0,%1"
5182  [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5183
5184; This split must be run before register allocation because it allocates the
5185; memory slot that is needed to move values to/from the FPR.  We don't allocate
5186; it earlier to allow for the combiner to merge insns together where it might
5187; not be needed and also in case the insns are deleted as dead code.
5188
5189(define_insn_and_split "floatsi<mode>2_lfiwax"
5190  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5191	(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5192   (clobber (match_scratch:DI 2 "=wi"))]
5193  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5194   && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5195  "#"
5196  ""
5197  [(pc)]
5198{
5199  rtx dest = operands[0];
5200  rtx src = operands[1];
5201  rtx tmp;
5202
5203  if (!MEM_P (src) && TARGET_POWERPC64
5204      && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5205    tmp = convert_to_mode (DImode, src, false);
5206  else
5207    {
5208      tmp = operands[2];
5209      if (GET_CODE (tmp) == SCRATCH)
5210	tmp = gen_reg_rtx (DImode);
5211      if (MEM_P (src))
5212	{
5213	  src = rs6000_address_for_fpconvert (src);
5214	  emit_insn (gen_lfiwax (tmp, src));
5215	}
5216      else
5217	{
5218	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5219	  emit_move_insn (stack, src);
5220	  emit_insn (gen_lfiwax (tmp, stack));
5221	}
5222    }
5223  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5224  DONE;
5225}
5226  [(set_attr "length" "12")
5227   (set_attr "type" "fpload")])
5228
5229(define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5230  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5231	(float:SFDF
5232	 (sign_extend:DI
5233	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5234   (clobber (match_scratch:DI 2 "=wi"))]
5235  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5236  "#"
5237  ""
5238  [(pc)]
5239{
5240  operands[1] = rs6000_address_for_fpconvert (operands[1]);
5241  if (GET_CODE (operands[2]) == SCRATCH)
5242    operands[2] = gen_reg_rtx (DImode);
5243  if (TARGET_P8_VECTOR)
5244    emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5245  else
5246    emit_insn (gen_lfiwax (operands[2], operands[1]));
5247  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5248  DONE;
5249}
5250  [(set_attr "length" "8")
5251   (set_attr "type" "fpload")])
5252
5253(define_insn "lfiwzx"
5254  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5255	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5256		   UNSPEC_LFIWZX))]
5257  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5258  "@
5259   lfiwzx %0,%y1
5260   lxsiwzx %x0,%y1
5261   mtvsrwz %x0,%1
5262   xxextractuw %x0,%x1,4"
5263  [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5264
5265(define_insn_and_split "floatunssi<mode>2_lfiwzx"
5266  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5267	(unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5268   (clobber (match_scratch:DI 2 "=wi"))]
5269  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5270  "#"
5271  ""
5272  [(pc)]
5273{
5274  rtx dest = operands[0];
5275  rtx src = operands[1];
5276  rtx tmp;
5277
5278  if (!MEM_P (src) && TARGET_POWERPC64
5279      && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5280    tmp = convert_to_mode (DImode, src, true);
5281  else
5282    {
5283      tmp = operands[2];
5284      if (GET_CODE (tmp) == SCRATCH)
5285	tmp = gen_reg_rtx (DImode);
5286      if (MEM_P (src))
5287	{
5288	  src = rs6000_address_for_fpconvert (src);
5289	  emit_insn (gen_lfiwzx (tmp, src));
5290	}
5291      else
5292	{
5293	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5294	  emit_move_insn (stack, src);
5295	  emit_insn (gen_lfiwzx (tmp, stack));
5296	}
5297    }
5298  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5299  DONE;
5300}
5301  [(set_attr "length" "12")
5302   (set_attr "type" "fpload")])
5303
5304(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5305  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5306	(unsigned_float:SFDF
5307	 (zero_extend:DI
5308	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5309   (clobber (match_scratch:DI 2 "=wi"))]
5310  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5311  "#"
5312  ""
5313  [(pc)]
5314{
5315  operands[1] = rs6000_address_for_fpconvert (operands[1]);
5316  if (GET_CODE (operands[2]) == SCRATCH)
5317    operands[2] = gen_reg_rtx (DImode);
5318  if (TARGET_P8_VECTOR)
5319    emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5320  else
5321    emit_insn (gen_lfiwzx (operands[2], operands[1]));
5322  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5323  DONE;
5324}
5325  [(set_attr "length" "8")
5326   (set_attr "type" "fpload")])
5327
5328; For each of these conversions, there is a define_expand, a define_insn
5329; with a '#' template, and a define_split (with C code).  The idea is
5330; to allow constant folding with the template of the define_insn,
5331; then to have the insns split later (between sched1 and final).
5332
5333(define_expand "floatsidf2"
5334  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5335		   (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5336	      (use (match_dup 2))
5337	      (use (match_dup 3))
5338	      (clobber (match_dup 4))
5339	      (clobber (match_dup 5))
5340	      (clobber (match_dup 6))])]
5341  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5342{
5343  if (TARGET_LFIWAX && TARGET_FCFID)
5344    {
5345      emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5346      DONE;
5347    }
5348  else if (TARGET_FCFID)
5349    {
5350      rtx dreg = operands[1];
5351      if (!REG_P (dreg))
5352	dreg = force_reg (SImode, dreg);
5353      dreg = convert_to_mode (DImode, dreg, false);
5354      emit_insn (gen_floatdidf2 (operands[0], dreg));
5355      DONE;
5356    }
5357
5358  if (!REG_P (operands[1]))
5359    operands[1] = force_reg (SImode, operands[1]);
5360  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5361  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5362  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5363  operands[5] = gen_reg_rtx (DFmode);
5364  operands[6] = gen_reg_rtx (SImode);
5365})
5366
5367(define_insn_and_split "*floatsidf2_internal"
5368  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5369	(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5370   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5371   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5372   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5373   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5374   (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5375  "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5376  "#"
5377  ""
5378  [(pc)]
5379{
5380  rtx lowword, highword;
5381  gcc_assert (MEM_P (operands[4]));
5382  highword = adjust_address (operands[4], SImode, 0);
5383  lowword = adjust_address (operands[4], SImode, 4);
5384  if (! WORDS_BIG_ENDIAN)
5385    std::swap (lowword, highword);
5386
5387  emit_insn (gen_xorsi3 (operands[6], operands[1],
5388			 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5389  emit_move_insn (lowword, operands[6]);
5390  emit_move_insn (highword, operands[2]);
5391  emit_move_insn (operands[5], operands[4]);
5392  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5393  DONE;
5394}
5395  [(set_attr "length" "24")
5396   (set_attr "type" "fp")])
5397
5398;; If we don't have a direct conversion to single precision, don't enable this
5399;; conversion for 32-bit without fast math, because we don't have the insn to
5400;; generate the fixup swizzle to avoid double rounding problems.
5401(define_expand "floatunssisf2"
5402  [(set (match_operand:SF 0 "gpc_reg_operand")
5403        (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5404  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5405   && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5406       || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5407	   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5408{
5409  if (TARGET_LFIWZX && TARGET_FCFIDUS)
5410    {
5411      emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5412      DONE;
5413    }
5414  else
5415    {
5416      rtx dreg = operands[1];
5417      if (!REG_P (dreg))
5418	dreg = force_reg (SImode, dreg);
5419      dreg = convert_to_mode (DImode, dreg, true);
5420      emit_insn (gen_floatdisf2 (operands[0], dreg));
5421      DONE;
5422    }
5423})
5424
5425(define_expand "floatunssidf2"
5426  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5427		   (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5428	      (use (match_dup 2))
5429	      (use (match_dup 3))
5430	      (clobber (match_dup 4))
5431	      (clobber (match_dup 5))])]
5432  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5433{
5434  if (TARGET_LFIWZX && TARGET_FCFID)
5435    {
5436      emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5437      DONE;
5438    }
5439  else if (TARGET_FCFID)
5440    {
5441      rtx dreg = operands[1];
5442      if (!REG_P (dreg))
5443	dreg = force_reg (SImode, dreg);
5444      dreg = convert_to_mode (DImode, dreg, true);
5445      emit_insn (gen_floatdidf2 (operands[0], dreg));
5446      DONE;
5447    }
5448
5449  if (!REG_P (operands[1]))
5450    operands[1] = force_reg (SImode, operands[1]);
5451  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5452  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5453  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5454  operands[5] = gen_reg_rtx (DFmode);
5455})
5456
5457(define_insn_and_split "*floatunssidf2_internal"
5458  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5459	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5460   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5461   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5462   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5463   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5464  "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5465   && !(TARGET_FCFID && TARGET_POWERPC64)"
5466  "#"
5467  ""
5468  [(pc)]
5469{
5470  rtx lowword, highword;
5471  gcc_assert (MEM_P (operands[4]));
5472  highword = adjust_address (operands[4], SImode, 0);
5473  lowword = adjust_address (operands[4], SImode, 4);
5474  if (! WORDS_BIG_ENDIAN)
5475    std::swap (lowword, highword);
5476
5477  emit_move_insn (lowword, operands[1]);
5478  emit_move_insn (highword, operands[2]);
5479  emit_move_insn (operands[5], operands[4]);
5480  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5481  DONE;
5482}
5483  [(set_attr "length" "20")
5484   (set_attr "type" "fp")])
5485
5486;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5487;; vector registers.  These insns favor doing the sign/zero extension in
5488;; the vector registers, rather then loading up a GPR, doing a sign/zero
5489;; extension and then a direct move.
5490
5491(define_expand "float<QHI:mode><FP_ISA3:mode>2"
5492  [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5493		   (float:FP_ISA3
5494		    (match_operand:QHI 1 "input_operand")))
5495	      (clobber (match_scratch:DI 2))
5496	      (clobber (match_scratch:DI 3))
5497	      (clobber (match_scratch:<QHI:MODE> 4))])]
5498  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5499{
5500  if (MEM_P (operands[1]))
5501    operands[1] = rs6000_address_for_fpconvert (operands[1]);
5502})
5503
5504(define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5505  [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5506	(float:FP_ISA3
5507	 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5508   (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5509   (clobber (match_scratch:DI 3 "=X,r,X"))
5510   (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5511  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5512  "#"
5513  "&& reload_completed"
5514  [(const_int 0)]
5515{
5516  rtx result = operands[0];
5517  rtx input = operands[1];
5518  rtx di = operands[2];
5519
5520  if (!MEM_P (input))
5521    {
5522      rtx tmp = operands[3];
5523      if (altivec_register_operand (input, <QHI:MODE>mode))
5524	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5525      else if (GET_CODE (tmp) == SCRATCH)
5526	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5527      else
5528	{
5529	  emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5530	  emit_move_insn (di, tmp);
5531	}
5532    }
5533  else
5534    {
5535      rtx tmp = operands[4];
5536      emit_move_insn (tmp, input);
5537      emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5538    }
5539
5540  emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5541  DONE;
5542})
5543
5544(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5545  [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5546		   (unsigned_float:FP_ISA3
5547		    (match_operand:QHI 1 "input_operand")))
5548	      (clobber (match_scratch:DI 2))
5549	      (clobber (match_scratch:DI 3))])]
5550  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5551{
5552  if (MEM_P (operands[1]))
5553    operands[1] = rs6000_address_for_fpconvert (operands[1]);
5554})
5555
5556(define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5557  [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5558	(unsigned_float:FP_ISA3
5559	 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5560   (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5561   (clobber (match_scratch:DI 3 "=X,r,X"))]
5562  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5563  "#"
5564  "&& reload_completed"
5565  [(const_int 0)]
5566{
5567  rtx result = operands[0];
5568  rtx input = operands[1];
5569  rtx di = operands[2];
5570
5571  if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5572    emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5573  else
5574    {
5575      rtx tmp = operands[3];
5576      if (GET_CODE (tmp) == SCRATCH)
5577	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5578      else
5579	{
5580	  emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5581	  emit_move_insn (di, tmp);
5582	}
5583    }
5584
5585  emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5586  DONE;
5587})
5588
5589(define_expand "fix_trunc<mode>si2"
5590  [(set (match_operand:SI 0 "gpc_reg_operand")
5591	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5592  "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5593{
5594  if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5595    {
5596      rtx src = force_reg (<MODE>mode, operands[1]);
5597
5598      if (TARGET_STFIWX)
5599	emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5600      else
5601	{
5602	  rtx tmp = gen_reg_rtx (DImode);
5603	  rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5604	  emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5605						      tmp, stack));
5606	}
5607      DONE;
5608    }
5609})
5610
5611; Like the convert to float patterns, this insn must be split before
5612; register allocation so that it can allocate the memory slot if it
5613; needed
5614(define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5615  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5616	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5617   (clobber (match_scratch:DI 2 "=d"))]
5618  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5619   && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5620   && TARGET_STFIWX && can_create_pseudo_p ()
5621   && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5622  "#"
5623  ""
5624  [(pc)]
5625{
5626  rtx dest = operands[0];
5627  rtx src = operands[1];
5628  rtx tmp = operands[2];
5629
5630  if (GET_CODE (tmp) == SCRATCH)
5631    tmp = gen_reg_rtx (DImode);
5632
5633  emit_insn (gen_fctiwz_<mode> (tmp, src));
5634  if (MEM_P (dest))
5635    {
5636      dest = rs6000_address_for_fpconvert (dest);
5637      emit_insn (gen_stfiwx (dest, tmp));
5638      DONE;
5639    }
5640  else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5641    {
5642      dest = gen_lowpart (DImode, dest);
5643      emit_move_insn (dest, tmp);
5644      DONE;
5645    }
5646  else
5647    {
5648      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5649      emit_insn (gen_stfiwx (stack, tmp));
5650      emit_move_insn (dest, stack);
5651      DONE;
5652    }
5653}
5654  [(set_attr "length" "12")
5655   (set_attr "type" "fp")])
5656
5657(define_insn_and_split "fix_trunc<mode>si2_internal"
5658  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5659	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5660   (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5661   (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5662  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5663   && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5664  "#"
5665  ""
5666  [(pc)]
5667{
5668  rtx lowword;
5669  gcc_assert (MEM_P (operands[3]));
5670  lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5671
5672  emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5673  emit_move_insn (operands[3], operands[2]);
5674  emit_move_insn (operands[0], lowword);
5675  DONE;
5676}
5677  [(set_attr "length" "16")
5678   (set_attr "type" "fp")])
5679
5680(define_expand "fix_trunc<mode>di2"
5681  [(set (match_operand:DI 0 "gpc_reg_operand")
5682	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5683  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5684  "")
5685
5686(define_insn "*fix_trunc<mode>di2_fctidz"
5687  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5688	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5689  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5690  "@
5691   fctidz %0,%1
5692   xscvdpsxds %x0,%x1"
5693  [(set_attr "type" "fp")])
5694
5695;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5696;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5697;; vector registers, so we need to do direct moves to the GPRs, but SImode
5698;; values can go in VSX registers.  Keeping the direct move part through
5699;; register allocation prevents the register allocator from doing a direct move
5700;; of the SImode value to a GPR, and then a store/load.
5701(define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5702  [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5703	(any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5704   (clobber (match_scratch:SI 2 "=X,X,wi"))]
5705  "TARGET_DIRECT_MOVE"
5706  "@
5707   fctiw<u>z %0,%1
5708   xscvdp<su>xws %x0,%x1
5709   #"
5710  "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5711  [(set (match_dup 2)
5712	(any_fix:SI (match_dup 1)))
5713   (set (match_dup 3)
5714	(match_dup 2))]
5715{
5716  operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5717}
5718  [(set_attr "length" "4,4,8")
5719   (set_attr "type" "fp")])
5720
5721(define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5722  [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5723	(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5724  "TARGET_DIRECT_MOVE"
5725  "@
5726   fctiw<u>z %0,%1
5727   xscvdp<su>xws %x0,%x1"
5728  [(set_attr "type" "fp")])
5729
5730;; Keep the convert and store together through register allocation to prevent
5731;; the register allocator from getting clever and doing a direct move to a GPR
5732;; and then store for reg+offset stores.
5733(define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5734  [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5735	(any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5736   (clobber (match_scratch:SI 2 "=wa"))]
5737    "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5738  "#"
5739  "&& reload_completed"
5740  [(set (match_dup 2)
5741	(any_fix:SI (match_dup 1)))
5742   (set (match_dup 0)
5743	(match_dup 3))]
5744{
5745  operands[3] = (<QHSI:MODE>mode == SImode
5746		 ? operands[2]
5747		 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5748})
5749
5750(define_expand "fixuns_trunc<mode>si2"
5751  [(set (match_operand:SI 0 "gpc_reg_operand")
5752	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5753  "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5754{
5755  if (!TARGET_P8_VECTOR)
5756    {
5757      emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5758      DONE;
5759    }
5760})
5761
5762(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5763  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5764	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5765   (clobber (match_scratch:DI 2 "=d"))]
5766  "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5767   && TARGET_STFIWX && can_create_pseudo_p ()
5768   && !TARGET_P8_VECTOR"
5769  "#"
5770  ""
5771  [(pc)]
5772{
5773  rtx dest = operands[0];
5774  rtx src = operands[1];
5775  rtx tmp = operands[2];
5776
5777  if (GET_CODE (tmp) == SCRATCH)
5778    tmp = gen_reg_rtx (DImode);
5779
5780  emit_insn (gen_fctiwuz_<mode> (tmp, src));
5781  if (MEM_P (dest))
5782    {
5783      dest = rs6000_address_for_fpconvert (dest);
5784      emit_insn (gen_stfiwx (dest, tmp));
5785      DONE;
5786    }
5787  else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5788    {
5789      dest = gen_lowpart (DImode, dest);
5790      emit_move_insn (dest, tmp);
5791      DONE;
5792    }
5793  else
5794    {
5795      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5796      emit_insn (gen_stfiwx (stack, tmp));
5797      emit_move_insn (dest, stack);
5798      DONE;
5799    }
5800}
5801  [(set_attr "length" "12")
5802   (set_attr "type" "fp")])
5803
5804(define_insn "fixuns_trunc<mode>di2"
5805  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5806	(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5807  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5808  "@
5809   fctiduz %0,%1
5810   xscvdpuxds %x0,%x1"
5811  [(set_attr "type" "fp")])
5812
5813;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5814;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5815;; because the first makes it clear that operand 0 is not live
5816;; before the instruction.
5817(define_insn "fctiwz_<mode>"
5818  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5819	(unspec:DI [(fix:SI
5820		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5821		   UNSPEC_FCTIWZ))]
5822  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5823  "@
5824   fctiwz %0,%1
5825   xscvdpsxws %x0,%x1"
5826  [(set_attr "type" "fp")])
5827
5828(define_insn "fctiwuz_<mode>"
5829  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5830	(unspec:DI [(unsigned_fix:SI
5831		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5832		   UNSPEC_FCTIWUZ))]
5833  "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5834  "@
5835   fctiwuz %0,%1
5836   xscvdpuxws %x0,%x1"
5837  [(set_attr "type" "fp")])
5838
5839;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5840;; since the friz instruction does not truncate the value if the floating
5841;; point value is < LONG_MIN or > LONG_MAX.
5842(define_insn "*friz"
5843  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5844	(float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5845  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5846   && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5847  "@
5848   friz %0,%1
5849   xsrdpiz %x0,%x1"
5850  [(set_attr "type" "fp")])
5851
5852;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5853;; optimization prevents on ISA 2.06 systems and earlier having to store the
5854;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5855;; extend it, store it back on the stack from the GPR, load it back into the
5856;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5857;; disable using store and load to sign/zero extend the value.
5858(define_insn_and_split "*round32<mode>2_fprs"
5859  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5860	(float:SFDF
5861	 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5862   (clobber (match_scratch:DI 2 "=d"))
5863   (clobber (match_scratch:DI 3 "=d"))]
5864  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5865   && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5866   && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5867  "#"
5868  ""
5869  [(pc)]
5870{
5871  rtx dest = operands[0];
5872  rtx src = operands[1];
5873  rtx tmp1 = operands[2];
5874  rtx tmp2 = operands[3];
5875  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5876
5877  if (GET_CODE (tmp1) == SCRATCH)
5878    tmp1 = gen_reg_rtx (DImode);
5879  if (GET_CODE (tmp2) == SCRATCH)
5880    tmp2 = gen_reg_rtx (DImode);
5881
5882  emit_insn (gen_fctiwz_<mode> (tmp1, src));
5883  emit_insn (gen_stfiwx (stack, tmp1));
5884  emit_insn (gen_lfiwax (tmp2, stack));
5885  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5886  DONE;
5887}
5888  [(set_attr "type" "fpload")
5889   (set_attr "length" "16")])
5890
5891(define_insn_and_split "*roundu32<mode>2_fprs"
5892  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5893	(unsigned_float:SFDF
5894	 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5895   (clobber (match_scratch:DI 2 "=d"))
5896   (clobber (match_scratch:DI 3 "=d"))]
5897  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5898   && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5899   && can_create_pseudo_p ()"
5900  "#"
5901  ""
5902  [(pc)]
5903{
5904  rtx dest = operands[0];
5905  rtx src = operands[1];
5906  rtx tmp1 = operands[2];
5907  rtx tmp2 = operands[3];
5908  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5909
5910  if (GET_CODE (tmp1) == SCRATCH)
5911    tmp1 = gen_reg_rtx (DImode);
5912  if (GET_CODE (tmp2) == SCRATCH)
5913    tmp2 = gen_reg_rtx (DImode);
5914
5915  emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5916  emit_insn (gen_stfiwx (stack, tmp1));
5917  emit_insn (gen_lfiwzx (tmp2, stack));
5918  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5919  DONE;
5920}
5921  [(set_attr "type" "fpload")
5922   (set_attr "length" "16")])
5923
5924;; No VSX equivalent to fctid
5925(define_insn "lrint<mode>di2"
5926  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5927	(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5928		   UNSPEC_FCTID))]
5929  "TARGET_<MODE>_FPR && TARGET_FPRND"
5930  "fctid %0,%1"
5931  [(set_attr "type" "fp")])
5932
5933(define_insn "btrunc<mode>2"
5934  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5935	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5936		     UNSPEC_FRIZ))]
5937  "TARGET_<MODE>_FPR && TARGET_FPRND"
5938  "@
5939   friz %0,%1
5940   xsrdpiz %x0,%x1"
5941  [(set_attr "type" "fp")
5942   (set_attr "fp_type" "fp_addsub_<Fs>")])
5943
5944(define_insn "ceil<mode>2"
5945  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5946	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5947		     UNSPEC_FRIP))]
5948  "TARGET_<MODE>_FPR && TARGET_FPRND"
5949  "@
5950   frip %0,%1
5951   xsrdpip %x0,%x1"
5952  [(set_attr "type" "fp")
5953   (set_attr "fp_type" "fp_addsub_<Fs>")])
5954
5955(define_insn "floor<mode>2"
5956  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5957	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5958		     UNSPEC_FRIM))]
5959  "TARGET_<MODE>_FPR && TARGET_FPRND"
5960  "@
5961   frim %0,%1
5962   xsrdpim %x0,%x1"
5963  [(set_attr "type" "fp")
5964   (set_attr "fp_type" "fp_addsub_<Fs>")])
5965
5966;; No VSX equivalent to frin
5967(define_insn "round<mode>2"
5968  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5969	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5970		     UNSPEC_FRIN))]
5971  "TARGET_<MODE>_FPR && TARGET_FPRND"
5972  "frin %0,%1"
5973  [(set_attr "type" "fp")
5974   (set_attr "fp_type" "fp_addsub_<Fs>")])
5975
5976(define_insn "*xsrdpi<mode>2"
5977  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5978	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5979		     UNSPEC_XSRDPI))]
5980  "TARGET_<MODE>_FPR && TARGET_VSX"
5981  "xsrdpi %x0,%x1"
5982  [(set_attr "type" "fp")
5983   (set_attr "fp_type" "fp_addsub_<Fs>")])
5984
5985(define_expand "lround<mode>di2"
5986  [(set (match_dup 2)
5987	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
5988		     UNSPEC_XSRDPI))
5989   (set (match_operand:DI 0 "gpc_reg_operand")
5990	(unspec:DI [(match_dup 2)]
5991		   UNSPEC_FCTID))]
5992  "TARGET_<MODE>_FPR && TARGET_VSX && TARGET_FPRND"
5993{
5994  operands[2] = gen_reg_rtx (<MODE>mode);
5995})
5996
5997; An UNSPEC is used so we don't have to support SImode in FP registers.
5998; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5999; is only generated for Power8 or later.
6000(define_insn "stfiwx"
6001  [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6002	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6003		   UNSPEC_STFIWX))]
6004  "TARGET_PPC_GFXOPT"
6005  "@
6006   stfiwx %1,%y0
6007   stxsiwx %x1,%y0"
6008  [(set_attr "type" "fpstore")])
6009
6010;; If we don't have a direct conversion to single precision, don't enable this
6011;; conversion for 32-bit without fast math, because we don't have the insn to
6012;; generate the fixup swizzle to avoid double rounding problems.
6013(define_expand "floatsisf2"
6014  [(set (match_operand:SF 0 "gpc_reg_operand")
6015        (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6016  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6017   && ((TARGET_FCFIDS && TARGET_LFIWAX)
6018       || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6019	   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6020{
6021  if (TARGET_FCFIDS && TARGET_LFIWAX)
6022    {
6023      emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6024      DONE;
6025    }
6026  else if (TARGET_FCFID && TARGET_LFIWAX)
6027    {
6028      rtx dfreg = gen_reg_rtx (DFmode);
6029      emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6030      emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6031      DONE;
6032    }
6033  else
6034    {
6035      rtx dreg = operands[1];
6036      if (!REG_P (dreg))
6037	dreg = force_reg (SImode, dreg);
6038      dreg = convert_to_mode (DImode, dreg, false);
6039      emit_insn (gen_floatdisf2 (operands[0], dreg));
6040      DONE;
6041    }
6042})
6043
6044(define_insn "floatdidf2"
6045  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6046	(float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6047  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6048  "@
6049   fcfid %0,%1
6050   xscvsxddp %x0,%x1"
6051  [(set_attr "type" "fp")])
6052
6053; Allow the combiner to merge source memory operands to the conversion so that
6054; the optimizer/register allocator doesn't try to load the value too early in a
6055; GPR and then use store/load to move it to a FPR and suffer from a store-load
6056; hit.  We will split after reload to avoid the trip through the GPRs
6057
6058(define_insn_and_split "*floatdidf2_mem"
6059  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6060	(float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6061   (clobber (match_scratch:DI 2 "=d,wi"))]
6062  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6063  "#"
6064  "&& reload_completed"
6065  [(set (match_dup 2) (match_dup 1))
6066   (set (match_dup 0) (float:DF (match_dup 2)))]
6067  ""
6068  [(set_attr "length" "8")
6069   (set_attr "type" "fpload")])
6070
6071(define_expand "floatunsdidf2"
6072  [(set (match_operand:DF 0 "gpc_reg_operand")
6073	(unsigned_float:DF
6074	 (match_operand:DI 1 "gpc_reg_operand")))]
6075  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6076  "")
6077
6078(define_insn "*floatunsdidf2_fcfidu"
6079  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6080	(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6081  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6082  "@
6083   fcfidu %0,%1
6084   xscvuxddp %x0,%x1"
6085  [(set_attr "type" "fp")
6086   (set_attr "length" "4")])
6087
6088(define_insn_and_split "*floatunsdidf2_mem"
6089  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6090	(unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6091   (clobber (match_scratch:DI 2 "=d,wi"))]
6092  "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6093  "#"
6094  "&& reload_completed"
6095  [(set (match_dup 2) (match_dup 1))
6096   (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6097  ""
6098  [(set_attr "length" "8")
6099   (set_attr "type" "fpload")])
6100
6101(define_expand "floatdisf2"
6102  [(set (match_operand:SF 0 "gpc_reg_operand")
6103        (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6104  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6105   && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6106{
6107  if (!TARGET_FCFIDS)
6108    {
6109      rtx val = operands[1];
6110      if (!flag_unsafe_math_optimizations)
6111	{
6112	  rtx label = gen_label_rtx ();
6113	  val = gen_reg_rtx (DImode);
6114	  emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6115	  emit_label (label);
6116	}
6117      emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6118      DONE;
6119    }
6120})
6121
6122(define_insn "floatdisf2_fcfids"
6123  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6124	(float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6125  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6126   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6127  "@
6128   fcfids %0,%1
6129   xscvsxdsp %x0,%x1"
6130  [(set_attr "type" "fp")])
6131
6132(define_insn_and_split "*floatdisf2_mem"
6133  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6134	(float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6135   (clobber (match_scratch:DI 2 "=d,d,wi"))]
6136  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6137   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6138  "#"
6139  "&& reload_completed"
6140  [(pc)]
6141{
6142  emit_move_insn (operands[2], operands[1]);
6143  emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6144  DONE;
6145}
6146  [(set_attr "length" "8")])
6147
6148;; This is not IEEE compliant if rounding mode is "round to nearest".
6149;; If the DI->DF conversion is inexact, then it's possible to suffer
6150;; from double rounding.
6151;; Instead of creating a new cpu type for two FP operations, just use fp
6152(define_insn_and_split "floatdisf2_internal1"
6153  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6154        (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6155   (clobber (match_scratch:DF 2 "=d"))]
6156  "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6157  "#"
6158  "&& reload_completed"
6159  [(set (match_dup 2)
6160        (float:DF (match_dup 1)))
6161   (set (match_dup 0)
6162        (float_truncate:SF (match_dup 2)))]
6163  ""
6164  [(set_attr "length" "8")
6165   (set_attr "type" "fp")])
6166
6167;; Twiddles bits to avoid double rounding.
6168;; Bits that might be truncated when converting to DFmode are replaced
6169;; by a bit that won't be lost at that stage, but is below the SFmode
6170;; rounding position.
6171(define_expand "floatdisf2_internal2"
6172  [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6173					      (const_int 53)))
6174	      (clobber (reg:DI CA_REGNO))])
6175   (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6176					(const_int 2047)))
6177   (set (match_dup 3) (plus:DI (match_dup 3)
6178			       (const_int 1)))
6179   (set (match_dup 0) (plus:DI (match_dup 0)
6180			       (const_int 2047)))
6181   (set (match_dup 4) (compare:CCUNS (match_dup 3)
6182				     (const_int 2)))
6183   (set (match_dup 0) (ior:DI (match_dup 0)
6184			      (match_dup 1)))
6185   (set (match_dup 0) (and:DI (match_dup 0)
6186			      (const_int -2048)))
6187   (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6188			   (label_ref (match_operand:DI 2 ""))
6189			   (pc)))
6190   (set (match_dup 0) (match_dup 1))]
6191  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6192   && !TARGET_FCFIDS"
6193{
6194  operands[3] = gen_reg_rtx (DImode);
6195  operands[4] = gen_reg_rtx (CCUNSmode);
6196})
6197
6198(define_expand "floatunsdisf2"
6199  [(set (match_operand:SF 0 "gpc_reg_operand")
6200        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6201  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6202   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6203  "")
6204
6205(define_insn "floatunsdisf2_fcfidus"
6206  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6207        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6208  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6209   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6210  "@
6211   fcfidus %0,%1
6212   xscvuxdsp %x0,%x1"
6213  [(set_attr "type" "fp")])
6214
6215(define_insn_and_split "*floatunsdisf2_mem"
6216  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6217	(unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6218   (clobber (match_scratch:DI 2 "=d,d,wi"))]
6219  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6220   && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6221  "#"
6222  "&& reload_completed"
6223  [(pc)]
6224{
6225  emit_move_insn (operands[2], operands[1]);
6226  emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6227  DONE;
6228}
6229  [(set_attr "length" "8")
6230   (set_attr "type" "fpload")])
6231
6232;; Define the TImode operations that can be done in a small number
6233;; of instructions.  The & constraints are to prevent the register
6234;; allocator from allocating registers that overlap with the inputs
6235;; (for example, having an input in 7,8 and an output in 6,7).  We
6236;; also allow for the output being the same as one of the inputs.
6237
6238(define_expand "addti3"
6239  [(set (match_operand:TI 0 "gpc_reg_operand")
6240	(plus:TI (match_operand:TI 1 "gpc_reg_operand")
6241		 (match_operand:TI 2 "reg_or_short_operand")))]
6242  "TARGET_64BIT"
6243{
6244  rtx lo0 = gen_lowpart (DImode, operands[0]);
6245  rtx lo1 = gen_lowpart (DImode, operands[1]);
6246  rtx lo2 = gen_lowpart (DImode, operands[2]);
6247  rtx hi0 = gen_highpart (DImode, operands[0]);
6248  rtx hi1 = gen_highpart (DImode, operands[1]);
6249  rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6250
6251  if (!reg_or_short_operand (lo2, DImode))
6252    lo2 = force_reg (DImode, lo2);
6253  if (!adde_operand (hi2, DImode))
6254    hi2 = force_reg (DImode, hi2);
6255
6256  emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6257  emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6258  DONE;
6259})
6260
6261(define_expand "subti3"
6262  [(set (match_operand:TI 0 "gpc_reg_operand")
6263	(minus:TI (match_operand:TI 1 "reg_or_short_operand")
6264		  (match_operand:TI 2 "gpc_reg_operand")))]
6265  "TARGET_64BIT"
6266{
6267  rtx lo0 = gen_lowpart (DImode, operands[0]);
6268  rtx lo1 = gen_lowpart (DImode, operands[1]);
6269  rtx lo2 = gen_lowpart (DImode, operands[2]);
6270  rtx hi0 = gen_highpart (DImode, operands[0]);
6271  rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6272  rtx hi2 = gen_highpart (DImode, operands[2]);
6273
6274  if (!reg_or_short_operand (lo1, DImode))
6275    lo1 = force_reg (DImode, lo1);
6276  if (!adde_operand (hi1, DImode))
6277    hi1 = force_reg (DImode, hi1);
6278
6279  emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6280  emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6281  DONE;
6282})
6283
6284;; 128-bit logical operations expanders
6285
6286(define_expand "and<mode>3"
6287  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6288	(and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6289		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6290  ""
6291  "")
6292
6293(define_expand "ior<mode>3"
6294  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6295        (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6296		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6297  ""
6298  "")
6299
6300(define_expand "xor<mode>3"
6301  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6302        (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6303		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6304  ""
6305  "")
6306
6307(define_expand "one_cmpl<mode>2"
6308  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6309        (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6310  ""
6311  "")
6312
6313(define_expand "nor<mode>3"
6314  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6315	(and:BOOL_128
6316	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6317	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6318  ""
6319  "")
6320
6321(define_expand "andc<mode>3"
6322  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6323        (and:BOOL_128
6324	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6325	 (match_operand:BOOL_128 1 "vlogical_operand")))]
6326  ""
6327  "")
6328
6329;; Power8 vector logical instructions.
6330(define_expand "eqv<mode>3"
6331  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6332	(not:BOOL_128
6333	 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6334		       (match_operand:BOOL_128 2 "vlogical_operand"))))]
6335  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6336  "")
6337
6338;; Rewrite nand into canonical form
6339(define_expand "nand<mode>3"
6340  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6341	(ior:BOOL_128
6342	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6343	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6344  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6345  "")
6346
6347;; The canonical form is to have the negated element first, so we need to
6348;; reverse arguments.
6349(define_expand "orc<mode>3"
6350  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6351	(ior:BOOL_128
6352	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6353	 (match_operand:BOOL_128 1 "vlogical_operand")))]
6354  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6355  "")
6356
6357;; 128-bit logical operations insns and split operations
6358(define_insn_and_split "*and<mode>3_internal"
6359  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6360        (and:BOOL_128
6361	 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6362	 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6363  ""
6364{
6365  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6366    return "xxland %x0,%x1,%x2";
6367
6368  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6369    return "vand %0,%1,%2";
6370
6371  return "#";
6372}
6373  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6374  [(const_int 0)]
6375{
6376  rs6000_split_logical (operands, AND, false, false, false);
6377  DONE;
6378}
6379  [(set (attr "type")
6380      (if_then_else
6381	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6382	(const_string "veclogical")
6383	(const_string "integer")))
6384   (set (attr "length")
6385      (if_then_else
6386	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6387	(const_string "4")
6388	(if_then_else
6389	 (match_test "TARGET_POWERPC64")
6390	 (const_string "8")
6391	 (const_string "16"))))])
6392
6393;; 128-bit IOR/XOR
6394(define_insn_and_split "*bool<mode>3_internal"
6395  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6396	(match_operator:BOOL_128 3 "boolean_or_operator"
6397	 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6398	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6399  ""
6400{
6401  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6402    return "xxl%q3 %x0,%x1,%x2";
6403
6404  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6405    return "v%q3 %0,%1,%2";
6406
6407  return "#";
6408}
6409  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6410  [(const_int 0)]
6411{
6412  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6413  DONE;
6414}
6415  [(set (attr "type")
6416      (if_then_else
6417	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6418	(const_string "veclogical")
6419	(const_string "integer")))
6420   (set (attr "length")
6421      (if_then_else
6422	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6423	(const_string "4")
6424	(if_then_else
6425	 (match_test "TARGET_POWERPC64")
6426	 (const_string "8")
6427	 (const_string "16"))))])
6428
6429;; 128-bit ANDC/ORC
6430(define_insn_and_split "*boolc<mode>3_internal1"
6431  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6432	(match_operator:BOOL_128 3 "boolean_operator"
6433	 [(not:BOOL_128
6434	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6435	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6436  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6437{
6438  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6439    return "xxl%q3 %x0,%x1,%x2";
6440
6441  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6442    return "v%q3 %0,%1,%2";
6443
6444  return "#";
6445}
6446  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6447   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6448  [(const_int 0)]
6449{
6450  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6451  DONE;
6452}
6453  [(set (attr "type")
6454      (if_then_else
6455	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6456	(const_string "veclogical")
6457	(const_string "integer")))
6458   (set (attr "length")
6459      (if_then_else
6460	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6461	(const_string "4")
6462	(if_then_else
6463	 (match_test "TARGET_POWERPC64")
6464	 (const_string "8")
6465	 (const_string "16"))))])
6466
6467(define_insn_and_split "*boolc<mode>3_internal2"
6468  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6469	(match_operator:TI2 3 "boolean_operator"
6470	 [(not:TI2
6471	   (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6472	  (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6473  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6474  "#"
6475  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6476  [(const_int 0)]
6477{
6478  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6479  DONE;
6480}
6481  [(set_attr "type" "integer")
6482   (set (attr "length")
6483	(if_then_else
6484	 (match_test "TARGET_POWERPC64")
6485	 (const_string "8")
6486	 (const_string "16")))])
6487
6488;; 128-bit NAND/NOR
6489(define_insn_and_split "*boolcc<mode>3_internal1"
6490  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6491	(match_operator:BOOL_128 3 "boolean_operator"
6492	 [(not:BOOL_128
6493	   (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6494	  (not:BOOL_128
6495	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6496  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6497{
6498  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6499    return "xxl%q3 %x0,%x1,%x2";
6500
6501  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6502    return "v%q3 %0,%1,%2";
6503
6504  return "#";
6505}
6506  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6507   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6508  [(const_int 0)]
6509{
6510  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6511  DONE;
6512}
6513  [(set (attr "type")
6514      (if_then_else
6515	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6516	(const_string "veclogical")
6517	(const_string "integer")))
6518   (set (attr "length")
6519      (if_then_else
6520	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6521	(const_string "4")
6522	(if_then_else
6523	 (match_test "TARGET_POWERPC64")
6524	 (const_string "8")
6525	 (const_string "16"))))])
6526
6527(define_insn_and_split "*boolcc<mode>3_internal2"
6528  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6529	(match_operator:TI2 3 "boolean_operator"
6530	 [(not:TI2
6531	   (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6532	  (not:TI2
6533	   (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6534  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6535  "#"
6536  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6537  [(const_int 0)]
6538{
6539  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6540  DONE;
6541}
6542  [(set_attr "type" "integer")
6543   (set (attr "length")
6544	(if_then_else
6545	 (match_test "TARGET_POWERPC64")
6546	 (const_string "8")
6547	 (const_string "16")))])
6548
6549
6550;; 128-bit EQV
6551(define_insn_and_split "*eqv<mode>3_internal1"
6552  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6553	(not:BOOL_128
6554	 (xor:BOOL_128
6555	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6556	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6557  "TARGET_P8_VECTOR"
6558{
6559  if (vsx_register_operand (operands[0], <MODE>mode))
6560    return "xxleqv %x0,%x1,%x2";
6561
6562  return "#";
6563}
6564  "TARGET_P8_VECTOR && reload_completed
6565   && int_reg_operand (operands[0], <MODE>mode)"
6566  [(const_int 0)]
6567{
6568  rs6000_split_logical (operands, XOR, true, false, false);
6569  DONE;
6570}
6571  [(set (attr "type")
6572      (if_then_else
6573	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6574	(const_string "veclogical")
6575	(const_string "integer")))
6576   (set (attr "length")
6577      (if_then_else
6578	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6579	(const_string "4")
6580	(if_then_else
6581	 (match_test "TARGET_POWERPC64")
6582	 (const_string "8")
6583	 (const_string "16"))))])
6584
6585(define_insn_and_split "*eqv<mode>3_internal2"
6586  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6587	(not:TI2
6588	 (xor:TI2
6589	  (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6590	  (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6591  "!TARGET_P8_VECTOR"
6592  "#"
6593  "reload_completed && !TARGET_P8_VECTOR"
6594  [(const_int 0)]
6595{
6596  rs6000_split_logical (operands, XOR, true, false, false);
6597  DONE;
6598}
6599  [(set_attr "type" "integer")
6600   (set (attr "length")
6601	(if_then_else
6602	 (match_test "TARGET_POWERPC64")
6603	 (const_string "8")
6604	 (const_string "16")))])
6605
6606;; 128-bit one's complement
6607(define_insn_and_split "*one_cmpl<mode>3_internal"
6608  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6609	(not:BOOL_128
6610	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6611  ""
6612{
6613  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6614    return "xxlnor %x0,%x1,%x1";
6615
6616  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6617    return "vnor %0,%1,%1";
6618
6619  return "#";
6620}
6621  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6622  [(const_int 0)]
6623{
6624  rs6000_split_logical (operands, NOT, false, false, false);
6625  DONE;
6626}
6627  [(set (attr "type")
6628      (if_then_else
6629	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6630	(const_string "veclogical")
6631	(const_string "integer")))
6632   (set (attr "length")
6633      (if_then_else
6634	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6635	(const_string "4")
6636	(if_then_else
6637	 (match_test "TARGET_POWERPC64")
6638	 (const_string "8")
6639	 (const_string "16"))))])
6640
6641
6642;; Now define ways of moving data around.
6643
6644;; Set up a register with a value from the GOT table
6645
6646(define_expand "movsi_got"
6647  [(set (match_operand:SI 0 "gpc_reg_operand")
6648	(unspec:SI [(match_operand:SI 1 "got_operand")
6649		    (match_dup 2)] UNSPEC_MOVSI_GOT))]
6650  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6651{
6652  if (GET_CODE (operands[1]) == CONST)
6653    {
6654      rtx offset = const0_rtx;
6655      HOST_WIDE_INT value;
6656
6657      operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6658      value = INTVAL (offset);
6659      if (value != 0)
6660	{
6661	  rtx tmp = (!can_create_pseudo_p ()
6662		     ? operands[0]
6663		     : gen_reg_rtx (Pmode));
6664	  emit_insn (gen_movsi_got (tmp, operands[1]));
6665	  emit_insn (gen_addsi3 (operands[0], tmp, offset));
6666	  DONE;
6667	}
6668    }
6669
6670  operands[2] = rs6000_got_register (operands[1]);
6671})
6672
6673(define_insn "*movsi_got_internal"
6674  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6675	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6676		    (match_operand:SI 2 "gpc_reg_operand" "b")]
6677		   UNSPEC_MOVSI_GOT))]
6678  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6679  "lwz %0,%a1@got(%2)"
6680  [(set_attr "type" "load")])
6681
6682;; Used by sched, shorten_branches and final when the GOT pseudo reg
6683;; didn't get allocated to a hard register.
6684(define_split
6685  [(set (match_operand:SI 0 "gpc_reg_operand")
6686	(unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6687		    (match_operand:SI 2 "memory_operand")]
6688		   UNSPEC_MOVSI_GOT))]
6689  "DEFAULT_ABI == ABI_V4
6690    && flag_pic == 1
6691    && reload_completed"
6692  [(set (match_dup 0) (match_dup 2))
6693   (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6694				 UNSPEC_MOVSI_GOT))]
6695  "")
6696
6697;; For SI, we special-case integers that can't be loaded in one insn.  We
6698;; do the load 16-bits at a time.  We could do this by loading from memory,
6699;; and this is even supposed to be faster, but it is simpler not to get
6700;; integers in the TOC.
6701
6702;;		MR           LA           LWZ          LFIWZX       LXSIWZX
6703;;		STW          STFIWX       STXSIWX      LI           LIS
6704;;		#            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6705;;		XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6706;;		MF%1         MT%0         MT%0         NOP
6707(define_insn "*movsi_internal1"
6708  [(set (match_operand:SI 0 "nonimmediate_operand"
6709		"=r,         r,           r,           ?*wI,        ?*wH,
6710		 m,          ?Z,          ?Z,          r,           r,
6711		 r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6712		 ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6713		 r,          *c*l,        *h,          *h")
6714
6715	(match_operand:SI 1 "input_operand"
6716		"r,          U,           m,           Z,           Z,
6717		 r,          wI,          wH,          I,           L,
6718		 n,          wIwH,        O,           wM,          wB,
6719		 O,          wM,          wS,          r,           wIwH,
6720		 *h,         r,           r,           0"))]
6721
6722  "!TARGET_SINGLE_FPU &&
6723   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6724  "@
6725   mr %0,%1
6726   la %0,%a1
6727   lwz%U1%X1 %0,%1
6728   lfiwzx %0,%y1
6729   lxsiwzx %x0,%y1
6730   stw%U0%X0 %1,%0
6731   stfiwx %1,%y0
6732   stxsiwx %x1,%y0
6733   li %0,%1
6734   lis %0,%v1
6735   #
6736   xxlor %x0,%x1,%x1
6737   xxspltib %x0,0
6738   xxspltib %x0,255
6739   vspltisw %0,%1
6740   xxlxor %x0,%x0,%x0
6741   xxlorc %x0,%x0,%x0
6742   #
6743   mtvsrwz %x0,%1
6744   mfvsrwz %0,%x1
6745   mf%1 %0
6746   mt%0 %1
6747   mt%0 %1
6748   nop"
6749  [(set_attr "type"
6750		"*,          *,           load,        fpload,      fpload,
6751		 store,      fpstore,     fpstore,     *,           *,
6752		 *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6753		 veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6754		 *,           *,           *,           *")
6755
6756   (set_attr "length"
6757		"4,          4,           4,           4,           4,
6758		 4,          4,           4,           4,           4,
6759		 8,          4,           4,           4,           4,
6760		 4,          4,           8,           4,           4,
6761		 4,          4,           4,           4")])
6762
6763(define_insn "*movsi_internal1_single"
6764  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6765        (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6766  "TARGET_SINGLE_FPU &&
6767   (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6768  "@
6769   mr %0,%1
6770   la %0,%a1
6771   lwz%U1%X1 %0,%1
6772   stw%U0%X0 %1,%0
6773   li %0,%1
6774   lis %0,%v1
6775   #
6776   mf%1 %0
6777   mt%0 %1
6778   mt%0 %1
6779   nop
6780   stfs%U0%X0 %1,%0
6781   lfs%U1%X1 %0,%1"
6782  [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6783   (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6784
6785;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6786;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6787;;
6788;; Because SF values are actually stored as DF values within the vector
6789;; registers, we need to convert the value to the vector SF format when
6790;; we need to use the bits in a union or similar cases.  We only need
6791;; to do this transformation when the value is a vector register.  Loads,
6792;; stores, and transfers within GPRs are assumed to be safe.
6793;;
6794;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6795;; no alternatives, because the call is created as part of secondary_reload,
6796;; and operand #2's register class is used to allocate the temporary register.
6797;; This function is called before reload, and it creates the temporary as
6798;; needed.
6799
6800;;		MR           LWZ          LFIWZX       LXSIWZX   STW
6801;;		STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6802;;		MTVSRWZ
6803
6804(define_insn_and_split "movsi_from_sf"
6805  [(set (match_operand:SI 0 "nonimmediate_operand"
6806		"=r,         r,           ?*wI,        ?*wH,     m,
6807		 m,          wY,          Z,           r,        ?*wIwH,
6808		 wIwH")
6809
6810	(unspec:SI [(match_operand:SF 1 "input_operand"
6811		"r,          m,           Z,           Z,        r,
6812		 f,          wb,          wu,          wIwH,     wIwH,
6813		 r")]
6814		    UNSPEC_SI_FROM_SF))
6815
6816   (clobber (match_scratch:V4SF 2
6817		"=X,         X,           X,           X,        X,
6818		 X,          X,           X,           wIwH,     X,
6819		 X"))]
6820
6821  "TARGET_NO_SF_SUBREG
6822   && (register_operand (operands[0], SImode)
6823       || register_operand (operands[1], SFmode))"
6824  "@
6825   mr %0,%1
6826   lwz%U1%X1 %0,%1
6827   lfiwzx %0,%y1
6828   lxsiwzx %x0,%y1
6829   stw%U0%X0 %1,%0
6830   stfs%U0%X0 %1,%0
6831   stxssp %1,%0
6832   stxsspx %x1,%y0
6833   #
6834   xscvdpspn %x0,%x1
6835   mtvsrwz %x0,%1"
6836  "&& reload_completed
6837   && int_reg_operand (operands[0], SImode)
6838   && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6839  [(const_int 0)]
6840{
6841  rtx op0 = operands[0];
6842  rtx op1 = operands[1];
6843  rtx op2 = operands[2];
6844  rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6845  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6846
6847  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6848  emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6849  DONE;
6850}
6851  [(set_attr "type"
6852		"*,          load,        fpload,      fpload,   store,
6853		 fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6854		 mffgpr")
6855
6856   (set_attr "length"
6857		"4,          4,           4,           4,        4,
6858		 4,          4,           4,           8,        4,
6859		 4")])
6860
6861;; movsi_from_sf with zero extension
6862;;
6863;;		RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6864;;		VSX->VSX     MTVSRWZ
6865
6866(define_insn_and_split "*movdi_from_sf_zero_ext"
6867  [(set (match_operand:DI 0 "gpc_reg_operand"
6868		"=r,         r,           ?*wI,        ?*wH,     r,
6869		 ?wK,        wIwH")
6870
6871	(zero_extend:DI
6872	 (unspec:SI [(match_operand:SF 1 "input_operand"
6873		"r,          m,           Z,           Z,        wIwH,
6874		 wIwH,       r")]
6875		    UNSPEC_SI_FROM_SF)))
6876
6877   (clobber (match_scratch:V4SF 2
6878		"=X,         X,           X,           X,        wa,
6879		 wIwH,       X"))]
6880
6881  "TARGET_DIRECT_MOVE_64BIT
6882   && (register_operand (operands[0], DImode)
6883       || register_operand (operands[1], SImode))"
6884  "@
6885   rldicl %0,%1,0,32
6886   lwz%U1%X1 %0,%1
6887   lfiwzx %0,%y1
6888   lxsiwzx %x0,%y1
6889   #
6890   #
6891   mtvsrwz %x0,%1"
6892  "&& reload_completed
6893   && register_operand (operands[0], DImode)
6894   && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6895  [(const_int 0)]
6896{
6897  rtx op0 = operands[0];
6898  rtx op1 = operands[1];
6899  rtx op2 = operands[2];
6900  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6901
6902  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6903  emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6904  DONE;
6905}
6906  [(set_attr "type"
6907		"*,          load,        fpload,      fpload,   two,
6908		 two,        mffgpr")
6909
6910   (set_attr "length"
6911		"4,          4,           4,           4,        8,
6912		 8,          4")])
6913
6914;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6915;; moving it to SImode.  We cannot do a SFmode store without having to do the
6916;; conversion explicitly since that doesn't work in most cases if the input
6917;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
6918;; former handles cases where the input will not fit in a SFmode, and the
6919;; latter assumes the value has already been rounded.
6920(define_insn "*movsi_from_df"
6921  [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
6922	(unspec:SI [(float_truncate:SF
6923		     (match_operand:DF 1 "gpc_reg_operand" "wa"))]
6924		    UNSPEC_SI_FROM_SF))]
6925  "TARGET_NO_SF_SUBREG"
6926  "xscvdpsp %x0,%x1"
6927  [(set_attr "type" "fp")])
6928
6929;; Split a load of a large constant into the appropriate two-insn
6930;; sequence.
6931
6932(define_split
6933  [(set (match_operand:SI 0 "gpc_reg_operand")
6934	(match_operand:SI 1 "const_int_operand"))]
6935  "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6936   && (INTVAL (operands[1]) & 0xffff) != 0"
6937  [(set (match_dup 0)
6938	(match_dup 2))
6939   (set (match_dup 0)
6940	(ior:SI (match_dup 0)
6941		(match_dup 3)))]
6942{
6943  if (rs6000_emit_set_const (operands[0], operands[1]))
6944    DONE;
6945  else
6946    FAIL;
6947})
6948
6949;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6950(define_split
6951  [(set (match_operand:DI 0 "altivec_register_operand")
6952	(match_operand:DI 1 "xxspltib_constant_split"))]
6953  "TARGET_P9_VECTOR && reload_completed"
6954  [(const_int 0)]
6955{
6956  rtx op0 = operands[0];
6957  rtx op1 = operands[1];
6958  int r = REGNO (op0);
6959  rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6960
6961  emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6962  emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6963  DONE;
6964})
6965
6966(define_insn "*mov<mode>_internal2"
6967  [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6968	(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6969		    (const_int 0)))
6970   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6971  ""
6972  "@
6973   cmp<wd>i %2,%0,0
6974   mr. %0,%1
6975   #"
6976  [(set_attr "type" "cmp,logical,cmp")
6977   (set_attr "dot" "yes")
6978   (set_attr "length" "4,4,8")])
6979
6980(define_split
6981  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6982	(compare:CC (match_operand:P 1 "gpc_reg_operand")
6983		    (const_int 0)))
6984   (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6985  "reload_completed"
6986  [(set (match_dup 0) (match_dup 1))
6987   (set (match_dup 2)
6988	(compare:CC (match_dup 0)
6989		    (const_int 0)))]
6990  "")
6991
6992(define_expand "mov<mode>"
6993  [(set (match_operand:INT 0 "general_operand")
6994	(match_operand:INT 1 "any_operand"))]
6995  ""
6996{
6997  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
6998  DONE;
6999})
7000
7001;;		MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7002;;		XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7003;;		MTVSRWZ     MF%1       MT%1       NOP
7004(define_insn "*mov<mode>_internal"
7005  [(set (match_operand:QHI 0 "nonimmediate_operand"
7006		"=r,        r,         ?*wJwK,    m,         Z,         r,
7007		 ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7008		 ?*wJwK,    r,         *c*l,      *h")
7009
7010	(match_operand:QHI 1 "input_operand"
7011		"r,         m,         Z,         r,         wJwK,      i,
7012		 wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7013		 r,         *h,        r,         0"))]
7014
7015  "gpc_reg_operand (operands[0], <MODE>mode)
7016   || gpc_reg_operand (operands[1], <MODE>mode)"
7017  "@
7018   mr %0,%1
7019   l<wd>z%U1%X1 %0,%1
7020   lxsi<wd>zx %x0,%y1
7021   st<wd>%U0%X0 %1,%0
7022   stxsi<wd>x %x1,%y0
7023   li %0,%1
7024   xxlor %x0,%x1,%x1
7025   xxspltib %x0,0
7026   xxspltib %x0,255
7027   vspltis<wd> %0,%1
7028   #
7029   mfvsrwz %0,%x1
7030   mtvsrwz %x0,%1
7031   mf%1 %0
7032   mt%0 %1
7033   nop"
7034  [(set_attr "type"
7035		"*,         load,      fpload,    store,     fpstore,   *,
7036		 vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7037		 mffgpr,    mfjmpr,    mtjmpr,    *")
7038
7039   (set_attr "length"
7040		"4,         4,         4,         4,         4,         4,
7041		 4,         4,         4,         4,         8,         4,
7042		 4,         4,         4,         4")])
7043
7044
7045;; Here is how to move condition codes around.  When we store CC data in
7046;; an integer register or memory, we store just the high-order 4 bits.
7047;; This lets us not shift in the most common case of CR0.
7048(define_expand "movcc"
7049  [(set (match_operand:CC 0 "nonimmediate_operand")
7050	(match_operand:CC 1 "nonimmediate_operand"))]
7051  ""
7052  "")
7053
7054(define_insn "*movcc_internal1"
7055  [(set (match_operand:CC 0 "nonimmediate_operand"
7056			    "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7057	(match_operand:CC 1 "general_operand"
7058			    " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7059  "register_operand (operands[0], CCmode)
7060   || register_operand (operands[1], CCmode)"
7061  "@
7062   mcrf %0,%1
7063   mtcrf 128,%1
7064   rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7065   crxor %0,%0,%0
7066   mfcr %0%Q1
7067   mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7068   mr %0,%1
7069   li %0,%1
7070   mf%1 %0
7071   mt%0 %1
7072   lwz%U1%X1 %0,%1
7073   stw%U0%X0 %1,%0"
7074  [(set (attr "type")
7075     (cond [(eq_attr "alternative" "0,3")
7076		(const_string "cr_logical")
7077	    (eq_attr "alternative" "1,2")
7078		(const_string "mtcr")
7079	    (eq_attr "alternative" "6,7")
7080		(const_string "integer")
7081	    (eq_attr "alternative" "8")
7082		(const_string "mfjmpr")
7083	    (eq_attr "alternative" "9")
7084		(const_string "mtjmpr")
7085	    (eq_attr "alternative" "10")
7086		(const_string "load")
7087	    (eq_attr "alternative" "11")
7088		(const_string "store")
7089	    (match_test "TARGET_MFCRF")
7090		(const_string "mfcrf")
7091	   ]
7092	(const_string "mfcr")))
7093   (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7094
7095;; For floating-point, we normally deal with the floating-point registers
7096;; unless -msoft-float is used.  The sole exception is that parameter passing
7097;; can produce floating-point values in fixed-point registers.  Unless the
7098;; value is a simple constant or already in memory, we deal with this by
7099;; allocating memory and copying the value explicitly via that memory location.
7100
7101;; Move 32-bit binary/decimal floating point
7102(define_expand "mov<mode>"
7103  [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7104	(match_operand:FMOVE32 1 "any_operand"))]
7105  "<fmove_ok>"
7106{
7107  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7108  DONE;
7109})
7110
7111(define_split
7112  [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7113	(match_operand:FMOVE32 1 "const_double_operand"))]
7114  "reload_completed
7115   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7116       || (GET_CODE (operands[0]) == SUBREG
7117	   && GET_CODE (SUBREG_REG (operands[0])) == REG
7118	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7119  [(set (match_dup 2) (match_dup 3))]
7120{
7121  long l;
7122
7123  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7124
7125  if (! TARGET_POWERPC64)
7126    operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7127  else
7128    operands[2] = gen_lowpart (SImode, operands[0]);
7129
7130  operands[3] = gen_int_mode (l, SImode);
7131})
7132
7133;; Originally, we tried to keep movsf and movsd common, but the differences
7134;; addressing was making it rather difficult to hide with mode attributes.  In
7135;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7136;; before the VSX stores meant that the register allocator would tend to do a
7137;; direct move to the GPR (which involves conversion from scalar to
7138;; vector/memory formats) to save values in the traditional Altivec registers,
7139;; while SDmode had problems on power6 if the GPR store was not first due to
7140;; the power6 not having an integer store operation.
7141;;
7142;;	LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7143;;	STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7144;;	MR           MT<x>      MF<x>       NOP
7145
7146(define_insn "movsf_hardfloat"
7147  [(set (match_operand:SF 0 "nonimmediate_operand"
7148	 "=!r,       f,         wb,         wu,        m,         wY,
7149	  Z,         m,         ww,         !r,        f,         ww,
7150	  !r,        *c*l,      !r,         *h")
7151	(match_operand:SF 1 "input_operand"
7152	 "m,         m,         wY,         Z,         f,         wb,
7153	  wu,        r,         j,          j,         f,         ww,
7154	  r,         r,         *h,         0"))]
7155  "(register_operand (operands[0], SFmode)
7156   || register_operand (operands[1], SFmode))
7157   && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7158   && (TARGET_ALLOW_SF_SUBREG
7159       || valid_sf_si_move (operands[0], operands[1], SFmode))"
7160  "@
7161   lwz%U1%X1 %0,%1
7162   lfs%U1%X1 %0,%1
7163   lxssp %0,%1
7164   lxsspx %x0,%y1
7165   stfs%U0%X0 %1,%0
7166   stxssp %1,%0
7167   stxsspx %x1,%y0
7168   stw%U0%X0 %1,%0
7169   xxlxor %x0,%x0,%x0
7170   li %0,0
7171   fmr %0,%1
7172   xscpsgndp %x0,%x1,%x1
7173   mr %0,%1
7174   mt%0 %1
7175   mf%1 %0
7176   nop"
7177  [(set_attr "type"
7178	"load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7179	 fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7180	 *,          mtjmpr,    mfjmpr,     *")])
7181
7182;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7183;;	FMR          MR         MT%0       MF%1       NOP
7184(define_insn "movsd_hardfloat"
7185  [(set (match_operand:SD 0 "nonimmediate_operand"
7186	 "=!r,       wz,        m,         Z,         ?wh,       ?r,
7187	  f,         !r,        *c*l,      !r,        *h")
7188	(match_operand:SD 1 "input_operand"
7189	 "m,         Z,         r,         wx,        r,         wh,
7190	  f,         r,         r,         *h,        0"))]
7191  "(register_operand (operands[0], SDmode)
7192   || register_operand (operands[1], SDmode))
7193   && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7194  "@
7195   lwz%U1%X1 %0,%1
7196   lfiwzx %0,%y1
7197   stw%U0%X0 %1,%0
7198   stfiwx %1,%y0
7199   mtvsrwz %x0,%1
7200   mfvsrwz %0,%x1
7201   fmr %0,%1
7202   mr %0,%1
7203   mt%0 %1
7204   mf%1 %0
7205   nop"
7206  [(set_attr "type"
7207	"load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7208	 fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7209
7210(define_insn "*mov<mode>_softfloat"
7211  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7212	(match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7213  "(gpc_reg_operand (operands[0], <MODE>mode)
7214   || gpc_reg_operand (operands[1], <MODE>mode))
7215   && TARGET_SOFT_FLOAT"
7216  "@
7217   mr %0,%1
7218   mt%0 %1
7219   mf%1 %0
7220   lwz%U1%X1 %0,%1
7221   stw%U0%X0 %1,%0
7222   li %0,%1
7223   lis %0,%v1
7224   #
7225   #
7226   nop"
7227  [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7228   (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7229
7230;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7231;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7232;;
7233;; Because SF values are actually stored as DF values within the vector
7234;; registers, we need to convert the value to the vector SF format when
7235;; we need to use the bits in a union or similar cases.  We only need
7236;; to do this transformation when the value is a vector register.  Loads,
7237;; stores, and transfers within GPRs are assumed to be safe.
7238;;
7239;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7240;; no alternatives, because the call is created as part of secondary_reload,
7241;; and operand #2's register class is used to allocate the temporary register.
7242;; This function is called before reload, and it creates the temporary as
7243;; needed.
7244
7245;;	    LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7246;;	    STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7247(define_insn_and_split "movsf_from_si"
7248  [(set (match_operand:SF 0 "nonimmediate_operand"
7249	    "=!r,       f,         wb,        wu,        m,         Z,
7250	     Z,         wy,        ?r,        !r")
7251
7252	(unspec:SF [(match_operand:SI 1 "input_operand"
7253	    "m,         m,         wY,        Z,         r,         f,
7254	     wu,        r,         wy,        r")]
7255		   UNSPEC_SF_FROM_SI))
7256
7257   (clobber (match_scratch:DI 2
7258	    "=X,        X,         X,         X,         X,         X,
7259             X,         r,         X,         X"))]
7260
7261  "TARGET_NO_SF_SUBREG
7262   && (register_operand (operands[0], SFmode)
7263       || register_operand (operands[1], SImode))"
7264  "@
7265   lwz%U1%X1 %0,%1
7266   lfs%U1%X1 %0,%1
7267   lxssp %0,%1
7268   lxsspx %x0,%y1
7269   stw%U0%X0 %1,%0
7270   stfiwx %1,%y0
7271   stxsiwx %x1,%y0
7272   #
7273   mfvsrwz %0,%x1
7274   mr %0,%1"
7275
7276  "&& reload_completed
7277   && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7278   && int_reg_operand_not_pseudo (operands[1], SImode)"
7279  [(const_int 0)]
7280{
7281  rtx op0 = operands[0];
7282  rtx op1 = operands[1];
7283  rtx op2 = operands[2];
7284  rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7285
7286  /* Move SF value to upper 32-bits for xscvspdpn.  */
7287  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7288  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7289  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7290  DONE;
7291}
7292  [(set_attr "length"
7293	    "4,          4,         4,         4,         4,         4,
7294	     4,          12,        4,         4")
7295   (set_attr "type"
7296	    "load,       fpload,    fpload,    fpload,    store,     fpstore,
7297	     fpstore,    vecfloat,  mffgpr,    *")])
7298
7299
7300;; Move 64-bit binary/decimal floating point
7301(define_expand "mov<mode>"
7302  [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7303	(match_operand:FMOVE64 1 "any_operand"))]
7304  ""
7305{
7306  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7307  DONE;
7308})
7309
7310(define_split
7311  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7312	(match_operand:FMOVE64 1 "const_int_operand"))]
7313  "! TARGET_POWERPC64 && reload_completed
7314   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7315       || (GET_CODE (operands[0]) == SUBREG
7316	   && GET_CODE (SUBREG_REG (operands[0])) == REG
7317	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7318  [(set (match_dup 2) (match_dup 4))
7319   (set (match_dup 3) (match_dup 1))]
7320{
7321  int endian = (WORDS_BIG_ENDIAN == 0);
7322  HOST_WIDE_INT value = INTVAL (operands[1]);
7323
7324  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7325  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7326  operands[4] = GEN_INT (value >> 32);
7327  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7328})
7329
7330(define_split
7331  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7332	(match_operand:FMOVE64 1 "const_double_operand"))]
7333  "! TARGET_POWERPC64 && reload_completed
7334   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7335       || (GET_CODE (operands[0]) == SUBREG
7336	   && GET_CODE (SUBREG_REG (operands[0])) == REG
7337	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7338  [(set (match_dup 2) (match_dup 4))
7339   (set (match_dup 3) (match_dup 5))]
7340{
7341  int endian = (WORDS_BIG_ENDIAN == 0);
7342  long l[2];
7343
7344  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7345
7346  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7347  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7348  operands[4] = gen_int_mode (l[endian], SImode);
7349  operands[5] = gen_int_mode (l[1 - endian], SImode);
7350})
7351
7352(define_split
7353  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7354	(match_operand:FMOVE64 1 "const_double_operand"))]
7355  "TARGET_POWERPC64 && reload_completed
7356   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7357       || (GET_CODE (operands[0]) == SUBREG
7358	   && GET_CODE (SUBREG_REG (operands[0])) == REG
7359	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7360  [(set (match_dup 2) (match_dup 3))]
7361{
7362  int endian = (WORDS_BIG_ENDIAN == 0);
7363  long l[2];
7364  HOST_WIDE_INT val;
7365
7366  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7367
7368  operands[2] = gen_lowpart (DImode, operands[0]);
7369  /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7370  val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7371         | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7372
7373  operands[3] = gen_int_mode (val, DImode);
7374})
7375
7376;; Don't have reload use general registers to load a constant.  It is
7377;; less efficient than loading the constant into an FP register, since
7378;; it will probably be used there.
7379
7380;; The move constraints are ordered to prefer floating point registers before
7381;; general purpose registers to avoid doing a store and a load to get the value
7382;; into a floating point register when it is needed for a floating point
7383;; operation.  Prefer traditional floating point registers over VSX registers,
7384;; since the D-form version of the memory instructions does not need a GPR for
7385;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7386;; registers.
7387
7388;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7389;; except for 0.0 which can be created on VSX with an xor instruction.
7390
7391(define_insn "*mov<mode>_hardfloat32"
7392  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7393	(match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7394  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7395   && (gpc_reg_operand (operands[0], <MODE>mode)
7396       || gpc_reg_operand (operands[1], <MODE>mode))"
7397  "@
7398   stfd%U0%X0 %1,%0
7399   lfd%U1%X1 %0,%1
7400   fmr %0,%1
7401   lxsd %0,%1
7402   stxsd %1,%0
7403   lxsd%U1x %x0,%y1
7404   stxsd%U0x %x1,%y0
7405   xxlor %x0,%x1,%x1
7406   xxlxor %x0,%x0,%x0
7407   #
7408   #
7409   #
7410   #"
7411  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7412   (set_attr "size" "64")
7413   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7414
7415(define_insn "*mov<mode>_softfloat32"
7416  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7417	(match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7418  "! TARGET_POWERPC64
7419   && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7420   && (gpc_reg_operand (operands[0], <MODE>mode)
7421       || gpc_reg_operand (operands[1], <MODE>mode))"
7422  "#"
7423  [(set_attr "type" "store,load,two,*,*,*")
7424   (set_attr "length" "8,8,8,8,12,16")])
7425
7426; ld/std require word-aligned displacements -> 'Y' constraint.
7427; List Y->r and r->Y before r->r for reload.
7428(define_insn "*mov<mode>_hardfloat64"
7429  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,YZ,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
7430	(match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,YZ,r,r,h,0,wg,r,<f64_dm>,r"))]
7431  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7432   && (gpc_reg_operand (operands[0], <MODE>mode)
7433       || gpc_reg_operand (operands[1], <MODE>mode))"
7434  "@
7435   stfd%U0%X0 %1,%0
7436   lfd%U1%X1 %0,%1
7437   fmr %0,%1
7438   lxsd %0,%1
7439   stxsd %1,%0
7440   lxsd%U1x %x0,%y1
7441   stxsd%U0x %x1,%y0
7442   xxlor %x0,%x1,%x1
7443   xxlxor %x0,%x0,%x0
7444   li %0,0
7445   std%U0%X0 %1,%0
7446   ld%U1%X1 %0,%1
7447   mr %0,%1
7448   mt%0 %1
7449   mf%1 %0
7450   nop
7451   mftgpr %0,%1
7452   mffgpr %0,%1
7453   mfvsrd %0,%x1
7454   mtvsrd %x0,%1"
7455  [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7456   (set_attr "size" "64")
7457   (set_attr "length" "4")])
7458
7459(define_insn "*mov<mode>_softfloat64"
7460  [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7461	(match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7462  "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7463   && (gpc_reg_operand (operands[0], <MODE>mode)
7464       || gpc_reg_operand (operands[1], <MODE>mode))"
7465  "@
7466   std%U0%X0 %1,%0
7467   ld%U1%X1 %0,%1
7468   mr %0,%1
7469   mt%0 %1
7470   mf%1 %0
7471   #
7472   #
7473   #
7474   nop"
7475  [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7476   (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7477
7478(define_expand "mov<mode>"
7479  [(set (match_operand:FMOVE128 0 "general_operand")
7480	(match_operand:FMOVE128 1 "any_operand"))]
7481  ""
7482{
7483  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7484  DONE;
7485})
7486
7487;; It's important to list Y->r and r->Y before r->r because otherwise
7488;; reload, given m->r, will try to pick r->r and reload it, which
7489;; doesn't make progress.
7490
7491;; We can't split little endian direct moves of TDmode, because the words are
7492;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7493;; problematical.  Don't allow direct move for this case.
7494
7495(define_insn_and_split "*mov<mode>_64bit_dm"
7496  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7497	(match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7498  "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7499   && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7500   && (gpc_reg_operand (operands[0], <MODE>mode)
7501       || gpc_reg_operand (operands[1], <MODE>mode))"
7502  "#"
7503  "&& reload_completed"
7504  [(pc)]
7505{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7506  [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7507
7508(define_insn_and_split "*movtd_64bit_nodm"
7509  [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7510	(match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7511  "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7512   && (gpc_reg_operand (operands[0], TDmode)
7513       || gpc_reg_operand (operands[1], TDmode))"
7514  "#"
7515  "&& reload_completed"
7516  [(pc)]
7517{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7518  [(set_attr "length" "8,8,8,12,12,8")])
7519
7520(define_insn_and_split "*mov<mode>_32bit"
7521  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7522	(match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7523  "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7524   && (FLOAT128_2REG_P (<MODE>mode)
7525       || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7526       || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7527   && (gpc_reg_operand (operands[0], <MODE>mode)
7528       || gpc_reg_operand (operands[1], <MODE>mode))"
7529  "#"
7530  "&& reload_completed"
7531  [(pc)]
7532{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7533  [(set_attr "length" "8,8,8,8,20,20,16")])
7534
7535(define_insn_and_split "*mov<mode>_softfloat"
7536  [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7537	(match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7538  "TARGET_SOFT_FLOAT
7539   && (gpc_reg_operand (operands[0], <MODE>mode)
7540       || gpc_reg_operand (operands[1], <MODE>mode))"
7541  "#"
7542  "&& reload_completed"
7543  [(pc)]
7544{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7545  [(set_attr "length" "20,20,16")])
7546
7547(define_expand "extenddf<mode>2"
7548  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7549	(float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7550  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7551{
7552  if (FLOAT128_IEEE_P (<MODE>mode))
7553    rs6000_expand_float128_convert (operands[0], operands[1], false);
7554  else if (TARGET_VSX)
7555    {
7556      if (<MODE>mode == TFmode)
7557	emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7558      else if (<MODE>mode == IFmode)
7559	emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7560      else
7561	gcc_unreachable ();
7562    }
7563   else
7564    {
7565      rtx zero = gen_reg_rtx (DFmode);
7566      rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7567
7568      if (<MODE>mode == TFmode)
7569	emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7570      else if (<MODE>mode == IFmode)
7571	emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7572      else
7573	gcc_unreachable ();
7574    }
7575  DONE;
7576})
7577
7578;; Allow memory operands for the source to be created by the combiner.
7579(define_insn_and_split "extenddf<mode>2_fprs"
7580  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7581	(float_extend:IBM128
7582	 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7583   (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7584  "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7585   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7586  "#"
7587  "&& reload_completed"
7588  [(set (match_dup 3) (match_dup 1))
7589   (set (match_dup 4) (match_dup 2))]
7590{
7591  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7592  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7593
7594  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7595  operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7596})
7597
7598(define_insn_and_split "extenddf<mode>2_vsx"
7599  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7600	(float_extend:IBM128
7601	 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7602  "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7603  "#"
7604  "&& reload_completed"
7605  [(set (match_dup 2) (match_dup 1))
7606   (set (match_dup 3) (match_dup 4))]
7607{
7608  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7609  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7610
7611  operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7612  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7613  operands[4] = CONST0_RTX (DFmode);
7614})
7615
7616(define_expand "extendsf<mode>2"
7617  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7618	(float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7619  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7620{
7621  if (FLOAT128_IEEE_P (<MODE>mode))
7622    rs6000_expand_float128_convert (operands[0], operands[1], false);
7623  else
7624    {
7625      rtx tmp = gen_reg_rtx (DFmode);
7626      emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7627      emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7628    }
7629  DONE;
7630})
7631
7632(define_expand "trunc<mode>df2"
7633  [(set (match_operand:DF 0 "gpc_reg_operand")
7634	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7635  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7636{
7637  if (FLOAT128_IEEE_P (<MODE>mode))
7638    {
7639      rs6000_expand_float128_convert (operands[0], operands[1], false);
7640      DONE;
7641    }
7642})
7643
7644(define_insn_and_split "trunc<mode>df2_internal1"
7645  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7646	(float_truncate:DF
7647	 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7648  "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7649   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7650  "@
7651   #
7652   fmr %0,%1"
7653  "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7654  [(const_int 0)]
7655{
7656  emit_note (NOTE_INSN_DELETED);
7657  DONE;
7658}
7659  [(set_attr "type" "fpsimple")])
7660
7661(define_insn "trunc<mode>df2_internal2"
7662  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7663	(float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7664  "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7665   && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7666  "fadd %0,%1,%L1"
7667  [(set_attr "type" "fp")
7668   (set_attr "fp_type" "fp_addsub_d")])
7669
7670(define_expand "trunc<mode>sf2"
7671  [(set (match_operand:SF 0 "gpc_reg_operand")
7672	(float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7673  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7674{
7675  if (FLOAT128_IEEE_P (<MODE>mode))
7676    rs6000_expand_float128_convert (operands[0], operands[1], false);
7677  else if (<MODE>mode == TFmode)
7678    emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7679  else if (<MODE>mode == IFmode)
7680    emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7681  else
7682    gcc_unreachable ();
7683  DONE;
7684})
7685
7686(define_insn_and_split "trunc<mode>sf2_fprs"
7687  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7688	(float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7689   (clobber (match_scratch:DF 2 "=d"))]
7690  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7691   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7692  "#"
7693  "&& reload_completed"
7694  [(set (match_dup 2)
7695	(float_truncate:DF (match_dup 1)))
7696   (set (match_dup 0)
7697	(float_truncate:SF (match_dup 2)))]
7698  "")
7699
7700(define_expand "floatsi<mode>2"
7701  [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7702		   (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7703	      (clobber (match_scratch:DI 2))])]
7704  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7705{
7706  rtx op0 = operands[0];
7707  rtx op1 = operands[1];
7708
7709  if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7710    ;
7711  else if (FLOAT128_IEEE_P (<MODE>mode))
7712    {
7713      rs6000_expand_float128_convert (op0, op1, false);
7714      DONE;
7715    }
7716  else
7717    {
7718      rtx tmp = gen_reg_rtx (DFmode);
7719      expand_float (tmp, op1, false);
7720      if (<MODE>mode == TFmode)
7721	emit_insn (gen_extenddftf2 (op0, tmp));
7722      else if (<MODE>mode == IFmode)
7723	emit_insn (gen_extenddfif2 (op0, tmp));
7724      else
7725	gcc_unreachable ();
7726      DONE;
7727    }
7728})
7729
7730; fadd, but rounding towards zero.
7731; This is probably not the optimal code sequence.
7732(define_insn "fix_trunc_helper<mode>"
7733  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7734	(unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7735		   UNSPEC_FIX_TRUNC_TF))
7736   (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7737  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7738  "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7739  [(set_attr "type" "fp")
7740   (set_attr "length" "20")])
7741
7742(define_expand "fix_trunc<mode>si2"
7743  [(set (match_operand:SI 0 "gpc_reg_operand")
7744	(fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7745  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7746{
7747  rtx op0 = operands[0];
7748  rtx op1 = operands[1];
7749
7750  if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7751    ;
7752  else
7753    {
7754      if (FLOAT128_IEEE_P (<MODE>mode))
7755	rs6000_expand_float128_convert (op0, op1, false);
7756      else if (<MODE>mode == TFmode)
7757	emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7758      else if (<MODE>mode == IFmode)
7759	emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7760      else
7761	gcc_unreachable ();
7762      DONE;
7763    }
7764})
7765
7766(define_expand "fix_trunc<mode>si2_fprs"
7767  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7768		   (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7769	      (clobber (match_dup 2))
7770	      (clobber (match_dup 3))
7771	      (clobber (match_dup 4))
7772	      (clobber (match_dup 5))])]
7773  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7774{
7775  operands[2] = gen_reg_rtx (DFmode);
7776  operands[3] = gen_reg_rtx (DFmode);
7777  operands[4] = gen_reg_rtx (DImode);
7778  operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7779})
7780
7781(define_insn_and_split "*fix_trunc<mode>si2_internal"
7782  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7783        (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7784   (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7785   (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7786   (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7787   (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7788  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7789  "#"
7790  ""
7791  [(pc)]
7792{
7793  rtx lowword;
7794  emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7795					 operands[3]));
7796
7797  gcc_assert (MEM_P (operands[5]));
7798  lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7799
7800  emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7801  emit_move_insn (operands[5], operands[4]);
7802  emit_move_insn (operands[0], lowword);
7803  DONE;
7804})
7805
7806(define_expand "fix_trunc<mode>di2"
7807  [(set (match_operand:DI 0 "gpc_reg_operand")
7808	(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7809  "TARGET_FLOAT128_TYPE"
7810{
7811  if (!TARGET_FLOAT128_HW)
7812    {
7813      rs6000_expand_float128_convert (operands[0], operands[1], false);
7814      DONE;
7815    }
7816})
7817
7818(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7819  [(set (match_operand:SDI 0 "gpc_reg_operand")
7820	(unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7821  "TARGET_FLOAT128_TYPE"
7822{
7823  rs6000_expand_float128_convert (operands[0], operands[1], true);
7824  DONE;
7825})
7826
7827(define_expand "floatdi<mode>2"
7828  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7829	(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7830  "TARGET_FLOAT128_TYPE"
7831{
7832  if (!TARGET_FLOAT128_HW)
7833    {
7834      rs6000_expand_float128_convert (operands[0], operands[1], false);
7835      DONE;
7836    }
7837})
7838
7839(define_expand "floatunsdi<IEEE128:mode>2"
7840  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7841	(unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7842  "TARGET_FLOAT128_TYPE"
7843{
7844  if (!TARGET_FLOAT128_HW)
7845    {
7846      rs6000_expand_float128_convert (operands[0], operands[1], true);
7847      DONE;
7848    }
7849})
7850
7851(define_expand "floatuns<IEEE128:mode>2"
7852  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7853	(unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
7854  "TARGET_FLOAT128_TYPE"
7855{
7856  rtx op0 = operands[0];
7857  rtx op1 = operands[1];
7858
7859  if (TARGET_FLOAT128_HW)
7860    emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7861  else
7862    rs6000_expand_float128_convert (op0, op1, true);
7863  DONE;
7864})
7865
7866(define_expand "neg<mode>2"
7867  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7868	(neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7869  "FLOAT128_IEEE_P (<MODE>mode)
7870   || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7871{
7872  if (FLOAT128_IEEE_P (<MODE>mode))
7873    {
7874      if (TARGET_FLOAT128_HW)
7875	{
7876	  if (<MODE>mode == TFmode)
7877	    emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7878	  else if (<MODE>mode == KFmode)
7879	    emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7880	  else
7881	    gcc_unreachable ();
7882	}
7883      else if (TARGET_FLOAT128_TYPE)
7884	{
7885	  if (<MODE>mode == TFmode)
7886	    emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7887	  else if (<MODE>mode == KFmode)
7888	    emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7889	  else
7890	    gcc_unreachable ();
7891	}
7892      else
7893	{
7894	  rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7895	  rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7896						<MODE>mode,
7897						operands[1], <MODE>mode);
7898
7899	  if (target && !rtx_equal_p (target, operands[0]))
7900	    emit_move_insn (operands[0], target);
7901	}
7902      DONE;
7903    }
7904})
7905
7906(define_insn "neg<mode>2_internal"
7907  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7908	(neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7909  "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7910{
7911  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7912    return "fneg %L0,%L1\;fneg %0,%1";
7913  else
7914    return "fneg %0,%1\;fneg %L0,%L1";
7915}
7916  [(set_attr "type" "fpsimple")
7917   (set_attr "length" "8")])
7918
7919(define_expand "abs<mode>2"
7920  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7921	(abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7922  "FLOAT128_IEEE_P (<MODE>mode)
7923   || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7924{
7925  rtx label;
7926
7927  if (FLOAT128_IEEE_P (<MODE>mode))
7928    {
7929      if (TARGET_FLOAT128_HW)
7930	{
7931	  if (<MODE>mode == TFmode)
7932	    emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7933	  else if (<MODE>mode == KFmode)
7934	    emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7935	  else
7936	    FAIL;
7937	  DONE;
7938	}
7939      else if (TARGET_FLOAT128_TYPE)
7940	{
7941	  if (<MODE>mode == TFmode)
7942	    emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7943	  else if (<MODE>mode == KFmode)
7944	    emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7945	  else
7946	    FAIL;
7947	  DONE;
7948	}
7949      else
7950	FAIL;
7951    }
7952
7953  label = gen_label_rtx ();
7954  if (<MODE>mode == TFmode)
7955    emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7956  else if (<MODE>mode == IFmode)
7957    emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7958  else
7959    FAIL;
7960  emit_label (label);
7961  DONE;
7962})
7963
7964(define_expand "abs<mode>2_internal"
7965  [(set (match_operand:IBM128 0 "gpc_reg_operand")
7966	(match_operand:IBM128 1 "gpc_reg_operand"))
7967   (set (match_dup 3) (match_dup 5))
7968   (set (match_dup 5) (abs:DF (match_dup 5)))
7969   (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7970   (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7971			   (label_ref (match_operand 2 ""))
7972			   (pc)))
7973   (set (match_dup 6) (neg:DF (match_dup 6)))]
7974  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7975{
7976  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7977  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7978  operands[3] = gen_reg_rtx (DFmode);
7979  operands[4] = gen_reg_rtx (CCFPmode);
7980  operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7981  operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7982})
7983
7984
7985;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7986;; register
7987
7988(define_expand "ieee_128bit_negative_zero"
7989  [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
7990  "TARGET_FLOAT128_TYPE"
7991{
7992  rtvec v = rtvec_alloc (16);
7993  int i, high;
7994
7995  for (i = 0; i < 16; i++)
7996    RTVEC_ELT (v, i) = const0_rtx;
7997
7998  high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7999  RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8000
8001  rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8002  DONE;
8003})
8004
8005;; IEEE 128-bit negate
8006
8007;; We have 2 insns here for negate and absolute value.  The first uses
8008;; match_scratch so that phases like combine can recognize neg/abs as generic
8009;; insns, and second insn after the first split pass loads up the bit to
8010;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8011;; neg/abs to create the constant just once.
8012
8013(define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8014  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8015	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8016   (clobber (match_scratch:V16QI 2 "=v"))]
8017  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8018  "#"
8019  "&& 1"
8020  [(parallel [(set (match_dup 0)
8021		   (neg:IEEE128 (match_dup 1)))
8022	      (use (match_dup 2))])]
8023{
8024  if (GET_CODE (operands[2]) == SCRATCH)
8025    operands[2] = gen_reg_rtx (V16QImode);
8026
8027  operands[3] = gen_reg_rtx (V16QImode);
8028  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8029}
8030  [(set_attr "length" "8")
8031   (set_attr "type" "vecsimple")])
8032
8033(define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8034  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8035	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8036   (use (match_operand:V16QI 2 "register_operand" "v"))]
8037  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8038  "xxlxor %x0,%x1,%x2"
8039  [(set_attr "type" "veclogical")])
8040
8041;; IEEE 128-bit absolute value
8042(define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8043  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8044	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8045   (clobber (match_scratch:V16QI 2 "=v"))]
8046  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8047  "#"
8048  "&& 1"
8049  [(parallel [(set (match_dup 0)
8050		   (abs:IEEE128 (match_dup 1)))
8051	      (use (match_dup 2))])]
8052{
8053  if (GET_CODE (operands[2]) == SCRATCH)
8054    operands[2] = gen_reg_rtx (V16QImode);
8055
8056  operands[3] = gen_reg_rtx (V16QImode);
8057  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8058}
8059  [(set_attr "length" "8")
8060   (set_attr "type" "vecsimple")])
8061
8062(define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8063  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8064	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8065   (use (match_operand:V16QI 2 "register_operand" "v"))]
8066  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8067  "xxlandc %x0,%x1,%x2"
8068  [(set_attr "type" "veclogical")])
8069
8070;; IEEE 128-bit negative absolute value
8071(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8072  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8073	(neg:IEEE128
8074	 (abs:IEEE128
8075	  (match_operand:IEEE128 1 "register_operand" "wa"))))
8076   (clobber (match_scratch:V16QI 2 "=v"))]
8077  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8078   && FLOAT128_IEEE_P (<MODE>mode)"
8079  "#"
8080  "&& 1"
8081  [(parallel [(set (match_dup 0)
8082		   (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8083	      (use (match_dup 2))])]
8084{
8085  if (GET_CODE (operands[2]) == SCRATCH)
8086    operands[2] = gen_reg_rtx (V16QImode);
8087
8088  operands[3] = gen_reg_rtx (V16QImode);
8089  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8090}
8091  [(set_attr "length" "8")
8092   (set_attr "type" "vecsimple")])
8093
8094(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8095  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8096	(neg:IEEE128
8097	 (abs:IEEE128
8098	  (match_operand:IEEE128 1 "register_operand" "wa"))))
8099   (use (match_operand:V16QI 2 "register_operand" "v"))]
8100  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8101  "xxlor %x0,%x1,%x2"
8102  [(set_attr "type" "veclogical")])
8103
8104;; Float128 conversion functions.  These expand to library function calls.
8105;; We use expand to convert from IBM double double to IEEE 128-bit
8106;; and trunc for the opposite.
8107(define_expand "extendiftf2"
8108  [(set (match_operand:TF 0 "gpc_reg_operand")
8109	(float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8110  "TARGET_FLOAT128_TYPE"
8111{
8112  rs6000_expand_float128_convert (operands[0], operands[1], false);
8113  DONE;
8114})
8115
8116(define_expand "extendifkf2"
8117  [(set (match_operand:KF 0 "gpc_reg_operand")
8118	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8119  "TARGET_FLOAT128_TYPE"
8120{
8121  rs6000_expand_float128_convert (operands[0], operands[1], false);
8122  DONE;
8123})
8124
8125(define_expand "extendtfkf2"
8126  [(set (match_operand:KF 0 "gpc_reg_operand")
8127	(float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8128  "TARGET_FLOAT128_TYPE"
8129{
8130  rs6000_expand_float128_convert (operands[0], operands[1], false);
8131  DONE;
8132})
8133
8134(define_expand "extendtfif2"
8135  [(set (match_operand:IF 0 "gpc_reg_operand")
8136	(float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8137  "TARGET_FLOAT128_TYPE"
8138{
8139  rs6000_expand_float128_convert (operands[0], operands[1], false);
8140  DONE;
8141})
8142
8143(define_expand "trunciftf2"
8144  [(set (match_operand:TF 0 "gpc_reg_operand")
8145	(float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8146  "TARGET_FLOAT128_TYPE"
8147{
8148  rs6000_expand_float128_convert (operands[0], operands[1], false);
8149  DONE;
8150})
8151
8152(define_expand "truncifkf2"
8153  [(set (match_operand:KF 0 "gpc_reg_operand")
8154	(float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8155  "TARGET_FLOAT128_TYPE"
8156{
8157  rs6000_expand_float128_convert (operands[0], operands[1], false);
8158  DONE;
8159})
8160
8161(define_expand "trunckftf2"
8162  [(set (match_operand:TF 0 "gpc_reg_operand")
8163	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8164  "TARGET_FLOAT128_TYPE"
8165{
8166  rs6000_expand_float128_convert (operands[0], operands[1], false);
8167  DONE;
8168})
8169
8170(define_expand "trunctfif2"
8171  [(set (match_operand:IF 0 "gpc_reg_operand")
8172	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8173  "TARGET_FLOAT128_TYPE"
8174{
8175  rs6000_expand_float128_convert (operands[0], operands[1], false);
8176  DONE;
8177})
8178
8179(define_insn_and_split "*extend<mode>tf2_internal"
8180  [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8181	(float_extend:TF
8182	 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8183   "TARGET_FLOAT128_TYPE
8184    && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8185  "#"
8186  "&& reload_completed"
8187  [(set (match_dup 0) (match_dup 2))]
8188{
8189  operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8190})
8191
8192(define_insn_and_split "*extendtf<mode>2_internal"
8193  [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8194	(float_extend:IFKF
8195	 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8196   "TARGET_FLOAT128_TYPE
8197    && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8198  "#"
8199  "&& reload_completed"
8200  [(set (match_dup 0) (match_dup 2))]
8201{
8202  operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8203})
8204
8205
8206;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8207;; must have 3 arguments, and scratch register constraint must be a single
8208;; constraint.
8209
8210;; Reload patterns to support gpr load/store with misaligned mem.
8211;; and multiple gpr load/store at offset >= 0xfffc
8212(define_expand "reload_<mode>_store"
8213  [(parallel [(match_operand 0 "memory_operand" "=m")
8214              (match_operand 1 "gpc_reg_operand" "r")
8215              (match_operand:GPR 2 "register_operand" "=&b")])]
8216  ""
8217{
8218  rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8219  DONE;
8220})
8221
8222(define_expand "reload_<mode>_load"
8223  [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8224              (match_operand 1 "memory_operand" "m")
8225              (match_operand:GPR 2 "register_operand" "=b")])]
8226  ""
8227{
8228  rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8229  DONE;
8230})
8231
8232
8233;; Reload patterns for various types using the vector registers.  We may need
8234;; an additional base register to convert the reg+offset addressing to reg+reg
8235;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8236;; index register for gpr registers.
8237(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8238  [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8239              (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8240              (match_operand:P 2 "register_operand" "=b")])]
8241  "<P:tptrsize>"
8242{
8243  rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8244  DONE;
8245})
8246
8247(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8248  [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8249              (match_operand:RELOAD 1 "memory_operand" "m")
8250              (match_operand:P 2 "register_operand" "=b")])]
8251  "<P:tptrsize>"
8252{
8253  rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8254  DONE;
8255})
8256
8257
8258;; Reload sometimes tries to move the address to a GPR, and can generate
8259;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8260;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8261
8262(define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8263  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8264	(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8265		       (match_operand:P 2 "reg_or_cint_operand" "rI"))
8266	       (const_int -16)))]
8267  "TARGET_ALTIVEC && reload_completed"
8268  "#"
8269  "&& reload_completed"
8270  [(set (match_dup 0)
8271	(plus:P (match_dup 1)
8272		(match_dup 2)))
8273   (set (match_dup 0)
8274	(and:P (match_dup 0)
8275	       (const_int -16)))])
8276
8277;; Power8 merge instructions to allow direct move to/from floating point
8278;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8279;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8280;; value, since it is allocated in reload and not all of the flow information
8281;; is setup for it.  We have two patterns to do the two moves between gprs and
8282;; fprs.  There isn't a dependancy between the two, but we could potentially
8283;; schedule other instructions between the two instructions.
8284
8285(define_insn "p8_fmrgow_<mode>"
8286  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8287	(unspec:FMOVE64X [
8288		(match_operand:DF 1 "register_operand" "d")
8289		(match_operand:DF 2 "register_operand" "d")]
8290			 UNSPEC_P8V_FMRGOW))]
8291  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8292  "fmrgow %0,%1,%2"
8293  [(set_attr "type" "fpsimple")])
8294
8295(define_insn "p8_mtvsrwz"
8296  [(set (match_operand:DF 0 "register_operand" "=d")
8297	(unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8298		   UNSPEC_P8V_MTVSRWZ))]
8299  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8300  "mtvsrwz %x0,%1"
8301  [(set_attr "type" "mftgpr")])
8302
8303(define_insn_and_split "reload_fpr_from_gpr<mode>"
8304  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8305	(unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8306			 UNSPEC_P8V_RELOAD_FROM_GPR))
8307   (clobber (match_operand:IF 2 "register_operand" "=d"))]
8308  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8309  "#"
8310  "&& reload_completed"
8311  [(const_int 0)]
8312{
8313  rtx dest = operands[0];
8314  rtx src = operands[1];
8315  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8316  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8317  rtx gpr_hi_reg = gen_highpart (SImode, src);
8318  rtx gpr_lo_reg = gen_lowpart (SImode, src);
8319
8320  emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8321  emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8322  emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8323  DONE;
8324}
8325  [(set_attr "length" "12")
8326   (set_attr "type" "three")])
8327
8328;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8329(define_insn "p8_mtvsrd_df"
8330  [(set (match_operand:DF 0 "register_operand" "=wa")
8331	(unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8332		   UNSPEC_P8V_MTVSRD))]
8333  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8334  "mtvsrd %x0,%1"
8335  [(set_attr "type" "mftgpr")])
8336
8337(define_insn "p8_xxpermdi_<mode>"
8338  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8339	(unspec:FMOVE128_GPR [
8340		(match_operand:DF 1 "register_operand" "wa")
8341		(match_operand:DF 2 "register_operand" "wa")]
8342		UNSPEC_P8V_XXPERMDI))]
8343  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8344  "xxpermdi %x0,%x1,%x2,0"
8345  [(set_attr "type" "vecperm")])
8346
8347(define_insn_and_split "reload_vsx_from_gpr<mode>"
8348  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8349	(unspec:FMOVE128_GPR
8350	 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8351	 UNSPEC_P8V_RELOAD_FROM_GPR))
8352   (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8353  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8354  "#"
8355  "&& reload_completed"
8356  [(const_int 0)]
8357{
8358  rtx dest = operands[0];
8359  rtx src = operands[1];
8360  /* You might think that we could use op0 as one temp and a DF clobber
8361     as op2, but you'd be wrong.  Secondary reload move patterns don't
8362     check for overlap of the clobber and the destination.  */
8363  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8364  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8365  rtx gpr_hi_reg = gen_highpart (DImode, src);
8366  rtx gpr_lo_reg = gen_lowpart (DImode, src);
8367
8368  emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8369  emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8370  emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8371  DONE;
8372}
8373  [(set_attr "length" "12")
8374   (set_attr "type" "three")])
8375
8376(define_split
8377  [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8378	(match_operand:FMOVE128_GPR 1 "input_operand"))]
8379  "reload_completed
8380   && (int_reg_operand (operands[0], <MODE>mode)
8381       || int_reg_operand (operands[1], <MODE>mode))
8382   && (!TARGET_DIRECT_MOVE_128
8383       || (!vsx_register_operand (operands[0], <MODE>mode)
8384           && !vsx_register_operand (operands[1], <MODE>mode)))"
8385  [(pc)]
8386{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8387
8388;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8389;; type is stored internally as double precision in the VSX registers, we have
8390;; to convert it from the vector format.
8391(define_insn "p8_mtvsrd_sf"
8392  [(set (match_operand:SF 0 "register_operand" "=wa")
8393	(unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8394		   UNSPEC_P8V_MTVSRD))]
8395  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8396  "mtvsrd %x0,%1"
8397  [(set_attr "type" "mftgpr")])
8398
8399(define_insn_and_split "reload_vsx_from_gprsf"
8400  [(set (match_operand:SF 0 "register_operand" "=wa")
8401	(unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8402		   UNSPEC_P8V_RELOAD_FROM_GPR))
8403   (clobber (match_operand:DI 2 "register_operand" "=r"))]
8404  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8405  "#"
8406  "&& reload_completed"
8407  [(const_int 0)]
8408{
8409  rtx op0 = operands[0];
8410  rtx op1 = operands[1];
8411  rtx op2 = operands[2];
8412  rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8413
8414  /* Move SF value to upper 32-bits for xscvspdpn.  */
8415  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8416  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8417  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8418  DONE;
8419}
8420  [(set_attr "length" "8")
8421   (set_attr "type" "two")])
8422
8423;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8424;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8425;; and then doing a move of that.
8426(define_insn "p8_mfvsrd_3_<mode>"
8427  [(set (match_operand:DF 0 "register_operand" "=r")
8428	(unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8429		   UNSPEC_P8V_RELOAD_FROM_VSX))]
8430  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8431  "mfvsrd %0,%x1"
8432  [(set_attr "type" "mftgpr")])
8433
8434(define_insn_and_split "reload_gpr_from_vsx<mode>"
8435  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8436	(unspec:FMOVE128_GPR
8437	 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8438	 UNSPEC_P8V_RELOAD_FROM_VSX))
8439   (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8440  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8441  "#"
8442  "&& reload_completed"
8443  [(const_int 0)]
8444{
8445  rtx dest = operands[0];
8446  rtx src = operands[1];
8447  rtx tmp = operands[2];
8448  rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8449  rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8450
8451  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8452  emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8453  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8454  DONE;
8455}
8456  [(set_attr "length" "12")
8457   (set_attr "type" "three")])
8458
8459;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8460;; type is stored internally as double precision, we have to convert it to the
8461;; vector format.
8462
8463(define_insn_and_split "reload_gpr_from_vsxsf"
8464  [(set (match_operand:SF 0 "register_operand" "=r")
8465	(unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8466		   UNSPEC_P8V_RELOAD_FROM_VSX))
8467   (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8468  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8469  "#"
8470  "&& reload_completed"
8471  [(const_int 0)]
8472{
8473  rtx op0 = operands[0];
8474  rtx op1 = operands[1];
8475  rtx op2 = operands[2];
8476  rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8477  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8478
8479  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8480  emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8481  DONE;
8482}
8483  [(set_attr "length" "8")
8484   (set_attr "type" "two")])
8485
8486
8487;; Next come the multi-word integer load and store and the load and store
8488;; multiple insns.
8489
8490;; List r->r after r->Y, otherwise reload will try to reload a
8491;; non-offsettable address by using r->r which won't make progress.
8492;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8493;; a gpr into a fpr instead of reloading an invalid 'Y' address
8494
8495;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8496;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8497;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8498;;        AVX const
8499
8500(define_insn "*movdi_internal32"
8501  [(set (match_operand:DI 0 "nonimmediate_operand"
8502         "=Y,        r,         r,         m,         ^d,         ^d,
8503          r,         wY,        Z,         ^wb,       $wv,        ^wi,
8504          *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8505          *wv")
8506
8507	(match_operand:DI 1 "input_operand"
8508         "r,         Y,         r,         ^d,        m,          ^d,
8509          IJKnGHF,   ^wb,       $wv,       wY,        Z,          ^wi,
8510          Oj,        wM,        OjwM,      Oj,        wM,         wS,
8511          wB"))]
8512
8513  "! TARGET_POWERPC64
8514   && (gpc_reg_operand (operands[0], DImode)
8515       || gpc_reg_operand (operands[1], DImode))"
8516  "@
8517   #
8518   #
8519   #
8520   stfd%U0%X0 %1,%0
8521   lfd%U1%X1 %0,%1
8522   fmr %0,%1
8523   #
8524   stxsd %1,%0
8525   stxsdx %x1,%y0
8526   lxsd %0,%1
8527   lxsdx %x0,%y1
8528   xxlor %x0,%x1,%x1
8529   xxspltib %x0,0
8530   xxspltib %x0,255
8531   vspltisw %0,%1
8532   xxlxor %x0,%x0,%x0
8533   xxlorc %x0,%x0,%x0
8534   #
8535   #"
8536  [(set_attr "type"
8537               "store,     load,      *,         fpstore,    fpload,     fpsimple,
8538                *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8539                vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8540                vecsimple")
8541   (set_attr "size" "64")])
8542
8543(define_split
8544  [(set (match_operand:DI 0 "gpc_reg_operand")
8545	(match_operand:DI 1 "const_int_operand"))]
8546  "! TARGET_POWERPC64 && reload_completed
8547   && gpr_or_gpr_p (operands[0], operands[1])
8548   && !direct_move_p (operands[0], operands[1])"
8549  [(set (match_dup 2) (match_dup 4))
8550   (set (match_dup 3) (match_dup 1))]
8551{
8552  HOST_WIDE_INT value = INTVAL (operands[1]);
8553  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8554				       DImode);
8555  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8556				       DImode);
8557  operands[4] = GEN_INT (value >> 32);
8558  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8559})
8560
8561(define_split
8562  [(set (match_operand:DIFD 0 "nonimmediate_operand")
8563        (match_operand:DIFD 1 "input_operand"))]
8564  "reload_completed && !TARGET_POWERPC64
8565   && gpr_or_gpr_p (operands[0], operands[1])
8566   && !direct_move_p (operands[0], operands[1])"
8567  [(pc)]
8568{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8569
8570;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8571;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8572;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8573;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8574;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8575(define_insn "*movdi_internal64"
8576  [(set (match_operand:DI 0 "nonimmediate_operand"
8577               "=YZ,       r,         r,         r,         r,          r,
8578                m,         ^d,        ^d,        wY,        Z,          $wb,
8579                $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8580                *wi,       *wv,       *wv,       r,         *h,         *h,
8581                ?*r,       ?*wg,      ?*r,       ?*wj")
8582
8583	(match_operand:DI 1 "input_operand"
8584               "r,         YZ,        r,         I,         L,          nF,
8585                ^d,        m,         ^d,        ^wb,       $wv,        wY,
8586                Z,         ^wi,       Oj,        wM,        OjwM,       Oj,
8587                wM,        wS,        wB,        *h,        r,          0,
8588                wg,        r,         wj,        r"))]
8589
8590  "TARGET_POWERPC64
8591   && (gpc_reg_operand (operands[0], DImode)
8592       || gpc_reg_operand (operands[1], DImode))"
8593  "@
8594   std%U0%X0 %1,%0
8595   ld%U1%X1 %0,%1
8596   mr %0,%1
8597   li %0,%1
8598   lis %0,%v1
8599   #
8600   stfd%U0%X0 %1,%0
8601   lfd%U1%X1 %0,%1
8602   fmr %0,%1
8603   stxsd %1,%0
8604   stxsdx %x1,%y0
8605   lxsd %0,%1
8606   lxsdx %x0,%y1
8607   xxlor %x0,%x1,%x1
8608   xxspltib %x0,0
8609   xxspltib %x0,255
8610   #
8611   xxlxor %x0,%x0,%x0
8612   xxlorc %x0,%x0,%x0
8613   #
8614   #
8615   mf%1 %0
8616   mt%0 %1
8617   nop
8618   mftgpr %0,%1
8619   mffgpr %0,%1
8620   mfvsrd %0,%x1
8621   mtvsrd %x0,%1"
8622  [(set_attr "type"
8623               "store,      load,	*,         *,         *,         *,
8624                fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8625                fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8626                veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8627                mftgpr,     mffgpr,     mftgpr,    mffgpr")
8628
8629   (set_attr "size" "64")
8630   (set_attr "length"
8631               "4,         4,         4,         4,         4,          20,
8632                4,         4,         4,         4,         4,          4,
8633                4,         4,         4,         4,         4,          8,
8634                8,         4,         4,         4,         4,          4,
8635                4,         4,         4,         4")])
8636
8637; Some DImode loads are best done as a load of -1 followed by a mask
8638; instruction.
8639(define_split
8640  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8641	(match_operand:DI 1 "const_int_operand"))]
8642  "TARGET_POWERPC64
8643   && num_insns_constant (operands[1], DImode) > 1
8644   && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8645   && rs6000_is_valid_and_mask (operands[1], DImode)"
8646  [(set (match_dup 0)
8647	(const_int -1))
8648   (set (match_dup 0)
8649	(and:DI (match_dup 0)
8650		(match_dup 1)))]
8651  "")
8652
8653;; Split a load of a large constant into the appropriate five-instruction
8654;; sequence.  Handle anything in a constant number of insns.
8655;; When non-easy constants can go in the TOC, this should use
8656;; easy_fp_constant predicate.
8657(define_split
8658  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8659	(match_operand:DI 1 "const_int_operand"))]
8660  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8661  [(set (match_dup 0) (match_dup 2))
8662   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8663{
8664  if (rs6000_emit_set_const (operands[0], operands[1]))
8665    DONE;
8666  else
8667    FAIL;
8668})
8669
8670(define_split
8671  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8672	(match_operand:DI 1 "const_scalar_int_operand"))]
8673  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8674  [(set (match_dup 0) (match_dup 2))
8675   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8676{
8677  if (rs6000_emit_set_const (operands[0], operands[1]))
8678    DONE;
8679  else
8680    FAIL;
8681})
8682
8683(define_split
8684  [(set (match_operand:DI 0 "altivec_register_operand")
8685	(match_operand:DI 1 "s5bit_cint_operand"))]
8686  "TARGET_VSX && reload_completed"
8687  [(const_int 0)]
8688{
8689  rtx op0 = operands[0];
8690  rtx op1 = operands[1];
8691  int r = REGNO (op0);
8692  rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8693
8694  emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8695  if (op1 != const0_rtx && op1 != constm1_rtx)
8696    {
8697      rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8698      emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8699    }
8700  DONE;
8701})
8702
8703;; Split integer constants that can be loaded with XXSPLTIB and a
8704;; sign extend operation.
8705(define_split
8706  [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8707	(match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8708  "TARGET_P9_VECTOR && reload_completed"
8709  [(const_int 0)]
8710{
8711  rtx op0 = operands[0];
8712  rtx op1 = operands[1];
8713  int r = REGNO (op0);
8714  rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8715
8716  emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8717  if (<MODE>mode == DImode)
8718    emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8719  else if (<MODE>mode == SImode)
8720    emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8721  else if (<MODE>mode == HImode)
8722    {
8723      rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8724      emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8725    }
8726  DONE;
8727})
8728
8729
8730;; TImode/PTImode is similar, except that we usually want to compute the
8731;; address into a register and use lsi/stsi (the exception is during reload).
8732
8733(define_insn "*mov<mode>_string"
8734  [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8735	(match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8736  "! TARGET_POWERPC64
8737   && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8738   && (gpc_reg_operand (operands[0], <MODE>mode)
8739       || gpc_reg_operand (operands[1], <MODE>mode))"
8740  "#"
8741  [(set_attr "type" "store,store,load,load,*,*")
8742   (set_attr "update" "yes")
8743   (set_attr "indexed" "yes")
8744   (set_attr "cell_micro" "conditional")])
8745
8746(define_insn "*mov<mode>_ppc64"
8747  [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8748	(match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8749  "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8750   && (gpc_reg_operand (operands[0], <MODE>mode)
8751       || gpc_reg_operand (operands[1], <MODE>mode)))"
8752{
8753  return rs6000_output_move_128bit (operands);
8754}
8755  [(set_attr "type" "store,store,load,load,*,*")
8756   (set_attr "length" "8")])
8757
8758(define_split
8759  [(set (match_operand:TI2 0 "int_reg_operand")
8760	(match_operand:TI2 1 "const_scalar_int_operand"))]
8761  "TARGET_POWERPC64
8762   && (VECTOR_MEM_NONE_P (<MODE>mode)
8763       || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8764  [(set (match_dup 2) (match_dup 4))
8765   (set (match_dup 3) (match_dup 5))]
8766{
8767  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8768				       <MODE>mode);
8769  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8770				       <MODE>mode);
8771  if (CONST_WIDE_INT_P (operands[1]))
8772    {
8773      operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8774      operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8775    }
8776  else if (CONST_INT_P (operands[1]))
8777    {
8778      operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8779      operands[5] = operands[1];
8780    }
8781  else
8782    FAIL;
8783})
8784
8785(define_split
8786  [(set (match_operand:TI2 0 "nonimmediate_operand")
8787        (match_operand:TI2 1 "input_operand"))]
8788  "reload_completed
8789   && gpr_or_gpr_p (operands[0], operands[1])
8790   && !direct_move_p (operands[0], operands[1])
8791   && !quad_load_store_p (operands[0], operands[1])"
8792  [(pc)]
8793{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8794
8795(define_expand "setmemsi"
8796  [(parallel [(set (match_operand:BLK 0 "")
8797		   (match_operand 2 "const_int_operand"))
8798	      (use (match_operand:SI 1 ""))
8799	      (use (match_operand:SI 3 ""))])]
8800  ""
8801{
8802  /* If value to set is not zero, use the library routine.  */
8803  if (operands[2] != const0_rtx)
8804    FAIL;
8805
8806  if (expand_block_clear (operands))
8807    DONE;
8808  else
8809    FAIL;
8810})
8811
8812;; String compare N insn.
8813;; Argument 0 is the target (result)
8814;; Argument 1 is the destination
8815;; Argument 2 is the source
8816;; Argument 3 is the length
8817;; Argument 4 is the alignment
8818
8819(define_expand "cmpstrnsi"
8820  [(parallel [(set (match_operand:SI 0)
8821               (compare:SI (match_operand:BLK 1)
8822                           (match_operand:BLK 2)))
8823	      (use (match_operand:SI 3))
8824	      (use (match_operand:SI 4))])]
8825  "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8826{
8827  if (optimize_insn_for_size_p ())
8828    FAIL;
8829
8830  if (expand_strn_compare (operands, 0))
8831    DONE;
8832  else
8833    FAIL;
8834})
8835
8836;; String compare insn.
8837;; Argument 0 is the target (result)
8838;; Argument 1 is the destination
8839;; Argument 2 is the source
8840;; Argument 3 is the alignment
8841
8842(define_expand "cmpstrsi"
8843  [(parallel [(set (match_operand:SI 0)
8844               (compare:SI (match_operand:BLK 1)
8845                           (match_operand:BLK 2)))
8846	      (use (match_operand:SI 3))])]
8847  "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8848{
8849  if (optimize_insn_for_size_p ())
8850    FAIL;
8851
8852  if (expand_strn_compare (operands, 1))
8853    DONE;
8854  else
8855    FAIL;
8856})
8857
8858;; Block compare insn.
8859;; Argument 0 is the target (result)
8860;; Argument 1 is the destination
8861;; Argument 2 is the source
8862;; Argument 3 is the length
8863;; Argument 4 is the alignment
8864
8865(define_expand "cmpmemsi"
8866  [(parallel [(set (match_operand:SI 0)
8867               (compare:SI (match_operand:BLK 1)
8868                           (match_operand:BLK 2)))
8869	      (use (match_operand:SI 3))
8870	      (use (match_operand:SI 4))])]
8871  "TARGET_POPCNTD"
8872{
8873  if (expand_block_compare (operands))
8874    DONE;
8875  else
8876    FAIL;
8877})
8878
8879;; String/block move insn.
8880;; Argument 0 is the destination
8881;; Argument 1 is the source
8882;; Argument 2 is the length
8883;; Argument 3 is the alignment
8884
8885(define_expand "movmemsi"
8886  [(parallel [(set (match_operand:BLK 0 "")
8887		   (match_operand:BLK 1 ""))
8888	      (use (match_operand:SI 2 ""))
8889	      (use (match_operand:SI 3 ""))])]
8890  ""
8891{
8892  if (expand_block_move (operands))
8893    DONE;
8894  else
8895    FAIL;
8896})
8897
8898;; Define insns that do load or store with update.  Some of these we can
8899;; get by using pre-decrement or pre-increment, but the hardware can also
8900;; do cases where the increment is not the size of the object.
8901;;
8902;; In all these cases, we use operands 0 and 1 for the register being
8903;; incremented because those are the operands that local-alloc will
8904;; tie and these are the pair most likely to be tieable (and the ones
8905;; that will benefit the most).
8906
8907(define_insn "*movdi_update1"
8908  [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8909	(mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8910			 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8911   (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8912	(plus:DI (match_dup 1) (match_dup 2)))]
8913  "TARGET_POWERPC64 && TARGET_UPDATE
8914   && (!avoiding_indexed_address_p (DImode)
8915       || !gpc_reg_operand (operands[2], DImode))"
8916  "@
8917   ldux %3,%0,%2
8918   ldu %3,%2(%0)"
8919  [(set_attr "type" "load")
8920   (set_attr "update" "yes")
8921   (set_attr "indexed" "yes,no")])
8922
8923(define_insn "movdi_<mode>_update"
8924  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8925			 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8926	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
8927   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8928	(plus:P (match_dup 1) (match_dup 2)))]
8929  "TARGET_POWERPC64 && TARGET_UPDATE
8930   && (!avoiding_indexed_address_p (Pmode)
8931       || !gpc_reg_operand (operands[2], Pmode)
8932       || (REG_P (operands[0])
8933	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8934  "@
8935   stdux %3,%0,%2
8936   stdu %3,%2(%0)"
8937  [(set_attr "type" "store")
8938   (set_attr "update" "yes")
8939   (set_attr "indexed" "yes,no")])
8940
8941;; This pattern is only conditional on TARGET_POWERPC64, as it is
8942;; needed for stack allocation, even if the user passes -mno-update.
8943(define_insn "movdi_<mode>_update_stack"
8944  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8945			 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8946	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
8947   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8948	(plus:P (match_dup 1) (match_dup 2)))]
8949  "TARGET_POWERPC64"
8950  "@
8951   stdux %3,%0,%2
8952   stdu %3,%2(%0)"
8953  [(set_attr "type" "store")
8954   (set_attr "update" "yes")
8955   (set_attr "indexed" "yes,no")])
8956
8957(define_insn "*movsi_update1"
8958  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8959	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8960			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8961   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8962	(plus:SI (match_dup 1) (match_dup 2)))]
8963  "TARGET_UPDATE
8964   && (!avoiding_indexed_address_p (SImode)
8965       || !gpc_reg_operand (operands[2], SImode))"
8966  "@
8967   lwzux %3,%0,%2
8968   lwzu %3,%2(%0)"
8969  [(set_attr "type" "load")
8970   (set_attr "update" "yes")
8971   (set_attr "indexed" "yes,no")])
8972
8973(define_insn "*movsi_update2"
8974  [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8975	(sign_extend:DI
8976	 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8977			  (match_operand:DI 2 "gpc_reg_operand" "r")))))
8978   (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8979	(plus:DI (match_dup 1) (match_dup 2)))]
8980  "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
8981  "lwaux %3,%0,%2"
8982  [(set_attr "type" "load")
8983   (set_attr "sign_extend" "yes")
8984   (set_attr "update" "yes")
8985   (set_attr "indexed" "yes")])
8986
8987(define_insn "movsi_update"
8988  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8989			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8990	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
8991   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8992	(plus:SI (match_dup 1) (match_dup 2)))]
8993  "TARGET_UPDATE
8994   && (!avoiding_indexed_address_p (SImode)
8995       || !gpc_reg_operand (operands[2], SImode)
8996       || (REG_P (operands[0])
8997	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8998  "@
8999   stwux %3,%0,%2
9000   stwu %3,%2(%0)"
9001  [(set_attr "type" "store")
9002   (set_attr "update" "yes")
9003   (set_attr "indexed" "yes,no")])
9004
9005;; This is an unconditional pattern; needed for stack allocation, even
9006;; if the user passes -mno-update.
9007(define_insn "movsi_update_stack"
9008  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9009			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9010	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
9011   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9012	(plus:SI (match_dup 1) (match_dup 2)))]
9013  ""
9014  "@
9015   stwux %3,%0,%2
9016   stwu %3,%2(%0)"
9017  [(set_attr "type" "store")
9018   (set_attr "update" "yes")
9019   (set_attr "indexed" "yes,no")])
9020
9021(define_insn "*movhi_update1"
9022  [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9023	(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9024			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9025   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9026	(plus:SI (match_dup 1) (match_dup 2)))]
9027  "TARGET_UPDATE
9028   && (!avoiding_indexed_address_p (SImode)
9029       || !gpc_reg_operand (operands[2], SImode))"
9030  "@
9031   lhzux %3,%0,%2
9032   lhzu %3,%2(%0)"
9033  [(set_attr "type" "load")
9034   (set_attr "update" "yes")
9035   (set_attr "indexed" "yes,no")])
9036
9037(define_insn "*movhi_update2"
9038  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9039	(zero_extend:SI
9040	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9041			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9042   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9043	(plus:SI (match_dup 1) (match_dup 2)))]
9044  "TARGET_UPDATE
9045   && (!avoiding_indexed_address_p (SImode)
9046       || !gpc_reg_operand (operands[2], SImode))"
9047  "@
9048   lhzux %3,%0,%2
9049   lhzu %3,%2(%0)"
9050  [(set_attr "type" "load")
9051   (set_attr "update" "yes")
9052   (set_attr "indexed" "yes,no")])
9053
9054(define_insn "*movhi_update3"
9055  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9056	(sign_extend:SI
9057	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9058			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9059   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9060	(plus:SI (match_dup 1) (match_dup 2)))]
9061  "TARGET_UPDATE
9062   && !(avoiding_indexed_address_p (SImode)
9063	&& gpc_reg_operand (operands[2], SImode))"
9064  "@
9065   lhaux %3,%0,%2
9066   lhau %3,%2(%0)"
9067  [(set_attr "type" "load")
9068   (set_attr "sign_extend" "yes")
9069   (set_attr "update" "yes")
9070   (set_attr "indexed" "yes,no")])
9071
9072(define_insn "*movhi_update4"
9073  [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9074			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9075	(match_operand:HI 3 "gpc_reg_operand" "r,r"))
9076   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9077	(plus:SI (match_dup 1) (match_dup 2)))]
9078  "TARGET_UPDATE
9079   && (!avoiding_indexed_address_p (SImode)
9080       || !gpc_reg_operand (operands[2], SImode))"
9081  "@
9082   sthux %3,%0,%2
9083   sthu %3,%2(%0)"
9084  [(set_attr "type" "store")
9085   (set_attr "update" "yes")
9086   (set_attr "indexed" "yes,no")])
9087
9088(define_insn "*movqi_update1"
9089  [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9090	(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9091			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9092   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9093	(plus:SI (match_dup 1) (match_dup 2)))]
9094  "TARGET_UPDATE
9095   && (!avoiding_indexed_address_p (SImode)
9096       || !gpc_reg_operand (operands[2], SImode))"
9097  "@
9098   lbzux %3,%0,%2
9099   lbzu %3,%2(%0)"
9100  [(set_attr "type" "load")
9101   (set_attr "update" "yes")
9102   (set_attr "indexed" "yes,no")])
9103
9104(define_insn "*movqi_update2"
9105  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9106	(zero_extend:SI
9107	 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9108			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9109   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9110	(plus:SI (match_dup 1) (match_dup 2)))]
9111  "TARGET_UPDATE
9112   && (!avoiding_indexed_address_p (SImode)
9113       || !gpc_reg_operand (operands[2], SImode))"
9114  "@
9115   lbzux %3,%0,%2
9116   lbzu %3,%2(%0)"
9117  [(set_attr "type" "load")
9118   (set_attr "update" "yes")
9119   (set_attr "indexed" "yes,no")])
9120
9121(define_insn "*movqi_update3"
9122  [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9123			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9124	(match_operand:QI 3 "gpc_reg_operand" "r,r"))
9125   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9126	(plus:SI (match_dup 1) (match_dup 2)))]
9127  "TARGET_UPDATE
9128   && (!avoiding_indexed_address_p (SImode)
9129       || !gpc_reg_operand (operands[2], SImode))"
9130  "@
9131   stbux %3,%0,%2
9132   stbu %3,%2(%0)"
9133  [(set_attr "type" "store")
9134   (set_attr "update" "yes")
9135   (set_attr "indexed" "yes,no")])
9136
9137(define_insn "*movsf_update1"
9138  [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9139	(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9140			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9141   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9142	(plus:SI (match_dup 1) (match_dup 2)))]
9143  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9144   && (!avoiding_indexed_address_p (SImode)
9145       || !gpc_reg_operand (operands[2], SImode))"
9146  "@
9147   lfsux %3,%0,%2
9148   lfsu %3,%2(%0)"
9149  [(set_attr "type" "fpload")
9150   (set_attr "update" "yes")
9151   (set_attr "indexed" "yes,no")])
9152
9153(define_insn "*movsf_update2"
9154  [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9155			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9156	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
9157   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9158	(plus:SI (match_dup 1) (match_dup 2)))]
9159  "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9160   && (!avoiding_indexed_address_p (SImode)
9161       || !gpc_reg_operand (operands[2], SImode))"
9162  "@
9163   stfsux %3,%0,%2
9164   stfsu %3,%2(%0)"
9165  [(set_attr "type" "fpstore")
9166   (set_attr "update" "yes")
9167   (set_attr "indexed" "yes,no")])
9168
9169(define_insn "*movsf_update3"
9170  [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9171	(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9172			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9173   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9174	(plus:SI (match_dup 1) (match_dup 2)))]
9175  "TARGET_SOFT_FLOAT && TARGET_UPDATE
9176   && (!avoiding_indexed_address_p (SImode)
9177       || !gpc_reg_operand (operands[2], SImode))"
9178  "@
9179   lwzux %3,%0,%2
9180   lwzu %3,%2(%0)"
9181  [(set_attr "type" "load")
9182   (set_attr "update" "yes")
9183   (set_attr "indexed" "yes,no")])
9184
9185(define_insn "*movsf_update4"
9186  [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9187			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9188	(match_operand:SF 3 "gpc_reg_operand" "r,r"))
9189   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9190	(plus:SI (match_dup 1) (match_dup 2)))]
9191  "TARGET_SOFT_FLOAT && TARGET_UPDATE
9192   && (!avoiding_indexed_address_p (SImode)
9193       || !gpc_reg_operand (operands[2], SImode))"
9194  "@
9195   stwux %3,%0,%2
9196   stwu %3,%2(%0)"
9197  [(set_attr "type" "store")
9198   (set_attr "update" "yes")
9199   (set_attr "indexed" "yes,no")])
9200
9201(define_insn "*movdf_update1"
9202  [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9203	(mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9204			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9205   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9206	(plus:SI (match_dup 1) (match_dup 2)))]
9207  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9208   && (!avoiding_indexed_address_p (SImode)
9209       || !gpc_reg_operand (operands[2], SImode))"
9210  "@
9211   lfdux %3,%0,%2
9212   lfdu %3,%2(%0)"
9213  [(set_attr "type" "fpload")
9214   (set_attr "update" "yes")
9215   (set_attr "indexed" "yes,no")
9216   (set_attr "size" "64")])
9217
9218(define_insn "*movdf_update2"
9219  [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9220			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9221	(match_operand:DF 3 "gpc_reg_operand" "d,d"))
9222   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9223	(plus:SI (match_dup 1) (match_dup 2)))]
9224  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9225   && (!avoiding_indexed_address_p (SImode)
9226       || !gpc_reg_operand (operands[2], SImode))"
9227  "@
9228   stfdux %3,%0,%2
9229   stfdu %3,%2(%0)"
9230  [(set_attr "type" "fpstore")
9231   (set_attr "update" "yes")
9232   (set_attr "indexed" "yes,no")])
9233
9234
9235;; After inserting conditional returns we can sometimes have
9236;; unnecessary register moves.  Unfortunately we cannot have a
9237;; modeless peephole here, because some single SImode sets have early
9238;; clobber outputs.  Although those sets expand to multi-ppc-insn
9239;; sequences, using get_attr_length here will smash the operands
9240;; array.  Neither is there an early_cobbler_p predicate.
9241;; Also this optimization interferes with scalars going into
9242;; altivec registers (the code does reloading through the FPRs).
9243(define_peephole2
9244  [(set (match_operand:DF 0 "gpc_reg_operand")
9245	(match_operand:DF 1 "any_operand"))
9246   (set (match_operand:DF 2 "gpc_reg_operand")
9247	(match_dup 0))]
9248  "!TARGET_VSX
9249   && peep2_reg_dead_p (2, operands[0])"
9250  [(set (match_dup 2) (match_dup 1))])
9251
9252(define_peephole2
9253  [(set (match_operand:SF 0 "gpc_reg_operand")
9254	(match_operand:SF 1 "any_operand"))
9255   (set (match_operand:SF 2 "gpc_reg_operand")
9256	(match_dup 0))]
9257  "!TARGET_P8_VECTOR
9258   && peep2_reg_dead_p (2, operands[0])"
9259  [(set (match_dup 2) (match_dup 1))])
9260
9261
9262;; TLS support.
9263
9264;; Mode attributes for different ABIs.
9265(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9266(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9267(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9268(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9269
9270(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9271  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9272        (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9273	      (match_operand 4 "" "g")))
9274   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9275	 	    (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9276		   UNSPEC_TLSGD)
9277   (clobber (reg:SI LR_REGNO))]
9278  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9279{
9280  if (TARGET_CMODEL != CMODEL_SMALL)
9281    return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9282	   "bl %z3\;nop";
9283  else
9284    return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9285}
9286  "&& TARGET_TLS_MARKERS"
9287  [(set (match_dup 0)
9288	(unspec:TLSmode [(match_dup 1)
9289			 (match_dup 2)]
9290			UNSPEC_TLSGD))
9291   (parallel [(set (match_dup 0)
9292   	     	   (call (mem:TLSmode (match_dup 3))
9293		   	 (match_dup 4)))
9294	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9295	      (clobber (reg:SI LR_REGNO))])]
9296  ""
9297  [(set_attr "type" "two")
9298   (set (attr "length")
9299     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9300     		   (const_int 16)
9301     		   (const_int 12)))])
9302
9303(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9304  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9305        (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9306	      (match_operand 4 "" "g")))
9307   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9308	 	    (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9309		   UNSPEC_TLSGD)
9310   (clobber (reg:SI LR_REGNO))]
9311  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9312{
9313  if (flag_pic)
9314    {
9315      if (TARGET_SECURE_PLT && flag_pic == 2)
9316	return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9317      else
9318	return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9319    }
9320  else
9321    return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9322}
9323  "&& TARGET_TLS_MARKERS"
9324  [(set (match_dup 0)
9325	(unspec:TLSmode [(match_dup 1)
9326			 (match_dup 2)]
9327			UNSPEC_TLSGD))
9328   (parallel [(set (match_dup 0)
9329   	     	   (call (mem:TLSmode (match_dup 3))
9330		   	 (match_dup 4)))
9331	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9332	      (clobber (reg:SI LR_REGNO))])]
9333  ""
9334  [(set_attr "type" "two")
9335   (set_attr "length" "8")])
9336
9337(define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9338  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9339	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9340			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9341			UNSPEC_TLSGD))]
9342  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9343  "addi %0,%1,%2@got@tlsgd"
9344  "&& TARGET_CMODEL != CMODEL_SMALL"
9345  [(set (match_dup 3)
9346  	(high:TLSmode
9347	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9348   (set (match_dup 0)
9349   	(lo_sum:TLSmode (match_dup 3)
9350	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9351{
9352  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9353}
9354  [(set (attr "length")
9355     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9356     		   (const_int 8)
9357     		   (const_int 4)))])
9358
9359(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9360  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9361     (high:TLSmode
9362       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9363			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9364		       UNSPEC_TLSGD)))]
9365  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9366  "addis %0,%1,%2@got@tlsgd@ha"
9367  [(set_attr "length" "4")])
9368
9369(define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9370  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9371     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9372       (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9373			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9374		       UNSPEC_TLSGD)))]
9375  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9376  "addi %0,%1,%2@got@tlsgd@l"
9377  [(set_attr "length" "4")])
9378
9379(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9380  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9381        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9382	      (match_operand 2 "" "g")))
9383   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9384		   UNSPEC_TLSGD)
9385   (clobber (reg:SI LR_REGNO))]
9386  "HAVE_AS_TLS && TARGET_TLS_MARKERS
9387   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9388  "bl %z1(%3@tlsgd)\;nop"
9389  [(set_attr "type" "branch")
9390   (set_attr "length" "8")])
9391
9392(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9393  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9394        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9395	      (match_operand 2 "" "g")))
9396   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9397		   UNSPEC_TLSGD)
9398   (clobber (reg:SI LR_REGNO))]
9399  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9400{
9401  if (flag_pic)
9402    {
9403      if (TARGET_SECURE_PLT && flag_pic == 2)
9404	return "bl %z1+32768(%3@tlsgd)@plt";
9405      return "bl %z1(%3@tlsgd)@plt";
9406    }
9407  return "bl %z1(%3@tlsgd)";
9408}
9409  [(set_attr "type" "branch")
9410   (set_attr "length" "4")])
9411
9412(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9413  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9414        (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9415	      (match_operand 3 "" "g")))
9416   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9417		   UNSPEC_TLSLD)
9418   (clobber (reg:SI LR_REGNO))]
9419  "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9420{
9421  if (TARGET_CMODEL != CMODEL_SMALL)
9422    return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9423	   "bl %z2\;nop";
9424  else
9425    return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9426}
9427  "&& TARGET_TLS_MARKERS"
9428  [(set (match_dup 0)
9429	(unspec:TLSmode [(match_dup 1)]
9430			UNSPEC_TLSLD))
9431   (parallel [(set (match_dup 0)
9432   	     	   (call (mem:TLSmode (match_dup 2))
9433		   	 (match_dup 3)))
9434	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9435	      (clobber (reg:SI LR_REGNO))])]
9436  ""
9437  [(set_attr "type" "two")
9438   (set (attr "length")
9439     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9440     		   (const_int 16)
9441     		   (const_int 12)))])
9442
9443(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9444  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9445        (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9446	      (match_operand 3 "" "g")))
9447   (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9448		   UNSPEC_TLSLD)
9449   (clobber (reg:SI LR_REGNO))]
9450  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9451{
9452  if (flag_pic)
9453    {
9454      if (TARGET_SECURE_PLT && flag_pic == 2)
9455	return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9456      else
9457	return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9458    }
9459  else
9460    return "addi %0,%1,%&@got@tlsld\;bl %z2";
9461}
9462  "&& TARGET_TLS_MARKERS"
9463  [(set (match_dup 0)
9464	(unspec:TLSmode [(match_dup 1)]
9465			UNSPEC_TLSLD))
9466   (parallel [(set (match_dup 0)
9467   	     	   (call (mem:TLSmode (match_dup 2))
9468		   	 (match_dup 3)))
9469	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9470	      (clobber (reg:SI LR_REGNO))])]
9471  ""
9472  [(set_attr "length" "8")])
9473
9474(define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9475  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9476	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9477			UNSPEC_TLSLD))]
9478  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9479  "addi %0,%1,%&@got@tlsld"
9480  "&& TARGET_CMODEL != CMODEL_SMALL"
9481  [(set (match_dup 2)
9482  	(high:TLSmode
9483	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9484   (set (match_dup 0)
9485   	(lo_sum:TLSmode (match_dup 2)
9486	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9487{
9488  operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9489}
9490  [(set (attr "length")
9491     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9492     		   (const_int 8)
9493     		   (const_int 4)))])
9494
9495(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9496  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9497     (high:TLSmode
9498       (unspec:TLSmode [(const_int 0)
9499			(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9500		       UNSPEC_TLSLD)))]
9501  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9502  "addis %0,%1,%&@got@tlsld@ha"
9503  [(set_attr "length" "4")])
9504
9505(define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9506  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9507     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9508       (unspec:TLSmode [(const_int 0)
9509                        (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9510                       UNSPEC_TLSLD)))]
9511  "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9512  "addi %0,%1,%&@got@tlsld@l"
9513  [(set_attr "length" "4")])
9514
9515(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9516  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9517        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9518	      (match_operand 2 "" "g")))
9519   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9520   (clobber (reg:SI LR_REGNO))]
9521  "HAVE_AS_TLS && TARGET_TLS_MARKERS
9522   && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9523  "bl %z1(%&@tlsld)\;nop"
9524  [(set_attr "type" "branch")
9525   (set_attr "length" "8")])
9526
9527(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9528  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9529        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9530	      (match_operand 2 "" "g")))
9531   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9532   (clobber (reg:SI LR_REGNO))]
9533  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9534{
9535  if (flag_pic)
9536    {
9537      if (TARGET_SECURE_PLT && flag_pic == 2)
9538	return "bl %z1+32768(%&@tlsld)@plt";
9539      return "bl %z1(%&@tlsld)@plt";
9540    }
9541  return "bl %z1(%&@tlsld)";
9542}
9543  [(set_attr "type" "branch")
9544   (set_attr "length" "4")])
9545
9546(define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9547  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9548	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9549			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9550			UNSPEC_TLSDTPREL))]
9551  "HAVE_AS_TLS"
9552  "addi %0,%1,%2@dtprel")
9553
9554(define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9555  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9556	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9557			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9558			UNSPEC_TLSDTPRELHA))]
9559  "HAVE_AS_TLS"
9560  "addis %0,%1,%2@dtprel@ha")
9561
9562(define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9563  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9564	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9565			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9566			UNSPEC_TLSDTPRELLO))]
9567  "HAVE_AS_TLS"
9568  "addi %0,%1,%2@dtprel@l")
9569
9570(define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9571  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9572	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9573			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9574			UNSPEC_TLSGOTDTPREL))]
9575  "HAVE_AS_TLS"
9576  "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9577  "&& TARGET_CMODEL != CMODEL_SMALL"
9578  [(set (match_dup 3)
9579	(high:TLSmode
9580	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9581   (set (match_dup 0)
9582	(lo_sum:TLSmode (match_dup 3)
9583	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9584{
9585  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9586}
9587  [(set (attr "length")
9588     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9589     		   (const_int 8)
9590     		   (const_int 4)))])
9591
9592(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9593  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9594     (high:TLSmode
9595       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9596			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9597		       UNSPEC_TLSGOTDTPREL)))]
9598  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9599  "addis %0,%1,%2@got@dtprel@ha"
9600  [(set_attr "length" "4")])
9601
9602(define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9603  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9604     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9605	 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9606			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9607			 UNSPEC_TLSGOTDTPREL)))]
9608  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9609  "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9610  [(set_attr "length" "4")])
9611
9612(define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9613  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9614	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9615			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9616			UNSPEC_TLSTPREL))]
9617  "HAVE_AS_TLS"
9618  "addi %0,%1,%2@tprel")
9619
9620(define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9621  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9622	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9623			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9624			UNSPEC_TLSTPRELHA))]
9625  "HAVE_AS_TLS"
9626  "addis %0,%1,%2@tprel@ha")
9627
9628(define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9629  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9630	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9631			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9632			UNSPEC_TLSTPRELLO))]
9633  "HAVE_AS_TLS"
9634  "addi %0,%1,%2@tprel@l")
9635
9636;; "b" output constraint here and on tls_tls input to support linker tls
9637;; optimization.  The linker may edit the instructions emitted by a
9638;; tls_got_tprel/tls_tls pair to addis,addi.
9639(define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9640  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9641	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9642			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9643			UNSPEC_TLSGOTTPREL))]
9644  "HAVE_AS_TLS"
9645  "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9646  "&& TARGET_CMODEL != CMODEL_SMALL"
9647  [(set (match_dup 3)
9648	(high:TLSmode
9649	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9650   (set (match_dup 0)
9651	(lo_sum:TLSmode (match_dup 3)
9652	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9653{
9654  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9655}
9656  [(set (attr "length")
9657     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9658     		   (const_int 8)
9659     		   (const_int 4)))])
9660
9661(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9662  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9663     (high:TLSmode
9664       (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9665			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9666		       UNSPEC_TLSGOTTPREL)))]
9667  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9668  "addis %0,%1,%2@got@tprel@ha"
9669  [(set_attr "length" "4")])
9670
9671(define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9672  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9673     (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9674	 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9675			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9676			 UNSPEC_TLSGOTTPREL)))]
9677  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9678  "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9679  [(set_attr "length" "4")])
9680
9681(define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9682  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9683	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9684			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9685			UNSPEC_TLSTLS))]
9686  "TARGET_ELF && HAVE_AS_TLS"
9687  "add %0,%1,%2@tls")
9688
9689(define_expand "tls_get_tpointer"
9690  [(set (match_operand:SI 0 "gpc_reg_operand")
9691	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9692  "TARGET_XCOFF && HAVE_AS_TLS"
9693{
9694  emit_insn (gen_tls_get_tpointer_internal ());
9695  emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9696  DONE;
9697})
9698
9699(define_insn "tls_get_tpointer_internal"
9700  [(set (reg:SI 3)
9701	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9702   (clobber (reg:SI LR_REGNO))]
9703  "TARGET_XCOFF && HAVE_AS_TLS"
9704  "bla __get_tpointer")
9705
9706(define_expand "tls_get_addr<mode>"
9707  [(set (match_operand:P 0 "gpc_reg_operand")
9708	(unspec:P [(match_operand:P 1 "gpc_reg_operand")
9709                   (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9710  "TARGET_XCOFF && HAVE_AS_TLS"
9711{
9712  emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9713  emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9714  emit_insn (gen_tls_get_addr_internal<mode> ());
9715  emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9716  DONE;
9717})
9718
9719(define_insn "tls_get_addr_internal<mode>"
9720  [(set (reg:P 3)
9721	(unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9722   (clobber (reg:P 0))
9723   (clobber (reg:P 4))
9724   (clobber (reg:P 5))
9725   (clobber (reg:P 11))
9726   (clobber (reg:CC CR0_REGNO))
9727   (clobber (reg:P LR_REGNO))]
9728  "TARGET_XCOFF && HAVE_AS_TLS"
9729  "bla __tls_get_addr")
9730
9731;; Next come insns related to the calling sequence.
9732;;
9733;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9734;; We move the back-chain and decrement the stack pointer.
9735;;
9736;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9737;; constant alloca, using that predicate will force the generic code to put
9738;; the constant size into a register before calling the expander.
9739;;
9740;; As a result the expander would not have the constant size information
9741;; in those cases and would have to generate less efficient code.
9742;;
9743;; Thus we allow reg_or_cint_operand instead so that the expander can see
9744;; the constant size.  The value is forced into a register if necessary.
9745;;
9746(define_expand "allocate_stack"
9747  [(set (match_operand 0 "gpc_reg_operand")
9748	(minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9749   (set (reg 1)
9750	(minus (reg 1) (match_dup 1)))]
9751  ""
9752{
9753  rtx chain = gen_reg_rtx (Pmode);
9754  rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9755  rtx neg_op0;
9756  rtx insn, par, set, mem;
9757
9758  /* By allowing reg_or_cint_operand as the predicate we can get
9759     better code for stack-clash-protection because we do not lose
9760     size information.  But the rest of the code expects the operand
9761     to be reg_or_short_operand.  If it isn't, then force it into
9762     a register.  */
9763  rtx orig_op1 = operands[1];
9764  if (!reg_or_short_operand (operands[1], Pmode))
9765    operands[1] = force_reg (Pmode, operands[1]);
9766
9767  emit_move_insn (chain, stack_bot);
9768
9769  /* Check stack bounds if necessary.  */
9770  if (crtl->limit_stack)
9771    {
9772      rtx available;
9773      available = expand_binop (Pmode, sub_optab,
9774				stack_pointer_rtx, stack_limit_rtx,
9775				NULL_RTX, 1, OPTAB_WIDEN);
9776      emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9777    }
9778
9779  /* Allocate and probe if requested.
9780     This may look similar to the loop we use for prologue allocations,
9781     but it is critically different.  For the former we know the loop
9782     will iterate, but do not know that generally here.  The former
9783     uses that knowledge to rotate the loop.  Combining them would be
9784     possible with some performance cost.  */
9785  if (flag_stack_clash_protection)
9786    {
9787      rtx rounded_size, last_addr, residual;
9788      HOST_WIDE_INT probe_interval;
9789      compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9790						&residual, &probe_interval,
9791						orig_op1);
9792
9793      /* We do occasionally get in here with constant sizes, we might
9794	 as well do a reasonable job when we obviously can.  */
9795      if (rounded_size != const0_rtx)
9796	{
9797	  rtx loop_lab, end_loop;
9798	  bool rotated = CONST_INT_P (rounded_size);
9799	  rtx update = GEN_INT (-probe_interval);
9800	  if (probe_interval > 32768)
9801	    update = force_reg (Pmode, update);
9802
9803	  emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9804							last_addr, rotated);
9805
9806	  if (Pmode == SImode)
9807	    emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9808					       stack_pointer_rtx,
9809					       update, chain));
9810	  else
9811	    emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9812					          stack_pointer_rtx,
9813					          update, chain));
9814	  emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9815						      last_addr, rotated);
9816	}
9817
9818      /* Now handle residuals.  We just have to set operands[1] correctly
9819	 and let the rest of the expander run.  */
9820      operands[1] = residual;
9821    }
9822
9823  if (!(CONST_INT_P (operands[1])
9824	&& IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9825    {
9826      operands[1] = force_reg (Pmode, operands[1]);
9827      neg_op0 = gen_reg_rtx (Pmode);
9828      if (TARGET_32BIT)
9829	emit_insn (gen_negsi2 (neg_op0, operands[1]));
9830      else
9831	emit_insn (gen_negdi2 (neg_op0, operands[1]));
9832    }
9833  else
9834    neg_op0 = GEN_INT (-INTVAL (operands[1]));
9835
9836  insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9837				       : gen_movdi_di_update_stack))
9838			(stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9839			 chain));
9840  /* Since we didn't use gen_frame_mem to generate the MEM, grab
9841     it now and set the alias set/attributes. The above gen_*_update
9842     calls will generate a PARALLEL with the MEM set being the first
9843     operation. */
9844  par = PATTERN (insn);
9845  gcc_assert (GET_CODE (par) == PARALLEL);
9846  set = XVECEXP (par, 0, 0);
9847  gcc_assert (GET_CODE (set) == SET);
9848  mem = SET_DEST (set);
9849  gcc_assert (MEM_P (mem));
9850  MEM_NOTRAP_P (mem) = 1;
9851  set_mem_alias_set (mem, get_frame_alias_set ());
9852
9853  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9854  DONE;
9855})
9856
9857;; These patterns say how to save and restore the stack pointer.  We need not
9858;; save the stack pointer at function level since we are careful to
9859;; preserve the backchain.  At block level, we have to restore the backchain
9860;; when we restore the stack pointer.
9861;;
9862;; For nonlocal gotos, we must save both the stack pointer and its
9863;; backchain and restore both.  Note that in the nonlocal case, the
9864;; save area is a memory location.
9865
9866(define_expand "save_stack_function"
9867  [(match_operand 0 "any_operand")
9868   (match_operand 1 "any_operand")]
9869  ""
9870  "DONE;")
9871
9872(define_expand "restore_stack_function"
9873  [(match_operand 0 "any_operand")
9874   (match_operand 1 "any_operand")]
9875  ""
9876  "DONE;")
9877
9878;; Adjust stack pointer (op0) to a new value (op1).
9879;; First copy old stack backchain to new location, and ensure that the
9880;; scheduler won't reorder the sp assignment before the backchain write.
9881(define_expand "restore_stack_block"
9882  [(set (match_dup 2) (match_dup 3))
9883   (set (match_dup 4) (match_dup 2))
9884   (match_dup 5)
9885   (set (match_operand 0 "register_operand")
9886	(match_operand 1 "register_operand"))]
9887  ""
9888{
9889  rtvec p;
9890
9891  operands[1] = force_reg (Pmode, operands[1]);
9892  operands[2] = gen_reg_rtx (Pmode);
9893  operands[3] = gen_frame_mem (Pmode, operands[0]);
9894  operands[4] = gen_frame_mem (Pmode, operands[1]);
9895  p = rtvec_alloc (1);
9896  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9897				  const0_rtx);
9898  operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9899})
9900
9901(define_expand "save_stack_nonlocal"
9902  [(set (match_dup 3) (match_dup 4))
9903   (set (match_operand 0 "memory_operand") (match_dup 3))
9904   (set (match_dup 2) (match_operand 1 "register_operand"))]
9905  ""
9906{
9907  int units_per_word = (TARGET_32BIT) ? 4 : 8;
9908
9909  /* Copy the backchain to the first word, sp to the second.  */
9910  operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9911  operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9912  operands[3] = gen_reg_rtx (Pmode);
9913  operands[4] = gen_frame_mem (Pmode, operands[1]);
9914})
9915
9916(define_expand "restore_stack_nonlocal"
9917  [(set (match_dup 2) (match_operand 1 "memory_operand"))
9918   (set (match_dup 3) (match_dup 4))
9919   (set (match_dup 5) (match_dup 2))
9920   (match_dup 6)
9921   (set (match_operand 0 "register_operand") (match_dup 3))]
9922  ""
9923{
9924  int units_per_word = (TARGET_32BIT) ? 4 : 8;
9925  rtvec p;
9926
9927  /* Restore the backchain from the first word, sp from the second.  */
9928  operands[2] = gen_reg_rtx (Pmode);
9929  operands[3] = gen_reg_rtx (Pmode);
9930  operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9931  operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9932  operands[5] = gen_frame_mem (Pmode, operands[3]);
9933  p = rtvec_alloc (1);
9934  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9935				  const0_rtx);
9936  operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9937})
9938
9939;; TOC register handling.
9940
9941;; Code to initialize the TOC register...
9942
9943(define_insn "load_toc_aix_si"
9944  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9945		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
9946	      (use (reg:SI 2))])]
9947  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9948{
9949  char buf[30];
9950  extern int need_toc_init;
9951  need_toc_init = 1;
9952  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9953  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9954  operands[2] = gen_rtx_REG (Pmode, 2);
9955  return "lwz %0,%1(%2)";
9956}
9957  [(set_attr "type" "load")
9958   (set_attr "update" "no")
9959   (set_attr "indexed" "no")])
9960
9961(define_insn "load_toc_aix_di"
9962  [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9963		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
9964	      (use (reg:DI 2))])]
9965  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9966{
9967  char buf[30];
9968  extern int need_toc_init;
9969  need_toc_init = 1;
9970  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9971			       !TARGET_ELF || !TARGET_MINIMAL_TOC);
9972  if (TARGET_ELF)
9973    strcat (buf, "@toc");
9974  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9975  operands[2] = gen_rtx_REG (Pmode, 2);
9976  return "ld %0,%1(%2)";
9977}
9978  [(set_attr "type" "load")
9979   (set_attr "update" "no")
9980   (set_attr "indexed" "no")])
9981
9982(define_insn "load_toc_v4_pic_si"
9983  [(set (reg:SI LR_REGNO)
9984	(unspec:SI [(const_int 0)] UNSPEC_TOC))]
9985  "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9986  "bl _GLOBAL_OFFSET_TABLE_@local-4"
9987  [(set_attr "type" "branch")
9988   (set_attr "length" "4")])
9989
9990(define_expand "load_toc_v4_PIC_1"
9991  [(parallel [(set (reg:SI LR_REGNO)
9992		   (match_operand:SI 0 "immediate_operand" "s"))
9993	      (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9994  "TARGET_ELF && DEFAULT_ABI == ABI_V4
9995   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9996  "")
9997
9998(define_insn "load_toc_v4_PIC_1_normal"
9999  [(set (reg:SI LR_REGNO)
10000	(match_operand:SI 0 "immediate_operand" "s"))
10001   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10002  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10003   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10004  "bcl 20,31,%0\n%0:"
10005  [(set_attr "type" "branch")
10006   (set_attr "length" "4")
10007   (set_attr "cannot_copy" "yes")])
10008
10009(define_insn "load_toc_v4_PIC_1_476"
10010  [(set (reg:SI LR_REGNO)
10011	(match_operand:SI 0 "immediate_operand" "s"))
10012   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10013  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10014   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10015{
10016  char name[32];
10017  static char templ[32];
10018
10019  get_ppc476_thunk_name (name);
10020  sprintf (templ, "bl %s\n%%0:", name);
10021  return templ;
10022}
10023  [(set_attr "type" "branch")
10024   (set_attr "length" "4")
10025   (set_attr "cannot_copy" "yes")])
10026
10027(define_expand "load_toc_v4_PIC_1b"
10028  [(parallel [(set (reg:SI LR_REGNO)
10029		   (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10030			       (label_ref (match_operand 1 ""))]
10031		           UNSPEC_TOCPTR))
10032	      (match_dup 1)])]
10033  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10034  "")
10035
10036(define_insn "load_toc_v4_PIC_1b_normal"
10037  [(set (reg:SI LR_REGNO)
10038	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10039		    (label_ref (match_operand 1 "" ""))]
10040		UNSPEC_TOCPTR))
10041   (match_dup 1)]
10042  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10043  "bcl 20,31,$+8\;.long %0-$"
10044  [(set_attr "type" "branch")
10045   (set_attr "length" "8")])
10046
10047(define_insn "load_toc_v4_PIC_1b_476"
10048  [(set (reg:SI LR_REGNO)
10049	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10050		    (label_ref (match_operand 1 "" ""))]
10051		UNSPEC_TOCPTR))
10052   (match_dup 1)]
10053  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10054{
10055  char name[32];
10056  static char templ[32];
10057
10058  get_ppc476_thunk_name (name);
10059  sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10060  return templ;
10061}
10062  [(set_attr "type" "branch")
10063   (set_attr "length" "16")])
10064
10065(define_insn "load_toc_v4_PIC_2"
10066  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10067	(mem:SI (plus:SI
10068		  (match_operand:SI 1 "gpc_reg_operand" "b")
10069		  (const
10070		    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10071			      (match_operand:SI 3 "immediate_operand" "s"))))))]
10072  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10073  "lwz %0,%2-%3(%1)"
10074  [(set_attr "type" "load")])
10075
10076(define_insn "load_toc_v4_PIC_3b"
10077  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10078	(plus:SI
10079	  (match_operand:SI 1 "gpc_reg_operand" "b")
10080	  (high:SI
10081	    (const
10082	      (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10083			(match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10084  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10085  "addis %0,%1,%2-%3@ha")
10086
10087(define_insn "load_toc_v4_PIC_3c"
10088  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10089	(lo_sum:SI
10090	  (match_operand:SI 1 "gpc_reg_operand" "b")
10091	  (const
10092	    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10093		      (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10094  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10095  "addi %0,%1,%2-%3@l")
10096
10097;; If the TOC is shared over a translation unit, as happens with all
10098;; the kinds of PIC that we support, we need to restore the TOC
10099;; pointer only when jumping over units of translation.
10100;; On Darwin, we need to reload the picbase.
10101
10102(define_expand "builtin_setjmp_receiver"
10103  [(use (label_ref (match_operand 0 "")))]
10104  "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10105   || (TARGET_TOC && TARGET_MINIMAL_TOC)
10106   || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10107{
10108#if TARGET_MACHO
10109  if (DEFAULT_ABI == ABI_DARWIN)
10110    {
10111      rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10112      rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10113      rtx tmplabrtx;
10114      char tmplab[20];
10115
10116      crtl->uses_pic_offset_table = 1;
10117      ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10118				  CODE_LABEL_NUMBER (operands[0]));
10119      tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10120
10121      emit_insn (gen_load_macho_picbase (tmplabrtx));
10122      emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10123      emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10124    }
10125  else
10126#endif
10127    rs6000_emit_load_toc_table (FALSE);
10128  DONE;
10129})
10130
10131;; Largetoc support
10132(define_insn "*largetoc_high"
10133  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10134        (high:DI
10135	  (unspec [(match_operand:DI 1 "" "")
10136		   (match_operand:DI 2 "gpc_reg_operand" "b")]
10137		  UNSPEC_TOCREL)))]
10138   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10139   "addis %0,%2,%1@toc@ha")
10140
10141(define_insn "*largetoc_high_aix<mode>"
10142  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10143        (high:P
10144	  (unspec [(match_operand:P 1 "" "")
10145		   (match_operand:P 2 "gpc_reg_operand" "b")]
10146		  UNSPEC_TOCREL)))]
10147   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10148   "addis %0,%1@u(%2)")
10149
10150(define_insn "*largetoc_high_plus"
10151  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10152        (high:DI
10153	  (plus:DI
10154	    (unspec [(match_operand:DI 1 "" "")
10155		     (match_operand:DI 2 "gpc_reg_operand" "b")]
10156		    UNSPEC_TOCREL)
10157	    (match_operand:DI 3 "add_cint_operand" "n"))))]
10158   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10159   "addis %0,%2,%1+%3@toc@ha")
10160
10161(define_insn "*largetoc_high_plus_aix<mode>"
10162  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10163        (high:P
10164	  (plus:P
10165	    (unspec [(match_operand:P 1 "" "")
10166		     (match_operand:P 2 "gpc_reg_operand" "b")]
10167		    UNSPEC_TOCREL)
10168	    (match_operand:P 3 "add_cint_operand" "n"))))]
10169   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10170   "addis %0,%1+%3@u(%2)")
10171
10172(define_insn "*largetoc_low"
10173  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10174        (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10175	           (match_operand:DI 2 "" "")))]
10176   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10177   "addi %0,%1,%2@l")
10178
10179(define_insn "*largetoc_low_aix<mode>"
10180  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10181        (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10182	           (match_operand:P 2 "" "")))]
10183   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10184   "la %0,%2@l(%1)")
10185
10186(define_insn_and_split "*tocref<mode>"
10187  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10188	(match_operand:P 1 "small_toc_ref" "R"))]
10189   "TARGET_TOC"
10190   "la %0,%a1"
10191   "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10192  [(set (match_dup 0) (high:P (match_dup 1)))
10193   (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10194
10195;; Elf specific ways of loading addresses for non-PIC code.
10196;; The output of this could be r0, but we make a very strong
10197;; preference for a base register because it will usually
10198;; be needed there.
10199(define_insn "elf_high"
10200  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10201	(high:SI (match_operand 1 "" "")))]
10202  "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10203  "lis %0,%1@ha")
10204
10205(define_insn "elf_low"
10206  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10207	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10208		   (match_operand 2 "" "")))]
10209   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10210   "la %0,%2@l(%1)")
10211
10212;; Call and call_value insns
10213(define_expand "call"
10214  [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10215		    (match_operand 1 ""))
10216	      (use (match_operand 2 ""))
10217	      (clobber (reg:SI LR_REGNO))])]
10218  ""
10219{
10220#if TARGET_MACHO
10221  if (MACHOPIC_INDIRECT)
10222    operands[0] = machopic_indirect_call_target (operands[0]);
10223#endif
10224
10225  gcc_assert (GET_CODE (operands[0]) == MEM);
10226  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10227
10228  operands[0] = XEXP (operands[0], 0);
10229
10230  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10231    {
10232      rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10233      DONE;
10234    }
10235
10236  if (GET_CODE (operands[0]) != SYMBOL_REF
10237      || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10238    {
10239      if (INTVAL (operands[2]) & CALL_LONG)
10240	operands[0] = rs6000_longcall_ref (operands[0]);
10241
10242      switch (DEFAULT_ABI)
10243        {
10244	case ABI_V4:
10245	case ABI_DARWIN:
10246	  operands[0] = force_reg (Pmode, operands[0]);
10247	  break;
10248
10249	default:
10250	  gcc_unreachable ();
10251	}
10252    }
10253})
10254
10255(define_expand "call_value"
10256  [(parallel [(set (match_operand 0 "")
10257		   (call (mem:SI (match_operand 1 "address_operand"))
10258			 (match_operand 2 "")))
10259	      (use (match_operand 3 ""))
10260	      (clobber (reg:SI LR_REGNO))])]
10261  ""
10262{
10263#if TARGET_MACHO
10264  if (MACHOPIC_INDIRECT)
10265    operands[1] = machopic_indirect_call_target (operands[1]);
10266#endif
10267
10268  gcc_assert (GET_CODE (operands[1]) == MEM);
10269  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10270
10271  operands[1] = XEXP (operands[1], 0);
10272
10273  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10274    {
10275      rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10276      DONE;
10277    }
10278
10279  if (GET_CODE (operands[1]) != SYMBOL_REF
10280      || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10281    {
10282      if (INTVAL (operands[3]) & CALL_LONG)
10283	operands[1] = rs6000_longcall_ref (operands[1]);
10284
10285      switch (DEFAULT_ABI)
10286        {
10287	case ABI_V4:
10288	case ABI_DARWIN:
10289	  operands[1] = force_reg (Pmode, operands[1]);
10290	  break;
10291
10292	default:
10293	  gcc_unreachable ();
10294	}
10295    }
10296})
10297
10298;; Call to function in current module.  No TOC pointer reload needed.
10299;; Operand2 is nonzero if we are using the V.4 calling sequence and
10300;; either the function was not prototyped, or it was prototyped as a
10301;; variable argument function.  It is > 0 if FP registers were passed
10302;; and < 0 if they were not.
10303
10304(define_insn "*call_local32"
10305  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10306	 (match_operand 1 "" "g,g"))
10307   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10308   (clobber (reg:SI LR_REGNO))]
10309  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10310{
10311  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10312    output_asm_insn ("crxor 6,6,6", operands);
10313
10314  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10315    output_asm_insn ("creqv 6,6,6", operands);
10316
10317  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10318}
10319  [(set_attr "type" "branch")
10320   (set_attr "length" "4,8")])
10321
10322(define_insn "*call_local64"
10323  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10324	 (match_operand 1 "" "g,g"))
10325   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10326   (clobber (reg:SI LR_REGNO))]
10327  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10328{
10329  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10330    output_asm_insn ("crxor 6,6,6", operands);
10331
10332  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10333    output_asm_insn ("creqv 6,6,6", operands);
10334
10335  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10336}
10337  [(set_attr "type" "branch")
10338   (set_attr "length" "4,8")])
10339
10340(define_insn "*call_value_local32"
10341  [(set (match_operand 0 "" "")
10342	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10343	      (match_operand 2 "" "g,g")))
10344   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10345   (clobber (reg:SI LR_REGNO))]
10346  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10347{
10348  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10349    output_asm_insn ("crxor 6,6,6", operands);
10350
10351  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10352    output_asm_insn ("creqv 6,6,6", operands);
10353
10354  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10355}
10356  [(set_attr "type" "branch")
10357   (set_attr "length" "4,8")])
10358
10359
10360(define_insn "*call_value_local64"
10361  [(set (match_operand 0 "" "")
10362	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10363	      (match_operand 2 "" "g,g")))
10364   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10365   (clobber (reg:SI LR_REGNO))]
10366  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10367{
10368  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10369    output_asm_insn ("crxor 6,6,6", operands);
10370
10371  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10372    output_asm_insn ("creqv 6,6,6", operands);
10373
10374  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10375}
10376  [(set_attr "type" "branch")
10377   (set_attr "length" "4,8")])
10378
10379
10380;; A function pointer under System V is just a normal pointer
10381;; operands[0] is the function pointer
10382;; operands[1] is the stack size to clean up
10383;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10384;; which indicates how to set cr1
10385
10386(define_insn "*call_indirect_nonlocal_sysv<mode>"
10387  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10388	 (match_operand 1 "" "g,g,g,g"))
10389   (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10390   (clobber (reg:SI LR_REGNO))]
10391  "DEFAULT_ABI == ABI_V4
10392   || DEFAULT_ABI == ABI_DARWIN"
10393{
10394  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10395    output_asm_insn ("crxor 6,6,6", operands);
10396
10397  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10398    output_asm_insn ("creqv 6,6,6", operands);
10399
10400  if (rs6000_speculate_indirect_jumps
10401      || which_alternative == 1 || which_alternative == 3)
10402    return "b%T0l";
10403  else
10404    return "crset 2\;beq%T0l-";
10405}
10406  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10407   (set (attr "length")
10408	(cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10409		    (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10410			(const_int 0)))
10411		  (const_string "8")
10412	       (and (eq (symbol_ref "which_alternative") (const_int 2))
10413		    (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10414			(const_int 0)))
10415		  (const_string "8")
10416	       (and (eq (symbol_ref "which_alternative") (const_int 2))
10417		    (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10418			(const_int 0)))
10419		  (const_string "12")
10420	       (eq (symbol_ref "which_alternative") (const_int 3))
10421		  (const_string "8")]
10422	      (const_string "4")))])
10423
10424(define_insn_and_split "*call_nonlocal_sysv<mode>"
10425  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10426	 (match_operand 1 "" "g,g"))
10427   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10428   (clobber (reg:SI LR_REGNO))]
10429  "(DEFAULT_ABI == ABI_DARWIN
10430   || (DEFAULT_ABI == ABI_V4
10431       && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10432{
10433  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10434    output_asm_insn ("crxor 6,6,6", operands);
10435
10436  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10437    output_asm_insn ("creqv 6,6,6", operands);
10438
10439#if TARGET_MACHO
10440  return output_call(insn, operands, 0, 2);
10441#else
10442  if (DEFAULT_ABI == ABI_V4 && flag_pic)
10443    {
10444      gcc_assert (!TARGET_SECURE_PLT);
10445      return "bl %z0@plt";
10446    }
10447  else
10448    return "bl %z0";
10449#endif
10450}
10451  "DEFAULT_ABI == ABI_V4
10452   && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10453   && (INTVAL (operands[2]) & CALL_LONG) == 0"
10454  [(parallel [(call (mem:SI (match_dup 0))
10455		    (match_dup 1))
10456	      (use (match_dup 2))
10457	      (use (match_dup 3))
10458	      (clobber (reg:SI LR_REGNO))])]
10459{
10460  operands[3] = pic_offset_table_rtx;
10461}
10462  [(set_attr "type" "branch,branch")
10463   (set_attr "length" "4,8")])
10464
10465(define_insn "*call_nonlocal_sysv_secure<mode>"
10466  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10467	 (match_operand 1 "" "g,g"))
10468   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10469   (use (match_operand:SI 3 "register_operand" "r,r"))
10470   (clobber (reg:SI LR_REGNO))]
10471  "(DEFAULT_ABI == ABI_V4
10472    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10473    && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10474{
10475  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10476    output_asm_insn ("crxor 6,6,6", operands);
10477
10478  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10479    output_asm_insn ("creqv 6,6,6", operands);
10480
10481  if (flag_pic == 2)
10482    /* The magic 32768 offset here and in the other sysv call insns
10483       corresponds to the offset of r30 in .got2, as given by LCTOC1.
10484       See sysv4.h:toc_section.  */
10485    return "bl %z0+32768@plt";
10486  else
10487    return "bl %z0@plt";
10488}
10489  [(set_attr "type" "branch,branch")
10490   (set_attr "length" "4,8")])
10491
10492(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10493  [(set (match_operand 0 "" "")
10494	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10495	      (match_operand 2 "" "g,g,g,g")))
10496   (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10497   (clobber (reg:SI LR_REGNO))]
10498  "DEFAULT_ABI == ABI_V4
10499   || DEFAULT_ABI == ABI_DARWIN"
10500{
10501  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10502    output_asm_insn ("crxor 6,6,6", operands);
10503
10504  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10505    output_asm_insn ("creqv 6,6,6", operands);
10506
10507  if (rs6000_speculate_indirect_jumps
10508      || which_alternative == 1 || which_alternative == 3)
10509    return "b%T1l";
10510  else
10511    return "crset 2\;beq%T1l-";
10512}
10513  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10514   (set (attr "length")
10515	(cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10516		    (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10517			(const_int 0)))
10518		  (const_string "8")
10519	       (and (eq (symbol_ref "which_alternative") (const_int 2))
10520		    (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10521			(const_int 0)))
10522		  (const_string "8")
10523	       (and (eq (symbol_ref "which_alternative") (const_int 2))
10524		    (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10525			(const_int 0)))
10526		  (const_string "12")
10527	       (eq (symbol_ref "which_alternative") (const_int 3))
10528		  (const_string "8")]
10529	      (const_string "4")))])
10530
10531(define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10532  [(set (match_operand 0 "" "")
10533	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10534	      (match_operand 2 "" "g,g")))
10535   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10536   (clobber (reg:SI LR_REGNO))]
10537  "(DEFAULT_ABI == ABI_DARWIN
10538   || (DEFAULT_ABI == ABI_V4
10539       && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10540{
10541  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10542    output_asm_insn ("crxor 6,6,6", operands);
10543
10544  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10545    output_asm_insn ("creqv 6,6,6", operands);
10546
10547#if TARGET_MACHO
10548  return output_call(insn, operands, 1, 3);
10549#else
10550  if (DEFAULT_ABI == ABI_V4 && flag_pic)
10551    {
10552      gcc_assert (!TARGET_SECURE_PLT);
10553      return "bl %z1@plt";
10554    }
10555  else
10556    return "bl %z1";
10557#endif
10558}
10559  "DEFAULT_ABI == ABI_V4
10560   && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10561   && (INTVAL (operands[3]) & CALL_LONG) == 0"
10562  [(parallel [(set (match_dup 0)
10563		   (call (mem:SI (match_dup 1))
10564			 (match_dup 2)))
10565	      (use (match_dup 3))
10566	      (use (match_dup 4))
10567	      (clobber (reg:SI LR_REGNO))])]
10568{
10569  operands[4] = pic_offset_table_rtx;
10570}
10571  [(set_attr "type" "branch,branch")
10572   (set_attr "length" "4,8")])
10573
10574(define_insn "*call_value_nonlocal_sysv_secure<mode>"
10575  [(set (match_operand 0 "" "")
10576	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10577	      (match_operand 2 "" "g,g")))
10578   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10579   (use (match_operand:SI 4 "register_operand" "r,r"))
10580   (clobber (reg:SI LR_REGNO))]
10581  "(DEFAULT_ABI == ABI_V4
10582    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10583    && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10584{
10585  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10586    output_asm_insn ("crxor 6,6,6", operands);
10587
10588  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10589    output_asm_insn ("creqv 6,6,6", operands);
10590
10591  if (flag_pic == 2)
10592    return "bl %z1+32768@plt";
10593  else
10594    return "bl %z1@plt";
10595}
10596  [(set_attr "type" "branch,branch")
10597   (set_attr "length" "4,8")])
10598
10599
10600;; Call to AIX abi function in the same module.
10601
10602(define_insn "*call_local_aix<mode>"
10603  [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10604	 (match_operand 1 "" "g"))
10605   (clobber (reg:P LR_REGNO))]
10606  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10607  "bl %z0"
10608  [(set_attr "type" "branch")
10609   (set_attr "length" "4")])
10610
10611(define_insn "*call_value_local_aix<mode>"
10612  [(set (match_operand 0 "" "")
10613	(call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10614	      (match_operand 2 "" "g")))
10615   (clobber (reg:P LR_REGNO))]
10616  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10617  "bl %z1"
10618  [(set_attr "type" "branch")
10619   (set_attr "length" "4")])
10620
10621;; Call to AIX abi function which may be in another module.
10622;; Restore the TOC pointer (r2) after the call.
10623
10624(define_insn "*call_nonlocal_aix<mode>"
10625  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10626	 (match_operand 1 "" "g"))
10627   (clobber (reg:P LR_REGNO))]
10628  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10629  "bl %z0\;nop"
10630  [(set_attr "type" "branch")
10631   (set_attr "length" "8")])
10632
10633(define_insn "*call_value_nonlocal_aix<mode>"
10634  [(set (match_operand 0 "" "")
10635	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10636	      (match_operand 2 "" "g")))
10637   (clobber (reg:P LR_REGNO))]
10638  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10639  "bl %z1\;nop"
10640  [(set_attr "type" "branch")
10641   (set_attr "length" "8")])
10642
10643;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10644;; Operand0 is the addresss of the function to call
10645;; Operand2 is the location in the function descriptor to load r2 from
10646;; Operand3 is the offset of the stack location holding the current TOC pointer
10647
10648(define_insn "*call_indirect_aix<mode>"
10649  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10650	 (match_operand 1 "" "g,g"))
10651   (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10652   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10653   (clobber (reg:P LR_REGNO))]
10654  "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10655  "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10656  [(set_attr "type" "jmpreg")
10657   (set_attr "length" "12")])
10658
10659(define_insn "*call_indirect_aix<mode>_nospec"
10660  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10661	 (match_operand 1 "" "g,g"))
10662   (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10663   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10664   (clobber (reg:P LR_REGNO))]
10665  "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10666  "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10667  [(set_attr "type" "jmpreg")
10668   (set_attr "length" "16")])
10669
10670(define_insn "*call_value_indirect_aix<mode>"
10671  [(set (match_operand 0 "" "")
10672	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10673	      (match_operand 2 "" "g,g")))
10674   (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10675   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10676   (clobber (reg:P LR_REGNO))]
10677  "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10678  "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10679  [(set_attr "type" "jmpreg")
10680   (set_attr "length" "12")])
10681
10682(define_insn "*call_value_indirect_aix<mode>_nospec"
10683  [(set (match_operand 0 "" "")
10684	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10685	      (match_operand 2 "" "g,g")))
10686   (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10687   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10688   (clobber (reg:P LR_REGNO))]
10689  "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10690  "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10691  [(set_attr "type" "jmpreg")
10692   (set_attr "length" "16")])
10693
10694;; Call to indirect functions with the ELFv2 ABI.
10695;; Operand0 is the addresss of the function to call
10696;; Operand2 is the offset of the stack location holding the current TOC pointer
10697
10698(define_insn "*call_indirect_elfv2<mode>"
10699  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10700	 (match_operand 1 "" "g,g"))
10701   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10702   (clobber (reg:P LR_REGNO))]
10703  "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10704  "b%T0l\;<ptrload> 2,%2(1)"
10705  [(set_attr "type" "jmpreg")
10706   (set_attr "length" "8")])
10707
10708;; Variant with deliberate misprediction.
10709(define_insn "*call_indirect_elfv2<mode>_nospec"
10710  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10711	 (match_operand 1 "" "g,g"))
10712   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10713   (clobber (reg:P LR_REGNO))]
10714  "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10715  "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10716  [(set_attr "type" "jmpreg")
10717   (set_attr "length" "12")])
10718
10719(define_insn "*call_value_indirect_elfv2<mode>"
10720  [(set (match_operand 0 "" "")
10721	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10722	      (match_operand 2 "" "g,g")))
10723   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10724   (clobber (reg:P LR_REGNO))]
10725  "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10726  "b%T1l\;<ptrload> 2,%3(1)"
10727  [(set_attr "type" "jmpreg")
10728   (set_attr "length" "8")])
10729
10730; Variant with deliberate misprediction.
10731(define_insn "*call_value_indirect_elfv2<mode>_nospec"
10732  [(set (match_operand 0 "" "")
10733	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10734	      (match_operand 2 "" "g,g")))
10735   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10736   (clobber (reg:P LR_REGNO))]
10737  "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10738  "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10739  [(set_attr "type" "jmpreg")
10740   (set_attr "length" "12")])
10741
10742;; Call subroutine returning any type.
10743(define_expand "untyped_call"
10744  [(parallel [(call (match_operand 0 "")
10745		    (const_int 0))
10746	      (match_operand 1 "")
10747	      (match_operand 2 "")])]
10748  ""
10749{
10750  int i;
10751
10752  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10753
10754  for (i = 0; i < XVECLEN (operands[2], 0); i++)
10755    {
10756      rtx set = XVECEXP (operands[2], 0, i);
10757      emit_move_insn (SET_DEST (set), SET_SRC (set));
10758    }
10759
10760  /* The optimizer does not know that the call sets the function value
10761     registers we stored in the result block.  We avoid problems by
10762     claiming that all hard registers are used and clobbered at this
10763     point.  */
10764  emit_insn (gen_blockage ());
10765
10766  DONE;
10767})
10768
10769;; sibling call patterns
10770(define_expand "sibcall"
10771  [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10772		    (match_operand 1 ""))
10773	      (use (match_operand 2 ""))
10774	      (simple_return)])]
10775  ""
10776{
10777#if TARGET_MACHO
10778  if (MACHOPIC_INDIRECT)
10779    operands[0] = machopic_indirect_call_target (operands[0]);
10780#endif
10781
10782  gcc_assert (GET_CODE (operands[0]) == MEM);
10783  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10784
10785  operands[0] = XEXP (operands[0], 0);
10786
10787  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10788    {
10789      rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10790      DONE;
10791    }
10792})
10793
10794(define_expand "sibcall_value"
10795  [(parallel [(set (match_operand 0 "register_operand")
10796		(call (mem:SI (match_operand 1 "address_operand"))
10797		      (match_operand 2 "")))
10798	      (use (match_operand 3 ""))
10799	      (simple_return)])]
10800  ""
10801{
10802#if TARGET_MACHO
10803  if (MACHOPIC_INDIRECT)
10804    operands[1] = machopic_indirect_call_target (operands[1]);
10805#endif
10806
10807  gcc_assert (GET_CODE (operands[1]) == MEM);
10808  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10809
10810  operands[1] = XEXP (operands[1], 0);
10811
10812  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10813    {
10814      rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10815      DONE;
10816    }
10817})
10818
10819(define_insn "*sibcall_local32"
10820  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10821	 (match_operand 1 "" "g,g"))
10822   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10823   (simple_return)]
10824  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10825{
10826  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10827    output_asm_insn ("crxor 6,6,6", operands);
10828
10829  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10830    output_asm_insn ("creqv 6,6,6", operands);
10831
10832  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10833}
10834  [(set_attr "type" "branch")
10835   (set_attr "length" "4,8")])
10836
10837(define_insn "*sibcall_local64"
10838  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10839	 (match_operand 1 "" "g,g"))
10840   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10841   (simple_return)]
10842  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10843{
10844  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10845    output_asm_insn ("crxor 6,6,6", operands);
10846
10847  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10848    output_asm_insn ("creqv 6,6,6", operands);
10849
10850  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10851}
10852  [(set_attr "type" "branch")
10853   (set_attr "length" "4,8")])
10854
10855(define_insn "*sibcall_value_local32"
10856  [(set (match_operand 0 "" "")
10857	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10858	      (match_operand 2 "" "g,g")))
10859   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10860   (simple_return)]
10861  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10862{
10863  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10864    output_asm_insn ("crxor 6,6,6", operands);
10865
10866  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10867    output_asm_insn ("creqv 6,6,6", operands);
10868
10869  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10870}
10871  [(set_attr "type" "branch")
10872   (set_attr "length" "4,8")])
10873
10874(define_insn "*sibcall_value_local64"
10875  [(set (match_operand 0 "" "")
10876	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10877	      (match_operand 2 "" "g,g")))
10878   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10879   (simple_return)]
10880  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10881{
10882  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10883    output_asm_insn ("crxor 6,6,6", operands);
10884
10885  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10886    output_asm_insn ("creqv 6,6,6", operands);
10887
10888  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10889}
10890  [(set_attr "type" "branch")
10891   (set_attr "length" "4,8")])
10892
10893(define_insn "*sibcall_nonlocal_sysv<mode>"
10894  [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10895	 (match_operand 1 "" ""))
10896   (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10897   (simple_return)]
10898  "(DEFAULT_ABI == ABI_DARWIN
10899    || DEFAULT_ABI == ABI_V4)
10900   && (INTVAL (operands[2]) & CALL_LONG) == 0"
10901{
10902  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10903    output_asm_insn ("crxor 6,6,6", operands);
10904
10905  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10906    output_asm_insn ("creqv 6,6,6", operands);
10907
10908  if (which_alternative >= 2)
10909    {
10910      if (rs6000_speculate_indirect_jumps)
10911	return "b%T0";
10912      else
10913	/* Can use CR0 since it is volatile across sibcalls.  */
10914	return "crset 2\;beq%T0-\;b $";
10915    }
10916  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10917    {
10918      gcc_assert (!TARGET_SECURE_PLT);
10919      return "b %z0@plt";
10920    }
10921  else
10922    return "b %z0";
10923}
10924  [(set_attr "type" "branch")
10925   (set (attr "length")
10926	(cond [(eq (symbol_ref "which_alternative") (const_int 1))
10927		  (const_string "8")
10928	       (and (eq (symbol_ref "which_alternative") (const_int 2))
10929		    (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10930			(const_int 0)))
10931		  (const_string "12")
10932	       (and (eq (symbol_ref "which_alternative") (const_int 3))
10933		    (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10934			(const_int 0)))
10935		  (const_string "8")
10936	       (and (eq (symbol_ref "which_alternative") (const_int 3))
10937		    (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10938			(const_int 0)))
10939		  (const_string "16")]
10940	      (const_string "4")))])
10941
10942(define_insn "*sibcall_value_nonlocal_sysv<mode>"
10943  [(set (match_operand 0 "" "")
10944	(call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10945	      (match_operand 2 "" "")))
10946   (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10947   (simple_return)]
10948  "(DEFAULT_ABI == ABI_DARWIN
10949    || DEFAULT_ABI == ABI_V4)
10950   && (INTVAL (operands[3]) & CALL_LONG) == 0"
10951{
10952  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10953    output_asm_insn ("crxor 6,6,6", operands);
10954
10955  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10956    output_asm_insn ("creqv 6,6,6", operands);
10957
10958  if (which_alternative >= 2)
10959    {
10960      if (rs6000_speculate_indirect_jumps)
10961	return "b%T1";
10962      else
10963	/* Can use CR0 since it is volatile across sibcalls.  */
10964	return "crset 2\;beq%T1-\;b $";
10965    }
10966  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10967    {
10968      gcc_assert (!TARGET_SECURE_PLT);
10969      return "b %z1@plt";
10970    }
10971  else
10972    return "b %z1";
10973}
10974  [(set_attr "type" "branch")
10975   (set (attr "length")
10976	(cond [(eq (symbol_ref "which_alternative") (const_int 1))
10977		  (const_string "8")
10978	       (and (eq (symbol_ref "which_alternative") (const_int 2))
10979		    (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10980			(const_int 0)))
10981		  (const_string "12")
10982	       (and (eq (symbol_ref "which_alternative") (const_int 3))
10983		    (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10984			(const_int 0)))
10985		  (const_string "8")
10986	       (and (eq (symbol_ref "which_alternative") (const_int 3))
10987		    (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10988			(const_int 0)))
10989		  (const_string "16")]
10990	      (const_string "4")))])
10991
10992;; AIX ABI sibling call patterns.
10993
10994(define_insn "*sibcall_aix<mode>"
10995  [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10996	 (match_operand 1 "" "g,g"))
10997   (simple_return)]
10998  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10999  "@
11000   b %z0
11001   b%T0"
11002  [(set_attr "type" "branch")
11003   (set_attr "length" "4")])
11004
11005(define_insn "*sibcall_value_aix<mode>"
11006  [(set (match_operand 0 "" "")
11007	(call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11008	      (match_operand 2 "" "g,g")))
11009   (simple_return)]
11010  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11011  "@
11012   b %z1
11013   b%T1"
11014  [(set_attr "type" "branch")
11015   (set_attr "length" "4")])
11016
11017(define_expand "sibcall_epilogue"
11018  [(use (const_int 0))]
11019  ""
11020{
11021  if (!TARGET_SCHED_PROLOG)
11022    emit_insn (gen_blockage ());
11023  rs6000_emit_epilogue (TRUE);
11024  DONE;
11025})
11026
11027;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11028;; all of memory.  This blocks insns from being moved across this point.
11029
11030(define_insn "blockage"
11031  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11032  ""
11033  ""
11034  [(set_attr "length" "0")])
11035
11036(define_expand "probe_stack_address"
11037  [(use (match_operand 0 "address_operand"))]
11038  ""
11039{
11040  operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11041  MEM_VOLATILE_P (operands[0]) = 1;
11042
11043  if (TARGET_64BIT)
11044    emit_insn (gen_probe_stack_di (operands[0]));
11045  else
11046    emit_insn (gen_probe_stack_si (operands[0]));
11047  DONE;
11048})
11049
11050(define_insn "probe_stack_<mode>"
11051  [(set (match_operand:P 0 "memory_operand" "=m")
11052        (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11053  ""
11054{
11055  operands[1] = gen_rtx_REG (Pmode, 0);
11056  return "st<wd>%U0%X0 %1,%0";
11057}
11058  [(set_attr "type" "store")
11059   (set (attr "update")
11060	(if_then_else (match_operand 0 "update_address_mem")
11061		      (const_string "yes")
11062		      (const_string "no")))
11063   (set (attr "indexed")
11064	(if_then_else (match_operand 0 "indexed_address_mem")
11065		      (const_string "yes")
11066		      (const_string "no")))
11067   (set_attr "length" "4")])
11068
11069(define_insn "probe_stack_range<P:mode>"
11070  [(set (match_operand:P 0 "register_operand" "=&r")
11071	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11072			    (match_operand:P 2 "register_operand" "r")
11073			    (match_operand:P 3 "register_operand" "r")]
11074			   UNSPECV_PROBE_STACK_RANGE))]
11075  ""
11076  "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11077  [(set_attr "type" "three")])
11078
11079;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11080;; signed & unsigned, and one type of branch.
11081;;
11082;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11083;; insns, and branches.
11084
11085(define_expand "cbranch<mode>4"
11086  [(use (match_operator 0 "comparison_operator"
11087         [(match_operand:GPR 1 "gpc_reg_operand")
11088          (match_operand:GPR 2 "reg_or_short_operand")]))
11089   (use (match_operand 3))]
11090  ""
11091{
11092  /* Take care of the possibility that operands[2] might be negative but
11093     this might be a logical operation.  That insn doesn't exist.  */
11094  if (GET_CODE (operands[2]) == CONST_INT
11095      && INTVAL (operands[2]) < 0)
11096    {
11097      operands[2] = force_reg (<MODE>mode, operands[2]);
11098      operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11099				    GET_MODE (operands[0]),
11100				    operands[1], operands[2]);
11101   }
11102
11103  rs6000_emit_cbranch (<MODE>mode, operands);
11104  DONE;
11105})
11106
11107(define_expand "cbranch<mode>4"
11108  [(use (match_operator 0 "comparison_operator"
11109         [(match_operand:FP 1 "gpc_reg_operand")
11110          (match_operand:FP 2 "gpc_reg_operand")]))
11111   (use (match_operand 3))]
11112  ""
11113{
11114  rs6000_emit_cbranch (<MODE>mode, operands);
11115  DONE;
11116})
11117
11118(define_expand "cstore<mode>4_signed"
11119  [(use (match_operator 1 "signed_comparison_operator"
11120         [(match_operand:P 2 "gpc_reg_operand")
11121          (match_operand:P 3 "gpc_reg_operand")]))
11122   (clobber (match_operand:P 0 "gpc_reg_operand"))]
11123  ""
11124{
11125  enum rtx_code cond_code = GET_CODE (operands[1]);
11126
11127  rtx op0 = operands[0];
11128  rtx op1 = operands[2];
11129  rtx op2 = operands[3];
11130
11131  if (cond_code == GE || cond_code == LT)
11132    {
11133      cond_code = swap_condition (cond_code);
11134      std::swap (op1, op2);
11135    }
11136
11137  rtx tmp1 = gen_reg_rtx (<MODE>mode);
11138  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11139  rtx tmp3 = gen_reg_rtx (<MODE>mode);
11140
11141  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11142  emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11143  emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11144
11145  emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11146
11147  if (cond_code == LE)
11148    emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11149  else
11150    {
11151      rtx tmp4 = gen_reg_rtx (<MODE>mode);
11152      emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11153      emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11154    }
11155
11156  DONE;
11157})
11158
11159(define_expand "cstore<mode>4_unsigned"
11160  [(use (match_operator 1 "unsigned_comparison_operator"
11161         [(match_operand:P 2 "gpc_reg_operand")
11162          (match_operand:P 3 "reg_or_short_operand")]))
11163   (clobber (match_operand:P 0 "gpc_reg_operand"))]
11164  ""
11165{
11166  enum rtx_code cond_code = GET_CODE (operands[1]);
11167
11168  rtx op0 = operands[0];
11169  rtx op1 = operands[2];
11170  rtx op2 = operands[3];
11171
11172  if (cond_code == GEU || cond_code == LTU)
11173    {
11174      cond_code = swap_condition (cond_code);
11175      std::swap (op1, op2);
11176    }
11177
11178  if (!gpc_reg_operand (op1, <MODE>mode))
11179    op1 = force_reg (<MODE>mode, op1);
11180  if (!reg_or_short_operand (op2, <MODE>mode))
11181    op2 = force_reg (<MODE>mode, op2);
11182
11183  rtx tmp = gen_reg_rtx (<MODE>mode);
11184  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11185
11186  emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11187  emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11188
11189  if (cond_code == LEU)
11190    emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11191  else
11192    emit_insn (gen_neg<mode>2 (op0, tmp2));
11193
11194  DONE;
11195})
11196
11197(define_expand "cstore_si_as_di"
11198  [(use (match_operator 1 "unsigned_comparison_operator"
11199         [(match_operand:SI 2 "gpc_reg_operand")
11200          (match_operand:SI 3 "reg_or_short_operand")]))
11201   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11202  ""
11203{
11204  int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11205  enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11206
11207  operands[2] = force_reg (SImode, operands[2]);
11208  operands[3] = force_reg (SImode, operands[3]);
11209  rtx op1 = gen_reg_rtx (DImode);
11210  rtx op2 = gen_reg_rtx (DImode);
11211  convert_move (op1, operands[2], uns_flag);
11212  convert_move (op2, operands[3], uns_flag);
11213
11214  if (cond_code == GT || cond_code == LE)
11215    {
11216      cond_code = swap_condition (cond_code);
11217      std::swap (op1, op2);
11218    }
11219
11220  rtx tmp = gen_reg_rtx (DImode);
11221  rtx tmp2 = gen_reg_rtx (DImode);
11222  emit_insn (gen_subdi3 (tmp, op1, op2));
11223  emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11224
11225  rtx tmp3;
11226  switch (cond_code)
11227    {
11228    default:
11229      gcc_unreachable ();
11230    case LT:
11231      tmp3 = tmp2;
11232      break;
11233    case GE:
11234      tmp3 = gen_reg_rtx (DImode);
11235      emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11236      break;
11237    }
11238
11239  convert_move (operands[0], tmp3, 1);
11240
11241  DONE;
11242})
11243
11244(define_expand "cstore<mode>4_signed_imm"
11245  [(use (match_operator 1 "signed_comparison_operator"
11246         [(match_operand:GPR 2 "gpc_reg_operand")
11247          (match_operand:GPR 3 "immediate_operand")]))
11248   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11249  ""
11250{
11251  bool invert = false;
11252
11253  enum rtx_code cond_code = GET_CODE (operands[1]);
11254
11255  rtx op0 = operands[0];
11256  rtx op1 = operands[2];
11257  HOST_WIDE_INT val = INTVAL (operands[3]);
11258
11259  if (cond_code == GE || cond_code == GT)
11260    {
11261      cond_code = reverse_condition (cond_code);
11262      invert = true;
11263    }
11264
11265  if (cond_code == LE)
11266    val++;
11267
11268  rtx tmp = gen_reg_rtx (<MODE>mode);
11269  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11270  rtx x = gen_reg_rtx (<MODE>mode);
11271  if (val < 0)
11272    emit_insn (gen_and<mode>3 (x, op1, tmp));
11273  else
11274    emit_insn (gen_ior<mode>3 (x, op1, tmp));
11275
11276  if (invert)
11277    {
11278      rtx tmp = gen_reg_rtx (<MODE>mode);
11279      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11280      x = tmp;
11281    }
11282
11283  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11284  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11285
11286  DONE;
11287})
11288
11289(define_expand "cstore<mode>4_unsigned_imm"
11290  [(use (match_operator 1 "unsigned_comparison_operator"
11291         [(match_operand:GPR 2 "gpc_reg_operand")
11292          (match_operand:GPR 3 "immediate_operand")]))
11293   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11294  ""
11295{
11296  bool invert = false;
11297
11298  enum rtx_code cond_code = GET_CODE (operands[1]);
11299
11300  rtx op0 = operands[0];
11301  rtx op1 = operands[2];
11302  HOST_WIDE_INT val = INTVAL (operands[3]);
11303
11304  if (cond_code == GEU || cond_code == GTU)
11305    {
11306      cond_code = reverse_condition (cond_code);
11307      invert = true;
11308    }
11309
11310  if (cond_code == LEU)
11311    val++;
11312
11313  rtx tmp = gen_reg_rtx (<MODE>mode);
11314  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11315  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11316  emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11317  rtx x = gen_reg_rtx (<MODE>mode);
11318  if (val < 0)
11319    emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11320  else
11321    emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11322
11323  if (invert)
11324    {
11325      rtx tmp = gen_reg_rtx (<MODE>mode);
11326      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11327      x = tmp;
11328    }
11329
11330  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11331  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11332
11333  DONE;
11334})
11335
11336(define_expand "cstore<mode>4"
11337  [(use (match_operator 1 "comparison_operator"
11338         [(match_operand:GPR 2 "gpc_reg_operand")
11339          (match_operand:GPR 3 "reg_or_short_operand")]))
11340   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11341  ""
11342{
11343  /* Expanding EQ and NE directly to some machine instructions does not help
11344     but does hurt combine.  So don't.  */
11345  if (GET_CODE (operands[1]) == EQ)
11346    emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11347  else if (<MODE>mode == Pmode
11348	   && GET_CODE (operands[1]) == NE)
11349    emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11350  else if (GET_CODE (operands[1]) == NE)
11351    {
11352      rtx tmp = gen_reg_rtx (<MODE>mode);
11353      emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11354      emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11355    }
11356
11357  /* If ISEL is fast, expand to it.  */
11358  else if (TARGET_ISEL)
11359    rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11360
11361  /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11362     etc. combinations magically work out just right.  */
11363  else if (<MODE>mode == Pmode
11364	   && unsigned_comparison_operator (operands[1], VOIDmode))
11365    emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11366					   operands[2], operands[3]));
11367
11368  /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11369  else if (<MODE>mode == SImode && Pmode == DImode)
11370    emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11371				    operands[2], operands[3]));
11372
11373  /* For signed comparisons against a constant, we can do some simple
11374     bit-twiddling.  */
11375  else if (signed_comparison_operator (operands[1], VOIDmode)
11376	   && CONST_INT_P (operands[3]))
11377    emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11378					     operands[2], operands[3]));
11379
11380  /* And similarly for unsigned comparisons.  */
11381  else if (unsigned_comparison_operator (operands[1], VOIDmode)
11382	   && CONST_INT_P (operands[3]))
11383    emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11384					       operands[2], operands[3]));
11385
11386  /* We also do not want to use mfcr for signed comparisons.  */
11387  else if (<MODE>mode == Pmode
11388	   && signed_comparison_operator (operands[1], VOIDmode))
11389    emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11390					 operands[2], operands[3]));
11391
11392  /* Everything else, use the mfcr brute force.  */
11393  else
11394    rs6000_emit_sCOND (<MODE>mode, operands);
11395
11396  DONE;
11397})
11398
11399(define_expand "cstore<mode>4"
11400  [(use (match_operator 1 "comparison_operator"
11401         [(match_operand:FP 2 "gpc_reg_operand")
11402          (match_operand:FP 3 "gpc_reg_operand")]))
11403   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11404  ""
11405{
11406  rs6000_emit_sCOND (<MODE>mode, operands);
11407  DONE;
11408})
11409
11410
11411(define_expand "stack_protect_set"
11412  [(match_operand 0 "memory_operand")
11413   (match_operand 1 "memory_operand")]
11414  ""
11415{
11416  if (rs6000_stack_protector_guard == SSP_TLS)
11417    {
11418      rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11419      rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11420      rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11421      operands[1] = gen_rtx_MEM (Pmode, addr);
11422    }
11423
11424  if (TARGET_64BIT)
11425    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11426  else
11427    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11428
11429  DONE;
11430})
11431
11432(define_insn "stack_protect_setsi"
11433  [(set (match_operand:SI 0 "memory_operand" "=m")
11434	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11435   (set (match_scratch:SI 2 "=&r") (const_int 0))]
11436  "TARGET_32BIT"
11437  "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11438  [(set_attr "type" "three")
11439   (set_attr "length" "12")])
11440
11441(define_insn "stack_protect_setdi"
11442  [(set (match_operand:DI 0 "memory_operand" "=Y")
11443	(unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11444   (set (match_scratch:DI 2 "=&r") (const_int 0))]
11445  "TARGET_64BIT"
11446  "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11447  [(set_attr "type" "three")
11448   (set_attr "length" "12")])
11449
11450(define_expand "stack_protect_test"
11451  [(match_operand 0 "memory_operand")
11452   (match_operand 1 "memory_operand")
11453   (match_operand 2 "")]
11454  ""
11455{
11456  rtx guard = operands[1];
11457
11458  if (rs6000_stack_protector_guard == SSP_TLS)
11459    {
11460      rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11461      rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11462      rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11463      guard = gen_rtx_MEM (Pmode, addr);
11464    }
11465
11466  operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11467  rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11468  rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11469  emit_jump_insn (jump);
11470
11471  DONE;
11472})
11473
11474(define_insn "stack_protect_testsi"
11475  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11476        (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11477		      (match_operand:SI 2 "memory_operand" "m,m")]
11478		     UNSPEC_SP_TEST))
11479   (set (match_scratch:SI 4 "=r,r") (const_int 0))
11480   (clobber (match_scratch:SI 3 "=&r,&r"))]
11481  "TARGET_32BIT"
11482  "@
11483   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11484   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11485  [(set_attr "length" "16,20")])
11486
11487(define_insn "stack_protect_testdi"
11488  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11489        (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11490		      (match_operand:DI 2 "memory_operand" "Y,Y")]
11491		     UNSPEC_SP_TEST))
11492   (set (match_scratch:DI 4 "=r,r") (const_int 0))
11493   (clobber (match_scratch:DI 3 "=&r,&r"))]
11494  "TARGET_64BIT"
11495  "@
11496   ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11497   ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11498  [(set_attr "length" "16,20")])
11499
11500
11501;; Here are the actual compare insns.
11502(define_insn "*cmp<mode>_signed"
11503  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11504	(compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11505		    (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11506  ""
11507  "cmp<wd>%I2 %0,%1,%2"
11508  [(set_attr "type" "cmp")])
11509
11510(define_insn "*cmp<mode>_unsigned"
11511  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11512	(compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11513		       (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11514  ""
11515  "cmpl<wd>%I2 %0,%1,%2"
11516  [(set_attr "type" "cmp")])
11517
11518;; If we are comparing a register for equality with a large constant,
11519;; we can do this with an XOR followed by a compare.  But this is profitable
11520;; only if the large constant is only used for the comparison (and in this
11521;; case we already have a register to reuse as scratch).
11522;;
11523;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11524;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11525
11526(define_peephole2
11527  [(set (match_operand:SI 0 "register_operand")
11528        (match_operand:SI 1 "logical_const_operand"))
11529   (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11530		       [(match_dup 0)
11531			(match_operand:SI 2 "logical_const_operand")]))
11532   (set (match_operand:CC 4 "cc_reg_operand")
11533        (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11534                    (match_dup 0)))
11535   (set (pc)
11536        (if_then_else (match_operator 6 "equality_operator"
11537                       [(match_dup 4) (const_int 0)])
11538                      (match_operand 7 "")
11539                      (match_operand 8 "")))]
11540  "peep2_reg_dead_p (3, operands[0])
11541   && peep2_reg_dead_p (4, operands[4])
11542   && REGNO (operands[0]) != REGNO (operands[5])"
11543 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11544  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11545  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11546
11547{
11548  /* Get the constant we are comparing against, and see what it looks like
11549     when sign-extended from 16 to 32 bits.  Then see what constant we could
11550     XOR with SEXTC to get the sign-extended value.  */
11551  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11552					      SImode,
11553					      operands[1], operands[2]);
11554  HOST_WIDE_INT c = INTVAL (cnst);
11555  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11556  HOST_WIDE_INT xorv = c ^ sextc;
11557
11558  operands[9] = GEN_INT (xorv);
11559  operands[10] = GEN_INT (sextc);
11560})
11561
11562;; The following two insns don't exist as single insns, but if we provide
11563;; them, we can swap an add and compare, which will enable us to overlap more
11564;; of the required delay between a compare and branch.  We generate code for
11565;; them by splitting.
11566
11567(define_insn ""
11568  [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11569	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11570		    (match_operand:SI 2 "short_cint_operand" "i")))
11571   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11572	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11573  ""
11574  "#"
11575  [(set_attr "length" "8")])
11576
11577(define_insn ""
11578  [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11579	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11580		       (match_operand:SI 2 "u_short_cint_operand" "i")))
11581   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11582	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11583  ""
11584  "#"
11585  [(set_attr "length" "8")])
11586
11587(define_split
11588  [(set (match_operand:CC 3 "cc_reg_operand")
11589	(compare:CC (match_operand:SI 1 "gpc_reg_operand")
11590		    (match_operand:SI 2 "short_cint_operand")))
11591   (set (match_operand:SI 0 "gpc_reg_operand")
11592	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11593  ""
11594  [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11595   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11596
11597(define_split
11598  [(set (match_operand:CCUNS 3 "cc_reg_operand")
11599	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11600		       (match_operand:SI 2 "u_short_cint_operand")))
11601   (set (match_operand:SI 0 "gpc_reg_operand")
11602	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11603  ""
11604  [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11605   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11606
11607;; Only need to compare second words if first words equal
11608(define_insn "*cmp<mode>_internal1"
11609  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11610	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11611		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11612  "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11613   && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11614  "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11615  [(set_attr "type" "fpcompare")
11616   (set_attr "length" "12")])
11617
11618(define_insn_and_split "*cmp<mode>_internal2"
11619  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11620	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11621		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11622    (clobber (match_scratch:DF 3 "=d"))
11623    (clobber (match_scratch:DF 4 "=d"))
11624    (clobber (match_scratch:DF 5 "=d"))
11625    (clobber (match_scratch:DF 6 "=d"))
11626    (clobber (match_scratch:DF 7 "=d"))
11627    (clobber (match_scratch:DF 8 "=d"))
11628    (clobber (match_scratch:DF 9 "=d"))
11629    (clobber (match_scratch:DF 10 "=d"))
11630    (clobber (match_scratch:GPR 11 "=b"))]
11631  "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11632   && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11633  "#"
11634  "&& reload_completed"
11635  [(set (match_dup 3) (match_dup 14))
11636   (set (match_dup 4) (match_dup 15))
11637   (set (match_dup 9) (abs:DF (match_dup 5)))
11638   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11639   (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11640			   (label_ref (match_dup 12))
11641			   (pc)))
11642   (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11643   (set (pc) (label_ref (match_dup 13)))
11644   (match_dup 12)
11645   (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11646   (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11647   (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11648   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11649   (match_dup 13)]
11650{
11651  REAL_VALUE_TYPE rv;
11652  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11653  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11654
11655  operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11656  operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11657  operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11658  operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11659  operands[12] = gen_label_rtx ();
11660  operands[13] = gen_label_rtx ();
11661  real_inf (&rv);
11662  operands[14] = force_const_mem (DFmode,
11663				  const_double_from_real_value (rv, DFmode));
11664  operands[15] = force_const_mem (DFmode,
11665				  const_double_from_real_value (dconst0,
11666								DFmode));
11667  if (TARGET_TOC)
11668    {
11669      rtx tocref;
11670      tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11671      operands[14] = gen_const_mem (DFmode, tocref);
11672      tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11673      operands[15] = gen_const_mem (DFmode, tocref);
11674      set_mem_alias_set (operands[14], get_TOC_alias_set ());
11675      set_mem_alias_set (operands[15], get_TOC_alias_set ());
11676    }
11677})
11678
11679;; Now we have the scc insns.  We can do some combinations because of the
11680;; way the machine works.
11681;;
11682;; Note that this is probably faster if we can put an insn between the
11683;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11684;; cases the insns below which don't use an intermediate CR field will
11685;; be used instead.
11686(define_insn ""
11687  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11688	(match_operator:SI 1 "scc_comparison_operator"
11689			   [(match_operand 2 "cc_reg_operand" "y")
11690			    (const_int 0)]))]
11691  ""
11692  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11693  [(set (attr "type")
11694     (cond [(match_test "TARGET_MFCRF")
11695		(const_string "mfcrf")
11696	   ]
11697	(const_string "mfcr")))
11698   (set_attr "length" "8")])
11699
11700;; Same as above, but get the OV/ORDERED bit.
11701(define_insn "move_from_CR_ov_bit"
11702  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11703	(unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11704		   UNSPEC_MV_CR_OV))]
11705  "TARGET_PAIRED_FLOAT"
11706  "mfcr %0\;rlwinm %0,%0,%t1,1"
11707  [(set_attr "type" "mfcr")
11708   (set_attr "length" "8")])
11709
11710(define_insn ""
11711  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11712	(match_operator:DI 1 "scc_comparison_operator"
11713			   [(match_operand 2 "cc_reg_operand" "y")
11714			    (const_int 0)]))]
11715  "TARGET_POWERPC64"
11716  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11717  [(set (attr "type")
11718     (cond [(match_test "TARGET_MFCRF")
11719		(const_string "mfcrf")
11720	   ]
11721	(const_string "mfcr")))
11722   (set_attr "length" "8")])
11723
11724(define_insn ""
11725  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11726	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
11727				       [(match_operand 2 "cc_reg_operand" "y,y")
11728					(const_int 0)])
11729		    (const_int 0)))
11730   (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11731	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11732  "TARGET_32BIT"
11733  "@
11734   mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11735   #"
11736  [(set_attr "type" "shift")
11737   (set_attr "dot" "yes")
11738   (set_attr "length" "8,16")])
11739
11740(define_split
11741  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11742	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
11743				       [(match_operand 2 "cc_reg_operand")
11744					(const_int 0)])
11745		    (const_int 0)))
11746   (set (match_operand:SI 3 "gpc_reg_operand")
11747	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11748  "TARGET_32BIT && reload_completed"
11749  [(set (match_dup 3)
11750	(match_op_dup 1 [(match_dup 2) (const_int 0)]))
11751   (set (match_dup 0)
11752	(compare:CC (match_dup 3)
11753		    (const_int 0)))]
11754  "")
11755
11756(define_insn ""
11757  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11758	(ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11759				      [(match_operand 2 "cc_reg_operand" "y")
11760				       (const_int 0)])
11761		   (match_operand:SI 3 "const_int_operand" "n")))]
11762  ""
11763{
11764  int is_bit = ccr_bit (operands[1], 1);
11765  int put_bit = 31 - (INTVAL (operands[3]) & 31);
11766  int count;
11767
11768  if (is_bit >= put_bit)
11769    count = is_bit - put_bit;
11770  else
11771    count = 32 - (put_bit - is_bit);
11772
11773  operands[4] = GEN_INT (count);
11774  operands[5] = GEN_INT (put_bit);
11775
11776  return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11777}
11778  [(set (attr "type")
11779     (cond [(match_test "TARGET_MFCRF")
11780		(const_string "mfcrf")
11781	   ]
11782	(const_string "mfcr")))
11783   (set_attr "length" "8")])
11784
11785(define_insn ""
11786  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11787	(compare:CC
11788	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11789				       [(match_operand 2 "cc_reg_operand" "y,y")
11790					(const_int 0)])
11791		    (match_operand:SI 3 "const_int_operand" "n,n"))
11792	 (const_int 0)))
11793   (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11794	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11795		   (match_dup 3)))]
11796  ""
11797{
11798  int is_bit = ccr_bit (operands[1], 1);
11799  int put_bit = 31 - (INTVAL (operands[3]) & 31);
11800  int count;
11801
11802  /* Force split for non-cc0 compare.  */
11803  if (which_alternative == 1)
11804     return "#";
11805
11806  if (is_bit >= put_bit)
11807    count = is_bit - put_bit;
11808  else
11809    count = 32 - (put_bit - is_bit);
11810
11811  operands[5] = GEN_INT (count);
11812  operands[6] = GEN_INT (put_bit);
11813
11814  return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11815}
11816  [(set_attr "type" "shift")
11817   (set_attr "dot" "yes")
11818   (set_attr "length" "8,16")])
11819
11820(define_split
11821  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11822	(compare:CC
11823	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11824				       [(match_operand 2 "cc_reg_operand")
11825					(const_int 0)])
11826		    (match_operand:SI 3 "const_int_operand"))
11827	 (const_int 0)))
11828   (set (match_operand:SI 4 "gpc_reg_operand")
11829	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11830		   (match_dup 3)))]
11831  "reload_completed"
11832  [(set (match_dup 4)
11833	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11834		   (match_dup 3)))
11835   (set (match_dup 0)
11836	(compare:CC (match_dup 4)
11837		    (const_int 0)))]
11838  "")
11839
11840
11841(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11842(define_code_attr UNS [(eq "CC")
11843		       (ne "CC")
11844		       (lt "CC") (ltu "CCUNS")
11845		       (gt "CC") (gtu "CCUNS")
11846		       (le "CC") (leu "CCUNS")
11847		       (ge "CC") (geu "CCUNS")])
11848(define_code_attr UNSu_ [(eq "")
11849			 (ne "")
11850			 (lt "") (ltu "u_")
11851			 (gt "") (gtu "u_")
11852			 (le "") (leu "u_")
11853			 (ge "") (geu "u_")])
11854(define_code_attr UNSIK [(eq "I")
11855			 (ne "I")
11856			 (lt "I") (ltu "K")
11857			 (gt "I") (gtu "K")
11858			 (le "I") (leu "K")
11859			 (ge "I") (geu "K")])
11860
11861(define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11862  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11863	(cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11864		 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11865   (clobber (match_scratch:GPR 3 "=r"))
11866   (clobber (match_scratch:GPR 4 "=r"))
11867   (clobber (match_scratch:<UNS> 5 "=y"))]
11868  "TARGET_ISEL
11869   && !(<CODE> == EQ && operands[2] == const0_rtx)
11870   && !(<CODE> == NE && operands[2] == const0_rtx
11871	&& <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11872  "#"
11873  "&& 1"
11874  [(pc)]
11875{
11876  rtx_code code = <CODE>;
11877  if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11878    {
11879      HOST_WIDE_INT val = INTVAL (operands[2]);
11880      if (code == LT && val != -0x8000)
11881	{
11882	  code = LE;
11883	  val--;
11884	}
11885      if (code == GT && val != 0x7fff)
11886	{
11887	  code = GE;
11888	  val++;
11889	}
11890      if (code == LTU && val != 0)
11891	{
11892	  code = LEU;
11893	  val--;
11894	}
11895      if (code == GTU && val != 0xffff)
11896	{
11897	  code = GEU;
11898	  val++;
11899	}
11900      operands[2] = GEN_INT (val);
11901    }
11902
11903  if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11904    operands[3] = const0_rtx;
11905  else
11906    {
11907      if (GET_CODE (operands[3]) == SCRATCH)
11908	operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11909      emit_move_insn (operands[3], const0_rtx);
11910    }
11911
11912  if (GET_CODE (operands[4]) == SCRATCH)
11913    operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11914  emit_move_insn (operands[4], const1_rtx);
11915
11916  if (GET_CODE (operands[5]) == SCRATCH)
11917    operands[5] = gen_reg_rtx (<UNS>mode);
11918
11919  rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11920  emit_insn (gen_rtx_SET (operands[5], c1));
11921
11922  rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11923  rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11924  emit_move_insn (operands[0], x);
11925
11926  DONE;
11927}
11928  [(set (attr "cost")
11929	(if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11930				   || <CODE> == NE
11931				   || <CODE> == LE || <CODE> == GE
11932				   || <CODE> == LEU || <CODE> == GEU")
11933		      (const_string "9")
11934		      (const_string "10")))])
11935
11936(define_mode_attr scc_eq_op2 [(SI "rKLI")
11937			      (DI "rKJI")])
11938
11939(define_expand "eq<mode>3"
11940  [(parallel [
11941     (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11942	  (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11943		  (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11944     (clobber (match_scratch:GPR 3 "=r"))
11945     (clobber (match_scratch:GPR 4 "=r"))])]
11946  ""
11947{
11948  if (TARGET_ISEL && operands[2] != const0_rtx)
11949    {
11950      emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11951					   operands[2]));
11952      DONE;
11953    }
11954})
11955
11956(define_insn_and_split "*eq<mode>3"
11957  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11958	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11959		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11960   (clobber (match_scratch:GPR 3 "=r"))
11961   (clobber (match_scratch:GPR 4 "=r"))]
11962  "!(TARGET_ISEL && operands[2] != const0_rtx)"
11963  "#"
11964  "&& 1"
11965  [(set (match_dup 4)
11966	(clz:GPR (match_dup 3)))
11967   (set (match_dup 0)
11968	(lshiftrt:GPR (match_dup 4)
11969		      (match_dup 5)))]
11970{
11971  operands[3] = rs6000_emit_eqne (<MODE>mode,
11972				  operands[1], operands[2], operands[3]);
11973
11974  if (GET_CODE (operands[4]) == SCRATCH)
11975    operands[4] = gen_reg_rtx (<MODE>mode);
11976
11977  operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11978}
11979  [(set (attr "length")
11980	(if_then_else (match_test "operands[2] == const0_rtx")
11981		      (const_string "8")
11982		      (const_string "12")))])
11983
11984(define_expand "ne<mode>3"
11985  [(parallel [
11986     (set (match_operand:P 0 "gpc_reg_operand" "=r")
11987	  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11988		(match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11989     (clobber (match_scratch:P 3 "=r"))
11990     (clobber (match_scratch:P 4 "=r"))
11991     (clobber (reg:P CA_REGNO))])]
11992  ""
11993{
11994  if (TARGET_ISEL && operands[2] != const0_rtx)
11995    {
11996      emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11997					   operands[2]));
11998      DONE;
11999    }
12000})
12001
12002(define_insn_and_split "*ne<mode>3"
12003  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12004	(ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12005	      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12006   (clobber (match_scratch:P 3 "=r"))
12007   (clobber (match_scratch:P 4 "=r"))
12008   (clobber (reg:P CA_REGNO))]
12009  "!(TARGET_ISEL && operands[2] != const0_rtx)"
12010  "#"
12011  "&& 1"
12012  [(parallel [(set (match_dup 4)
12013		   (plus:P (match_dup 3)
12014			   (const_int -1)))
12015	      (set (reg:P CA_REGNO)
12016		   (ne:P (match_dup 3)
12017			 (const_int 0)))])
12018   (parallel [(set (match_dup 0)
12019		   (plus:P (plus:P (not:P (match_dup 4))
12020				   (reg:P CA_REGNO))
12021			   (match_dup 3)))
12022	      (clobber (reg:P CA_REGNO))])]
12023{
12024  operands[3] = rs6000_emit_eqne (<MODE>mode,
12025				  operands[1], operands[2], operands[3]);
12026
12027  if (GET_CODE (operands[4]) == SCRATCH)
12028    operands[4] = gen_reg_rtx (<MODE>mode);
12029}
12030  [(set (attr "length")
12031	(if_then_else (match_test "operands[2] == const0_rtx")
12032		      (const_string "8")
12033		      (const_string "12")))])
12034
12035(define_insn_and_split "*neg_eq_<mode>"
12036  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12037	(neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12038		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12039   (clobber (match_scratch:P 3 "=r"))
12040   (clobber (match_scratch:P 4 "=r"))
12041   (clobber (reg:P CA_REGNO))]
12042  ""
12043  "#"
12044  ""
12045  [(parallel [(set (match_dup 4)
12046		   (plus:P (match_dup 3)
12047			   (const_int -1)))
12048	      (set (reg:P CA_REGNO)
12049		   (ne:P (match_dup 3)
12050			 (const_int 0)))])
12051   (parallel [(set (match_dup 0)
12052		   (plus:P (reg:P CA_REGNO)
12053			   (const_int -1)))
12054	      (clobber (reg:P CA_REGNO))])]
12055{
12056  operands[3] = rs6000_emit_eqne (<MODE>mode,
12057				  operands[1], operands[2], operands[3]);
12058
12059  if (GET_CODE (operands[4]) == SCRATCH)
12060    operands[4] = gen_reg_rtx (<MODE>mode);
12061}
12062  [(set (attr "length")
12063	(if_then_else (match_test "operands[2] == const0_rtx")
12064		      (const_string "8")
12065		      (const_string "12")))])
12066
12067(define_insn_and_split "*neg_ne_<mode>"
12068  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12069	(neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12070		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12071   (clobber (match_scratch:P 3 "=r"))
12072   (clobber (match_scratch:P 4 "=r"))
12073   (clobber (reg:P CA_REGNO))]
12074  ""
12075  "#"
12076  ""
12077  [(parallel [(set (match_dup 4)
12078		   (neg:P (match_dup 3)))
12079	      (set (reg:P CA_REGNO)
12080		   (eq:P (match_dup 3)
12081			 (const_int 0)))])
12082   (parallel [(set (match_dup 0)
12083		   (plus:P (reg:P CA_REGNO)
12084			   (const_int -1)))
12085	      (clobber (reg:P CA_REGNO))])]
12086{
12087  operands[3] = rs6000_emit_eqne (<MODE>mode,
12088				  operands[1], operands[2], operands[3]);
12089
12090  if (GET_CODE (operands[4]) == SCRATCH)
12091    operands[4] = gen_reg_rtx (<MODE>mode);
12092}
12093  [(set (attr "length")
12094	(if_then_else (match_test "operands[2] == const0_rtx")
12095		      (const_string "8")
12096		      (const_string "12")))])
12097
12098(define_insn_and_split "*plus_eq_<mode>"
12099  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12100	(plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12101		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12102		(match_operand:P 3 "gpc_reg_operand" "r")))
12103   (clobber (match_scratch:P 4 "=r"))
12104   (clobber (match_scratch:P 5 "=r"))
12105   (clobber (reg:P CA_REGNO))]
12106  ""
12107  "#"
12108  ""
12109  [(parallel [(set (match_dup 5)
12110		   (neg:P (match_dup 4)))
12111	      (set (reg:P CA_REGNO)
12112		   (eq:P (match_dup 4)
12113			 (const_int 0)))])
12114   (parallel [(set (match_dup 0)
12115		   (plus:P (match_dup 3)
12116			   (reg:P CA_REGNO)))
12117	      (clobber (reg:P CA_REGNO))])]
12118{
12119  operands[4] = rs6000_emit_eqne (<MODE>mode,
12120				  operands[1], operands[2], operands[4]);
12121
12122  if (GET_CODE (operands[5]) == SCRATCH)
12123    operands[5] = gen_reg_rtx (<MODE>mode);
12124}
12125  [(set (attr "length")
12126	(if_then_else (match_test "operands[2] == const0_rtx")
12127		      (const_string "8")
12128		      (const_string "12")))])
12129
12130(define_insn_and_split "*plus_ne_<mode>"
12131  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12132	(plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12133		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12134		(match_operand:P 3 "gpc_reg_operand" "r")))
12135   (clobber (match_scratch:P 4 "=r"))
12136   (clobber (match_scratch:P 5 "=r"))
12137   (clobber (reg:P CA_REGNO))]
12138  ""
12139  "#"
12140  ""
12141  [(parallel [(set (match_dup 5)
12142		   (plus:P (match_dup 4)
12143			   (const_int -1)))
12144	      (set (reg:P CA_REGNO)
12145		   (ne:P (match_dup 4)
12146			 (const_int 0)))])
12147   (parallel [(set (match_dup 0)
12148		   (plus:P (match_dup 3)
12149			   (reg:P CA_REGNO)))
12150	      (clobber (reg:P CA_REGNO))])]
12151{
12152  operands[4] = rs6000_emit_eqne (<MODE>mode,
12153				  operands[1], operands[2], operands[4]);
12154
12155  if (GET_CODE (operands[5]) == SCRATCH)
12156    operands[5] = gen_reg_rtx (<MODE>mode);
12157}
12158  [(set (attr "length")
12159	(if_then_else (match_test "operands[2] == const0_rtx")
12160		      (const_string "8")
12161		      (const_string "12")))])
12162
12163(define_insn_and_split "*minus_eq_<mode>"
12164  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12165	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12166		 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12167		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12168   (clobber (match_scratch:P 4 "=r"))
12169   (clobber (match_scratch:P 5 "=r"))
12170   (clobber (reg:P CA_REGNO))]
12171  ""
12172  "#"
12173  ""
12174  [(parallel [(set (match_dup 5)
12175		   (plus:P (match_dup 4)
12176			   (const_int -1)))
12177	      (set (reg:P CA_REGNO)
12178		   (ne:P (match_dup 4)
12179			 (const_int 0)))])
12180   (parallel [(set (match_dup 0)
12181		   (plus:P (plus:P (match_dup 3)
12182				   (reg:P CA_REGNO))
12183			   (const_int -1)))
12184	      (clobber (reg:P CA_REGNO))])]
12185{
12186  operands[4] = rs6000_emit_eqne (<MODE>mode,
12187				  operands[1], operands[2], operands[4]);
12188
12189  if (GET_CODE (operands[5]) == SCRATCH)
12190    operands[5] = gen_reg_rtx (<MODE>mode);
12191}
12192  [(set (attr "length")
12193	(if_then_else (match_test "operands[2] == const0_rtx")
12194		      (const_string "8")
12195		      (const_string "12")))])
12196
12197(define_insn_and_split "*minus_ne_<mode>"
12198  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12199	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12200		 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12201		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12202   (clobber (match_scratch:P 4 "=r"))
12203   (clobber (match_scratch:P 5 "=r"))
12204   (clobber (reg:P CA_REGNO))]
12205  ""
12206  "#"
12207  ""
12208  [(parallel [(set (match_dup 5)
12209		   (neg:P (match_dup 4)))
12210	      (set (reg:P CA_REGNO)
12211		   (eq:P (match_dup 4)
12212			 (const_int 0)))])
12213   (parallel [(set (match_dup 0)
12214		   (plus:P (plus:P (match_dup 3)
12215				   (reg:P CA_REGNO))
12216			   (const_int -1)))
12217	      (clobber (reg:P CA_REGNO))])]
12218{
12219  operands[4] = rs6000_emit_eqne (<MODE>mode,
12220				  operands[1], operands[2], operands[4]);
12221
12222  if (GET_CODE (operands[5]) == SCRATCH)
12223    operands[5] = gen_reg_rtx (<MODE>mode);
12224}
12225  [(set (attr "length")
12226	(if_then_else (match_test "operands[2] == const0_rtx")
12227		      (const_string "8")
12228		      (const_string "12")))])
12229
12230(define_insn_and_split "*eqsi3_ext<mode>"
12231  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12232	(eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12233		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12234   (clobber (match_scratch:SI 3 "=r"))
12235   (clobber (match_scratch:SI 4 "=r"))]
12236  ""
12237  "#"
12238  ""
12239  [(set (match_dup 4)
12240	(clz:SI (match_dup 3)))
12241   (set (match_dup 0)
12242	(zero_extend:EXTSI
12243	  (lshiftrt:SI (match_dup 4)
12244		       (const_int 5))))]
12245{
12246  operands[3] = rs6000_emit_eqne (SImode,
12247				  operands[1], operands[2], operands[3]);
12248
12249  if (GET_CODE (operands[4]) == SCRATCH)
12250    operands[4] = gen_reg_rtx (SImode);
12251}
12252  [(set (attr "length")
12253	(if_then_else (match_test "operands[2] == const0_rtx")
12254		      (const_string "8")
12255		      (const_string "12")))])
12256
12257(define_insn_and_split "*nesi3_ext<mode>"
12258  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12259	(ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12260		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12261   (clobber (match_scratch:SI 3 "=r"))
12262   (clobber (match_scratch:SI 4 "=r"))
12263   (clobber (match_scratch:EXTSI 5 "=r"))]
12264  "!TARGET_ISEL"
12265  "#"
12266  "&& 1"
12267  [(set (match_dup 4)
12268	(clz:SI (match_dup 3)))
12269   (set (match_dup 5)
12270	(zero_extend:EXTSI
12271	  (lshiftrt:SI (match_dup 4)
12272		       (const_int 5))))
12273   (set (match_dup 0)
12274	(xor:EXTSI (match_dup 5)
12275		   (const_int 1)))]
12276{
12277  operands[3] = rs6000_emit_eqne (SImode,
12278				  operands[1], operands[2], operands[3]);
12279
12280  if (GET_CODE (operands[4]) == SCRATCH)
12281    operands[4] = gen_reg_rtx (SImode);
12282  if (GET_CODE (operands[5]) == SCRATCH)
12283    operands[5] = gen_reg_rtx (<MODE>mode);
12284}
12285  [(set (attr "length")
12286	(if_then_else (match_test "operands[2] == const0_rtx")
12287		      (const_string "12")
12288		      (const_string "16")))])
12289
12290;; Define both directions of branch and return.  If we need a reload
12291;; register, we'd rather use CR0 since it is much easier to copy a
12292;; register CC value to there.
12293
12294(define_insn ""
12295  [(set (pc)
12296	(if_then_else (match_operator 1 "branch_comparison_operator"
12297				      [(match_operand 2 "cc_reg_operand" "y")
12298				       (const_int 0)])
12299		      (label_ref (match_operand 0))
12300		      (pc)))]
12301  ""
12302{
12303  return output_cbranch (operands[1], "%l0", 0, insn);
12304}
12305  [(set_attr "type" "branch")])
12306
12307(define_insn ""
12308  [(set (pc)
12309	(if_then_else (match_operator 0 "branch_comparison_operator"
12310				      [(match_operand 1 "cc_reg_operand" "y")
12311				       (const_int 0)])
12312		      (any_return)
12313		      (pc)))]
12314  "<return_pred>"
12315{
12316  return output_cbranch (operands[0], NULL, 0, insn);
12317}
12318  [(set_attr "type" "jmpreg")
12319   (set_attr "length" "4")])
12320
12321;; Logic on condition register values.
12322
12323; This pattern matches things like
12324; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12325;					   (eq:SI (reg:CCFP 68) (const_int 0)))
12326;				   (const_int 1)))
12327; which are generated by the branch logic.
12328; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12329
12330(define_insn "cceq_ior_compare"
12331  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12332        (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12333	                [(match_operator:SI 2
12334				      "branch_positive_comparison_operator"
12335				      [(match_operand 3
12336						      "cc_reg_operand" "y,y")
12337				       (const_int 0)])
12338	                 (match_operator:SI 4
12339				      "branch_positive_comparison_operator"
12340				      [(match_operand 5
12341						      "cc_reg_operand" "0,y")
12342				       (const_int 0)])])
12343		      (const_int 1)))]
12344  ""
12345  "cr%q1 %E0,%j2,%j4"
12346  [(set_attr "type" "cr_logical")
12347   (set_attr "cr_logical_3op" "no,yes")])
12348
12349; Why is the constant -1 here, but 1 in the previous pattern?
12350; Because ~1 has all but the low bit set.
12351(define_insn "cceq_ior_compare_complement"
12352  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12353        (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12354	                [(not:SI (match_operator:SI 2
12355				      "branch_positive_comparison_operator"
12356				      [(match_operand 3
12357						      "cc_reg_operand" "y,y")
12358				       (const_int 0)]))
12359	                 (match_operator:SI 4
12360				"branch_positive_comparison_operator"
12361				[(match_operand 5
12362						"cc_reg_operand" "0,y")
12363				 (const_int 0)])])
12364		      (const_int -1)))]
12365  ""
12366  "cr%q1 %E0,%j2,%j4"
12367  [(set_attr "type" "cr_logical")
12368   (set_attr "cr_logical_3op" "no,yes")])
12369
12370(define_insn "*cceq_rev_compare"
12371  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12372	(compare:CCEQ (match_operator:SI 1
12373				      "branch_positive_comparison_operator"
12374				      [(match_operand 2
12375						      "cc_reg_operand" "0,y")
12376				       (const_int 0)])
12377		      (const_int 0)))]
12378  ""
12379  "crnot %E0,%j1"
12380  [(set_attr "type" "cr_logical")
12381   (set_attr "cr_logical_3op" "no,yes")])
12382
12383;; If we are comparing the result of two comparisons, this can be done
12384;; using creqv or crxor.
12385
12386(define_insn_and_split ""
12387  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12388	(compare:CCEQ (match_operator 1 "branch_comparison_operator"
12389			      [(match_operand 2 "cc_reg_operand" "y")
12390			       (const_int 0)])
12391		      (match_operator 3 "branch_comparison_operator"
12392			      [(match_operand 4 "cc_reg_operand" "y")
12393			       (const_int 0)])))]
12394  ""
12395  "#"
12396  ""
12397  [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12398				    (match_dup 5)))]
12399{
12400  int positive_1, positive_2;
12401
12402  positive_1 = branch_positive_comparison_operator (operands[1],
12403						    GET_MODE (operands[1]));
12404  positive_2 = branch_positive_comparison_operator (operands[3],
12405						    GET_MODE (operands[3]));
12406
12407  if (! positive_1)
12408    operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12409							    GET_CODE (operands[1])),
12410				  SImode,
12411				  operands[2], const0_rtx);
12412  else if (GET_MODE (operands[1]) != SImode)
12413    operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12414				  operands[2], const0_rtx);
12415
12416  if (! positive_2)
12417    operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12418							    GET_CODE (operands[3])),
12419				  SImode,
12420				  operands[4], const0_rtx);
12421  else if (GET_MODE (operands[3]) != SImode)
12422    operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12423				  operands[4], const0_rtx);
12424
12425  if (positive_1 == positive_2)
12426    {
12427      operands[1] = gen_rtx_NOT (SImode, operands[1]);
12428      operands[5] = constm1_rtx;
12429    }
12430  else
12431    {
12432      operands[5] = const1_rtx;
12433    }
12434})
12435
12436;; Unconditional branch and return.
12437
12438(define_insn "jump"
12439  [(set (pc)
12440	(label_ref (match_operand 0)))]
12441  ""
12442  "b %l0"
12443  [(set_attr "type" "branch")])
12444
12445(define_insn "<return_str>return"
12446  [(any_return)]
12447  "<return_pred>"
12448  "blr"
12449  [(set_attr "type" "jmpreg")])
12450
12451(define_expand "indirect_jump"
12452  [(set (pc) (match_operand 0 "register_operand"))]
12453 ""
12454{
12455  if (!rs6000_speculate_indirect_jumps) {
12456    rtx ccreg = gen_reg_rtx (CCmode);
12457    if (Pmode == DImode)
12458      emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12459    else
12460      emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12461    DONE;
12462  }
12463})
12464
12465(define_insn "*indirect_jump<mode>"
12466  [(set (pc)
12467	(match_operand:P 0 "register_operand" "c,*l"))]
12468  "rs6000_speculate_indirect_jumps"
12469  "b%T0"
12470  [(set_attr "type" "jmpreg")])
12471
12472(define_insn "indirect_jump<mode>_nospec"
12473  [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12474   (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12475  "!rs6000_speculate_indirect_jumps"
12476  "crset %E1\;beq%T0- %1\;b $"
12477  [(set_attr "type" "jmpreg")
12478   (set_attr "length" "12")])
12479
12480;; Table jump for switch statements:
12481(define_expand "tablejump"
12482  [(use (match_operand 0))
12483   (use (label_ref (match_operand 1)))]
12484  ""
12485{
12486  if (rs6000_speculate_indirect_jumps)
12487    {
12488      if (TARGET_32BIT)
12489      	emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12490      else
12491	emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12492    }
12493  else
12494    {
12495      rtx ccreg = gen_reg_rtx (CCmode);
12496      rtx jump;
12497      if (TARGET_32BIT)
12498	jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12499      else
12500	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12501      emit_jump_insn (jump);
12502    }
12503  DONE;
12504})
12505
12506(define_expand "tablejumpsi"
12507  [(set (match_dup 3)
12508	(plus:SI (match_operand:SI 0)
12509		 (match_dup 2)))
12510   (parallel [(set (pc)
12511		   (match_dup 3))
12512	      (use (label_ref (match_operand 1)))])]
12513  "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12514{
12515  operands[0] = force_reg (SImode, operands[0]);
12516  operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12517  operands[3] = gen_reg_rtx (SImode);
12518})
12519
12520(define_expand "tablejumpsi_nospec"
12521  [(set (match_dup 4)
12522	(plus:SI (match_operand:SI 0)
12523		 (match_dup 3)))
12524   (parallel [(set (pc)
12525		   (match_dup 4))
12526	      (use (label_ref (match_operand 1)))
12527	      (clobber (match_operand 2))])]
12528  "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12529{
12530  operands[0] = force_reg (SImode, operands[0]);
12531  operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12532  operands[4] = gen_reg_rtx (SImode);
12533})
12534
12535(define_expand "tablejumpdi"
12536  [(set (match_dup 4)
12537        (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12538   (set (match_dup 3)
12539	(plus:DI (match_dup 4)
12540		 (match_dup 2)))
12541   (parallel [(set (pc)
12542		   (match_dup 3))
12543	      (use (label_ref (match_operand 1)))])]
12544  "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12545{
12546  operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12547  operands[3] = gen_reg_rtx (DImode);
12548  operands[4] = gen_reg_rtx (DImode);
12549})
12550
12551(define_expand "tablejumpdi_nospec"
12552  [(set (match_dup 5)
12553        (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12554   (set (match_dup 4)
12555	(plus:DI (match_dup 5)
12556		 (match_dup 3)))
12557   (parallel [(set (pc)
12558		   (match_dup 4))
12559	      (use (label_ref (match_operand 1)))
12560	      (clobber (match_operand 2))])]
12561  "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12562{
12563  operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12564  operands[4] = gen_reg_rtx (DImode);
12565  operands[5] = gen_reg_rtx (DImode);
12566})
12567
12568(define_insn "*tablejump<mode>_internal1"
12569  [(set (pc)
12570	(match_operand:P 0 "register_operand" "c,*l"))
12571   (use (label_ref (match_operand 1)))]
12572  "rs6000_speculate_indirect_jumps"
12573  "b%T0"
12574  [(set_attr "type" "jmpreg")])
12575
12576(define_insn "*tablejump<mode>_internal1_nospec"
12577  [(set (pc)
12578	(match_operand:P 0 "register_operand" "c,*l"))
12579   (use (label_ref (match_operand 1)))
12580   (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12581  "!rs6000_speculate_indirect_jumps"
12582  "crset %E2\;beq%T0- %2\;b $"
12583  [(set_attr "type" "jmpreg")
12584   (set_attr "length" "12")])
12585
12586(define_insn "nop"
12587  [(unspec [(const_int 0)] UNSPEC_NOP)]
12588  ""
12589  "nop")
12590
12591(define_insn "group_ending_nop"
12592  [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12593  ""
12594{
12595  operands[0] = gen_rtx_REG (Pmode,
12596			     rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12597  return "ori %0,%0,0";
12598})
12599
12600(define_insn "rs6000_speculation_barrier"
12601  [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12602  ""
12603{
12604  operands[0] = gen_rtx_REG (Pmode, 31);
12605  return "ori %0,%0,0";
12606})
12607
12608;; Define the subtract-one-and-jump insns, starting with the template
12609;; so loop.c knows what to generate.
12610
12611(define_expand "doloop_end"
12612  [(use (match_operand 0))	; loop pseudo
12613   (use (match_operand 1))]	; label
12614  ""
12615{
12616  if (TARGET_64BIT)
12617    {
12618      if (GET_MODE (operands[0]) != DImode)
12619	FAIL;
12620      emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12621    }
12622  else
12623    {
12624      if (GET_MODE (operands[0]) != SImode)
12625	FAIL;
12626      emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12627    }
12628  DONE;
12629})
12630
12631(define_expand "ctr<mode>"
12632  [(parallel [(set (pc)
12633		   (if_then_else (ne (match_operand:P 0 "register_operand")
12634				     (const_int 1))
12635				 (label_ref (match_operand 1))
12636				 (pc)))
12637	      (set (match_dup 0)
12638		   (plus:P (match_dup 0)
12639			    (const_int -1)))
12640	      (clobber (match_scratch:CC 2))
12641	      (clobber (match_scratch:P 3))])]
12642  ""
12643  "")
12644
12645;; We need to be able to do this for any operand, including MEM, or we
12646;; will cause reload to blow up since we don't allow output reloads on
12647;; JUMP_INSNs.
12648;; For the length attribute to be calculated correctly, the
12649;; label MUST be operand 0.
12650;; rs6000_legitimate_combined_insn prevents combine creating any of
12651;; the ctr<mode> insns.
12652
12653(define_code_iterator eqne [eq ne])
12654(define_code_attr bd [(eq "bdz") (ne "bdnz")])
12655(define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12656
12657(define_insn "<bd>_<mode>"
12658  [(set (pc)
12659	(if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12660			  (const_int 1))
12661		      (label_ref (match_operand 0))
12662		      (pc)))
12663   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12664	(plus:P (match_dup 1)
12665		(const_int -1)))
12666   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12667   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12668  ""
12669{
12670  if (which_alternative != 0)
12671    return "#";
12672  else if (get_attr_length (insn) == 4)
12673    return "<bd> %l0";
12674  else
12675    return "<bd_neg> $+8\;b %l0";
12676}
12677  [(set_attr "type" "branch")
12678   (set_attr "length" "*,16,20,20")])
12679
12680;; Now the splitter if we could not allocate the CTR register
12681(define_split
12682  [(set (pc)
12683	(if_then_else (match_operator 2 "comparison_operator"
12684				      [(match_operand:P 1 "gpc_reg_operand")
12685				       (const_int 1)])
12686		      (match_operand 5)
12687		      (match_operand 6)))
12688   (set (match_operand:P 0 "nonimmediate_operand")
12689	(plus:P (match_dup 1)
12690		(const_int -1)))
12691   (clobber (match_scratch:CC 3))
12692   (clobber (match_scratch:P 4))]
12693  "reload_completed"
12694  [(set (pc)
12695	(if_then_else (match_dup 7)
12696		      (match_dup 5)
12697		      (match_dup 6)))]
12698{
12699  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12700				const0_rtx);
12701  emit_insn (gen_rtx_SET (operands[3],
12702			  gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12703  if (int_reg_operand (operands[0], <MODE>mode))
12704    emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12705  else
12706    {
12707      emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12708      emit_move_insn (operands[0], operands[4]);
12709    }
12710    /* No DONE so branch comes from the pattern.  */
12711})
12712
12713;; patterns for bdnzt/bdnzf/bdzt/bdzf
12714;; Note that in the case of long branches we have to decompose this into
12715;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12716;; and the CR bit, which means there is no way to conveniently invert the
12717;; comparison as is done with plain bdnz/bdz.
12718
12719(define_insn "<bd>tf_<mode>"
12720  [(set (pc)
12721	(if_then_else
12722	  (and
12723	     (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12724		   (const_int 1))
12725	     (match_operator 3 "branch_comparison_operator"
12726		      [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12727		       (const_int 0)]))
12728	  (label_ref (match_operand 0))
12729	  (pc)))
12730   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12731	(plus:P (match_dup 1)
12732		(const_int -1)))
12733   (clobber (match_scratch:P 5 "=X,X,&r,r"))
12734   (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12735   (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12736  ""
12737{
12738  if (which_alternative != 0)
12739    return "#";
12740  else if (get_attr_length (insn) == 4)
12741    {
12742      if (branch_positive_comparison_operator (operands[3],
12743					       GET_MODE (operands[3])))
12744	return "<bd>t %j3,%l0";
12745      else
12746	return "<bd>f %j3,%l0";
12747    }
12748  else
12749    {
12750      static char seq[96];
12751      char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12752      sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12753      return seq;
12754    }
12755}
12756  [(set_attr "type" "branch")
12757   (set_attr "length" "*,16,20,20")])
12758
12759;; Now the splitter if we could not allocate the CTR register
12760(define_split
12761  [(set (pc)
12762	(if_then_else
12763	  (and
12764	     (match_operator 1 "comparison_operator"
12765			     [(match_operand:P 0 "gpc_reg_operand")
12766			      (const_int 1)])
12767	     (match_operator 3 "branch_comparison_operator"
12768		      [(match_operand 2 "cc_reg_operand")
12769		       (const_int 0)]))
12770	  (match_operand 4)
12771	  (match_operand 5)))
12772   (set (match_operand:P 6 "nonimmediate_operand")
12773	(plus:P (match_dup 0)
12774		(const_int -1)))
12775   (clobber (match_scratch:P 7))
12776   (clobber (match_scratch:CC 8))
12777   (clobber (match_scratch:CCEQ 9))]
12778  "reload_completed"
12779[(pc)]
12780{
12781  rtx ctr = operands[0];
12782  rtx ctrcmp = operands[1];
12783  rtx ccin = operands[2];
12784  rtx cccmp = operands[3];
12785  rtx dst1 = operands[4];
12786  rtx dst2 = operands[5];
12787  rtx ctrout = operands[6];
12788  rtx ctrtmp = operands[7];
12789  enum rtx_code cmpcode = GET_CODE (ctrcmp);
12790  bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12791  if (!ispos)
12792    cmpcode = reverse_condition (cmpcode);
12793  /* Generate crand/crandc here.  */
12794  emit_insn (gen_rtx_SET (operands[8],
12795			  gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12796  rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12797
12798  rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12799  if (ispos)
12800     emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12801				      operands[8], cccmp, ccin));
12802  else
12803     emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12804						 operands[8], cccmp, ccin));
12805  if (int_reg_operand (ctrout, <MODE>mode))
12806     emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12807  else
12808    {
12809      emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12810      emit_move_insn (ctrout, ctrtmp);
12811    }
12812  rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12813  emit_jump_insn (gen_rtx_SET (pc_rtx,
12814			       gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12815						     dst1, dst2)));
12816  DONE;
12817})
12818
12819
12820(define_insn "trap"
12821  [(trap_if (const_int 1) (const_int 0))]
12822  ""
12823  "trap"
12824  [(set_attr "type" "trap")])
12825
12826(define_expand "ctrap<mode>4"
12827  [(trap_if (match_operator 0 "ordered_comparison_operator"
12828			    [(match_operand:GPR 1 "register_operand")
12829			     (match_operand:GPR 2 "reg_or_short_operand")])
12830	    (match_operand 3 "zero_constant" ""))]
12831  ""
12832  "")
12833
12834(define_insn ""
12835  [(trap_if (match_operator 0 "ordered_comparison_operator"
12836                            [(match_operand:GPR 1 "register_operand" "r")
12837                             (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12838	    (const_int 0))]
12839  ""
12840  "t<wd>%V0%I2 %1,%2"
12841  [(set_attr "type" "trap")])
12842
12843;; Insns related to generating the function prologue and epilogue.
12844
12845(define_expand "prologue"
12846  [(use (const_int 0))]
12847  ""
12848{
12849  rs6000_emit_prologue ();
12850  if (!TARGET_SCHED_PROLOG)
12851    emit_insn (gen_blockage ());
12852  DONE;
12853})
12854
12855(define_insn "*movesi_from_cr_one"
12856  [(match_parallel 0 "mfcr_operation"
12857		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12858			 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12859				     (match_operand 3 "immediate_operand" "n")]
12860			  UNSPEC_MOVESI_FROM_CR))])]
12861  "TARGET_MFCRF"
12862{
12863  int mask = 0;
12864  int i;
12865  for (i = 0; i < XVECLEN (operands[0], 0); i++)
12866  {
12867    mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12868    operands[4] = GEN_INT (mask);
12869    output_asm_insn ("mfcr %1,%4", operands);
12870  }
12871  return "";
12872}
12873  [(set_attr "type" "mfcrf")])
12874
12875;; Don't include the volatile CRs since their values are not used wrt CR save
12876;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12877;; prologue past an insn (early exit test) that defines a register used in the
12878;; prologue.
12879(define_insn "prologue_movesi_from_cr"
12880  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12881        (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12882		    (reg:CC CR4_REGNO)]
12883		   UNSPEC_MOVESI_FROM_CR))]
12884  ""
12885  "mfcr %0"
12886  [(set_attr "type" "mfcr")])
12887
12888(define_insn "*crsave"
12889  [(match_parallel 0 "crsave_operation"
12890		   [(set (match_operand:SI 1 "memory_operand" "=m")
12891			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12892  ""
12893  "stw %2,%1"
12894  [(set_attr "type" "store")])
12895
12896(define_insn "*stmw"
12897  [(match_parallel 0 "stmw_operation"
12898		   [(set (match_operand:SI 1 "memory_operand" "=m")
12899       			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12900  "TARGET_MULTIPLE"
12901  "stmw %2,%1"
12902  [(set_attr "type" "store")
12903   (set_attr "update" "yes")
12904   (set_attr "indexed" "yes")])
12905
12906; The following comment applies to:
12907;     save_gpregs_*
12908;     save_fpregs_*
12909;     restore_gpregs*
12910;     return_and_restore_gpregs*
12911;     return_and_restore_fpregs*
12912;     return_and_restore_fpregs_aix*
12913;
12914; The out-of-line save / restore functions expects one input argument.
12915; Since those are not standard call_insn's, we must avoid using
12916; MATCH_OPERAND for that argument. That way the register rename
12917; optimization will not try to rename this register.
12918; Each pattern is repeated for each possible register number used in
12919; various ABIs (r11, r1, and for some functions r12)
12920
12921(define_insn "*save_gpregs_<mode>_r11"
12922  [(match_parallel 0 "any_parallel_operand"
12923		   [(clobber (reg:P LR_REGNO))
12924		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12925                    (use (reg:P 11))
12926		    (set (match_operand:P 2 "memory_operand" "=m")
12927			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12928  ""
12929  "bl %1"
12930  [(set_attr "type" "branch")
12931   (set_attr "length" "4")])
12932
12933(define_insn "*save_gpregs_<mode>_r12"
12934  [(match_parallel 0 "any_parallel_operand"
12935		   [(clobber (reg:P LR_REGNO))
12936		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12937                    (use (reg:P 12))
12938		    (set (match_operand:P 2 "memory_operand" "=m")
12939			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12940  ""
12941  "bl %1"
12942  [(set_attr "type" "branch")
12943   (set_attr "length" "4")])
12944
12945(define_insn "*save_gpregs_<mode>_r1"
12946  [(match_parallel 0 "any_parallel_operand"
12947		   [(clobber (reg:P LR_REGNO))
12948		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12949                    (use (reg:P 1))
12950		    (set (match_operand:P 2 "memory_operand" "=m")
12951			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12952  ""
12953  "bl %1"
12954  [(set_attr "type" "branch")
12955   (set_attr "length" "4")])
12956
12957(define_insn "*save_fpregs_<mode>_r11"
12958  [(match_parallel 0 "any_parallel_operand"
12959		   [(clobber (reg:P LR_REGNO))
12960		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12961                    (use (reg:P 11))
12962		    (set (match_operand:DF 2 "memory_operand" "=m")
12963			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12964  ""
12965  "bl %1"
12966  [(set_attr "type" "branch")
12967   (set_attr "length" "4")])
12968
12969(define_insn "*save_fpregs_<mode>_r12"
12970  [(match_parallel 0 "any_parallel_operand"
12971		   [(clobber (reg:P LR_REGNO))
12972		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12973                    (use (reg:P 12))
12974		    (set (match_operand:DF 2 "memory_operand" "=m")
12975			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12976  ""
12977  "bl %1"
12978  [(set_attr "type" "branch")
12979   (set_attr "length" "4")])
12980
12981(define_insn "*save_fpregs_<mode>_r1"
12982  [(match_parallel 0 "any_parallel_operand"
12983		   [(clobber (reg:P LR_REGNO))
12984		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12985                    (use (reg:P 1))
12986		    (set (match_operand:DF 2 "memory_operand" "=m")
12987			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12988  ""
12989  "bl %1"
12990  [(set_attr "type" "branch")
12991   (set_attr "length" "4")])
12992
12993; This is to explain that changes to the stack pointer should
12994; not be moved over loads from or stores to stack memory.
12995(define_insn "stack_tie"
12996  [(match_parallel 0 "tie_operand"
12997		   [(set (mem:BLK (reg 1)) (const_int 0))])]
12998  ""
12999  ""
13000  [(set_attr "length" "0")])
13001
13002; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13003; stay behind all restores from the stack, it cannot be reordered to before
13004; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13005(define_insn "stack_restore_tie"
13006  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13007	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13008		 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13009   (set (mem:BLK (scratch)) (const_int 0))]
13010  "TARGET_32BIT"
13011  "@
13012   mr %0,%1
13013   add%I2 %0,%1,%2"
13014  [(set_attr "type" "*,add")])
13015
13016(define_expand "epilogue"
13017  [(use (const_int 0))]
13018  ""
13019{
13020  if (!TARGET_SCHED_PROLOG)
13021    emit_insn (gen_blockage ());
13022  rs6000_emit_epilogue (FALSE);
13023  DONE;
13024})
13025
13026; On some processors, doing the mtcrf one CC register at a time is
13027; faster (like on the 604e).  On others, doing them all at once is
13028; faster; for instance, on the 601 and 750.
13029
13030(define_expand "movsi_to_cr_one"
13031  [(set (match_operand:CC 0 "cc_reg_operand")
13032        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13033		    (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13034  ""
13035  "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13036
13037(define_insn "*movsi_to_cr"
13038  [(match_parallel 0 "mtcrf_operation"
13039		   [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13040			 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13041				     (match_operand 3 "immediate_operand" "n")]
13042				    UNSPEC_MOVESI_TO_CR))])]
13043 ""
13044{
13045  int mask = 0;
13046  int i;
13047  for (i = 0; i < XVECLEN (operands[0], 0); i++)
13048    mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13049  operands[4] = GEN_INT (mask);
13050  return "mtcrf %4,%2";
13051}
13052  [(set_attr "type" "mtcr")])
13053
13054(define_insn "*mtcrfsi"
13055  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13056        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13057		    (match_operand 2 "immediate_operand" "n")]
13058		   UNSPEC_MOVESI_TO_CR))]
13059  "GET_CODE (operands[0]) == REG
13060   && CR_REGNO_P (REGNO (operands[0]))
13061   && GET_CODE (operands[2]) == CONST_INT
13062   && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13063  "mtcrf %R0,%1"
13064  [(set_attr "type" "mtcr")])
13065
13066; The load-multiple instructions have similar properties.
13067; Note that "load_multiple" is a name known to the machine-independent
13068; code that actually corresponds to the PowerPC load-string.
13069
13070(define_insn "*lmw"
13071  [(match_parallel 0 "lmw_operation"
13072		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13073       			 (match_operand:SI 2 "memory_operand" "m"))])]
13074  "TARGET_MULTIPLE"
13075  "lmw %1,%2"
13076  [(set_attr "type" "load")
13077   (set_attr "update" "yes")
13078   (set_attr "indexed" "yes")
13079   (set_attr "cell_micro" "always")])
13080
13081; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13082; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13083
13084; The following comment applies to:
13085;     save_gpregs_*
13086;     save_fpregs_*
13087;     restore_gpregs*
13088;     return_and_restore_gpregs*
13089;     return_and_restore_fpregs*
13090;     return_and_restore_fpregs_aix*
13091;
13092; The out-of-line save / restore functions expects one input argument.
13093; Since those are not standard call_insn's, we must avoid using
13094; MATCH_OPERAND for that argument. That way the register rename
13095; optimization will not try to rename this register.
13096; Each pattern is repeated for each possible register number used in
13097; various ABIs (r11, r1, and for some functions r12)
13098
13099(define_insn "*restore_gpregs_<mode>_r11"
13100 [(match_parallel 0 "any_parallel_operand"
13101		  [(clobber (reg:P LR_REGNO))
13102		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13103		   (use (reg:P 11))
13104		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13105			(match_operand:P 3 "memory_operand" "m"))])]
13106 ""
13107 "bl %1"
13108 [(set_attr "type" "branch")
13109  (set_attr "length" "4")])
13110
13111(define_insn "*restore_gpregs_<mode>_r12"
13112 [(match_parallel 0 "any_parallel_operand"
13113		  [(clobber (reg:P LR_REGNO))
13114		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13115		   (use (reg:P 12))
13116		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13117			(match_operand:P 3 "memory_operand" "m"))])]
13118 ""
13119 "bl %1"
13120 [(set_attr "type" "branch")
13121  (set_attr "length" "4")])
13122
13123(define_insn "*restore_gpregs_<mode>_r1"
13124 [(match_parallel 0 "any_parallel_operand"
13125		  [(clobber (reg:P LR_REGNO))
13126		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13127		   (use (reg:P 1))
13128		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13129			(match_operand:P 3 "memory_operand" "m"))])]
13130 ""
13131 "bl %1"
13132 [(set_attr "type" "branch")
13133  (set_attr "length" "4")])
13134
13135(define_insn "*return_and_restore_gpregs_<mode>_r11"
13136 [(match_parallel 0 "any_parallel_operand"
13137		  [(return)
13138		   (clobber (reg:P LR_REGNO))
13139		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13140		   (use (reg:P 11))
13141		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13142			(match_operand:P 3 "memory_operand" "m"))])]
13143 ""
13144 "b %1"
13145 [(set_attr "type" "branch")
13146  (set_attr "length" "4")])
13147
13148(define_insn "*return_and_restore_gpregs_<mode>_r12"
13149 [(match_parallel 0 "any_parallel_operand"
13150		  [(return)
13151		   (clobber (reg:P LR_REGNO))
13152		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13153		   (use (reg:P 12))
13154		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13155			(match_operand:P 3 "memory_operand" "m"))])]
13156 ""
13157 "b %1"
13158 [(set_attr "type" "branch")
13159  (set_attr "length" "4")])
13160
13161(define_insn "*return_and_restore_gpregs_<mode>_r1"
13162 [(match_parallel 0 "any_parallel_operand"
13163		  [(return)
13164		   (clobber (reg:P LR_REGNO))
13165		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13166		   (use (reg:P 1))
13167		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13168			(match_operand:P 3 "memory_operand" "m"))])]
13169 ""
13170 "b %1"
13171 [(set_attr "type" "branch")
13172  (set_attr "length" "4")])
13173
13174(define_insn "*return_and_restore_fpregs_<mode>_r11"
13175 [(match_parallel 0 "any_parallel_operand"
13176		  [(return)
13177		   (clobber (reg:P LR_REGNO))
13178		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13179		   (use (reg:P 11))
13180		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13181			(match_operand:DF 3 "memory_operand" "m"))])]
13182 ""
13183 "b %1"
13184 [(set_attr "type" "branch")
13185  (set_attr "length" "4")])
13186
13187(define_insn "*return_and_restore_fpregs_<mode>_r12"
13188 [(match_parallel 0 "any_parallel_operand"
13189		  [(return)
13190		   (clobber (reg:P LR_REGNO))
13191		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13192		   (use (reg:P 12))
13193		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13194			(match_operand:DF 3 "memory_operand" "m"))])]
13195 ""
13196 "b %1"
13197 [(set_attr "type" "branch")
13198  (set_attr "length" "4")])
13199
13200(define_insn "*return_and_restore_fpregs_<mode>_r1"
13201 [(match_parallel 0 "any_parallel_operand"
13202		  [(return)
13203		   (clobber (reg:P LR_REGNO))
13204		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13205		   (use (reg:P 1))
13206		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13207			(match_operand:DF 3 "memory_operand" "m"))])]
13208 ""
13209 "b %1"
13210 [(set_attr "type" "branch")
13211  (set_attr "length" "4")])
13212
13213(define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13214 [(match_parallel 0 "any_parallel_operand"
13215		  [(return)
13216		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13217		   (use (reg:P 11))
13218		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13219			(match_operand:DF 3 "memory_operand" "m"))])]
13220 ""
13221 "b %1"
13222 [(set_attr "type" "branch")
13223  (set_attr "length" "4")])
13224
13225(define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13226 [(match_parallel 0 "any_parallel_operand"
13227		  [(return)
13228		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13229		   (use (reg:P 1))
13230		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13231			(match_operand:DF 3 "memory_operand" "m"))])]
13232 ""
13233 "b %1"
13234 [(set_attr "type" "branch")
13235  (set_attr "length" "4")])
13236
13237; This is used in compiling the unwind routines.
13238(define_expand "eh_return"
13239  [(use (match_operand 0 "general_operand"))]
13240  ""
13241{
13242  if (TARGET_32BIT)
13243    emit_insn (gen_eh_set_lr_si (operands[0]));
13244  else
13245    emit_insn (gen_eh_set_lr_di (operands[0]));
13246  DONE;
13247})
13248
13249; We can't expand this before we know where the link register is stored.
13250(define_insn "eh_set_lr_<mode>"
13251  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13252  		    UNSPECV_EH_RR)
13253   (clobber (match_scratch:P 1 "=&b"))]
13254  ""
13255  "#")
13256
13257(define_split
13258  [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13259   (clobber (match_scratch 1))]
13260  "reload_completed"
13261  [(const_int 0)]
13262{
13263  rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13264  DONE;
13265})
13266
13267(define_insn "prefetch"
13268  [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13269	     (match_operand:SI 1 "const_int_operand" "n")
13270	     (match_operand:SI 2 "const_int_operand" "n"))]
13271  ""
13272{
13273  if (GET_CODE (operands[0]) == REG)
13274    return INTVAL (operands[1]) ? "dcbtst 0,%0" : "dcbt 0,%0";
13275  return INTVAL (operands[1]) ? "dcbtst %a0" : "dcbt %a0";
13276}
13277  [(set_attr "type" "load")])
13278
13279;; Handle -fsplit-stack.
13280
13281(define_expand "split_stack_prologue"
13282  [(const_int 0)]
13283  ""
13284{
13285  rs6000_expand_split_stack_prologue ();
13286  DONE;
13287})
13288
13289(define_expand "load_split_stack_limit"
13290  [(set (match_operand 0)
13291	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13292  ""
13293{
13294  emit_insn (gen_rtx_SET (operands[0],
13295			  gen_rtx_UNSPEC (Pmode,
13296					  gen_rtvec (1, const0_rtx),
13297					  UNSPEC_STACK_CHECK)));
13298  DONE;
13299})
13300
13301(define_insn "load_split_stack_limit_di"
13302  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13303	(unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13304  "TARGET_64BIT"
13305  "ld %0,-0x7040(13)"
13306  [(set_attr "type" "load")
13307   (set_attr "update" "no")
13308   (set_attr "indexed" "no")])
13309
13310(define_insn "load_split_stack_limit_si"
13311  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13312	(unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13313  "!TARGET_64BIT"
13314  "lwz %0,-0x7020(2)"
13315  [(set_attr "type" "load")
13316   (set_attr "update" "no")
13317   (set_attr "indexed" "no")])
13318
13319;; A return instruction which the middle-end doesn't see.
13320;; Use r0 to stop regrename twiddling with lr restore insns emitted
13321;; after the call to __morestack.
13322(define_insn "split_stack_return"
13323  [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13324  ""
13325  "blr"
13326  [(set_attr "type" "jmpreg")])
13327
13328;; If there are operand 0 bytes available on the stack, jump to
13329;; operand 1.
13330(define_expand "split_stack_space_check"
13331  [(set (match_dup 2)
13332	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13333   (set (match_dup 3)
13334	(minus (reg STACK_POINTER_REGNUM)
13335	       (match_operand 0)))
13336   (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13337   (set (pc) (if_then_else
13338	      (geu (match_dup 4) (const_int 0))
13339	      (label_ref (match_operand 1))
13340	      (pc)))]
13341  ""
13342{
13343  rs6000_split_stack_space_check (operands[0], operands[1]);
13344  DONE;
13345})
13346
13347(define_insn "bpermd_<mode>"
13348  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13349	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13350		   (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13351  "TARGET_POPCNTD"
13352  "bpermd %0,%1,%2"
13353  [(set_attr "type" "popcnt")])
13354
13355
13356;; Builtin fma support.  Handle
13357;; Note that the conditions for expansion are in the FMA_F iterator.
13358
13359(define_expand "fma<mode>4"
13360  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13361	(fma:FMA_F
13362	  (match_operand:FMA_F 1 "gpc_reg_operand")
13363	  (match_operand:FMA_F 2 "gpc_reg_operand")
13364	  (match_operand:FMA_F 3 "gpc_reg_operand")))]
13365  ""
13366  "")
13367
13368(define_insn "*fma<mode>4_fpr"
13369  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13370	(fma:SFDF
13371	  (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13372	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13373	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13374  "TARGET_<MODE>_FPR"
13375  "@
13376   fmadd<Ftrad> %0,%1,%2,%3
13377   xsmadda<Fvsx> %x0,%x1,%x2
13378   xsmaddm<Fvsx> %x0,%x1,%x3"
13379  [(set_attr "type" "fp")
13380   (set_attr "fp_type" "fp_maddsub_<Fs>")])
13381
13382; Altivec only has fma and nfms.
13383(define_expand "fms<mode>4"
13384  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13385	(fma:FMA_F
13386	  (match_operand:FMA_F 1 "gpc_reg_operand")
13387	  (match_operand:FMA_F 2 "gpc_reg_operand")
13388	  (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13389  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13390  "")
13391
13392(define_insn "*fms<mode>4_fpr"
13393  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13394	(fma:SFDF
13395	 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13396	 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13397	 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13398  "TARGET_<MODE>_FPR"
13399  "@
13400   fmsub<Ftrad> %0,%1,%2,%3
13401   xsmsuba<Fvsx> %x0,%x1,%x2
13402   xsmsubm<Fvsx> %x0,%x1,%x3"
13403  [(set_attr "type" "fp")
13404   (set_attr "fp_type" "fp_maddsub_<Fs>")])
13405
13406;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13407(define_expand "fnma<mode>4"
13408  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13409	(neg:FMA_F
13410	  (fma:FMA_F
13411	    (match_operand:FMA_F 1 "gpc_reg_operand")
13412	    (match_operand:FMA_F 2 "gpc_reg_operand")
13413	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13414  "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13415  "")
13416
13417;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13418(define_expand "fnms<mode>4"
13419  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13420	(neg:FMA_F
13421	  (fma:FMA_F
13422	    (match_operand:FMA_F 1 "gpc_reg_operand")
13423	    (match_operand:FMA_F 2 "gpc_reg_operand")
13424	    (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13425  "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13426  "")
13427
13428; Not an official optab name, but used from builtins.
13429(define_expand "nfma<mode>4"
13430  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13431	(neg:FMA_F
13432	  (fma:FMA_F
13433	    (match_operand:FMA_F 1 "gpc_reg_operand")
13434	    (match_operand:FMA_F 2 "gpc_reg_operand")
13435	    (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13436  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13437  "")
13438
13439(define_insn "*nfma<mode>4_fpr"
13440  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13441	(neg:SFDF
13442	 (fma:SFDF
13443	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13444	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13445	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13446  "TARGET_<MODE>_FPR"
13447  "@
13448   fnmadd<Ftrad> %0,%1,%2,%3
13449   xsnmadda<Fvsx> %x0,%x1,%x2
13450   xsnmaddm<Fvsx> %x0,%x1,%x3"
13451  [(set_attr "type" "fp")
13452   (set_attr "fp_type" "fp_maddsub_<Fs>")])
13453
13454; Not an official optab name, but used from builtins.
13455(define_expand "nfms<mode>4"
13456  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13457	(neg:FMA_F
13458	  (fma:FMA_F
13459	    (match_operand:FMA_F 1 "gpc_reg_operand")
13460	    (match_operand:FMA_F 2 "gpc_reg_operand")
13461	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13462  ""
13463  "")
13464
13465(define_insn "*nfmssf4_fpr"
13466  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13467	(neg:SFDF
13468	 (fma:SFDF
13469	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13470	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13471	  (neg:SFDF
13472	   (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13473  "TARGET_<MODE>_FPR"
13474  "@
13475   fnmsub<Ftrad> %0,%1,%2,%3
13476   xsnmsuba<Fvsx> %x0,%x1,%x2
13477   xsnmsubm<Fvsx> %x0,%x1,%x3"
13478  [(set_attr "type" "fp")
13479   (set_attr "fp_type" "fp_maddsub_<Fs>")])
13480
13481
13482(define_expand "rs6000_get_timebase"
13483  [(use (match_operand:DI 0 "gpc_reg_operand"))]
13484  ""
13485{
13486  if (TARGET_POWERPC64)
13487    emit_insn (gen_rs6000_mftb_di (operands[0]));
13488  else
13489    emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13490  DONE;
13491})
13492
13493(define_insn "rs6000_get_timebase_ppc32"
13494  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13495        (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13496   (clobber (match_scratch:SI 1 "=r"))
13497   (clobber (match_scratch:CC 2 "=y"))]
13498  "!TARGET_POWERPC64"
13499{
13500  if (WORDS_BIG_ENDIAN)
13501    if (TARGET_MFCRF)
13502      {
13503        return "mfspr %0,269\;"
13504	       "mfspr %L0,268\;"
13505	       "mfspr %1,269\;"
13506	       "cmpw %2,%0,%1\;"
13507	       "bne- %2,$-16";
13508      }
13509    else
13510      {
13511        return "mftbu %0\;"
13512	       "mftb %L0\;"
13513	       "mftbu %1\;"
13514	       "cmpw %2,%0,%1\;"
13515	       "bne- %2,$-16";
13516      }
13517  else
13518    if (TARGET_MFCRF)
13519      {
13520        return "mfspr %L0,269\;"
13521	       "mfspr %0,268\;"
13522	       "mfspr %1,269\;"
13523	       "cmpw %2,%L0,%1\;"
13524	       "bne- %2,$-16";
13525      }
13526    else
13527      {
13528        return "mftbu %L0\;"
13529	       "mftb %0\;"
13530	       "mftbu %1\;"
13531	       "cmpw %2,%L0,%1\;"
13532	       "bne- %2,$-16";
13533      }
13534}
13535  [(set_attr "length" "20")])
13536
13537(define_insn "rs6000_mftb_<mode>"
13538  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13539        (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13540  ""
13541{
13542  if (TARGET_MFCRF)
13543    return "mfspr %0,268";
13544  else
13545    return "mftb %0";
13546})
13547
13548
13549(define_insn "rs6000_mffs"
13550  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13551	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13552  "TARGET_HARD_FLOAT"
13553  "mffs %0")
13554
13555(define_insn "rs6000_mtfsf"
13556  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13557		     (match_operand:DF 1 "gpc_reg_operand" "d")]
13558		    UNSPECV_MTFSF)]
13559  "TARGET_HARD_FLOAT"
13560  "mtfsf %0,%1")
13561
13562
13563;; Power8 fusion support for fusing an addis instruction with a D-form load of
13564;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13565;; register that is being loaded.  The fused ops must be physically adjacent.
13566
13567;; There are two parts to addis fusion.  The support for fused TOCs occur
13568;; before register allocation, and is meant to reduce the lifetime for the
13569;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13570;; to use the register that is being load.  The peephole2 then gathers any
13571;; other fused possibilities that it can find after register allocation.  If
13572;; power9 fusion is selected, we also fuse floating point loads/stores.
13573
13574;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13575;; before register allocation, so that we can avoid allocating a temporary base
13576;; register that won't be used, and that we try to load into base registers,
13577;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13578;; (addis followed by load) even on power8.
13579
13580(define_split
13581  [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13582	(match_operand:INT1 1 "toc_fusion_mem_raw"))]
13583  "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13584  [(parallel [(set (match_dup 0) (match_dup 2))
13585	      (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13586	      (use (match_dup 3))
13587	      (clobber (scratch:DI))])]
13588{
13589  operands[2] = fusion_wrap_memory_address (operands[1]);
13590  operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13591})
13592
13593(define_insn "*toc_fusionload_<mode>"
13594  [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13595	(match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13596   (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13597   (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13598   (clobber (match_scratch:DI 3 "=X,&b"))]
13599  "TARGET_TOC_FUSION_INT"
13600{
13601  if (base_reg_operand (operands[0], <MODE>mode))
13602    return emit_fusion_gpr_load (operands[0], operands[1]);
13603
13604  return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13605}
13606  [(set_attr "type" "load")
13607   (set_attr "length" "8")])
13608
13609(define_insn "*toc_fusionload_di"
13610  [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13611	(match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13612   (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13613   (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13614   (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13615  "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13616   && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13617{
13618  if (base_reg_operand (operands[0], DImode))
13619    return emit_fusion_gpr_load (operands[0], operands[1]);
13620
13621  return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13622}
13623  [(set_attr "type" "load")
13624   (set_attr "length" "8")])
13625
13626
13627;; Find cases where the addis that feeds into a load instruction is either used
13628;; once or is the same as the target register, and replace it with the fusion
13629;; insn
13630
13631(define_peephole2
13632  [(set (match_operand:P 0 "base_reg_operand")
13633	(match_operand:P 1 "fusion_gpr_addis"))
13634   (set (match_operand:INT1 2 "base_reg_operand")
13635	(match_operand:INT1 3 "fusion_gpr_mem_load"))]
13636  "TARGET_P8_FUSION
13637   && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13638			 operands[3])"
13639  [(const_int 0)]
13640{
13641  expand_fusion_gpr_load (operands);
13642  DONE;
13643})
13644
13645;; Fusion insn, created by the define_peephole2 above (and eventually by
13646;; reload)
13647
13648(define_insn "fusion_gpr_load_<mode>"
13649  [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13650	(unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13651		     UNSPEC_FUSION_GPR))]
13652  "TARGET_P8_FUSION"
13653{
13654  return emit_fusion_gpr_load (operands[0], operands[1]);
13655}
13656  [(set_attr "type" "load")
13657   (set_attr "length" "8")])
13658
13659
13660;; ISA 3.0 (power9) fusion support
13661;; Merge addis with floating load/store to FPRs (or GPRs).
13662(define_peephole2
13663  [(set (match_operand:P 0 "base_reg_operand")
13664	(match_operand:P 1 "fusion_gpr_addis"))
13665   (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13666	(match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13667  "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13668   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13669  [(const_int 0)]
13670{
13671  expand_fusion_p9_load (operands);
13672  DONE;
13673})
13674
13675(define_peephole2
13676  [(set (match_operand:P 0 "base_reg_operand")
13677	(match_operand:P 1 "fusion_gpr_addis"))
13678   (set (match_operand:SFDF 2 "offsettable_mem_operand")
13679	(match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13680  "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13681   && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13682   && !rtx_equal_p (operands[0], operands[3])"
13683  [(const_int 0)]
13684{
13685  expand_fusion_p9_store (operands);
13686  DONE;
13687})
13688
13689(define_peephole2
13690  [(set (match_operand:SDI 0 "int_reg_operand")
13691	(match_operand:SDI 1 "upper16_cint_operand"))
13692   (set (match_dup 0)
13693	(ior:SDI (match_dup 0)
13694		 (match_operand:SDI 2 "u_short_cint_operand")))]
13695  "TARGET_P9_FUSION"
13696  [(set (match_dup 0)
13697	(unspec:SDI [(match_dup 1)
13698		     (match_dup 2)] UNSPEC_FUSION_P9))])
13699
13700(define_peephole2
13701  [(set (match_operand:SDI 0 "int_reg_operand")
13702	(match_operand:SDI 1 "upper16_cint_operand"))
13703   (set (match_operand:SDI 2 "int_reg_operand")
13704	(ior:SDI (match_dup 0)
13705		 (match_operand:SDI 3 "u_short_cint_operand")))]
13706  "TARGET_P9_FUSION
13707   && !rtx_equal_p (operands[0], operands[2])
13708   && peep2_reg_dead_p (2, operands[0])"
13709  [(set (match_dup 2)
13710	(unspec:SDI [(match_dup 1)
13711		     (match_dup 3)] UNSPEC_FUSION_P9))])
13712
13713;; Fusion insns, created by the define_peephole2 above (and eventually by
13714;; reload).  Because we want to eventually have secondary_reload generate
13715;; these, they have to have a single alternative that gives the register
13716;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13717(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13718  [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13719	(unspec:GPR_FUSION
13720	 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13721	 UNSPEC_FUSION_P9))
13722   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13723  "TARGET_P9_FUSION"
13724{
13725  /* This insn is a secondary reload insn, which cannot have alternatives.
13726     If we are not loading up register 0, use the power8 fusion instead.  */
13727  if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13728    return emit_fusion_gpr_load (operands[0], operands[1]);
13729
13730  return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13731}
13732  [(set_attr "type" "load")
13733   (set_attr "length" "8")])
13734
13735(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13736  [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13737	(unspec:GPR_FUSION
13738	 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13739	 UNSPEC_FUSION_P9))
13740   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13741  "TARGET_P9_FUSION"
13742{
13743  return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13744}
13745  [(set_attr "type" "store")
13746   (set_attr "length" "8")])
13747
13748(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13749  [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13750	(unspec:FPR_FUSION
13751	 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13752	 UNSPEC_FUSION_P9))
13753   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13754  "TARGET_P9_FUSION"
13755{
13756  return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13757}
13758  [(set_attr "type" "fpload")
13759   (set_attr "length" "8")])
13760
13761(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13762  [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13763	(unspec:FPR_FUSION
13764	 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13765	 UNSPEC_FUSION_P9))
13766   (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13767  "TARGET_P9_FUSION"
13768{
13769  return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13770}
13771  [(set_attr "type" "fpstore")
13772   (set_attr "length" "8")])
13773
13774(define_insn "*fusion_p9_<mode>_constant"
13775  [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13776	(unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13777		     (match_operand:SDI 2 "u_short_cint_operand" "K")]
13778		    UNSPEC_FUSION_P9))]
13779  "TARGET_P9_FUSION"
13780{
13781  emit_fusion_addis (operands[0], operands[1]);
13782  return "ori %0,%0,%2";
13783}
13784  [(set_attr "type" "two")
13785   (set_attr "length" "8")])
13786
13787
13788;; Optimize cases where we want to do a D-form load (register+offset) on
13789;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13790;; has generated:
13791;;	LFD 0,32(3)
13792;;	XXLOR 32,0,0
13793;;
13794;; and we change this to:
13795;;	LI 0,32
13796;;	LXSDX 32,3,9
13797
13798(define_peephole2
13799  [(match_scratch:P 0 "b")
13800   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13801	(match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13802   (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13803	(match_dup 1))]
13804  "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13805  [(set (match_dup 0)
13806	(match_dup 4))
13807   (set (match_dup 3)
13808	(match_dup 5))]
13809{
13810  rtx tmp_reg = operands[0];
13811  rtx mem = operands[2];
13812  rtx addr = XEXP (mem, 0);
13813  rtx add_op0, add_op1, new_addr;
13814
13815  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13816  add_op0 = XEXP (addr, 0);
13817  add_op1 = XEXP (addr, 1);
13818  gcc_assert (REG_P (add_op0));
13819  new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13820
13821  operands[4] = add_op1;
13822  operands[5] = change_address (mem, <MODE>mode, new_addr);
13823})
13824
13825;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13826;; Altivec register, and the register allocator has generated:
13827;;	XXLOR 0,32,32
13828;;	STFD 0,32(3)
13829;;
13830;; and we change this to:
13831;;	LI 0,32
13832;;	STXSDX 32,3,9
13833
13834(define_peephole2
13835  [(match_scratch:P 0 "b")
13836   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13837	(match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13838   (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13839	(match_dup 1))]
13840  "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13841  [(set (match_dup 0)
13842	(match_dup 4))
13843   (set (match_dup 5)
13844	(match_dup 2))]
13845{
13846  rtx tmp_reg = operands[0];
13847  rtx mem = operands[3];
13848  rtx addr = XEXP (mem, 0);
13849  rtx add_op0, add_op1, new_addr;
13850
13851  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13852  add_op0 = XEXP (addr, 0);
13853  add_op1 = XEXP (addr, 1);
13854  gcc_assert (REG_P (add_op0));
13855  new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13856
13857  operands[4] = add_op1;
13858  operands[5] = change_address (mem, <MODE>mode, new_addr);
13859})
13860
13861
13862;; Miscellaneous ISA 2.06 (power7) instructions
13863(define_insn "addg6s"
13864  [(set (match_operand:SI 0 "register_operand" "=r")
13865	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
13866		    (match_operand:SI 2 "register_operand" "r")]
13867		   UNSPEC_ADDG6S))]
13868  "TARGET_POPCNTD"
13869  "addg6s %0,%1,%2"
13870  [(set_attr "type" "integer")
13871   (set_attr "length" "4")])
13872
13873(define_insn "cdtbcd"
13874  [(set (match_operand:SI 0 "register_operand" "=r")
13875	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13876		   UNSPEC_CDTBCD))]
13877  "TARGET_POPCNTD"
13878  "cdtbcd %0,%1"
13879  [(set_attr "type" "integer")
13880   (set_attr "length" "4")])
13881
13882(define_insn "cbcdtd"
13883  [(set (match_operand:SI 0 "register_operand" "=r")
13884	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13885		   UNSPEC_CBCDTD))]
13886  "TARGET_POPCNTD"
13887  "cbcdtd %0,%1"
13888  [(set_attr "type" "integer")
13889   (set_attr "length" "4")])
13890
13891(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13892					UNSPEC_DIVEU])
13893
13894(define_int_attr div_extend [(UNSPEC_DIVE	"e")
13895			     (UNSPEC_DIVEU	"eu")])
13896
13897(define_insn "div<div_extend>_<mode>"
13898  [(set (match_operand:GPR 0 "register_operand" "=r")
13899	(unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13900		     (match_operand:GPR 2 "register_operand" "r")]
13901		    UNSPEC_DIV_EXTEND))]
13902  "TARGET_POPCNTD"
13903  "div<wd><div_extend> %0,%1,%2"
13904  [(set_attr "type" "div")
13905   (set_attr "size" "<bits>")])
13906
13907
13908;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13909
13910; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13911(define_mode_attr FP128_64 [(TF "DF")
13912			    (IF "DF")
13913			    (TD "DI")
13914			    (KF "DI")])
13915
13916(define_expand "unpack<mode>"
13917  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13918	(unspec:<FP128_64>
13919	 [(match_operand:FMOVE128 1 "register_operand")
13920	  (match_operand:QI 2 "const_0_to_1_operand")]
13921	 UNSPEC_UNPACK_128BIT))]
13922  "FLOAT128_2REG_P (<MODE>mode)"
13923  "")
13924
13925(define_insn_and_split "unpack<mode>_dm"
13926  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13927	(unspec:<FP128_64>
13928	 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13929	  (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13930	 UNSPEC_UNPACK_128BIT))]
13931  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13932  "#"
13933  "&& reload_completed"
13934  [(set (match_dup 0) (match_dup 3))]
13935{
13936  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13937
13938  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13939    {
13940      emit_note (NOTE_INSN_DELETED);
13941      DONE;
13942    }
13943
13944  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13945}
13946  [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13947   (set_attr "length" "4")])
13948
13949(define_insn_and_split "unpack<mode>_nodm"
13950  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13951	(unspec:<FP128_64>
13952	 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13953	  (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13954	 UNSPEC_UNPACK_128BIT))]
13955  "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13956  "#"
13957  "&& reload_completed"
13958  [(set (match_dup 0) (match_dup 3))]
13959{
13960  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13961
13962  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13963    {
13964      emit_note (NOTE_INSN_DELETED);
13965      DONE;
13966    }
13967
13968  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13969}
13970  [(set_attr "type" "fp,fpstore")
13971   (set_attr "length" "4")])
13972
13973(define_insn_and_split "pack<mode>"
13974  [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13975	(unspec:FMOVE128
13976	 [(match_operand:<FP128_64> 1 "register_operand" "d")
13977	  (match_operand:<FP128_64> 2 "register_operand" "d")]
13978	 UNSPEC_PACK_128BIT))]
13979  "FLOAT128_2REG_P (<MODE>mode)"
13980  "#"
13981  "&& reload_completed"
13982  [(set (match_dup 3) (match_dup 1))
13983   (set (match_dup 4) (match_dup 2))]
13984{
13985  unsigned dest_hi = REGNO (operands[0]);
13986  unsigned dest_lo = dest_hi + 1;
13987
13988  gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13989  gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13990
13991  operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13992  operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13993}
13994  [(set_attr "type" "fp")
13995   (set_attr "length" "8")])
13996
13997(define_insn "unpack<mode>"
13998  [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13999	(unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14000		    (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14001	 UNSPEC_UNPACK_128BIT))]
14002  "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14003{
14004  if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14005    return ASM_COMMENT_START " xxpermdi to same register";
14006
14007  operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14008  return "xxpermdi %x0,%x1,%x1,%3";
14009}
14010  [(set_attr "type" "vecperm")])
14011
14012(define_insn "pack<mode>"
14013  [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14014	(unspec:FMOVE128_VSX
14015	 [(match_operand:DI 1 "register_operand" "wa")
14016	  (match_operand:DI 2 "register_operand" "wa")]
14017	 UNSPEC_PACK_128BIT))]
14018  "TARGET_VSX"
14019  "xxpermdi %x0,%x1,%x2,0"
14020  [(set_attr "type" "vecperm")])
14021
14022
14023
14024;; ISA 2.08 IEEE 128-bit floating point support.
14025
14026(define_insn "add<mode>3"
14027  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14028	(plus:IEEE128
14029	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14030	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14031  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14032  "xsaddqp %0,%1,%2"
14033  [(set_attr "type" "vecfloat")
14034   (set_attr "size" "128")])
14035
14036(define_insn "sub<mode>3"
14037  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14038	(minus:IEEE128
14039	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14040	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14041  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14042  "xssubqp %0,%1,%2"
14043  [(set_attr "type" "vecfloat")
14044   (set_attr "size" "128")])
14045
14046(define_insn "mul<mode>3"
14047  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14048	(mult:IEEE128
14049	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14050	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14051  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14052  "xsmulqp %0,%1,%2"
14053  [(set_attr "type" "qmul")
14054   (set_attr "size" "128")])
14055
14056(define_insn "div<mode>3"
14057  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14058	(div:IEEE128
14059	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14060	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14061  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14062  "xsdivqp %0,%1,%2"
14063  [(set_attr "type" "vecdiv")
14064   (set_attr "size" "128")])
14065
14066(define_insn "sqrt<mode>2"
14067  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14068	(sqrt:IEEE128
14069	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14070  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14071   "xssqrtqp %0,%1"
14072  [(set_attr "type" "vecdiv")
14073   (set_attr "size" "128")])
14074
14075(define_expand "copysign<mode>3"
14076  [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14077   (use (match_operand:IEEE128 1 "altivec_register_operand"))
14078   (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14079  "FLOAT128_IEEE_P (<MODE>mode)"
14080{
14081  if (TARGET_FLOAT128_HW)
14082    emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14083					 operands[2]));
14084  else
14085    emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14086					 operands[2]));
14087  DONE;
14088})
14089
14090(define_insn "copysign<mode>3_hard"
14091  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14092	(unspec:IEEE128
14093	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14094	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14095	 UNSPEC_COPYSIGN))]
14096  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14097   "xscpsgnqp %0,%2,%1"
14098  [(set_attr "type" "vecmove")
14099   (set_attr "size" "128")])
14100
14101(define_insn "copysign<mode>3_soft"
14102  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14103	(unspec:IEEE128
14104	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14105	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14106	 UNSPEC_COPYSIGN))
14107   (clobber (match_scratch:IEEE128 3 "=&v"))]
14108  "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14109   "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14110  [(set_attr "type" "veccomplex")
14111   (set_attr "length" "8")])
14112
14113(define_insn "neg<mode>2_hw"
14114  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14115	(neg:IEEE128
14116	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14117  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14118  "xsnegqp %0,%1"
14119  [(set_attr "type" "vecmove")
14120   (set_attr "size" "128")])
14121
14122
14123(define_insn "abs<mode>2_hw"
14124  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14125	(abs:IEEE128
14126	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14127  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14128  "xsabsqp %0,%1"
14129  [(set_attr "type" "vecmove")
14130   (set_attr "size" "128")])
14131
14132
14133(define_insn "*nabs<mode>2_hw"
14134  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14135	(neg:IEEE128
14136	 (abs:IEEE128
14137	  (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14138  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14139  "xsnabsqp %0,%1"
14140  [(set_attr "type" "vecmove")
14141   (set_attr "size" "128")])
14142
14143;; Initially don't worry about doing fusion
14144(define_insn "fma<mode>4_hw"
14145  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14146	(fma:IEEE128
14147	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14148	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14149	 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14150  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14151  "xsmaddqp %0,%1,%2"
14152  [(set_attr "type" "qmul")
14153   (set_attr "size" "128")])
14154
14155(define_insn "*fms<mode>4_hw"
14156  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14157	(fma:IEEE128
14158	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14159	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14160	 (neg:IEEE128
14161	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14162  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14163  "xsmsubqp %0,%1,%2"
14164  [(set_attr "type" "qmul")
14165   (set_attr "size" "128")])
14166
14167(define_insn "*nfma<mode>4_hw"
14168  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14169	(neg:IEEE128
14170	 (fma:IEEE128
14171	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14172	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14173	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14174  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14175  "xsnmaddqp %0,%1,%2"
14176  [(set_attr "type" "qmul")
14177   (set_attr "size" "128")])
14178
14179(define_insn "*nfms<mode>4_hw"
14180  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14181	(neg:IEEE128
14182	 (fma:IEEE128
14183	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14184	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14185	  (neg:IEEE128
14186	   (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14187  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14188  "xsnmsubqp %0,%1,%2"
14189  [(set_attr "type" "qmul")
14190   (set_attr "size" "128")])
14191
14192(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14193  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14194	(float_extend:IEEE128
14195	 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14196  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14197  "xscvdpqp %0,%1"
14198  [(set_attr "type" "vecfloat")
14199   (set_attr "size" "128")])
14200
14201;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14202;; point is a simple copy.
14203(define_insn_and_split "extendkftf2"
14204  [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14205	(float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14206  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14207  "@
14208   #
14209   xxlor %x0,%x1,%x1"
14210  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14211  [(const_int 0)]
14212{
14213  emit_note (NOTE_INSN_DELETED);
14214  DONE;
14215}
14216  [(set_attr "type" "*,veclogical")
14217   (set_attr "length" "0,4")])
14218
14219(define_insn_and_split "trunctfkf2"
14220  [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14221	(float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14222  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14223  "@
14224   #
14225   xxlor %x0,%x1,%x1"
14226  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14227  [(const_int 0)]
14228{
14229  emit_note (NOTE_INSN_DELETED);
14230  DONE;
14231}
14232  [(set_attr "type" "*,veclogical")
14233   (set_attr "length" "0,4")])
14234
14235(define_insn "trunc<mode>df2_hw"
14236  [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14237	(float_truncate:DF
14238	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14239  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14240  "xscvqpdp %0,%1"
14241  [(set_attr "type" "vecfloat")
14242   (set_attr "size" "128")])
14243
14244;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14245;; the KFmode -> DFmode conversion using round to odd rather than the normal
14246;; conversion
14247(define_insn_and_split "trunc<mode>sf2_hw"
14248  [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14249	(float_truncate:SF
14250	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14251   (clobber (match_scratch:DF 2 "=v"))]
14252  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14253  "#"
14254  "&& 1"
14255  [(set (match_dup 2)
14256	(unspec:DF [(match_dup 1)]
14257		   UNSPEC_TRUNC_ROUND_TO_ODD))
14258   (set (match_dup 0)
14259	(float_truncate:SF (match_dup 2)))]
14260{
14261  if (GET_CODE (operands[2]) == SCRATCH)
14262    operands[2] = gen_reg_rtx (DFmode);
14263}
14264  [(set_attr "type" "vecfloat")
14265   (set_attr "length" "8")])
14266
14267;; Conversion between IEEE 128-bit and integer types
14268
14269;; The fix function for DImode and SImode was declared earlier as a
14270;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14271;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14272;; unless we have the IEEE 128-bit hardware.
14273;;
14274;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14275;; to provide a GPR target that used direct move and a conversion in the GPR
14276;; which works around QImode/HImode not being allowed in vector registers in
14277;; ISA 2.07 (power8).
14278(define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14279  [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14280	(any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14281  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14282  "xscvqp<su><wd>z %0,%1"
14283  [(set_attr "type" "vecfloat")
14284   (set_attr "size" "128")])
14285
14286(define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14287  [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14288	(any_fix:QHI
14289	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14290  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14291  "xscvqp<su>wz %0,%1"
14292  [(set_attr "type" "vecfloat")
14293   (set_attr "size" "128")])
14294
14295;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14296;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14297(define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14298  [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14299	(any_fix:QHSI
14300	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14301   (clobber (match_scratch:QHSI 2 "=v"))]
14302  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14303  "#"
14304  "&& reload_completed"
14305  [(set (match_dup 2)
14306	(any_fix:QHSI (match_dup 1)))
14307   (set (match_dup 0)
14308	(match_dup 2))])
14309
14310(define_insn "float_<mode>di2_hw"
14311  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14312	(float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14313  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14314  "xscvsdqp %0,%1"
14315  [(set_attr "type" "vecfloat")
14316   (set_attr "size" "128")])
14317
14318(define_insn_and_split "float_<mode>si2_hw"
14319  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14320	(float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14321   (clobber (match_scratch:DI 2 "=v"))]
14322  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14323  "#"
14324  "&& 1"
14325  [(set (match_dup 2)
14326	(sign_extend:DI (match_dup 1)))
14327   (set (match_dup 0)
14328	(float:IEEE128 (match_dup 2)))]
14329{
14330  if (GET_CODE (operands[2]) == SCRATCH)
14331    operands[2] = gen_reg_rtx (DImode);
14332
14333  if (MEM_P (operands[1]))
14334    operands[1] = rs6000_address_for_fpconvert (operands[1]);
14335})
14336
14337(define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14338  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14339	(float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14340   (clobber (match_scratch:DI 2 "=X,r,X"))]
14341  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14342  "#"
14343  "&& reload_completed"
14344  [(const_int 0)]
14345{
14346  rtx dest = operands[0];
14347  rtx src = operands[1];
14348  rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14349
14350  if (altivec_register_operand (src, <QHI:MODE>mode))
14351    emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14352  else if (int_reg_operand (src, <QHI:MODE>mode))
14353    {
14354      rtx ext_di = operands[2];
14355      emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14356      emit_move_insn (dest_di, ext_di);
14357    }
14358  else if (MEM_P (src))
14359    {
14360      rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14361      emit_move_insn (dest_qhi, src);
14362      emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14363    }
14364  else
14365    gcc_unreachable ();
14366
14367  emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14368  DONE;
14369}
14370  [(set_attr "length" "8,12,12")
14371   (set_attr "type" "vecfloat")
14372   (set_attr "size" "128")])
14373
14374(define_insn "floatuns_<mode>di2_hw"
14375  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14376	(unsigned_float:IEEE128
14377	 (match_operand:DI 1 "altivec_register_operand" "v")))]
14378  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14379  "xscvudqp %0,%1"
14380  [(set_attr "type" "vecfloat")
14381   (set_attr "size" "128")])
14382
14383(define_insn_and_split "floatuns_<mode>si2_hw"
14384  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14385	(unsigned_float:IEEE128
14386	 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14387   (clobber (match_scratch:DI 2 "=v"))]
14388  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14389  "#"
14390  "&& 1"
14391  [(set (match_dup 2)
14392	(zero_extend:DI (match_dup 1)))
14393   (set (match_dup 0)
14394	(float:IEEE128 (match_dup 2)))]
14395{
14396  if (GET_CODE (operands[2]) == SCRATCH)
14397    operands[2] = gen_reg_rtx (DImode);
14398
14399  if (MEM_P (operands[1]))
14400    operands[1] = rs6000_address_for_fpconvert (operands[1]);
14401})
14402
14403(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14404  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14405	(unsigned_float:IEEE128
14406	 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14407   (clobber (match_scratch:DI 2 "=X,r,X"))]
14408  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14409  "#"
14410  "&& reload_completed"
14411  [(const_int 0)]
14412{
14413  rtx dest = operands[0];
14414  rtx src = operands[1];
14415  rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14416
14417  if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14418    emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14419  else if (int_reg_operand (src, <QHI:MODE>mode))
14420    {
14421      rtx ext_di = operands[2];
14422      emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14423      emit_move_insn (dest_di, ext_di);
14424    }
14425  else
14426    gcc_unreachable ();
14427
14428  emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14429  DONE;
14430}
14431  [(set_attr "length" "8,12,8")
14432   (set_attr "type" "vecfloat")
14433   (set_attr "size" "128")])
14434
14435;; IEEE 128-bit round to integer built-in functions
14436(define_insn "floor<mode>2"
14437  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14438	(unspec:IEEE128
14439	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14440	 UNSPEC_FRIM))]
14441  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14442  "xsrqpi 1,%0,%1,3"
14443  [(set_attr "type" "vecfloat")
14444   (set_attr "size" "128")])
14445
14446(define_insn "ceil<mode>2"
14447  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14448	(unspec:IEEE128
14449	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14450	 UNSPEC_FRIP))]
14451  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14452  "xsrqpi 1,%0,%1,2"
14453  [(set_attr "type" "vecfloat")
14454   (set_attr "size" "128")])
14455
14456(define_insn "btrunc<mode>2"
14457  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14458	(unspec:IEEE128
14459	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14460	 UNSPEC_FRIZ))]
14461  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14462  "xsrqpi 1,%0,%1,1"
14463  [(set_attr "type" "vecfloat")
14464   (set_attr "size" "128")])
14465
14466(define_insn "round<mode>2"
14467  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14468	(unspec:IEEE128
14469	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14470	 UNSPEC_FRIN))]
14471  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14472  "xsrqpi 0,%0,%1,0"
14473  [(set_attr "type" "vecfloat")
14474   (set_attr "size" "128")])
14475
14476;; IEEE 128-bit instructions with round to odd semantics
14477(define_insn "add<mode>3_odd"
14478  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14479	(unspec:IEEE128
14480	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14481	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14482	 UNSPEC_ADD_ROUND_TO_ODD))]
14483  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14484  "xsaddqpo %0,%1,%2"
14485  [(set_attr "type" "vecfloat")
14486   (set_attr "size" "128")])
14487
14488(define_insn "sub<mode>3_odd"
14489  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14490	(unspec:IEEE128
14491	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14492	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14493	 UNSPEC_SUB_ROUND_TO_ODD))]
14494  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14495  "xssubqpo %0,%1,%2"
14496  [(set_attr "type" "vecfloat")
14497   (set_attr "size" "128")])
14498
14499(define_insn "mul<mode>3_odd"
14500  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14501	(unspec:IEEE128
14502	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14503	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14504	 UNSPEC_MUL_ROUND_TO_ODD))]
14505  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14506  "xsmulqpo %0,%1,%2"
14507  [(set_attr "type" "qmul")
14508   (set_attr "size" "128")])
14509
14510(define_insn "div<mode>3_odd"
14511  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14512	(unspec:IEEE128
14513	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14514	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14515	 UNSPEC_DIV_ROUND_TO_ODD))]
14516  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14517  "xsdivqpo %0,%1,%2"
14518  [(set_attr "type" "vecdiv")
14519   (set_attr "size" "128")])
14520
14521(define_insn "sqrt<mode>2_odd"
14522  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14523	(unspec:IEEE128
14524	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14525	 UNSPEC_SQRT_ROUND_TO_ODD))]
14526  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14527   "xssqrtqpo %0,%1"
14528  [(set_attr "type" "vecdiv")
14529   (set_attr "size" "128")])
14530
14531(define_insn "fma<mode>4_odd"
14532  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14533	(unspec:IEEE128
14534	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14535	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14536	  (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14537	 UNSPEC_FMA_ROUND_TO_ODD))]
14538  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14539  "xsmaddqpo %0,%1,%2"
14540  [(set_attr "type" "qmul")
14541   (set_attr "size" "128")])
14542
14543(define_insn "*fms<mode>4_odd"
14544  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14545	(unspec:IEEE128
14546	 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14547	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14548	  (neg:IEEE128
14549	   (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14550	 UNSPEC_FMA_ROUND_TO_ODD))]
14551  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14552  "xsmsubqpo %0,%1,%2"
14553  [(set_attr "type" "qmul")
14554   (set_attr "size" "128")])
14555
14556(define_insn "*nfma<mode>4_odd"
14557  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14558	(neg:IEEE128
14559	 (unspec:IEEE128
14560	  [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14561	   (match_operand:IEEE128 2 "altivec_register_operand" "v")
14562	   (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14563	  UNSPEC_FMA_ROUND_TO_ODD)))]
14564  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14565  "xsnmaddqpo %0,%1,%2"
14566  [(set_attr "type" "qmul")
14567   (set_attr "size" "128")])
14568
14569(define_insn "*nfms<mode>4_odd"
14570  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14571	(neg:IEEE128
14572	 (unspec:IEEE128
14573	  [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14574	   (match_operand:IEEE128 2 "altivec_register_operand" "v")
14575	   (neg:IEEE128
14576	    (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14577	  UNSPEC_FMA_ROUND_TO_ODD)))]
14578  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14579  "xsnmsubqpo %0,%1,%2"
14580  [(set_attr "type" "qmul")
14581   (set_attr "size" "128")])
14582
14583(define_insn "trunc<mode>df2_odd"
14584  [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14585	(unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14586		   UNSPEC_TRUNC_ROUND_TO_ODD))]
14587  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14588  "xscvqpdpo %0,%1"
14589  [(set_attr "type" "vecfloat")
14590   (set_attr "size" "128")])
14591
14592;; IEEE 128-bit comparisons
14593(define_insn "*cmp<mode>_hw"
14594  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14595	(compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14596		      (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14597  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14598   "xscmpuqp %0,%1,%2"
14599  [(set_attr "type" "veccmp")
14600   (set_attr "size" "128")])
14601
14602;; Miscellaneous ISA 3.0 (power9) instructions
14603
14604(define_insn "darn_32"
14605  [(set (match_operand:SI 0 "register_operand" "=r")
14606        (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14607  "TARGET_P9_MISC"
14608  "darn %0,0"
14609  [(set_attr "type" "integer")])
14610
14611(define_insn "darn_raw"
14612  [(set (match_operand:DI 0 "register_operand" "=r")
14613        (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14614  "TARGET_P9_MISC && TARGET_64BIT"
14615  "darn %0,2"
14616  [(set_attr "type" "integer")])
14617
14618(define_insn "darn"
14619  [(set (match_operand:DI 0 "register_operand" "=r")
14620        (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14621  "TARGET_P9_MISC && TARGET_64BIT"
14622  "darn %0,1"
14623  [(set_attr "type" "integer")])
14624
14625;; Test byte within range.
14626;;
14627;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14628;; represents a byte whose value is ignored in this context and
14629;; vv, the least significant byte, holds the byte value that is to
14630;; be tested for membership within the range specified by operand 2.
14631;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14632;;
14633;; Return in target register operand 0 a value of 1 if lo <= vv and
14634;; vv <= hi.  Otherwise, set register operand 0 to 0.
14635;;
14636;; Though the instructions to which this expansion maps operate on
14637;; 64-bit registers, the current implementation only operates on
14638;; SI-mode operands as the high-order bits provide no information
14639;; that is not already available in the low-order bits.  To avoid the
14640;; costs of data widening operations, future enhancements might allow
14641;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14642(define_expand "cmprb"
14643  [(set (match_dup 3)
14644	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14645		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14646	 UNSPEC_CMPRB))
14647   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14648	(if_then_else:SI (lt (match_dup 3)
14649			     (const_int 0))
14650			 (const_int -1)
14651			 (if_then_else (gt (match_dup 3)
14652					   (const_int 0))
14653				       (const_int 1)
14654				       (const_int 0))))]
14655  "TARGET_P9_MISC"
14656{
14657  operands[3] = gen_reg_rtx (CCmode);
14658})
14659
14660;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14661;; represents a byte whose value is ignored in this context and
14662;; vv, the least significant byte, holds the byte value that is to
14663;; be tested for membership within the range specified by operand 2.
14664;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14665;;
14666;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14667;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
14668;; 3 bits of the target CR register are all set to 0.
14669(define_insn "*cmprb_internal"
14670  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14671	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14672		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14673	 UNSPEC_CMPRB))]
14674  "TARGET_P9_MISC"
14675  "cmprb %0,0,%1,%2"
14676  [(set_attr "type" "logical")])
14677
14678;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14679;; register operand 1 is on.  Otherwise, set operand 0 register to 1
14680;; if the GT bit (0x4) of condition register operand 1 is on.
14681;; Otherwise, set operand 0 to 0.  Note that the result stored into
14682;; register operand 0 is non-zero iff either the LT or GT bits are on
14683;; within condition register operand 1.
14684(define_insn "setb_signed"
14685   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14686	 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14687			      (const_int 0))
14688			  (const_int -1)
14689			  (if_then_else (gt (match_dup 1)
14690					    (const_int 0))
14691					(const_int 1)
14692					(const_int 0))))]
14693  "TARGET_P9_MISC"
14694  "setb %0,%1"
14695  [(set_attr "type" "logical")])
14696
14697(define_insn "setb_unsigned"
14698   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14699	 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14700			      (const_int 0))
14701			  (const_int -1)
14702			  (if_then_else (gtu (match_dup 1)
14703					    (const_int 0))
14704					(const_int 1)
14705					(const_int 0))))]
14706  "TARGET_P9_MISC"
14707  "setb %0,%1"
14708  [(set_attr "type" "logical")])
14709
14710;; Test byte within two ranges.
14711;;
14712;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14713;; represents a byte whose value is ignored in this context and
14714;; vv, the least significant byte, holds the byte value that is to
14715;; be tested for membership within the range specified by operand 2.
14716;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14717;;
14718;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14719;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
14720;; operand 0 to 0.
14721;;
14722;; Though the instructions to which this expansion maps operate on
14723;; 64-bit registers, the current implementation only operates on
14724;; SI-mode operands as the high-order bits provide no information
14725;; that is not already available in the low-order bits.  To avoid the
14726;; costs of data widening operations, future enhancements might allow
14727;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14728(define_expand "cmprb2"
14729  [(set (match_dup 3)
14730	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14731		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14732	 UNSPEC_CMPRB2))
14733   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14734	(if_then_else:SI (lt (match_dup 3)
14735			     (const_int 0))
14736			 (const_int -1)
14737			 (if_then_else (gt (match_dup 3)
14738					   (const_int 0))
14739				       (const_int 1)
14740				       (const_int 0))))]
14741  "TARGET_P9_MISC"
14742{
14743  operands[3] = gen_reg_rtx (CCmode);
14744})
14745
14746;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14747;; represents a byte whose value is ignored in this context and
14748;; vv, the least significant byte, holds the byte value that is to
14749;; be tested for membership within the ranges specified by operand 2.
14750;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14751;;
14752;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14753;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14754;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
14755;; CR register are all set to 0.
14756(define_insn "*cmprb2_internal"
14757  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14758	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14759		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14760	 UNSPEC_CMPRB2))]
14761  "TARGET_P9_MISC"
14762  "cmprb %0,1,%1,%2"
14763  [(set_attr "type" "logical")])
14764
14765;; Test byte membership within set of 8 bytes.
14766;;
14767;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14768;; represents a byte whose value is ignored in this context and
14769;; vv, the least significant byte, holds the byte value that is to
14770;; be tested for membership within the set specified by operand 2.
14771;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14772;;
14773;; Return in target register operand 0 a value of 1 if vv equals one
14774;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
14775;; register operand 0 to 0.  Note that the 8 byte values held within
14776;; operand 2 need not be unique.
14777;;
14778;; Though the instructions to which this expansion maps operate on
14779;; 64-bit registers, the current implementation requires that operands
14780;; 0 and 1 have mode SI as the high-order bits provide no information
14781;; that is not already available in the low-order bits.  To avoid the
14782;; costs of data widening operations, future enhancements might allow
14783;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14784(define_expand "cmpeqb"
14785  [(set (match_dup 3)
14786	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14787		    (match_operand:DI 2 "gpc_reg_operand" "r")]
14788	 UNSPEC_CMPEQB))
14789   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14790	(if_then_else:SI (lt (match_dup 3)
14791			     (const_int 0))
14792			 (const_int -1)
14793			 (if_then_else (gt (match_dup 3)
14794					   (const_int 0))
14795				       (const_int 1)
14796				       (const_int 0))))]
14797  "TARGET_P9_MISC && TARGET_64BIT"
14798{
14799  operands[3] = gen_reg_rtx (CCmode);
14800})
14801
14802;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14803;; represents a byte whose value is ignored in this context and
14804;; vv, the least significant byte, holds the byte value that is to
14805;; be tested for membership within the set specified by operand 2.
14806;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14807;;
14808;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14809;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
14810;; set the GT bit to zero.  The other 3 bits of the target CR register
14811;; are all set to 0.
14812(define_insn "*cmpeqb_internal"
14813  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14814	 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14815		     (match_operand:DI 2 "gpc_reg_operand" "r")]
14816	  UNSPEC_CMPEQB))]
14817  "TARGET_P9_MISC && TARGET_64BIT"
14818  "cmpeqb %0,%1,%2"
14819  [(set_attr "type" "logical")])
14820
14821
14822(include "sync.md")
14823(include "vector.md")
14824(include "vsx.md")
14825(include "altivec.md")
14826(include "dfp.md")
14827(include "paired.md")
14828(include "crypto.md")
14829(include "htm.md")
14830