1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2;; Copyright (C) 1990-2020 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   (FIRST_ALTIVEC_REGNO		64)
37   (LAST_ALTIVEC_REGNO		95)
38   (LR_REGNO			96)
39   (CTR_REGNO			97)
40   (CA_REGNO			98)
41   (ARG_POINTER_REGNUM		99)
42   (CR0_REGNO			100)
43   (CR1_REGNO			101)
44   (CR2_REGNO			102)
45   (CR3_REGNO			103)
46   (CR4_REGNO			104)
47   (CR5_REGNO			105)
48   (CR6_REGNO			106)
49   (CR7_REGNO			107)
50   (MAX_CR_REGNO		107)
51   (VRSAVE_REGNO		108)
52   (VSCR_REGNO			109)
53   (FRAME_POINTER_REGNUM	110)
54  ])
55
56;;
57;; UNSPEC usage
58;;
59
60(define_c_enum "unspec"
61  [UNSPEC_PROBE_STACK		; probe stack memory reference
62   UNSPEC_TOCPTR		; address of a word pointing to the TOC
63   UNSPEC_TOC			; address of the TOC (more-or-less)
64   UNSPEC_TOCSLOT		; offset from r1 of toc pointer save slot
65   UNSPEC_MOVSI_GOT
66   UNSPEC_FCTIWZ
67   UNSPEC_FRIM
68   UNSPEC_FRIN
69   UNSPEC_FRIP
70   UNSPEC_FRIZ
71   UNSPEC_XSRDPI
72   UNSPEC_LD_MPIC		; load_macho_picbase
73   UNSPEC_RELD_MPIC		; re-load_macho_picbase
74   UNSPEC_MPIC_CORRECT		; macho_correct_pic
75   UNSPEC_TLSGD
76   UNSPEC_TLSLD
77   UNSPEC_TLS_GET_ADDR
78   UNSPEC_MOVESI_FROM_CR
79   UNSPEC_MOVESI_TO_CR
80   UNSPEC_TLSDTPREL
81   UNSPEC_TLSDTPRELHA
82   UNSPEC_TLSDTPRELLO
83   UNSPEC_TLSGOTDTPREL
84   UNSPEC_TLSTPREL
85   UNSPEC_TLSTPRELHA
86   UNSPEC_TLSTPRELLO
87   UNSPEC_TLSGOTTPREL
88   UNSPEC_TLSTLS
89   UNSPEC_TLSTLS_PCREL
90   UNSPEC_FIX_TRUNC_TF		; fadd, rounding towards zero
91   UNSPEC_STFIWX
92   UNSPEC_POPCNTB
93   UNSPEC_FRES
94   UNSPEC_SP_SET
95   UNSPEC_SP_TEST
96   UNSPEC_SYNC
97   UNSPEC_LWSYNC
98   UNSPEC_SYNC_OP
99   UNSPEC_ATOMIC
100   UNSPEC_CMPXCHG
101   UNSPEC_XCHG
102   UNSPEC_AND
103   UNSPEC_DLMZB
104   UNSPEC_DLMZB_CR
105   UNSPEC_DLMZB_STRLEN
106   UNSPEC_RSQRT
107   UNSPEC_TOCREL
108   UNSPEC_MACHOPIC_OFFSET
109   UNSPEC_BPERM
110   UNSPEC_COPYSIGN
111   UNSPEC_PARITY
112   UNSPEC_CMPB
113   UNSPEC_FCTIW
114   UNSPEC_FCTID
115   UNSPEC_LFIWAX
116   UNSPEC_LFIWZX
117   UNSPEC_FCTIWUZ
118   UNSPEC_NOP
119   UNSPEC_GRP_END_NOP
120   UNSPEC_P8V_FMRGOW
121   UNSPEC_P8V_MTVSRWZ
122   UNSPEC_P8V_RELOAD_FROM_GPR
123   UNSPEC_P8V_MTVSRD
124   UNSPEC_P8V_XXPERMDI
125   UNSPEC_P8V_RELOAD_FROM_VSX
126   UNSPEC_ADDG6S
127   UNSPEC_CDTBCD
128   UNSPEC_CBCDTD
129   UNSPEC_DIVE
130   UNSPEC_DIVEU
131   UNSPEC_UNPACK_128BIT
132   UNSPEC_PACK_128BIT
133   UNSPEC_LSQ
134   UNSPEC_FUSION_GPR
135   UNSPEC_STACK_CHECK
136   UNSPEC_CMPRB
137   UNSPEC_CMPRB2
138   UNSPEC_CMPEQB
139   UNSPEC_ADD_ROUND_TO_ODD
140   UNSPEC_SUB_ROUND_TO_ODD
141   UNSPEC_MUL_ROUND_TO_ODD
142   UNSPEC_DIV_ROUND_TO_ODD
143   UNSPEC_FMA_ROUND_TO_ODD
144   UNSPEC_SQRT_ROUND_TO_ODD
145   UNSPEC_TRUNC_ROUND_TO_ODD
146   UNSPEC_SIGNBIT
147   UNSPEC_SF_FROM_SI
148   UNSPEC_SI_FROM_SF
149   UNSPEC_PLTSEQ
150   UNSPEC_PLT16_HA
151  ])
152
153;;
154;; UNSPEC_VOLATILE usage
155;;
156
157(define_c_enum "unspecv"
158  [UNSPECV_BLOCK
159   UNSPECV_LL			; load-locked
160   UNSPECV_SC			; store-conditional
161   UNSPECV_PROBE_STACK_RANGE	; probe range of stack addresses
162   UNSPECV_EH_RR		; eh_reg_restore
163   UNSPECV_ISYNC		; isync instruction
164   UNSPECV_MFTB			; move from time base
165   UNSPECV_DARN			; darn 1 (deliver a random number)
166   UNSPECV_DARN_32		; darn 2
167   UNSPECV_DARN_RAW		; darn 0
168   UNSPECV_NLGR			; non-local goto receiver
169   UNSPECV_MFFS			; Move from FPSCR
170   UNSPECV_MFFSL		; Move from FPSCR light instruction version
171   UNSPECV_MFFSCRN		; Move from FPSCR float rounding mode
172   UNSPECV_MFFSCDRN		; Move from FPSCR decimal float rounding mode
173   UNSPECV_MTFSF		; Move to FPSCR Fields 8 to 15
174   UNSPECV_MTFSF_HI		; Move to FPSCR Fields 0 to 7
175   UNSPECV_MTFSB0		; Set FPSCR Field bit to 0
176   UNSPECV_MTFSB1		; Set FPSCR Field bit to 1
177   UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
178   UNSPECV_SPEC_BARRIER         ; Speculation barrier
179   UNSPECV_PLT16_LO
180   UNSPECV_PLT_PCREL
181  ])
182
183; The three different kinds of epilogue.
184(define_enum "epilogue_type" [normal sibcall eh_return])
185
186;; Define an insn type attribute.  This is used in function unit delay
187;; computations.
188(define_attr "type"
189  "integer,two,three,
190   add,logical,shift,insert,
191   mul,halfmul,div,
192   exts,cntlz,popcnt,isel,
193   load,store,fpload,fpstore,vecload,vecstore,
194   cmp,
195   branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
196   cr_logical,mfcr,mfcrf,mtcr,
197   fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
198   vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
199   vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
200   veclogical,veccmpfx,vecexts,vecmove,
201   htm,htmsimple,dfp,mma"
202  (const_string "integer"))
203
204;; What data size does this instruction work on?
205;; This is used for insert, mul and others as necessary.
206(define_attr "size" "8,16,32,64,128" (const_string "32"))
207
208;; What is the insn_cost for this insn?  The target hook can still override
209;; this.  For optimizing for size the "length" attribute is used instead.
210(define_attr "cost" "" (const_int 0))
211
212;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
213;; This is used for add, logical, shift, exts, mul.
214(define_attr "dot" "no,yes" (const_string "no"))
215
216;; Does this instruction sign-extend its result?
217;; This is used for load insns.
218(define_attr "sign_extend" "no,yes" (const_string "no"))
219
220;; Does this cr_logical instruction have three operands?  That is, BT != BB.
221(define_attr "cr_logical_3op" "no,yes" (const_string "no"))
222
223;; Does this instruction use indexed (that is, reg+reg) addressing?
224;; This is used for load and store insns.  If operand 0 or 1 is a MEM
225;; it is automatically set based on that.  If a load or store instruction
226;; has fewer than two operands it needs to set this attribute manually
227;; or the compiler will crash.
228(define_attr "indexed" "no,yes"
229  (if_then_else (ior (match_operand 0 "indexed_address_mem")
230		     (match_operand 1 "indexed_address_mem"))
231		(const_string "yes")
232		(const_string "no")))
233
234;; Does this instruction use update addressing?
235;; This is used for load and store insns.  See the comments for "indexed".
236(define_attr "update" "no,yes"
237  (if_then_else (ior (match_operand 0 "update_address_mem")
238		     (match_operand 1 "update_address_mem"))
239		(const_string "yes")
240		(const_string "no")))
241
242;; Is this instruction using operands[2] as shift amount, and can that be a
243;; register?
244;; This is used for shift insns.
245(define_attr "maybe_var_shift" "no,yes" (const_string "no"))
246
247;; Is this instruction using a shift amount from a register?
248;; This is used for shift insns.
249(define_attr "var_shift" "no,yes"
250  (if_then_else (and (eq_attr "type" "shift")
251		     (eq_attr "maybe_var_shift" "yes"))
252		(if_then_else (match_operand 2 "gpc_reg_operand")
253			      (const_string "yes")
254			      (const_string "no"))
255		(const_string "no")))
256
257;; Is copying of this instruction disallowed?
258(define_attr "cannot_copy" "no,yes" (const_string "no"))
259
260
261;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
262;; before the instruction.  A prefixed instruction has a prefix instruction
263;; word that extends the immediate value of the instructions from 12-16 bits to
264;; 34 bits.  The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
265;; insns.  The default "length" attribute will also be adjusted by default to
266;; be 12 bytes.
267(define_attr "prefixed" "no,yes"
268  (cond [(ior (match_test "!TARGET_PREFIXED")
269	      (match_test "!NONJUMP_INSN_P (insn)"))
270	 (const_string "no")
271
272	 (eq_attr "type" "load,fpload,vecload")
273	 (if_then_else (match_test "prefixed_load_p (insn)")
274		       (const_string "yes")
275		       (const_string "no"))
276
277	 (eq_attr "type" "store,fpstore,vecstore")
278	 (if_then_else (match_test "prefixed_store_p (insn)")
279		       (const_string "yes")
280		       (const_string "no"))
281
282	 (eq_attr "type" "integer,add")
283	 (if_then_else (match_test "prefixed_paddi_p (insn)")
284		       (const_string "yes")
285		       (const_string "no"))]
286
287	(const_string "no")))
288
289;; Return the number of real hardware instructions in a combined insn.  If it
290;; is 0, just use the length / 4.
291(define_attr "num_insns" "" (const_int 0))
292
293;; If an insn is prefixed, return the maximum number of prefixed instructions
294;; in the insn.  The macro ADJUST_INSN_LENGTH uses this number to adjust the
295;; insn length.
296(define_attr "max_prefixed_insns" "" (const_int 1))
297
298;; Length of the instruction (in bytes).  This length does not consider the
299;; length for prefixed instructions.  The macro ADJUST_INSN_LENGTH will adjust
300;; the length if there are prefixed instructions.
301;;
302;; While it might be tempting to use num_insns to calculate the length, it can
303;; be problematical unless all insn lengths are adjusted to use num_insns
304;; (i.e. if num_insns is 0, it will get the length, which in turn will get
305;; num_insns and recurse).
306(define_attr "length" "" (const_int 4))
307
308;; Processor type -- this attribute must exactly match the processor_type
309;; enumeration in rs6000-opts.h.
310(define_attr "cpu"
311  "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
312   ppc750,ppc7400,ppc7450,
313   ppc403,ppc405,ppc440,ppc476,
314   ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
315   power4,power5,power6,power7,power8,power9,power10,
316   rs64a,mpccore,cell,ppca2,titan"
317  (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
318
319;; The ISA we implement.
320(define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,p10"
321  (const_string "any"))
322
323;; Is this alternative enabled for the current CPU/ISA/etc.?
324(define_attr "enabled" ""
325  (cond
326    [(eq_attr "isa" "any")
327     (const_int 1)
328
329     (and (eq_attr "isa" "p5")
330	  (match_test "TARGET_POPCNTB"))
331     (const_int 1)
332
333     (and (eq_attr "isa" "p6")
334	  (match_test "TARGET_CMPB"))
335     (const_int 1)
336
337     (and (eq_attr "isa" "p7")
338	  (match_test "TARGET_POPCNTD"))
339     (const_int 1)
340
341     (and (eq_attr "isa" "p7v")
342	  (match_test "TARGET_VSX"))
343     (const_int 1)
344
345     (and (eq_attr "isa" "p8v")
346	  (match_test "TARGET_P8_VECTOR"))
347     (const_int 1)
348
349     (and (eq_attr "isa" "p9v")
350	  (match_test "TARGET_P9_VECTOR"))
351     (const_int 1)
352
353     (and (eq_attr "isa" "p9kf")
354	  (match_test "TARGET_FLOAT128_TYPE"))
355     (const_int 1)
356
357     (and (eq_attr "isa" "p9tf")
358	  (match_test "FLOAT128_VECTOR_P (TFmode)"))
359     (const_int 1)
360
361     (and (eq_attr "isa" "p10")
362	  (match_test "TARGET_POWER10"))
363     (const_int 1)
364    ] (const_int 0)))
365
366;; If this instruction is microcoded on the CELL processor
367; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
368(define_attr "cell_micro" "not,conditional,always"
369  (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
370			  (eq_attr "dot" "yes"))
371		     (and (eq_attr "type" "load")
372			  (eq_attr "sign_extend" "yes"))
373		     (and (eq_attr "type" "shift")
374			  (eq_attr "var_shift" "yes")))
375		(const_string "always")
376		(const_string "not")))
377
378(automata_option "ndfa")
379
380(include "rs64.md")
381(include "mpc.md")
382(include "40x.md")
383(include "440.md")
384(include "476.md")
385(include "601.md")
386(include "603.md")
387(include "6xx.md")
388(include "7xx.md")
389(include "7450.md")
390(include "8540.md")
391(include "e300c2c3.md")
392(include "e500mc.md")
393(include "e500mc64.md")
394(include "e5500.md")
395(include "e6500.md")
396(include "power4.md")
397(include "power5.md")
398(include "power6.md")
399(include "power7.md")
400(include "power8.md")
401(include "power9.md")
402(include "power10.md")
403(include "cell.md")
404(include "a2.md")
405(include "titan.md")
406
407(include "predicates.md")
408(include "constraints.md")
409
410
411;; Mode iterators
412
413; This mode iterator allows :GPR to be used to indicate the allowable size
414; of whole values in GPRs.
415(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
416
417; And again, for patterns that need two (potentially) different integer modes.
418(define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
419
420; Any supported integer mode.
421(define_mode_iterator INT [QI HI SI DI TI PTI])
422
423; Any supported integer mode that fits in one register.
424(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
425
426; Integer modes supported in VSX registers with ISA 3.0 instructions
427(define_mode_iterator INT_ISA3 [QI HI SI DI])
428
429; Everything we can extend QImode to.
430(define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
431
432; Everything we can extend HImode to.
433(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
434
435; Everything we can extend SImode to.
436(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
437
438; QImode or HImode for small integer moves and small atomic ops
439(define_mode_iterator QHI [QI HI])
440
441; QImode, HImode, SImode for fused ops only for GPR loads
442(define_mode_iterator QHSI [QI HI SI])
443
444; HImode or SImode for sign extended fusion ops
445(define_mode_iterator HSI [HI SI])
446
447; SImode or DImode, even if DImode doesn't fit in GPRs.
448(define_mode_iterator SDI [SI DI])
449
450; The size of a pointer.  Also, the size of the value that a record-condition
451; (one with a '.') will compare; and the size used for arithmetic carries.
452(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
453
454; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
455; PTImode is GPR only)
456(define_mode_iterator TI2 [TI PTI])
457
458; Any hardware-supported floating-point mode
459(define_mode_iterator FP [
460  (SF "TARGET_HARD_FLOAT")
461  (DF "TARGET_HARD_FLOAT")
462  (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
463  (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
464  (KF "TARGET_FLOAT128_TYPE")
465  (DD "TARGET_DFP")
466  (TD "TARGET_DFP")])
467
468; Any fma capable floating-point mode.
469(define_mode_iterator FMA_F [
470  (SF "TARGET_HARD_FLOAT")
471  (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
472  (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
473  (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
474  (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
475  (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
476  ])
477
478; Floating point move iterators to combine binary and decimal moves
479(define_mode_iterator FMOVE32 [SF SD])
480(define_mode_iterator FMOVE64 [DF DD])
481(define_mode_iterator FMOVE64X [DI DF DD])
482(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
483				(IF "FLOAT128_IBM_P (IFmode)")
484				(TD "TARGET_HARD_FLOAT")])
485
486(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
487				    (IF "FLOAT128_2REG_P (IFmode)")
488				    (TD "TARGET_HARD_FLOAT")])
489
490; Iterators for 128 bit types for direct move
491(define_mode_iterator FMOVE128_GPR [TI
492				    V16QI
493				    V8HI
494				    V4SI
495				    V4SF
496				    V2DI
497				    V2DF
498				    V1TI
499				    (KF    "FLOAT128_VECTOR_P (KFmode)")
500				    (TF    "FLOAT128_VECTOR_P (TFmode)")])
501
502; Iterator for 128-bit VSX types for pack/unpack
503(define_mode_iterator FMOVE128_VSX [V1TI KF])
504
505; Iterators for converting to/from TFmode
506(define_mode_iterator IFKF [IF KF])
507
508; Constraints for moving IF/KFmode.
509(define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
510
511; Whether a floating point move is ok, don't allow SD without hardware FP
512(define_mode_attr fmove_ok [(SF "")
513			    (DF "")
514			    (SD "TARGET_HARD_FLOAT")
515			    (DD "")])
516
517; Convert REAL_VALUE to the appropriate bits
518(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
519					(DF "REAL_VALUE_TO_TARGET_DOUBLE")
520					(SD "REAL_VALUE_TO_TARGET_DECIMAL32")
521					(DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
522
523; Whether 0.0 has an all-zero bit pattern
524(define_mode_attr zero_fp [(SF "j")
525			   (DF "j")
526			   (TF "j")
527			   (IF "j")
528			   (KF "j")
529			   (SD "wn")
530			   (DD "wn")
531			   (TD "wn")])
532
533; Definitions for 64-bit VSX
534(define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
535
536; Definitions for 64-bit direct move
537(define_mode_attr f64_dm  [(DF "wa") (DD "d")])
538
539; Definitions for 64-bit use of altivec registers
540(define_mode_attr f64_av  [(DF "v") (DD "wn")])
541
542; Definitions for 64-bit access to ISA 3.0 (power9) vector
543(define_mode_attr f64_p9  [(DF "v") (DD "wn")])
544
545; These modes do not fit in integer registers in 32-bit mode.
546(define_mode_iterator DIFD [DI DF DD])
547
548; Iterator for reciprocal estimate instructions
549(define_mode_iterator RECIPF [SF DF V4SF V2DF])
550
551; SFmode or DFmode.
552(define_mode_iterator SFDF [SF DF])
553
554; And again, for when we need two FP modes in a pattern.
555(define_mode_iterator SFDF2 [SF DF])
556
557; A generic s/d attribute, for sp/dp for example.
558(define_mode_attr sd [(SF   "s") (DF   "d")
559		      (V4SF "s") (V2DF "d")])
560
561; "s" or nothing, for fmuls/fmul for example.
562(define_mode_attr s [(SF "s") (DF "")])
563
564; Iterator for 128-bit floating point that uses the IBM double-double format
565(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
566			      (TF "FLOAT128_IBM_P (TFmode)")])
567
568; Iterator for 128-bit floating point that uses IEEE 128-bit float
569(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
570			       (TF "FLOAT128_IEEE_P (TFmode)")])
571
572; Iterator for 128-bit floating point
573(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
574				(IF "TARGET_FLOAT128_TYPE")
575				(TF "TARGET_LONG_DOUBLE_128")])
576
577; Iterator for signbit on 64-bit machines with direct move
578(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
579			       (TF "FLOAT128_VECTOR_P (TFmode)")])
580
581; Iterator for ISA 3.0 supported floating point types
582(define_mode_iterator FP_ISA3 [SF DF])
583
584; SF/DF constraint for arithmetic on traditional floating point registers
585(define_mode_attr Ff		[(SF "f") (DF "d") (DI "d")])
586
587; SF/DF constraint for arithmetic on VSX registers using instructions added in
588; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
589; but are used on SFmode, since internally SFmode values are kept in the DFmode
590; format.
591(define_mode_attr Fv		[(SF "wa") (DF "wa") (DI "wa")])
592
593; Which isa is needed for those float instructions?
594(define_mode_attr Fisa		[(SF "p8v")  (DF "*") (DI "*")])
595
596; FRE/FRES support
597(define_mode_attr FFRE		[(SF "FRES") (DF "FRE")])
598
599; Conditional returns.
600(define_code_iterator any_return [return simple_return])
601(define_code_attr return_pred [(return "direct_return ()")
602			       (simple_return "1")])
603(define_code_attr return_str [(return "") (simple_return "simple_")])
604
605; Logical operators.
606(define_code_iterator iorxor		[ior xor])
607(define_code_iterator and_ior_xor	[and ior xor])
608
609; Signed/unsigned variants of ops.
610(define_code_iterator any_extend	[sign_extend zero_extend])
611(define_code_iterator any_fix		[fix unsigned_fix])
612(define_code_iterator any_float		[float unsigned_float])
613
614(define_code_attr u  [(sign_extend	"")
615		      (zero_extend	"u")
616		      (fix		"")
617		      (unsigned_fix	"u")])
618
619(define_code_attr su [(sign_extend	"s")
620		      (zero_extend	"u")
621		      (fix		"s")
622		      (unsigned_fix	"u")
623		      (float		"s")
624		      (unsigned_float	"u")])
625
626(define_code_attr az [(sign_extend	"a")
627		      (zero_extend	"z")
628		      (fix		"a")
629		      (unsigned_fix	"z")
630		      (float		"a")
631		      (unsigned_float	"z")])
632
633(define_code_attr uns [(fix		"")
634		       (unsigned_fix	"uns")
635		       (float		"")
636		       (unsigned_float	"uns")])
637
638; Various instructions that come in SI and DI forms.
639; A generic w/d attribute, for things like cmpw/cmpd.
640(define_mode_attr wd [(QI    "b")
641		      (HI    "h")
642		      (SI    "w")
643		      (DI    "d")
644		      (V16QI "b")
645		      (V8HI  "h")
646		      (V4SI  "w")
647		      (V2DI  "d")
648		      (V1TI  "q")
649		      (TI    "q")])
650
651;; How many bits in this mode?
652(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
653					   (SF "32") (DF "64")])
654
655; DImode bits
656(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
657
658;; Bitmask for shift instructions
659(define_mode_attr hH [(SI "h") (DI "H")])
660
661;; A mode twice the size of the given mode
662(define_mode_attr dmode [(SI "di") (DI "ti")])
663(define_mode_attr DMODE [(SI "DI") (DI "TI")])
664
665;; Suffix for reload patterns
666(define_mode_attr ptrsize [(SI "32bit")
667			   (DI "64bit")])
668
669(define_mode_attr tptrsize [(SI "TARGET_32BIT")
670			    (DI "TARGET_64BIT")])
671
672(define_mode_attr mptrsize [(SI "si")
673			    (DI "di")])
674
675(define_mode_attr ptrload [(SI "lwz")
676			   (DI "ld")])
677
678(define_mode_attr ptrm [(SI "m")
679			(DI "Y")])
680
681(define_mode_attr rreg [(SF   "f")
682			(DF   "wa")
683			(TF   "f")
684			(TD   "f")
685			(V4SF "wa")
686			(V2DF "wa")])
687
688(define_mode_attr rreg2 [(SF   "f")
689			 (DF   "d")])
690
691(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
692				 (DF "TARGET_FCFID")])
693
694;; Mode iterator for logical operations on 128-bit types
695(define_mode_iterator BOOL_128		[TI
696					 PTI
697					 (V16QI	"TARGET_ALTIVEC")
698					 (V8HI	"TARGET_ALTIVEC")
699					 (V4SI	"TARGET_ALTIVEC")
700					 (V4SF	"TARGET_ALTIVEC")
701					 (V2DI	"TARGET_ALTIVEC")
702					 (V2DF	"TARGET_ALTIVEC")
703					 (V1TI  "TARGET_ALTIVEC")])
704
705;; For the GPRs we use 3 constraints for register outputs, two that are the
706;; same as the output register, and a third where the output register is an
707;; early clobber, so we don't have to deal with register overlaps.  For the
708;; vector types, we prefer to use the vector registers.  For TI mode, allow
709;; either.
710
711;; Mode attribute for boolean operation register constraints for output
712(define_mode_attr BOOL_REGS_OUTPUT	[(TI	"&r,r,r,wa,v")
713					 (PTI	"&r,r,r")
714					 (V16QI	"wa,v,&?r,?r,?r")
715					 (V8HI	"wa,v,&?r,?r,?r")
716					 (V4SI	"wa,v,&?r,?r,?r")
717					 (V4SF	"wa,v,&?r,?r,?r")
718					 (V2DI	"wa,v,&?r,?r,?r")
719					 (V2DF	"wa,v,&?r,?r,?r")
720					 (V1TI	"wa,v,&?r,?r,?r")])
721
722;; Mode attribute for boolean operation register constraints for operand1
723(define_mode_attr BOOL_REGS_OP1		[(TI	"r,0,r,wa,v")
724					 (PTI	"r,0,r")
725					 (V16QI	"wa,v,r,0,r")
726					 (V8HI	"wa,v,r,0,r")
727					 (V4SI	"wa,v,r,0,r")
728					 (V4SF	"wa,v,r,0,r")
729					 (V2DI	"wa,v,r,0,r")
730					 (V2DF	"wa,v,r,0,r")
731					 (V1TI	"wa,v,r,0,r")])
732
733;; Mode attribute for boolean operation register constraints for operand2
734(define_mode_attr BOOL_REGS_OP2		[(TI	"r,r,0,wa,v")
735					 (PTI	"r,r,0")
736					 (V16QI	"wa,v,r,r,0")
737					 (V8HI	"wa,v,r,r,0")
738					 (V4SI	"wa,v,r,r,0")
739					 (V4SF	"wa,v,r,r,0")
740					 (V2DI	"wa,v,r,r,0")
741					 (V2DF	"wa,v,r,r,0")
742					 (V1TI	"wa,v,r,r,0")])
743
744;; Mode attribute for boolean operation register constraints for operand1
745;; for one_cmpl.  To simplify things, we repeat the constraint where 0
746;; is used for operand1 or operand2
747(define_mode_attr BOOL_REGS_UNARY	[(TI	"r,0,0,wa,v")
748					 (PTI	"r,0,0")
749					 (V16QI	"wa,v,r,0,0")
750					 (V8HI	"wa,v,r,0,0")
751					 (V4SI	"wa,v,r,0,0")
752					 (V4SF	"wa,v,r,0,0")
753					 (V2DI	"wa,v,r,0,0")
754					 (V2DF	"wa,v,r,0,0")
755					 (V1TI	"wa,v,r,0,0")])
756
757;; Reload iterator for creating the function to allocate a base register to
758;; supplement addressing modes.
759(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
760			      SF SD SI DF DD DI TI PTI KF IF TF
761			      POI PXI])
762
763;; Iterate over smin, smax
764(define_code_iterator fp_minmax	[smin smax])
765
766(define_code_attr     minmax	[(smin "min")
767				 (smax "max")])
768
769(define_code_attr     SMINMAX	[(smin "SMIN")
770				 (smax "SMAX")])
771
772;; Iterator to optimize the following cases:
773;;	D-form load to FPR register & move to Altivec register
774;;	Move Altivec register to FPR register and store
775(define_mode_iterator ALTIVEC_DFORM [DF
776				     (SF "TARGET_P8_VECTOR")
777				     (DI "TARGET_POWERPC64")])
778
779(include "darwin.md")
780
781;; Start with fixed-point load and store insns.  Here we put only the more
782;; complex forms.  Basic data transfer is done later.
783
784(define_insn "zero_extendqi<mode>2"
785  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
786	(zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
787  ""
788  "@
789   lbz%U1%X1 %0,%1
790   rlwinm %0,%1,0,0xff
791   lxsibzx %x0,%y1
792   vextractub %0,%1,7"
793  [(set_attr "type" "load,shift,fpload,vecperm")
794   (set_attr "isa" "*,*,p9v,p9v")])
795
796(define_insn_and_split "*zero_extendqi<mode>2_dot"
797  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
798	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
799		    (const_int 0)))
800   (clobber (match_scratch:EXTQI 0 "=r,r"))]
801  ""
802  "@
803   andi. %0,%1,0xff
804   #"
805  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
806  [(set (match_dup 0)
807	(zero_extend:EXTQI (match_dup 1)))
808   (set (match_dup 2)
809	(compare:CC (match_dup 0)
810		    (const_int 0)))]
811  ""
812  [(set_attr "type" "logical")
813   (set_attr "dot" "yes")
814   (set_attr "length" "4,8")])
815
816(define_insn_and_split "*zero_extendqi<mode>2_dot2"
817  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
818	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
819		    (const_int 0)))
820   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
821	(zero_extend:EXTQI (match_dup 1)))]
822  ""
823  "@
824   andi. %0,%1,0xff
825   #"
826  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
827  [(set (match_dup 0)
828	(zero_extend:EXTQI (match_dup 1)))
829   (set (match_dup 2)
830	(compare:CC (match_dup 0)
831		    (const_int 0)))]
832  ""
833  [(set_attr "type" "logical")
834   (set_attr "dot" "yes")
835   (set_attr "length" "4,8")])
836
837
838(define_insn "zero_extendhi<mode>2"
839  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
840	(zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
841  ""
842  "@
843   lhz%U1%X1 %0,%1
844   rlwinm %0,%1,0,0xffff
845   lxsihzx %x0,%y1
846   vextractuh %0,%1,6"
847  [(set_attr "type" "load,shift,fpload,vecperm")
848   (set_attr "isa" "*,*,p9v,p9v")])
849
850(define_insn_and_split "*zero_extendhi<mode>2_dot"
851  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
852	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
853		    (const_int 0)))
854   (clobber (match_scratch:EXTHI 0 "=r,r"))]
855  ""
856  "@
857   andi. %0,%1,0xffff
858   #"
859  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
860  [(set (match_dup 0)
861	(zero_extend:EXTHI (match_dup 1)))
862   (set (match_dup 2)
863	(compare:CC (match_dup 0)
864		    (const_int 0)))]
865  ""
866  [(set_attr "type" "logical")
867   (set_attr "dot" "yes")
868   (set_attr "length" "4,8")])
869
870(define_insn_and_split "*zero_extendhi<mode>2_dot2"
871  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
872	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
873		    (const_int 0)))
874   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
875	(zero_extend:EXTHI (match_dup 1)))]
876  ""
877  "@
878   andi. %0,%1,0xffff
879   #"
880  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
881  [(set (match_dup 0)
882	(zero_extend:EXTHI (match_dup 1)))
883   (set (match_dup 2)
884	(compare:CC (match_dup 0)
885		    (const_int 0)))]
886  ""
887  [(set_attr "type" "logical")
888   (set_attr "dot" "yes")
889   (set_attr "length" "4,8")])
890
891
892(define_insn "zero_extendsi<mode>2"
893  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
894	(zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
895  ""
896  "@
897   lwz%U1%X1 %0,%1
898   rldicl %0,%1,0,32
899   lfiwzx %0,%y1
900   lxsiwzx %x0,%y1
901   mtvsrwz %x0,%1
902   mfvsrwz %0,%x1
903   xxextractuw %x0,%x1,4"
904  [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
905   (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
906
907(define_insn_and_split "*zero_extendsi<mode>2_dot"
908  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
909	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
910		    (const_int 0)))
911   (clobber (match_scratch:EXTSI 0 "=r,r"))]
912  ""
913  "@
914   rldicl. %0,%1,0,32
915   #"
916  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
917  [(set (match_dup 0)
918	(zero_extend:DI (match_dup 1)))
919   (set (match_dup 2)
920	(compare:CC (match_dup 0)
921		    (const_int 0)))]
922  ""
923  [(set_attr "type" "shift")
924   (set_attr "dot" "yes")
925   (set_attr "length" "4,8")])
926
927(define_insn_and_split "*zero_extendsi<mode>2_dot2"
928  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
929	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
930		    (const_int 0)))
931   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
932	(zero_extend:EXTSI (match_dup 1)))]
933  ""
934  "@
935   rldicl. %0,%1,0,32
936   #"
937  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
938  [(set (match_dup 0)
939	(zero_extend:EXTSI (match_dup 1)))
940   (set (match_dup 2)
941	(compare:CC (match_dup 0)
942		    (const_int 0)))]
943  ""
944  [(set_attr "type" "shift")
945   (set_attr "dot" "yes")
946   (set_attr "length" "4,8")])
947
948
949(define_insn "extendqi<mode>2"
950  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
951	(sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
952  ""
953  "@
954   extsb %0,%1
955   vextsb2d %0,%1"
956  [(set_attr "type" "exts,vecperm")
957   (set_attr "isa" "*,p9v")])
958
959(define_insn_and_split "*extendqi<mode>2_dot"
960  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
961	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
962		    (const_int 0)))
963   (clobber (match_scratch:EXTQI 0 "=r,r"))]
964  ""
965  "@
966   extsb. %0,%1
967   #"
968  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
969  [(set (match_dup 0)
970	(sign_extend:EXTQI (match_dup 1)))
971   (set (match_dup 2)
972	(compare:CC (match_dup 0)
973		    (const_int 0)))]
974  ""
975  [(set_attr "type" "exts")
976   (set_attr "dot" "yes")
977   (set_attr "length" "4,8")])
978
979(define_insn_and_split "*extendqi<mode>2_dot2"
980  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
981	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
982		    (const_int 0)))
983   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
984	(sign_extend:EXTQI (match_dup 1)))]
985  ""
986  "@
987   extsb. %0,%1
988   #"
989  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
990  [(set (match_dup 0)
991	(sign_extend:EXTQI (match_dup 1)))
992   (set (match_dup 2)
993	(compare:CC (match_dup 0)
994		    (const_int 0)))]
995  ""
996  [(set_attr "type" "exts")
997   (set_attr "dot" "yes")
998   (set_attr "length" "4,8")])
999
1000
1001(define_expand "extendhi<mode>2"
1002  [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1003	(sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1004  ""
1005  "")
1006
1007(define_insn "*extendhi<mode>2"
1008  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1009	(sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1010  ""
1011  "@
1012   lha%U1%X1 %0,%1
1013   extsh %0,%1
1014   #
1015   vextsh2d %0,%1"
1016  [(set_attr "type" "load,exts,fpload,vecperm")
1017   (set_attr "sign_extend" "yes")
1018   (set_attr "length" "*,*,8,*")
1019   (set_attr "isa" "*,*,p9v,p9v")])
1020
1021(define_split
1022  [(set (match_operand:EXTHI 0 "altivec_register_operand")
1023	(sign_extend:EXTHI
1024	 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1025  "TARGET_P9_VECTOR && reload_completed"
1026  [(set (match_dup 2)
1027	(match_dup 1))
1028   (set (match_dup 0)
1029	(sign_extend:EXTHI (match_dup 2)))]
1030{
1031  operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1032})
1033
1034(define_insn_and_split "*extendhi<mode>2_dot"
1035  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1036	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1037		    (const_int 0)))
1038   (clobber (match_scratch:EXTHI 0 "=r,r"))]
1039  ""
1040  "@
1041   extsh. %0,%1
1042   #"
1043  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1044  [(set (match_dup 0)
1045	(sign_extend:EXTHI (match_dup 1)))
1046   (set (match_dup 2)
1047	(compare:CC (match_dup 0)
1048		    (const_int 0)))]
1049  ""
1050  [(set_attr "type" "exts")
1051   (set_attr "dot" "yes")
1052   (set_attr "length" "4,8")])
1053
1054(define_insn_and_split "*extendhi<mode>2_dot2"
1055  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1056	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1057		    (const_int 0)))
1058   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1059	(sign_extend:EXTHI (match_dup 1)))]
1060  ""
1061  "@
1062   extsh. %0,%1
1063   #"
1064  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1065  [(set (match_dup 0)
1066	(sign_extend:EXTHI (match_dup 1)))
1067   (set (match_dup 2)
1068	(compare:CC (match_dup 0)
1069		    (const_int 0)))]
1070  ""
1071  [(set_attr "type" "exts")
1072   (set_attr "dot" "yes")
1073   (set_attr "length" "4,8")])
1074
1075
1076(define_insn "extendsi<mode>2"
1077  [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1078		     "=r, r,   d,     wa,    wa,    v,      v,     wr")
1079	(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1080		     "YZ, r,   Z,     Z,     r,     v,      v,     ?wa")))]
1081  ""
1082  "@
1083   lwa%U1%X1 %0,%1
1084   extsw %0,%1
1085   lfiwax %0,%y1
1086   lxsiwax %x0,%y1
1087   mtvsrwa %x0,%1
1088   vextsw2d %0,%1
1089   #
1090   #"
1091  [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1092   (set_attr "sign_extend" "yes")
1093   (set_attr "length" "*,*,*,*,*,*,8,8")
1094   (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1095
1096(define_split
1097  [(set (match_operand:EXTSI 0 "int_reg_operand")
1098	(sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1099  "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1100  [(set (match_dup 2)
1101	(match_dup 1))
1102   (set (match_dup 0)
1103	(sign_extend:DI (match_dup 2)))]
1104{
1105  operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1106})
1107
1108(define_split
1109  [(set (match_operand:DI 0 "altivec_register_operand")
1110	(sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1111  "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1112  [(const_int 0)]
1113{
1114  rtx dest = operands[0];
1115  rtx src = operands[1];
1116  int dest_regno = REGNO (dest);
1117  int src_regno = REGNO (src);
1118  rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1119  rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1120
1121  if (BYTES_BIG_ENDIAN)
1122    {
1123      emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1124      emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1125    }
1126  else
1127    {
1128      emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1129      emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1130    }
1131  DONE;
1132})
1133
1134(define_insn_and_split "*extendsi<mode>2_dot"
1135  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1136	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1137		    (const_int 0)))
1138   (clobber (match_scratch:EXTSI 0 "=r,r"))]
1139  ""
1140  "@
1141   extsw. %0,%1
1142   #"
1143  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1144  [(set (match_dup 0)
1145	(sign_extend:EXTSI (match_dup 1)))
1146   (set (match_dup 2)
1147	(compare:CC (match_dup 0)
1148		    (const_int 0)))]
1149  ""
1150  [(set_attr "type" "exts")
1151   (set_attr "dot" "yes")
1152   (set_attr "length" "4,8")])
1153
1154(define_insn_and_split "*extendsi<mode>2_dot2"
1155  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1156	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1157		    (const_int 0)))
1158   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1159	(sign_extend:EXTSI (match_dup 1)))]
1160  ""
1161  "@
1162   extsw. %0,%1
1163   #"
1164  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1165  [(set (match_dup 0)
1166	(sign_extend:EXTSI (match_dup 1)))
1167   (set (match_dup 2)
1168	(compare:CC (match_dup 0)
1169		    (const_int 0)))]
1170  ""
1171  [(set_attr "type" "exts")
1172   (set_attr "dot" "yes")
1173   (set_attr "length" "4,8")])
1174
1175;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1176
1177(define_insn "*macchwc"
1178  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1179        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1180                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1181                                       (const_int 16))
1182                                      (sign_extend:SI
1183                                       (match_operand:HI 1 "gpc_reg_operand" "r")))
1184                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1185                    (const_int 0)))
1186   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1187        (plus:SI (mult:SI (ashiftrt:SI
1188                           (match_dup 2)
1189                           (const_int 16))
1190                          (sign_extend:SI
1191                           (match_dup 1)))
1192                 (match_dup 4)))]
1193  "TARGET_MULHW"
1194  "macchw. %0,%1,%2"
1195  [(set_attr "type" "halfmul")])
1196
1197(define_insn "*macchw"
1198  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1199        (plus:SI (mult:SI (ashiftrt:SI
1200                           (match_operand:SI 2 "gpc_reg_operand" "r")
1201                           (const_int 16))
1202                          (sign_extend:SI
1203                           (match_operand:HI 1 "gpc_reg_operand" "r")))
1204                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1205  "TARGET_MULHW"
1206  "macchw %0,%1,%2"
1207  [(set_attr "type" "halfmul")])
1208
1209(define_insn "*macchwuc"
1210  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1211        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1212                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1213                                       (const_int 16))
1214                                      (zero_extend:SI
1215                                       (match_operand:HI 1 "gpc_reg_operand" "r")))
1216                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1217                    (const_int 0)))
1218   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1219        (plus:SI (mult:SI (lshiftrt:SI
1220                           (match_dup 2)
1221                           (const_int 16))
1222                          (zero_extend:SI
1223                           (match_dup 1)))
1224                 (match_dup 4)))]
1225  "TARGET_MULHW"
1226  "macchwu. %0,%1,%2"
1227  [(set_attr "type" "halfmul")])
1228
1229(define_insn "*macchwu"
1230  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1231        (plus:SI (mult:SI (lshiftrt:SI
1232                           (match_operand:SI 2 "gpc_reg_operand" "r")
1233                           (const_int 16))
1234                          (zero_extend:SI
1235                           (match_operand:HI 1 "gpc_reg_operand" "r")))
1236                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1237  "TARGET_MULHW"
1238  "macchwu %0,%1,%2"
1239  [(set_attr "type" "halfmul")])
1240
1241(define_insn "*machhwc"
1242  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1243        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1244                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
1245                                       (const_int 16))
1246                                      (ashiftrt:SI
1247                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1248                                       (const_int 16)))
1249                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1250                    (const_int 0)))
1251   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1252        (plus:SI (mult:SI (ashiftrt:SI
1253                           (match_dup 1)
1254                           (const_int 16))
1255                          (ashiftrt:SI
1256                           (match_dup 2)
1257                           (const_int 16)))
1258                 (match_dup 4)))]
1259  "TARGET_MULHW"
1260  "machhw. %0,%1,%2"
1261  [(set_attr "type" "halfmul")])
1262
1263(define_insn "*machhw"
1264  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265        (plus:SI (mult:SI (ashiftrt:SI
1266                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1267                           (const_int 16))
1268                          (ashiftrt:SI
1269                           (match_operand:SI 2 "gpc_reg_operand" "r")
1270                           (const_int 16)))
1271                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1272  "TARGET_MULHW"
1273  "machhw %0,%1,%2"
1274  [(set_attr "type" "halfmul")])
1275
1276(define_insn "*machhwuc"
1277  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1278        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1279                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
1280                                       (const_int 16))
1281                                      (lshiftrt:SI
1282                                       (match_operand:SI 2 "gpc_reg_operand" "r")
1283                                       (const_int 16)))
1284                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1285                    (const_int 0)))
1286   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1287        (plus:SI (mult:SI (lshiftrt:SI
1288                           (match_dup 1)
1289                           (const_int 16))
1290                          (lshiftrt:SI
1291                           (match_dup 2)
1292                           (const_int 16)))
1293                 (match_dup 4)))]
1294  "TARGET_MULHW"
1295  "machhwu. %0,%1,%2"
1296  [(set_attr "type" "halfmul")])
1297
1298(define_insn "*machhwu"
1299  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300        (plus:SI (mult:SI (lshiftrt:SI
1301                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1302                           (const_int 16))
1303                          (lshiftrt:SI
1304                           (match_operand:SI 2 "gpc_reg_operand" "r")
1305                           (const_int 16)))
1306                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1307  "TARGET_MULHW"
1308  "machhwu %0,%1,%2"
1309  [(set_attr "type" "halfmul")])
1310
1311(define_insn "*maclhwc"
1312  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1313        (compare:CC (plus:SI (mult:SI (sign_extend:SI
1314                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1315                                      (sign_extend:SI
1316                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1317                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1318                    (const_int 0)))
1319   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1320        (plus:SI (mult:SI (sign_extend:SI
1321                           (match_dup 1))
1322                          (sign_extend:SI
1323                           (match_dup 2)))
1324                 (match_dup 4)))]
1325  "TARGET_MULHW"
1326  "maclhw. %0,%1,%2"
1327  [(set_attr "type" "halfmul")])
1328
1329(define_insn "*maclhw"
1330  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1331        (plus:SI (mult:SI (sign_extend:SI
1332                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1333                          (sign_extend:SI
1334                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1335                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1336  "TARGET_MULHW"
1337  "maclhw %0,%1,%2"
1338  [(set_attr "type" "halfmul")])
1339
1340(define_insn "*maclhwuc"
1341  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1342        (compare:CC (plus:SI (mult:SI (zero_extend:SI
1343                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1344                                      (zero_extend:SI
1345                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1346                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1347                    (const_int 0)))
1348   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1349        (plus:SI (mult:SI (zero_extend:SI
1350                           (match_dup 1))
1351                          (zero_extend:SI
1352                           (match_dup 2)))
1353                 (match_dup 4)))]
1354  "TARGET_MULHW"
1355  "maclhwu. %0,%1,%2"
1356  [(set_attr "type" "halfmul")])
1357
1358(define_insn "*maclhwu"
1359  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1360        (plus:SI (mult:SI (zero_extend:SI
1361                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1362                          (zero_extend:SI
1363                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1364                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1365  "TARGET_MULHW"
1366  "maclhwu %0,%1,%2"
1367  [(set_attr "type" "halfmul")])
1368
1369(define_insn "*nmacchwc"
1370  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1371        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1372                              (mult:SI (ashiftrt:SI
1373                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1374                                        (const_int 16))
1375                                       (sign_extend:SI
1376                                        (match_operand:HI 1 "gpc_reg_operand" "r"))))
1377                    (const_int 0)))
1378   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1379        (minus:SI (match_dup 4)
1380                  (mult:SI (ashiftrt:SI
1381                            (match_dup 2)
1382                            (const_int 16))
1383                           (sign_extend:SI
1384                            (match_dup 1)))))]
1385  "TARGET_MULHW"
1386  "nmacchw. %0,%1,%2"
1387  [(set_attr "type" "halfmul")])
1388
1389(define_insn "*nmacchw"
1390  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1391        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1392                  (mult:SI (ashiftrt:SI
1393                            (match_operand:SI 2 "gpc_reg_operand" "r")
1394                            (const_int 16))
1395                           (sign_extend:SI
1396                            (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1397  "TARGET_MULHW"
1398  "nmacchw %0,%1,%2"
1399  [(set_attr "type" "halfmul")])
1400
1401(define_insn "*nmachhwc"
1402  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1403        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1404                              (mult:SI (ashiftrt:SI
1405                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1406                                        (const_int 16))
1407                                       (ashiftrt:SI
1408                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1409                                        (const_int 16))))
1410                    (const_int 0)))
1411   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1412        (minus:SI (match_dup 4)
1413                  (mult:SI (ashiftrt:SI
1414                            (match_dup 1)
1415                            (const_int 16))
1416                           (ashiftrt:SI
1417                            (match_dup 2)
1418                            (const_int 16)))))]
1419  "TARGET_MULHW"
1420  "nmachhw. %0,%1,%2"
1421  [(set_attr "type" "halfmul")])
1422
1423(define_insn "*nmachhw"
1424  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1425        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1426                  (mult:SI (ashiftrt:SI
1427                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1428                            (const_int 16))
1429                           (ashiftrt:SI
1430                            (match_operand:SI 2 "gpc_reg_operand" "r")
1431                            (const_int 16)))))]
1432  "TARGET_MULHW"
1433  "nmachhw %0,%1,%2"
1434  [(set_attr "type" "halfmul")])
1435
1436(define_insn "*nmaclhwc"
1437  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1438        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1439                              (mult:SI (sign_extend:SI
1440                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1441                                       (sign_extend:SI
1442                                        (match_operand:HI 2 "gpc_reg_operand" "r"))))
1443                    (const_int 0)))
1444   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1445        (minus:SI (match_dup 4)
1446                  (mult:SI (sign_extend:SI
1447                            (match_dup 1))
1448                           (sign_extend:SI
1449                            (match_dup 2)))))]
1450  "TARGET_MULHW"
1451  "nmaclhw. %0,%1,%2"
1452  [(set_attr "type" "halfmul")])
1453
1454(define_insn "*nmaclhw"
1455  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1456        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1457                  (mult:SI (sign_extend:SI
1458                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1459                           (sign_extend:SI
1460                            (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1461  "TARGET_MULHW"
1462  "nmaclhw %0,%1,%2"
1463  [(set_attr "type" "halfmul")])
1464
1465(define_insn "*mulchwc"
1466  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1467        (compare:CC (mult:SI (ashiftrt:SI
1468                              (match_operand:SI 2 "gpc_reg_operand" "r")
1469                              (const_int 16))
1470                             (sign_extend:SI
1471                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1472                    (const_int 0)))
1473   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1474        (mult:SI (ashiftrt:SI
1475                  (match_dup 2)
1476                  (const_int 16))
1477                 (sign_extend:SI
1478                  (match_dup 1))))]
1479  "TARGET_MULHW"
1480  "mulchw. %0,%1,%2"
1481  [(set_attr "type" "halfmul")])
1482
1483(define_insn "*mulchw"
1484  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1485        (mult:SI (ashiftrt:SI
1486                  (match_operand:SI 2 "gpc_reg_operand" "r")
1487                  (const_int 16))
1488                 (sign_extend:SI
1489                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1490  "TARGET_MULHW"
1491  "mulchw %0,%1,%2"
1492  [(set_attr "type" "halfmul")])
1493
1494(define_insn "*mulchwuc"
1495  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1496        (compare:CC (mult:SI (lshiftrt:SI
1497                              (match_operand:SI 2 "gpc_reg_operand" "r")
1498                              (const_int 16))
1499                             (zero_extend:SI
1500                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1501                    (const_int 0)))
1502   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1503        (mult:SI (lshiftrt:SI
1504                  (match_dup 2)
1505                  (const_int 16))
1506                 (zero_extend:SI
1507                  (match_dup 1))))]
1508  "TARGET_MULHW"
1509  "mulchwu. %0,%1,%2"
1510  [(set_attr "type" "halfmul")])
1511
1512(define_insn "*mulchwu"
1513  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1514        (mult:SI (lshiftrt:SI
1515                  (match_operand:SI 2 "gpc_reg_operand" "r")
1516                  (const_int 16))
1517                 (zero_extend:SI
1518                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1519  "TARGET_MULHW"
1520  "mulchwu %0,%1,%2"
1521  [(set_attr "type" "halfmul")])
1522
1523(define_insn "*mulhhwc"
1524  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1525        (compare:CC (mult:SI (ashiftrt:SI
1526                              (match_operand:SI 1 "gpc_reg_operand" "%r")
1527                              (const_int 16))
1528                             (ashiftrt:SI
1529                              (match_operand:SI 2 "gpc_reg_operand" "r")
1530                              (const_int 16)))
1531                    (const_int 0)))
1532   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1533        (mult:SI (ashiftrt:SI
1534                  (match_dup 1)
1535                  (const_int 16))
1536                 (ashiftrt:SI
1537                  (match_dup 2)
1538                  (const_int 16))))]
1539  "TARGET_MULHW"
1540  "mulhhw. %0,%1,%2"
1541  [(set_attr "type" "halfmul")])
1542
1543(define_insn "*mulhhw"
1544  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1545        (mult:SI (ashiftrt:SI
1546                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1547                  (const_int 16))
1548                 (ashiftrt:SI
1549                  (match_operand:SI 2 "gpc_reg_operand" "r")
1550                  (const_int 16))))]
1551  "TARGET_MULHW"
1552  "mulhhw %0,%1,%2"
1553  [(set_attr "type" "halfmul")])
1554
1555(define_insn "*mulhhwuc"
1556  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1557        (compare:CC (mult:SI (lshiftrt:SI
1558                              (match_operand:SI 1 "gpc_reg_operand" "%r")
1559                              (const_int 16))
1560                             (lshiftrt:SI
1561                              (match_operand:SI 2 "gpc_reg_operand" "r")
1562                              (const_int 16)))
1563                    (const_int 0)))
1564   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1565        (mult:SI (lshiftrt:SI
1566                  (match_dup 1)
1567                  (const_int 16))
1568                 (lshiftrt:SI
1569                  (match_dup 2)
1570                  (const_int 16))))]
1571  "TARGET_MULHW"
1572  "mulhhwu. %0,%1,%2"
1573  [(set_attr "type" "halfmul")])
1574
1575(define_insn "*mulhhwu"
1576  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1577        (mult:SI (lshiftrt:SI
1578                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1579                  (const_int 16))
1580                 (lshiftrt:SI
1581                  (match_operand:SI 2 "gpc_reg_operand" "r")
1582                  (const_int 16))))]
1583  "TARGET_MULHW"
1584  "mulhhwu %0,%1,%2"
1585  [(set_attr "type" "halfmul")])
1586
1587(define_insn "*mullhwc"
1588  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1589        (compare:CC (mult:SI (sign_extend:SI
1590                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1591                             (sign_extend:SI
1592                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1593                    (const_int 0)))
1594   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1595        (mult:SI (sign_extend:SI
1596                  (match_dup 1))
1597                 (sign_extend:SI
1598                  (match_dup 2))))]
1599  "TARGET_MULHW"
1600  "mullhw. %0,%1,%2"
1601  [(set_attr "type" "halfmul")])
1602
1603(define_insn "*mullhw"
1604  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1605        (mult:SI (sign_extend:SI
1606                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1607                 (sign_extend:SI
1608                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1609  "TARGET_MULHW"
1610  "mullhw %0,%1,%2"
1611  [(set_attr "type" "halfmul")])
1612
1613(define_insn "*mullhwuc"
1614  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1615        (compare:CC (mult:SI (zero_extend:SI
1616                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1617                             (zero_extend:SI
1618                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1619                    (const_int 0)))
1620   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1621        (mult:SI (zero_extend:SI
1622                  (match_dup 1))
1623                 (zero_extend:SI
1624                  (match_dup 2))))]
1625  "TARGET_MULHW"
1626  "mullhwu. %0,%1,%2"
1627  [(set_attr "type" "halfmul")])
1628
1629(define_insn "*mullhwu"
1630  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1631        (mult:SI (zero_extend:SI
1632                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1633                 (zero_extend:SI
1634                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1635  "TARGET_MULHW"
1636  "mullhwu %0,%1,%2"
1637  [(set_attr "type" "halfmul")])
1638
1639;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1640(define_insn "dlmzb"
1641  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1642        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1643                    (match_operand:SI 2 "gpc_reg_operand" "r")]
1644                   UNSPEC_DLMZB_CR))
1645   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1646        (unspec:SI [(match_dup 1)
1647                    (match_dup 2)]
1648                   UNSPEC_DLMZB))]
1649  "TARGET_DLMZB"
1650  "dlmzb. %0,%1,%2")
1651
1652(define_expand "strlensi"
1653  [(set (match_operand:SI 0 "gpc_reg_operand")
1654        (unspec:SI [(match_operand:BLK 1 "general_operand")
1655                    (match_operand:QI 2 "const_int_operand")
1656                    (match_operand 3 "const_int_operand")]
1657                   UNSPEC_DLMZB_STRLEN))
1658   (clobber (match_scratch:CC 4))]
1659  "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1660{
1661  rtx result = operands[0];
1662  rtx src = operands[1];
1663  rtx search_char = operands[2];
1664  rtx align = operands[3];
1665  rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1666  rtx loop_label, end_label, mem, cr0, cond;
1667  if (search_char != const0_rtx
1668      || !CONST_INT_P (align)
1669      || INTVAL (align) < 8)
1670        FAIL;
1671  word1 = gen_reg_rtx (SImode);
1672  word2 = gen_reg_rtx (SImode);
1673  scratch_dlmzb = gen_reg_rtx (SImode);
1674  scratch_string = gen_reg_rtx (Pmode);
1675  loop_label = gen_label_rtx ();
1676  end_label = gen_label_rtx ();
1677  addr = force_reg (Pmode, XEXP (src, 0));
1678  emit_move_insn (scratch_string, addr);
1679  emit_label (loop_label);
1680  mem = change_address (src, SImode, scratch_string);
1681  emit_move_insn (word1, mem);
1682  emit_move_insn (word2, adjust_address (mem, SImode, 4));
1683  cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1684  emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1685  cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1686  emit_jump_insn (gen_rtx_SET (pc_rtx,
1687                               gen_rtx_IF_THEN_ELSE (VOIDmode,
1688                                                     cond,
1689                                                     gen_rtx_LABEL_REF
1690                                                       (VOIDmode,
1691                                                        end_label),
1692                                                     pc_rtx)));
1693  emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1694  emit_jump_insn (gen_rtx_SET (pc_rtx,
1695                               gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1696  emit_barrier ();
1697  emit_label (end_label);
1698  emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1699  emit_insn (gen_subsi3 (result, scratch_string, addr));
1700  emit_insn (gen_addsi3 (result, result, constm1_rtx));
1701  DONE;
1702})
1703
1704;; Fixed-point arithmetic insns.
1705
1706(define_expand "add<mode>3"
1707  [(set (match_operand:SDI 0 "gpc_reg_operand")
1708	(plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1709		  (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1710  ""
1711{
1712  if (<MODE>mode == DImode && !TARGET_POWERPC64)
1713    {
1714      rtx lo0 = gen_lowpart (SImode, operands[0]);
1715      rtx lo1 = gen_lowpart (SImode, operands[1]);
1716      rtx lo2 = gen_lowpart (SImode, operands[2]);
1717      rtx hi0 = gen_highpart (SImode, operands[0]);
1718      rtx hi1 = gen_highpart (SImode, operands[1]);
1719      rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1720
1721      if (!reg_or_short_operand (lo2, SImode))
1722	lo2 = force_reg (SImode, lo2);
1723      if (!adde_operand (hi2, SImode))
1724	hi2 = force_reg (SImode, hi2);
1725
1726      emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1727      emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1728      DONE;
1729    }
1730
1731  if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1732    {
1733      rtx tmp = ((!can_create_pseudo_p ()
1734		  || rtx_equal_p (operands[0], operands[1]))
1735		 ? operands[0] : gen_reg_rtx (<MODE>mode));
1736
1737      /* Adding a constant to r0 is not a valid insn, so use a different
1738	 strategy in that case.  */
1739      if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1740	{
1741	  if (operands[0] == operands[1])
1742	    FAIL;
1743	  rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1744	  emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1745	  DONE;
1746	}
1747
1748      HOST_WIDE_INT val = INTVAL (operands[2]);
1749      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1750      HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1751
1752      if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1753	FAIL;
1754
1755      /* The ordering here is important for the prolog expander.
1756	 When space is allocated from the stack, adding 'low' first may
1757	 produce a temporary deallocation (which would be bad).  */
1758      emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1759      emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1760      DONE;
1761    }
1762})
1763
1764(define_insn "*add<mode>3"
1765  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1766	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1767		  (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1768  ""
1769  "@
1770   add %0,%1,%2
1771   addi %0,%1,%2
1772   addis %0,%1,%v2
1773   addi %0,%1,%2"
1774  [(set_attr "type" "add")
1775   (set_attr "isa" "*,*,*,p10")])
1776
1777(define_insn "*addsi3_high"
1778  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1779        (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1780                 (high:SI (match_operand 2 "" ""))))]
1781  "TARGET_MACHO && !TARGET_64BIT"
1782  "addis %0,%1,ha16(%2)"
1783  [(set_attr "type" "add")])
1784
1785(define_insn_and_split "*add<mode>3_dot"
1786  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1787	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1788			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1789		    (const_int 0)))
1790   (clobber (match_scratch:GPR 0 "=r,r"))]
1791  "<MODE>mode == Pmode"
1792  "@
1793   add. %0,%1,%2
1794   #"
1795  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1796  [(set (match_dup 0)
1797	(plus:GPR (match_dup 1)
1798		 (match_dup 2)))
1799   (set (match_dup 3)
1800	(compare:CC (match_dup 0)
1801		    (const_int 0)))]
1802  ""
1803  [(set_attr "type" "add")
1804   (set_attr "dot" "yes")
1805   (set_attr "length" "4,8")])
1806
1807(define_insn_and_split "*add<mode>3_dot2"
1808  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1809	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1810			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1811		    (const_int 0)))
1812   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1813	(plus:GPR (match_dup 1)
1814		  (match_dup 2)))]
1815  "<MODE>mode == Pmode"
1816  "@
1817   add. %0,%1,%2
1818   #"
1819  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1820  [(set (match_dup 0)
1821	(plus:GPR (match_dup 1)
1822		  (match_dup 2)))
1823   (set (match_dup 3)
1824	(compare:CC (match_dup 0)
1825		    (const_int 0)))]
1826  ""
1827  [(set_attr "type" "add")
1828   (set_attr "dot" "yes")
1829   (set_attr "length" "4,8")])
1830
1831(define_insn_and_split "*add<mode>3_imm_dot"
1832  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1833	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1834			      (match_operand:GPR 2 "short_cint_operand" "I,I"))
1835		    (const_int 0)))
1836   (clobber (match_scratch:GPR 0 "=r,r"))
1837   (clobber (reg:GPR CA_REGNO))]
1838  "<MODE>mode == Pmode"
1839  "@
1840   addic. %0,%1,%2
1841   #"
1842  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1843  [(set (match_dup 0)
1844	(plus:GPR (match_dup 1)
1845		  (match_dup 2)))
1846   (set (match_dup 3)
1847	(compare:CC (match_dup 0)
1848		    (const_int 0)))]
1849  ""
1850  [(set_attr "type" "add")
1851   (set_attr "dot" "yes")
1852   (set_attr "length" "4,8")])
1853
1854(define_insn_and_split "*add<mode>3_imm_dot2"
1855  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1856	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1857			      (match_operand:GPR 2 "short_cint_operand" "I,I"))
1858		    (const_int 0)))
1859   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1860	(plus:GPR (match_dup 1)
1861		  (match_dup 2)))
1862   (clobber (reg:GPR CA_REGNO))]
1863  "<MODE>mode == Pmode"
1864  "@
1865   addic. %0,%1,%2
1866   #"
1867  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1868  [(set (match_dup 0)
1869	(plus:GPR (match_dup 1)
1870		  (match_dup 2)))
1871   (set (match_dup 3)
1872	(compare:CC (match_dup 0)
1873		    (const_int 0)))]
1874  ""
1875  [(set_attr "type" "add")
1876   (set_attr "dot" "yes")
1877   (set_attr "length" "4,8")])
1878
1879;; Split an add that we can't do in one insn into two insns, each of which
1880;; does one 16-bit part.  This is used by combine.  Note that the low-order
1881;; add should be last in case the result gets used in an address.
1882
1883(define_split
1884  [(set (match_operand:GPR 0 "gpc_reg_operand")
1885	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1886		  (match_operand:GPR 2 "non_add_cint_operand")))]
1887  ""
1888  [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1889   (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1890{
1891  HOST_WIDE_INT val = INTVAL (operands[2]);
1892  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1893  HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1894
1895  operands[4] = GEN_INT (low);
1896  if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1897    operands[3] = GEN_INT (rest);
1898  else if (can_create_pseudo_p ())
1899    {
1900      operands[3] = gen_reg_rtx (DImode);
1901      emit_move_insn (operands[3], operands[2]);
1902      emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1903      DONE;
1904    }
1905  else
1906    FAIL;
1907})
1908
1909
1910(define_insn "add<mode>3_carry"
1911  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1912	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1913		(match_operand:P 2 "reg_or_short_operand" "rI")))
1914   (set (reg:P CA_REGNO)
1915	(ltu:P (plus:P (match_dup 1)
1916		       (match_dup 2))
1917	       (match_dup 1)))]
1918  ""
1919  "add%I2c %0,%1,%2"
1920  [(set_attr "type" "add")])
1921
1922(define_insn "*add<mode>3_imm_carry_pos"
1923  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1924	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1925		(match_operand:P 2 "short_cint_operand" "n")))
1926   (set (reg:P CA_REGNO)
1927	(geu:P (match_dup 1)
1928	       (match_operand:P 3 "const_int_operand" "n")))]
1929  "INTVAL (operands[2]) > 0
1930   && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1931  "addic %0,%1,%2"
1932  [(set_attr "type" "add")])
1933
1934(define_insn "*add<mode>3_imm_carry_0"
1935  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1936	(match_operand:P 1 "gpc_reg_operand" "r"))
1937   (set (reg:P CA_REGNO)
1938	(const_int 0))]
1939  ""
1940  "addic %0,%1,0"
1941  [(set_attr "type" "add")])
1942
1943(define_insn "*add<mode>3_imm_carry_m1"
1944  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1945	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1946		(const_int -1)))
1947   (set (reg:P CA_REGNO)
1948	(ne:P (match_dup 1)
1949	      (const_int 0)))]
1950  ""
1951  "addic %0,%1,-1"
1952  [(set_attr "type" "add")])
1953
1954(define_insn "*add<mode>3_imm_carry_neg"
1955  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1956	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1957		(match_operand:P 2 "short_cint_operand" "n")))
1958   (set (reg:P CA_REGNO)
1959	(gtu:P (match_dup 1)
1960	       (match_operand:P 3 "const_int_operand" "n")))]
1961  "INTVAL (operands[2]) < 0
1962   && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1963  "addic %0,%1,%2"
1964  [(set_attr "type" "add")])
1965
1966
1967(define_expand "add<mode>3_carry_in"
1968  [(parallel [
1969     (set (match_operand:GPR 0 "gpc_reg_operand")
1970	  (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1971			      (match_operand:GPR 2 "adde_operand"))
1972		    (reg:GPR CA_REGNO)))
1973     (clobber (reg:GPR CA_REGNO))])]
1974  ""
1975{
1976  if (operands[2] == const0_rtx)
1977    {
1978      emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1979      DONE;
1980    }
1981  if (operands[2] == constm1_rtx)
1982    {
1983      emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1984      DONE;
1985    }
1986})
1987
1988(define_insn "*add<mode>3_carry_in_internal"
1989  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1990	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1991			    (match_operand:GPR 2 "gpc_reg_operand" "r"))
1992		  (reg:GPR CA_REGNO)))
1993   (clobber (reg:GPR CA_REGNO))]
1994  ""
1995  "adde %0,%1,%2"
1996  [(set_attr "type" "add")])
1997
1998(define_insn "*add<mode>3_carry_in_internal2"
1999  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2000	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2001			    (reg:GPR CA_REGNO))
2002		  (match_operand:GPR 2 "gpc_reg_operand" "r")))
2003   (clobber (reg:GPR CA_REGNO))]
2004  ""
2005  "adde %0,%1,%2"
2006  [(set_attr "type" "add")])
2007
2008(define_insn "add<mode>3_carry_in_0"
2009  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2010	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2011		  (reg:GPR CA_REGNO)))
2012   (clobber (reg:GPR CA_REGNO))]
2013  ""
2014  "addze %0,%1"
2015  [(set_attr "type" "add")])
2016
2017(define_insn "add<mode>3_carry_in_m1"
2018  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2019	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2020			    (reg:GPR CA_REGNO))
2021		  (const_int -1)))
2022   (clobber (reg:GPR CA_REGNO))]
2023  ""
2024  "addme %0,%1"
2025  [(set_attr "type" "add")])
2026
2027
2028(define_expand "one_cmpl<mode>2"
2029  [(set (match_operand:SDI 0 "gpc_reg_operand")
2030	(not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2031  ""
2032{
2033  if (<MODE>mode == DImode && !TARGET_POWERPC64)
2034    {
2035      rs6000_split_logical (operands, NOT, false, false, false);
2036      DONE;
2037    }
2038})
2039
2040(define_insn "*one_cmpl<mode>2"
2041  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2042	(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2043  ""
2044  "not %0,%1")
2045
2046(define_insn_and_split "*one_cmpl<mode>2_dot"
2047  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2048	(compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2049		    (const_int 0)))
2050   (clobber (match_scratch:GPR 0 "=r,r"))]
2051  "<MODE>mode == Pmode"
2052  "@
2053   not. %0,%1
2054   #"
2055  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2056  [(set (match_dup 0)
2057	(not:GPR (match_dup 1)))
2058   (set (match_dup 2)
2059	(compare:CC (match_dup 0)
2060		    (const_int 0)))]
2061  ""
2062  [(set_attr "type" "logical")
2063   (set_attr "dot" "yes")
2064   (set_attr "length" "4,8")])
2065
2066(define_insn_and_split "*one_cmpl<mode>2_dot2"
2067  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2068	(compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2069		    (const_int 0)))
2070   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2071	(not:GPR (match_dup 1)))]
2072  "<MODE>mode == Pmode"
2073  "@
2074   not. %0,%1
2075   #"
2076  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2077  [(set (match_dup 0)
2078	(not:GPR (match_dup 1)))
2079   (set (match_dup 2)
2080	(compare:CC (match_dup 0)
2081		    (const_int 0)))]
2082  ""
2083  [(set_attr "type" "logical")
2084   (set_attr "dot" "yes")
2085   (set_attr "length" "4,8")])
2086
2087
2088(define_expand "sub<mode>3"
2089  [(set (match_operand:SDI 0 "gpc_reg_operand")
2090	(minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2091		   (match_operand:SDI 2 "gpc_reg_operand")))]
2092  ""
2093{
2094  if (<MODE>mode == DImode && !TARGET_POWERPC64)
2095    {
2096      rtx lo0 = gen_lowpart (SImode, operands[0]);
2097      rtx lo1 = gen_lowpart (SImode, operands[1]);
2098      rtx lo2 = gen_lowpart (SImode, operands[2]);
2099      rtx hi0 = gen_highpart (SImode, operands[0]);
2100      rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2101      rtx hi2 = gen_highpart (SImode, operands[2]);
2102
2103      if (!reg_or_short_operand (lo1, SImode))
2104	lo1 = force_reg (SImode, lo1);
2105      if (!adde_operand (hi1, SImode))
2106	hi1 = force_reg (SImode, hi1);
2107
2108      emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2109      emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2110      DONE;
2111    }
2112
2113  if (short_cint_operand (operands[1], <MODE>mode))
2114    {
2115      emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2116      DONE;
2117    }
2118})
2119
2120(define_insn "*subf<mode>3"
2121  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2122	(minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2123		   (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2124  ""
2125  "subf %0,%1,%2"
2126  [(set_attr "type" "add")])
2127
2128(define_insn_and_split "*subf<mode>3_dot"
2129  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2130	(compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2131			       (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2132		    (const_int 0)))
2133   (clobber (match_scratch:GPR 0 "=r,r"))]
2134  "<MODE>mode == Pmode"
2135  "@
2136   subf. %0,%1,%2
2137   #"
2138  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2139  [(set (match_dup 0)
2140	(minus:GPR (match_dup 2)
2141		   (match_dup 1)))
2142   (set (match_dup 3)
2143	(compare:CC (match_dup 0)
2144		    (const_int 0)))]
2145  ""
2146  [(set_attr "type" "add")
2147   (set_attr "dot" "yes")
2148   (set_attr "length" "4,8")])
2149
2150(define_insn_and_split "*subf<mode>3_dot2"
2151  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2152	(compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2153			       (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2154		    (const_int 0)))
2155   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2156	(minus:GPR (match_dup 2)
2157		   (match_dup 1)))]
2158  "<MODE>mode == Pmode"
2159  "@
2160   subf. %0,%1,%2
2161   #"
2162  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2163  [(set (match_dup 0)
2164	(minus:GPR (match_dup 2)
2165		   (match_dup 1)))
2166   (set (match_dup 3)
2167	(compare:CC (match_dup 0)
2168		    (const_int 0)))]
2169  ""
2170  [(set_attr "type" "add")
2171   (set_attr "dot" "yes")
2172   (set_attr "length" "4,8")])
2173
2174(define_insn "subf<mode>3_imm"
2175  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2176	(minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2177		   (match_operand:GPR 1 "gpc_reg_operand" "r")))
2178   (clobber (reg:GPR CA_REGNO))]
2179  ""
2180  "subfic %0,%1,%2"
2181  [(set_attr "type" "add")])
2182
2183(define_insn_and_split "subf<mode>3_carry_dot2"
2184  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2185	(compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2186			       (match_operand:P 1 "gpc_reg_operand" "r,r"))
2187		    (const_int 0)))
2188   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2189	(minus:P (match_dup 2)
2190		   (match_dup 1)))
2191   (set (reg:P CA_REGNO)
2192	(leu:P (match_dup 1)
2193	       (match_dup 2)))]
2194  "<MODE>mode == Pmode"
2195  "@
2196   subfc. %0,%1,%2
2197   #"
2198  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2199  [(parallel [(set (match_dup 0)
2200                   (minus:P (match_dup 2)
2201                            (match_dup 1)))
2202              (set (reg:P CA_REGNO)
2203                   (leu:P (match_dup 1)
2204                          (match_dup 2)))])
2205   (set (match_dup 3)
2206        (compare:CC (match_dup 0)
2207                    (const_int 0)))]
2208  ""
2209  [(set_attr "type" "add")
2210   (set_attr "dot" "yes")
2211   (set_attr "length" "4,8")])
2212
2213(define_insn "subf<mode>3_carry"
2214  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2215	(minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2216		 (match_operand:P 1 "gpc_reg_operand" "r")))
2217   (set (reg:P CA_REGNO)
2218	(leu:P (match_dup 1)
2219	       (match_dup 2)))]
2220  ""
2221  "subf%I2c %0,%1,%2"
2222  [(set_attr "type" "add")])
2223
2224(define_insn "*subf<mode>3_imm_carry_0"
2225  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2226	(neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2227   (set (reg:P CA_REGNO)
2228	(eq:P (match_dup 1)
2229	      (const_int 0)))]
2230  ""
2231  "subfic %0,%1,0"
2232  [(set_attr "type" "add")])
2233
2234(define_insn "*subf<mode>3_imm_carry_m1"
2235  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2236	(not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2237   (set (reg:P CA_REGNO)
2238	(const_int 1))]
2239  ""
2240  "subfic %0,%1,-1"
2241  [(set_attr "type" "add")])
2242
2243
2244(define_expand "subf<mode>3_carry_in"
2245  [(parallel [
2246     (set (match_operand:GPR 0 "gpc_reg_operand")
2247	  (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2248			      (reg:GPR CA_REGNO))
2249		    (match_operand:GPR 2 "adde_operand")))
2250     (clobber (reg:GPR CA_REGNO))])]
2251  ""
2252{
2253  if (operands[2] == const0_rtx)
2254    {
2255      emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2256      DONE;
2257    }
2258  if (operands[2] == constm1_rtx)
2259    {
2260      emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2261      DONE;
2262    }
2263})
2264
2265(define_insn "*subf<mode>3_carry_in_internal"
2266  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2267	(plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2268			    (reg:GPR CA_REGNO))
2269		  (match_operand:GPR 2 "gpc_reg_operand" "r")))
2270   (clobber (reg:GPR CA_REGNO))]
2271  ""
2272  "subfe %0,%1,%2"
2273  [(set_attr "type" "add")])
2274
2275(define_insn "subf<mode>3_carry_in_0"
2276  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2277	(plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2278		  (reg:GPR CA_REGNO)))
2279   (clobber (reg:GPR CA_REGNO))]
2280  ""
2281  "subfze %0,%1"
2282  [(set_attr "type" "add")])
2283
2284(define_insn "subf<mode>3_carry_in_m1"
2285  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2286	(plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2287			     (match_operand:GPR 1 "gpc_reg_operand" "r"))
2288		  (const_int -2)))
2289   (clobber (reg:GPR CA_REGNO))]
2290  ""
2291  "subfme %0,%1"
2292  [(set_attr "type" "add")])
2293
2294(define_insn "subf<mode>3_carry_in_xx"
2295  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2296	(plus:GPR (reg:GPR CA_REGNO)
2297		  (const_int -1)))
2298   (clobber (reg:GPR CA_REGNO))]
2299  ""
2300  "subfe %0,%0,%0"
2301  [(set_attr "type" "add")])
2302
2303
2304(define_insn "@neg<mode>2"
2305  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2306	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2307  ""
2308  "neg %0,%1"
2309  [(set_attr "type" "add")])
2310
2311(define_insn_and_split "*neg<mode>2_dot"
2312  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2313	(compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2314		    (const_int 0)))
2315   (clobber (match_scratch:GPR 0 "=r,r"))]
2316  "<MODE>mode == Pmode"
2317  "@
2318   neg. %0,%1
2319   #"
2320  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2321  [(set (match_dup 0)
2322	(neg:GPR (match_dup 1)))
2323   (set (match_dup 2)
2324	(compare:CC (match_dup 0)
2325		    (const_int 0)))]
2326  ""
2327  [(set_attr "type" "add")
2328   (set_attr "dot" "yes")
2329   (set_attr "length" "4,8")])
2330
2331(define_insn_and_split "*neg<mode>2_dot2"
2332  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2333	(compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2334		    (const_int 0)))
2335   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2336	(neg:GPR (match_dup 1)))]
2337  "<MODE>mode == Pmode"
2338  "@
2339   neg. %0,%1
2340   #"
2341  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2342  [(set (match_dup 0)
2343	(neg:GPR (match_dup 1)))
2344   (set (match_dup 2)
2345	(compare:CC (match_dup 0)
2346		    (const_int 0)))]
2347  ""
2348  [(set_attr "type" "add")
2349   (set_attr "dot" "yes")
2350   (set_attr "length" "4,8")])
2351
2352
2353(define_insn "clz<mode>2"
2354  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2355	(clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2356  ""
2357  "cntlz<wd> %0,%1"
2358  [(set_attr "type" "cntlz")])
2359
2360(define_expand "ctz<mode>2"
2361   [(set (match_operand:GPR 0 "gpc_reg_operand")
2362	 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2363  ""
2364{
2365  if (TARGET_CTZ)
2366    {
2367      emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2368      DONE;
2369    }
2370
2371  rtx tmp1 = gen_reg_rtx (<MODE>mode);
2372  rtx tmp2 = gen_reg_rtx (<MODE>mode);
2373  rtx tmp3 = gen_reg_rtx (<MODE>mode);
2374
2375  if (TARGET_POPCNTD)
2376    {
2377      emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2378      emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2379      emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2380      emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2381    }
2382  else
2383    {
2384      emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2385      emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2386      emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2387      emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2388    }
2389
2390  DONE;
2391})
2392
2393(define_insn "ctz<mode>2_hw"
2394  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2395	(ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2396  "TARGET_CTZ"
2397  "cnttz<wd> %0,%1"
2398  [(set_attr "type" "cntlz")])
2399
2400(define_expand "ffs<mode>2"
2401  [(set (match_operand:GPR 0 "gpc_reg_operand")
2402	(ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2403  ""
2404{
2405  rtx tmp1 = gen_reg_rtx (<MODE>mode);
2406  rtx tmp2 = gen_reg_rtx (<MODE>mode);
2407  rtx tmp3 = gen_reg_rtx (<MODE>mode);
2408  emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2409  emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2410  emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2411  emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2412  DONE;
2413})
2414
2415
2416(define_expand "popcount<mode>2"
2417  [(set (match_operand:GPR 0 "gpc_reg_operand")
2418	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2419  "TARGET_POPCNTB || TARGET_POPCNTD"
2420{
2421  rs6000_emit_popcount (operands[0], operands[1]);
2422  DONE;
2423})
2424
2425(define_insn "popcntb<mode>2"
2426  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2427	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2428		    UNSPEC_POPCNTB))]
2429  "TARGET_POPCNTB"
2430  "popcntb %0,%1"
2431  [(set_attr "type" "popcnt")])
2432
2433(define_insn "popcntd<mode>2"
2434  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2435	(popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2436  "TARGET_POPCNTD"
2437  "popcnt<wd> %0,%1"
2438  [(set_attr "type" "popcnt")])
2439
2440
2441(define_expand "parity<mode>2"
2442  [(set (match_operand:GPR 0 "gpc_reg_operand")
2443	(parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2444  "TARGET_POPCNTB"
2445{
2446  rs6000_emit_parity (operands[0], operands[1]);
2447  DONE;
2448})
2449
2450(define_insn "parity<mode>2_cmpb"
2451  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2452	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2453  "TARGET_CMPB && TARGET_POPCNTB"
2454  "prty<wd> %0,%1"
2455  [(set_attr "type" "popcnt")])
2456
2457(define_insn "cmpb<mode>3"
2458  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2459	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2460		     (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2461  "TARGET_CMPB"
2462  "cmpb %0,%1,%2"
2463  [(set_attr "type" "cmp")])
2464
2465;; Since the hardware zeros the upper part of the register, save generating the
2466;; AND immediate if we are converting to unsigned
2467(define_insn "*bswap<mode>2_extenddi"
2468  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2469	(zero_extend:DI
2470	 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2471  "TARGET_POWERPC64"
2472  "l<wd>brx %0,%y1"
2473  [(set_attr "type" "load")])
2474
2475(define_insn "*bswaphi2_extendsi"
2476  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2477	(zero_extend:SI
2478	 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2479  ""
2480  "lhbrx %0,%y1"
2481  [(set_attr "type" "load")])
2482
2483;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2484;; the register allocator from converting a gpr<-gpr swap into a store and then
2485;; load with byte swap, which can be slower than doing it in the registers.  It
2486;; also prevents certain failures with the RELOAD register allocator.
2487
2488(define_expand "bswap<mode>2"
2489  [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2490   (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2491  ""
2492{
2493  rtx dest = operands[0];
2494  rtx src = operands[1];
2495
2496  if (!REG_P (dest) && !REG_P (src))
2497    src = force_reg (<MODE>mode, src);
2498
2499  if (MEM_P (src))
2500    {
2501      src = rs6000_force_indexed_or_indirect_mem (src);
2502      emit_insn (gen_bswap<mode>2_load (dest, src));
2503    }
2504  else if (MEM_P (dest))
2505    {
2506      dest = rs6000_force_indexed_or_indirect_mem (dest);
2507      emit_insn (gen_bswap<mode>2_store (dest, src));
2508    }
2509  else
2510    emit_insn (gen_bswap<mode>2_reg (dest, src));
2511  DONE;
2512})
2513
2514(define_insn "bswap<mode>2_load"
2515  [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2516	(bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2517  ""
2518  "l<wd>brx %0,%y1"
2519  [(set_attr "type" "load")])
2520
2521(define_insn "bswap<mode>2_store"
2522  [(set (match_operand:HSI 0 "memory_operand" "=Z")
2523	(bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2524  ""
2525  "st<wd>brx %1,%y0"
2526  [(set_attr "type" "store")])
2527
2528(define_insn_and_split "bswaphi2_reg"
2529  [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2530	(bswap:HI
2531	 (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2532   (clobber (match_scratch:SI 2 "=&r,X"))]
2533  ""
2534  "@
2535   #
2536   xxbrh %x0,%x1"
2537  "reload_completed && int_reg_operand (operands[0], HImode)"
2538  [(set (match_dup 3)
2539	(and:SI (lshiftrt:SI (match_dup 4)
2540			     (const_int 8))
2541		(const_int 255)))
2542   (set (match_dup 2)
2543	(and:SI (ashift:SI (match_dup 4)
2544			   (const_int 8))
2545		(const_int 65280)))		;; 0xff00
2546   (set (match_dup 3)
2547	(ior:SI (match_dup 3)
2548		(match_dup 2)))]
2549{
2550  operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2551  operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2552}
2553  [(set_attr "length" "12,4")
2554   (set_attr "type" "*,vecperm")
2555   (set_attr "isa" "*,p9v")])
2556
2557;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2558;; zero_extract insns do not change for -mlittle.
2559(define_insn_and_split "bswapsi2_reg"
2560  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2561	(bswap:SI
2562	 (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2563  ""
2564  "@
2565   #
2566   xxbrw %x0,%x1"
2567  "reload_completed && int_reg_operand (operands[0], SImode)"
2568  [(set (match_dup 0)					; DABC
2569	(rotate:SI (match_dup 1)
2570		   (const_int 24)))
2571   (set (match_dup 0)					; DCBC
2572	(ior:SI (and:SI (ashift:SI (match_dup 1)
2573				   (const_int 8))
2574			(const_int 16711680))
2575		(and:SI (match_dup 0)
2576			(const_int -16711681))))
2577   (set (match_dup 0)					; DCBA
2578	(ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2579				     (const_int 24))
2580			(const_int 255))
2581		(and:SI (match_dup 0)
2582			(const_int -256))))]
2583  ""
2584  [(set_attr "length" "12,4")
2585   (set_attr "type" "*,vecperm")
2586   (set_attr "isa" "*,p9v")])
2587
2588;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2589;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2590;; complex code.
2591
2592(define_expand "bswapdi2"
2593  [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2594		   (bswap:DI
2595		    (match_operand:DI 1 "reg_or_mem_operand")))
2596	      (clobber (match_scratch:DI 2))
2597	      (clobber (match_scratch:DI 3))])]
2598  ""
2599{
2600  rtx dest = operands[0];
2601  rtx src = operands[1];
2602
2603  if (!REG_P (dest) && !REG_P (src))
2604    operands[1] = src = force_reg (DImode, src);
2605
2606  if (TARGET_POWERPC64 && TARGET_LDBRX)
2607    {
2608      if (MEM_P (src))
2609        {
2610	  src = rs6000_force_indexed_or_indirect_mem (src);
2611	  emit_insn (gen_bswapdi2_load (dest, src));
2612        }
2613      else if (MEM_P (dest))
2614        {
2615	  dest = rs6000_force_indexed_or_indirect_mem (dest);
2616	  emit_insn (gen_bswapdi2_store (dest, src));
2617        }
2618      else if (TARGET_P9_VECTOR)
2619	emit_insn (gen_bswapdi2_xxbrd (dest, src));
2620      else
2621	emit_insn (gen_bswapdi2_reg (dest, src));
2622      DONE;
2623    }
2624
2625  if (!TARGET_POWERPC64)
2626    {
2627      /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2628	 that uses 64-bit registers needs the same scratch registers as 64-bit
2629	 mode.  */
2630      emit_insn (gen_bswapdi2_32bit (dest, src));
2631      DONE;
2632    }
2633})
2634
2635;; Power7/cell has ldbrx/stdbrx, so use it directly
2636(define_insn "bswapdi2_load"
2637  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2638	(bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2639  "TARGET_POWERPC64 && TARGET_LDBRX"
2640  "ldbrx %0,%y1"
2641  [(set_attr "type" "load")])
2642
2643(define_insn "bswapdi2_store"
2644  [(set (match_operand:DI 0 "memory_operand" "=Z")
2645	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2646  "TARGET_POWERPC64 && TARGET_LDBRX"
2647  "stdbrx %1,%y0"
2648  [(set_attr "type" "store")])
2649
2650(define_insn "bswapdi2_xxbrd"
2651  [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2652	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2653  "TARGET_P9_VECTOR"
2654  "xxbrd %x0,%x1"
2655  [(set_attr "type" "vecperm")
2656   (set_attr "isa" "p9v")])
2657
2658(define_insn "bswapdi2_reg"
2659  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2660	(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2661   (clobber (match_scratch:DI 2 "=&r"))
2662   (clobber (match_scratch:DI 3 "=&r"))]
2663  "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2664  "#"
2665  [(set_attr "length" "36")])
2666
2667;; Non-power7/cell, fall back to use lwbrx/stwbrx
2668(define_insn "*bswapdi2_64bit"
2669  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2670	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2671   (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2672   (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2673  "TARGET_POWERPC64 && !TARGET_LDBRX
2674   && (REG_P (operands[0]) || REG_P (operands[1]))
2675   && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2676   && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2677  "#"
2678  [(set_attr "length" "16,12,36")])
2679
2680(define_split
2681  [(set (match_operand:DI 0 "gpc_reg_operand")
2682	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2683   (clobber (match_operand:DI 2 "gpc_reg_operand"))
2684   (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2685  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2686  [(const_int 0)]
2687{
2688  rtx dest   = operands[0];
2689  rtx src    = operands[1];
2690  rtx op2    = operands[2];
2691  rtx op3    = operands[3];
2692  rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2693				    BYTES_BIG_ENDIAN ? 4 : 0);
2694  rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2695				     BYTES_BIG_ENDIAN ? 4 : 0);
2696  rtx addr1;
2697  rtx addr2;
2698  rtx word1;
2699  rtx word2;
2700
2701  addr1 = XEXP (src, 0);
2702  if (GET_CODE (addr1) == PLUS)
2703    {
2704      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2705      if (TARGET_AVOID_XFORM)
2706	{
2707	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2708	  addr2 = op2;
2709	}
2710      else
2711	addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2712    }
2713  else if (TARGET_AVOID_XFORM)
2714    {
2715      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2716      addr2 = op2;
2717    }
2718  else
2719    {
2720      emit_move_insn (op2, GEN_INT (4));
2721      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2722    }
2723
2724  word1 = change_address (src, SImode, addr1);
2725  word2 = change_address (src, SImode, addr2);
2726
2727  if (BYTES_BIG_ENDIAN)
2728    {
2729      emit_insn (gen_bswapsi2 (op3_32, word2));
2730      emit_insn (gen_bswapsi2 (dest_32, word1));
2731    }
2732  else
2733    {
2734      emit_insn (gen_bswapsi2 (op3_32, word1));
2735      emit_insn (gen_bswapsi2 (dest_32, word2));
2736    }
2737
2738  emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2739  emit_insn (gen_iordi3 (dest, dest, op3));
2740  DONE;
2741})
2742
2743(define_split
2744  [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2745	(bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2746   (clobber (match_operand:DI 2 "gpc_reg_operand"))
2747   (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2748  "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2749  [(const_int 0)]
2750{
2751  rtx dest   = operands[0];
2752  rtx src    = operands[1];
2753  rtx op2    = operands[2];
2754  rtx op3    = operands[3];
2755  rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2756				    BYTES_BIG_ENDIAN ? 4 : 0);
2757  rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2758				    BYTES_BIG_ENDIAN ? 4 : 0);
2759  rtx addr1;
2760  rtx addr2;
2761  rtx word1;
2762  rtx word2;
2763
2764  addr1 = XEXP (dest, 0);
2765  if (GET_CODE (addr1) == PLUS)
2766    {
2767      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2768      if (TARGET_AVOID_XFORM)
2769	{
2770	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2771	  addr2 = op2;
2772	}
2773      else
2774	addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2775    }
2776  else if (TARGET_AVOID_XFORM)
2777    {
2778      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2779      addr2 = op2;
2780    }
2781  else
2782    {
2783      emit_move_insn (op2, GEN_INT (4));
2784      addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2785    }
2786
2787  word1 = change_address (dest, SImode, addr1);
2788  word2 = change_address (dest, SImode, addr2);
2789
2790  emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2791
2792  if (BYTES_BIG_ENDIAN)
2793    {
2794      emit_insn (gen_bswapsi2 (word1, src_si));
2795      emit_insn (gen_bswapsi2 (word2, op3_si));
2796    }
2797  else
2798    {
2799      emit_insn (gen_bswapsi2 (word2, src_si));
2800      emit_insn (gen_bswapsi2 (word1, op3_si));
2801    }
2802  DONE;
2803})
2804
2805(define_split
2806  [(set (match_operand:DI 0 "gpc_reg_operand")
2807	(bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2808   (clobber (match_operand:DI 2 "gpc_reg_operand"))
2809   (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2810  "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2811  [(const_int 0)]
2812{
2813  rtx dest    = operands[0];
2814  rtx src     = operands[1];
2815  rtx op2     = operands[2];
2816  rtx op3     = operands[3];
2817  int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2818  rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2819  rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2820  rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2821  rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2822
2823  emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2824  emit_insn (gen_bswapsi2 (dest_si, src_si));
2825  emit_insn (gen_bswapsi2 (op3_si, op2_si));
2826  emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2827  emit_insn (gen_iordi3 (dest, dest, op3));
2828  DONE;
2829})
2830
2831(define_insn "bswapdi2_32bit"
2832  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2833	(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2834   (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2835  "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2836  "#"
2837  [(set_attr "length" "16,12,36")])
2838
2839(define_split
2840  [(set (match_operand:DI 0 "gpc_reg_operand")
2841	(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2842   (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2843  "!TARGET_POWERPC64 && reload_completed"
2844  [(const_int 0)]
2845{
2846  rtx dest  = operands[0];
2847  rtx src   = operands[1];
2848  rtx op2   = operands[2];
2849  rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2850  rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2851  rtx addr1;
2852  rtx addr2;
2853  rtx word1;
2854  rtx word2;
2855
2856  addr1 = XEXP (src, 0);
2857  if (GET_CODE (addr1) == PLUS)
2858    {
2859      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2860      if (TARGET_AVOID_XFORM
2861	  || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2862	{
2863	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2864	  addr2 = op2;
2865	}
2866      else
2867	addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2868    }
2869  else if (TARGET_AVOID_XFORM
2870	   || REGNO (addr1) == REGNO (dest2))
2871    {
2872      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2873      addr2 = op2;
2874    }
2875  else
2876    {
2877      emit_move_insn (op2, GEN_INT (4));
2878      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2879    }
2880
2881  word1 = change_address (src, SImode, addr1);
2882  word2 = change_address (src, SImode, addr2);
2883
2884  emit_insn (gen_bswapsi2 (dest2, word1));
2885  /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2886     thus allowing us to omit an early clobber on the output.  */
2887  emit_insn (gen_bswapsi2 (dest1, word2));
2888  DONE;
2889})
2890
2891(define_split
2892  [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2893	(bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2894   (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2895  "!TARGET_POWERPC64 && reload_completed"
2896  [(const_int 0)]
2897{
2898  rtx dest = operands[0];
2899  rtx src  = operands[1];
2900  rtx op2  = operands[2];
2901  rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2902  rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2903  rtx addr1;
2904  rtx addr2;
2905  rtx word1;
2906  rtx word2;
2907
2908  addr1 = XEXP (dest, 0);
2909  if (GET_CODE (addr1) == PLUS)
2910    {
2911      emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2912      if (TARGET_AVOID_XFORM)
2913	{
2914	  emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2915	  addr2 = op2;
2916	}
2917      else
2918	addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2919    }
2920  else if (TARGET_AVOID_XFORM)
2921    {
2922      emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2923      addr2 = op2;
2924    }
2925  else
2926    {
2927      emit_move_insn (op2, GEN_INT (4));
2928      addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2929    }
2930
2931  word1 = change_address (dest, SImode, addr1);
2932  word2 = change_address (dest, SImode, addr2);
2933
2934  emit_insn (gen_bswapsi2 (word2, src1));
2935  emit_insn (gen_bswapsi2 (word1, src2));
2936  DONE;
2937})
2938
2939(define_split
2940  [(set (match_operand:DI 0 "gpc_reg_operand")
2941	(bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2942   (clobber (match_operand:SI 2 ""))]
2943  "!TARGET_POWERPC64 && reload_completed"
2944  [(const_int 0)]
2945{
2946  rtx dest  = operands[0];
2947  rtx src   = operands[1];
2948  rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2949  rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2950  rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2951  rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2952
2953  emit_insn (gen_bswapsi2 (dest1, src2));
2954  emit_insn (gen_bswapsi2 (dest2, src1));
2955  DONE;
2956})
2957
2958
2959(define_insn "mul<mode>3"
2960  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2961	(mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2962		  (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2963  ""
2964  "@
2965   mull<wd> %0,%1,%2
2966   mulli %0,%1,%2"
2967   [(set_attr "type" "mul")
2968    (set (attr "size")
2969      (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2970		(const_string "8")
2971             (match_operand:GPR 2 "short_cint_operand")
2972		(const_string "16")]
2973	(const_string "<bits>")))])
2974
2975(define_insn_and_split "*mul<mode>3_dot"
2976  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2977	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2978			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2979		    (const_int 0)))
2980   (clobber (match_scratch:GPR 0 "=r,r"))]
2981  "<MODE>mode == Pmode"
2982  "@
2983   mull<wd>. %0,%1,%2
2984   #"
2985  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2986  [(set (match_dup 0)
2987	(mult:GPR (match_dup 1)
2988		  (match_dup 2)))
2989   (set (match_dup 3)
2990	(compare:CC (match_dup 0)
2991		    (const_int 0)))]
2992  ""
2993  [(set_attr "type" "mul")
2994   (set_attr "size" "<bits>")
2995   (set_attr "dot" "yes")
2996   (set_attr "length" "4,8")])
2997
2998(define_insn_and_split "*mul<mode>3_dot2"
2999  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3000	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3001			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3002		    (const_int 0)))
3003   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3004	(mult:GPR (match_dup 1)
3005		  (match_dup 2)))]
3006  "<MODE>mode == Pmode"
3007  "@
3008   mull<wd>. %0,%1,%2
3009   #"
3010  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3011  [(set (match_dup 0)
3012	(mult:GPR (match_dup 1)
3013		  (match_dup 2)))
3014   (set (match_dup 3)
3015	(compare:CC (match_dup 0)
3016		    (const_int 0)))]
3017  ""
3018  [(set_attr "type" "mul")
3019   (set_attr "size" "<bits>")
3020   (set_attr "dot" "yes")
3021   (set_attr "length" "4,8")])
3022
3023
3024(define_expand "<su>mul<mode>3_highpart"
3025  [(set (match_operand:GPR 0 "gpc_reg_operand")
3026	(subreg:GPR
3027	  (mult:<DMODE> (any_extend:<DMODE>
3028			  (match_operand:GPR 1 "gpc_reg_operand"))
3029			(any_extend:<DMODE>
3030			  (match_operand:GPR 2 "gpc_reg_operand")))
3031	 0))]
3032  ""
3033{
3034  if (<MODE>mode == SImode && TARGET_POWERPC64)
3035    {
3036      emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3037					     operands[2]));
3038      DONE;
3039    }
3040
3041  if (!WORDS_BIG_ENDIAN)
3042    {
3043      emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3044						 operands[2]));
3045      DONE;
3046    }
3047})
3048
3049(define_insn "*<su>mul<mode>3_highpart"
3050  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3051	(subreg:GPR
3052	  (mult:<DMODE> (any_extend:<DMODE>
3053			  (match_operand:GPR 1 "gpc_reg_operand" "r"))
3054			(any_extend:<DMODE>
3055			  (match_operand:GPR 2 "gpc_reg_operand" "r")))
3056	 0))]
3057  "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3058  "mulh<wd><u> %0,%1,%2"
3059  [(set_attr "type" "mul")
3060   (set_attr "size" "<bits>")])
3061
3062(define_insn "<su>mulsi3_highpart_le"
3063  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3064	(subreg:SI
3065	  (mult:DI (any_extend:DI
3066		     (match_operand:SI 1 "gpc_reg_operand" "r"))
3067		   (any_extend:DI
3068		     (match_operand:SI 2 "gpc_reg_operand" "r")))
3069	 4))]
3070  "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3071  "mulhw<u> %0,%1,%2"
3072  [(set_attr "type" "mul")])
3073
3074(define_insn "<su>muldi3_highpart_le"
3075  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3076	(subreg:DI
3077	  (mult:TI (any_extend:TI
3078		     (match_operand:DI 1 "gpc_reg_operand" "r"))
3079		   (any_extend:TI
3080		     (match_operand:DI 2 "gpc_reg_operand" "r")))
3081	 8))]
3082  "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3083  "mulhd<u> %0,%1,%2"
3084  [(set_attr "type" "mul")
3085   (set_attr "size" "64")])
3086
3087(define_insn "<su>mulsi3_highpart_64"
3088  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3089	(truncate:SI
3090	  (lshiftrt:DI
3091	    (mult:DI (any_extend:DI
3092		       (match_operand:SI 1 "gpc_reg_operand" "r"))
3093		     (any_extend:DI
3094		       (match_operand:SI 2 "gpc_reg_operand" "r")))
3095	    (const_int 32))))]
3096  "TARGET_POWERPC64"
3097  "mulhw<u> %0,%1,%2"
3098  [(set_attr "type" "mul")])
3099
3100(define_expand "<u>mul<mode><dmode>3"
3101  [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3102	(mult:<DMODE> (any_extend:<DMODE>
3103			(match_operand:GPR 1 "gpc_reg_operand"))
3104		      (any_extend:<DMODE>
3105			(match_operand:GPR 2 "gpc_reg_operand"))))]
3106  "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3107{
3108  rtx l = gen_reg_rtx (<MODE>mode);
3109  rtx h = gen_reg_rtx (<MODE>mode);
3110  emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3111  emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3112  emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3113  emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3114  DONE;
3115})
3116
3117(define_insn "*maddld<mode>4"
3118  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3119	(plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3120			    (match_operand:GPR 2 "gpc_reg_operand" "r"))
3121		  (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3122  "TARGET_MADDLD"
3123  "maddld %0,%1,%2,%3"
3124  [(set_attr "type" "mul")])
3125
3126(define_insn "udiv<mode>3"
3127  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3128        (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3129		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3130  ""
3131  "div<wd>u %0,%1,%2"
3132  [(set_attr "type" "div")
3133   (set_attr "size" "<bits>")])
3134
3135
3136;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3137;; modulus.  If it isn't a power of two, force operands into register and do
3138;; a normal divide.
3139(define_expand "div<mode>3"
3140  [(set (match_operand:GPR 0 "gpc_reg_operand")
3141	(div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3142		 (match_operand:GPR 2 "reg_or_cint_operand")))]
3143  ""
3144{
3145  if (CONST_INT_P (operands[2])
3146      && INTVAL (operands[2]) > 0
3147      && exact_log2 (INTVAL (operands[2])) >= 0)
3148    {
3149      emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3150      DONE;
3151    }
3152
3153  operands[2] = force_reg (<MODE>mode, operands[2]);
3154})
3155
3156(define_insn "*div<mode>3"
3157  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3158        (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3159		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3160  ""
3161  "div<wd> %0,%1,%2"
3162  [(set_attr "type" "div")
3163   (set_attr "size" "<bits>")])
3164
3165(define_insn "div<mode>3_sra"
3166  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3167	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3168		 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3169   (clobber (reg:GPR CA_REGNO))]
3170  ""
3171  "sra<wd>i %0,%1,%p2\;addze %0,%0"
3172  [(set_attr "type" "two")
3173   (set_attr "length" "8")])
3174
3175(define_insn_and_split "*div<mode>3_sra_dot"
3176  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3177	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3178			     (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3179		    (const_int 0)))
3180   (clobber (match_scratch:GPR 0 "=r,r"))
3181   (clobber (reg:GPR CA_REGNO))]
3182  "<MODE>mode == Pmode"
3183  "@
3184   sra<wd>i %0,%1,%p2\;addze. %0,%0
3185   #"
3186  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3187  [(parallel [(set (match_dup 0)
3188		   (div:GPR (match_dup 1)
3189			    (match_dup 2)))
3190	      (clobber (reg:GPR CA_REGNO))])
3191   (set (match_dup 3)
3192	(compare:CC (match_dup 0)
3193		    (const_int 0)))]
3194  ""
3195  [(set_attr "type" "two")
3196   (set_attr "length" "8,12")
3197   (set_attr "cell_micro" "not")])
3198
3199(define_insn_and_split "*div<mode>3_sra_dot2"
3200  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3201	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3202			     (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3203		    (const_int 0)))
3204   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3205	(div:GPR (match_dup 1)
3206		 (match_dup 2)))
3207   (clobber (reg:GPR CA_REGNO))]
3208  "<MODE>mode == Pmode"
3209  "@
3210   sra<wd>i %0,%1,%p2\;addze. %0,%0
3211   #"
3212  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3213  [(parallel [(set (match_dup 0)
3214		   (div:GPR (match_dup 1)
3215			    (match_dup 2)))
3216	      (clobber (reg:GPR CA_REGNO))])
3217   (set (match_dup 3)
3218	(compare:CC (match_dup 0)
3219		    (const_int 0)))]
3220  ""
3221  [(set_attr "type" "two")
3222   (set_attr "length" "8,12")
3223   (set_attr "cell_micro" "not")])
3224
3225(define_expand "mod<mode>3"
3226  [(set (match_operand:GPR 0 "gpc_reg_operand")
3227	(mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3228		 (match_operand:GPR 2 "reg_or_cint_operand")))]
3229  ""
3230{
3231  int i;
3232  rtx temp1;
3233  rtx temp2;
3234
3235  if (!CONST_INT_P (operands[2])
3236      || INTVAL (operands[2]) <= 0
3237      || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3238    {
3239      if (!TARGET_MODULO)
3240	FAIL;
3241
3242      operands[2] = force_reg (<MODE>mode, operands[2]);
3243    }
3244  else
3245    {
3246      temp1 = gen_reg_rtx (<MODE>mode);
3247      temp2 = gen_reg_rtx (<MODE>mode);
3248
3249      emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3250      emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3251      emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3252      DONE;
3253    }
3254})
3255
3256;; In order to enable using a peephole2 for combining div/mod to eliminate the
3257;; mod, prefer putting the result of mod into a different register
3258(define_insn "*mod<mode>3"
3259  [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3260        (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3261		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3262  "TARGET_MODULO"
3263  "mods<wd> %0,%1,%2"
3264  [(set_attr "type" "div")
3265   (set_attr "size" "<bits>")])
3266
3267
3268(define_insn "umod<mode>3"
3269  [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3270        (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3271		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3272  "TARGET_MODULO"
3273  "modu<wd> %0,%1,%2"
3274  [(set_attr "type" "div")
3275   (set_attr "size" "<bits>")])
3276
3277;; On machines with modulo support, do a combined div/mod the old fashioned
3278;; method, since the multiply/subtract is faster than doing the mod instruction
3279;; after a divide.
3280
3281(define_peephole2
3282  [(set (match_operand:GPR 0 "gpc_reg_operand")
3283	(div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3284		 (match_operand:GPR 2 "gpc_reg_operand")))
3285   (set (match_operand:GPR 3 "gpc_reg_operand")
3286	(mod:GPR (match_dup 1)
3287		 (match_dup 2)))]
3288  "TARGET_MODULO
3289   && ! reg_mentioned_p (operands[0], operands[1])
3290   && ! reg_mentioned_p (operands[0], operands[2])
3291   && ! reg_mentioned_p (operands[3], operands[1])
3292   && ! reg_mentioned_p (operands[3], operands[2])"
3293  [(set (match_dup 0)
3294	(div:GPR (match_dup 1)
3295		 (match_dup 2)))
3296   (set (match_dup 3)
3297	(mult:GPR (match_dup 0)
3298		  (match_dup 2)))
3299   (set (match_dup 3)
3300	(minus:GPR (match_dup 1)
3301		   (match_dup 3)))])
3302
3303(define_peephole2
3304  [(set (match_operand:GPR 0 "gpc_reg_operand")
3305	(udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3306		  (match_operand:GPR 2 "gpc_reg_operand")))
3307   (set (match_operand:GPR 3 "gpc_reg_operand")
3308	(umod:GPR (match_dup 1)
3309		  (match_dup 2)))]
3310  "TARGET_MODULO
3311   && ! reg_mentioned_p (operands[0], operands[1])
3312   && ! reg_mentioned_p (operands[0], operands[2])
3313   && ! reg_mentioned_p (operands[3], operands[1])
3314   && ! reg_mentioned_p (operands[3], operands[2])"
3315  [(set (match_dup 0)
3316	(udiv:GPR (match_dup 1)
3317		  (match_dup 2)))
3318   (set (match_dup 3)
3319	(mult:GPR (match_dup 0)
3320		  (match_dup 2)))
3321   (set (match_dup 3)
3322	(minus:GPR (match_dup 1)
3323		   (match_dup 3)))])
3324
3325
3326;; Logical instructions
3327;; The logical instructions are mostly combined by using match_operator,
3328;; but the plain AND insns are somewhat different because there is no
3329;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3330;; those rotate-and-mask operations.  Thus, the AND insns come first.
3331
3332(define_expand "and<mode>3"
3333  [(set (match_operand:SDI 0 "gpc_reg_operand")
3334	(and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3335		 (match_operand:SDI 2 "reg_or_cint_operand")))]
3336  ""
3337{
3338  if (<MODE>mode == DImode && !TARGET_POWERPC64)
3339    {
3340      rs6000_split_logical (operands, AND, false, false, false);
3341      DONE;
3342    }
3343
3344  if (CONST_INT_P (operands[2]))
3345    {
3346      if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3347	{
3348	  emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3349	  DONE;
3350	}
3351
3352      if (logical_const_operand (operands[2], <MODE>mode))
3353	{
3354	  emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3355	  DONE;
3356	}
3357
3358      if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3359	{
3360	  rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3361	  DONE;
3362	}
3363
3364      operands[2] = force_reg (<MODE>mode, operands[2]);
3365    }
3366})
3367
3368
3369(define_insn "and<mode>3_imm"
3370  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3371	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3372		 (match_operand:GPR 2 "logical_const_operand" "n")))
3373   (clobber (match_scratch:CC 3 "=x"))]
3374  "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3375  "andi%e2. %0,%1,%u2"
3376  [(set_attr "type" "logical")
3377   (set_attr "dot" "yes")])
3378
3379(define_insn_and_split "*and<mode>3_imm_dot"
3380  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3381	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3382			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3383		    (const_int 0)))
3384   (clobber (match_scratch:GPR 0 "=r,r"))
3385   (clobber (match_scratch:CC 4 "=X,x"))]
3386  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3387   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3388  "@
3389   andi%e2. %0,%1,%u2
3390   #"
3391  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3392  [(parallel [(set (match_dup 0)
3393		   (and:GPR (match_dup 1)
3394			    (match_dup 2)))
3395	      (clobber (match_dup 4))])
3396   (set (match_dup 3)
3397	(compare:CC (match_dup 0)
3398		    (const_int 0)))]
3399  ""
3400  [(set_attr "type" "logical")
3401   (set_attr "dot" "yes")
3402   (set_attr "length" "4,8")])
3403
3404(define_insn_and_split "*and<mode>3_imm_dot2"
3405  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3406	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3407			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3408		    (const_int 0)))
3409   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3410	(and:GPR (match_dup 1)
3411		 (match_dup 2)))
3412   (clobber (match_scratch:CC 4 "=X,x"))]
3413  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3414   && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3415  "@
3416   andi%e2. %0,%1,%u2
3417   #"
3418  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3419  [(parallel [(set (match_dup 0)
3420		   (and:GPR (match_dup 1)
3421			    (match_dup 2)))
3422	      (clobber (match_dup 4))])
3423   (set (match_dup 3)
3424	(compare:CC (match_dup 0)
3425		    (const_int 0)))]
3426  ""
3427  [(set_attr "type" "logical")
3428   (set_attr "dot" "yes")
3429   (set_attr "length" "4,8")])
3430
3431(define_insn_and_split "*and<mode>3_imm_mask_dot"
3432  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3433	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3434			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3435		    (const_int 0)))
3436   (clobber (match_scratch:GPR 0 "=r,r"))]
3437  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3438   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3439  "@
3440   andi%e2. %0,%1,%u2
3441   #"
3442  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3443  [(set (match_dup 0)
3444	(and:GPR (match_dup 1)
3445		 (match_dup 2)))
3446   (set (match_dup 3)
3447	(compare:CC (match_dup 0)
3448		    (const_int 0)))]
3449  ""
3450  [(set_attr "type" "logical")
3451   (set_attr "dot" "yes")
3452   (set_attr "length" "4,8")])
3453
3454(define_insn_and_split "*and<mode>3_imm_mask_dot2"
3455  [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3456	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3457			     (match_operand:GPR 2 "logical_const_operand" "n,n"))
3458		    (const_int 0)))
3459   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3460	(and:GPR (match_dup 1)
3461		 (match_dup 2)))]
3462  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3463   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3464  "@
3465   andi%e2. %0,%1,%u2
3466   #"
3467  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3468  [(set (match_dup 0)
3469	(and:GPR (match_dup 1)
3470		 (match_dup 2)))
3471   (set (match_dup 3)
3472	(compare:CC (match_dup 0)
3473		    (const_int 0)))]
3474  ""
3475  [(set_attr "type" "logical")
3476   (set_attr "dot" "yes")
3477   (set_attr "length" "4,8")])
3478
3479(define_insn "*and<mode>3_imm_dot_shifted"
3480  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3481	(compare:CC
3482	  (and:GPR
3483	    (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3484			  (match_operand:SI 4 "const_int_operand" "n"))
3485	    (match_operand:GPR 2 "const_int_operand" "n"))
3486	  (const_int 0)))
3487   (clobber (match_scratch:GPR 0 "=r"))]
3488  "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3489				   << INTVAL (operands[4])),
3490			  DImode)
3491   && (<MODE>mode == Pmode
3492       || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3493{
3494  operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3495  return "andi%e2. %0,%1,%u2";
3496}
3497  [(set_attr "type" "logical")
3498   (set_attr "dot" "yes")])
3499
3500
3501(define_insn "and<mode>3_mask"
3502  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3503	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3504		 (match_operand:GPR 2 "const_int_operand" "n")))]
3505  "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3506{
3507  return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3508}
3509  [(set_attr "type" "shift")])
3510
3511(define_insn_and_split "*and<mode>3_mask_dot"
3512  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3513	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3514			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3515		    (const_int 0)))
3516   (clobber (match_scratch:GPR 0 "=r,r"))]
3517  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3518   && !logical_const_operand (operands[2], <MODE>mode)
3519   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3520{
3521  if (which_alternative == 0)
3522    return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3523  else
3524    return "#";
3525}
3526  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3527  [(set (match_dup 0)
3528	(and:GPR (match_dup 1)
3529		 (match_dup 2)))
3530   (set (match_dup 3)
3531	(compare:CC (match_dup 0)
3532		    (const_int 0)))]
3533  ""
3534  [(set_attr "type" "shift")
3535   (set_attr "dot" "yes")
3536   (set_attr "length" "4,8")])
3537
3538(define_insn_and_split "*and<mode>3_mask_dot2"
3539  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3540	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3541			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3542		    (const_int 0)))
3543   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3544	(and:GPR (match_dup 1)
3545		 (match_dup 2)))]
3546  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3547   && !logical_const_operand (operands[2], <MODE>mode)
3548   && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3549{
3550  if (which_alternative == 0)
3551    return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3552  else
3553    return "#";
3554}
3555  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3556  [(set (match_dup 0)
3557	(and:GPR (match_dup 1)
3558		 (match_dup 2)))
3559   (set (match_dup 3)
3560	(compare:CC (match_dup 0)
3561		    (const_int 0)))]
3562  ""
3563  [(set_attr "type" "shift")
3564   (set_attr "dot" "yes")
3565   (set_attr "length" "4,8")])
3566
3567
3568(define_insn_and_split "*and<mode>3_2insn"
3569  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3570	(and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3571		 (match_operand:GPR 2 "const_int_operand" "n")))]
3572  "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3573   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3574	|| logical_const_operand (operands[2], <MODE>mode))"
3575  "#"
3576  "&& 1"
3577  [(pc)]
3578{
3579  rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3580  DONE;
3581}
3582  [(set_attr "type" "shift")
3583   (set_attr "length" "8")])
3584
3585(define_insn_and_split "*and<mode>3_2insn_dot"
3586  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3587	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3588			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3589		    (const_int 0)))
3590   (clobber (match_scratch:GPR 0 "=r,r"))]
3591  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3592   && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3593   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3594	|| logical_const_operand (operands[2], <MODE>mode))"
3595  "#"
3596  "&& reload_completed"
3597  [(pc)]
3598{
3599  rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3600  DONE;
3601}
3602  [(set_attr "type" "shift")
3603   (set_attr "dot" "yes")
3604   (set_attr "length" "8,12")])
3605
3606(define_insn_and_split "*and<mode>3_2insn_dot2"
3607  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3608	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3609			     (match_operand:GPR 2 "const_int_operand" "n,n"))
3610		    (const_int 0)))
3611   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3612	(and:GPR (match_dup 1)
3613		 (match_dup 2)))]
3614  "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3615   && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3616   && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3617	|| logical_const_operand (operands[2], <MODE>mode))"
3618  "#"
3619  "&& reload_completed"
3620  [(pc)]
3621{
3622  rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3623  DONE;
3624}
3625  [(set_attr "type" "shift")
3626   (set_attr "dot" "yes")
3627   (set_attr "length" "8,12")])
3628
3629
3630(define_expand "<code><mode>3"
3631  [(set (match_operand:SDI 0 "gpc_reg_operand")
3632	(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3633		    (match_operand:SDI 2 "reg_or_cint_operand")))]
3634  ""
3635{
3636  if (<MODE>mode == DImode && !TARGET_POWERPC64)
3637    {
3638      rs6000_split_logical (operands, <CODE>, false, false, false);
3639      DONE;
3640    }
3641
3642  if (non_logical_cint_operand (operands[2], <MODE>mode))
3643    {
3644      rtx tmp = ((!can_create_pseudo_p ()
3645		  || rtx_equal_p (operands[0], operands[1]))
3646		 ? operands[0] : gen_reg_rtx (<MODE>mode));
3647
3648      HOST_WIDE_INT value = INTVAL (operands[2]);
3649      HOST_WIDE_INT lo = value & 0xffff;
3650      HOST_WIDE_INT hi = value - lo;
3651
3652      emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3653      emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3654      DONE;
3655    }
3656
3657  if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3658    operands[2] = force_reg (<MODE>mode, operands[2]);
3659})
3660
3661(define_split
3662  [(set (match_operand:GPR 0 "gpc_reg_operand")
3663	(iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3664		    (match_operand:GPR 2 "non_logical_cint_operand")))]
3665  ""
3666  [(set (match_dup 3)
3667	(iorxor:GPR (match_dup 1)
3668		    (match_dup 4)))
3669   (set (match_dup 0)
3670	(iorxor:GPR (match_dup 3)
3671		    (match_dup 5)))]
3672{
3673  operands[3] = ((!can_create_pseudo_p ()
3674		  || rtx_equal_p (operands[0], operands[1]))
3675		 ? operands[0] : gen_reg_rtx (<MODE>mode));
3676
3677  HOST_WIDE_INT value = INTVAL (operands[2]);
3678  HOST_WIDE_INT lo = value & 0xffff;
3679  HOST_WIDE_INT hi = value - lo;
3680
3681  operands[4] = GEN_INT (hi);
3682  operands[5] = GEN_INT (lo);
3683})
3684
3685(define_insn "*bool<mode>3_imm"
3686  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3687	(match_operator:GPR 3 "boolean_or_operator"
3688	 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3689	  (match_operand:GPR 2 "logical_const_operand" "n")]))]
3690  ""
3691  "%q3i%e2 %0,%1,%u2"
3692  [(set_attr "type" "logical")])
3693
3694(define_insn "*bool<mode>3"
3695  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3696	(match_operator:GPR 3 "boolean_operator"
3697	 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3698	  (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3699  ""
3700  "%q3 %0,%1,%2"
3701  [(set_attr "type" "logical")])
3702
3703(define_insn_and_split "*bool<mode>3_dot"
3704  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3705	(compare:CC (match_operator:GPR 3 "boolean_operator"
3706	 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3707	  (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3708	 (const_int 0)))
3709   (clobber (match_scratch:GPR 0 "=r,r"))]
3710  "<MODE>mode == Pmode"
3711  "@
3712   %q3. %0,%1,%2
3713   #"
3714  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3715  [(set (match_dup 0)
3716	(match_dup 3))
3717   (set (match_dup 4)
3718	(compare:CC (match_dup 0)
3719		    (const_int 0)))]
3720  ""
3721  [(set_attr "type" "logical")
3722   (set_attr "dot" "yes")
3723   (set_attr "length" "4,8")])
3724
3725(define_insn_and_split "*bool<mode>3_dot2"
3726  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3727	(compare:CC (match_operator:GPR 3 "boolean_operator"
3728	 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3729	  (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3730	 (const_int 0)))
3731   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3732	(match_dup 3))]
3733  "<MODE>mode == Pmode"
3734  "@
3735   %q3. %0,%1,%2
3736   #"
3737  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3738  [(set (match_dup 0)
3739	(match_dup 3))
3740   (set (match_dup 4)
3741	(compare:CC (match_dup 0)
3742		    (const_int 0)))]
3743  ""
3744  [(set_attr "type" "logical")
3745   (set_attr "dot" "yes")
3746   (set_attr "length" "4,8")])
3747
3748
3749(define_insn "*boolc<mode>3"
3750  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3751	(match_operator:GPR 3 "boolean_operator"
3752	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3753	  (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3754  ""
3755  "%q3 %0,%1,%2"
3756  [(set_attr "type" "logical")])
3757
3758(define_insn_and_split "*boolc<mode>3_dot"
3759  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3760	(compare:CC (match_operator:GPR 3 "boolean_operator"
3761	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3762	  (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3763	 (const_int 0)))
3764   (clobber (match_scratch:GPR 0 "=r,r"))]
3765  "<MODE>mode == Pmode"
3766  "@
3767   %q3. %0,%1,%2
3768   #"
3769  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3770  [(set (match_dup 0)
3771	(match_dup 3))
3772   (set (match_dup 4)
3773	(compare:CC (match_dup 0)
3774		    (const_int 0)))]
3775  ""
3776  [(set_attr "type" "logical")
3777   (set_attr "dot" "yes")
3778   (set_attr "length" "4,8")])
3779
3780(define_insn_and_split "*boolc<mode>3_dot2"
3781  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3782	(compare:CC (match_operator:GPR 3 "boolean_operator"
3783	 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3784	  (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3785	 (const_int 0)))
3786   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3787	(match_dup 3))]
3788  "<MODE>mode == Pmode"
3789  "@
3790   %q3. %0,%1,%2
3791   #"
3792  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3793  [(set (match_dup 0)
3794	(match_dup 3))
3795   (set (match_dup 4)
3796	(compare:CC (match_dup 0)
3797		    (const_int 0)))]
3798  ""
3799  [(set_attr "type" "logical")
3800   (set_attr "dot" "yes")
3801   (set_attr "length" "4,8")])
3802
3803
3804(define_insn "*boolcc<mode>3"
3805  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3806	(match_operator:GPR 3 "boolean_operator"
3807	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3808	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3809  ""
3810  "%q3 %0,%1,%2"
3811  [(set_attr "type" "logical")])
3812
3813(define_insn_and_split "*boolcc<mode>3_dot"
3814  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3815	(compare:CC (match_operator:GPR 3 "boolean_operator"
3816	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3817	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3818	 (const_int 0)))
3819   (clobber (match_scratch:GPR 0 "=r,r"))]
3820  "<MODE>mode == Pmode"
3821  "@
3822   %q3. %0,%1,%2
3823   #"
3824  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3825  [(set (match_dup 0)
3826	(match_dup 3))
3827   (set (match_dup 4)
3828	(compare:CC (match_dup 0)
3829		    (const_int 0)))]
3830  ""
3831  [(set_attr "type" "logical")
3832   (set_attr "dot" "yes")
3833   (set_attr "length" "4,8")])
3834
3835(define_insn_and_split "*boolcc<mode>3_dot2"
3836  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3837	(compare:CC (match_operator:GPR 3 "boolean_operator"
3838	 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3839	  (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3840	 (const_int 0)))
3841   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3842	(match_dup 3))]
3843  "<MODE>mode == Pmode"
3844  "@
3845   %q3. %0,%1,%2
3846   #"
3847  "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3848  [(set (match_dup 0)
3849	(match_dup 3))
3850   (set (match_dup 4)
3851	(compare:CC (match_dup 0)
3852		    (const_int 0)))]
3853  ""
3854  [(set_attr "type" "logical")
3855   (set_attr "dot" "yes")
3856   (set_attr "length" "4,8")])
3857
3858
3859;; TODO: Should have dots of this as well.
3860(define_insn "*eqv<mode>3"
3861  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3862	(not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3863			  (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3864  ""
3865  "eqv %0,%1,%2"
3866  [(set_attr "type" "logical")])
3867
3868;; Rotate-and-mask and insert.
3869
3870(define_insn "*rotl<mode>3_mask"
3871  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3872	(and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3873		  [(match_operand:GPR 1 "gpc_reg_operand" "r")
3874		   (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3875		 (match_operand:GPR 3 "const_int_operand" "n")))]
3876  "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3877{
3878  return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3879}
3880  [(set_attr "type" "shift")
3881   (set_attr "maybe_var_shift" "yes")])
3882
3883(define_insn_and_split "*rotl<mode>3_mask_dot"
3884  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3885	(compare:CC
3886	  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3887		    [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3888		     (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3889		   (match_operand:GPR 3 "const_int_operand" "n,n"))
3890	  (const_int 0)))
3891   (clobber (match_scratch:GPR 0 "=r,r"))]
3892  "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3893   && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3894{
3895  if (which_alternative == 0)
3896    return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3897  else
3898    return "#";
3899}
3900  "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3901  [(set (match_dup 0)
3902	(and:GPR (match_dup 4)
3903		 (match_dup 3)))
3904   (set (match_dup 5)
3905	(compare:CC (match_dup 0)
3906		    (const_int 0)))]
3907  ""
3908  [(set_attr "type" "shift")
3909   (set_attr "maybe_var_shift" "yes")
3910   (set_attr "dot" "yes")
3911   (set_attr "length" "4,8")])
3912
3913(define_insn_and_split "*rotl<mode>3_mask_dot2"
3914  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3915	(compare:CC
3916	  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3917		    [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3918		     (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3919		   (match_operand:GPR 3 "const_int_operand" "n,n"))
3920	  (const_int 0)))
3921   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3922	(and:GPR (match_dup 4)
3923		 (match_dup 3)))]
3924  "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3925   && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3926{
3927  if (which_alternative == 0)
3928    return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3929  else
3930    return "#";
3931}
3932  "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3933  [(set (match_dup 0)
3934	(and:GPR (match_dup 4)
3935		 (match_dup 3)))
3936   (set (match_dup 5)
3937	(compare:CC (match_dup 0)
3938		    (const_int 0)))]
3939  ""
3940  [(set_attr "type" "shift")
3941   (set_attr "maybe_var_shift" "yes")
3942   (set_attr "dot" "yes")
3943   (set_attr "length" "4,8")])
3944
3945; Special case for less-than-0.  We can do it with just one machine
3946; instruction, but the generic optimizers do not realise it is cheap.
3947(define_insn "*lt0_<mode>di"
3948  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3949	(lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3950		(const_int 0)))]
3951  "TARGET_POWERPC64"
3952  "srdi %0,%1,63"
3953  [(set_attr "type" "shift")])
3954
3955(define_insn "*lt0_<mode>si"
3956  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3957	(lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3958		(const_int 0)))]
3959  ""
3960  "rlwinm %0,%1,1,31,31"
3961  [(set_attr "type" "shift")])
3962
3963
3964
3965; Two forms for insert (the two arms of the IOR are not canonicalized,
3966; both are an AND so are the same precedence).
3967(define_insn "*rotl<mode>3_insert"
3968  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3969	(ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3970			   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3971			    (match_operand:SI 2 "const_int_operand" "n")])
3972			  (match_operand:GPR 3 "const_int_operand" "n"))
3973		 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3974			  (match_operand:GPR 6 "const_int_operand" "n"))))]
3975  "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3976   && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3977{
3978  return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3979}
3980  [(set_attr "type" "insert")])
3981; FIXME: this needs an attr "size", so that the scheduler can see the
3982; difference between rlwimi and rldimi.  We also might want dot forms,
3983; but not for rlwimi on POWER4 and similar processors.
3984
3985(define_insn "*rotl<mode>3_insert_2"
3986  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3987	(ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3988			  (match_operand:GPR 6 "const_int_operand" "n"))
3989		 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3990			   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3991			    (match_operand:SI 2 "const_int_operand" "n")])
3992			  (match_operand:GPR 3 "const_int_operand" "n"))))]
3993  "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3994   && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3995{
3996  return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3997}
3998  [(set_attr "type" "insert")])
3999
4000; There are also some forms without one of the ANDs.
4001(define_insn "*rotl<mode>3_insert_3"
4002  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4003	(ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4004			  (match_operand:GPR 4 "const_int_operand" "n"))
4005		 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4006			     (match_operand:SI 2 "const_int_operand" "n"))))]
4007  "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4008{
4009  if (<MODE>mode == SImode)
4010    return "rlwimi %0,%1,%h2,0,31-%h2";
4011  else
4012    return "rldimi %0,%1,%H2,0";
4013}
4014  [(set_attr "type" "insert")])
4015
4016(define_insn "*rotl<mode>3_insert_4"
4017  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4018	(ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4019			  (match_operand:GPR 4 "const_int_operand" "n"))
4020		 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4021			       (match_operand:SI 2 "const_int_operand" "n"))))]
4022  "<MODE>mode == SImode &&
4023   GET_MODE_PRECISION (<MODE>mode)
4024   == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4025{
4026  operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4027			 - INTVAL (operands[2]));
4028  if (<MODE>mode == SImode)
4029    return "rlwimi %0,%1,%h2,32-%h2,31";
4030  else
4031    return "rldimi %0,%1,%H2,64-%H2";
4032}
4033  [(set_attr "type" "insert")])
4034
4035(define_insn "*rotlsi3_insert_5"
4036  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4037	(ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4038			(match_operand:SI 2 "const_int_operand" "n,n"))
4039		(and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4040			(match_operand:SI 4 "const_int_operand" "n,n"))))]
4041  "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4042   && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4043   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4044  "@
4045   rlwimi %0,%3,0,%4
4046   rlwimi %0,%1,0,%2"
4047  [(set_attr "type" "insert")])
4048
4049(define_insn "*rotldi3_insert_6"
4050  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4051	(ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4052			(match_operand:DI 2 "const_int_operand" "n"))
4053		(and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4054			(match_operand:DI 4 "const_int_operand" "n"))))]
4055  "exact_log2 (-UINTVAL (operands[2])) > 0
4056   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4057{
4058  operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4059  return "rldimi %0,%3,0,%5";
4060}
4061  [(set_attr "type" "insert")
4062   (set_attr "size" "64")])
4063
4064(define_insn "*rotldi3_insert_7"
4065  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4066	(ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4067			(match_operand:DI 4 "const_int_operand" "n"))
4068		(and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4069			(match_operand:DI 2 "const_int_operand" "n"))))]
4070  "exact_log2 (-UINTVAL (operands[2])) > 0
4071   && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4072{
4073  operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4074  return "rldimi %0,%3,0,%5";
4075}
4076  [(set_attr "type" "insert")
4077   (set_attr "size" "64")])
4078
4079
4080; This handles the important case of multiple-precision shifts.  There is
4081; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4082(define_split
4083  [(set (match_operand:GPR 0 "gpc_reg_operand")
4084	(ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4085			     (match_operand:SI 3 "const_int_operand"))
4086		 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4087			       (match_operand:SI 4 "const_int_operand"))))]
4088  "can_create_pseudo_p ()
4089   && INTVAL (operands[3]) + INTVAL (operands[4])
4090      >= GET_MODE_PRECISION (<MODE>mode)"
4091  [(set (match_dup 5)
4092	(lshiftrt:GPR (match_dup 2)
4093		      (match_dup 4)))
4094   (set (match_dup 0)
4095	(ior:GPR (and:GPR (match_dup 5)
4096			  (match_dup 6))
4097		 (ashift:GPR (match_dup 1)
4098			     (match_dup 3))))]
4099{
4100  unsigned HOST_WIDE_INT mask = 1;
4101  mask = (mask << INTVAL (operands[3])) - 1;
4102  operands[5] = gen_reg_rtx (<MODE>mode);
4103  operands[6] = GEN_INT (mask);
4104})
4105
4106(define_split
4107  [(set (match_operand:GPR 0 "gpc_reg_operand")
4108	(ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4109			       (match_operand:SI 4 "const_int_operand"))
4110		 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4111			     (match_operand:SI 3 "const_int_operand"))))]
4112  "can_create_pseudo_p ()
4113   && INTVAL (operands[3]) + INTVAL (operands[4])
4114      >= GET_MODE_PRECISION (<MODE>mode)"
4115  [(set (match_dup 5)
4116	(lshiftrt:GPR (match_dup 2)
4117		      (match_dup 4)))
4118   (set (match_dup 0)
4119	(ior:GPR (and:GPR (match_dup 5)
4120			  (match_dup 6))
4121		 (ashift:GPR (match_dup 1)
4122			     (match_dup 3))))]
4123{
4124  unsigned HOST_WIDE_INT mask = 1;
4125  mask = (mask << INTVAL (operands[3])) - 1;
4126  operands[5] = gen_reg_rtx (<MODE>mode);
4127  operands[6] = GEN_INT (mask);
4128})
4129
4130
4131; Another important case is setting some bits to 1; we can do that with
4132; an insert instruction, in many cases.
4133(define_insn_and_split "*ior<mode>_mask"
4134  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4135	(ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4136		 (match_operand:GPR 2 "const_int_operand" "n")))
4137   (clobber (match_scratch:GPR 3 "=r"))]
4138  "!logical_const_operand (operands[2], <MODE>mode)
4139   && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4140  "#"
4141  "&& 1"
4142  [(set (match_dup 3)
4143	(const_int -1))
4144   (set (match_dup 0)
4145	(ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4146				      (match_dup 4))
4147			  (match_dup 2))
4148		 (and:GPR (match_dup 1)
4149			  (match_dup 5))))]
4150{
4151  int nb, ne;
4152  rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4153  if (GET_CODE (operands[3]) == SCRATCH)
4154    operands[3] = gen_reg_rtx (<MODE>mode);
4155  operands[4] = GEN_INT (ne);
4156  operands[5] = GEN_INT (~UINTVAL (operands[2]));
4157}
4158  [(set_attr "type" "two")
4159   (set_attr "length" "8")])
4160
4161
4162; Yet another case is an rldimi with the second value coming from memory.
4163; The zero_extend that should become part of the rldimi is merged into the
4164; load from memory instead.  Split things properly again.
4165(define_split
4166  [(set (match_operand:DI 0 "gpc_reg_operand")
4167	(ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4168			   (match_operand:SI 2 "const_int_operand"))
4169		(zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4170  "INTVAL (operands[2]) == <bits>"
4171  [(set (match_dup 4)
4172	(zero_extend:DI (match_dup 3)))
4173   (set (match_dup 0)
4174	(ior:DI (and:DI (match_dup 4)
4175			(match_dup 5))
4176		(ashift:DI (match_dup 1)
4177			   (match_dup 2))))]
4178{
4179  operands[4] = gen_reg_rtx (DImode);
4180  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4181})
4182
4183; rlwimi, too.
4184(define_split
4185  [(set (match_operand:SI 0 "gpc_reg_operand")
4186	(ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4187			   (match_operand:SI 2 "const_int_operand"))
4188		(zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4189  "INTVAL (operands[2]) == <bits>"
4190  [(set (match_dup 4)
4191	(zero_extend:SI (match_dup 3)))
4192   (set (match_dup 0)
4193	(ior:SI (and:SI (match_dup 4)
4194			(match_dup 5))
4195		(ashift:SI (match_dup 1)
4196			   (match_dup 2))))]
4197{
4198  operands[4] = gen_reg_rtx (SImode);
4199  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4200})
4201
4202
4203;; Now the simple shifts.
4204
4205(define_insn "rotl<mode>3"
4206  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4207	(rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4208		    (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4209  ""
4210  "rotl<wd>%I2 %0,%1,%<hH>2"
4211  [(set_attr "type" "shift")
4212   (set_attr "maybe_var_shift" "yes")])
4213
4214(define_insn "*rotlsi3_64"
4215  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4216	(zero_extend:DI
4217	    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4218		       (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4219  "TARGET_POWERPC64"
4220  "rotlw%I2 %0,%1,%h2"
4221  [(set_attr "type" "shift")
4222   (set_attr "maybe_var_shift" "yes")])
4223
4224(define_insn_and_split "*rotl<mode>3_dot"
4225  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4226	(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4227				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4228		    (const_int 0)))
4229   (clobber (match_scratch:GPR 0 "=r,r"))]
4230  "<MODE>mode == Pmode"
4231  "@
4232   rotl<wd>%I2. %0,%1,%<hH>2
4233   #"
4234  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4235  [(set (match_dup 0)
4236	(rotate:GPR (match_dup 1)
4237		    (match_dup 2)))
4238   (set (match_dup 3)
4239	(compare:CC (match_dup 0)
4240		    (const_int 0)))]
4241  ""
4242  [(set_attr "type" "shift")
4243   (set_attr "maybe_var_shift" "yes")
4244   (set_attr "dot" "yes")
4245   (set_attr "length" "4,8")])
4246
4247(define_insn_and_split "*rotl<mode>3_dot2"
4248  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4249	(compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4250				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4251		    (const_int 0)))
4252   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4253	(rotate:GPR (match_dup 1)
4254		    (match_dup 2)))]
4255  "<MODE>mode == Pmode"
4256  "@
4257   rotl<wd>%I2. %0,%1,%<hH>2
4258   #"
4259  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4260  [(set (match_dup 0)
4261	(rotate:GPR (match_dup 1)
4262		    (match_dup 2)))
4263   (set (match_dup 3)
4264	(compare:CC (match_dup 0)
4265		    (const_int 0)))]
4266  ""
4267  [(set_attr "type" "shift")
4268   (set_attr "maybe_var_shift" "yes")
4269   (set_attr "dot" "yes")
4270   (set_attr "length" "4,8")])
4271
4272
4273(define_insn "ashl<mode>3"
4274  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4275	(ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4276		    (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4277  ""
4278  "sl<wd>%I2 %0,%1,%<hH>2"
4279  [(set_attr "type" "shift")
4280   (set_attr "maybe_var_shift" "yes")])
4281
4282(define_insn "*ashlsi3_64"
4283  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4284	(zero_extend:DI
4285	    (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4286		       (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4287  "TARGET_POWERPC64"
4288  "slw%I2 %0,%1,%h2"
4289  [(set_attr "type" "shift")
4290   (set_attr "maybe_var_shift" "yes")])
4291
4292(define_insn_and_split "*ashl<mode>3_dot"
4293  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4294	(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4295				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4296		    (const_int 0)))
4297   (clobber (match_scratch:GPR 0 "=r,r"))]
4298  "<MODE>mode == Pmode"
4299  "@
4300   sl<wd>%I2. %0,%1,%<hH>2
4301   #"
4302  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4303  [(set (match_dup 0)
4304	(ashift:GPR (match_dup 1)
4305		    (match_dup 2)))
4306   (set (match_dup 3)
4307	(compare:CC (match_dup 0)
4308		    (const_int 0)))]
4309  ""
4310  [(set_attr "type" "shift")
4311   (set_attr "maybe_var_shift" "yes")
4312   (set_attr "dot" "yes")
4313   (set_attr "length" "4,8")])
4314
4315(define_insn_and_split "*ashl<mode>3_dot2"
4316  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4317	(compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4318				(match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4319		    (const_int 0)))
4320   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4321	(ashift:GPR (match_dup 1)
4322		    (match_dup 2)))]
4323  "<MODE>mode == Pmode"
4324  "@
4325   sl<wd>%I2. %0,%1,%<hH>2
4326   #"
4327  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4328  [(set (match_dup 0)
4329	(ashift:GPR (match_dup 1)
4330		    (match_dup 2)))
4331   (set (match_dup 3)
4332	(compare:CC (match_dup 0)
4333		    (const_int 0)))]
4334  ""
4335  [(set_attr "type" "shift")
4336   (set_attr "maybe_var_shift" "yes")
4337   (set_attr "dot" "yes")
4338   (set_attr "length" "4,8")])
4339
4340;; Pretend we have a memory form of extswsli until register allocation is done
4341;; so that we use LWZ to load the value from memory, instead of LWA.
4342(define_insn_and_split "ashdi3_extswsli"
4343  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4344	(ashift:DI
4345	 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4346	 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4347  "TARGET_EXTSWSLI"
4348  "@
4349   extswsli %0,%1,%2
4350   #"
4351  "&& reload_completed && MEM_P (operands[1])"
4352  [(set (match_dup 3)
4353	(match_dup 1))
4354   (set (match_dup 0)
4355	(ashift:DI (sign_extend:DI (match_dup 3))
4356		   (match_dup 2)))]
4357{
4358  operands[3] = gen_lowpart (SImode, operands[0]);
4359}
4360  [(set_attr "type" "shift")
4361   (set_attr "maybe_var_shift" "no")])
4362
4363
4364(define_insn_and_split "ashdi3_extswsli_dot"
4365  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4366	(compare:CC
4367	 (ashift:DI
4368	  (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4369	  (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4370	 (const_int 0)))
4371   (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4372  "TARGET_EXTSWSLI"
4373  "@
4374   extswsli. %0,%1,%2
4375   #
4376   #
4377   #"
4378  "&& reload_completed
4379   && (cc_reg_not_cr0_operand (operands[3], CCmode)
4380       || memory_operand (operands[1], SImode))"
4381  [(pc)]
4382{
4383  rtx dest = operands[0];
4384  rtx src = operands[1];
4385  rtx shift = operands[2];
4386  rtx cr = operands[3];
4387  rtx src2;
4388
4389  if (!MEM_P (src))
4390    src2 = src;
4391  else
4392    {
4393      src2 = gen_lowpart (SImode, dest);
4394      emit_move_insn (src2, src);
4395    }
4396
4397  if (REGNO (cr) == CR0_REGNO)
4398    {
4399      emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4400      DONE;
4401    }
4402
4403  emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4404  emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4405  DONE;
4406}
4407  [(set_attr "type" "shift")
4408   (set_attr "maybe_var_shift" "no")
4409   (set_attr "dot" "yes")
4410   (set_attr "length" "4,8,8,12")])
4411
4412(define_insn_and_split "ashdi3_extswsli_dot2"
4413  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4414	(compare:CC
4415	 (ashift:DI
4416	  (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4417	  (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4418	 (const_int 0)))
4419   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4420	(ashift:DI (sign_extend:DI (match_dup 1))
4421		   (match_dup 2)))]
4422  "TARGET_EXTSWSLI"
4423  "@
4424   extswsli. %0,%1,%2
4425   #
4426   #
4427   #"
4428  "&& reload_completed
4429   && (cc_reg_not_cr0_operand (operands[3], CCmode)
4430       || memory_operand (operands[1], SImode))"
4431  [(pc)]
4432{
4433  rtx dest = operands[0];
4434  rtx src = operands[1];
4435  rtx shift = operands[2];
4436  rtx cr = operands[3];
4437  rtx src2;
4438
4439  if (!MEM_P (src))
4440    src2 = src;
4441  else
4442    {
4443      src2 = gen_lowpart (SImode, dest);
4444      emit_move_insn (src2, src);
4445    }
4446
4447  if (REGNO (cr) == CR0_REGNO)
4448    {
4449      emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4450      DONE;
4451    }
4452
4453  emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4454  emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4455  DONE;
4456}
4457  [(set_attr "type" "shift")
4458   (set_attr "maybe_var_shift" "no")
4459   (set_attr "dot" "yes")
4460   (set_attr "length" "4,8,8,12")])
4461
4462(define_insn "lshr<mode>3"
4463  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4464	(lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4465		      (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4466  ""
4467  "sr<wd>%I2 %0,%1,%<hH>2"
4468  [(set_attr "type" "shift")
4469   (set_attr "maybe_var_shift" "yes")])
4470
4471(define_insn "*lshrsi3_64"
4472  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4473	(zero_extend:DI
4474	    (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4475			 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4476  "TARGET_POWERPC64"
4477  "srw%I2 %0,%1,%h2"
4478  [(set_attr "type" "shift")
4479   (set_attr "maybe_var_shift" "yes")])
4480
4481(define_insn_and_split "*lshr<mode>3_dot"
4482  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4483	(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4484				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4485		    (const_int 0)))
4486   (clobber (match_scratch:GPR 0 "=r,r"))]
4487  "<MODE>mode == Pmode"
4488  "@
4489   sr<wd>%I2. %0,%1,%<hH>2
4490   #"
4491  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4492  [(set (match_dup 0)
4493	(lshiftrt:GPR (match_dup 1)
4494		      (match_dup 2)))
4495   (set (match_dup 3)
4496	(compare:CC (match_dup 0)
4497		    (const_int 0)))]
4498  ""
4499  [(set_attr "type" "shift")
4500   (set_attr "maybe_var_shift" "yes")
4501   (set_attr "dot" "yes")
4502   (set_attr "length" "4,8")])
4503
4504(define_insn_and_split "*lshr<mode>3_dot2"
4505  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4506	(compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4507				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4508		    (const_int 0)))
4509   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4510	(lshiftrt:GPR (match_dup 1)
4511		      (match_dup 2)))]
4512  "<MODE>mode == Pmode"
4513  "@
4514   sr<wd>%I2. %0,%1,%<hH>2
4515   #"
4516  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4517  [(set (match_dup 0)
4518	(lshiftrt:GPR (match_dup 1)
4519		      (match_dup 2)))
4520   (set (match_dup 3)
4521	(compare:CC (match_dup 0)
4522		    (const_int 0)))]
4523  ""
4524  [(set_attr "type" "shift")
4525   (set_attr "maybe_var_shift" "yes")
4526   (set_attr "dot" "yes")
4527   (set_attr "length" "4,8")])
4528
4529
4530(define_insn "ashr<mode>3"
4531  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4532	(ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4533		      (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4534   (clobber (reg:GPR CA_REGNO))]
4535  ""
4536  "sra<wd>%I2 %0,%1,%<hH>2"
4537  [(set_attr "type" "shift")
4538   (set_attr "maybe_var_shift" "yes")])
4539
4540(define_insn "*ashrsi3_64"
4541  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4542	(sign_extend:DI
4543	    (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4544			 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4545   (clobber (reg:SI CA_REGNO))]
4546  "TARGET_POWERPC64"
4547  "sraw%I2 %0,%1,%h2"
4548  [(set_attr "type" "shift")
4549   (set_attr "maybe_var_shift" "yes")])
4550
4551(define_insn_and_split "*ashr<mode>3_dot"
4552  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4553	(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4554				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4555		    (const_int 0)))
4556   (clobber (match_scratch:GPR 0 "=r,r"))
4557   (clobber (reg:GPR CA_REGNO))]
4558  "<MODE>mode == Pmode"
4559  "@
4560   sra<wd>%I2. %0,%1,%<hH>2
4561   #"
4562  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4563  [(parallel [(set (match_dup 0)
4564		   (ashiftrt:GPR (match_dup 1)
4565				 (match_dup 2)))
4566	      (clobber (reg:GPR CA_REGNO))])
4567   (set (match_dup 3)
4568	(compare:CC (match_dup 0)
4569		    (const_int 0)))]
4570  ""
4571  [(set_attr "type" "shift")
4572   (set_attr "maybe_var_shift" "yes")
4573   (set_attr "dot" "yes")
4574   (set_attr "length" "4,8")])
4575
4576(define_insn_and_split "*ashr<mode>3_dot2"
4577  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4578	(compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4579				  (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4580		    (const_int 0)))
4581   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4582	(ashiftrt:GPR (match_dup 1)
4583		      (match_dup 2)))
4584   (clobber (reg:GPR CA_REGNO))]
4585  "<MODE>mode == Pmode"
4586  "@
4587   sra<wd>%I2. %0,%1,%<hH>2
4588   #"
4589  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4590  [(parallel [(set (match_dup 0)
4591		   (ashiftrt:GPR (match_dup 1)
4592				 (match_dup 2)))
4593	      (clobber (reg:GPR CA_REGNO))])
4594   (set (match_dup 3)
4595	(compare:CC (match_dup 0)
4596		    (const_int 0)))]
4597  ""
4598  [(set_attr "type" "shift")
4599   (set_attr "maybe_var_shift" "yes")
4600   (set_attr "dot" "yes")
4601   (set_attr "length" "4,8")])
4602
4603;; Builtins to replace a division to generate FRE reciprocal estimate
4604;; instructions and the necessary fixup instructions
4605(define_expand "recip<mode>3"
4606  [(match_operand:RECIPF 0 "gpc_reg_operand")
4607   (match_operand:RECIPF 1 "gpc_reg_operand")
4608   (match_operand:RECIPF 2 "gpc_reg_operand")]
4609  "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4610{
4611   rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4612   DONE;
4613})
4614
4615;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4616;; hardware division.  This is only done before register allocation and with
4617;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4618;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4619;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4620(define_split
4621  [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4622	(div:RECIPF (match_operand 1 "gpc_reg_operand")
4623		    (match_operand 2 "gpc_reg_operand")))]
4624  "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4625   && can_create_pseudo_p () && flag_finite_math_only
4626   && !flag_trapping_math && flag_reciprocal_math"
4627  [(const_int 0)]
4628{
4629  rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4630  DONE;
4631})
4632
4633;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4634;; appropriate fixup.
4635(define_expand "rsqrt<mode>2"
4636  [(match_operand:RECIPF 0 "gpc_reg_operand")
4637   (match_operand:RECIPF 1 "gpc_reg_operand")]
4638  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4639{
4640  rs6000_emit_swsqrt (operands[0], operands[1], 1);
4641  DONE;
4642})
4643
4644;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4645;; modes here, and also add in conditional vsx/power8-vector support to access
4646;; values in the traditional Altivec registers if the appropriate
4647;; -mupper-regs-{df,sf} option is enabled.
4648
4649(define_expand "abs<mode>2"
4650  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4651	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4652  "TARGET_HARD_FLOAT"
4653  "")
4654
4655(define_insn "*abs<mode>2_fpr"
4656  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4657	(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4658  "TARGET_HARD_FLOAT"
4659  "@
4660   fabs %0,%1
4661   xsabsdp %x0,%x1"
4662  [(set_attr "type" "fpsimple")])
4663
4664(define_insn "*nabs<mode>2_fpr"
4665  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4666	(neg:SFDF
4667	 (abs:SFDF
4668	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4669  "TARGET_HARD_FLOAT"
4670  "@
4671   fnabs %0,%1
4672   xsnabsdp %x0,%x1"
4673  [(set_attr "type" "fpsimple")])
4674
4675(define_expand "neg<mode>2"
4676  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4677	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4678  "TARGET_HARD_FLOAT"
4679  "")
4680
4681(define_insn "*neg<mode>2_fpr"
4682  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4683	(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4684  "TARGET_HARD_FLOAT"
4685  "@
4686   fneg %0,%1
4687   xsnegdp %x0,%x1"
4688  [(set_attr "type" "fpsimple")])
4689
4690(define_expand "add<mode>3"
4691  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4692	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4693		   (match_operand:SFDF 2 "gpc_reg_operand")))]
4694  "TARGET_HARD_FLOAT"
4695  "")
4696
4697(define_insn "*add<mode>3_fpr"
4698  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4699	(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4700		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4701  "TARGET_HARD_FLOAT"
4702  "@
4703   fadd<s> %0,%1,%2
4704   xsadd<sd>p %x0,%x1,%x2"
4705  [(set_attr "type" "fp")
4706   (set_attr "isa" "*,<Fisa>")])
4707
4708(define_expand "sub<mode>3"
4709  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4710	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4711		    (match_operand:SFDF 2 "gpc_reg_operand")))]
4712  "TARGET_HARD_FLOAT"
4713  "")
4714
4715(define_insn "*sub<mode>3_fpr"
4716  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4717	(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4718		    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4719  "TARGET_HARD_FLOAT"
4720  "@
4721   fsub<s> %0,%1,%2
4722   xssub<sd>p %x0,%x1,%x2"
4723  [(set_attr "type" "fp")
4724   (set_attr "isa" "*,<Fisa>")])
4725
4726(define_expand "mul<mode>3"
4727  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4728	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4729		   (match_operand:SFDF 2 "gpc_reg_operand")))]
4730  "TARGET_HARD_FLOAT"
4731  "")
4732
4733(define_insn "*mul<mode>3_fpr"
4734  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4735	(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4736		   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4737  "TARGET_HARD_FLOAT"
4738  "@
4739   fmul<s> %0,%1,%2
4740   xsmul<sd>p %x0,%x1,%x2"
4741  [(set_attr "type" "dmul")
4742   (set_attr "isa" "*,<Fisa>")])
4743
4744(define_expand "div<mode>3"
4745  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4746	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4747		  (match_operand:SFDF 2 "gpc_reg_operand")))]
4748  "TARGET_HARD_FLOAT"
4749{
4750  if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4751      && can_create_pseudo_p () && flag_finite_math_only
4752      && !flag_trapping_math && flag_reciprocal_math)
4753    {
4754      rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4755      DONE;
4756    }
4757})
4758
4759(define_insn "*div<mode>3_fpr"
4760  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4761	(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4762		  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4763  "TARGET_HARD_FLOAT"
4764  "@
4765   fdiv<s> %0,%1,%2
4766   xsdiv<sd>p %x0,%x1,%x2"
4767  [(set_attr "type" "<sd>div")
4768   (set_attr "isa" "*,<Fisa>")])
4769
4770(define_insn "*sqrt<mode>2_internal"
4771  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4772	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4773  "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4774  "@
4775   fsqrt<s> %0,%1
4776   xssqrt<sd>p %x0,%x1"
4777  [(set_attr "type" "<sd>sqrt")
4778   (set_attr "isa" "*,<Fisa>")])
4779
4780(define_expand "sqrt<mode>2"
4781  [(set (match_operand:SFDF 0 "gpc_reg_operand")
4782	(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4783  "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4784{
4785  if (<MODE>mode == SFmode
4786      && TARGET_RECIP_PRECISION
4787      && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4788      && !optimize_function_for_size_p (cfun)
4789      && flag_finite_math_only && !flag_trapping_math
4790      && flag_unsafe_math_optimizations)
4791    {
4792      rs6000_emit_swsqrt (operands[0], operands[1], 0);
4793      DONE;
4794    }
4795})
4796
4797;; Floating point reciprocal approximation
4798(define_insn "fre<sd>"
4799  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4800	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4801		     UNSPEC_FRES))]
4802  "TARGET_<FFRE>"
4803  "@
4804   fre<s> %0,%1
4805   xsre<sd>p %x0,%x1"
4806  [(set_attr "type" "fp")
4807   (set_attr "isa" "*,<Fisa>")])
4808
4809(define_insn "*rsqrt<mode>2"
4810  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4811	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4812		     UNSPEC_RSQRT))]
4813  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4814  "@
4815   frsqrte<s> %0,%1
4816   xsrsqrte<sd>p %x0,%x1"
4817  [(set_attr "type" "fp")
4818   (set_attr "isa" "*,<Fisa>")])
4819
4820;; Floating point comparisons
4821(define_insn "*cmp<mode>_fpr"
4822  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4823	(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4824		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4825  "TARGET_HARD_FLOAT"
4826  "@
4827   fcmpu %0,%1,%2
4828   xscmpudp %0,%x1,%x2"
4829  [(set_attr "type" "fpcompare")
4830   (set_attr "isa" "*,<Fisa>")])
4831
4832;; Floating point conversions
4833(define_expand "extendsfdf2"
4834  [(set (match_operand:DF 0 "gpc_reg_operand")
4835	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4836  "TARGET_HARD_FLOAT"
4837{
4838  if (HONOR_SNANS (SFmode))
4839    operands[1] = force_reg (SFmode, operands[1]);
4840})
4841
4842(define_insn_and_split "*extendsfdf2_fpr"
4843  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4844	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4845  "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4846  "@
4847   #
4848   fmr %0,%1
4849   lfs%U1%X1 %0,%1
4850   #
4851   xscpsgndp %x0,%x1,%x1
4852   lxsspx %x0,%y1
4853   lxssp %0,%1"
4854  "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4855  [(const_int 0)]
4856{
4857  emit_note (NOTE_INSN_DELETED);
4858  DONE;
4859}
4860  [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4861   (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4862
4863(define_insn "*extendsfdf2_snan"
4864  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4865	(float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4866  "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4867  "@
4868   frsp %0,%1
4869   xsrsp %x0,%x1"
4870  [(set_attr "type" "fp")
4871   (set_attr "isa" "*,p8v")])
4872
4873(define_expand "truncdfsf2"
4874  [(set (match_operand:SF 0 "gpc_reg_operand")
4875	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4876  "TARGET_HARD_FLOAT"
4877  "")
4878
4879(define_insn "*truncdfsf2_fpr"
4880  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4881	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4882  "TARGET_HARD_FLOAT"
4883  "@
4884   frsp %0,%1
4885   xsrsp %x0,%x1"
4886  [(set_attr "type" "fp")
4887   (set_attr "isa" "*,p8v")])
4888
4889;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4890;; builtins.c and optabs.c that are not correct for IBM long double
4891;; when little-endian.
4892(define_expand "signbit<mode>2"
4893  [(set (match_dup 2)
4894	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4895   (set (match_dup 3)
4896   	(subreg:DI (match_dup 2) 0))
4897   (set (match_dup 4)
4898   	(match_dup 5))
4899   (set (match_operand:SI 0 "gpc_reg_operand")
4900  	(match_dup 6))]
4901  "TARGET_HARD_FLOAT
4902   && (!FLOAT128_IEEE_P (<MODE>mode)
4903       || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4904{
4905  if (FLOAT128_IEEE_P (<MODE>mode))
4906    {
4907      rtx dest = operands[0];
4908      rtx src = operands[1];
4909      rtx tmp = gen_reg_rtx (DImode);
4910      rtx dest_di = gen_lowpart (DImode, dest);
4911
4912      emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4913      emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4914      DONE;
4915    }
4916  operands[2] = gen_reg_rtx (DFmode);
4917  operands[3] = gen_reg_rtx (DImode);
4918  if (TARGET_POWERPC64)
4919    {
4920      operands[4] = gen_reg_rtx (DImode);
4921      operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4922      operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4923				    WORDS_BIG_ENDIAN ? 4 : 0);
4924    }
4925  else
4926    {
4927      operands[4] = gen_reg_rtx (SImode);
4928      operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4929				    WORDS_BIG_ENDIAN ? 0 : 4);
4930      operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4931    }
4932})
4933
4934;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4935;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4936;; register allocator would typically move the entire _Float128 item to GPRs (2
4937;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4938;;
4939;; After register allocation, if the _Float128 had originally been in GPRs, the
4940;; split allows the post reload phases to eliminate the move, and do the shift
4941;; directly with the register that contains the signbit.
4942(define_insn_and_split "@signbit<mode>2_dm"
4943  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4944	(unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4945		   UNSPEC_SIGNBIT))]
4946  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4947  "@
4948   mfvsrd %0,%x1
4949   #"
4950  "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4951  [(set (match_dup 0)
4952	(match_dup 2))]
4953{
4954  operands[2] = gen_highpart (DImode, operands[1]);
4955}
4956 [(set_attr "type" "mftgpr,*")])
4957
4958;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4959;; register and then doing a direct move if the value comes from memory.  On
4960;; little endian, we have to load the 2nd double-word to get the sign bit.
4961(define_insn_and_split "*signbit<mode>2_dm_mem"
4962  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4963	(unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4964		   UNSPEC_SIGNBIT))]
4965  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4966  "#"
4967  "&& 1"
4968  [(set (match_dup 0)
4969	(match_dup 2))]
4970{
4971  rtx dest = operands[0];
4972  rtx src = operands[1];
4973  rtx addr = XEXP (src, 0);
4974
4975  if (WORDS_BIG_ENDIAN)
4976    operands[2] = adjust_address (src, DImode, 0);
4977
4978  else if (REG_P (addr) || SUBREG_P (addr))
4979    operands[2] = adjust_address (src, DImode, 8);
4980
4981  else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4982	   && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4983    operands[2] = adjust_address (src, DImode, 8);
4984
4985  else
4986    {
4987      rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4988      emit_insn (gen_rtx_SET (tmp, addr));
4989      operands[2] = change_address (src, DImode,
4990				    gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4991    }
4992})
4993
4994(define_expand "copysign<mode>3"
4995  [(set (match_dup 3)
4996        (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4997   (set (match_dup 4)
4998	(neg:SFDF (abs:SFDF (match_dup 1))))
4999   (set (match_operand:SFDF 0 "gpc_reg_operand")
5000        (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5001			       (match_dup 5))
5002			 (match_dup 3)
5003			 (match_dup 4)))]
5004  "TARGET_HARD_FLOAT
5005   && ((TARGET_PPC_GFXOPT
5006        && !HONOR_NANS (<MODE>mode)
5007        && !HONOR_SIGNED_ZEROS (<MODE>mode))
5008       || TARGET_CMPB
5009       || VECTOR_UNIT_VSX_P (<MODE>mode))"
5010{
5011  if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5012    {
5013      emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5014					     operands[2]));
5015      DONE;
5016    }
5017
5018   operands[3] = gen_reg_rtx (<MODE>mode);
5019   operands[4] = gen_reg_rtx (<MODE>mode);
5020   operands[5] = CONST0_RTX (<MODE>mode);
5021  })
5022
5023;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5024;; compiler from optimizing -0.0
5025(define_insn "copysign<mode>3_fcpsgn"
5026  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5027	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5028		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5029		     UNSPEC_COPYSIGN))]
5030  "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5031  "@
5032   fcpsgn %0,%2,%1
5033   xscpsgndp %x0,%x2,%x1"
5034  [(set_attr "type" "fpsimple")])
5035
5036;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5037;; fsel instruction and some auxiliary computations.  Then we just have a
5038;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5039;; combine.
5040;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5041;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5042;; computations.  Then we just have a single DEFINE_INSN for fsel and the
5043;; define_splits to make them if made by combine.  On VSX machines we have the
5044;; min/max instructions.
5045;;
5046;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5047;; to allow either DF/SF to use only traditional registers.
5048
5049(define_expand "s<minmax><mode>3"
5050  [(set (match_operand:SFDF 0 "gpc_reg_operand")
5051	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5052			(match_operand:SFDF 2 "gpc_reg_operand")))]
5053  "TARGET_MINMAX"
5054{
5055  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5056  DONE;
5057})
5058
5059(define_insn "*s<minmax><mode>3_vsx"
5060  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5061	(fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5062			(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5063  "TARGET_VSX && TARGET_HARD_FLOAT"
5064{
5065  return (TARGET_P9_MINMAX
5066	  ? "xs<minmax>cdp %x0,%x1,%x2"
5067	  : "xs<minmax>dp %x0,%x1,%x2");
5068}
5069  [(set_attr "type" "fp")])
5070
5071;; The conditional move instructions allow us to perform max and min operations
5072;; even when we don't have the appropriate max/min instruction using the FSEL
5073;; instruction.
5074
5075(define_insn_and_split "*s<minmax><mode>3_fpr"
5076  [(set (match_operand:SFDF 0 "gpc_reg_operand")
5077	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5078			(match_operand:SFDF 2 "gpc_reg_operand")))]
5079  "!TARGET_VSX && TARGET_MINMAX"
5080  "#"
5081  "&& 1"
5082  [(const_int 0)]
5083{
5084  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5085  DONE;
5086})
5087
5088(define_expand "mov<mode>cc"
5089   [(set (match_operand:GPR 0 "gpc_reg_operand")
5090	 (if_then_else:GPR (match_operand 1 "comparison_operator")
5091			   (match_operand:GPR 2 "gpc_reg_operand")
5092			   (match_operand:GPR 3 "gpc_reg_operand")))]
5093  "TARGET_ISEL"
5094{
5095  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5096    DONE;
5097  else
5098    FAIL;
5099})
5100
5101;; We use the BASE_REGS for the isel input operands because, if rA is
5102;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5103;; because we may switch the operands and rB may end up being rA.
5104;;
5105;; We need 2 patterns: an unsigned and a signed pattern.  We could
5106;; leave out the mode in operand 4 and use one pattern, but reload can
5107;; change the mode underneath our feet and then gets confused trying
5108;; to reload the value.
5109(define_mode_iterator CCEITHER [CC CCUNS])
5110(define_mode_attr un [(CC "") (CCUNS "un")])
5111(define_insn "isel_<un>signed_<GPR:mode>"
5112  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5113	(if_then_else:GPR
5114	 (match_operator 1 "scc_comparison_operator"
5115			 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5116			  (const_int 0)])
5117	 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5118	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5119  "TARGET_ISEL"
5120  "isel %0,%2,%3,%j1"
5121  [(set_attr "type" "isel")])
5122
5123;; These patterns can be useful for combine; they let combine know that
5124;; isel can handle reversed comparisons so long as the operands are
5125;; registers.
5126
5127(define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5128  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5129	(if_then_else:GPR
5130	 (match_operator 1 "scc_rev_comparison_operator"
5131			 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5132			  (const_int 0)])
5133	 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5134	 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5135  "TARGET_ISEL"
5136{
5137  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5138  return "isel %0,%3,%2,%j1";
5139}
5140  [(set_attr "type" "isel")])
5141
5142;; Floating point conditional move
5143(define_expand "mov<mode>cc"
5144   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5145	 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5146			    (match_operand:SFDF 2 "gpc_reg_operand")
5147			    (match_operand:SFDF 3 "gpc_reg_operand")))]
5148  "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5149{
5150  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5151    DONE;
5152  else
5153    FAIL;
5154})
5155
5156(define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5157  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5158	(if_then_else:SFDF
5159	 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5160	     (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5161	 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5162	 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5163  "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5164  "fsel %0,%1,%2,%3"
5165  [(set_attr "type" "fp")])
5166
5167(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5168  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5169	(if_then_else:SFDF
5170	 (match_operator:CCFP 1 "fpmask_comparison_operator"
5171		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5172		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5173	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5174	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5175   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5176  "TARGET_P9_MINMAX"
5177  "#"
5178  ""
5179  [(set (match_dup 6)
5180	(if_then_else:V2DI (match_dup 1)
5181			   (match_dup 7)
5182			   (match_dup 8)))
5183   (set (match_dup 0)
5184	(if_then_else:SFDF (ne (match_dup 6)
5185			       (match_dup 8))
5186			   (match_dup 4)
5187			   (match_dup 5)))]
5188{
5189  if (GET_CODE (operands[6]) == SCRATCH)
5190    operands[6] = gen_reg_rtx (V2DImode);
5191
5192  operands[7] = CONSTM1_RTX (V2DImode);
5193  operands[8] = CONST0_RTX (V2DImode);
5194}
5195 [(set_attr "length" "8")
5196  (set_attr "type" "vecperm")])
5197
5198;; Handle inverting the fpmask comparisons.
5199(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5200  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5201	(if_then_else:SFDF
5202	 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5203		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5204		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5205	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5206	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5207   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5208  "TARGET_P9_MINMAX"
5209  "#"
5210  "&& 1"
5211  [(set (match_dup 6)
5212	(if_then_else:V2DI (match_dup 9)
5213			   (match_dup 7)
5214			   (match_dup 8)))
5215   (set (match_dup 0)
5216	(if_then_else:SFDF (ne (match_dup 6)
5217			       (match_dup 8))
5218			   (match_dup 5)
5219			   (match_dup 4)))]
5220{
5221  rtx op1 = operands[1];
5222  enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5223
5224  if (GET_CODE (operands[6]) == SCRATCH)
5225    operands[6] = gen_reg_rtx (V2DImode);
5226
5227  operands[7] = CONSTM1_RTX (V2DImode);
5228  operands[8] = CONST0_RTX (V2DImode);
5229
5230  operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5231}
5232 [(set_attr "length" "8")
5233  (set_attr "type" "vecperm")])
5234
5235(define_insn "*fpmask<mode>"
5236  [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5237	(if_then_else:V2DI
5238	 (match_operator:CCFP 1 "fpmask_comparison_operator"
5239		[(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5240		 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5241	 (match_operand:V2DI 4 "all_ones_constant" "")
5242	 (match_operand:V2DI 5 "zero_constant" "")))]
5243  "TARGET_P9_MINMAX"
5244  "xscmp%V1dp %x0,%x2,%x3"
5245  [(set_attr "type" "fpcompare")])
5246
5247(define_insn "*xxsel<mode>"
5248  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5249	(if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5250			       (match_operand:V2DI 2 "zero_constant" ""))
5251			   (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5252			   (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5253  "TARGET_P9_MINMAX"
5254  "xxsel %x0,%x4,%x3,%x1"
5255  [(set_attr "type" "vecmove")])
5256
5257
5258;; Conversions to and from floating-point.
5259
5260; We don't define lfiwax/lfiwzx with the normal definition, because we
5261; don't want to support putting SImode in FPR registers.
5262(define_insn "lfiwax"
5263  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5264	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5265		   UNSPEC_LFIWAX))]
5266  "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5267  "@
5268   lfiwax %0,%y1
5269   lxsiwax %x0,%y1
5270   mtvsrwa %x0,%1
5271   vextsw2d %0,%1"
5272  [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5273   (set_attr "isa" "*,p8v,p8v,p9v")])
5274
5275; This split must be run before register allocation because it allocates the
5276; memory slot that is needed to move values to/from the FPR.  We don't allocate
5277; it earlier to allow for the combiner to merge insns together where it might
5278; not be needed and also in case the insns are deleted as dead code.
5279
5280(define_insn_and_split "floatsi<mode>2_lfiwax"
5281  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5282	(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5283   (clobber (match_scratch:DI 2 "=d,wa"))]
5284  "TARGET_HARD_FLOAT && TARGET_LFIWAX
5285   && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5286  "#"
5287  ""
5288  [(pc)]
5289{
5290  rtx dest = operands[0];
5291  rtx src = operands[1];
5292  rtx tmp;
5293
5294  if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5295    tmp = convert_to_mode (DImode, src, false);
5296  else
5297    {
5298      tmp = operands[2];
5299      if (GET_CODE (tmp) == SCRATCH)
5300	tmp = gen_reg_rtx (DImode);
5301      if (MEM_P (src))
5302	{
5303	  src = rs6000_force_indexed_or_indirect_mem (src);
5304	  emit_insn (gen_lfiwax (tmp, src));
5305	}
5306      else
5307	{
5308	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5309	  emit_move_insn (stack, src);
5310	  emit_insn (gen_lfiwax (tmp, stack));
5311	}
5312    }
5313  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5314  DONE;
5315}
5316  [(set_attr "length" "12")
5317   (set_attr "type" "fpload")])
5318
5319(define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5320  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5321	(float:SFDF
5322	 (sign_extend:DI
5323	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5324   (clobber (match_scratch:DI 2 "=d,wa"))]
5325  "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5326  "#"
5327  ""
5328  [(pc)]
5329{
5330  operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5331  if (GET_CODE (operands[2]) == SCRATCH)
5332    operands[2] = gen_reg_rtx (DImode);
5333  if (TARGET_P8_VECTOR)
5334    emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5335  else
5336    emit_insn (gen_lfiwax (operands[2], operands[1]));
5337  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5338  DONE;
5339}
5340  [(set_attr "length" "8")
5341   (set_attr "type" "fpload")])
5342
5343(define_insn "lfiwzx"
5344  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5345	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5346		   UNSPEC_LFIWZX))]
5347  "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5348  "@
5349   lfiwzx %0,%y1
5350   lxsiwzx %x0,%y1
5351   mtvsrwz %x0,%1
5352   xxextractuw %x0,%x1,4"
5353  [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5354   (set_attr "isa" "*,p8v,p8v,p9v")])
5355
5356(define_insn_and_split "floatunssi<mode>2_lfiwzx"
5357  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5358	(unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5359   (clobber (match_scratch:DI 2 "=d,wa"))]
5360  "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5361  "#"
5362  ""
5363  [(pc)]
5364{
5365  rtx dest = operands[0];
5366  rtx src = operands[1];
5367  rtx tmp;
5368
5369  if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5370    tmp = convert_to_mode (DImode, src, true);
5371  else
5372    {
5373      tmp = operands[2];
5374      if (GET_CODE (tmp) == SCRATCH)
5375	tmp = gen_reg_rtx (DImode);
5376      if (MEM_P (src))
5377	{
5378	  src = rs6000_force_indexed_or_indirect_mem (src);
5379	  emit_insn (gen_lfiwzx (tmp, src));
5380	}
5381      else
5382	{
5383	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5384	  emit_move_insn (stack, src);
5385	  emit_insn (gen_lfiwzx (tmp, stack));
5386	}
5387    }
5388  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5389  DONE;
5390}
5391  [(set_attr "length" "12")
5392   (set_attr "type" "fpload")])
5393
5394(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5395  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5396	(unsigned_float:SFDF
5397	 (zero_extend:DI
5398	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5399   (clobber (match_scratch:DI 2 "=d,wa"))]
5400  "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5401  "#"
5402  ""
5403  [(pc)]
5404{
5405  operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5406  if (GET_CODE (operands[2]) == SCRATCH)
5407    operands[2] = gen_reg_rtx (DImode);
5408  if (TARGET_P8_VECTOR)
5409    emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5410  else
5411    emit_insn (gen_lfiwzx (operands[2], operands[1]));
5412  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5413  DONE;
5414}
5415  [(set_attr "length" "8")
5416   (set_attr "type" "fpload")])
5417
5418; For each of these conversions, there is a define_expand, a define_insn
5419; with a '#' template, and a define_split (with C code).  The idea is
5420; to allow constant folding with the template of the define_insn,
5421; then to have the insns split later (between sched1 and final).
5422
5423(define_expand "floatsidf2"
5424  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5425		   (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5426	      (use (match_dup 2))
5427	      (use (match_dup 3))
5428	      (clobber (match_dup 4))
5429	      (clobber (match_dup 5))
5430	      (clobber (match_dup 6))])]
5431  "TARGET_HARD_FLOAT"
5432{
5433  if (TARGET_LFIWAX && TARGET_FCFID)
5434    {
5435      emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5436      DONE;
5437    }
5438  else if (TARGET_FCFID)
5439    {
5440      rtx dreg = operands[1];
5441      if (!REG_P (dreg))
5442	dreg = force_reg (SImode, dreg);
5443      dreg = convert_to_mode (DImode, dreg, false);
5444      emit_insn (gen_floatdidf2 (operands[0], dreg));
5445      DONE;
5446    }
5447
5448  if (!REG_P (operands[1]))
5449    operands[1] = force_reg (SImode, operands[1]);
5450  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5451  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5452  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5453  operands[5] = gen_reg_rtx (DFmode);
5454  operands[6] = gen_reg_rtx (SImode);
5455})
5456
5457(define_insn_and_split "*floatsidf2_internal"
5458  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5459	(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   (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5465  "!TARGET_FCFID && TARGET_HARD_FLOAT"
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_insn (gen_xorsi3 (operands[6], operands[1],
5478			 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5479  emit_move_insn (lowword, operands[6]);
5480  emit_move_insn (highword, operands[2]);
5481  emit_move_insn (operands[5], operands[4]);
5482  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5483  DONE;
5484}
5485  [(set_attr "length" "24")
5486   (set_attr "type" "fp")])
5487
5488;; If we don't have a direct conversion to single precision, don't enable this
5489;; conversion for 32-bit without fast math, because we don't have the insn to
5490;; generate the fixup swizzle to avoid double rounding problems.
5491(define_expand "floatunssisf2"
5492  [(set (match_operand:SF 0 "gpc_reg_operand")
5493        (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5494  "TARGET_HARD_FLOAT
5495   && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5496       || (TARGET_FCFID
5497	   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5498{
5499  if (TARGET_LFIWZX && TARGET_FCFIDUS)
5500    {
5501      emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5502      DONE;
5503    }
5504  else
5505    {
5506      rtx dreg = operands[1];
5507      if (!REG_P (dreg))
5508	dreg = force_reg (SImode, dreg);
5509      dreg = convert_to_mode (DImode, dreg, true);
5510      emit_insn (gen_floatdisf2 (operands[0], dreg));
5511      DONE;
5512    }
5513})
5514
5515(define_expand "floatunssidf2"
5516  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5517		   (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5518	      (use (match_dup 2))
5519	      (use (match_dup 3))
5520	      (clobber (match_dup 4))
5521	      (clobber (match_dup 5))])]
5522  "TARGET_HARD_FLOAT"
5523{
5524  if (TARGET_LFIWZX && TARGET_FCFID)
5525    {
5526      emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5527      DONE;
5528    }
5529  else if (TARGET_FCFID)
5530    {
5531      rtx dreg = operands[1];
5532      if (!REG_P (dreg))
5533	dreg = force_reg (SImode, dreg);
5534      dreg = convert_to_mode (DImode, dreg, true);
5535      emit_insn (gen_floatdidf2 (operands[0], dreg));
5536      DONE;
5537    }
5538
5539  if (!REG_P (operands[1]))
5540    operands[1] = force_reg (SImode, operands[1]);
5541  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5542  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5543  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5544  operands[5] = gen_reg_rtx (DFmode);
5545})
5546
5547(define_insn_and_split "*floatunssidf2_internal"
5548  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5549	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5550   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5551   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5552   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5553   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5554  "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5555   && !(TARGET_FCFID && TARGET_POWERPC64)"
5556  "#"
5557  ""
5558  [(pc)]
5559{
5560  rtx lowword, highword;
5561  gcc_assert (MEM_P (operands[4]));
5562  highword = adjust_address (operands[4], SImode, 0);
5563  lowword = adjust_address (operands[4], SImode, 4);
5564  if (! WORDS_BIG_ENDIAN)
5565    std::swap (lowword, highword);
5566
5567  emit_move_insn (lowword, operands[1]);
5568  emit_move_insn (highword, operands[2]);
5569  emit_move_insn (operands[5], operands[4]);
5570  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5571  DONE;
5572}
5573  [(set_attr "length" "20")
5574   (set_attr "type" "fp")])
5575
5576;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5577;; vector registers.  These insns favor doing the sign/zero extension in
5578;; the vector registers, rather then loading up a GPR, doing a sign/zero
5579;; extension and then a direct move.
5580
5581(define_expand "float<QHI:mode><FP_ISA3:mode>2"
5582  [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5583		   (float:FP_ISA3
5584		    (match_operand:QHI 1 "input_operand")))
5585	      (clobber (match_scratch:DI 2))
5586	      (clobber (match_scratch:DI 3))
5587	      (clobber (match_scratch:<QHI:MODE> 4))])]
5588  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5589{
5590  if (MEM_P (operands[1]))
5591    operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5592})
5593
5594(define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5595  [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5596	(float:FP_ISA3
5597	 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5598   (clobber (match_scratch:DI 2 "=v,wa,v"))
5599   (clobber (match_scratch:DI 3 "=X,r,X"))
5600   (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5601  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5602  "#"
5603  "&& reload_completed"
5604  [(const_int 0)]
5605{
5606  rtx result = operands[0];
5607  rtx input = operands[1];
5608  rtx di = operands[2];
5609
5610  if (!MEM_P (input))
5611    {
5612      rtx tmp = operands[3];
5613      if (altivec_register_operand (input, <QHI:MODE>mode))
5614	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5615      else if (GET_CODE (tmp) == SCRATCH)
5616	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5617      else
5618	{
5619	  emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5620	  emit_move_insn (di, tmp);
5621	}
5622    }
5623  else
5624    {
5625      rtx tmp = operands[4];
5626      emit_move_insn (tmp, input);
5627      emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5628    }
5629
5630  emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5631  DONE;
5632}
5633  [(set_attr "isa" "p9v,*,p9v")])
5634
5635(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5636  [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5637		   (unsigned_float:FP_ISA3
5638		    (match_operand:QHI 1 "input_operand")))
5639	      (clobber (match_scratch:DI 2))
5640	      (clobber (match_scratch:DI 3))])]
5641  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5642{
5643  if (MEM_P (operands[1]))
5644    operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5645})
5646
5647(define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5648  [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5649	(unsigned_float:FP_ISA3
5650	 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5651   (clobber (match_scratch:DI 2 "=v,wa,wa"))
5652   (clobber (match_scratch:DI 3 "=X,r,X"))]
5653  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5654  "#"
5655  "&& reload_completed"
5656  [(const_int 0)]
5657{
5658  rtx result = operands[0];
5659  rtx input = operands[1];
5660  rtx di = operands[2];
5661
5662  if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5663    emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5664  else
5665    {
5666      rtx tmp = operands[3];
5667      if (GET_CODE (tmp) == SCRATCH)
5668	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5669      else
5670	{
5671	  emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5672	  emit_move_insn (di, tmp);
5673	}
5674    }
5675
5676  emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5677  DONE;
5678}
5679  [(set_attr "isa" "p9v,*,p9v")])
5680
5681(define_expand "fix_trunc<mode>si2"
5682  [(set (match_operand:SI 0 "gpc_reg_operand")
5683	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5684  "TARGET_HARD_FLOAT"
5685{
5686  if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5687    {
5688      rtx src = force_reg (<MODE>mode, operands[1]);
5689
5690      if (TARGET_STFIWX)
5691	emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5692      else
5693	{
5694	  rtx tmp = gen_reg_rtx (DImode);
5695	  rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5696	  emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5697						      tmp, stack));
5698	}
5699      DONE;
5700    }
5701})
5702
5703; Like the convert to float patterns, this insn must be split before
5704; register allocation so that it can allocate the memory slot if it
5705; needed
5706(define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5707  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5708	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5709   (clobber (match_scratch:DI 2 "=d"))]
5710  "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5711   && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5712  "#"
5713  ""
5714  [(pc)]
5715{
5716  rtx dest = operands[0];
5717  rtx src = operands[1];
5718  rtx tmp = operands[2];
5719
5720  if (GET_CODE (tmp) == SCRATCH)
5721    tmp = gen_reg_rtx (DImode);
5722
5723  emit_insn (gen_fctiwz_<mode> (tmp, src));
5724  if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5725    {
5726      dest = rs6000_force_indexed_or_indirect_mem (dest);
5727      emit_insn (gen_stfiwx (dest, tmp));
5728      DONE;
5729    }
5730  else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5731    {
5732      dest = gen_lowpart (DImode, dest);
5733      emit_move_insn (dest, tmp);
5734      DONE;
5735    }
5736  else
5737    {
5738      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5739      emit_insn (gen_stfiwx (stack, tmp));
5740      emit_move_insn (dest, stack);
5741      DONE;
5742    }
5743}
5744  [(set_attr "length" "12")
5745   (set_attr "type" "fp")])
5746
5747(define_insn_and_split "fix_trunc<mode>si2_internal"
5748  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5749	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5750   (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5751   (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5752  "TARGET_HARD_FLOAT
5753   && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5754  "#"
5755  ""
5756  [(pc)]
5757{
5758  rtx lowword;
5759  gcc_assert (MEM_P (operands[3]));
5760  lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5761
5762  emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5763  emit_move_insn (operands[3], operands[2]);
5764  emit_move_insn (operands[0], lowword);
5765  DONE;
5766}
5767  [(set_attr "length" "16")
5768   (set_attr "type" "fp")])
5769
5770(define_expand "fix_trunc<mode>di2"
5771  [(set (match_operand:DI 0 "gpc_reg_operand")
5772	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5773  "TARGET_HARD_FLOAT && TARGET_FCFID"
5774  "")
5775
5776(define_insn "*fix_trunc<mode>di2_fctidz"
5777  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5778	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5779  "TARGET_HARD_FLOAT && TARGET_FCFID"
5780  "@
5781   fctidz %0,%1
5782   xscvdpsxds %x0,%x1"
5783  [(set_attr "type" "fp")])
5784
5785;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5786;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5787;; vector registers, so we need to do direct moves to the GPRs, but SImode
5788;; values can go in VSX registers.  Keeping the direct move part through
5789;; register allocation prevents the register allocator from doing a direct move
5790;; of the SImode value to a GPR, and then a store/load.
5791(define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5792  [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5793	(any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5794   (clobber (match_scratch:SI 2 "=X,X,wa"))]
5795  "TARGET_DIRECT_MOVE"
5796  "@
5797   fctiw<u>z %0,%1
5798   xscvdp<su>xws %x0,%x1
5799   #"
5800  "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5801  [(set (match_dup 2)
5802	(any_fix:SI (match_dup 1)))
5803   (set (match_dup 3)
5804	(match_dup 2))]
5805{
5806  operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5807}
5808  [(set_attr "type" "fp")
5809   (set_attr "length" "4,4,8")
5810   (set_attr "isa" "p9v,p9v,*")])
5811
5812(define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5813  [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5814	(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5815  "TARGET_DIRECT_MOVE"
5816  "@
5817   fctiw<u>z %0,%1
5818   xscvdp<su>xws %x0,%x1"
5819  [(set_attr "type" "fp")])
5820
5821;; Keep the convert and store together through register allocation to prevent
5822;; the register allocator from getting clever and doing a direct move to a GPR
5823;; and then store for reg+offset stores.
5824(define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5825  [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5826	(any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5827   (clobber (match_scratch:SI 2 "=wa"))]
5828    "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5829  "#"
5830  "&& reload_completed"
5831  [(set (match_dup 2)
5832	(any_fix:SI (match_dup 1)))
5833   (set (match_dup 0)
5834	(match_dup 3))]
5835{
5836  operands[3] = (<QHSI:MODE>mode == SImode
5837		 ? operands[2]
5838		 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5839})
5840
5841(define_expand "fixuns_trunc<mode>si2"
5842  [(set (match_operand:SI 0 "gpc_reg_operand")
5843	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5844  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5845{
5846  if (!TARGET_P8_VECTOR)
5847    {
5848      emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5849      DONE;
5850    }
5851})
5852
5853(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5854  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5855	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5856   (clobber (match_scratch:DI 2 "=d"))]
5857  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5858   && TARGET_STFIWX && can_create_pseudo_p ()
5859   && !TARGET_P8_VECTOR"
5860  "#"
5861  ""
5862  [(pc)]
5863{
5864  rtx dest = operands[0];
5865  rtx src = operands[1];
5866  rtx tmp = operands[2];
5867
5868  if (GET_CODE (tmp) == SCRATCH)
5869    tmp = gen_reg_rtx (DImode);
5870
5871  emit_insn (gen_fctiwuz_<mode> (tmp, src));
5872  if (MEM_P (dest))
5873    {
5874      dest = rs6000_force_indexed_or_indirect_mem (dest);
5875      emit_insn (gen_stfiwx (dest, tmp));
5876      DONE;
5877    }
5878  else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5879    {
5880      dest = gen_lowpart (DImode, dest);
5881      emit_move_insn (dest, tmp);
5882      DONE;
5883    }
5884  else
5885    {
5886      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5887      emit_insn (gen_stfiwx (stack, tmp));
5888      emit_move_insn (dest, stack);
5889      DONE;
5890    }
5891}
5892  [(set_attr "length" "12")
5893   (set_attr "type" "fp")])
5894
5895(define_insn "fixuns_trunc<mode>di2"
5896  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5897	(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5898  "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5899  "@
5900   fctiduz %0,%1
5901   xscvdpuxds %x0,%x1"
5902  [(set_attr "type" "fp")])
5903
5904(define_insn "rs6000_mtfsb0"
5905  [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5906		    UNSPECV_MTFSB0)]
5907  "TARGET_HARD_FLOAT"
5908  "mtfsb0 %0"
5909  [(set_attr "type" "fp")])
5910
5911(define_insn "rs6000_mtfsb1"
5912  [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5913		    UNSPECV_MTFSB1)]
5914  "TARGET_HARD_FLOAT"
5915  "mtfsb1 %0"
5916  [(set_attr "type" "fp")])
5917
5918(define_insn "rs6000_mffscrn"
5919  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5920	(unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5921			    UNSPECV_MFFSCRN))]
5922   "TARGET_P9_MISC"
5923   "mffscrn %0,%1"
5924  [(set_attr "type" "fp")])
5925
5926(define_insn "rs6000_mffscdrn"
5927  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5928   (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5929   (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5930  "TARGET_P9_MISC"
5931  "mffscdrn %0,%1"
5932  [(set_attr "type" "fp")])
5933
5934(define_expand "rs6000_set_fpscr_rn"
5935 [(match_operand:DI 0 "reg_or_cint_operand")]
5936  "TARGET_HARD_FLOAT"
5937{
5938  rtx tmp_df = gen_reg_rtx (DFmode);
5939
5940  /* The floating point rounding control bits are FPSCR[62:63]. Put the
5941     new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5942  if (TARGET_P9_MISC)
5943    {
5944      rtx src_df = force_reg (DImode, operands[0]);
5945      src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5946      emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5947      DONE;
5948    }
5949
5950  if (CONST_INT_P (operands[0]))
5951    {
5952      if ((INTVAL (operands[0]) & 0x1) == 0x1)
5953	emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5954      else
5955	emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5956
5957      if ((INTVAL (operands[0]) & 0x2) == 0x2)
5958	emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5959      else
5960	emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5961    }
5962  else
5963    {
5964      rtx tmp_rn = gen_reg_rtx (DImode);
5965      rtx tmp_di = gen_reg_rtx (DImode);
5966
5967      /* Extract new RN mode from operand.  */
5968      emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5969
5970      /* Insert new RN mode into FSCPR.  */
5971      emit_insn (gen_rs6000_mffs (tmp_df));
5972      tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5973      emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5974      emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5975
5976      /* Need to write to field k=15.  The fields are [0:15].  Hence with
5977	 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5978	 8-bit field[0:7]. Need to set the bit that corresponds to the
5979	 value of i that you want [0:7].  */
5980      tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5981      emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5982    }
5983  DONE;
5984})
5985
5986(define_expand "rs6000_set_fpscr_drn"
5987  [(match_operand:DI 0  "gpc_reg_operand")]
5988  "TARGET_HARD_FLOAT"
5989{
5990  rtx tmp_df = gen_reg_rtx (DFmode);
5991
5992  /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5993     new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5994  if (TARGET_P9_MISC)
5995    {
5996      rtx src_df = gen_reg_rtx (DFmode);
5997
5998      emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5999      src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6000      emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6001    }
6002  else
6003    {
6004      rtx tmp_rn = gen_reg_rtx (DImode);
6005      rtx tmp_di = gen_reg_rtx (DImode);
6006
6007      /* Extract new DRN mode from operand.  */
6008      emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6009      emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6010
6011      /* Insert new RN mode into FSCPR.  */
6012      emit_insn (gen_rs6000_mffs (tmp_df));
6013      tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6014      emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6015      emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6016
6017      /* Need to write to field 7.  The fields are [0:15].  The equation to
6018	 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6019	 i to 0x1 to get field 7 where i selects the field.  */
6020      tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6021      emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6022    }
6023  DONE;
6024})
6025
6026;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6027;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6028;; because the first makes it clear that operand 0 is not live
6029;; before the instruction.
6030(define_insn "fctiwz_<mode>"
6031  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6032	(unspec:DI [(fix:SI
6033		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6034		   UNSPEC_FCTIWZ))]
6035  "TARGET_HARD_FLOAT"
6036  "@
6037   fctiwz %0,%1
6038   xscvdpsxws %x0,%x1"
6039  [(set_attr "type" "fp")])
6040
6041(define_insn "fctiwuz_<mode>"
6042  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6043	(unspec:DI [(unsigned_fix:SI
6044		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6045		   UNSPEC_FCTIWUZ))]
6046  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6047  "@
6048   fctiwuz %0,%1
6049   xscvdpuxws %x0,%x1"
6050  [(set_attr "type" "fp")])
6051
6052;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6053;; since the friz instruction does not truncate the value if the floating
6054;; point value is < LONG_MIN or > LONG_MAX.
6055(define_insn "*friz"
6056  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6057	(float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6058  "TARGET_HARD_FLOAT && TARGET_FPRND
6059   && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6060  "@
6061   friz %0,%1
6062   xsrdpiz %x0,%x1"
6063  [(set_attr "type" "fp")])
6064
6065;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
6066;; optimization prevents on ISA 2.06 systems and earlier having to store the
6067;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6068;; extend it, store it back on the stack from the GPR, load it back into the
6069;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6070;; disable using store and load to sign/zero extend the value.
6071(define_insn_and_split "*round32<mode>2_fprs"
6072  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6073	(float:SFDF
6074	 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6075   (clobber (match_scratch:DI 2 "=d"))
6076   (clobber (match_scratch:DI 3 "=d"))]
6077  "TARGET_HARD_FLOAT
6078   && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6079   && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6080  "#"
6081  ""
6082  [(pc)]
6083{
6084  rtx dest = operands[0];
6085  rtx src = operands[1];
6086  rtx tmp1 = operands[2];
6087  rtx tmp2 = operands[3];
6088  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6089
6090  if (GET_CODE (tmp1) == SCRATCH)
6091    tmp1 = gen_reg_rtx (DImode);
6092  if (GET_CODE (tmp2) == SCRATCH)
6093    tmp2 = gen_reg_rtx (DImode);
6094
6095  emit_insn (gen_fctiwz_<mode> (tmp1, src));
6096  emit_insn (gen_stfiwx (stack, tmp1));
6097  emit_insn (gen_lfiwax (tmp2, stack));
6098  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6099  DONE;
6100}
6101  [(set_attr "type" "fpload")
6102   (set_attr "length" "16")])
6103
6104(define_insn_and_split "*roundu32<mode>2_fprs"
6105  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6106	(unsigned_float:SFDF
6107	 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6108   (clobber (match_scratch:DI 2 "=d"))
6109   (clobber (match_scratch:DI 3 "=d"))]
6110  "TARGET_HARD_FLOAT
6111   && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6112   && can_create_pseudo_p ()"
6113  "#"
6114  ""
6115  [(pc)]
6116{
6117  rtx dest = operands[0];
6118  rtx src = operands[1];
6119  rtx tmp1 = operands[2];
6120  rtx tmp2 = operands[3];
6121  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6122
6123  if (GET_CODE (tmp1) == SCRATCH)
6124    tmp1 = gen_reg_rtx (DImode);
6125  if (GET_CODE (tmp2) == SCRATCH)
6126    tmp2 = gen_reg_rtx (DImode);
6127
6128  emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6129  emit_insn (gen_stfiwx (stack, tmp1));
6130  emit_insn (gen_lfiwzx (tmp2, stack));
6131  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6132  DONE;
6133}
6134  [(set_attr "type" "fpload")
6135   (set_attr "length" "16")])
6136
6137;; No VSX equivalent to fctid
6138(define_insn "lrint<mode>di2"
6139  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6140	(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6141		   UNSPEC_FCTID))]
6142  "TARGET_HARD_FLOAT && TARGET_FPRND"
6143  "fctid %0,%1"
6144  [(set_attr "type" "fp")])
6145
6146(define_insn "btrunc<mode>2"
6147  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6148	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6149		     UNSPEC_FRIZ))]
6150  "TARGET_HARD_FLOAT && TARGET_FPRND"
6151  "@
6152   friz %0,%1
6153   xsrdpiz %x0,%x1"
6154  [(set_attr "type" "fp")])
6155
6156(define_insn "ceil<mode>2"
6157  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6158	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6159		     UNSPEC_FRIP))]
6160  "TARGET_HARD_FLOAT && TARGET_FPRND"
6161  "@
6162   frip %0,%1
6163   xsrdpip %x0,%x1"
6164  [(set_attr "type" "fp")])
6165
6166(define_insn "floor<mode>2"
6167  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6168	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6169		     UNSPEC_FRIM))]
6170  "TARGET_HARD_FLOAT && TARGET_FPRND"
6171  "@
6172   frim %0,%1
6173   xsrdpim %x0,%x1"
6174  [(set_attr "type" "fp")])
6175
6176;; No VSX equivalent to frin
6177(define_insn "round<mode>2"
6178  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6179	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6180		     UNSPEC_FRIN))]
6181  "TARGET_HARD_FLOAT && TARGET_FPRND"
6182  "frin %0,%1"
6183  [(set_attr "type" "fp")])
6184
6185(define_insn "*xsrdpi<mode>2"
6186  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6187	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6188		     UNSPEC_XSRDPI))]
6189  "TARGET_HARD_FLOAT && TARGET_VSX"
6190  "xsrdpi %x0,%x1"
6191  [(set_attr "type" "fp")])
6192
6193(define_expand "lround<mode>di2"
6194  [(set (match_dup 2)
6195	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6196		     UNSPEC_XSRDPI))
6197   (set (match_operand:DI 0 "gpc_reg_operand")
6198	(unspec:DI [(match_dup 2)]
6199		   UNSPEC_FCTID))]
6200  "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6201{
6202  operands[2] = gen_reg_rtx (<MODE>mode);
6203})
6204
6205; An UNSPEC is used so we don't have to support SImode in FP registers.
6206(define_insn "stfiwx"
6207  [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6208	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6209		   UNSPEC_STFIWX))]
6210  "TARGET_PPC_GFXOPT"
6211  "@
6212   stfiwx %1,%y0
6213   stxsiwx %x1,%y0"
6214  [(set_attr "type" "fpstore")
6215   (set_attr "isa" "*,p8v")])
6216
6217;; If we don't have a direct conversion to single precision, don't enable this
6218;; conversion for 32-bit without fast math, because we don't have the insn to
6219;; generate the fixup swizzle to avoid double rounding problems.
6220(define_expand "floatsisf2"
6221  [(set (match_operand:SF 0 "gpc_reg_operand")
6222        (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6223  "TARGET_HARD_FLOAT
6224   && ((TARGET_FCFIDS && TARGET_LFIWAX)
6225       || (TARGET_FCFID
6226	   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6227{
6228  if (TARGET_FCFIDS && TARGET_LFIWAX)
6229    {
6230      emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6231      DONE;
6232    }
6233  else if (TARGET_FCFID && TARGET_LFIWAX)
6234    {
6235      rtx dfreg = gen_reg_rtx (DFmode);
6236      emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6237      emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6238      DONE;
6239    }
6240  else
6241    {
6242      rtx dreg = operands[1];
6243      if (!REG_P (dreg))
6244	dreg = force_reg (SImode, dreg);
6245      dreg = convert_to_mode (DImode, dreg, false);
6246      emit_insn (gen_floatdisf2 (operands[0], dreg));
6247      DONE;
6248    }
6249})
6250
6251(define_insn "floatdidf2"
6252  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6253	(float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6254  "TARGET_FCFID && TARGET_HARD_FLOAT"
6255  "@
6256   fcfid %0,%1
6257   xscvsxddp %x0,%x1"
6258  [(set_attr "type" "fp")])
6259
6260; Allow the combiner to merge source memory operands to the conversion so that
6261; the optimizer/register allocator doesn't try to load the value too early in a
6262; GPR and then use store/load to move it to a FPR and suffer from a store-load
6263; hit.  We will split after reload to avoid the trip through the GPRs
6264
6265(define_insn_and_split "*floatdidf2_mem"
6266  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6267	(float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6268   (clobber (match_scratch:DI 2 "=d,wa"))]
6269  "TARGET_HARD_FLOAT && TARGET_FCFID"
6270  "#"
6271  "&& reload_completed"
6272  [(set (match_dup 2) (match_dup 1))
6273   (set (match_dup 0) (float:DF (match_dup 2)))]
6274  ""
6275  [(set_attr "length" "8")
6276   (set_attr "type" "fpload")])
6277
6278(define_expand "floatunsdidf2"
6279  [(set (match_operand:DF 0 "gpc_reg_operand")
6280	(unsigned_float:DF
6281	 (match_operand:DI 1 "gpc_reg_operand")))]
6282  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6283  "")
6284
6285(define_insn "*floatunsdidf2_fcfidu"
6286  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6287	(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6288  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6289  "@
6290   fcfidu %0,%1
6291   xscvuxddp %x0,%x1"
6292  [(set_attr "type" "fp")])
6293
6294(define_insn_and_split "*floatunsdidf2_mem"
6295  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6296	(unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6297   (clobber (match_scratch:DI 2 "=d,wa"))]
6298  "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6299  "#"
6300  "&& reload_completed"
6301  [(set (match_dup 2) (match_dup 1))
6302   (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6303  ""
6304  [(set_attr "length" "8")
6305   (set_attr "type" "fpload")])
6306
6307(define_expand "floatdisf2"
6308  [(set (match_operand:SF 0 "gpc_reg_operand")
6309        (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6310  "TARGET_FCFID && TARGET_HARD_FLOAT
6311   && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6312{
6313  if (!TARGET_FCFIDS)
6314    {
6315      rtx val = operands[1];
6316      if (!flag_unsafe_math_optimizations)
6317	{
6318	  rtx label = gen_label_rtx ();
6319	  val = gen_reg_rtx (DImode);
6320	  emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6321	  emit_label (label);
6322	}
6323      emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6324      DONE;
6325    }
6326})
6327
6328(define_insn "floatdisf2_fcfids"
6329  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6330	(float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6331  "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6332  "@
6333   fcfids %0,%1
6334   xscvsxdsp %x0,%x1"
6335  [(set_attr "type" "fp")
6336   (set_attr "isa" "*,p8v")])
6337
6338(define_insn_and_split "*floatdisf2_mem"
6339  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6340	(float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6341   (clobber (match_scratch:DI 2 "=d,d,wa"))]
6342  "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6343  "#"
6344  "&& reload_completed"
6345  [(pc)]
6346{
6347  emit_move_insn (operands[2], operands[1]);
6348  emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6349  DONE;
6350}
6351  [(set_attr "length" "8")
6352   (set_attr "isa" "*,p8v,p8v")])
6353
6354;; This is not IEEE compliant if rounding mode is "round to nearest".
6355;; If the DI->DF conversion is inexact, then it's possible to suffer
6356;; from double rounding.
6357;; Instead of creating a new cpu type for two FP operations, just use fp
6358(define_insn_and_split "floatdisf2_internal1"
6359  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6360        (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6361   (clobber (match_scratch:DF 2 "=d"))]
6362  "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6363  "#"
6364  "&& reload_completed"
6365  [(set (match_dup 2)
6366        (float:DF (match_dup 1)))
6367   (set (match_dup 0)
6368        (float_truncate:SF (match_dup 2)))]
6369  ""
6370  [(set_attr "length" "8")
6371   (set_attr "type" "fp")])
6372
6373;; Twiddles bits to avoid double rounding.
6374;; Bits that might be truncated when converting to DFmode are replaced
6375;; by a bit that won't be lost at that stage, but is below the SFmode
6376;; rounding position.
6377(define_expand "floatdisf2_internal2"
6378  [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6379					      (const_int 53)))
6380	      (clobber (reg:DI CA_REGNO))])
6381   (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6382					(const_int 2047)))
6383   (set (match_dup 3) (plus:DI (match_dup 3)
6384			       (const_int 1)))
6385   (set (match_dup 0) (plus:DI (match_dup 0)
6386			       (const_int 2047)))
6387   (set (match_dup 4) (compare:CCUNS (match_dup 3)
6388				     (const_int 2)))
6389   (set (match_dup 0) (ior:DI (match_dup 0)
6390			      (match_dup 1)))
6391   (set (match_dup 0) (and:DI (match_dup 0)
6392			      (const_int -2048)))
6393   (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6394			   (label_ref (match_operand:DI 2 ""))
6395			   (pc)))
6396   (set (match_dup 0) (match_dup 1))]
6397  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6398{
6399  operands[3] = gen_reg_rtx (DImode);
6400  operands[4] = gen_reg_rtx (CCUNSmode);
6401})
6402
6403(define_expand "floatunsdisf2"
6404  [(set (match_operand:SF 0 "gpc_reg_operand")
6405        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6406  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6407  "")
6408
6409(define_insn "floatunsdisf2_fcfidus"
6410  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6411        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6412  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6413  "@
6414   fcfidus %0,%1
6415   xscvuxdsp %x0,%x1"
6416  [(set_attr "type" "fp")
6417   (set_attr "isa" "*,p8v")])
6418
6419(define_insn_and_split "*floatunsdisf2_mem"
6420  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6421	(unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6422   (clobber (match_scratch:DI 2 "=d,d,wa"))]
6423  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6424  "#"
6425  "&& reload_completed"
6426  [(pc)]
6427{
6428  emit_move_insn (operands[2], operands[1]);
6429  emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6430  DONE;
6431}
6432  [(set_attr "type" "fpload")
6433   (set_attr "length" "8")
6434   (set_attr "isa" "*,p8v,p8v")])
6435
6436;; Define the TImode operations that can be done in a small number
6437;; of instructions.  The & constraints are to prevent the register
6438;; allocator from allocating registers that overlap with the inputs
6439;; (for example, having an input in 7,8 and an output in 6,7).  We
6440;; also allow for the output being the same as one of the inputs.
6441
6442(define_expand "addti3"
6443  [(set (match_operand:TI 0 "gpc_reg_operand")
6444	(plus:TI (match_operand:TI 1 "gpc_reg_operand")
6445		 (match_operand:TI 2 "reg_or_short_operand")))]
6446  "TARGET_64BIT"
6447{
6448  rtx lo0 = gen_lowpart (DImode, operands[0]);
6449  rtx lo1 = gen_lowpart (DImode, operands[1]);
6450  rtx lo2 = gen_lowpart (DImode, operands[2]);
6451  rtx hi0 = gen_highpart (DImode, operands[0]);
6452  rtx hi1 = gen_highpart (DImode, operands[1]);
6453  rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6454
6455  if (!reg_or_short_operand (lo2, DImode))
6456    lo2 = force_reg (DImode, lo2);
6457  if (!adde_operand (hi2, DImode))
6458    hi2 = force_reg (DImode, hi2);
6459
6460  emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6461  emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6462  DONE;
6463})
6464
6465(define_expand "subti3"
6466  [(set (match_operand:TI 0 "gpc_reg_operand")
6467	(minus:TI (match_operand:TI 1 "reg_or_short_operand")
6468		  (match_operand:TI 2 "gpc_reg_operand")))]
6469  "TARGET_64BIT"
6470{
6471  rtx lo0 = gen_lowpart (DImode, operands[0]);
6472  rtx lo1 = gen_lowpart (DImode, operands[1]);
6473  rtx lo2 = gen_lowpart (DImode, operands[2]);
6474  rtx hi0 = gen_highpart (DImode, operands[0]);
6475  rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6476  rtx hi2 = gen_highpart (DImode, operands[2]);
6477
6478  if (!reg_or_short_operand (lo1, DImode))
6479    lo1 = force_reg (DImode, lo1);
6480  if (!adde_operand (hi1, DImode))
6481    hi1 = force_reg (DImode, hi1);
6482
6483  emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6484  emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6485  DONE;
6486})
6487
6488;; 128-bit logical operations expanders
6489
6490(define_expand "and<mode>3"
6491  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6492	(and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6493		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6494  ""
6495  "")
6496
6497(define_expand "ior<mode>3"
6498  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6499        (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6500		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6501  ""
6502  "")
6503
6504(define_expand "xor<mode>3"
6505  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6506        (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6507		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6508  ""
6509  "")
6510
6511(define_expand "nor<mode>3"
6512  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6513	(and:BOOL_128
6514	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6515	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6516  ""
6517  "")
6518
6519(define_expand "andc<mode>3"
6520  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6521        (and:BOOL_128
6522	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6523	 (match_operand:BOOL_128 1 "vlogical_operand")))]
6524  ""
6525  "")
6526
6527;; Power8 vector logical instructions.
6528(define_expand "eqv<mode>3"
6529  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6530	(not:BOOL_128
6531	 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6532		       (match_operand:BOOL_128 2 "vlogical_operand"))))]
6533  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6534  "")
6535
6536;; Rewrite nand into canonical form
6537(define_expand "nand<mode>3"
6538  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6539	(ior:BOOL_128
6540	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6541	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6542  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6543  "")
6544
6545;; The canonical form is to have the negated element first, so we need to
6546;; reverse arguments.
6547(define_expand "orc<mode>3"
6548  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6549	(ior:BOOL_128
6550	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6551	 (match_operand:BOOL_128 1 "vlogical_operand")))]
6552  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6553  "")
6554
6555;; 128-bit logical operations insns and split operations
6556(define_insn_and_split "*and<mode>3_internal"
6557  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6558        (and:BOOL_128
6559	 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6560	 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6561  ""
6562{
6563  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6564    return "xxland %x0,%x1,%x2";
6565
6566  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6567    return "vand %0,%1,%2";
6568
6569  return "#";
6570}
6571  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6572  [(const_int 0)]
6573{
6574  rs6000_split_logical (operands, AND, false, false, false);
6575  DONE;
6576}
6577  [(set (attr "type")
6578      (if_then_else
6579	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6580	(const_string "veclogical")
6581	(const_string "integer")))
6582   (set (attr "length")
6583      (if_then_else
6584	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6585	(const_string "4")
6586	(if_then_else
6587	 (match_test "TARGET_POWERPC64")
6588	 (const_string "8")
6589	 (const_string "16"))))])
6590
6591;; 128-bit IOR/XOR
6592(define_insn_and_split "*bool<mode>3_internal"
6593  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6594	(match_operator:BOOL_128 3 "boolean_or_operator"
6595	 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6596	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6597  ""
6598{
6599  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6600    return "xxl%q3 %x0,%x1,%x2";
6601
6602  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6603    return "v%q3 %0,%1,%2";
6604
6605  return "#";
6606}
6607  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6608  [(const_int 0)]
6609{
6610  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6611  DONE;
6612}
6613  [(set (attr "type")
6614      (if_then_else
6615	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6616	(const_string "veclogical")
6617	(const_string "integer")))
6618   (set (attr "length")
6619      (if_then_else
6620	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6621	(const_string "4")
6622	(if_then_else
6623	 (match_test "TARGET_POWERPC64")
6624	 (const_string "8")
6625	 (const_string "16"))))])
6626
6627;; 128-bit ANDC/ORC
6628(define_insn_and_split "*boolc<mode>3_internal1"
6629  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6630	(match_operator:BOOL_128 3 "boolean_operator"
6631	 [(not:BOOL_128
6632	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6633	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6634  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6635{
6636  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6637    return "xxl%q3 %x0,%x1,%x2";
6638
6639  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6640    return "v%q3 %0,%1,%2";
6641
6642  return "#";
6643}
6644  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6645   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6646  [(const_int 0)]
6647{
6648  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6649  DONE;
6650}
6651  [(set (attr "type")
6652      (if_then_else
6653	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6654	(const_string "veclogical")
6655	(const_string "integer")))
6656   (set (attr "length")
6657      (if_then_else
6658	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6659	(const_string "4")
6660	(if_then_else
6661	 (match_test "TARGET_POWERPC64")
6662	 (const_string "8")
6663	 (const_string "16"))))])
6664
6665(define_insn_and_split "*boolc<mode>3_internal2"
6666  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6667	(match_operator:TI2 3 "boolean_operator"
6668	 [(not:TI2
6669	   (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6670	  (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6671  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6672  "#"
6673  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6674  [(const_int 0)]
6675{
6676  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6677  DONE;
6678}
6679  [(set_attr "type" "integer")
6680   (set (attr "length")
6681	(if_then_else
6682	 (match_test "TARGET_POWERPC64")
6683	 (const_string "8")
6684	 (const_string "16")))])
6685
6686;; 128-bit NAND/NOR
6687(define_insn_and_split "*boolcc<mode>3_internal1"
6688  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6689	(match_operator:BOOL_128 3 "boolean_operator"
6690	 [(not:BOOL_128
6691	   (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6692	  (not:BOOL_128
6693	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6694  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6695{
6696  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6697    return "xxl%q3 %x0,%x1,%x2";
6698
6699  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6700    return "v%q3 %0,%1,%2";
6701
6702  return "#";
6703}
6704  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6705   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6706  [(const_int 0)]
6707{
6708  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6709  DONE;
6710}
6711  [(set (attr "type")
6712      (if_then_else
6713	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6714	(const_string "veclogical")
6715	(const_string "integer")))
6716   (set (attr "length")
6717      (if_then_else
6718	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6719	(const_string "4")
6720	(if_then_else
6721	 (match_test "TARGET_POWERPC64")
6722	 (const_string "8")
6723	 (const_string "16"))))])
6724
6725(define_insn_and_split "*boolcc<mode>3_internal2"
6726  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6727	(match_operator:TI2 3 "boolean_operator"
6728	 [(not:TI2
6729	   (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6730	  (not:TI2
6731	   (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6732  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6733  "#"
6734  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6735  [(const_int 0)]
6736{
6737  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6738  DONE;
6739}
6740  [(set_attr "type" "integer")
6741   (set (attr "length")
6742	(if_then_else
6743	 (match_test "TARGET_POWERPC64")
6744	 (const_string "8")
6745	 (const_string "16")))])
6746
6747
6748;; 128-bit EQV
6749(define_insn_and_split "*eqv<mode>3_internal1"
6750  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6751	(not:BOOL_128
6752	 (xor:BOOL_128
6753	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6754	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6755  "TARGET_P8_VECTOR"
6756{
6757  if (vsx_register_operand (operands[0], <MODE>mode))
6758    return "xxleqv %x0,%x1,%x2";
6759
6760  return "#";
6761}
6762  "TARGET_P8_VECTOR && reload_completed
6763   && int_reg_operand (operands[0], <MODE>mode)"
6764  [(const_int 0)]
6765{
6766  rs6000_split_logical (operands, XOR, true, false, false);
6767  DONE;
6768}
6769  [(set (attr "type")
6770      (if_then_else
6771	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6772	(const_string "veclogical")
6773	(const_string "integer")))
6774   (set (attr "length")
6775      (if_then_else
6776	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6777	(const_string "4")
6778	(if_then_else
6779	 (match_test "TARGET_POWERPC64")
6780	 (const_string "8")
6781	 (const_string "16"))))])
6782
6783(define_insn_and_split "*eqv<mode>3_internal2"
6784  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6785	(not:TI2
6786	 (xor:TI2
6787	  (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6788	  (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6789  "!TARGET_P8_VECTOR"
6790  "#"
6791  "reload_completed && !TARGET_P8_VECTOR"
6792  [(const_int 0)]
6793{
6794  rs6000_split_logical (operands, XOR, true, false, false);
6795  DONE;
6796}
6797  [(set_attr "type" "integer")
6798   (set (attr "length")
6799	(if_then_else
6800	 (match_test "TARGET_POWERPC64")
6801	 (const_string "8")
6802	 (const_string "16")))])
6803
6804;; 128-bit one's complement
6805(define_insn_and_split "one_cmpl<mode>2"
6806  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6807	(not:BOOL_128
6808	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6809  ""
6810{
6811  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6812    return "xxlnor %x0,%x1,%x1";
6813
6814  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6815    return "vnor %0,%1,%1";
6816
6817  return "#";
6818}
6819  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6820  [(const_int 0)]
6821{
6822  rs6000_split_logical (operands, NOT, false, false, false);
6823  DONE;
6824}
6825  [(set (attr "type")
6826      (if_then_else
6827	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6828	(const_string "veclogical")
6829	(const_string "integer")))
6830   (set (attr "length")
6831      (if_then_else
6832	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6833	(const_string "4")
6834	(if_then_else
6835	 (match_test "TARGET_POWERPC64")
6836	 (const_string "8")
6837	 (const_string "16"))))])
6838
6839
6840;; Now define ways of moving data around.
6841
6842;; Set up a register with a value from the GOT table
6843
6844(define_expand "movsi_got"
6845  [(set (match_operand:SI 0 "gpc_reg_operand")
6846	(unspec:SI [(match_operand:SI 1 "got_operand")
6847		    (match_dup 2)] UNSPEC_MOVSI_GOT))]
6848  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6849{
6850  if (GET_CODE (operands[1]) == CONST)
6851    {
6852      rtx offset = const0_rtx;
6853      HOST_WIDE_INT value;
6854
6855      operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6856      value = INTVAL (offset);
6857      if (value != 0)
6858	{
6859	  rtx tmp = (!can_create_pseudo_p ()
6860		     ? operands[0]
6861		     : gen_reg_rtx (Pmode));
6862	  emit_insn (gen_movsi_got (tmp, operands[1]));
6863	  emit_insn (gen_addsi3 (operands[0], tmp, offset));
6864	  DONE;
6865	}
6866    }
6867
6868  operands[2] = rs6000_got_register (operands[1]);
6869})
6870
6871(define_insn "*movsi_got_internal"
6872  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6873	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6874		    (match_operand:SI 2 "gpc_reg_operand" "b")]
6875		   UNSPEC_MOVSI_GOT))]
6876  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6877  "lwz %0,%a1@got(%2)"
6878  [(set_attr "type" "load")])
6879
6880;; Used by sched, shorten_branches and final when the GOT pseudo reg
6881;; didn't get allocated to a hard register.
6882(define_split
6883  [(set (match_operand:SI 0 "gpc_reg_operand")
6884	(unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6885		    (match_operand:SI 2 "memory_operand")]
6886		   UNSPEC_MOVSI_GOT))]
6887  "DEFAULT_ABI == ABI_V4
6888    && flag_pic == 1
6889    && reload_completed"
6890  [(set (match_dup 0) (match_dup 2))
6891   (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6892				 UNSPEC_MOVSI_GOT))]
6893  "")
6894
6895;;	   MR          LA
6896;;	   LWZ         LFIWZX      LXSIWZX
6897;;	   STW         STFIWX      STXSIWX
6898;;	   LI          LIS         PLI         #
6899;;	   XXLOR       XXSPLTIB 0  XXSPLTIB -1 VSPLTISW
6900;;	   XXLXOR 0    XXLORC -1   P9 const
6901;;	   MTVSRWZ     MFVSRWZ
6902;;	   MF%1        MT%0        NOP
6903
6904(define_insn "*movsi_internal1"
6905  [(set (match_operand:SI 0 "nonimmediate_operand"
6906	  "=r,         r,
6907	   r,          d,          v,
6908	   m,          Z,          Z,
6909	   r,          r,          r,          r,
6910	   wa,         wa,         wa,         v,
6911	   wa,         v,          v,
6912	   wa,         r,
6913	   r,          *h,         *h")
6914	(match_operand:SI 1 "input_operand"
6915	  "r,          U,
6916	   m,          Z,          Z,
6917	   r,          d,          v,
6918	   I,          L,          eI,         n,
6919	   wa,         O,          wM,         wB,
6920	   O,          wM,         wS,
6921	   r,          wa,
6922	   *h,         r,          0"))]
6923  "gpc_reg_operand (operands[0], SImode)
6924   || gpc_reg_operand (operands[1], SImode)"
6925  "@
6926   mr %0,%1
6927   la %0,%a1
6928   lwz%U1%X1 %0,%1
6929   lfiwzx %0,%y1
6930   lxsiwzx %x0,%y1
6931   stw%U0%X0 %1,%0
6932   stfiwx %1,%y0
6933   stxsiwx %x1,%y0
6934   li %0,%1
6935   lis %0,%v1
6936   li %0,%1
6937   #
6938   xxlor %x0,%x1,%x1
6939   xxspltib %x0,0
6940   xxspltib %x0,255
6941   vspltisw %0,%1
6942   xxlxor %x0,%x0,%x0
6943   xxlorc %x0,%x0,%x0
6944   #
6945   mtvsrwz %x0,%1
6946   mfvsrwz %0,%x1
6947   mf%1 %0
6948   mt%0 %1
6949   nop"
6950  [(set_attr "type"
6951	  "*,          *,
6952	   load,       fpload,     fpload,
6953	   store,      fpstore,    fpstore,
6954	   *,          *,          *,          *,
6955	   veclogical, vecsimple,  vecsimple,  vecsimple,
6956	   veclogical, veclogical, vecsimple,
6957	   mffgpr,     mftgpr,
6958	   *,          *,          *")
6959   (set_attr "length"
6960	  "*,          *,
6961	   *,          *,          *,
6962	   *,          *,          *,
6963	   *,          *,          *,          8,
6964	   *,          *,          *,          *,
6965	   *,          *,          8,
6966	   *,          *,
6967	   *,          *,          *")
6968   (set_attr "isa"
6969	  "*,          *,
6970	   *,          p8v,        p8v,
6971	   *,          p8v,        p8v,
6972	   *,          *,          p10,        *,
6973	   p8v,        p9v,        p9v,        p8v,
6974	   p9v,        p8v,        p9v,
6975	   p8v,        p8v,
6976	   *,          *,          *")])
6977
6978;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6979;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6980;;
6981;; Because SF values are actually stored as DF values within the vector
6982;; registers, we need to convert the value to the vector SF format when
6983;; we need to use the bits in a union or similar cases.  We only need
6984;; to do this transformation when the value is a vector register.  Loads,
6985;; stores, and transfers within GPRs are assumed to be safe.
6986;;
6987;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6988;; no alternatives, because the call is created as part of secondary_reload,
6989;; and operand #2's register class is used to allocate the temporary register.
6990;; This function is called before reload, and it creates the temporary as
6991;; needed.
6992
6993;;		MR           LWZ          LFIWZX       LXSIWZX   STW
6994;;		STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6995;;		MTVSRWZ
6996
6997(define_insn_and_split "movsi_from_sf"
6998  [(set (match_operand:SI 0 "nonimmediate_operand"
6999		"=r,         r,           ?*d,         ?*v,      m,
7000		 m,          wY,          Z,           r,        ?*wa,
7001		 wa")
7002	(unspec:SI [(match_operand:SF 1 "input_operand"
7003		"r,          m,           Z,           Z,        r,
7004		 f,          v,           wa,          wa,       wa,
7005		 r")]
7006		    UNSPEC_SI_FROM_SF))
7007   (clobber (match_scratch:V4SF 2
7008		"=X,         X,           X,           X,        X,
7009		 X,          X,           X,           wa,       X,
7010		 X"))]
7011  "TARGET_NO_SF_SUBREG
7012   && (register_operand (operands[0], SImode)
7013       || register_operand (operands[1], SFmode))"
7014  "@
7015   mr %0,%1
7016   lwz%U1%X1 %0,%1
7017   lfiwzx %0,%y1
7018   lxsiwzx %x0,%y1
7019   stw%U0%X0 %1,%0
7020   stfs%U0%X0 %1,%0
7021   stxssp %1,%0
7022   stxsspx %x1,%y0
7023   #
7024   xscvdpspn %x0,%x1
7025   mtvsrwz %x0,%1"
7026  "&& reload_completed
7027   && int_reg_operand (operands[0], SImode)
7028   && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7029  [(const_int 0)]
7030{
7031  rtx op0 = operands[0];
7032  rtx op1 = operands[1];
7033  rtx op2 = operands[2];
7034  rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7035  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7036
7037  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7038  emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7039  DONE;
7040}
7041  [(set_attr "type"
7042		"*,          load,        fpload,      fpload,   store,
7043		 fpstore,    fpstore,     fpstore,     mftgpr,   fp,
7044		 mffgpr")
7045   (set_attr "length"
7046		"*,          *,           *,           *,        *,
7047		 *,          *,           *,           8,        *,
7048		 *")
7049   (set_attr "isa"
7050		"*,          *,           p8v,         p8v,      *,
7051		 *,          p9v,         p8v,         p8v,      p8v,
7052		 p8v")])
7053
7054;; movsi_from_sf with zero extension
7055;;
7056;;		RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
7057;;		VSX->VSX     MTVSRWZ
7058
7059(define_insn_and_split "*movdi_from_sf_zero_ext"
7060  [(set (match_operand:DI 0 "gpc_reg_operand"
7061		"=r,         r,           ?*d,         ?*v,      r,
7062		 ?v,         wa")
7063	(zero_extend:DI
7064	 (unspec:SI [(match_operand:SF 1 "input_operand"
7065		"r,          m,           Z,           Z,        wa,
7066		 wa,         r")]
7067		    UNSPEC_SI_FROM_SF)))
7068   (clobber (match_scratch:V4SF 2
7069		"=X,         X,           X,           X,        wa,
7070		 wa,         X"))]
7071  "TARGET_DIRECT_MOVE_64BIT
7072   && (register_operand (operands[0], DImode)
7073       || register_operand (operands[1], SImode))"
7074  "@
7075   rldicl %0,%1,0,32
7076   lwz%U1%X1 %0,%1
7077   lfiwzx %0,%y1
7078   lxsiwzx %x0,%y1
7079   #
7080   #
7081   mtvsrwz %x0,%1"
7082  "&& reload_completed
7083   && register_operand (operands[0], DImode)
7084   && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7085  [(const_int 0)]
7086{
7087  rtx op0 = operands[0];
7088  rtx op1 = operands[1];
7089  rtx op2 = operands[2];
7090  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7091
7092  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7093  emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7094  DONE;
7095}
7096  [(set_attr "type"
7097		"*,          load,        fpload,      fpload,   two,
7098		 two,        mffgpr")
7099   (set_attr "length"
7100		"*,          *,           *,           *,        8,
7101		 8,          *")
7102   (set_attr "isa"
7103		"*,          *,           p8v,         p8v,      p8v,
7104		 p9v,        p8v")])
7105
7106;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7107;; moving it to SImode.  We cannot do a SFmode store without having to do the
7108;; conversion explicitly since that doesn't work in most cases if the input
7109;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7110;; former handles cases where the input will not fit in a SFmode, and the
7111;; latter assumes the value has already been rounded.
7112(define_insn "*movsi_from_df"
7113  [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7114	(unspec:SI [(float_truncate:SF
7115		     (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7116		    UNSPEC_SI_FROM_SF))]
7117  "TARGET_NO_SF_SUBREG"
7118  "xscvdpsp %x0,%x1"
7119  [(set_attr "type" "fp")])
7120
7121;; Split a load of a large constant into the appropriate two-insn
7122;; sequence.
7123
7124(define_split
7125  [(set (match_operand:SI 0 "gpc_reg_operand")
7126	(match_operand:SI 1 "const_int_operand"))]
7127  "num_insns_constant (operands[1], SImode) > 1"
7128  [(set (match_dup 0)
7129	(match_dup 2))
7130   (set (match_dup 0)
7131	(ior:SI (match_dup 0)
7132		(match_dup 3)))]
7133{
7134  if (rs6000_emit_set_const (operands[0], operands[1]))
7135    DONE;
7136  else
7137    FAIL;
7138})
7139
7140;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7141(define_split
7142  [(set (match_operand:DI 0 "altivec_register_operand")
7143	(match_operand:DI 1 "xxspltib_constant_split"))]
7144  "TARGET_P9_VECTOR && reload_completed"
7145  [(const_int 0)]
7146{
7147  rtx op0 = operands[0];
7148  rtx op1 = operands[1];
7149  int r = REGNO (op0);
7150  rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7151
7152  emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7153  emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7154  DONE;
7155})
7156
7157(define_insn "*mov<mode>_internal2"
7158  [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7159	(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7160		    (const_int 0)))
7161   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7162  ""
7163  "@
7164   cmp<wd>i %2,%0,0
7165   mr. %0,%1
7166   #"
7167  [(set_attr "type" "cmp,logical,cmp")
7168   (set_attr "dot" "yes")
7169   (set_attr "length" "4,4,8")])
7170
7171(define_split
7172  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7173	(compare:CC (match_operand:P 1 "gpc_reg_operand")
7174		    (const_int 0)))
7175   (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7176  "reload_completed"
7177  [(set (match_dup 0) (match_dup 1))
7178   (set (match_dup 2)
7179	(compare:CC (match_dup 0)
7180		    (const_int 0)))]
7181  "")
7182
7183(define_expand "mov<mode>"
7184  [(set (match_operand:INT 0 "general_operand")
7185	(match_operand:INT 1 "any_operand"))]
7186  ""
7187{
7188  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7189  DONE;
7190})
7191
7192;;		MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7193;;		XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7194;;		MTVSRWZ     MF%1       MT%1       NOP
7195(define_insn "*mov<mode>_internal"
7196  [(set (match_operand:QHI 0 "nonimmediate_operand"
7197		"=r,        r,         wa,        m,         Z,         r,
7198		 wa,        wa,        wa,        v,         ?v,        r,
7199		 wa,        r,         *c*l,      *h")
7200	(match_operand:QHI 1 "input_operand"
7201		"r,         m,         Z,         r,         wa,        i,
7202		 wa,        O,         wM,        wB,        wS,        wa,
7203		 r,         *h,        r,         0"))]
7204  "gpc_reg_operand (operands[0], <MODE>mode)
7205   || gpc_reg_operand (operands[1], <MODE>mode)"
7206  "@
7207   mr %0,%1
7208   l<wd>z%U1%X1 %0,%1
7209   lxsi<wd>zx %x0,%y1
7210   st<wd>%U0%X0 %1,%0
7211   stxsi<wd>x %x1,%y0
7212   li %0,%1
7213   xxlor %x0,%x1,%x1
7214   xxspltib %x0,0
7215   xxspltib %x0,255
7216   vspltis<wd> %0,%1
7217   #
7218   mfvsrwz %0,%x1
7219   mtvsrwz %x0,%1
7220   mf%1 %0
7221   mt%0 %1
7222   nop"
7223  [(set_attr "type"
7224		"*,         load,      fpload,    store,     fpstore,   *,
7225		 vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7226		 mffgpr,    mfjmpr,    mtjmpr,    *")
7227   (set_attr "length"
7228		"*,         *,         *,         *,         *,         *,
7229		 *,         *,         *,         *,         8,         *,
7230		 *,         *,         *,         *")
7231   (set_attr "isa"
7232		"*,         *,         p9v,       *,         p9v,       *,
7233		 p9v,       p9v,       p9v,       p9v,       p9v,       p9v,
7234		 p9v,       *,         *,         *")])
7235
7236
7237;; Here is how to move condition codes around.  When we store CC data in
7238;; an integer register or memory, we store just the high-order 4 bits.
7239;; This lets us not shift in the most common case of CR0.
7240(define_expand "movcc"
7241  [(set (match_operand:CC 0 "nonimmediate_operand")
7242	(match_operand:CC 1 "nonimmediate_operand"))]
7243  ""
7244  "")
7245
7246(define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7247
7248(define_insn "*movcc_<mode>"
7249  [(set (match_operand:CC_any 0 "nonimmediate_operand"
7250				"=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7251	(match_operand:CC_any 1 "general_operand"
7252				" y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7253  "register_operand (operands[0], <MODE>mode)
7254   || register_operand (operands[1], <MODE>mode)"
7255  "@
7256   mcrf %0,%1
7257   mtcrf 128,%1
7258   rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7259   crxor %0,%0,%0
7260   mfcr %0%Q1
7261   mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7262   mr %0,%1
7263   li %0,%1
7264   mf%1 %0
7265   mt%0 %1
7266   lwz%U1%X1 %0,%1
7267   stw%U0%X0 %1,%0"
7268  [(set_attr_alternative "type"
7269     [(const_string "cr_logical")
7270      (const_string "mtcr")
7271      (const_string "mtcr")
7272      (const_string "cr_logical")
7273      (if_then_else (match_test "TARGET_MFCRF")
7274		    (const_string "mfcrf") (const_string "mfcr"))
7275      (if_then_else (match_test "TARGET_MFCRF")
7276		    (const_string "mfcrf") (const_string "mfcr"))
7277      (const_string "integer")
7278      (const_string "integer")
7279      (const_string "mfjmpr")
7280      (const_string "mtjmpr")
7281      (const_string "load")
7282      (const_string "store")])
7283   (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7284
7285;; For floating-point, we normally deal with the floating-point registers
7286;; unless -msoft-float is used.  The sole exception is that parameter passing
7287;; can produce floating-point values in fixed-point registers.  Unless the
7288;; value is a simple constant or already in memory, we deal with this by
7289;; allocating memory and copying the value explicitly via that memory location.
7290
7291;; Move 32-bit binary/decimal floating point
7292(define_expand "mov<mode>"
7293  [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7294	(match_operand:FMOVE32 1 "any_operand"))]
7295  "<fmove_ok>"
7296{
7297  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7298  DONE;
7299})
7300
7301(define_split
7302  [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7303	(match_operand:FMOVE32 1 "const_double_operand"))]
7304  "reload_completed
7305   && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7306       || (SUBREG_P (operands[0])
7307	   && REG_P (SUBREG_REG (operands[0]))
7308	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7309  [(set (match_dup 2) (match_dup 3))]
7310{
7311  long l;
7312
7313  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7314
7315  if (! TARGET_POWERPC64)
7316    operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7317  else
7318    operands[2] = gen_lowpart (SImode, operands[0]);
7319
7320  operands[3] = gen_int_mode (l, SImode);
7321})
7322
7323;; Originally, we tried to keep movsf and movsd common, but the differences
7324;; addressing was making it rather difficult to hide with mode attributes.  In
7325;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7326;; before the VSX stores meant that the register allocator would tend to do a
7327;; direct move to the GPR (which involves conversion from scalar to
7328;; vector/memory formats) to save values in the traditional Altivec registers,
7329;; while SDmode had problems on power6 if the GPR store was not first due to
7330;; the power6 not having an integer store operation.
7331;;
7332;;	LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7333;;	STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7334;;	MR           MT<x>      MF<x>       NOP
7335
7336(define_insn "movsf_hardfloat"
7337  [(set (match_operand:SF 0 "nonimmediate_operand"
7338	 "=!r,       f,         v,          wa,        m,         wY,
7339	  Z,         m,         wa,         !r,        f,         wa,
7340	  !r,        *c*l,      !r,         *h")
7341	(match_operand:SF 1 "input_operand"
7342	 "m,         m,         wY,         Z,         f,         v,
7343	  wa,        r,         j,          j,         f,         wa,
7344	  r,         r,         *h,         0"))]
7345  "(register_operand (operands[0], SFmode)
7346   || register_operand (operands[1], SFmode))
7347   && TARGET_HARD_FLOAT
7348   && (TARGET_ALLOW_SF_SUBREG
7349       || valid_sf_si_move (operands[0], operands[1], SFmode))"
7350  "@
7351   lwz%U1%X1 %0,%1
7352   lfs%U1%X1 %0,%1
7353   lxssp %0,%1
7354   lxsspx %x0,%y1
7355   stfs%U0%X0 %1,%0
7356   stxssp %1,%0
7357   stxsspx %x1,%y0
7358   stw%U0%X0 %1,%0
7359   xxlxor %x0,%x0,%x0
7360   li %0,0
7361   fmr %0,%1
7362   xscpsgndp %x0,%x1,%x1
7363   mr %0,%1
7364   mt%0 %1
7365   mf%1 %0
7366   nop"
7367  [(set_attr "type"
7368	"load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7369	 fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7370	 *,          mtjmpr,    mfjmpr,     *")
7371   (set_attr "isa"
7372	"*,          *,         p9v,        p8v,       *,         p9v,
7373	 p8v,        *,         *,          *,         *,         *,
7374	 *,          *,         *,          *")])
7375
7376;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7377;;	FMR          MR         MT%0       MF%1       NOP
7378(define_insn "movsd_hardfloat"
7379  [(set (match_operand:SD 0 "nonimmediate_operand"
7380	 "=!r,       d,         m,         Z,         ?d,        ?r,
7381	  f,         !r,        *c*l,      !r,        *h")
7382	(match_operand:SD 1 "input_operand"
7383	 "m,         Z,         r,         wx,        r,         d,
7384	  f,         r,         r,         *h,        0"))]
7385  "(register_operand (operands[0], SDmode)
7386   || register_operand (operands[1], SDmode))
7387   && TARGET_HARD_FLOAT"
7388  "@
7389   lwz%U1%X1 %0,%1
7390   lfiwzx %0,%y1
7391   stw%U0%X0 %1,%0
7392   stfiwx %1,%y0
7393   mtvsrwz %x0,%1
7394   mfvsrwz %0,%x1
7395   fmr %0,%1
7396   mr %0,%1
7397   mt%0 %1
7398   mf%1 %0
7399   nop"
7400  [(set_attr "type"
7401	"load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7402	 fpsimple,   *,         mtjmpr,    mfjmpr,    *")
7403   (set_attr "isa"
7404	"*,          p7,        *,         *,         p8v,       p8v,
7405	 *,          *,         *,         *,         *")])
7406
7407;;	MR           MT%0       MF%0       LWZ        STW        LI
7408;;	LIS          G-const.   F/n-const  NOP
7409(define_insn "*mov<mode>_softfloat"
7410  [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7411	"=r,         *c*l,      r,         r,         m,         r,
7412          r,         r,         r,         *h")
7413
7414	(match_operand:FMOVE32 1 "input_operand"
7415	 "r,         r,         *h,        m,         r,         I,
7416          L,         G,         Fn,        0"))]
7417
7418  "(gpc_reg_operand (operands[0], <MODE>mode)
7419   || gpc_reg_operand (operands[1], <MODE>mode))
7420   && TARGET_SOFT_FLOAT"
7421  "@
7422   mr %0,%1
7423   mt%0 %1
7424   mf%1 %0
7425   lwz%U1%X1 %0,%1
7426   stw%U0%X0 %1,%0
7427   li %0,%1
7428   lis %0,%v1
7429   #
7430   #
7431   nop"
7432  [(set_attr "type"
7433	"*,          mtjmpr,    mfjmpr,    load,      store,     *,
7434	 *,          *,         *,         *")
7435
7436   (set_attr "length"
7437	"*,          *,         *,         *,         *,         *,
7438         *,          *,         8,         *")])
7439
7440;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7441;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7442;;
7443;; Because SF values are actually stored as DF values within the vector
7444;; registers, we need to convert the value to the vector SF format when
7445;; we need to use the bits in a union or similar cases.  We only need
7446;; to do this transformation when the value is a vector register.  Loads,
7447;; stores, and transfers within GPRs are assumed to be safe.
7448;;
7449;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7450;; no alternatives, because the call is created as part of secondary_reload,
7451;; and operand #2's register class is used to allocate the temporary register.
7452;; This function is called before reload, and it creates the temporary as
7453;; needed.
7454
7455;;	    LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7456;;	    STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7457(define_insn_and_split "movsf_from_si"
7458  [(set (match_operand:SF 0 "nonimmediate_operand"
7459	    "=!r,       f,         v,         wa,        m,         Z,
7460	     Z,         wa,        ?r,        !r")
7461	(unspec:SF [(match_operand:SI 1 "input_operand"
7462	    "m,         m,         wY,        Z,         r,         f,
7463	     wa,        r,         wa,        r")]
7464		   UNSPEC_SF_FROM_SI))
7465   (clobber (match_scratch:DI 2
7466	    "=X,        X,         X,         X,         X,         X,
7467             X,         r,         X,         X"))]
7468  "TARGET_NO_SF_SUBREG
7469   && (register_operand (operands[0], SFmode)
7470       || register_operand (operands[1], SImode))"
7471  "@
7472   lwz%U1%X1 %0,%1
7473   lfs%U1%X1 %0,%1
7474   lxssp %0,%1
7475   lxsspx %x0,%y1
7476   stw%U0%X0 %1,%0
7477   stfiwx %1,%y0
7478   stxsiwx %x1,%y0
7479   #
7480   mfvsrwz %0,%x1
7481   mr %0,%1"
7482
7483  "&& reload_completed
7484   && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7485   && int_reg_operand_not_pseudo (operands[1], SImode)"
7486  [(const_int 0)]
7487{
7488  rtx op0 = operands[0];
7489  rtx op1 = operands[1];
7490  rtx op2 = operands[2];
7491  rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7492
7493  /* Move SF value to upper 32-bits for xscvspdpn.  */
7494  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7495  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7496  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7497  DONE;
7498}
7499  [(set_attr "length"
7500	    "*,          *,         *,         *,         *,         *,
7501	     *,          12,        *,         *")
7502   (set_attr "type"
7503	    "load,       fpload,    fpload,    fpload,    store,     fpstore,
7504	     fpstore,    vecfloat,  mffgpr,    *")
7505   (set_attr "isa"
7506	    "*,          *,         p9v,       p8v,       *,         *,
7507	     p8v,        p8v,       p8v,       *")])
7508
7509
7510;; Move 64-bit binary/decimal floating point
7511(define_expand "mov<mode>"
7512  [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7513	(match_operand:FMOVE64 1 "any_operand"))]
7514  ""
7515{
7516  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7517  DONE;
7518})
7519
7520(define_split
7521  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7522	(match_operand:FMOVE64 1 "const_int_operand"))]
7523  "! TARGET_POWERPC64 && reload_completed
7524   && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7525       || (SUBREG_P (operands[0])
7526	   && REG_P (SUBREG_REG (operands[0]))
7527	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7528  [(set (match_dup 2) (match_dup 4))
7529   (set (match_dup 3) (match_dup 1))]
7530{
7531  int endian = (WORDS_BIG_ENDIAN == 0);
7532  HOST_WIDE_INT value = INTVAL (operands[1]);
7533
7534  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7535  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7536  operands[4] = GEN_INT (value >> 32);
7537  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7538})
7539
7540(define_split
7541  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7542	(match_operand:FMOVE64 1 "const_double_operand"))]
7543  "! TARGET_POWERPC64 && reload_completed
7544   && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7545       || (SUBREG_P (operands[0])
7546	   && REG_P (SUBREG_REG (operands[0]))
7547	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7548  [(set (match_dup 2) (match_dup 4))
7549   (set (match_dup 3) (match_dup 5))]
7550{
7551  int endian = (WORDS_BIG_ENDIAN == 0);
7552  long l[2];
7553
7554  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7555
7556  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7557  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7558  operands[4] = gen_int_mode (l[endian], SImode);
7559  operands[5] = gen_int_mode (l[1 - endian], SImode);
7560})
7561
7562(define_split
7563  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7564	(match_operand:FMOVE64 1 "const_double_operand"))]
7565  "TARGET_POWERPC64 && reload_completed
7566   && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7567       || (SUBREG_P (operands[0])
7568	   && REG_P (SUBREG_REG (operands[0]))
7569	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7570  [(set (match_dup 2) (match_dup 3))]
7571{
7572  int endian = (WORDS_BIG_ENDIAN == 0);
7573  long l[2];
7574  HOST_WIDE_INT val;
7575
7576  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7577
7578  operands[2] = gen_lowpart (DImode, operands[0]);
7579  /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7580  val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7581         | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7582
7583  operands[3] = gen_int_mode (val, DImode);
7584})
7585
7586;; Don't have reload use general registers to load a constant.  It is
7587;; less efficient than loading the constant into an FP register, since
7588;; it will probably be used there.
7589
7590;; The move constraints are ordered to prefer floating point registers before
7591;; general purpose registers to avoid doing a store and a load to get the value
7592;; into a floating point register when it is needed for a floating point
7593;; operation.  Prefer traditional floating point registers over VSX registers,
7594;; since the D-form version of the memory instructions does not need a GPR for
7595;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7596;; registers.
7597
7598;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7599;; except for 0.0 which can be created on VSX with an xor instruction.
7600
7601;;           STFD         LFD         FMR         LXSD        STXSD
7602;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7603;;           LWZ          STW         MR
7604
7605
7606(define_insn "*mov<mode>_hardfloat32"
7607  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7608            "=m,          d,          d,          <f64_p9>,   wY,
7609              <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7610              Y,          r,          !r")
7611	(match_operand:FMOVE64 1 "input_operand"
7612             "d,          m,          d,          wY,         <f64_p9>,
7613              Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7614              r,          Y,          r"))]
7615  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7616   && (gpc_reg_operand (operands[0], <MODE>mode)
7617       || gpc_reg_operand (operands[1], <MODE>mode))"
7618  "@
7619   stfd%U0%X0 %1,%0
7620   lfd%U1%X1 %0,%1
7621   fmr %0,%1
7622   lxsd %0,%1
7623   stxsd %1,%0
7624   lxsdx %x0,%y1
7625   stxsdx %x1,%y0
7626   xxlor %x0,%x1,%x1
7627   xxlxor %x0,%x0,%x0
7628   #
7629   #
7630   #
7631   #"
7632  [(set_attr "type"
7633            "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7634             fpload,      fpstore,    veclogical, veclogical, two,
7635             store,       load,       two")
7636   (set_attr "size" "64")
7637   (set_attr "length"
7638            "*,           *,          *,          *,          *,
7639             *,           *,          *,          *,          8,
7640             8,           8,          8")
7641   (set_attr "isa"
7642            "*,           *,          *,          p9v,        p9v,
7643             p7v,         p7v,        *,          *,          *,
7644             *,           *,          *")])
7645
7646;;           STW      LWZ     MR      G-const H-const F-const
7647
7648(define_insn "*mov<mode>_softfloat32"
7649  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7650           "=Y,       r,      r,      r,      r,      r")
7651
7652	(match_operand:FMOVE64 1 "input_operand"
7653            "r,       Y,      r,      G,      H,      F"))]
7654
7655  "!TARGET_POWERPC64
7656   && (gpc_reg_operand (operands[0], <MODE>mode)
7657       || gpc_reg_operand (operands[1], <MODE>mode))"
7658  "#"
7659  [(set_attr "type"
7660            "store,   load,   two,    *,      *,      *")
7661
7662   (set_attr "length"
7663             "8,      8,      8,      8,      12,     16")])
7664
7665; ld/std require word-aligned displacements -> 'Y' constraint.
7666; List Y->r and r->Y before r->r for reload.
7667
7668;;           STFD         LFD         FMR         LXSD        STXSD
7669;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7670;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7671;;           NOP          MFVSRD      MTVSRD
7672
7673(define_insn "*mov<mode>_hardfloat64"
7674  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7675           "=m,           d,          d,          <f64_p9>,   wY,
7676             <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7677             YZ,          r,          !r,         *c*l,       !r,
7678            *h,           r,          <f64_dm>")
7679	(match_operand:FMOVE64 1 "input_operand"
7680            "d,           m,          d,          wY,         <f64_p9>,
7681             Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7682             r,           YZ,         r,          r,          *h,
7683             0,           <f64_dm>,   r"))]
7684  "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7685   && (gpc_reg_operand (operands[0], <MODE>mode)
7686       || gpc_reg_operand (operands[1], <MODE>mode))"
7687  "@
7688   stfd%U0%X0 %1,%0
7689   lfd%U1%X1 %0,%1
7690   fmr %0,%1
7691   lxsd %0,%1
7692   stxsd %1,%0
7693   lxsdx %x0,%y1
7694   stxsdx %x1,%y0
7695   xxlor %x0,%x1,%x1
7696   xxlxor %x0,%x0,%x0
7697   li %0,0
7698   std%U0%X0 %1,%0
7699   ld%U1%X1 %0,%1
7700   mr %0,%1
7701   mt%0 %1
7702   mf%1 %0
7703   nop
7704   mfvsrd %0,%x1
7705   mtvsrd %x0,%1"
7706  [(set_attr "type"
7707            "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7708             fpload,      fpstore,    veclogical, veclogical, integer,
7709             store,       load,       *,          mtjmpr,     mfjmpr,
7710             *,           mftgpr,     mffgpr")
7711   (set_attr "size" "64")
7712   (set_attr "isa"
7713            "*,           *,          *,          p9v,        p9v,
7714             p7v,         p7v,        *,          *,          *,
7715             *,           *,          *,          *,          *,
7716             *,           p8v,        p8v")])
7717
7718;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7719;;           H-const  F-const  Special
7720
7721(define_insn "*mov<mode>_softfloat64"
7722  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7723           "=Y,       r,      r,      *c*l,   r,      r,
7724             r,       r,      *h")
7725
7726	(match_operand:FMOVE64 1 "input_operand"
7727            "r,       Y,      r,      r,      *h,     G,
7728             H,       F,      0"))]
7729
7730  "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7731   && (gpc_reg_operand (operands[0], <MODE>mode)
7732       || gpc_reg_operand (operands[1], <MODE>mode))"
7733  "@
7734   std%U0%X0 %1,%0
7735   ld%U1%X1 %0,%1
7736   mr %0,%1
7737   mt%0 %1
7738   mf%1 %0
7739   #
7740   #
7741   #
7742   nop"
7743  [(set_attr "type"
7744            "store,   load,   *,      mtjmpr, mfjmpr, *,
7745             *,       *,      *")
7746
7747   (set_attr "length"
7748            "*,       *,      *,      *,      *,      8,
7749             12,      16,     *")])
7750
7751(define_expand "mov<mode>"
7752  [(set (match_operand:FMOVE128 0 "general_operand")
7753	(match_operand:FMOVE128 1 "any_operand"))]
7754  ""
7755{
7756  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7757  DONE;
7758})
7759
7760;; It's important to list Y->r and r->Y before r->r because otherwise
7761;; reload, given m->r, will try to pick r->r and reload it, which
7762;; doesn't make progress.
7763
7764;; We can't split little endian direct moves of TDmode, because the words are
7765;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7766;; problematical.  Don't allow direct move for this case.
7767
7768;;		FPR load    FPR store   FPR move    FPR zero    GPR load
7769;;		GPR zero    GPR store   GPR move    MFVSRD      MTVSRD
7770
7771(define_insn_and_split "*mov<mode>_64bit_dm"
7772  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7773		"=m,        d,          d,          d,          Y,
7774		 r,         r,          r,          r,          d")
7775
7776	(match_operand:FMOVE128_FPR 1 "input_operand"
7777		"d,         m,          d,          <zero_fp>,  r,
7778		 <zero_fp>, Y,          r,          d,          r"))]
7779
7780  "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7781   && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7782   && (gpc_reg_operand (operands[0], <MODE>mode)
7783       || gpc_reg_operand (operands[1], <MODE>mode))"
7784  "#"
7785  "&& reload_completed"
7786  [(pc)]
7787{
7788  rs6000_split_multireg_move (operands[0], operands[1]);
7789  DONE;
7790}
7791  [(set_attr "length" "8")
7792   (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7793   (set_attr "max_prefixed_insns" "2")
7794   (set_attr "num_insns" "2")])
7795
7796(define_insn_and_split "*movtd_64bit_nodm"
7797  [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7798	(match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7799  "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7800   && (gpc_reg_operand (operands[0], TDmode)
7801       || gpc_reg_operand (operands[1], TDmode))"
7802  "#"
7803  "&& reload_completed"
7804  [(pc)]
7805{
7806  rs6000_split_multireg_move (operands[0], operands[1]);
7807  DONE;
7808}
7809  [(set_attr "length" "8,8,8,12,12,8")
7810   (set_attr "max_prefixed_insns" "2")
7811   (set_attr "num_insns" "2,2,2,3,3,2")])
7812
7813(define_insn_and_split "*mov<mode>_32bit"
7814  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7815	(match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7816  "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7817   && (FLOAT128_2REG_P (<MODE>mode)
7818       || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7819       || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7820   && (gpc_reg_operand (operands[0], <MODE>mode)
7821       || gpc_reg_operand (operands[1], <MODE>mode))"
7822  "#"
7823  "&& reload_completed"
7824  [(pc)]
7825{
7826  rs6000_split_multireg_move (operands[0], operands[1]);
7827  DONE;
7828}
7829  [(set_attr "length" "8,8,8,8,20,20,16")])
7830
7831(define_insn_and_split "*mov<mode>_softfloat"
7832  [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7833	(match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7834  "TARGET_SOFT_FLOAT
7835   && (gpc_reg_operand (operands[0], <MODE>mode)
7836       || gpc_reg_operand (operands[1], <MODE>mode))"
7837  "#"
7838  "&& reload_completed"
7839  [(pc)]
7840{
7841  rs6000_split_multireg_move (operands[0], operands[1]);
7842  DONE;
7843}
7844  [(set_attr_alternative "length"
7845       [(if_then_else (match_test "TARGET_POWERPC64")
7846	    (const_string "8")
7847	    (const_string "16"))
7848	(if_then_else (match_test "TARGET_POWERPC64")
7849	    (const_string "8")
7850	    (const_string "16"))
7851	(if_then_else (match_test "TARGET_POWERPC64")
7852	    (const_string "16")
7853	    (const_string "32"))
7854	(if_then_else (match_test "TARGET_POWERPC64")
7855	    (const_string "8")
7856	    (const_string "16"))])])
7857
7858(define_expand "@extenddf<mode>2"
7859  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7860	(float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7861  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7862{
7863  if (FLOAT128_IEEE_P (<MODE>mode))
7864    rs6000_expand_float128_convert (operands[0], operands[1], false);
7865  else if (TARGET_VSX)
7866    emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7867  else
7868    {
7869      rtx zero = gen_reg_rtx (DFmode);
7870      rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7871
7872      emit_insn (gen_extenddf2_fprs (<MODE>mode,
7873				     operands[0], operands[1], zero));
7874    }
7875  DONE;
7876})
7877
7878;; Allow memory operands for the source to be created by the combiner.
7879(define_insn_and_split "@extenddf<mode>2_fprs"
7880  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7881	(float_extend:IBM128
7882	 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7883   (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7884  "!TARGET_VSX && TARGET_HARD_FLOAT
7885   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7886  "#"
7887  "&& reload_completed"
7888  [(set (match_dup 3) (match_dup 1))
7889   (set (match_dup 4) (match_dup 2))]
7890{
7891  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7892  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7893
7894  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7895  operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7896})
7897
7898(define_insn_and_split "@extenddf<mode>2_vsx"
7899  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7900	(float_extend:IBM128
7901	 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7902  "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7903  "#"
7904  "&& reload_completed"
7905  [(set (match_dup 2) (match_dup 1))
7906   (set (match_dup 3) (match_dup 4))]
7907{
7908  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7909  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7910
7911  operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7912  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7913  operands[4] = CONST0_RTX (DFmode);
7914})
7915
7916(define_expand "extendsf<mode>2"
7917  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7918	(float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7919  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7920{
7921  if (FLOAT128_IEEE_P (<MODE>mode))
7922    rs6000_expand_float128_convert (operands[0], operands[1], false);
7923  else
7924    {
7925      rtx tmp = gen_reg_rtx (DFmode);
7926      emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7927      emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7928    }
7929  DONE;
7930})
7931
7932(define_expand "trunc<mode>df2"
7933  [(set (match_operand:DF 0 "gpc_reg_operand")
7934	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7935  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7936{
7937  if (FLOAT128_IEEE_P (<MODE>mode))
7938    {
7939      rs6000_expand_float128_convert (operands[0], operands[1], false);
7940      DONE;
7941    }
7942})
7943
7944(define_insn_and_split "trunc<mode>df2_internal1"
7945  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7946	(float_truncate:DF
7947	 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7948  "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7949   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7950  "@
7951   #
7952   fmr %0,%1"
7953  "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7954  [(const_int 0)]
7955{
7956  emit_note (NOTE_INSN_DELETED);
7957  DONE;
7958}
7959  [(set_attr "type" "fpsimple")])
7960
7961(define_insn "trunc<mode>df2_internal2"
7962  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7963	(float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7964  "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7965   && TARGET_LONG_DOUBLE_128"
7966  "fadd %0,%1,%L1"
7967  [(set_attr "type" "fp")])
7968
7969(define_expand "trunc<mode>sf2"
7970  [(set (match_operand:SF 0 "gpc_reg_operand")
7971	(float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7972  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7973{
7974  if (FLOAT128_IEEE_P (<MODE>mode))
7975    rs6000_expand_float128_convert (operands[0], operands[1], false);
7976  else
7977    {
7978      rtx tmp = gen_reg_rtx (DFmode);
7979      emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7980      emit_insn (gen_truncdfsf2 (operands[0], tmp));
7981    }
7982  DONE;
7983})
7984
7985(define_expand "floatsi<mode>2"
7986  [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7987		   (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7988	      (clobber (match_scratch:DI 2))])]
7989  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7990{
7991  rtx op0 = operands[0];
7992  rtx op1 = operands[1];
7993
7994  if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7995    ;
7996  else if (FLOAT128_IEEE_P (<MODE>mode))
7997    {
7998      rs6000_expand_float128_convert (op0, op1, false);
7999      DONE;
8000    }
8001  else
8002    {
8003      rtx tmp = gen_reg_rtx (DFmode);
8004      expand_float (tmp, op1, false);
8005      emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8006      DONE;
8007    }
8008})
8009
8010; fadd, but rounding towards zero.
8011; This is probably not the optimal code sequence.
8012(define_insn "fix_trunc_helper<mode>"
8013  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8014	(unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8015		   UNSPEC_FIX_TRUNC_TF))
8016   (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8017  "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8018  "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8019  [(set_attr "type" "fp")
8020   (set_attr "length" "20")])
8021
8022(define_expand "fix_trunc<mode>si2"
8023  [(set (match_operand:SI 0 "gpc_reg_operand")
8024	(fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8025  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8026{
8027  rtx op0 = operands[0];
8028  rtx op1 = operands[1];
8029
8030  if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8031    ;
8032  else
8033    {
8034      if (FLOAT128_IEEE_P (<MODE>mode))
8035	rs6000_expand_float128_convert (op0, op1, false);
8036      else
8037	emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8038      DONE;
8039    }
8040})
8041
8042(define_expand "@fix_trunc<mode>si2_fprs"
8043  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8044		   (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8045	      (clobber (match_dup 2))
8046	      (clobber (match_dup 3))
8047	      (clobber (match_dup 4))
8048	      (clobber (match_dup 5))])]
8049  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8050{
8051  operands[2] = gen_reg_rtx (DFmode);
8052  operands[3] = gen_reg_rtx (DFmode);
8053  operands[4] = gen_reg_rtx (DImode);
8054  operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8055})
8056
8057(define_insn_and_split "*fix_trunc<mode>si2_internal"
8058  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8059        (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8060   (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8061   (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8062   (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8063   (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8064  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8065  "#"
8066  ""
8067  [(pc)]
8068{
8069  rtx lowword;
8070  emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8071					 operands[3]));
8072
8073  gcc_assert (MEM_P (operands[5]));
8074  lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8075
8076  emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8077  emit_move_insn (operands[5], operands[4]);
8078  emit_move_insn (operands[0], lowword);
8079  DONE;
8080})
8081
8082(define_expand "fix_trunc<mode>di2"
8083  [(set (match_operand:DI 0 "gpc_reg_operand")
8084	(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8085  "TARGET_FLOAT128_TYPE"
8086{
8087  if (!TARGET_FLOAT128_HW)
8088    {
8089      rs6000_expand_float128_convert (operands[0], operands[1], false);
8090      DONE;
8091    }
8092})
8093
8094(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8095  [(set (match_operand:SDI 0 "gpc_reg_operand")
8096	(unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8097  "TARGET_FLOAT128_TYPE"
8098{
8099  rs6000_expand_float128_convert (operands[0], operands[1], true);
8100  DONE;
8101})
8102
8103(define_expand "floatdi<mode>2"
8104  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8105	(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8106  "TARGET_FLOAT128_TYPE"
8107{
8108  if (!TARGET_FLOAT128_HW)
8109    {
8110      rs6000_expand_float128_convert (operands[0], operands[1], false);
8111      DONE;
8112    }
8113})
8114
8115(define_expand "floatunsdi<IEEE128:mode>2"
8116  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8117	(unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8118  "TARGET_FLOAT128_TYPE"
8119{
8120  if (!TARGET_FLOAT128_HW)
8121    {
8122      rs6000_expand_float128_convert (operands[0], operands[1], true);
8123      DONE;
8124    }
8125})
8126
8127(define_expand "floatuns<IEEE128:mode>2"
8128  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8129	(unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8130  "TARGET_FLOAT128_TYPE"
8131{
8132  rtx op0 = operands[0];
8133  rtx op1 = operands[1];
8134
8135  if (TARGET_FLOAT128_HW)
8136    emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8137  else
8138    rs6000_expand_float128_convert (op0, op1, true);
8139  DONE;
8140})
8141
8142(define_expand "neg<mode>2"
8143  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8144	(neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8145  "FLOAT128_IEEE_P (<MODE>mode)
8146   || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8147{
8148  if (FLOAT128_IEEE_P (<MODE>mode))
8149    {
8150      if (TARGET_FLOAT128_HW)
8151	emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8152      else if (TARGET_FLOAT128_TYPE)
8153	emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8154					     operands[0], operands[1]));
8155      else
8156	{
8157	  rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8158	  rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8159						<MODE>mode,
8160						operands[1], <MODE>mode);
8161
8162	  if (target && !rtx_equal_p (target, operands[0]))
8163	    emit_move_insn (operands[0], target);
8164	}
8165      DONE;
8166    }
8167})
8168
8169(define_insn "neg<mode>2_internal"
8170  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8171	(neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8172  "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8173{
8174  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8175    return "fneg %L0,%L1\;fneg %0,%1";
8176  else
8177    return "fneg %0,%1\;fneg %L0,%L1";
8178}
8179  [(set_attr "type" "fpsimple")
8180   (set_attr "length" "8")])
8181
8182(define_expand "abs<mode>2"
8183  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8184	(abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8185  "FLOAT128_IEEE_P (<MODE>mode)
8186   || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8187{
8188  rtx label;
8189
8190  if (FLOAT128_IEEE_P (<MODE>mode))
8191    {
8192      if (TARGET_FLOAT128_HW)
8193	{
8194	  emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8195	  DONE;
8196	}
8197      else if (TARGET_FLOAT128_TYPE)
8198	{
8199	  emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8200					       operands[0], operands[1]));
8201	  DONE;
8202	}
8203      else
8204	FAIL;
8205    }
8206
8207  label = gen_label_rtx ();
8208  emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8209  emit_label (label);
8210  DONE;
8211})
8212
8213(define_expand "@abs<mode>2_internal"
8214  [(set (match_operand:IBM128 0 "gpc_reg_operand")
8215	(match_operand:IBM128 1 "gpc_reg_operand"))
8216   (set (match_dup 3) (match_dup 5))
8217   (set (match_dup 5) (abs:DF (match_dup 5)))
8218   (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8219   (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8220			   (label_ref (match_operand 2 ""))
8221			   (pc)))
8222   (set (match_dup 6) (neg:DF (match_dup 6)))]
8223  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8224{
8225  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8226  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8227  operands[3] = gen_reg_rtx (DFmode);
8228  operands[4] = gen_reg_rtx (CCFPmode);
8229  operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8230  operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8231})
8232
8233
8234;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8235;; register
8236
8237(define_expand "ieee_128bit_negative_zero"
8238  [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8239  "TARGET_FLOAT128_TYPE"
8240{
8241  rtvec v = rtvec_alloc (16);
8242  int i, high;
8243
8244  for (i = 0; i < 16; i++)
8245    RTVEC_ELT (v, i) = const0_rtx;
8246
8247  high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8248  RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8249
8250  rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8251  DONE;
8252})
8253
8254;; IEEE 128-bit negate
8255
8256;; We have 2 insns here for negate and absolute value.  The first uses
8257;; match_scratch so that phases like combine can recognize neg/abs as generic
8258;; insns, and second insn after the first split pass loads up the bit to
8259;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8260;; neg/abs to create the constant just once.
8261
8262(define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8263  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8264	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8265   (clobber (match_scratch:V16QI 2 "=v"))]
8266  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8267  "#"
8268  "&& 1"
8269  [(parallel [(set (match_dup 0)
8270		   (neg:IEEE128 (match_dup 1)))
8271	      (use (match_dup 2))])]
8272{
8273  if (GET_CODE (operands[2]) == SCRATCH)
8274    operands[2] = gen_reg_rtx (V16QImode);
8275
8276  operands[3] = gen_reg_rtx (V16QImode);
8277  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8278}
8279  [(set_attr "length" "8")
8280   (set_attr "type" "vecsimple")])
8281
8282(define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8283  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8284	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8285   (use (match_operand:V16QI 2 "register_operand" "v"))]
8286  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8287  "xxlxor %x0,%x1,%x2"
8288  [(set_attr "type" "veclogical")])
8289
8290;; IEEE 128-bit absolute value
8291(define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8292  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8293	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8294   (clobber (match_scratch:V16QI 2 "=v"))]
8295  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8296  "#"
8297  "&& 1"
8298  [(parallel [(set (match_dup 0)
8299		   (abs:IEEE128 (match_dup 1)))
8300	      (use (match_dup 2))])]
8301{
8302  if (GET_CODE (operands[2]) == SCRATCH)
8303    operands[2] = gen_reg_rtx (V16QImode);
8304
8305  operands[3] = gen_reg_rtx (V16QImode);
8306  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8307}
8308  [(set_attr "length" "8")
8309   (set_attr "type" "vecsimple")])
8310
8311(define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8312  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8313	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8314   (use (match_operand:V16QI 2 "register_operand" "v"))]
8315  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8316  "xxlandc %x0,%x1,%x2"
8317  [(set_attr "type" "veclogical")])
8318
8319;; IEEE 128-bit negative absolute value
8320(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8321  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8322	(neg:IEEE128
8323	 (abs:IEEE128
8324	  (match_operand:IEEE128 1 "register_operand" "wa"))))
8325   (clobber (match_scratch:V16QI 2 "=v"))]
8326  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8327   && FLOAT128_IEEE_P (<MODE>mode)"
8328  "#"
8329  "&& 1"
8330  [(parallel [(set (match_dup 0)
8331		   (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8332	      (use (match_dup 2))])]
8333{
8334  if (GET_CODE (operands[2]) == SCRATCH)
8335    operands[2] = gen_reg_rtx (V16QImode);
8336
8337  operands[3] = gen_reg_rtx (V16QImode);
8338  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8339}
8340  [(set_attr "length" "8")
8341   (set_attr "type" "vecsimple")])
8342
8343(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8344  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8345	(neg:IEEE128
8346	 (abs:IEEE128
8347	  (match_operand:IEEE128 1 "register_operand" "wa"))))
8348   (use (match_operand:V16QI 2 "register_operand" "v"))]
8349  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8350  "xxlor %x0,%x1,%x2"
8351  [(set_attr "type" "veclogical")])
8352
8353;; Float128 conversion functions.  These expand to library function calls.
8354;; We use expand to convert from IBM double double to IEEE 128-bit
8355;; and trunc for the opposite.
8356(define_expand "extendiftf2"
8357  [(set (match_operand:TF 0 "gpc_reg_operand")
8358	(float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8359  "TARGET_FLOAT128_TYPE"
8360{
8361  rs6000_expand_float128_convert (operands[0], operands[1], false);
8362  DONE;
8363})
8364
8365(define_expand "extendifkf2"
8366  [(set (match_operand:KF 0 "gpc_reg_operand")
8367	(float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8368  "TARGET_FLOAT128_TYPE"
8369{
8370  rs6000_expand_float128_convert (operands[0], operands[1], false);
8371  DONE;
8372})
8373
8374(define_expand "extendtfkf2"
8375  [(set (match_operand:KF 0 "gpc_reg_operand")
8376	(float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8377  "TARGET_FLOAT128_TYPE"
8378{
8379  rs6000_expand_float128_convert (operands[0], operands[1], false);
8380  DONE;
8381})
8382
8383(define_expand "extendtfif2"
8384  [(set (match_operand:IF 0 "gpc_reg_operand")
8385	(float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8386  "TARGET_FLOAT128_TYPE"
8387{
8388  rs6000_expand_float128_convert (operands[0], operands[1], false);
8389  DONE;
8390})
8391
8392(define_expand "trunciftf2"
8393  [(set (match_operand:TF 0 "gpc_reg_operand")
8394	(float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8395  "TARGET_FLOAT128_TYPE"
8396{
8397  rs6000_expand_float128_convert (operands[0], operands[1], false);
8398  DONE;
8399})
8400
8401(define_expand "truncifkf2"
8402  [(set (match_operand:KF 0 "gpc_reg_operand")
8403	(float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8404  "TARGET_FLOAT128_TYPE"
8405{
8406  rs6000_expand_float128_convert (operands[0], operands[1], false);
8407  DONE;
8408})
8409
8410(define_expand "trunckftf2"
8411  [(set (match_operand:TF 0 "gpc_reg_operand")
8412	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8413  "TARGET_FLOAT128_TYPE"
8414{
8415  rs6000_expand_float128_convert (operands[0], operands[1], false);
8416  DONE;
8417})
8418
8419(define_expand "trunctfif2"
8420  [(set (match_operand:IF 0 "gpc_reg_operand")
8421	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8422  "TARGET_FLOAT128_TYPE"
8423{
8424  rs6000_expand_float128_convert (operands[0], operands[1], false);
8425  DONE;
8426})
8427
8428(define_insn_and_split "*extend<mode>tf2_internal"
8429  [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8430	(float_extend:TF
8431	 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8432   "TARGET_FLOAT128_TYPE
8433    && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8434  "#"
8435  "&& reload_completed"
8436  [(set (match_dup 0) (match_dup 2))]
8437{
8438  operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8439})
8440
8441(define_insn_and_split "*extendtf<mode>2_internal"
8442  [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8443	(float_extend:IFKF
8444	 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8445   "TARGET_FLOAT128_TYPE
8446    && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8447  "#"
8448  "&& reload_completed"
8449  [(set (match_dup 0) (match_dup 2))]
8450{
8451  operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8452})
8453
8454
8455;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8456;; must have 3 arguments, and scratch register constraint must be a single
8457;; constraint.
8458
8459;; Reload patterns to support gpr load/store with misaligned mem.
8460;; and multiple gpr load/store at offset >= 0xfffc
8461(define_expand "reload_<mode>_store"
8462  [(parallel [(match_operand 0 "memory_operand" "=m")
8463              (match_operand 1 "gpc_reg_operand" "r")
8464              (match_operand:GPR 2 "register_operand" "=&b")])]
8465  ""
8466{
8467  rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8468  DONE;
8469})
8470
8471(define_expand "reload_<mode>_load"
8472  [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8473              (match_operand 1 "memory_operand" "m")
8474              (match_operand:GPR 2 "register_operand" "=b")])]
8475  ""
8476{
8477  rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8478  DONE;
8479})
8480
8481
8482;; Reload patterns for various types using the vector registers.  We may need
8483;; an additional base register to convert the reg+offset addressing to reg+reg
8484;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8485;; index register for gpr registers.
8486(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8487  [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8488              (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8489              (match_operand:P 2 "register_operand" "=b")])]
8490  "<P:tptrsize>"
8491{
8492  rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8493  DONE;
8494})
8495
8496(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8497  [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8498              (match_operand:RELOAD 1 "memory_operand" "m")
8499              (match_operand:P 2 "register_operand" "=b")])]
8500  "<P:tptrsize>"
8501{
8502  rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8503  DONE;
8504})
8505
8506
8507;; Reload sometimes tries to move the address to a GPR, and can generate
8508;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8509;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8510
8511(define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8512  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8513	(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8514		       (match_operand:P 2 "reg_or_cint_operand" "rI"))
8515	       (const_int -16)))]
8516  "TARGET_ALTIVEC && reload_completed"
8517  "#"
8518  "&& reload_completed"
8519  [(set (match_dup 0)
8520	(plus:P (match_dup 1)
8521		(match_dup 2)))
8522   (set (match_dup 0)
8523	(and:P (match_dup 0)
8524	       (const_int -16)))])
8525
8526;; Power8 merge instructions to allow direct move to/from floating point
8527;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8528;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8529;; value, since it is allocated in reload and not all of the flow information
8530;; is setup for it.  We have two patterns to do the two moves between gprs and
8531;; fprs.  There isn't a dependancy between the two, but we could potentially
8532;; schedule other instructions between the two instructions.
8533
8534(define_insn "p8_fmrgow_<mode>"
8535  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8536	(unspec:FMOVE64X [
8537		(match_operand:DF 1 "register_operand" "d")
8538		(match_operand:DF 2 "register_operand" "d")]
8539			 UNSPEC_P8V_FMRGOW))]
8540  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8541  "fmrgow %0,%1,%2"
8542  [(set_attr "type" "fpsimple")])
8543
8544(define_insn "p8_mtvsrwz"
8545  [(set (match_operand:DF 0 "register_operand" "=d")
8546	(unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8547		   UNSPEC_P8V_MTVSRWZ))]
8548  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8549  "mtvsrwz %x0,%1"
8550  [(set_attr "type" "mftgpr")])
8551
8552(define_insn_and_split "reload_fpr_from_gpr<mode>"
8553  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8554	(unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8555			 UNSPEC_P8V_RELOAD_FROM_GPR))
8556   (clobber (match_operand:IF 2 "register_operand" "=d"))]
8557  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8558  "#"
8559  "&& reload_completed"
8560  [(const_int 0)]
8561{
8562  rtx dest = operands[0];
8563  rtx src = operands[1];
8564  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8565  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8566  rtx gpr_hi_reg = gen_highpart (SImode, src);
8567  rtx gpr_lo_reg = gen_lowpart (SImode, src);
8568
8569  emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8570  emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8571  emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8572  DONE;
8573}
8574  [(set_attr "length" "12")
8575   (set_attr "type" "three")])
8576
8577;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8578(define_insn "p8_mtvsrd_df"
8579  [(set (match_operand:DF 0 "register_operand" "=wa")
8580	(unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8581		   UNSPEC_P8V_MTVSRD))]
8582  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8583  "mtvsrd %x0,%1"
8584  [(set_attr "type" "mftgpr")])
8585
8586(define_insn "p8_xxpermdi_<mode>"
8587  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8588	(unspec:FMOVE128_GPR [
8589		(match_operand:DF 1 "register_operand" "wa")
8590		(match_operand:DF 2 "register_operand" "wa")]
8591		UNSPEC_P8V_XXPERMDI))]
8592  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8593  "xxpermdi %x0,%x1,%x2,0"
8594  [(set_attr "type" "vecperm")])
8595
8596(define_insn_and_split "reload_vsx_from_gpr<mode>"
8597  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8598	(unspec:FMOVE128_GPR
8599	 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8600	 UNSPEC_P8V_RELOAD_FROM_GPR))
8601   (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8602  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8603  "#"
8604  "&& reload_completed"
8605  [(const_int 0)]
8606{
8607  rtx dest = operands[0];
8608  rtx src = operands[1];
8609  /* You might think that we could use op0 as one temp and a DF clobber
8610     as op2, but you'd be wrong.  Secondary reload move patterns don't
8611     check for overlap of the clobber and the destination.  */
8612  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8613  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8614  rtx gpr_hi_reg = gen_highpart (DImode, src);
8615  rtx gpr_lo_reg = gen_lowpart (DImode, src);
8616
8617  emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8618  emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8619  emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8620  DONE;
8621}
8622  [(set_attr "length" "12")
8623   (set_attr "type" "three")])
8624
8625(define_split
8626  [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8627	(match_operand:FMOVE128_GPR 1 "input_operand"))]
8628  "reload_completed
8629   && (int_reg_operand (operands[0], <MODE>mode)
8630       || int_reg_operand (operands[1], <MODE>mode))
8631   && (!TARGET_DIRECT_MOVE_128
8632       || (!vsx_register_operand (operands[0], <MODE>mode)
8633           && !vsx_register_operand (operands[1], <MODE>mode)))"
8634  [(pc)]
8635{
8636  rs6000_split_multireg_move (operands[0], operands[1]);
8637  DONE;
8638})
8639
8640;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8641;; type is stored internally as double precision in the VSX registers, we have
8642;; to convert it from the vector format.
8643(define_insn "p8_mtvsrd_sf"
8644  [(set (match_operand:SF 0 "register_operand" "=wa")
8645	(unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8646		   UNSPEC_P8V_MTVSRD))]
8647  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8648  "mtvsrd %x0,%1"
8649  [(set_attr "type" "mftgpr")])
8650
8651(define_insn_and_split "reload_vsx_from_gprsf"
8652  [(set (match_operand:SF 0 "register_operand" "=wa")
8653	(unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8654		   UNSPEC_P8V_RELOAD_FROM_GPR))
8655   (clobber (match_operand:DI 2 "register_operand" "=r"))]
8656  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8657  "#"
8658  "&& reload_completed"
8659  [(const_int 0)]
8660{
8661  rtx op0 = operands[0];
8662  rtx op1 = operands[1];
8663  rtx op2 = operands[2];
8664  rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8665
8666  /* Move SF value to upper 32-bits for xscvspdpn.  */
8667  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8668  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8669  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8670  DONE;
8671}
8672  [(set_attr "length" "8")
8673   (set_attr "type" "two")])
8674
8675;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8676;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8677;; and then doing a move of that.
8678(define_insn "p8_mfvsrd_3_<mode>"
8679  [(set (match_operand:DF 0 "register_operand" "=r")
8680	(unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8681		   UNSPEC_P8V_RELOAD_FROM_VSX))]
8682  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8683  "mfvsrd %0,%x1"
8684  [(set_attr "type" "mftgpr")])
8685
8686(define_insn_and_split "reload_gpr_from_vsx<mode>"
8687  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8688	(unspec:FMOVE128_GPR
8689	 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8690	 UNSPEC_P8V_RELOAD_FROM_VSX))
8691   (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8692  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8693  "#"
8694  "&& reload_completed"
8695  [(const_int 0)]
8696{
8697  rtx dest = operands[0];
8698  rtx src = operands[1];
8699  rtx tmp = operands[2];
8700  rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8701  rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8702
8703  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8704  emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8705  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8706  DONE;
8707}
8708  [(set_attr "length" "12")
8709   (set_attr "type" "three")])
8710
8711;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8712;; type is stored internally as double precision, we have to convert it to the
8713;; vector format.
8714
8715(define_insn_and_split "reload_gpr_from_vsxsf"
8716  [(set (match_operand:SF 0 "register_operand" "=r")
8717	(unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8718		   UNSPEC_P8V_RELOAD_FROM_VSX))
8719   (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8720  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8721  "#"
8722  "&& reload_completed"
8723  [(const_int 0)]
8724{
8725  rtx op0 = operands[0];
8726  rtx op1 = operands[1];
8727  rtx op2 = operands[2];
8728  rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8729  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8730
8731  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8732  emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8733  DONE;
8734}
8735  [(set_attr "length" "8")
8736   (set_attr "type" "two")
8737   (set_attr "isa" "p8v")])
8738
8739;; Next come the multi-word integer load and store and the load and store
8740;; multiple insns.
8741
8742;; List r->r after r->Y, otherwise reload will try to reload a
8743;; non-offsettable address by using r->r which won't make progress.
8744;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8745;; a gpr into a fpr instead of reloading an invalid 'Y' address
8746
8747;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8748;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8749;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8750;;        AVX const
8751
8752(define_insn "*movdi_internal32"
8753  [(set (match_operand:DI 0 "nonimmediate_operand"
8754         "=Y,        r,         r,         m,         ^d,        ^d,
8755          r,         wY,        Z,         ^v,        $v,        ^wa,
8756          wa,        wa,        v,         wa,        *i,        v,
8757          v")
8758	(match_operand:DI 1 "input_operand"
8759         "r,         Y,         r,         ^d,        m,         ^d,
8760          IJKnF,     ^v,        $v,        wY,        Z,         ^wa,
8761          Oj,        wM,        OjwM,      Oj,        wM,        wS,
8762          wB"))]
8763  "! TARGET_POWERPC64
8764   && (gpc_reg_operand (operands[0], DImode)
8765       || gpc_reg_operand (operands[1], DImode))"
8766  "@
8767   #
8768   #
8769   #
8770   stfd%U0%X0 %1,%0
8771   lfd%U1%X1 %0,%1
8772   fmr %0,%1
8773   #
8774   stxsd %1,%0
8775   stxsdx %x1,%y0
8776   lxsd %0,%1
8777   lxsdx %x0,%y1
8778   xxlor %x0,%x1,%x1
8779   xxspltib %x0,0
8780   xxspltib %x0,255
8781   vspltisw %0,%1
8782   xxlxor %x0,%x0,%x0
8783   xxlorc %x0,%x0,%x0
8784   #
8785   #"
8786  [(set_attr "type"
8787         "store,     load,      *,         fpstore,   fpload,    fpsimple,
8788          *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8789          vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8790          vecsimple")
8791   (set_attr "size" "64")
8792   (set_attr "length"
8793         "8,         8,         8,         *,         *,         *,
8794          16,        *,         *,         *,         *,         *,
8795          *,         *,         *,         *,         *,         8,
8796          *")
8797   (set_attr "isa"
8798         "*,         *,         *,         *,         *,         *,
8799          *,         p9v,       p7v,       p9v,       p7v,       *,
8800          p9v,       p9v,       p7v,       *,         *,         p7v,
8801          p7v")])
8802
8803(define_split
8804  [(set (match_operand:DI 0 "gpc_reg_operand")
8805	(match_operand:DI 1 "const_int_operand"))]
8806  "! TARGET_POWERPC64 && reload_completed
8807   && gpr_or_gpr_p (operands[0], operands[1])
8808   && !direct_move_p (operands[0], operands[1])"
8809  [(set (match_dup 2) (match_dup 4))
8810   (set (match_dup 3) (match_dup 1))]
8811{
8812  HOST_WIDE_INT value = INTVAL (operands[1]);
8813  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8814				       DImode);
8815  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8816				       DImode);
8817  operands[4] = GEN_INT (value >> 32);
8818  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8819})
8820
8821(define_split
8822  [(set (match_operand:DIFD 0 "nonimmediate_operand")
8823        (match_operand:DIFD 1 "input_operand"))]
8824  "reload_completed && !TARGET_POWERPC64
8825   && gpr_or_gpr_p (operands[0], operands[1])
8826   && !direct_move_p (operands[0], operands[1])"
8827  [(pc)]
8828{
8829  rs6000_split_multireg_move (operands[0], operands[1]);
8830  DONE;
8831})
8832
8833;;	   GPR store   GPR load    GPR move
8834;;	   GPR li      GPR lis     GPR pli     GPR #
8835;;	   FPR store   FPR load    FPR move
8836;;	   AVX store   AVX store   AVX load    AVX load    VSX move
8837;;	   P9 0        P9 -1       AVX 0/-1    VSX 0       VSX -1
8838;;	   P9 const    AVX const
8839;;	   From SPR    To SPR      SPR<->SPR
8840;;	   VSX->GPR    GPR->VSX
8841(define_insn "*movdi_internal64"
8842  [(set (match_operand:DI 0 "nonimmediate_operand"
8843	  "=YZ,        r,          r,
8844	   r,          r,          r,          r,
8845	   m,          ^d,         ^d,
8846	   wY,         Z,          $v,         $v,         ^wa,
8847	   wa,         wa,         v,          wa,         wa,
8848	   v,          v,
8849	   r,          *h,         *h,
8850	   ?r,         ?wa")
8851	(match_operand:DI 1 "input_operand"
8852	  "r,          YZ,         r,
8853	   I,          L,          eI,         nF,
8854	   ^d,         m,          ^d,
8855	   ^v,         $v,         wY,         Z,          ^wa,
8856	   Oj,         wM,         OjwM,       Oj,         wM,
8857	   wS,         wB,
8858	   *h,         r,          0,
8859	   wa,         r"))]
8860  "TARGET_POWERPC64
8861   && (gpc_reg_operand (operands[0], DImode)
8862       || gpc_reg_operand (operands[1], DImode))"
8863  "@
8864   std%U0%X0 %1,%0
8865   ld%U1%X1 %0,%1
8866   mr %0,%1
8867   li %0,%1
8868   lis %0,%v1
8869   li %0,%1
8870   #
8871   stfd%U0%X0 %1,%0
8872   lfd%U1%X1 %0,%1
8873   fmr %0,%1
8874   stxsd %1,%0
8875   stxsdx %x1,%y0
8876   lxsd %0,%1
8877   lxsdx %x0,%y1
8878   xxlor %x0,%x1,%x1
8879   xxspltib %x0,0
8880   xxspltib %x0,255
8881   #
8882   xxlxor %x0,%x0,%x0
8883   xxlorc %x0,%x0,%x0
8884   #
8885   #
8886   mf%1 %0
8887   mt%0 %1
8888   nop
8889   mfvsrd %0,%x1
8890   mtvsrd %x0,%1"
8891  [(set_attr "type"
8892	  "store,      load,       *,
8893	   *,          *,          *,          *,
8894	   fpstore,    fpload,     fpsimple,
8895	   fpstore,    fpstore,    fpload,     fpload,     veclogical,
8896	   vecsimple,  vecsimple,  vecsimple,  veclogical, veclogical,
8897	   vecsimple,  vecsimple,
8898	   mfjmpr,     mtjmpr,     *,
8899	   mftgpr,     mffgpr")
8900   (set_attr "size" "64")
8901   (set_attr "length"
8902	  "*,          *,          *,
8903	   *,          *,          *,          20,
8904	   *,          *,          *,
8905	   *,          *,          *,          *,          *,
8906	   *,          *,          *,          *,          *,
8907	   8,          *,
8908	   *,          *,          *,
8909	   *,          *")
8910   (set_attr "isa"
8911	  "*,          *,          *,
8912	   *,          *,          p10,        *,
8913	   *,          *,          *,
8914	   p9v,        p7v,        p9v,        p7v,        *,
8915	   p9v,        p9v,        p7v,        *,          *,
8916	   p7v,        p7v,
8917	   *,          *,          *,
8918	   p8v,        p8v")])
8919
8920; Some DImode loads are best done as a load of -1 followed by a mask
8921; instruction.
8922(define_split
8923  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8924	(match_operand:DI 1 "const_int_operand"))]
8925  "TARGET_POWERPC64
8926   && num_insns_constant (operands[1], DImode) > 1
8927   && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8928   && rs6000_is_valid_and_mask (operands[1], DImode)"
8929  [(set (match_dup 0)
8930	(const_int -1))
8931   (set (match_dup 0)
8932	(and:DI (match_dup 0)
8933		(match_dup 1)))]
8934  "")
8935
8936;; Split a load of a large constant into the appropriate five-instruction
8937;; sequence.  Handle anything in a constant number of insns.
8938;; When non-easy constants can go in the TOC, this should use
8939;; easy_fp_constant predicate.
8940(define_split
8941  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8942	(match_operand:DI 1 "const_int_operand"))]
8943  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8944  [(set (match_dup 0) (match_dup 2))
8945   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8946{
8947  if (rs6000_emit_set_const (operands[0], operands[1]))
8948    DONE;
8949  else
8950    FAIL;
8951})
8952
8953(define_split
8954  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8955	(match_operand:DI 1 "const_scalar_int_operand"))]
8956  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8957  [(set (match_dup 0) (match_dup 2))
8958   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8959{
8960  if (rs6000_emit_set_const (operands[0], operands[1]))
8961    DONE;
8962  else
8963    FAIL;
8964})
8965
8966(define_split
8967  [(set (match_operand:DI 0 "altivec_register_operand")
8968	(match_operand:DI 1 "s5bit_cint_operand"))]
8969  "TARGET_VSX && reload_completed"
8970  [(const_int 0)]
8971{
8972  rtx op0 = operands[0];
8973  rtx op1 = operands[1];
8974  int r = REGNO (op0);
8975  rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8976
8977  emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8978  if (op1 != const0_rtx && op1 != constm1_rtx)
8979    {
8980      rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8981      emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8982    }
8983  DONE;
8984})
8985
8986;; Split integer constants that can be loaded with XXSPLTIB and a
8987;; sign extend operation.
8988(define_split
8989  [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8990	(match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8991  "TARGET_P9_VECTOR && reload_completed"
8992  [(const_int 0)]
8993{
8994  rtx op0 = operands[0];
8995  rtx op1 = operands[1];
8996  int r = REGNO (op0);
8997  rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8998
8999  emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9000  if (<MODE>mode == DImode)
9001    emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9002  else if (<MODE>mode == SImode)
9003    emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9004  else if (<MODE>mode == HImode)
9005    {
9006      rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9007      emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9008    }
9009  DONE;
9010})
9011
9012
9013;; TImode/PTImode is similar, except that we usually want to compute the
9014;; address into a register and use lsi/stsi (the exception is during reload).
9015
9016(define_insn "*mov<mode>_string"
9017  [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9018	(match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9019  "! TARGET_POWERPC64
9020   && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9021   && (gpc_reg_operand (operands[0], <MODE>mode)
9022       || gpc_reg_operand (operands[1], <MODE>mode))"
9023  "#"
9024  [(set_attr "type" "store,store,load,load,*,*")
9025   (set_attr "update" "yes")
9026   (set_attr "indexed" "yes")
9027   (set_attr "cell_micro" "conditional")])
9028
9029(define_insn "*mov<mode>_ppc64"
9030  [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9031	(match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9032  "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9033   && (gpc_reg_operand (operands[0], <MODE>mode)
9034       || gpc_reg_operand (operands[1], <MODE>mode)))"
9035{
9036  return rs6000_output_move_128bit (operands);
9037}
9038  [(set_attr "type" "store,store,load,load,*,*")
9039   (set_attr "length" "8")
9040   (set_attr "max_prefixed_insns" "2")])
9041
9042(define_split
9043  [(set (match_operand:TI2 0 "int_reg_operand")
9044	(match_operand:TI2 1 "const_scalar_int_operand"))]
9045  "TARGET_POWERPC64
9046   && (VECTOR_MEM_NONE_P (<MODE>mode)
9047       || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9048  [(set (match_dup 2) (match_dup 4))
9049   (set (match_dup 3) (match_dup 5))]
9050{
9051  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9052				       <MODE>mode);
9053  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9054				       <MODE>mode);
9055  if (CONST_WIDE_INT_P (operands[1]))
9056    {
9057      operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9058      operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9059    }
9060  else if (CONST_INT_P (operands[1]))
9061    {
9062      operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9063      operands[5] = operands[1];
9064    }
9065  else
9066    FAIL;
9067})
9068
9069(define_split
9070  [(set (match_operand:TI2 0 "nonimmediate_operand")
9071        (match_operand:TI2 1 "input_operand"))]
9072  "reload_completed
9073   && gpr_or_gpr_p (operands[0], operands[1])
9074   && !direct_move_p (operands[0], operands[1])
9075   && !quad_load_store_p (operands[0], operands[1])"
9076  [(pc)]
9077{
9078  rs6000_split_multireg_move (operands[0], operands[1]);
9079  DONE;
9080})
9081
9082(define_expand "setmemsi"
9083  [(parallel [(set (match_operand:BLK 0 "")
9084		   (match_operand 2 "const_int_operand"))
9085	      (use (match_operand:SI 1 ""))
9086	      (use (match_operand:SI 3 ""))])]
9087  ""
9088{
9089  /* If value to set is not zero, use the library routine.  */
9090  if (operands[2] != const0_rtx)
9091    FAIL;
9092
9093  if (expand_block_clear (operands))
9094    DONE;
9095  else
9096    FAIL;
9097})
9098
9099;; String compare N insn.
9100;; Argument 0 is the target (result)
9101;; Argument 1 is the destination
9102;; Argument 2 is the source
9103;; Argument 3 is the length
9104;; Argument 4 is the alignment
9105
9106(define_expand "cmpstrnsi"
9107  [(parallel [(set (match_operand:SI 0)
9108               (compare:SI (match_operand:BLK 1)
9109                           (match_operand:BLK 2)))
9110	      (use (match_operand:SI 3))
9111	      (use (match_operand:SI 4))])]
9112  "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9113{
9114  if (optimize_insn_for_size_p ())
9115    FAIL;
9116
9117  if (expand_strn_compare (operands, 0))
9118    DONE;
9119  else
9120    FAIL;
9121})
9122
9123;; String compare insn.
9124;; Argument 0 is the target (result)
9125;; Argument 1 is the destination
9126;; Argument 2 is the source
9127;; Argument 3 is the alignment
9128
9129(define_expand "cmpstrsi"
9130  [(parallel [(set (match_operand:SI 0)
9131               (compare:SI (match_operand:BLK 1)
9132                           (match_operand:BLK 2)))
9133	      (use (match_operand:SI 3))])]
9134  "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9135{
9136  if (optimize_insn_for_size_p ())
9137    FAIL;
9138
9139  if (expand_strn_compare (operands, 1))
9140    DONE;
9141  else
9142    FAIL;
9143})
9144
9145;; Block compare insn.
9146;; Argument 0 is the target (result)
9147;; Argument 1 is the destination
9148;; Argument 2 is the source
9149;; Argument 3 is the length
9150;; Argument 4 is the alignment
9151
9152(define_expand "cmpmemsi"
9153  [(parallel [(set (match_operand:SI 0)
9154               (compare:SI (match_operand:BLK 1)
9155                           (match_operand:BLK 2)))
9156	      (use (match_operand:SI 3))
9157	      (use (match_operand:SI 4))])]
9158  "TARGET_POPCNTD"
9159{
9160  if (expand_block_compare (operands))
9161    DONE;
9162  else
9163    FAIL;
9164})
9165
9166;; String/block copy insn (source and destination must not overlap).
9167;; Argument 0 is the destination
9168;; Argument 1 is the source
9169;; Argument 2 is the length
9170;; Argument 3 is the alignment
9171
9172(define_expand "cpymemsi"
9173  [(parallel [(set (match_operand:BLK 0 "")
9174		   (match_operand:BLK 1 ""))
9175	      (use (match_operand:SI 2 ""))
9176	      (use (match_operand:SI 3 ""))])]
9177  ""
9178{
9179  if (expand_block_move (operands, false))
9180    DONE;
9181  else
9182    FAIL;
9183})
9184
9185;; String/block move insn (source and destination may overlap).
9186;; Argument 0 is the destination
9187;; Argument 1 is the source
9188;; Argument 2 is the length
9189;; Argument 3 is the alignment
9190
9191(define_expand "movmemsi"
9192  [(parallel [(set (match_operand:BLK 0 "")
9193		   (match_operand:BLK 1 ""))
9194	      (use (match_operand:SI 2 ""))
9195	      (use (match_operand:SI 3 ""))])]
9196  ""
9197{
9198  if (expand_block_move (operands, true))
9199    DONE;
9200  else
9201    FAIL;
9202})
9203
9204
9205;; Define insns that do load or store with update.  Some of these we can
9206;; get by using pre-decrement or pre-increment, but the hardware can also
9207;; do cases where the increment is not the size of the object.
9208;;
9209;; In all these cases, we use operands 0 and 1 for the register being
9210;; incremented because those are the operands that local-alloc will
9211;; tie and these are the pair most likely to be tieable (and the ones
9212;; that will benefit the most).
9213
9214(define_insn "*movdi_update1"
9215  [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9216	(mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9217			(match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9218   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9219	(plus:P (match_dup 1) (match_dup 2)))]
9220  "TARGET_POWERPC64 && TARGET_UPDATE
9221   && (!avoiding_indexed_address_p (DImode)
9222       || !gpc_reg_operand (operands[2], Pmode))"
9223  "@
9224   ldux %3,%0,%2
9225   ldu %3,%2(%0)"
9226  [(set_attr "type" "load")
9227   (set_attr "update" "yes")
9228   (set_attr "indexed" "yes,no")])
9229
9230(define_insn "movdi_<mode>_update"
9231  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9232			(match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9233	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
9234   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9235	(plus:P (match_dup 1) (match_dup 2)))]
9236  "TARGET_POWERPC64 && TARGET_UPDATE
9237   && (!avoiding_indexed_address_p (DImode)
9238       || !gpc_reg_operand (operands[2], Pmode)
9239       || (REG_P (operands[0])
9240	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9241  "@
9242   stdux %3,%0,%2
9243   stdu %3,%2(%0)"
9244  [(set_attr "type" "store")
9245   (set_attr "update" "yes")
9246   (set_attr "indexed" "yes,no")])
9247
9248;; This pattern is only conditional on TARGET_64BIT, as it is
9249;; needed for stack allocation, even if the user passes -mno-update.
9250(define_insn "movdi_update_stack"
9251  [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9252			 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9253	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
9254   (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9255	(plus:DI (match_dup 1) (match_dup 2)))]
9256  "TARGET_64BIT"
9257  "@
9258   stdux %3,%0,%2
9259   stdu %3,%2(%0)"
9260  [(set_attr "type" "store")
9261   (set_attr "update" "yes")
9262   (set_attr "indexed" "yes,no")])
9263
9264(define_insn "*movsi_update1"
9265  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9266	(mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9267			(match_operand:P 2 "reg_or_short_operand" "r,I"))))
9268   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9269	(plus:P (match_dup 1) (match_dup 2)))]
9270  "TARGET_UPDATE
9271   && (!avoiding_indexed_address_p (SImode)
9272       || !gpc_reg_operand (operands[2], Pmode))"
9273  "@
9274   lwzux %3,%0,%2
9275   lwzu %3,%2(%0)"
9276  [(set_attr "type" "load")
9277   (set_attr "update" "yes")
9278   (set_attr "indexed" "yes,no")])
9279
9280(define_insn "*movsi_update2"
9281  [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9282	(sign_extend:EXTSI
9283	 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9284			 (match_operand:P 2 "gpc_reg_operand" "r")))))
9285   (set (match_operand:P 0 "gpc_reg_operand" "=b")
9286	(plus:P (match_dup 1) (match_dup 2)))]
9287  "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9288  "lwaux %3,%0,%2"
9289  [(set_attr "type" "load")
9290   (set_attr "sign_extend" "yes")
9291   (set_attr "update" "yes")
9292   (set_attr "indexed" "yes")])
9293
9294(define_insn "movsi_<mode>_update"
9295  [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9296			(match_operand:P 2 "reg_or_short_operand" "r,I")))
9297	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
9298   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9299	(plus:P (match_dup 1) (match_dup 2)))]
9300  "TARGET_UPDATE
9301   && (!avoiding_indexed_address_p (SImode)
9302       || !gpc_reg_operand (operands[2], Pmode)
9303       || (REG_P (operands[0])
9304	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9305  "@
9306   stwux %3,%0,%2
9307   stwu %3,%2(%0)"
9308  [(set_attr "type" "store")
9309   (set_attr "update" "yes")
9310   (set_attr "indexed" "yes,no")])
9311
9312;; This is an unconditional pattern; needed for stack allocation, even
9313;; if the user passes -mno-update.
9314(define_insn "movsi_update_stack"
9315  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9316			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9317	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
9318   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9319	(plus:SI (match_dup 1) (match_dup 2)))]
9320  "TARGET_32BIT"
9321  "@
9322   stwux %3,%0,%2
9323   stwu %3,%2(%0)"
9324  [(set_attr "type" "store")
9325   (set_attr "update" "yes")
9326   (set_attr "indexed" "yes,no")])
9327
9328(define_insn "*movhi_update1"
9329  [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9330	(mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9331			(match_operand:P 2 "reg_or_short_operand" "r,I"))))
9332   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9333	(plus:P (match_dup 1) (match_dup 2)))]
9334  "TARGET_UPDATE
9335   && (!avoiding_indexed_address_p (HImode)
9336       || !gpc_reg_operand (operands[2], SImode))"
9337  "@
9338   lhzux %3,%0,%2
9339   lhzu %3,%2(%0)"
9340  [(set_attr "type" "load")
9341   (set_attr "update" "yes")
9342   (set_attr "indexed" "yes,no")])
9343
9344(define_insn "*movhi_update2"
9345  [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9346	(zero_extend:EXTHI
9347	 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9348			 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9349   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9350	(plus:P (match_dup 1) (match_dup 2)))]
9351  "TARGET_UPDATE
9352   && (!avoiding_indexed_address_p (HImode)
9353       || !gpc_reg_operand (operands[2], Pmode))"
9354  "@
9355   lhzux %3,%0,%2
9356   lhzu %3,%2(%0)"
9357  [(set_attr "type" "load")
9358   (set_attr "update" "yes")
9359   (set_attr "indexed" "yes,no")])
9360
9361(define_insn "*movhi_update3"
9362  [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9363	(sign_extend:EXTHI
9364	 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9365			 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9366   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9367	(plus:P (match_dup 1) (match_dup 2)))]
9368  "TARGET_UPDATE
9369   && !(avoiding_indexed_address_p (HImode)
9370	&& gpc_reg_operand (operands[2], Pmode))"
9371  "@
9372   lhaux %3,%0,%2
9373   lhau %3,%2(%0)"
9374  [(set_attr "type" "load")
9375   (set_attr "sign_extend" "yes")
9376   (set_attr "update" "yes")
9377   (set_attr "indexed" "yes,no")])
9378
9379(define_insn "*movhi_update4"
9380  [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9381			(match_operand:P 2 "reg_or_short_operand" "r,I")))
9382	(match_operand:HI 3 "gpc_reg_operand" "r,r"))
9383   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9384	(plus:P (match_dup 1) (match_dup 2)))]
9385  "TARGET_UPDATE
9386   && (!avoiding_indexed_address_p (HImode)
9387       || !gpc_reg_operand (operands[2], Pmode))"
9388  "@
9389   sthux %3,%0,%2
9390   sthu %3,%2(%0)"
9391  [(set_attr "type" "store")
9392   (set_attr "update" "yes")
9393   (set_attr "indexed" "yes,no")])
9394
9395(define_insn "*movqi_update1"
9396  [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9397	(mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9398			(match_operand:P 2 "reg_or_short_operand" "r,I"))))
9399   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9400	(plus:P (match_dup 1) (match_dup 2)))]
9401  "TARGET_UPDATE
9402   && (!avoiding_indexed_address_p (QImode)
9403       || !gpc_reg_operand (operands[2], Pmode))"
9404  "@
9405   lbzux %3,%0,%2
9406   lbzu %3,%2(%0)"
9407  [(set_attr "type" "load")
9408   (set_attr "update" "yes")
9409   (set_attr "indexed" "yes,no")])
9410
9411(define_insn "*movqi_update2"
9412  [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9413	(zero_extend:EXTQI
9414	 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9415			 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9416   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9417	(plus:P (match_dup 1) (match_dup 2)))]
9418  "TARGET_UPDATE
9419   && (!avoiding_indexed_address_p (QImode)
9420       || !gpc_reg_operand (operands[2], Pmode))"
9421  "@
9422   lbzux %3,%0,%2
9423   lbzu %3,%2(%0)"
9424  [(set_attr "type" "load")
9425   (set_attr "update" "yes")
9426   (set_attr "indexed" "yes,no")])
9427
9428(define_insn "*movqi_update3"
9429  [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9430			(match_operand:P 2 "reg_or_short_operand" "r,I")))
9431	(match_operand:QI 3 "gpc_reg_operand" "r,r"))
9432   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9433	(plus:P (match_dup 1) (match_dup 2)))]
9434  "TARGET_UPDATE
9435   && (!avoiding_indexed_address_p (QImode)
9436       || !gpc_reg_operand (operands[2], Pmode))"
9437  "@
9438   stbux %3,%0,%2
9439   stbu %3,%2(%0)"
9440  [(set_attr "type" "store")
9441   (set_attr "update" "yes")
9442   (set_attr "indexed" "yes,no")])
9443
9444(define_insn "*mov<SFDF:mode>_update1"
9445  [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9446	(mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9447			  (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9448   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9449	(plus:P (match_dup 1) (match_dup 2)))]
9450  "TARGET_HARD_FLOAT && TARGET_UPDATE
9451   && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9452       || !gpc_reg_operand (operands[2], Pmode))"
9453  "@
9454   lf<sd>ux %3,%0,%2
9455   lf<sd>u %3,%2(%0)"
9456  [(set_attr "type" "fpload")
9457   (set_attr "update" "yes")
9458   (set_attr "indexed" "yes,no")
9459   (set_attr "size" "<SFDF:bits>")])
9460
9461(define_insn "*mov<SFDF:mode>_update2"
9462  [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9463			  (match_operand:P 2 "reg_or_short_operand" "r,I")))
9464	(match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9465   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9466	(plus:P (match_dup 1) (match_dup 2)))]
9467  "TARGET_HARD_FLOAT && TARGET_UPDATE
9468   && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9469       || !gpc_reg_operand (operands[2], Pmode))"
9470  "@
9471   stf<sd>ux %3,%0,%2
9472   stf<sd>u %3,%2(%0)"
9473  [(set_attr "type" "fpstore")
9474   (set_attr "update" "yes")
9475   (set_attr "indexed" "yes,no")
9476   (set_attr "size" "<SFDF:bits>")])
9477
9478(define_insn "*movsf_update3"
9479  [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9480	(mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9481			(match_operand:P 2 "reg_or_short_operand" "r,I"))))
9482   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9483	(plus:P (match_dup 1) (match_dup 2)))]
9484  "TARGET_SOFT_FLOAT && TARGET_UPDATE
9485   && (!avoiding_indexed_address_p (SFmode)
9486       || !gpc_reg_operand (operands[2], Pmode))"
9487  "@
9488   lwzux %3,%0,%2
9489   lwzu %3,%2(%0)"
9490  [(set_attr "type" "load")
9491   (set_attr "update" "yes")
9492   (set_attr "indexed" "yes,no")])
9493
9494(define_insn "*movsf_update4"
9495  [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9496			(match_operand:P 2 "reg_or_short_operand" "r,I")))
9497	(match_operand:SF 3 "gpc_reg_operand" "r,r"))
9498   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9499	(plus:P (match_dup 1) (match_dup 2)))]
9500  "TARGET_SOFT_FLOAT && TARGET_UPDATE
9501   && (!avoiding_indexed_address_p (SFmode)
9502       || !gpc_reg_operand (operands[2], Pmode))"
9503  "@
9504   stwux %3,%0,%2
9505   stwu %3,%2(%0)"
9506  [(set_attr "type" "store")
9507   (set_attr "update" "yes")
9508   (set_attr "indexed" "yes,no")])
9509
9510
9511;; After inserting conditional returns we can sometimes have
9512;; unnecessary register moves.  Unfortunately we cannot have a
9513;; modeless peephole here, because some single SImode sets have early
9514;; clobber outputs.  Although those sets expand to multi-ppc-insn
9515;; sequences, using get_attr_length here will smash the operands
9516;; array.  Neither is there an early_cobbler_p predicate.
9517;; Also this optimization interferes with scalars going into
9518;; altivec registers (the code does reloading through the FPRs).
9519(define_peephole2
9520  [(set (match_operand:DF 0 "gpc_reg_operand")
9521	(match_operand:DF 1 "any_operand"))
9522   (set (match_operand:DF 2 "gpc_reg_operand")
9523	(match_dup 0))]
9524  "!TARGET_VSX
9525   && peep2_reg_dead_p (2, operands[0])"
9526  [(set (match_dup 2) (match_dup 1))])
9527
9528(define_peephole2
9529  [(set (match_operand:SF 0 "gpc_reg_operand")
9530	(match_operand:SF 1 "any_operand"))
9531   (set (match_operand:SF 2 "gpc_reg_operand")
9532	(match_dup 0))]
9533  "!TARGET_P8_VECTOR
9534   && peep2_reg_dead_p (2, operands[0])"
9535  [(set (match_dup 2) (match_dup 1))])
9536
9537
9538;; TLS support.
9539
9540(define_insn "*tls_gd_pcrel<bits>"
9541  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9542	(unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9543		   (const_int 0)]
9544		  UNSPEC_TLSGD))]
9545  "HAVE_AS_TLS && TARGET_ELF"
9546  "la %0,%1@got@tlsgd@pcrel"
9547  [(set_attr "prefixed" "yes")])
9548
9549(define_insn_and_split "*tls_gd<bits>"
9550  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9551	(unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9552		   (match_operand:P 2 "gpc_reg_operand" "b")]
9553		  UNSPEC_TLSGD))]
9554  "HAVE_AS_TLS && TARGET_ELF"
9555  "addi %0,%2,%1@got@tlsgd"
9556  "&& TARGET_CMODEL != CMODEL_SMALL"
9557  [(set (match_dup 3)
9558	(high:P
9559	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9560   (set (match_dup 0)
9561	(lo_sum:P (match_dup 3)
9562	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9563{
9564  operands[3] = gen_reg_rtx (<MODE>mode);
9565}
9566  [(set (attr "length")
9567     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9568		   (const_int 8)
9569		   (const_int 4)))])
9570
9571(define_insn "*tls_gd_high<bits>"
9572  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9573     (high:P
9574       (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9575		  (match_operand:P 2 "gpc_reg_operand" "b")]
9576		 UNSPEC_TLSGD)))]
9577  "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9578  "addis %0,%2,%1@got@tlsgd@ha")
9579
9580(define_insn "*tls_gd_low<bits>"
9581  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9582     (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9583       (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9584		  (match_operand:P 3 "gpc_reg_operand" "b")]
9585		 UNSPEC_TLSGD)))]
9586  "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9587  "addi %0,%1,%2@got@tlsgd@l")
9588
9589(define_insn "*tls_ld_pcrel<bits>"
9590  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9591	(unspec:P [(const_int 0)]
9592		  UNSPEC_TLSLD))]
9593  "HAVE_AS_TLS && TARGET_ELF"
9594  "la %0,%&@got@tlsld@pcrel"
9595  [(set_attr "prefixed" "yes")])
9596
9597(define_insn_and_split "*tls_ld<bits>"
9598  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9599	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9600		  UNSPEC_TLSLD))]
9601  "HAVE_AS_TLS && TARGET_ELF"
9602  "addi %0,%1,%&@got@tlsld"
9603  "&& TARGET_CMODEL != CMODEL_SMALL"
9604  [(set (match_dup 2)
9605	(high:P
9606	    (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9607   (set (match_dup 0)
9608	(lo_sum:P (match_dup 2)
9609	    (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9610{
9611  operands[2] = gen_reg_rtx (<MODE>mode);
9612}
9613  [(set (attr "length")
9614     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9615		   (const_int 8)
9616		   (const_int 4)))])
9617
9618(define_insn "*tls_ld_high<bits>"
9619  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9620     (high:P
9621       (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9622		 UNSPEC_TLSLD)))]
9623  "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9624  "addis %0,%1,%&@got@tlsld@ha")
9625
9626(define_insn "*tls_ld_low<bits>"
9627  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9628     (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9629       (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9630		 UNSPEC_TLSLD)))]
9631  "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9632  "addi %0,%1,%&@got@tlsld@l")
9633
9634(define_insn "tls_dtprel_<bits>"
9635  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9636	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9637		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9638		  UNSPEC_TLSDTPREL))]
9639  "HAVE_AS_TLS"
9640  "addi %0,%1,%2@dtprel"
9641  [(set (attr "prefixed")
9642	(if_then_else (match_test "rs6000_tls_size == 16")
9643		      (const_string "no")
9644		      (const_string "yes")))])
9645
9646(define_insn "tls_dtprel_ha_<bits>"
9647  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9648	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9649		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9650		  UNSPEC_TLSDTPRELHA))]
9651  "HAVE_AS_TLS"
9652  "addis %0,%1,%2@dtprel@ha")
9653
9654(define_insn "tls_dtprel_lo_<bits>"
9655  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9656	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9657		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9658		  UNSPEC_TLSDTPRELLO))]
9659  "HAVE_AS_TLS"
9660  "addi %0,%1,%2@dtprel@l")
9661
9662(define_insn_and_split "tls_got_dtprel_<bits>"
9663  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9664	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9665		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9666		  UNSPEC_TLSGOTDTPREL))]
9667  "HAVE_AS_TLS"
9668  "<ptrload> %0,%2@got@dtprel(%1)"
9669  "&& TARGET_CMODEL != CMODEL_SMALL"
9670  [(set (match_dup 3)
9671	(high:P
9672	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9673   (set (match_dup 0)
9674	(lo_sum:P (match_dup 3)
9675	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9676{
9677  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9678}
9679  [(set (attr "length")
9680     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9681		   (const_int 8)
9682		   (const_int 4)))])
9683
9684(define_insn "*tls_got_dtprel_high<bits>"
9685  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9686     (high:P
9687       (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9688		  (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9689		 UNSPEC_TLSGOTDTPREL)))]
9690  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9691  "addis %0,%1,%2@got@dtprel@ha")
9692
9693(define_insn "*tls_got_dtprel_low<bits>"
9694  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9695     (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9696	 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9697		    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9698		   UNSPEC_TLSGOTDTPREL)))]
9699  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9700  "<ptrload> %0,%2@got@dtprel@l(%1)")
9701
9702(define_insn "tls_tprel_<bits>"
9703  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9704	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9705		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9706		  UNSPEC_TLSTPREL))]
9707  "HAVE_AS_TLS"
9708  "addi %0,%1,%2@tprel"
9709  [(set (attr "prefixed")
9710	(if_then_else (match_test "rs6000_tls_size == 16")
9711		      (const_string "no")
9712		      (const_string "yes")))])
9713
9714(define_insn "tls_tprel_ha_<bits>"
9715  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9716	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9717		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9718		  UNSPEC_TLSTPRELHA))]
9719  "HAVE_AS_TLS"
9720  "addis %0,%1,%2@tprel@ha")
9721
9722(define_insn "tls_tprel_lo_<bits>"
9723  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9724	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9725		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9726		  UNSPEC_TLSTPRELLO))]
9727  "HAVE_AS_TLS"
9728  "addi %0,%1,%2@tprel@l")
9729
9730(define_insn "*tls_got_tprel_pcrel_<bits>"
9731  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9732	(unspec:P [(const_int 0)
9733		   (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9734		  UNSPEC_TLSGOTTPREL))]
9735  "HAVE_AS_TLS"
9736  "<ptrload> %0,%1@got@tprel@pcrel"
9737  [(set_attr "prefixed" "yes")])
9738
9739;; "b" output constraint here and on tls_tls input to support linker tls
9740;; optimization.  The linker may edit the instructions emitted by a
9741;; tls_got_tprel/tls_tls pair to addis,addi.
9742(define_insn_and_split "tls_got_tprel_<bits>"
9743  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9744	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9745		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9746		  UNSPEC_TLSGOTTPREL))]
9747  "HAVE_AS_TLS"
9748  "<ptrload> %0,%2@got@tprel(%1)"
9749  "&& TARGET_CMODEL != CMODEL_SMALL"
9750  [(set (match_dup 3)
9751	(high:P
9752	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9753   (set (match_dup 0)
9754	(lo_sum:P (match_dup 3)
9755	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9756{
9757  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9758}
9759  [(set (attr "length")
9760     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9761		   (const_int 8)
9762		   (const_int 4)))])
9763
9764(define_insn "*tls_got_tprel_high<bits>"
9765  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9766     (high:P
9767       (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9768		  (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9769		 UNSPEC_TLSGOTTPREL)))]
9770  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9771  "addis %0,%1,%2@got@tprel@ha")
9772
9773(define_insn "*tls_got_tprel_low<bits>"
9774  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9775     (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9776	 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9777		    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9778		   UNSPEC_TLSGOTTPREL)))]
9779  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9780  "<ptrload> %0,%2@got@tprel@l(%1)")
9781
9782(define_insn "tls_tls_pcrel_<bits>"
9783  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9784	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9785		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9786		  UNSPEC_TLSTLS_PCREL))]
9787  "TARGET_ELF && HAVE_AS_TLS"
9788  "add %0,%1,%2@tls@pcrel")
9789
9790(define_insn "tls_tls_<bits>"
9791  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9792	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9793		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9794		  UNSPEC_TLSTLS))]
9795  "TARGET_ELF && HAVE_AS_TLS"
9796  "add %0,%1,%2@tls")
9797
9798(define_expand "tls_get_tpointer"
9799  [(set (match_operand:SI 0 "gpc_reg_operand")
9800	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9801  "TARGET_XCOFF && HAVE_AS_TLS"
9802{
9803  emit_insn (gen_tls_get_tpointer_internal ());
9804  emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9805  DONE;
9806})
9807
9808(define_insn "tls_get_tpointer_internal"
9809  [(set (reg:SI 3)
9810	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9811   (clobber (reg:SI LR_REGNO))]
9812  "TARGET_XCOFF && HAVE_AS_TLS"
9813  "bla __get_tpointer")
9814
9815(define_expand "tls_get_addr<mode>"
9816  [(set (match_operand:P 0 "gpc_reg_operand")
9817	(unspec:P [(match_operand:P 1 "gpc_reg_operand")
9818                   (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9819  "TARGET_XCOFF && HAVE_AS_TLS"
9820{
9821  emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9822  emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9823  emit_insn (gen_tls_get_addr_internal<mode> ());
9824  emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9825  DONE;
9826})
9827
9828(define_insn "tls_get_addr_internal<mode>"
9829  [(set (reg:P 3)
9830	(unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9831   (clobber (reg:P 0))
9832   (clobber (reg:P 4))
9833   (clobber (reg:P 5))
9834   (clobber (reg:P 11))
9835   (clobber (reg:CC CR0_REGNO))
9836   (clobber (reg:P LR_REGNO))]
9837  "TARGET_XCOFF && HAVE_AS_TLS"
9838  "bla __tls_get_addr")
9839
9840;; Next come insns related to the calling sequence.
9841;;
9842;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9843;; We move the back-chain and decrement the stack pointer.
9844;;
9845;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9846;; constant alloca, using that predicate will force the generic code to put
9847;; the constant size into a register before calling the expander.
9848;;
9849;; As a result the expander would not have the constant size information
9850;; in those cases and would have to generate less efficient code.
9851;;
9852;; Thus we allow reg_or_cint_operand instead so that the expander can see
9853;; the constant size.  The value is forced into a register if necessary.
9854;;
9855(define_expand "allocate_stack"
9856  [(set (match_operand 0 "gpc_reg_operand")
9857	(minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9858   (set (reg 1)
9859	(minus (reg 1) (match_dup 1)))]
9860  ""
9861{
9862  rtx chain = gen_reg_rtx (Pmode);
9863  rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9864  rtx neg_op0;
9865  rtx insn, par, set, mem;
9866
9867  /* By allowing reg_or_cint_operand as the predicate we can get
9868     better code for stack-clash-protection because we do not lose
9869     size information.  But the rest of the code expects the operand
9870     to be reg_or_short_operand.  If it isn't, then force it into
9871     a register.  */
9872  rtx orig_op1 = operands[1];
9873  if (!reg_or_short_operand (operands[1], Pmode))
9874    operands[1] = force_reg (Pmode, operands[1]);
9875
9876  emit_move_insn (chain, stack_bot);
9877
9878  /* Check stack bounds if necessary.  */
9879  if (crtl->limit_stack)
9880    {
9881      rtx available;
9882      available = expand_binop (Pmode, sub_optab,
9883				stack_pointer_rtx, stack_limit_rtx,
9884				NULL_RTX, 1, OPTAB_WIDEN);
9885      emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9886    }
9887
9888  /* Allocate and probe if requested.
9889     This may look similar to the loop we use for prologue allocations,
9890     but it is critically different.  For the former we know the loop
9891     will iterate, but do not know that generally here.  The former
9892     uses that knowledge to rotate the loop.  Combining them would be
9893     possible with some performance cost.  */
9894  if (flag_stack_clash_protection)
9895    {
9896      rtx rounded_size, last_addr, residual;
9897      HOST_WIDE_INT probe_interval;
9898      compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9899						&residual, &probe_interval,
9900						orig_op1);
9901
9902      /* We do occasionally get in here with constant sizes, we might
9903	 as well do a reasonable job when we obviously can.  */
9904      if (rounded_size != const0_rtx)
9905	{
9906	  rtx loop_lab, end_loop;
9907	  bool rotated = CONST_INT_P (rounded_size);
9908	  rtx update = GEN_INT (-probe_interval);
9909	  if (probe_interval > 32768)
9910	    update = force_reg (Pmode, update);
9911
9912	  emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9913							last_addr, rotated);
9914
9915	  if (TARGET_32BIT)
9916	    emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9917					       stack_pointer_rtx,
9918					       update, chain));
9919	  else
9920	    emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9921					       stack_pointer_rtx,
9922					       update, chain));
9923	  emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9924						      last_addr, rotated);
9925	}
9926
9927      /* Now handle residuals.  We just have to set operands[1] correctly
9928	 and let the rest of the expander run.  */
9929      operands[1] = residual;
9930    }
9931
9932  if (!(CONST_INT_P (operands[1])
9933	&& IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9934    {
9935      operands[1] = force_reg (Pmode, operands[1]);
9936      neg_op0 = gen_reg_rtx (Pmode);
9937      emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9938    }
9939  else
9940    neg_op0 = GEN_INT (-INTVAL (operands[1]));
9941
9942  insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9943				       : gen_movdi_update_stack))
9944			(stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9945			 chain));
9946  /* Since we didn't use gen_frame_mem to generate the MEM, grab
9947     it now and set the alias set/attributes. The above gen_*_update
9948     calls will generate a PARALLEL with the MEM set being the first
9949     operation. */
9950  par = PATTERN (insn);
9951  gcc_assert (GET_CODE (par) == PARALLEL);
9952  set = XVECEXP (par, 0, 0);
9953  gcc_assert (GET_CODE (set) == SET);
9954  mem = SET_DEST (set);
9955  gcc_assert (MEM_P (mem));
9956  MEM_NOTRAP_P (mem) = 1;
9957  set_mem_alias_set (mem, get_frame_alias_set ());
9958
9959  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9960  DONE;
9961})
9962
9963;; These patterns say how to save and restore the stack pointer.  We need not
9964;; save the stack pointer at function level since we are careful to
9965;; preserve the backchain.  At block level, we have to restore the backchain
9966;; when we restore the stack pointer.
9967;;
9968;; For nonlocal gotos, we must save both the stack pointer and its
9969;; backchain and restore both.  Note that in the nonlocal case, the
9970;; save area is a memory location.
9971
9972(define_expand "save_stack_function"
9973  [(match_operand 0 "any_operand")
9974   (match_operand 1 "any_operand")]
9975  ""
9976  "DONE;")
9977
9978(define_expand "restore_stack_function"
9979  [(match_operand 0 "any_operand")
9980   (match_operand 1 "any_operand")]
9981  ""
9982  "DONE;")
9983
9984;; Adjust stack pointer (op0) to a new value (op1).
9985;; First copy old stack backchain to new location, and ensure that the
9986;; scheduler won't reorder the sp assignment before the backchain write.
9987(define_expand "restore_stack_block"
9988  [(set (match_dup 2) (match_dup 3))
9989   (set (match_dup 4) (match_dup 2))
9990   (match_dup 5)
9991   (set (match_operand 0 "register_operand")
9992	(match_operand 1 "register_operand"))]
9993  ""
9994{
9995  rtvec p;
9996
9997  operands[1] = force_reg (Pmode, operands[1]);
9998  operands[2] = gen_reg_rtx (Pmode);
9999  operands[3] = gen_frame_mem (Pmode, operands[0]);
10000  operands[4] = gen_frame_mem (Pmode, operands[1]);
10001  p = rtvec_alloc (1);
10002  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10003				  const0_rtx);
10004  operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10005})
10006
10007(define_expand "save_stack_nonlocal"
10008  [(set (match_dup 3) (match_dup 4))
10009   (set (match_operand 0 "memory_operand") (match_dup 3))
10010   (set (match_dup 2) (match_operand 1 "register_operand"))]
10011  ""
10012{
10013  int units_per_word = (TARGET_32BIT) ? 4 : 8;
10014
10015  /* Copy the backchain to the first word, sp to the second.  */
10016  operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10017  operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10018  operands[3] = gen_reg_rtx (Pmode);
10019  operands[4] = gen_frame_mem (Pmode, operands[1]);
10020})
10021
10022(define_expand "restore_stack_nonlocal"
10023  [(set (match_dup 2) (match_operand 1 "memory_operand"))
10024   (set (match_dup 3) (match_dup 4))
10025   (set (match_dup 5) (match_dup 2))
10026   (match_dup 6)
10027   (set (match_operand 0 "register_operand") (match_dup 3))]
10028  ""
10029{
10030  int units_per_word = (TARGET_32BIT) ? 4 : 8;
10031  rtvec p;
10032
10033  /* Restore the backchain from the first word, sp from the second.  */
10034  operands[2] = gen_reg_rtx (Pmode);
10035  operands[3] = gen_reg_rtx (Pmode);
10036  operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10037  operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10038  operands[5] = gen_frame_mem (Pmode, operands[3]);
10039  p = rtvec_alloc (1);
10040  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10041				  const0_rtx);
10042  operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10043})
10044
10045;; Load up a PC-relative address.  Print_operand_address will append a @pcrel
10046;; to the symbol or label.
10047(define_insn "*pcrel_local_addr"
10048  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10049	(match_operand:DI 1 "pcrel_local_address"))]
10050  "TARGET_PCREL"
10051  "la %0,%a1"
10052  [(set_attr "prefixed" "yes")])
10053
10054;; Load up a PC-relative address to an external symbol.  If the symbol and the
10055;; program are both defined in the main program, the linker will optimize this
10056;; to a PADDI.  Otherwise, it will create a GOT address that is relocated by
10057;; the dynamic linker and loaded up.  Print_operand_address will append a
10058;; @got@pcrel to the symbol.
10059(define_insn "*pcrel_extern_addr"
10060  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10061	(match_operand:DI 1 "pcrel_external_address"))]
10062  "TARGET_PCREL"
10063  "ld %0,%a1"
10064  [(set_attr "prefixed" "yes")
10065   (set_attr "type" "load")])
10066
10067;; TOC register handling.
10068
10069;; Code to initialize the TOC register...
10070
10071(define_insn "load_toc_aix_si"
10072  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10073		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
10074	      (use (reg:SI 2))])]
10075  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10076{
10077  char buf[30];
10078  extern int need_toc_init;
10079  need_toc_init = 1;
10080  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10081  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10082  operands[2] = gen_rtx_REG (Pmode, 2);
10083  return "lwz %0,%1(%2)";
10084}
10085  [(set_attr "type" "load")
10086   (set_attr "update" "no")
10087   (set_attr "indexed" "no")])
10088
10089(define_insn "load_toc_aix_di"
10090  [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10091		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
10092	      (use (reg:DI 2))])]
10093  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10094{
10095  char buf[30];
10096  extern int need_toc_init;
10097  need_toc_init = 1;
10098  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10099			       !TARGET_ELF || !TARGET_MINIMAL_TOC);
10100  if (TARGET_ELF)
10101    strcat (buf, "@toc");
10102  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10103  operands[2] = gen_rtx_REG (Pmode, 2);
10104  return "ld %0,%1(%2)";
10105}
10106  [(set_attr "type" "load")
10107   (set_attr "update" "no")
10108   (set_attr "indexed" "no")])
10109
10110(define_insn "load_toc_v4_pic_si"
10111  [(set (reg:SI LR_REGNO)
10112	(unspec:SI [(const_int 0)] UNSPEC_TOC))]
10113  "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10114  "bl _GLOBAL_OFFSET_TABLE_@local-4"
10115  [(set_attr "type" "branch")])
10116
10117(define_expand "load_toc_v4_PIC_1"
10118  [(parallel [(set (reg:SI LR_REGNO)
10119		   (match_operand:SI 0 "immediate_operand" "s"))
10120	      (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10121  "TARGET_ELF && DEFAULT_ABI == ABI_V4
10122   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10123  "")
10124
10125(define_insn "load_toc_v4_PIC_1_normal"
10126  [(set (reg:SI LR_REGNO)
10127	(match_operand:SI 0 "immediate_operand" "s"))
10128   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10129  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10130   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10131  "bcl 20,31,%0\n%0:"
10132  [(set_attr "type" "branch")
10133   (set_attr "cannot_copy" "yes")])
10134
10135(define_insn "load_toc_v4_PIC_1_476"
10136  [(set (reg:SI LR_REGNO)
10137	(match_operand:SI 0 "immediate_operand" "s"))
10138   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10139  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10140   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10141{
10142  char name[32];
10143  static char templ[32];
10144
10145  get_ppc476_thunk_name (name);
10146  sprintf (templ, "bl %s\n%%0:", name);
10147  return templ;
10148}
10149  [(set_attr "type" "branch")
10150   (set_attr "cannot_copy" "yes")])
10151
10152(define_expand "load_toc_v4_PIC_1b"
10153  [(parallel [(set (reg:SI LR_REGNO)
10154		   (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10155			       (label_ref (match_operand 1 ""))]
10156		           UNSPEC_TOCPTR))
10157	      (match_dup 1)])]
10158  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10159  "")
10160
10161(define_insn "load_toc_v4_PIC_1b_normal"
10162  [(set (reg:SI LR_REGNO)
10163	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10164		    (label_ref (match_operand 1 "" ""))]
10165		UNSPEC_TOCPTR))
10166   (match_dup 1)]
10167  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10168  "bcl 20,31,$+8\;.long %0-$"
10169  [(set_attr "type" "branch")
10170   (set_attr "length" "8")])
10171
10172(define_insn "load_toc_v4_PIC_1b_476"
10173  [(set (reg:SI LR_REGNO)
10174	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10175		    (label_ref (match_operand 1 "" ""))]
10176		UNSPEC_TOCPTR))
10177   (match_dup 1)]
10178  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10179{
10180  char name[32];
10181  static char templ[32];
10182
10183  get_ppc476_thunk_name (name);
10184  sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10185  return templ;
10186}
10187  [(set_attr "type" "branch")
10188   (set_attr "length" "16")])
10189
10190(define_insn "load_toc_v4_PIC_2"
10191  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10192	(mem:SI (plus:SI
10193		  (match_operand:SI 1 "gpc_reg_operand" "b")
10194		  (const
10195		    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10196			      (match_operand:SI 3 "immediate_operand" "s"))))))]
10197  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10198  "lwz %0,%2-%3(%1)"
10199  [(set_attr "type" "load")])
10200
10201(define_insn "load_toc_v4_PIC_3b"
10202  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10203	(plus:SI
10204	  (match_operand:SI 1 "gpc_reg_operand" "b")
10205	  (high:SI
10206	    (const
10207	      (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10208			(match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10209  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10210  "addis %0,%1,%2-%3@ha")
10211
10212(define_insn "load_toc_v4_PIC_3c"
10213  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10214	(lo_sum:SI
10215	  (match_operand:SI 1 "gpc_reg_operand" "b")
10216	  (const
10217	    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10218		      (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10219  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10220  "addi %0,%1,%2-%3@l")
10221
10222;; If the TOC is shared over a translation unit, as happens with all
10223;; the kinds of PIC that we support, we need to restore the TOC
10224;; pointer only when jumping over units of translation.
10225;; On Darwin, we need to reload the picbase.
10226
10227(define_expand "builtin_setjmp_receiver"
10228  [(use (label_ref (match_operand 0 "")))]
10229  "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10230   || (TARGET_TOC && TARGET_MINIMAL_TOC)
10231   || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10232{
10233#if TARGET_MACHO
10234  if (DEFAULT_ABI == ABI_DARWIN)
10235    {
10236      rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10237      rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10238      rtx tmplabrtx;
10239      char tmplab[20];
10240
10241      crtl->uses_pic_offset_table = 1;
10242      ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10243				  CODE_LABEL_NUMBER (operands[0]));
10244      tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10245
10246      emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10247      emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10248      emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10249					picrtx, tmplabrtx));
10250    }
10251  else
10252#endif
10253    rs6000_emit_load_toc_table (FALSE);
10254  DONE;
10255})
10256
10257;; Largetoc support
10258(define_insn "*largetoc_high"
10259  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10260        (high:DI
10261	  (unspec [(match_operand:DI 1 "" "")
10262		   (match_operand:DI 2 "gpc_reg_operand" "b")]
10263		  UNSPEC_TOCREL)))]
10264   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10265   "addis %0,%2,%1@toc@ha")
10266
10267(define_insn "*largetoc_high_aix<mode>"
10268  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10269        (high:P
10270	  (unspec [(match_operand:P 1 "" "")
10271		   (match_operand:P 2 "gpc_reg_operand" "b")]
10272		  UNSPEC_TOCREL)))]
10273   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10274   "addis %0,%1@u(%2)")
10275
10276(define_insn "*largetoc_high_plus"
10277  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10278        (high:DI
10279	  (plus:DI
10280	    (unspec [(match_operand:DI 1 "" "")
10281		     (match_operand:DI 2 "gpc_reg_operand" "b")]
10282		    UNSPEC_TOCREL)
10283	    (match_operand:DI 3 "add_cint_operand" "n"))))]
10284   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10285   "addis %0,%2,%1+%3@toc@ha")
10286
10287(define_insn "*largetoc_high_plus_aix<mode>"
10288  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10289        (high:P
10290	  (plus:P
10291	    (unspec [(match_operand:P 1 "" "")
10292		     (match_operand:P 2 "gpc_reg_operand" "b")]
10293		    UNSPEC_TOCREL)
10294	    (match_operand:P 3 "add_cint_operand" "n"))))]
10295   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10296   "addis %0,%1+%3@u(%2)")
10297
10298(define_insn "*largetoc_low"
10299  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10300        (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10301	           (match_operand:DI 2 "" "")))]
10302   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10303   "addi %0,%1,%2@l")
10304
10305(define_insn "*largetoc_low_aix<mode>"
10306  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10307        (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10308	           (match_operand:P 2 "" "")))]
10309   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10310   "la %0,%2@l(%1)")
10311
10312(define_insn_and_split "*tocref<mode>"
10313  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10314	(match_operand:P 1 "small_toc_ref" "R"))]
10315   "TARGET_TOC
10316    && legitimate_constant_pool_address_p (operands[1], QImode, false)"
10317   "la %0,%a1"
10318   "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10319  [(set (match_dup 0) (high:P (match_dup 1)))
10320   (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10321
10322;; Elf specific ways of loading addresses for non-PIC code.
10323;; The output of this could be r0, but we make a very strong
10324;; preference for a base register because it will usually
10325;; be needed there.
10326(define_insn "elf_high"
10327  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10328	(high:SI (match_operand 1 "" "")))]
10329  "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10330  "lis %0,%1@ha")
10331
10332(define_insn "elf_low"
10333  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10334	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10335		   (match_operand 2 "" "")))]
10336   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10337   "la %0,%2@l(%1)")
10338
10339(define_insn "*pltseq_tocsave_<mode>"
10340  [(set (match_operand:P 0 "memory_operand" "=m")
10341	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10342		   (match_operand:P 2 "symbol_ref_operand" "s")
10343		   (match_operand:P 3 "" "")]
10344		  UNSPEC_PLTSEQ))]
10345  "TARGET_PLTSEQ
10346   && DEFAULT_ABI == ABI_ELFv2"
10347{
10348  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10349})
10350
10351(define_insn "*pltseq_plt16_ha_<mode>"
10352  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10353	(unspec:P [(match_operand:P 1 "" "")
10354		   (match_operand:P 2 "symbol_ref_operand" "s")
10355		   (match_operand:P 3 "" "")]
10356		  UNSPEC_PLT16_HA))]
10357  "TARGET_PLTSEQ"
10358{
10359  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10360})
10361
10362(define_insn "*pltseq_plt16_lo_<mode>"
10363  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10364	(unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
10365			    (match_operand:P 2 "symbol_ref_operand" "s")
10366			    (match_operand:P 3 "" "")]
10367			   UNSPECV_PLT16_LO))]
10368  "TARGET_PLTSEQ"
10369{
10370  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10371}
10372  [(set_attr "type" "load")])
10373
10374(define_insn "*pltseq_mtctr_<mode>"
10375  [(set (match_operand:P 0 "register_operand" "=c")
10376	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10377		   (match_operand:P 2 "symbol_ref_operand" "s")
10378		   (match_operand:P 3 "" "")]
10379		  UNSPEC_PLTSEQ))]
10380  "TARGET_PLTSEQ"
10381{
10382  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10383})
10384
10385(define_insn "*pltseq_plt_pcrel<mode>"
10386  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10387	(unspec_volatile:P [(match_operand:P 1 "" "")
10388			    (match_operand:P 2 "symbol_ref_operand" "s")
10389			    (match_operand:P 3 "" "")]
10390			   UNSPECV_PLT_PCREL))]
10391  "HAVE_AS_PLTSEQ && TARGET_ELF
10392   && rs6000_pcrel_p (cfun)"
10393{
10394  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10395}
10396  [(set_attr "type" "load")
10397   (set_attr "length" "12")])
10398
10399;; Call and call_value insns
10400;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10401(define_expand "call"
10402  [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10403		    (match_operand 1 ""))
10404	      (use (match_operand 2 ""))
10405	      (clobber (reg:SI LR_REGNO))])]
10406  ""
10407{
10408#if TARGET_MACHO
10409  if (MACHOPIC_INDIRECT)
10410    operands[0] = machopic_indirect_call_target (operands[0]);
10411#endif
10412
10413  gcc_assert (MEM_P (operands[0]));
10414
10415  operands[0] = XEXP (operands[0], 0);
10416
10417  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10418    rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10419  else if (DEFAULT_ABI == ABI_V4)
10420    rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10421  else if (DEFAULT_ABI == ABI_DARWIN)
10422    rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10423  else
10424    gcc_unreachable ();
10425
10426  DONE;
10427})
10428
10429(define_expand "call_value"
10430  [(parallel [(set (match_operand 0 "")
10431		   (call (mem:SI (match_operand 1 "address_operand"))
10432			 (match_operand 2 "")))
10433	      (use (match_operand 3 ""))
10434	      (clobber (reg:SI LR_REGNO))])]
10435  ""
10436{
10437#if TARGET_MACHO
10438  if (MACHOPIC_INDIRECT)
10439    operands[1] = machopic_indirect_call_target (operands[1]);
10440#endif
10441
10442  gcc_assert (MEM_P (operands[1]));
10443
10444  operands[1] = XEXP (operands[1], 0);
10445
10446  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10447    rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10448  else if (DEFAULT_ABI == ABI_V4)
10449    rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10450  else if (DEFAULT_ABI == ABI_DARWIN)
10451    rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10452  else
10453    gcc_unreachable ();
10454
10455  DONE;
10456})
10457
10458;; Call to function in current module.  No TOC pointer reload needed.
10459;; Operand2 is nonzero if we are using the V.4 calling sequence and
10460;; either the function was not prototyped, or it was prototyped as a
10461;; variable argument function.  It is > 0 if FP registers were passed
10462;; and < 0 if they were not.
10463
10464(define_insn "*call_local<mode>"
10465  [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
10466	 (match_operand 1))
10467   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10468   (clobber (reg:P LR_REGNO))]
10469  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10470{
10471  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10472    output_asm_insn ("crxor 6,6,6", operands);
10473
10474  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10475    output_asm_insn ("creqv 6,6,6", operands);
10476
10477  if (rs6000_pcrel_p (cfun))
10478    return "bl %z0@notoc";
10479  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10480}
10481  [(set_attr "type" "branch")
10482   (set_attr "length" "4,8")])
10483
10484(define_insn "*call_value_local<mode>"
10485  [(set (match_operand 0 "" "")
10486	(call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
10487	      (match_operand 2)))
10488   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10489   (clobber (reg:P LR_REGNO))]
10490  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10491{
10492  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10493    output_asm_insn ("crxor 6,6,6", operands);
10494
10495  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10496    output_asm_insn ("creqv 6,6,6", operands);
10497
10498  if (rs6000_pcrel_p (cfun))
10499    return "bl %z1@notoc";
10500  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10501}
10502  [(set_attr "type" "branch")
10503   (set_attr "length" "4,8")])
10504
10505
10506;; A function pointer under System V is just a normal pointer
10507;; operands[0] is the function pointer
10508;; operands[1] is the tls call arg
10509;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10510;; which indicates how to set cr1
10511
10512(define_insn "*call_indirect_nonlocal_sysv<mode>"
10513  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10514	 (match_operand 1))
10515   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10516   (clobber (reg:P LR_REGNO))]
10517  "DEFAULT_ABI == ABI_V4
10518   || DEFAULT_ABI == ABI_DARWIN"
10519{
10520  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10521    output_asm_insn ("crxor 6,6,6", operands);
10522
10523  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10524    output_asm_insn ("creqv 6,6,6", operands);
10525
10526  return rs6000_indirect_call_template (operands, 0);
10527}
10528  [(set_attr "type" "jmpreg")
10529   (set (attr "length")
10530	(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10531			 (match_test "which_alternative != 1"))
10532		    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10533		  (const_string "12")
10534	       (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10535			 (match_test "which_alternative != 1"))
10536		    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10537		  (const_string "8")]
10538	      (const_string "4")))])
10539
10540(define_insn "*call_nonlocal_sysv<mode>"
10541  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10542	 (match_operand 1))
10543   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10544   (clobber (reg:P LR_REGNO))]
10545  "(DEFAULT_ABI == ABI_DARWIN
10546   || (DEFAULT_ABI == ABI_V4
10547       && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10548{
10549  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10550    output_asm_insn ("crxor 6,6,6", operands);
10551
10552  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10553    output_asm_insn ("creqv 6,6,6", operands);
10554
10555  return rs6000_call_template (operands, 0);
10556}
10557  [(set_attr "type" "branch,branch")
10558   (set_attr "length" "4,8")])
10559
10560(define_insn "*call_nonlocal_sysv_secure<mode>"
10561  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10562	 (match_operand 1))
10563   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10564   (use (match_operand:SI 3 "register_operand" "r,r"))
10565   (clobber (reg:P LR_REGNO))]
10566  "(DEFAULT_ABI == ABI_V4
10567    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10568    && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10569{
10570  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10571    output_asm_insn ("crxor 6,6,6", operands);
10572
10573  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10574    output_asm_insn ("creqv 6,6,6", operands);
10575
10576  return rs6000_call_template (operands, 0);
10577}
10578  [(set_attr "type" "branch,branch")
10579   (set_attr "length" "4,8")])
10580
10581(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10582  [(set (match_operand 0 "" "")
10583	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10584	      (match_operand:P 2 "unspec_tls" "")))
10585   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10586   (clobber (reg:P LR_REGNO))]
10587  "DEFAULT_ABI == ABI_V4
10588   || DEFAULT_ABI == ABI_DARWIN"
10589{
10590  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10591    output_asm_insn ("crxor 6,6,6", operands);
10592
10593  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10594    output_asm_insn ("creqv 6,6,6", operands);
10595
10596  return rs6000_indirect_call_template (operands, 1);
10597}
10598  [(set_attr "type" "jmpreg")
10599   (set (attr "length")
10600	(plus
10601	  (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10602	    (const_int 4)
10603	    (const_int 0))
10604	  (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10605			     (match_test "which_alternative != 1"))
10606	    (const_int 8)
10607	    (const_int 4))))])
10608
10609(define_insn "*call_value_nonlocal_sysv<mode>"
10610  [(set (match_operand 0 "" "")
10611	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10612	      (match_operand:P 2 "unspec_tls" "")))
10613   (use (match_operand:SI 3 "immediate_operand" "n"))
10614   (clobber (reg:P LR_REGNO))]
10615  "(DEFAULT_ABI == ABI_DARWIN
10616    || (DEFAULT_ABI == ABI_V4
10617	&& (INTVAL (operands[3]) & CALL_LONG) == 0))"
10618{
10619  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10620    output_asm_insn ("crxor 6,6,6", operands);
10621
10622  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10623    output_asm_insn ("creqv 6,6,6", operands);
10624
10625  return rs6000_call_template (operands, 1);
10626}
10627  [(set_attr "type" "branch")
10628   (set (attr "length")
10629	(if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10630	  (const_int 8)
10631	  (const_int 4)))])
10632
10633(define_insn "*call_value_nonlocal_sysv_secure<mode>"
10634  [(set (match_operand 0 "" "")
10635	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10636	      (match_operand:P 2 "unspec_tls" "")))
10637   (use (match_operand:SI 3 "immediate_operand" "n"))
10638   (use (match_operand:SI 4 "register_operand" "r"))
10639   (clobber (reg:P LR_REGNO))]
10640  "(DEFAULT_ABI == ABI_V4
10641    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10642    && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10643{
10644  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10645    output_asm_insn ("crxor 6,6,6", operands);
10646
10647  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10648    output_asm_insn ("creqv 6,6,6", operands);
10649
10650  return rs6000_call_template (operands, 1);
10651}
10652  [(set_attr "type" "branch")
10653   (set (attr "length")
10654	(if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10655	  (const_int 8)
10656	  (const_int 4)))])
10657
10658;; Call to AIX abi function which may be in another module.
10659;; Restore the TOC pointer (r2) after the call.
10660
10661(define_insn "*call_nonlocal_aix<mode>"
10662  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10663	 (match_operand 1))
10664   (use (match_operand:SI 2 "immediate_operand" "n"))
10665   (clobber (reg:P LR_REGNO))]
10666  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10667   && (INTVAL (operands[2]) & CALL_LONG) == 0"
10668{
10669  return rs6000_call_template (operands, 0);
10670}
10671  [(set_attr "type" "branch")
10672   (set (attr "length")
10673	(if_then_else (match_test "rs6000_pcrel_p (cfun)")
10674	  (const_int 4)
10675	  (const_int 8)))])
10676
10677(define_insn "*call_value_nonlocal_aix<mode>"
10678  [(set (match_operand 0 "" "")
10679	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10680	      (match_operand:P 2 "unspec_tls" "")))
10681   (use (match_operand:SI 3 "immediate_operand" "n"))
10682   (clobber (reg:P LR_REGNO))]
10683  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10684   && (INTVAL (operands[3]) & CALL_LONG) == 0"
10685{
10686  return rs6000_call_template (operands, 1);
10687}
10688  [(set_attr "type" "branch")
10689   (set (attr "length")
10690	(if_then_else (match_test "rs6000_pcrel_p (cfun)")
10691	    (const_int 4)
10692	    (const_int 8)))])
10693
10694;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10695;; Operand0 is the addresss of the function to call
10696;; Operand3 is the location in the function descriptor to load r2 from
10697;; Operand4 is the offset of the stack location holding the current TOC pointer
10698
10699(define_insn "*call_indirect_aix<mode>"
10700  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10701	 (match_operand 1))
10702   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10703   (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10704   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10705   (clobber (reg:P LR_REGNO))]
10706  "DEFAULT_ABI == ABI_AIX"
10707{
10708  return rs6000_indirect_call_template (operands, 0);
10709}
10710  [(set_attr "type" "jmpreg")
10711   (set (attr "length")
10712	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10713			   (match_test "which_alternative != 1"))
10714		      (const_string "16")
10715		      (const_string "12")))])
10716
10717(define_insn "*call_value_indirect_aix<mode>"
10718  [(set (match_operand 0 "" "")
10719	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10720	      (match_operand:P 2 "unspec_tls" "")))
10721   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10722   (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10723   (set (reg:P TOC_REGNUM)
10724	(unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
10725		  UNSPEC_TOCSLOT))
10726   (clobber (reg:P LR_REGNO))]
10727  "DEFAULT_ABI == ABI_AIX"
10728{
10729  return rs6000_indirect_call_template (operands, 1);
10730}
10731  [(set_attr "type" "jmpreg")
10732   (set (attr "length")
10733	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10734			   (match_test "which_alternative != 1"))
10735	    (const_string "16")
10736	    (const_string "12")))])
10737
10738;; Call to indirect functions with the ELFv2 ABI.
10739;; Operand0 is the addresss of the function to call
10740;; Operand3 is the offset of the stack location holding the current TOC pointer
10741
10742(define_insn "*call_indirect_elfv2<mode>"
10743  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10744	 (match_operand 1))
10745   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10746   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10747   (clobber (reg:P LR_REGNO))]
10748  "DEFAULT_ABI == ABI_ELFv2"
10749{
10750  return rs6000_indirect_call_template (operands, 0);
10751}
10752  [(set_attr "type" "jmpreg")
10753   (set (attr "length")
10754	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10755			   (match_test "which_alternative != 1"))
10756		      (const_string "12")
10757		      (const_string "8")))])
10758
10759(define_insn "*call_indirect_pcrel<mode>"
10760  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10761	 (match_operand 1))
10762   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10763   (clobber (reg:P LR_REGNO))]
10764  "rs6000_pcrel_p (cfun)"
10765{
10766  return rs6000_indirect_call_template (operands, 0);
10767}
10768  [(set_attr "type" "jmpreg")
10769   (set (attr "length")
10770	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10771			   (match_test "which_alternative != 1"))
10772		      (const_string "8")
10773		      (const_string "4")))])
10774
10775(define_insn "*call_value_indirect_elfv2<mode>"
10776  [(set (match_operand 0 "" "")
10777	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10778	      (match_operand:P 2 "unspec_tls" "")))
10779   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10780   (set (reg:P TOC_REGNUM)
10781	(unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10782		  UNSPEC_TOCSLOT))
10783   (clobber (reg:P LR_REGNO))]
10784  "DEFAULT_ABI == ABI_ELFv2"
10785{
10786  return rs6000_indirect_call_template (operands, 1);
10787}
10788  [(set_attr "type" "jmpreg")
10789   (set (attr "length")
10790	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10791			   (match_test "which_alternative != 1"))
10792	    (const_string "12")
10793	    (const_string "8")))])
10794
10795(define_insn "*call_value_indirect_pcrel<mode>"
10796  [(set (match_operand 0 "" "")
10797	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10798	      (match_operand:P 2 "unspec_tls" "")))
10799   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10800   (clobber (reg:P LR_REGNO))]
10801  "rs6000_pcrel_p (cfun)"
10802{
10803  return rs6000_indirect_call_template (operands, 1);
10804}
10805  [(set_attr "type" "jmpreg")
10806   (set (attr "length")
10807	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10808			   (match_test "which_alternative != 1"))
10809	    (const_string "8")
10810	    (const_string "4")))])
10811
10812;; Call subroutine returning any type.
10813(define_expand "untyped_call"
10814  [(parallel [(call (match_operand 0 "")
10815		    (const_int 0))
10816	      (match_operand 1 "")
10817	      (match_operand 2 "")])]
10818  ""
10819{
10820  int i;
10821
10822  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10823
10824  for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10825    emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
10826  emit_insn (gen_blockage ());
10827
10828  for (i = 0; i < XVECLEN (operands[2], 0); i++)
10829    {
10830      rtx set = XVECEXP (operands[2], 0, i);
10831      emit_move_insn (SET_DEST (set), SET_SRC (set));
10832    }
10833
10834  /* The optimizer does not know that the call sets the function value
10835     registers we stored in the result block.  We avoid problems by
10836     claiming that all hard registers are used and clobbered at this
10837     point.  */
10838  emit_insn (gen_blockage ());
10839
10840  DONE;
10841})
10842
10843;; sibling call patterns
10844(define_expand "sibcall"
10845  [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10846		    (match_operand 1 ""))
10847	      (use (match_operand 2 ""))
10848	      (simple_return)])]
10849  ""
10850{
10851#if TARGET_MACHO
10852  if (MACHOPIC_INDIRECT)
10853    operands[0] = machopic_indirect_call_target (operands[0]);
10854#endif
10855
10856  gcc_assert (MEM_P (operands[0]));
10857  gcc_assert (CONST_INT_P (operands[1]));
10858
10859  operands[0] = XEXP (operands[0], 0);
10860
10861  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10862    rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10863  else if (DEFAULT_ABI == ABI_V4)
10864    rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10865  else if (DEFAULT_ABI == ABI_DARWIN)
10866    rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10867  else
10868    gcc_unreachable ();
10869
10870  DONE;
10871})
10872
10873(define_expand "sibcall_value"
10874  [(parallel [(set (match_operand 0 "register_operand")
10875		(call (mem:SI (match_operand 1 "address_operand"))
10876		      (match_operand 2 "")))
10877	      (use (match_operand 3 ""))
10878	      (simple_return)])]
10879  ""
10880{
10881#if TARGET_MACHO
10882  if (MACHOPIC_INDIRECT)
10883    operands[1] = machopic_indirect_call_target (operands[1]);
10884#endif
10885
10886  gcc_assert (MEM_P (operands[1]));
10887  gcc_assert (CONST_INT_P (operands[2]));
10888
10889  operands[1] = XEXP (operands[1], 0);
10890
10891  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10892    rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10893  else if (DEFAULT_ABI == ABI_V4)
10894    rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10895  else if (DEFAULT_ABI == ABI_DARWIN)
10896    rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10897  else
10898    gcc_unreachable ();
10899
10900  DONE;
10901})
10902
10903(define_insn "*sibcall_local32"
10904  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10905	 (match_operand 1))
10906   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10907   (simple_return)]
10908  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10909{
10910  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10911    output_asm_insn ("crxor 6,6,6", operands);
10912
10913  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10914    output_asm_insn ("creqv 6,6,6", operands);
10915
10916  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10917}
10918  [(set_attr "type" "branch")
10919   (set_attr "length" "4,8")])
10920
10921(define_insn "*sibcall_local64"
10922  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10923	 (match_operand 1))
10924   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10925   (simple_return)]
10926  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10927{
10928  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10929    output_asm_insn ("crxor 6,6,6", operands);
10930
10931  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10932    output_asm_insn ("creqv 6,6,6", operands);
10933
10934  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10935}
10936  [(set_attr "type" "branch")
10937   (set_attr "length" "4,8")])
10938
10939(define_insn "*sibcall_value_local32"
10940  [(set (match_operand 0 "" "")
10941	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10942	      (match_operand 2)))
10943   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10944   (simple_return)]
10945  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10946{
10947  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10948    output_asm_insn ("crxor 6,6,6", operands);
10949
10950  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10951    output_asm_insn ("creqv 6,6,6", operands);
10952
10953  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10954}
10955  [(set_attr "type" "branch")
10956   (set_attr "length" "4,8")])
10957
10958(define_insn "*sibcall_value_local64"
10959  [(set (match_operand 0 "" "")
10960	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10961	      (match_operand 2)))
10962   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10963   (simple_return)]
10964  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10965{
10966  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10967    output_asm_insn ("crxor 6,6,6", operands);
10968
10969  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10970    output_asm_insn ("creqv 6,6,6", operands);
10971
10972  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10973}
10974  [(set_attr "type" "branch")
10975   (set_attr "length" "4,8")])
10976
10977(define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10978  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10979	 (match_operand 1))
10980   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10981   (simple_return)]
10982  "DEFAULT_ABI == ABI_V4
10983   || DEFAULT_ABI == ABI_DARWIN"
10984{
10985  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10986    output_asm_insn ("crxor 6,6,6", operands);
10987
10988  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10989    output_asm_insn ("creqv 6,6,6", operands);
10990
10991  return rs6000_indirect_sibcall_template (operands, 0);
10992}
10993  [(set_attr "type" "jmpreg")
10994   (set (attr "length")
10995	(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10996			 (match_test "which_alternative != 1"))
10997		    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10998		  (const_string "12")
10999	       (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11000			 (match_test "which_alternative != 1"))
11001		   (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11002		  (const_string "8")]
11003	      (const_string "4")))])
11004
11005(define_insn "*sibcall_nonlocal_sysv<mode>"
11006  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11007	 (match_operand 1))
11008   (use (match_operand 2 "immediate_operand" "O,n"))
11009   (simple_return)]
11010  "(DEFAULT_ABI == ABI_DARWIN
11011    || DEFAULT_ABI == ABI_V4)
11012   && (INTVAL (operands[2]) & CALL_LONG) == 0"
11013{
11014  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11015    output_asm_insn ("crxor 6,6,6", operands);
11016
11017  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11018    output_asm_insn ("creqv 6,6,6", operands);
11019
11020  return rs6000_sibcall_template (operands, 0);
11021}
11022  [(set_attr "type" "branch")
11023   (set_attr "length" "4,8")])
11024
11025(define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11026  [(set (match_operand 0 "" "")
11027	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11028	      (match_operand 2)))
11029   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11030   (simple_return)]
11031  "DEFAULT_ABI == ABI_V4
11032   || DEFAULT_ABI == ABI_DARWIN"
11033{
11034  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11035    output_asm_insn ("crxor 6,6,6", operands);
11036
11037  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11038    output_asm_insn ("creqv 6,6,6", operands);
11039
11040  return rs6000_indirect_sibcall_template (operands, 1);
11041}
11042  [(set_attr "type" "jmpreg")
11043   (set (attr "length")
11044	(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11045			 (match_test "which_alternative != 1"))
11046		    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11047		  (const_string "12")
11048	       (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11049			 (match_test "which_alternative != 1"))
11050		   (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11051		  (const_string "8")]
11052	      (const_string "4")))])
11053
11054(define_insn "*sibcall_value_nonlocal_sysv<mode>"
11055  [(set (match_operand 0 "" "")
11056	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11057	      (match_operand 2)))
11058   (use (match_operand:SI 3 "immediate_operand" "O,n"))
11059   (simple_return)]
11060  "(DEFAULT_ABI == ABI_DARWIN
11061    || DEFAULT_ABI == ABI_V4)
11062   && (INTVAL (operands[3]) & CALL_LONG) == 0"
11063{
11064  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11065    output_asm_insn ("crxor 6,6,6", operands);
11066
11067  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11068    output_asm_insn ("creqv 6,6,6", operands);
11069
11070  return rs6000_sibcall_template (operands, 1);
11071}
11072  [(set_attr "type" "branch")
11073   (set_attr "length" "4,8")])
11074
11075;; AIX ABI sibling call patterns.
11076
11077(define_insn "*sibcall_aix<mode>"
11078  [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11079	 (match_operand 1))
11080   (simple_return)]
11081  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11082{
11083  if (which_alternative == 0)
11084    return rs6000_sibcall_template (operands, 0);
11085  else
11086    return "b%T0";
11087}
11088  [(set_attr "type" "branch")])
11089
11090(define_insn "*sibcall_value_aix<mode>"
11091  [(set (match_operand 0 "" "")
11092	(call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11093	      (match_operand 2)))
11094   (simple_return)]
11095  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11096{
11097  if (which_alternative == 0)
11098    return rs6000_sibcall_template (operands, 1);
11099  else
11100    return "b%T1";
11101}
11102  [(set_attr "type" "branch")])
11103
11104(define_expand "sibcall_epilogue"
11105  [(use (const_int 0))]
11106  ""
11107{
11108  if (!TARGET_SCHED_PROLOG)
11109    emit_insn (gen_blockage ());
11110  rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11111  DONE;
11112})
11113
11114;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11115;; all of memory.  This blocks insns from being moved across this point.
11116
11117(define_insn "blockage"
11118  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11119  ""
11120  ""
11121  [(set_attr "length" "0")])
11122
11123(define_expand "probe_stack_address"
11124  [(use (match_operand 0 "address_operand"))]
11125  ""
11126{
11127  operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11128  MEM_VOLATILE_P (operands[0]) = 1;
11129
11130  if (TARGET_64BIT)
11131    emit_insn (gen_probe_stack_di (operands[0]));
11132  else
11133    emit_insn (gen_probe_stack_si (operands[0]));
11134  DONE;
11135})
11136
11137(define_insn "probe_stack_<mode>"
11138  [(set (match_operand:P 0 "memory_operand" "=m")
11139        (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11140  ""
11141{
11142  operands[1] = gen_rtx_REG (Pmode, 0);
11143  return "st<wd>%U0%X0 %1,%0";
11144}
11145  [(set_attr "type" "store")
11146   (set (attr "update")
11147	(if_then_else (match_operand 0 "update_address_mem")
11148		      (const_string "yes")
11149		      (const_string "no")))
11150   (set (attr "indexed")
11151	(if_then_else (match_operand 0 "indexed_address_mem")
11152		      (const_string "yes")
11153		      (const_string "no")))])
11154
11155(define_insn "probe_stack_range<P:mode>"
11156  [(set (match_operand:P 0 "register_operand" "=&r")
11157	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11158			    (match_operand:P 2 "register_operand" "r")
11159			    (match_operand:P 3 "register_operand" "r")]
11160			   UNSPECV_PROBE_STACK_RANGE))]
11161  ""
11162  "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11163  [(set_attr "type" "three")])
11164
11165;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11166;; signed & unsigned, and one type of branch.
11167;;
11168;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11169;; insns, and branches.
11170
11171(define_expand "cbranch<mode>4"
11172  [(use (match_operator 0 "comparison_operator"
11173         [(match_operand:GPR 1 "gpc_reg_operand")
11174          (match_operand:GPR 2 "reg_or_short_operand")]))
11175   (use (match_operand 3))]
11176  ""
11177{
11178  /* Take care of the possibility that operands[2] might be negative but
11179     this might be a logical operation.  That insn doesn't exist.  */
11180  if (CONST_INT_P (operands[2])
11181      && INTVAL (operands[2]) < 0)
11182    {
11183      operands[2] = force_reg (<MODE>mode, operands[2]);
11184      operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11185				    GET_MODE (operands[0]),
11186				    operands[1], operands[2]);
11187   }
11188
11189  rs6000_emit_cbranch (<MODE>mode, operands);
11190  DONE;
11191})
11192
11193(define_expand "cbranch<mode>4"
11194  [(use (match_operator 0 "comparison_operator"
11195         [(match_operand:FP 1 "gpc_reg_operand")
11196          (match_operand:FP 2 "gpc_reg_operand")]))
11197   (use (match_operand 3))]
11198  ""
11199{
11200  rs6000_emit_cbranch (<MODE>mode, operands);
11201  DONE;
11202})
11203
11204(define_expand "cstore<mode>4_signed"
11205  [(use (match_operator 1 "signed_comparison_operator"
11206         [(match_operand:P 2 "gpc_reg_operand")
11207          (match_operand:P 3 "gpc_reg_operand")]))
11208   (clobber (match_operand:P 0 "gpc_reg_operand"))]
11209  ""
11210{
11211  enum rtx_code cond_code = GET_CODE (operands[1]);
11212
11213  rtx op0 = operands[0];
11214  rtx op1 = operands[2];
11215  rtx op2 = operands[3];
11216
11217  if (cond_code == GE || cond_code == LT)
11218    {
11219      cond_code = swap_condition (cond_code);
11220      std::swap (op1, op2);
11221    }
11222
11223  rtx tmp1 = gen_reg_rtx (<MODE>mode);
11224  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11225  rtx tmp3 = gen_reg_rtx (<MODE>mode);
11226
11227  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11228  emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11229  emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11230
11231  emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11232
11233  if (cond_code == LE)
11234    emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11235  else
11236    {
11237      rtx tmp4 = gen_reg_rtx (<MODE>mode);
11238      emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11239      emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11240    }
11241
11242  DONE;
11243})
11244
11245(define_expand "cstore<mode>4_unsigned"
11246  [(use (match_operator 1 "unsigned_comparison_operator"
11247         [(match_operand:P 2 "gpc_reg_operand")
11248          (match_operand:P 3 "reg_or_short_operand")]))
11249   (clobber (match_operand:P 0 "gpc_reg_operand"))]
11250  ""
11251{
11252  enum rtx_code cond_code = GET_CODE (operands[1]);
11253
11254  rtx op0 = operands[0];
11255  rtx op1 = operands[2];
11256  rtx op2 = operands[3];
11257
11258  if (cond_code == GEU || cond_code == LTU)
11259    {
11260      cond_code = swap_condition (cond_code);
11261      std::swap (op1, op2);
11262    }
11263
11264  if (!gpc_reg_operand (op1, <MODE>mode))
11265    op1 = force_reg (<MODE>mode, op1);
11266  if (!reg_or_short_operand (op2, <MODE>mode))
11267    op2 = force_reg (<MODE>mode, op2);
11268
11269  rtx tmp = gen_reg_rtx (<MODE>mode);
11270  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11271
11272  emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11273  emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11274
11275  if (cond_code == LEU)
11276    emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11277  else
11278    emit_insn (gen_neg<mode>2 (op0, tmp2));
11279
11280  DONE;
11281})
11282
11283(define_expand "cstore_si_as_di"
11284  [(use (match_operator 1 "unsigned_comparison_operator"
11285         [(match_operand:SI 2 "gpc_reg_operand")
11286          (match_operand:SI 3 "reg_or_short_operand")]))
11287   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11288  ""
11289{
11290  int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11291  enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11292
11293  operands[2] = force_reg (SImode, operands[2]);
11294  operands[3] = force_reg (SImode, operands[3]);
11295  rtx op1 = gen_reg_rtx (DImode);
11296  rtx op2 = gen_reg_rtx (DImode);
11297  convert_move (op1, operands[2], uns_flag);
11298  convert_move (op2, operands[3], uns_flag);
11299
11300  if (cond_code == GT || cond_code == LE)
11301    {
11302      cond_code = swap_condition (cond_code);
11303      std::swap (op1, op2);
11304    }
11305
11306  rtx tmp = gen_reg_rtx (DImode);
11307  rtx tmp2 = gen_reg_rtx (DImode);
11308  emit_insn (gen_subdi3 (tmp, op1, op2));
11309  emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11310
11311  rtx tmp3;
11312  switch (cond_code)
11313    {
11314    default:
11315      gcc_unreachable ();
11316    case LT:
11317      tmp3 = tmp2;
11318      break;
11319    case GE:
11320      tmp3 = gen_reg_rtx (DImode);
11321      emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11322      break;
11323    }
11324
11325  convert_move (operands[0], tmp3, 1);
11326
11327  DONE;
11328})
11329
11330(define_expand "cstore<mode>4_signed_imm"
11331  [(use (match_operator 1 "signed_comparison_operator"
11332         [(match_operand:GPR 2 "gpc_reg_operand")
11333          (match_operand:GPR 3 "immediate_operand")]))
11334   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11335  ""
11336{
11337  bool invert = false;
11338
11339  enum rtx_code cond_code = GET_CODE (operands[1]);
11340
11341  rtx op0 = operands[0];
11342  rtx op1 = operands[2];
11343  HOST_WIDE_INT val = INTVAL (operands[3]);
11344
11345  if (cond_code == GE || cond_code == GT)
11346    {
11347      cond_code = reverse_condition (cond_code);
11348      invert = true;
11349    }
11350
11351  if (cond_code == LE)
11352    val++;
11353
11354  rtx tmp = gen_reg_rtx (<MODE>mode);
11355  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11356  rtx x = gen_reg_rtx (<MODE>mode);
11357  if (val < 0)
11358    emit_insn (gen_and<mode>3 (x, op1, tmp));
11359  else
11360    emit_insn (gen_ior<mode>3 (x, op1, tmp));
11361
11362  if (invert)
11363    {
11364      rtx tmp = gen_reg_rtx (<MODE>mode);
11365      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11366      x = tmp;
11367    }
11368
11369  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11370  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11371
11372  DONE;
11373})
11374
11375(define_expand "cstore<mode>4_unsigned_imm"
11376  [(use (match_operator 1 "unsigned_comparison_operator"
11377         [(match_operand:GPR 2 "gpc_reg_operand")
11378          (match_operand:GPR 3 "immediate_operand")]))
11379   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11380  ""
11381{
11382  bool invert = false;
11383
11384  enum rtx_code cond_code = GET_CODE (operands[1]);
11385
11386  rtx op0 = operands[0];
11387  rtx op1 = operands[2];
11388  HOST_WIDE_INT val = INTVAL (operands[3]);
11389
11390  if (cond_code == GEU || cond_code == GTU)
11391    {
11392      cond_code = reverse_condition (cond_code);
11393      invert = true;
11394    }
11395
11396  if (cond_code == LEU)
11397    val++;
11398
11399  rtx tmp = gen_reg_rtx (<MODE>mode);
11400  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11401  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11402  emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11403  rtx x = gen_reg_rtx (<MODE>mode);
11404  if (val < 0)
11405    emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11406  else
11407    emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11408
11409  if (invert)
11410    {
11411      rtx tmp = gen_reg_rtx (<MODE>mode);
11412      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11413      x = tmp;
11414    }
11415
11416  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11417  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11418
11419  DONE;
11420})
11421
11422(define_expand "cstore<mode>4"
11423  [(use (match_operator 1 "comparison_operator"
11424         [(match_operand:GPR 2 "gpc_reg_operand")
11425          (match_operand:GPR 3 "reg_or_short_operand")]))
11426   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11427  ""
11428{
11429  /* Expanding EQ and NE directly to some machine instructions does not help
11430     but does hurt combine.  So don't.  */
11431  if (GET_CODE (operands[1]) == EQ)
11432    emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11433  else if (<MODE>mode == Pmode
11434	   && GET_CODE (operands[1]) == NE)
11435    emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11436  else if (GET_CODE (operands[1]) == NE)
11437    {
11438      rtx tmp = gen_reg_rtx (<MODE>mode);
11439      emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11440      emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11441    }
11442
11443  /* If ISEL is fast, expand to it.  */
11444  else if (TARGET_ISEL)
11445    rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11446
11447  /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11448     etc. combinations magically work out just right.  */
11449  else if (<MODE>mode == Pmode
11450	   && unsigned_comparison_operator (operands[1], VOIDmode))
11451    emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11452					   operands[2], operands[3]));
11453
11454  /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11455  else if (<MODE>mode == SImode && Pmode == DImode)
11456    emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11457				    operands[2], operands[3]));
11458
11459  /* For signed comparisons against a constant, we can do some simple
11460     bit-twiddling.  */
11461  else if (signed_comparison_operator (operands[1], VOIDmode)
11462	   && CONST_INT_P (operands[3]))
11463    emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11464					     operands[2], operands[3]));
11465
11466  /* And similarly for unsigned comparisons.  */
11467  else if (unsigned_comparison_operator (operands[1], VOIDmode)
11468	   && CONST_INT_P (operands[3]))
11469    emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11470					       operands[2], operands[3]));
11471
11472  /* We also do not want to use mfcr for signed comparisons.  */
11473  else if (<MODE>mode == Pmode
11474	   && signed_comparison_operator (operands[1], VOIDmode))
11475    emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11476					 operands[2], operands[3]));
11477
11478  /* Everything else, use the mfcr brute force.  */
11479  else
11480    rs6000_emit_sCOND (<MODE>mode, operands);
11481
11482  DONE;
11483})
11484
11485(define_expand "cstore<mode>4"
11486  [(use (match_operator 1 "comparison_operator"
11487         [(match_operand:FP 2 "gpc_reg_operand")
11488          (match_operand:FP 3 "gpc_reg_operand")]))
11489   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11490  ""
11491{
11492  rs6000_emit_sCOND (<MODE>mode, operands);
11493  DONE;
11494})
11495
11496
11497(define_expand "stack_protect_set"
11498  [(match_operand 0 "memory_operand")
11499   (match_operand 1 "memory_operand")]
11500  ""
11501{
11502  if (rs6000_stack_protector_guard == SSP_TLS)
11503    {
11504      rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11505      rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11506      rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11507      operands[1] = gen_rtx_MEM (Pmode, addr);
11508    }
11509
11510  if (TARGET_64BIT)
11511    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11512  else
11513    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11514
11515  DONE;
11516})
11517
11518(define_insn "stack_protect_setsi"
11519  [(set (match_operand:SI 0 "memory_operand" "=m")
11520	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11521   (set (match_scratch:SI 2 "=&r") (const_int 0))]
11522  "TARGET_32BIT"
11523  "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11524  [(set_attr "type" "three")
11525   (set_attr "length" "12")])
11526
11527;; We can't use the prefixed attribute here because there are two memory
11528;; instructions.  We can't split the insn due to the fact that this operation
11529;; needs to be done in one piece.
11530(define_insn "stack_protect_setdi"
11531  [(set (match_operand:DI 0 "memory_operand" "=Y")
11532	(unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11533   (set (match_scratch:DI 2 "=&r") (const_int 0))]
11534  "TARGET_64BIT"
11535{
11536  if (prefixed_memory (operands[1], DImode))
11537    output_asm_insn ("pld %2,%1", operands);
11538  else
11539    output_asm_insn ("ld%U1%X1 %2,%1", operands);
11540
11541  if (prefixed_memory (operands[0], DImode))
11542    output_asm_insn ("pstd %2,%0", operands);
11543  else
11544    output_asm_insn ("std%U0%X0 %2,%0", operands);
11545
11546  return "li %2,0";
11547}
11548  [(set_attr "type" "three")
11549
11550  ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11551  ;; prefixed instruction + 4 bytes for the possible NOP).  Add in 4 bytes for
11552  ;; the LI 0 at the end.
11553   (set_attr "prefixed" "no")
11554   (set_attr "num_insns" "3")
11555   (set (attr "length")
11556	(cond [(and (match_operand 0 "prefixed_memory")
11557		    (match_operand 1 "prefixed_memory"))
11558	       (const_int 24)
11559
11560	       (ior (match_operand 0 "prefixed_memory")
11561		    (match_operand 1 "prefixed_memory"))
11562	       (const_int 20)]
11563
11564	      (const_int 12)))])
11565
11566(define_expand "stack_protect_test"
11567  [(match_operand 0 "memory_operand")
11568   (match_operand 1 "memory_operand")
11569   (match_operand 2 "")]
11570  ""
11571{
11572  rtx guard = operands[1];
11573
11574  if (rs6000_stack_protector_guard == SSP_TLS)
11575    {
11576      rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11577      rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11578      rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11579      guard = gen_rtx_MEM (Pmode, addr);
11580    }
11581
11582  operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11583  rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11584  rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11585  emit_jump_insn (jump);
11586
11587  DONE;
11588})
11589
11590(define_insn "stack_protect_testsi"
11591  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11592        (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11593		      (match_operand:SI 2 "memory_operand" "m,m")]
11594		     UNSPEC_SP_TEST))
11595   (set (match_scratch:SI 4 "=r,r") (const_int 0))
11596   (clobber (match_scratch:SI 3 "=&r,&r"))]
11597  "TARGET_32BIT"
11598  "@
11599   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11600   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11601  [(set_attr "length" "16,20")])
11602
11603;; We can't use the prefixed attribute here because there are two memory
11604;; instructions.  We can't split the insn due to the fact that this operation
11605;; needs to be done in one piece.
11606(define_insn "stack_protect_testdi"
11607  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11608        (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11609		      (match_operand:DI 2 "memory_operand" "Y,Y")]
11610		     UNSPEC_SP_TEST))
11611   (set (match_scratch:DI 4 "=r,r") (const_int 0))
11612   (clobber (match_scratch:DI 3 "=&r,&r"))]
11613  "TARGET_64BIT"
11614{
11615  if (prefixed_memory (operands[1], DImode))
11616    output_asm_insn ("pld %3,%1", operands);
11617  else
11618    output_asm_insn ("ld%U1%X1 %3,%1", operands);
11619
11620  if (prefixed_memory (operands[2], DImode))
11621    output_asm_insn ("pld %4,%2", operands);
11622  else
11623    output_asm_insn ("ld%U2%X2 %4,%2", operands);
11624
11625  if (which_alternative == 0)
11626    output_asm_insn ("xor. %3,%3,%4", operands);
11627  else
11628    output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11629
11630  return "li %4,0";
11631}
11632  ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11633  ;; prefixed instruction + 4 bytes for the possible NOP).  Add in either 4 or
11634  ;; 8 bytes to do the test.
11635  [(set_attr "prefixed" "no")
11636   (set_attr "num_insns" "4,5")
11637   (set (attr "length")
11638	(cond [(and (match_operand 1 "prefixed_memory")
11639		    (match_operand 2 "prefixed_memory"))
11640	       (if_then_else (eq_attr "alternative" "0")
11641			     (const_int 28)
11642			     (const_int 32))
11643
11644	       (ior (match_operand 1 "prefixed_memory")
11645		    (match_operand 2 "prefixed_memory"))
11646	       (if_then_else (eq_attr "alternative" "0")
11647			     (const_int 20)
11648			     (const_int 24))]
11649
11650	      (if_then_else (eq_attr "alternative" "0")
11651			    (const_int 16)
11652			    (const_int 20))))])
11653
11654
11655;; Here are the actual compare insns.
11656(define_insn "*cmp<mode>_signed"
11657  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11658	(compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11659		    (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11660  ""
11661  "cmp<wd>%I2 %0,%1,%2"
11662  [(set_attr "type" "cmp")])
11663
11664(define_insn "*cmp<mode>_unsigned"
11665  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11666	(compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11667		       (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11668  ""
11669  "cmpl<wd>%I2 %0,%1,%2"
11670  [(set_attr "type" "cmp")])
11671
11672;; If we are comparing a register for equality with a large constant,
11673;; we can do this with an XOR followed by a compare.  But this is profitable
11674;; only if the large constant is only used for the comparison (and in this
11675;; case we already have a register to reuse as scratch).
11676;;
11677;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11678;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11679
11680(define_peephole2
11681  [(set (match_operand:SI 0 "register_operand")
11682        (match_operand:SI 1 "logical_const_operand"))
11683   (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11684		       [(match_dup 0)
11685			(match_operand:SI 2 "logical_const_operand")]))
11686   (set (match_operand:CC 4 "cc_reg_operand")
11687        (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11688                    (match_dup 0)))
11689   (set (pc)
11690        (if_then_else (match_operator 6 "equality_operator"
11691                       [(match_dup 4) (const_int 0)])
11692                      (match_operand 7 "")
11693                      (match_operand 8 "")))]
11694  "peep2_reg_dead_p (3, operands[0])
11695   && peep2_reg_dead_p (4, operands[4])
11696   && REGNO (operands[0]) != REGNO (operands[5])"
11697 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11698  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11699  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11700
11701{
11702  /* Get the constant we are comparing against, and see what it looks like
11703     when sign-extended from 16 to 32 bits.  Then see what constant we could
11704     XOR with SEXTC to get the sign-extended value.  */
11705  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11706					      SImode,
11707					      operands[1], operands[2]);
11708  HOST_WIDE_INT c = INTVAL (cnst);
11709  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11710  HOST_WIDE_INT xorv = c ^ sextc;
11711
11712  operands[9] = GEN_INT (xorv);
11713  operands[10] = GEN_INT (sextc);
11714})
11715
11716;; Only need to compare second words if first words equal
11717(define_insn "*cmp<mode>_internal1"
11718  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11719	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11720		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11721  "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11722   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11723  "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11724  [(set_attr "type" "fpcompare")
11725   (set_attr "length" "12")])
11726
11727(define_insn_and_split "*cmp<IBM128:mode>_internal2"
11728  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11729	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11730		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11731    (clobber (match_scratch:DF 3 "=d"))
11732    (clobber (match_scratch:DF 4 "=d"))
11733    (clobber (match_scratch:DF 5 "=d"))
11734    (clobber (match_scratch:DF 6 "=d"))
11735    (clobber (match_scratch:DF 7 "=d"))
11736    (clobber (match_scratch:DF 8 "=d"))
11737    (clobber (match_scratch:DF 9 "=d"))
11738    (clobber (match_scratch:DF 10 "=d"))
11739    (clobber (match_scratch:GPR 11 "=b"))]
11740  "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11741   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11742  "#"
11743  "&& reload_completed"
11744  [(set (match_dup 3) (match_dup 14))
11745   (set (match_dup 4) (match_dup 15))
11746   (set (match_dup 9) (abs:DF (match_dup 5)))
11747   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11748   (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11749			   (label_ref (match_dup 12))
11750			   (pc)))
11751   (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11752   (set (pc) (label_ref (match_dup 13)))
11753   (match_dup 12)
11754   (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11755   (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11756   (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11757   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11758   (match_dup 13)]
11759{
11760  REAL_VALUE_TYPE rv;
11761  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11762  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11763
11764  operands[5] = simplify_gen_subreg (DFmode, operands[1],
11765				     <IBM128:MODE>mode, hi_word);
11766  operands[6] = simplify_gen_subreg (DFmode, operands[1],
11767				     <IBM128:MODE>mode, lo_word);
11768  operands[7] = simplify_gen_subreg (DFmode, operands[2],
11769				     <IBM128:MODE>mode, hi_word);
11770  operands[8] = simplify_gen_subreg (DFmode, operands[2],
11771				     <IBM128:MODE>mode, lo_word);
11772  operands[12] = gen_label_rtx ();
11773  operands[13] = gen_label_rtx ();
11774  real_inf (&rv);
11775  operands[14] = force_const_mem (DFmode,
11776				  const_double_from_real_value (rv, DFmode));
11777  operands[15] = force_const_mem (DFmode,
11778				  const_double_from_real_value (dconst0,
11779								DFmode));
11780  if (TARGET_TOC)
11781    {
11782      rtx tocref;
11783      tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11784      operands[14] = gen_const_mem (DFmode, tocref);
11785      tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11786      operands[15] = gen_const_mem (DFmode, tocref);
11787      set_mem_alias_set (operands[14], get_TOC_alias_set ());
11788      set_mem_alias_set (operands[15], get_TOC_alias_set ());
11789    }
11790})
11791
11792;; Now we have the scc insns.  We can do some combinations because of the
11793;; way the machine works.
11794;;
11795;; Note that this is probably faster if we can put an insn between the
11796;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11797;; cases the insns below which don't use an intermediate CR field will
11798;; be used instead.
11799(define_insn "set<mode>_cc"
11800  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11801	(match_operator:GPR 1 "scc_comparison_operator"
11802			    [(match_operand 2 "cc_reg_operand" "y")
11803			     (const_int 0)]))]
11804  ""
11805  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11806  [(set (attr "type")
11807     (cond [(match_test "TARGET_MFCRF")
11808		(const_string "mfcrf")
11809	   ]
11810	(const_string "mfcr")))
11811   (set_attr "length" "8")])
11812
11813
11814(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11815(define_code_attr UNS [(eq "CC")
11816		       (ne "CC")
11817		       (lt "CC") (ltu "CCUNS")
11818		       (gt "CC") (gtu "CCUNS")
11819		       (le "CC") (leu "CCUNS")
11820		       (ge "CC") (geu "CCUNS")])
11821(define_code_attr UNSu_ [(eq "")
11822			 (ne "")
11823			 (lt "") (ltu "u_")
11824			 (gt "") (gtu "u_")
11825			 (le "") (leu "u_")
11826			 (ge "") (geu "u_")])
11827(define_code_attr UNSIK [(eq "I")
11828			 (ne "I")
11829			 (lt "I") (ltu "K")
11830			 (gt "I") (gtu "K")
11831			 (le "I") (leu "K")
11832			 (ge "I") (geu "K")])
11833
11834(define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11835  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11836	(cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11837		 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11838   (clobber (match_scratch:GPR 3 "=r"))
11839   (clobber (match_scratch:GPR 4 "=r"))
11840   (clobber (match_scratch:<UNS> 5 "=y"))]
11841  "TARGET_ISEL
11842   && !(<CODE> == EQ && operands[2] == const0_rtx)
11843   && !(<CODE> == NE && operands[2] == const0_rtx
11844	&& <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11845  "#"
11846  "&& 1"
11847  [(pc)]
11848{
11849  rtx_code code = <CODE>;
11850  if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11851    {
11852      HOST_WIDE_INT val = INTVAL (operands[2]);
11853      if (code == LT && val != -0x8000)
11854	{
11855	  code = LE;
11856	  val--;
11857	}
11858      if (code == GT && val != 0x7fff)
11859	{
11860	  code = GE;
11861	  val++;
11862	}
11863      if (code == LTU && val != 0)
11864	{
11865	  code = LEU;
11866	  val--;
11867	}
11868      if (code == GTU && val != 0xffff)
11869	{
11870	  code = GEU;
11871	  val++;
11872	}
11873      operands[2] = GEN_INT (val);
11874    }
11875
11876  if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11877    operands[3] = const0_rtx;
11878  else
11879    {
11880      if (GET_CODE (operands[3]) == SCRATCH)
11881	operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11882      emit_move_insn (operands[3], const0_rtx);
11883    }
11884
11885  if (GET_CODE (operands[4]) == SCRATCH)
11886    operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11887  emit_move_insn (operands[4], const1_rtx);
11888
11889  if (GET_CODE (operands[5]) == SCRATCH)
11890    operands[5] = gen_reg_rtx (<UNS>mode);
11891
11892  rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11893  emit_insn (gen_rtx_SET (operands[5], c1));
11894
11895  rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11896  rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11897  emit_move_insn (operands[0], x);
11898
11899  DONE;
11900}
11901  [(set (attr "cost")
11902	(if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11903				   || <CODE> == NE
11904				   || <CODE> == LE || <CODE> == GE
11905				   || <CODE> == LEU || <CODE> == GEU")
11906		      (const_string "9")
11907		      (const_string "10")))])
11908
11909(define_mode_attr scc_eq_op2 [(SI "rKLI")
11910			      (DI "rKJI")])
11911
11912(define_expand "eq<mode>3"
11913  [(parallel [
11914     (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11915	  (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11916		  (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11917     (clobber (match_scratch:GPR 3 "=r"))
11918     (clobber (match_scratch:GPR 4 "=r"))])]
11919  ""
11920{
11921  if (TARGET_ISEL && operands[2] != const0_rtx)
11922    {
11923      emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11924					   operands[2]));
11925      DONE;
11926    }
11927})
11928
11929(define_insn_and_split "*eq<mode>3"
11930  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11931	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11932		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11933   (clobber (match_scratch:GPR 3 "=r"))
11934   (clobber (match_scratch:GPR 4 "=r"))]
11935  "!(TARGET_ISEL && operands[2] != const0_rtx)"
11936  "#"
11937  "&& 1"
11938  [(set (match_dup 4)
11939	(clz:GPR (match_dup 3)))
11940   (set (match_dup 0)
11941	(lshiftrt:GPR (match_dup 4)
11942		      (match_dup 5)))]
11943{
11944  operands[3] = rs6000_emit_eqne (<MODE>mode,
11945				  operands[1], operands[2], operands[3]);
11946
11947  if (GET_CODE (operands[4]) == SCRATCH)
11948    operands[4] = gen_reg_rtx (<MODE>mode);
11949
11950  operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11951}
11952  [(set (attr "length")
11953	(if_then_else (match_test "operands[2] == const0_rtx")
11954		      (const_string "8")
11955		      (const_string "12")))])
11956
11957(define_expand "ne<mode>3"
11958  [(parallel [
11959     (set (match_operand:P 0 "gpc_reg_operand" "=r")
11960	  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11961		(match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11962     (clobber (match_scratch:P 3 "=r"))
11963     (clobber (match_scratch:P 4 "=r"))
11964     (clobber (reg:P CA_REGNO))])]
11965  ""
11966{
11967  if (TARGET_ISEL && operands[2] != const0_rtx)
11968    {
11969      emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11970					   operands[2]));
11971      DONE;
11972    }
11973})
11974
11975(define_insn_and_split "*ne<mode>3"
11976  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11977	(ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11978	      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11979   (clobber (match_scratch:P 3 "=r"))
11980   (clobber (match_scratch:P 4 "=r"))
11981   (clobber (reg:P CA_REGNO))]
11982  "!(TARGET_ISEL && operands[2] != const0_rtx)"
11983  "#"
11984  "&& 1"
11985  [(parallel [(set (match_dup 4)
11986		   (plus:P (match_dup 3)
11987			   (const_int -1)))
11988	      (set (reg:P CA_REGNO)
11989		   (ne:P (match_dup 3)
11990			 (const_int 0)))])
11991   (parallel [(set (match_dup 0)
11992		   (plus:P (plus:P (not:P (match_dup 4))
11993				   (reg:P CA_REGNO))
11994			   (match_dup 3)))
11995	      (clobber (reg:P CA_REGNO))])]
11996{
11997  operands[3] = rs6000_emit_eqne (<MODE>mode,
11998				  operands[1], operands[2], operands[3]);
11999
12000  if (GET_CODE (operands[4]) == SCRATCH)
12001    operands[4] = gen_reg_rtx (<MODE>mode);
12002}
12003  [(set (attr "length")
12004	(if_then_else (match_test "operands[2] == const0_rtx")
12005		      (const_string "8")
12006		      (const_string "12")))])
12007
12008(define_insn_and_split "*neg_eq_<mode>"
12009  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12010	(neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12011		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12012   (clobber (match_scratch:P 3 "=r"))
12013   (clobber (match_scratch:P 4 "=r"))
12014   (clobber (reg:P CA_REGNO))]
12015  ""
12016  "#"
12017  ""
12018  [(parallel [(set (match_dup 4)
12019		   (plus:P (match_dup 3)
12020			   (const_int -1)))
12021	      (set (reg:P CA_REGNO)
12022		   (ne:P (match_dup 3)
12023			 (const_int 0)))])
12024   (parallel [(set (match_dup 0)
12025		   (plus:P (reg:P CA_REGNO)
12026			   (const_int -1)))
12027	      (clobber (reg:P CA_REGNO))])]
12028{
12029  operands[3] = rs6000_emit_eqne (<MODE>mode,
12030				  operands[1], operands[2], operands[3]);
12031
12032  if (GET_CODE (operands[4]) == SCRATCH)
12033    operands[4] = gen_reg_rtx (<MODE>mode);
12034}
12035  [(set (attr "length")
12036	(if_then_else (match_test "operands[2] == const0_rtx")
12037		      (const_string "8")
12038		      (const_string "12")))])
12039
12040(define_insn_and_split "*neg_ne_<mode>"
12041  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12042	(neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12043		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12044   (clobber (match_scratch:P 3 "=r"))
12045   (clobber (match_scratch:P 4 "=r"))
12046   (clobber (reg:P CA_REGNO))]
12047  ""
12048  "#"
12049  ""
12050  [(parallel [(set (match_dup 4)
12051		   (neg:P (match_dup 3)))
12052	      (set (reg:P CA_REGNO)
12053		   (eq:P (match_dup 3)
12054			 (const_int 0)))])
12055   (parallel [(set (match_dup 0)
12056		   (plus:P (reg:P CA_REGNO)
12057			   (const_int -1)))
12058	      (clobber (reg:P CA_REGNO))])]
12059{
12060  operands[3] = rs6000_emit_eqne (<MODE>mode,
12061				  operands[1], operands[2], operands[3]);
12062
12063  if (GET_CODE (operands[4]) == SCRATCH)
12064    operands[4] = gen_reg_rtx (<MODE>mode);
12065}
12066  [(set (attr "length")
12067	(if_then_else (match_test "operands[2] == const0_rtx")
12068		      (const_string "8")
12069		      (const_string "12")))])
12070
12071(define_insn_and_split "*plus_eq_<mode>"
12072  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12073	(plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12074		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12075		(match_operand:P 3 "gpc_reg_operand" "r")))
12076   (clobber (match_scratch:P 4 "=r"))
12077   (clobber (match_scratch:P 5 "=r"))
12078   (clobber (reg:P CA_REGNO))]
12079  ""
12080  "#"
12081  ""
12082  [(parallel [(set (match_dup 5)
12083		   (neg:P (match_dup 4)))
12084	      (set (reg:P CA_REGNO)
12085		   (eq:P (match_dup 4)
12086			 (const_int 0)))])
12087   (parallel [(set (match_dup 0)
12088		   (plus:P (match_dup 3)
12089			   (reg:P CA_REGNO)))
12090	      (clobber (reg:P CA_REGNO))])]
12091{
12092  operands[4] = rs6000_emit_eqne (<MODE>mode,
12093				  operands[1], operands[2], operands[4]);
12094
12095  if (GET_CODE (operands[5]) == SCRATCH)
12096    operands[5] = gen_reg_rtx (<MODE>mode);
12097}
12098  [(set (attr "length")
12099	(if_then_else (match_test "operands[2] == const0_rtx")
12100		      (const_string "8")
12101		      (const_string "12")))])
12102
12103(define_insn_and_split "*plus_ne_<mode>"
12104  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12105	(plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12106		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12107		(match_operand:P 3 "gpc_reg_operand" "r")))
12108   (clobber (match_scratch:P 4 "=r"))
12109   (clobber (match_scratch:P 5 "=r"))
12110   (clobber (reg:P CA_REGNO))]
12111  ""
12112  "#"
12113  ""
12114  [(parallel [(set (match_dup 5)
12115		   (plus:P (match_dup 4)
12116			   (const_int -1)))
12117	      (set (reg:P CA_REGNO)
12118		   (ne:P (match_dup 4)
12119			 (const_int 0)))])
12120   (parallel [(set (match_dup 0)
12121		   (plus:P (match_dup 3)
12122			   (reg:P CA_REGNO)))
12123	      (clobber (reg:P CA_REGNO))])]
12124{
12125  operands[4] = rs6000_emit_eqne (<MODE>mode,
12126				  operands[1], operands[2], operands[4]);
12127
12128  if (GET_CODE (operands[5]) == SCRATCH)
12129    operands[5] = gen_reg_rtx (<MODE>mode);
12130}
12131  [(set (attr "length")
12132	(if_then_else (match_test "operands[2] == const0_rtx")
12133		      (const_string "8")
12134		      (const_string "12")))])
12135
12136(define_insn_and_split "*minus_eq_<mode>"
12137  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12138	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12139		 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12140		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12141   (clobber (match_scratch:P 4 "=r"))
12142   (clobber (match_scratch:P 5 "=r"))
12143   (clobber (reg:P CA_REGNO))]
12144  ""
12145  "#"
12146  ""
12147  [(parallel [(set (match_dup 5)
12148		   (plus:P (match_dup 4)
12149			   (const_int -1)))
12150	      (set (reg:P CA_REGNO)
12151		   (ne:P (match_dup 4)
12152			 (const_int 0)))])
12153   (parallel [(set (match_dup 0)
12154		   (plus:P (plus:P (match_dup 3)
12155				   (reg:P CA_REGNO))
12156			   (const_int -1)))
12157	      (clobber (reg:P CA_REGNO))])]
12158{
12159  operands[4] = rs6000_emit_eqne (<MODE>mode,
12160				  operands[1], operands[2], operands[4]);
12161
12162  if (GET_CODE (operands[5]) == SCRATCH)
12163    operands[5] = gen_reg_rtx (<MODE>mode);
12164}
12165  [(set (attr "length")
12166	(if_then_else (match_test "operands[2] == const0_rtx")
12167		      (const_string "8")
12168		      (const_string "12")))])
12169
12170(define_insn_and_split "*minus_ne_<mode>"
12171  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12172	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12173		 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12174		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12175   (clobber (match_scratch:P 4 "=r"))
12176   (clobber (match_scratch:P 5 "=r"))
12177   (clobber (reg:P CA_REGNO))]
12178  ""
12179  "#"
12180  ""
12181  [(parallel [(set (match_dup 5)
12182		   (neg:P (match_dup 4)))
12183	      (set (reg:P CA_REGNO)
12184		   (eq:P (match_dup 4)
12185			 (const_int 0)))])
12186   (parallel [(set (match_dup 0)
12187		   (plus:P (plus:P (match_dup 3)
12188				   (reg:P CA_REGNO))
12189			   (const_int -1)))
12190	      (clobber (reg:P CA_REGNO))])]
12191{
12192  operands[4] = rs6000_emit_eqne (<MODE>mode,
12193				  operands[1], operands[2], operands[4]);
12194
12195  if (GET_CODE (operands[5]) == SCRATCH)
12196    operands[5] = gen_reg_rtx (<MODE>mode);
12197}
12198  [(set (attr "length")
12199	(if_then_else (match_test "operands[2] == const0_rtx")
12200		      (const_string "8")
12201		      (const_string "12")))])
12202
12203(define_insn_and_split "*eqsi3_ext<mode>"
12204  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12205	(eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12206		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12207   (clobber (match_scratch:SI 3 "=r"))
12208   (clobber (match_scratch:SI 4 "=r"))]
12209  ""
12210  "#"
12211  ""
12212  [(set (match_dup 4)
12213	(clz:SI (match_dup 3)))
12214   (set (match_dup 0)
12215	(zero_extend:EXTSI
12216	  (lshiftrt:SI (match_dup 4)
12217		       (const_int 5))))]
12218{
12219  operands[3] = rs6000_emit_eqne (SImode,
12220				  operands[1], operands[2], operands[3]);
12221
12222  if (GET_CODE (operands[4]) == SCRATCH)
12223    operands[4] = gen_reg_rtx (SImode);
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 "*nesi3_ext<mode>"
12231  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12232	(ne: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   (clobber (match_scratch:EXTSI 5 "=r"))]
12237  "!TARGET_ISEL"
12238  "#"
12239  "&& 1"
12240  [(set (match_dup 4)
12241	(clz:SI (match_dup 3)))
12242   (set (match_dup 5)
12243	(zero_extend:EXTSI
12244	  (lshiftrt:SI (match_dup 4)
12245		       (const_int 5))))
12246   (set (match_dup 0)
12247	(xor:EXTSI (match_dup 5)
12248		   (const_int 1)))]
12249{
12250  operands[3] = rs6000_emit_eqne (SImode,
12251				  operands[1], operands[2], operands[3]);
12252
12253  if (GET_CODE (operands[4]) == SCRATCH)
12254    operands[4] = gen_reg_rtx (SImode);
12255  if (GET_CODE (operands[5]) == SCRATCH)
12256    operands[5] = gen_reg_rtx (<MODE>mode);
12257}
12258  [(set (attr "length")
12259	(if_then_else (match_test "operands[2] == const0_rtx")
12260		      (const_string "12")
12261		      (const_string "16")))])
12262
12263
12264(define_code_iterator fp_rev [ordered ne unle unge])
12265(define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12266
12267(define_insn_and_split "*<code><mode>_cc"
12268  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12269	(fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12270		    (const_int 0)))]
12271  "!flag_finite_math_only"
12272  "#"
12273  "&& 1"
12274  [(pc)]
12275{
12276  rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12277  rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12278  rtx tmp = gen_reg_rtx (<MODE>mode);
12279  emit_move_insn (tmp, eq);
12280  emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12281  DONE;
12282}
12283  [(set_attr "length" "12")])
12284
12285(define_insn_and_split "*<code><mode>_cc"
12286  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12287	(fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12288		  (const_int 0)))]
12289  "!flag_finite_math_only"
12290  "#"
12291  "&& 1"
12292  [(pc)]
12293{
12294  rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12295
12296  emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12297  DONE;
12298}
12299  [(set_attr "length" "12")])
12300
12301;; Conditional branches.
12302;; These either are a single bc insn, or a bc around a b.
12303
12304(define_insn "*cbranch"
12305  [(set (pc)
12306	(if_then_else (match_operator 1 "branch_comparison_operator"
12307				      [(match_operand 2 "cc_reg_operand" "y")
12308				       (const_int 0)])
12309		      (label_ref (match_operand 0))
12310		      (pc)))]
12311  ""
12312{
12313  return output_cbranch (operands[1], "%l0", 0, insn);
12314}
12315  [(set_attr "type" "branch")
12316   (set (attr "length")
12317	(if_then_else (and (ge (minus (match_dup 0) (pc))
12318			       (const_int -32768))
12319			   (lt (minus (match_dup 0) (pc))
12320			       (const_int 32764)))
12321		      (const_int 4)
12322		      (const_int 8)))])
12323
12324(define_insn_and_split "*cbranch_2insn"
12325  [(set (pc)
12326	(if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12327				      [(match_operand 2 "cc_reg_operand" "y")
12328				       (const_int 0)])
12329		      (label_ref (match_operand 0))
12330		      (pc)))]
12331  "!flag_finite_math_only"
12332  "#"
12333  "&& 1"
12334  [(pc)]
12335{
12336  rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12337
12338  rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12339
12340  rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12341  rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12342  rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12343  emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12344
12345  if (note)
12346    {
12347      profile_probability prob
12348	= profile_probability::from_reg_br_prob_note (XINT (note, 0));
12349
12350      add_reg_br_prob_note (get_last_insn (), prob);
12351    }
12352
12353  DONE;
12354}
12355  [(set_attr "type" "branch")
12356   (set (attr "length")
12357	(if_then_else (and (ge (minus (match_dup 0) (pc))
12358			       (const_int -32764))
12359			   (lt (minus (match_dup 0) (pc))
12360			       (const_int 32760)))
12361		      (const_int 8)
12362		      (const_int 16)))])
12363
12364;; Conditional return.
12365(define_insn "*creturn"
12366  [(set (pc)
12367	(if_then_else (match_operator 0 "branch_comparison_operator"
12368				      [(match_operand 1 "cc_reg_operand" "y")
12369				       (const_int 0)])
12370		      (any_return)
12371		      (pc)))]
12372  "<return_pred>"
12373{
12374  return output_cbranch (operands[0], NULL, 0, insn);
12375}
12376  [(set_attr "type" "jmpreg")])
12377
12378;; Logic on condition register values.
12379
12380; This pattern matches things like
12381; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12382;					   (eq:SI (reg:CCFP 68) (const_int 0)))
12383;				   (const_int 1)))
12384; which are generated by the branch logic.
12385; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12386
12387(define_insn "@cceq_ior_compare_<mode>"
12388  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12389        (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12390	                [(match_operator:GPR 2
12391				      "branch_positive_comparison_operator"
12392				      [(match_operand 3
12393						      "cc_reg_operand" "y,y")
12394				       (const_int 0)])
12395	                 (match_operator:GPR 4
12396				      "branch_positive_comparison_operator"
12397				      [(match_operand 5
12398						      "cc_reg_operand" "0,y")
12399				       (const_int 0)])])
12400		      (const_int 1)))]
12401  ""
12402  "cr%q1 %E0,%j2,%j4"
12403  [(set_attr "type" "cr_logical")
12404   (set_attr "cr_logical_3op" "no,yes")])
12405
12406; Why is the constant -1 here, but 1 in the previous pattern?
12407; Because ~1 has all but the low bit set.
12408(define_insn "cceq_ior_compare_complement"
12409  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12410        (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12411	                [(not:SI (match_operator:SI 2
12412				      "branch_positive_comparison_operator"
12413				      [(match_operand 3
12414						      "cc_reg_operand" "y,y")
12415				       (const_int 0)]))
12416	                 (match_operator:SI 4
12417				"branch_positive_comparison_operator"
12418				[(match_operand 5
12419						"cc_reg_operand" "0,y")
12420				 (const_int 0)])])
12421		      (const_int -1)))]
12422  ""
12423  "cr%q1 %E0,%j2,%j4"
12424  [(set_attr "type" "cr_logical")
12425   (set_attr "cr_logical_3op" "no,yes")])
12426
12427(define_insn "@cceq_rev_compare_<mode>"
12428  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12429	(compare:CCEQ (match_operator:GPR 1
12430				      "branch_positive_comparison_operator"
12431				      [(match_operand 2
12432						      "cc_reg_operand" "0,y")
12433				       (const_int 0)])
12434		      (const_int 0)))]
12435  ""
12436  "crnot %E0,%j1"
12437  [(set_attr "type" "cr_logical")
12438   (set_attr "cr_logical_3op" "no,yes")])
12439
12440;; If we are comparing the result of two comparisons, this can be done
12441;; using creqv or crxor.
12442
12443(define_insn_and_split ""
12444  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12445	(compare:CCEQ (match_operator 1 "branch_comparison_operator"
12446			      [(match_operand 2 "cc_reg_operand" "y")
12447			       (const_int 0)])
12448		      (match_operator 3 "branch_comparison_operator"
12449			      [(match_operand 4 "cc_reg_operand" "y")
12450			       (const_int 0)])))]
12451  ""
12452  "#"
12453  ""
12454  [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12455				    (match_dup 5)))]
12456{
12457  int positive_1, positive_2;
12458
12459  positive_1 = branch_positive_comparison_operator (operands[1],
12460						    GET_MODE (operands[1]));
12461  positive_2 = branch_positive_comparison_operator (operands[3],
12462						    GET_MODE (operands[3]));
12463
12464  if (! positive_1)
12465    operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12466							    GET_CODE (operands[1])),
12467				  SImode,
12468				  operands[2], const0_rtx);
12469  else if (GET_MODE (operands[1]) != SImode)
12470    operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12471				  operands[2], const0_rtx);
12472
12473  if (! positive_2)
12474    operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12475							    GET_CODE (operands[3])),
12476				  SImode,
12477				  operands[4], const0_rtx);
12478  else if (GET_MODE (operands[3]) != SImode)
12479    operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12480				  operands[4], const0_rtx);
12481
12482  if (positive_1 == positive_2)
12483    {
12484      operands[1] = gen_rtx_NOT (SImode, operands[1]);
12485      operands[5] = constm1_rtx;
12486    }
12487  else
12488    {
12489      operands[5] = const1_rtx;
12490    }
12491})
12492
12493;; Unconditional branch and return.
12494
12495(define_insn "jump"
12496  [(set (pc)
12497	(label_ref (match_operand 0)))]
12498  ""
12499  "b %l0"
12500  [(set_attr "type" "branch")])
12501
12502(define_insn "<return_str>return"
12503  [(any_return)]
12504  "<return_pred>"
12505  "blr"
12506  [(set_attr "type" "jmpreg")])
12507
12508(define_expand "indirect_jump"
12509  [(set (pc) (match_operand 0 "register_operand"))]
12510 ""
12511{
12512  if (!rs6000_speculate_indirect_jumps) {
12513    rtx ccreg = gen_reg_rtx (CCmode);
12514    emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12515    DONE;
12516  }
12517})
12518
12519(define_insn "*indirect_jump<mode>"
12520  [(set (pc)
12521	(match_operand:P 0 "register_operand" "c,*l"))]
12522  "rs6000_speculate_indirect_jumps"
12523  "b%T0"
12524  [(set_attr "type" "jmpreg")])
12525
12526(define_insn "@indirect_jump<mode>_nospec"
12527  [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12528   (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12529  "!rs6000_speculate_indirect_jumps"
12530  "crset %E1\;beq%T0- %1\;b $"
12531  [(set_attr "type" "jmpreg")
12532   (set_attr "length" "12")])
12533
12534;; Table jump for switch statements:
12535(define_expand "tablejump"
12536  [(use (match_operand 0))
12537   (use (label_ref (match_operand 1)))]
12538  ""
12539{
12540  if (rs6000_speculate_indirect_jumps)
12541    {
12542      if (TARGET_32BIT)
12543      	emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12544      else
12545	emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12546    }
12547  else
12548    {
12549      rtx ccreg = gen_reg_rtx (CCmode);
12550      rtx jump;
12551      if (TARGET_32BIT)
12552	jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12553      else
12554	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12555      emit_jump_insn (jump);
12556    }
12557  DONE;
12558})
12559
12560(define_expand "tablejumpsi"
12561  [(set (match_dup 3)
12562	(plus:SI (match_operand:SI 0)
12563		 (match_dup 2)))
12564   (parallel [(set (pc)
12565		   (match_dup 3))
12566	      (use (label_ref (match_operand 1)))])]
12567  "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12568{
12569  operands[0] = force_reg (SImode, operands[0]);
12570  operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12571  operands[3] = gen_reg_rtx (SImode);
12572})
12573
12574(define_expand "tablejumpsi_nospec"
12575  [(set (match_dup 4)
12576	(plus:SI (match_operand:SI 0)
12577		 (match_dup 3)))
12578   (parallel [(set (pc)
12579		   (match_dup 4))
12580	      (use (label_ref (match_operand 1)))
12581	      (clobber (match_operand 2))])]
12582  "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12583{
12584  operands[0] = force_reg (SImode, operands[0]);
12585  operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12586  operands[4] = gen_reg_rtx (SImode);
12587})
12588
12589(define_expand "tablejumpdi"
12590  [(set (match_dup 4)
12591        (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12592   (set (match_dup 3)
12593	(plus:DI (match_dup 4)
12594		 (match_dup 2)))
12595   (parallel [(set (pc)
12596		   (match_dup 3))
12597	      (use (label_ref (match_operand 1)))])]
12598  "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12599{
12600  operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12601  operands[3] = gen_reg_rtx (DImode);
12602  operands[4] = gen_reg_rtx (DImode);
12603})
12604
12605(define_expand "tablejumpdi_nospec"
12606  [(set (match_dup 5)
12607        (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12608   (set (match_dup 4)
12609	(plus:DI (match_dup 5)
12610		 (match_dup 3)))
12611   (parallel [(set (pc)
12612		   (match_dup 4))
12613	      (use (label_ref (match_operand 1)))
12614	      (clobber (match_operand 2))])]
12615  "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12616{
12617  operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12618  operands[4] = gen_reg_rtx (DImode);
12619  operands[5] = gen_reg_rtx (DImode);
12620})
12621
12622(define_insn "*tablejump<mode>_internal1"
12623  [(set (pc)
12624	(match_operand:P 0 "register_operand" "c,*l"))
12625   (use (label_ref (match_operand 1)))]
12626  "rs6000_speculate_indirect_jumps"
12627  "b%T0"
12628  [(set_attr "type" "jmpreg")])
12629
12630(define_insn "*tablejump<mode>_internal1_nospec"
12631  [(set (pc)
12632	(match_operand:P 0 "register_operand" "c,*l"))
12633   (use (label_ref (match_operand 1)))
12634   (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12635  "!rs6000_speculate_indirect_jumps"
12636  "crset %E2\;beq%T0- %2\;b $"
12637  [(set_attr "type" "jmpreg")
12638   (set_attr "length" "12")])
12639
12640(define_insn "nop"
12641  [(unspec [(const_int 0)] UNSPEC_NOP)]
12642  ""
12643  "nop")
12644
12645(define_insn "group_ending_nop"
12646  [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12647  ""
12648{
12649  operands[0] = gen_rtx_REG (Pmode,
12650			     rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12651  return "ori %0,%0,0";
12652})
12653
12654(define_insn "speculation_barrier"
12655  [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12656  ""
12657{
12658  operands[0] = gen_rtx_REG (Pmode, 31);
12659  return "ori %0,%0,0";
12660})
12661
12662;; Define the subtract-one-and-jump insns, starting with the template
12663;; so loop.c knows what to generate.
12664
12665(define_expand "doloop_end"
12666  [(use (match_operand 0))	; loop pseudo
12667   (use (match_operand 1))]	; label
12668  ""
12669{
12670  if (GET_MODE (operands[0]) != Pmode)
12671    FAIL;
12672
12673  emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12674  DONE;
12675})
12676
12677(define_expand "@ctr<mode>"
12678  [(parallel [(set (pc)
12679		   (if_then_else (ne (match_operand:P 0 "register_operand")
12680				     (const_int 1))
12681				 (label_ref (match_operand 1))
12682				 (pc)))
12683	      (set (match_dup 0)
12684		   (plus:P (match_dup 0)
12685			    (const_int -1)))
12686	      (clobber (match_scratch:CC 2))
12687	      (clobber (match_scratch:P 3))])]
12688  ""
12689  "")
12690
12691;; We need to be able to do this for any operand, including MEM, or we
12692;; will cause reload to blow up since we don't allow output reloads on
12693;; JUMP_INSNs.
12694;; For the length attribute to be calculated correctly, the
12695;; label MUST be operand 0.
12696;; rs6000_legitimate_combined_insn prevents combine creating any of
12697;; the ctr<mode> insns.
12698
12699(define_code_iterator eqne [eq ne])
12700(define_code_attr bd [(eq "bdz") (ne "bdnz")])
12701(define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12702
12703(define_insn "<bd>_<mode>"
12704  [(set (pc)
12705	(if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12706			  (const_int 1))
12707		      (label_ref (match_operand 0))
12708		      (pc)))
12709   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12710	(plus:P (match_dup 1)
12711		(const_int -1)))
12712   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12713   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12714  ""
12715{
12716  if (which_alternative != 0)
12717    return "#";
12718  else if (get_attr_length (insn) == 4)
12719    return "<bd> %l0";
12720  else
12721    return "<bd_neg> $+8\;b %l0";
12722}
12723  [(set_attr "type" "branch")
12724   (set_attr_alternative "length"
12725     [(if_then_else (and (ge (minus (match_dup 0) (pc))
12726			     (const_int -32768))
12727			 (lt (minus (match_dup 0) (pc))
12728			     (const_int 32764)))
12729		    (const_int 4)
12730		    (const_int 8))
12731      (const_string "16")
12732      (const_string "20")
12733      (const_string "20")])])
12734
12735;; Now the splitter if we could not allocate the CTR register
12736(define_split
12737  [(set (pc)
12738	(if_then_else (match_operator 2 "comparison_operator"
12739				      [(match_operand:P 1 "gpc_reg_operand")
12740				       (const_int 1)])
12741		      (match_operand 5)
12742		      (match_operand 6)))
12743   (set (match_operand:P 0 "nonimmediate_operand")
12744	(plus:P (match_dup 1)
12745		(const_int -1)))
12746   (clobber (match_scratch:CC 3))
12747   (clobber (match_scratch:P 4))]
12748  "reload_completed"
12749  [(set (pc)
12750	(if_then_else (match_dup 7)
12751		      (match_dup 5)
12752		      (match_dup 6)))]
12753{
12754  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12755				const0_rtx);
12756  emit_insn (gen_rtx_SET (operands[3],
12757			  gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12758  if (int_reg_operand (operands[0], <MODE>mode))
12759    emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12760  else
12761    {
12762      emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12763      emit_move_insn (operands[0], operands[4]);
12764    }
12765    /* No DONE so branch comes from the pattern.  */
12766})
12767
12768;; patterns for bdnzt/bdnzf/bdzt/bdzf
12769;; Note that in the case of long branches we have to decompose this into
12770;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12771;; and the CR bit, which means there is no way to conveniently invert the
12772;; comparison as is done with plain bdnz/bdz.
12773
12774(define_insn "<bd>tf_<mode>"
12775  [(set (pc)
12776	(if_then_else
12777	  (and
12778	     (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12779		   (const_int 1))
12780	     (match_operator 3 "branch_comparison_operator"
12781		      [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12782		       (const_int 0)]))
12783	  (label_ref (match_operand 0))
12784	  (pc)))
12785   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12786	(plus:P (match_dup 1)
12787		(const_int -1)))
12788   (clobber (match_scratch:P 5 "=X,X,&r,r"))
12789   (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12790   (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12791  ""
12792{
12793  if (which_alternative != 0)
12794    return "#";
12795  else if (get_attr_length (insn) == 4)
12796    {
12797      if (branch_positive_comparison_operator (operands[3],
12798					       GET_MODE (operands[3])))
12799	return "<bd>t %j3,%l0";
12800      else
12801	return "<bd>f %j3,%l0";
12802    }
12803  else
12804    {
12805      static char seq[96];
12806      char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12807      sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12808      return seq;
12809    }
12810}
12811  [(set_attr "type" "branch")
12812   (set_attr_alternative "length"
12813     [(if_then_else (and (ge (minus (match_dup 0) (pc))
12814			     (const_int -32768))
12815			 (lt (minus (match_dup 0) (pc))
12816			     (const_int 32764)))
12817		    (const_int 4)
12818		    (const_int 8))
12819      (const_string "16")
12820      (const_string "20")
12821      (const_string "20")])])
12822
12823;; Now the splitter if we could not allocate the CTR register
12824(define_split
12825  [(set (pc)
12826	(if_then_else
12827	  (and
12828	     (match_operator 1 "comparison_operator"
12829			     [(match_operand:P 0 "gpc_reg_operand")
12830			      (const_int 1)])
12831	     (match_operator 3 "branch_comparison_operator"
12832		      [(match_operand 2 "cc_reg_operand")
12833		       (const_int 0)]))
12834	  (match_operand 4)
12835	  (match_operand 5)))
12836   (set (match_operand:P 6 "nonimmediate_operand")
12837	(plus:P (match_dup 0)
12838		(const_int -1)))
12839   (clobber (match_scratch:P 7))
12840   (clobber (match_scratch:CC 8))
12841   (clobber (match_scratch:CCEQ 9))]
12842  "reload_completed"
12843[(pc)]
12844{
12845  rtx ctr = operands[0];
12846  rtx ctrcmp = operands[1];
12847  rtx ccin = operands[2];
12848  rtx cccmp = operands[3];
12849  rtx dst1 = operands[4];
12850  rtx dst2 = operands[5];
12851  rtx ctrout = operands[6];
12852  rtx ctrtmp = operands[7];
12853  enum rtx_code cmpcode = GET_CODE (ctrcmp);
12854  bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12855  if (!ispos)
12856    cmpcode = reverse_condition (cmpcode);
12857  /* Generate crand/crandc here.  */
12858  emit_insn (gen_rtx_SET (operands[8],
12859			  gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12860  rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12861
12862  rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12863  if (ispos)
12864     emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
12865				      operands[8], cccmp, ccin));
12866  else
12867     emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12868						 operands[8], cccmp, ccin));
12869  if (int_reg_operand (ctrout, <MODE>mode))
12870     emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12871  else
12872    {
12873      emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12874      emit_move_insn (ctrout, ctrtmp);
12875    }
12876  rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12877  emit_jump_insn (gen_rtx_SET (pc_rtx,
12878			       gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12879						     dst1, dst2)));
12880  DONE;
12881})
12882
12883
12884(define_insn "trap"
12885  [(trap_if (const_int 1) (const_int 0))]
12886  ""
12887  "trap"
12888  [(set_attr "type" "trap")])
12889
12890(define_expand "ctrap<mode>4"
12891  [(trap_if (match_operator 0 "ordered_comparison_operator"
12892			    [(match_operand:GPR 1 "register_operand")
12893			     (match_operand:GPR 2 "reg_or_short_operand")])
12894	    (match_operand 3 "zero_constant" ""))]
12895  ""
12896  "")
12897
12898(define_insn ""
12899  [(trap_if (match_operator 0 "ordered_comparison_operator"
12900                            [(match_operand:GPR 1 "register_operand" "r")
12901                             (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12902	    (const_int 0))]
12903  ""
12904  "t<wd>%V0%I2 %1,%2"
12905  [(set_attr "type" "trap")])
12906
12907;; Insns related to generating the function prologue and epilogue.
12908
12909(define_expand "prologue"
12910  [(use (const_int 0))]
12911  ""
12912{
12913  rs6000_emit_prologue ();
12914  if (!TARGET_SCHED_PROLOG)
12915    emit_insn (gen_blockage ());
12916  DONE;
12917})
12918
12919(define_insn "*movesi_from_cr_one"
12920  [(match_parallel 0 "mfcr_operation"
12921		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12922			 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12923				     (match_operand 3 "immediate_operand" "n")]
12924			  UNSPEC_MOVESI_FROM_CR))])]
12925  "TARGET_MFCRF"
12926{
12927  int mask = 0;
12928  int i;
12929  for (i = 0; i < XVECLEN (operands[0], 0); i++)
12930  {
12931    mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12932    operands[4] = GEN_INT (mask);
12933    output_asm_insn ("mfcr %1,%4", operands);
12934  }
12935  return "";
12936}
12937  [(set_attr "type" "mfcrf")])
12938
12939;; Don't include the volatile CRs since their values are not used wrt CR save
12940;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12941;; prologue past an insn (early exit test) that defines a register used in the
12942;; prologue.
12943(define_insn "prologue_movesi_from_cr"
12944  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12945        (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12946		    (reg:CC CR4_REGNO)]
12947		   UNSPEC_MOVESI_FROM_CR))]
12948  ""
12949  "mfcr %0"
12950  [(set_attr "type" "mfcr")])
12951
12952(define_insn "*crsave"
12953  [(match_parallel 0 "crsave_operation"
12954		   [(set (match_operand:SI 1 "memory_operand" "=m")
12955			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12956  ""
12957  "stw %2,%1"
12958  [(set_attr "type" "store")])
12959
12960(define_insn "*stmw"
12961  [(match_parallel 0 "stmw_operation"
12962		   [(set (match_operand:SI 1 "memory_operand" "=m")
12963       			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12964  "TARGET_MULTIPLE"
12965  "stmw %2,%1"
12966  [(set_attr "type" "store")
12967   (set_attr "update" "yes")
12968   (set_attr "indexed" "yes")])
12969
12970; The following comment applies to:
12971;     save_gpregs_*
12972;     save_fpregs_*
12973;     restore_gpregs*
12974;     return_and_restore_gpregs*
12975;     return_and_restore_fpregs*
12976;     return_and_restore_fpregs_aix*
12977;
12978; The out-of-line save / restore functions expects one input argument.
12979; Since those are not standard call_insn's, we must avoid using
12980; MATCH_OPERAND for that argument. That way the register rename
12981; optimization will not try to rename this register.
12982; Each pattern is repeated for each possible register number used in
12983; various ABIs (r11, r1, and for some functions r12)
12984
12985(define_insn "*save_gpregs_<mode>_r11"
12986  [(match_parallel 0 "any_parallel_operand"
12987		   [(clobber (reg:P LR_REGNO))
12988		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
12989                    (use (reg:P 11))
12990		    (set (match_operand:P 2 "memory_operand" "=m")
12991			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12992  ""
12993  "bl %1"
12994  [(set_attr "type" "branch")])
12995
12996(define_insn "*save_gpregs_<mode>_r12"
12997  [(match_parallel 0 "any_parallel_operand"
12998		   [(clobber (reg:P LR_REGNO))
12999		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13000                    (use (reg:P 12))
13001		    (set (match_operand:P 2 "memory_operand" "=m")
13002			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13003  ""
13004  "bl %1"
13005  [(set_attr "type" "branch")])
13006
13007(define_insn "*save_gpregs_<mode>_r1"
13008  [(match_parallel 0 "any_parallel_operand"
13009		   [(clobber (reg:P LR_REGNO))
13010		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13011                    (use (reg:P 1))
13012		    (set (match_operand:P 2 "memory_operand" "=m")
13013			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13014  ""
13015  "bl %1"
13016  [(set_attr "type" "branch")])
13017
13018(define_insn "*save_fpregs_<mode>_r11"
13019  [(match_parallel 0 "any_parallel_operand"
13020		   [(clobber (reg:P LR_REGNO))
13021		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13022                    (use (reg:P 11))
13023		    (set (match_operand:DF 2 "memory_operand" "=m")
13024			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13025  ""
13026  "bl %1"
13027  [(set_attr "type" "branch")])
13028
13029(define_insn "*save_fpregs_<mode>_r12"
13030  [(match_parallel 0 "any_parallel_operand"
13031		   [(clobber (reg:P LR_REGNO))
13032		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13033                    (use (reg:P 12))
13034		    (set (match_operand:DF 2 "memory_operand" "=m")
13035			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13036  ""
13037  "bl %1"
13038  [(set_attr "type" "branch")])
13039
13040(define_insn "*save_fpregs_<mode>_r1"
13041  [(match_parallel 0 "any_parallel_operand"
13042		   [(clobber (reg:P LR_REGNO))
13043		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13044                    (use (reg:P 1))
13045		    (set (match_operand:DF 2 "memory_operand" "=m")
13046			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13047  ""
13048  "bl %1"
13049  [(set_attr "type" "branch")])
13050
13051; This is to explain that changes to the stack pointer should
13052; not be moved over loads from or stores to stack memory.
13053(define_insn "stack_tie"
13054  [(match_parallel 0 "tie_operand"
13055		   [(set (mem:BLK (reg 1)) (const_int 0))])]
13056  ""
13057  ""
13058  [(set_attr "length" "0")])
13059
13060; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13061; stay behind all restores from the stack, it cannot be reordered to before
13062; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13063(define_insn "stack_restore_tie"
13064  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13065	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13066		 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13067   (set (mem:BLK (scratch)) (const_int 0))]
13068  "TARGET_32BIT"
13069  "@
13070   mr %0,%1
13071   add%I2 %0,%1,%2"
13072  [(set_attr "type" "*,add")])
13073
13074(define_expand "epilogue"
13075  [(use (const_int 0))]
13076  ""
13077{
13078  if (!TARGET_SCHED_PROLOG)
13079    emit_insn (gen_blockage ());
13080  rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13081  DONE;
13082})
13083
13084; On some processors, doing the mtcrf one CC register at a time is
13085; faster (like on the 604e).  On others, doing them all at once is
13086; faster; for instance, on the 601 and 750.
13087
13088(define_expand "movsi_to_cr_one"
13089  [(set (match_operand:CC 0 "cc_reg_operand")
13090        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13091		    (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13092  ""
13093  "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13094
13095(define_insn "*movsi_to_cr"
13096  [(match_parallel 0 "mtcrf_operation"
13097		   [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13098			 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13099				     (match_operand 3 "immediate_operand" "n")]
13100				    UNSPEC_MOVESI_TO_CR))])]
13101 ""
13102{
13103  int mask = 0;
13104  int i;
13105  for (i = 0; i < XVECLEN (operands[0], 0); i++)
13106    mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13107  operands[4] = GEN_INT (mask);
13108  return "mtcrf %4,%2";
13109}
13110  [(set_attr "type" "mtcr")])
13111
13112(define_insn "*mtcrfsi"
13113  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13114        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13115		    (match_operand 2 "immediate_operand" "n")]
13116		   UNSPEC_MOVESI_TO_CR))]
13117  "REG_P (operands[0])
13118   && CR_REGNO_P (REGNO (operands[0]))
13119   && CONST_INT_P (operands[2])
13120   && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13121  "mtcrf %R0,%1"
13122  [(set_attr "type" "mtcr")])
13123
13124; The load-multiple instructions have similar properties.
13125; Note that "load_multiple" is a name known to the machine-independent
13126; code that actually corresponds to the PowerPC load-string.
13127
13128(define_insn "*lmw"
13129  [(match_parallel 0 "lmw_operation"
13130		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13131       			 (match_operand:SI 2 "memory_operand" "m"))])]
13132  "TARGET_MULTIPLE"
13133  "lmw %1,%2"
13134  [(set_attr "type" "load")
13135   (set_attr "update" "yes")
13136   (set_attr "indexed" "yes")
13137   (set_attr "cell_micro" "always")])
13138
13139; FIXME: "any_parallel_operand" is a bit flexible...
13140
13141; The following comment applies to:
13142;     save_gpregs_*
13143;     save_fpregs_*
13144;     restore_gpregs*
13145;     return_and_restore_gpregs*
13146;     return_and_restore_fpregs*
13147;     return_and_restore_fpregs_aix*
13148;
13149; The out-of-line save / restore functions expects one input argument.
13150; Since those are not standard call_insn's, we must avoid using
13151; MATCH_OPERAND for that argument. That way the register rename
13152; optimization will not try to rename this register.
13153; Each pattern is repeated for each possible register number used in
13154; various ABIs (r11, r1, and for some functions r12)
13155
13156(define_insn "*restore_gpregs_<mode>_r11"
13157 [(match_parallel 0 "any_parallel_operand"
13158		  [(clobber (reg:P LR_REGNO))
13159		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13160		   (use (reg:P 11))
13161		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13162			(match_operand:P 3 "memory_operand" "m"))])]
13163 ""
13164 "bl %1"
13165 [(set_attr "type" "branch")])
13166
13167(define_insn "*restore_gpregs_<mode>_r12"
13168 [(match_parallel 0 "any_parallel_operand"
13169		  [(clobber (reg:P LR_REGNO))
13170		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13171		   (use (reg:P 12))
13172		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13173			(match_operand:P 3 "memory_operand" "m"))])]
13174 ""
13175 "bl %1"
13176 [(set_attr "type" "branch")])
13177
13178(define_insn "*restore_gpregs_<mode>_r1"
13179 [(match_parallel 0 "any_parallel_operand"
13180		  [(clobber (reg:P LR_REGNO))
13181		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13182		   (use (reg:P 1))
13183		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13184			(match_operand:P 3 "memory_operand" "m"))])]
13185 ""
13186 "bl %1"
13187 [(set_attr "type" "branch")])
13188
13189(define_insn "*return_and_restore_gpregs_<mode>_r11"
13190 [(match_parallel 0 "any_parallel_operand"
13191		  [(return)
13192		   (clobber (reg:P LR_REGNO))
13193		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13194		   (use (reg:P 11))
13195		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13196			(match_operand:P 3 "memory_operand" "m"))])]
13197 ""
13198 "b %1"
13199 [(set_attr "type" "branch")])
13200
13201(define_insn "*return_and_restore_gpregs_<mode>_r12"
13202 [(match_parallel 0 "any_parallel_operand"
13203		  [(return)
13204		   (clobber (reg:P LR_REGNO))
13205		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13206		   (use (reg:P 12))
13207		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13208			(match_operand:P 3 "memory_operand" "m"))])]
13209 ""
13210 "b %1"
13211 [(set_attr "type" "branch")])
13212
13213(define_insn "*return_and_restore_gpregs_<mode>_r1"
13214 [(match_parallel 0 "any_parallel_operand"
13215		  [(return)
13216		   (clobber (reg:P LR_REGNO))
13217		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13218		   (use (reg:P 1))
13219		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13220			(match_operand:P 3 "memory_operand" "m"))])]
13221 ""
13222 "b %1"
13223 [(set_attr "type" "branch")])
13224
13225(define_insn "*return_and_restore_fpregs_<mode>_r11"
13226 [(match_parallel 0 "any_parallel_operand"
13227		  [(return)
13228		   (clobber (reg:P LR_REGNO))
13229		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13230		   (use (reg:P 11))
13231		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13232			(match_operand:DF 3 "memory_operand" "m"))])]
13233 ""
13234 "b %1"
13235 [(set_attr "type" "branch")])
13236
13237(define_insn "*return_and_restore_fpregs_<mode>_r12"
13238 [(match_parallel 0 "any_parallel_operand"
13239		  [(return)
13240		   (clobber (reg:P LR_REGNO))
13241		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13242		   (use (reg:P 12))
13243		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13244			(match_operand:DF 3 "memory_operand" "m"))])]
13245 ""
13246 "b %1"
13247 [(set_attr "type" "branch")])
13248
13249(define_insn "*return_and_restore_fpregs_<mode>_r1"
13250 [(match_parallel 0 "any_parallel_operand"
13251		  [(return)
13252		   (clobber (reg:P LR_REGNO))
13253		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13254		   (use (reg:P 1))
13255		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13256			(match_operand:DF 3 "memory_operand" "m"))])]
13257 ""
13258 "b %1"
13259 [(set_attr "type" "branch")])
13260
13261(define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13262 [(match_parallel 0 "any_parallel_operand"
13263		  [(return)
13264		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13265		   (use (reg:P 11))
13266		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13267			(match_operand:DF 3 "memory_operand" "m"))])]
13268 ""
13269 "b %1"
13270 [(set_attr "type" "branch")])
13271
13272(define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13273 [(match_parallel 0 "any_parallel_operand"
13274		  [(return)
13275		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13276		   (use (reg:P 1))
13277		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13278			(match_operand:DF 3 "memory_operand" "m"))])]
13279 ""
13280 "b %1"
13281 [(set_attr "type" "branch")])
13282
13283; This is used in compiling the unwind routines.
13284(define_expand "eh_return"
13285  [(use (match_operand 0 "general_operand"))]
13286  ""
13287{
13288  emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13289  DONE;
13290})
13291
13292; We can't expand this before we know where the link register is stored.
13293(define_insn_and_split "@eh_set_lr_<mode>"
13294  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13295   (clobber (match_scratch:P 1 "=&b"))]
13296  ""
13297  "#"
13298  "reload_completed"
13299  [(const_int 0)]
13300{
13301  rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13302  DONE;
13303})
13304
13305(define_insn "prefetch"
13306  [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13307	     (match_operand:SI 1 "const_int_operand" "n")
13308	     (match_operand:SI 2 "const_int_operand" "n"))]
13309  ""
13310{
13311
13312
13313  /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13314     AIX does not support the dcbtstt and dcbtt extended mnemonics.
13315     The AIX assembler does not support the three operand form of dcbt
13316     and dcbtst on Power 7 (-mpwr7).  */
13317  int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13318
13319  if (REG_P (operands[0]))
13320    {
13321      if (INTVAL (operands[1]) == 0)
13322        return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13323      else
13324        return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13325    }
13326  else
13327    {
13328      if (INTVAL (operands[1]) == 0)
13329        return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13330      else
13331        return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13332    }
13333}
13334  [(set_attr "type" "load")])
13335
13336;; Handle -fsplit-stack.
13337
13338(define_expand "split_stack_prologue"
13339  [(const_int 0)]
13340  ""
13341{
13342  rs6000_expand_split_stack_prologue ();
13343  DONE;
13344})
13345
13346(define_expand "load_split_stack_limit"
13347  [(set (match_operand 0)
13348	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13349  ""
13350{
13351  emit_insn (gen_rtx_SET (operands[0],
13352			  gen_rtx_UNSPEC (Pmode,
13353					  gen_rtvec (1, const0_rtx),
13354					  UNSPEC_STACK_CHECK)));
13355  DONE;
13356})
13357
13358(define_insn "load_split_stack_limit_di"
13359  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13360	(unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13361  "TARGET_64BIT"
13362  "ld %0,-0x7040(13)"
13363  [(set_attr "type" "load")
13364   (set_attr "update" "no")
13365   (set_attr "indexed" "no")])
13366
13367(define_insn "load_split_stack_limit_si"
13368  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13369	(unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13370  "!TARGET_64BIT"
13371  "lwz %0,-0x7020(2)"
13372  [(set_attr "type" "load")
13373   (set_attr "update" "no")
13374   (set_attr "indexed" "no")])
13375
13376;; A return instruction which the middle-end doesn't see.
13377;; Use r0 to stop regrename twiddling with lr restore insns emitted
13378;; after the call to __morestack.
13379(define_insn "split_stack_return"
13380  [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13381  ""
13382  "blr"
13383  [(set_attr "type" "jmpreg")])
13384
13385;; If there are operand 0 bytes available on the stack, jump to
13386;; operand 1.
13387(define_expand "split_stack_space_check"
13388  [(set (match_dup 2)
13389	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13390   (set (match_dup 3)
13391	(minus (reg STACK_POINTER_REGNUM)
13392	       (match_operand 0)))
13393   (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13394   (set (pc) (if_then_else
13395	      (geu (match_dup 4) (const_int 0))
13396	      (label_ref (match_operand 1))
13397	      (pc)))]
13398  ""
13399{
13400  rs6000_split_stack_space_check (operands[0], operands[1]);
13401  DONE;
13402})
13403
13404(define_insn "bpermd_<mode>"
13405  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13406	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13407		   (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13408  "TARGET_POPCNTD"
13409  "bpermd %0,%1,%2"
13410  [(set_attr "type" "popcnt")])
13411
13412
13413;; Builtin fma support.  Handle
13414;; Note that the conditions for expansion are in the FMA_F iterator.
13415
13416(define_expand "fma<mode>4"
13417  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13418	(fma:FMA_F
13419	  (match_operand:FMA_F 1 "gpc_reg_operand")
13420	  (match_operand:FMA_F 2 "gpc_reg_operand")
13421	  (match_operand:FMA_F 3 "gpc_reg_operand")))]
13422  ""
13423  "")
13424
13425(define_insn "*fma<mode>4_fpr"
13426  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13427	(fma:SFDF
13428	  (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13429	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13430	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13431  "TARGET_HARD_FLOAT"
13432  "@
13433   fmadd<s> %0,%1,%2,%3
13434   xsmadda<sd>p %x0,%x1,%x2
13435   xsmaddm<sd>p %x0,%x1,%x3"
13436  [(set_attr "type" "fp")
13437   (set_attr "isa" "*,<Fisa>,<Fisa>")])
13438
13439; Altivec only has fma and nfms.
13440(define_expand "fms<mode>4"
13441  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13442	(fma:FMA_F
13443	  (match_operand:FMA_F 1 "gpc_reg_operand")
13444	  (match_operand:FMA_F 2 "gpc_reg_operand")
13445	  (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13446  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13447  "")
13448
13449(define_insn "*fms<mode>4_fpr"
13450  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13451	(fma:SFDF
13452	 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13453	 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13454	 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13455  "TARGET_HARD_FLOAT"
13456  "@
13457   fmsub<s> %0,%1,%2,%3
13458   xsmsuba<sd>p %x0,%x1,%x2
13459   xsmsubm<sd>p %x0,%x1,%x3"
13460  [(set_attr "type" "fp")
13461   (set_attr "isa" "*,<Fisa>,<Fisa>")])
13462
13463;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13464(define_expand "fnma<mode>4"
13465  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13466	(neg:FMA_F
13467	  (fma:FMA_F
13468	    (match_operand:FMA_F 1 "gpc_reg_operand")
13469	    (match_operand:FMA_F 2 "gpc_reg_operand")
13470	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13471  "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13472  "")
13473
13474;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13475(define_expand "fnms<mode>4"
13476  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13477	(neg:FMA_F
13478	  (fma:FMA_F
13479	    (match_operand:FMA_F 1 "gpc_reg_operand")
13480	    (match_operand:FMA_F 2 "gpc_reg_operand")
13481	    (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13482  "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13483  "")
13484
13485; Not an official optab name, but used from builtins.
13486(define_expand "nfma<mode>4"
13487  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13488	(neg:FMA_F
13489	  (fma:FMA_F
13490	    (match_operand:FMA_F 1 "gpc_reg_operand")
13491	    (match_operand:FMA_F 2 "gpc_reg_operand")
13492	    (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13493  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13494  "")
13495
13496(define_insn "*nfma<mode>4_fpr"
13497  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13498	(neg:SFDF
13499	 (fma:SFDF
13500	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13501	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13502	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13503  "TARGET_HARD_FLOAT"
13504  "@
13505   fnmadd<s> %0,%1,%2,%3
13506   xsnmadda<sd>p %x0,%x1,%x2
13507   xsnmaddm<sd>p %x0,%x1,%x3"
13508  [(set_attr "type" "fp")
13509   (set_attr "isa" "*,<Fisa>,<Fisa>")])
13510
13511; Not an official optab name, but used from builtins.
13512(define_expand "nfms<mode>4"
13513  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13514	(neg:FMA_F
13515	  (fma:FMA_F
13516	    (match_operand:FMA_F 1 "gpc_reg_operand")
13517	    (match_operand:FMA_F 2 "gpc_reg_operand")
13518	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13519  ""
13520  "")
13521
13522(define_insn "*nfmssf4_fpr"
13523  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13524	(neg:SFDF
13525	 (fma:SFDF
13526	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13527	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13528	  (neg:SFDF
13529	   (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13530  "TARGET_HARD_FLOAT"
13531  "@
13532   fnmsub<s> %0,%1,%2,%3
13533   xsnmsuba<sd>p %x0,%x1,%x2
13534   xsnmsubm<sd>p %x0,%x1,%x3"
13535  [(set_attr "type" "fp")
13536   (set_attr "isa" "*,<Fisa>,<Fisa>")])
13537
13538(define_expand "rs6000_get_timebase"
13539  [(use (match_operand:DI 0 "gpc_reg_operand"))]
13540  ""
13541{
13542  if (TARGET_POWERPC64)
13543    emit_insn (gen_rs6000_mftb_di (operands[0]));
13544  else
13545    emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13546  DONE;
13547})
13548
13549(define_insn "rs6000_get_timebase_ppc32"
13550  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13551        (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13552   (clobber (match_scratch:SI 1 "=r"))
13553   (clobber (match_scratch:CC 2 "=y"))]
13554  "!TARGET_POWERPC64"
13555{
13556  if (WORDS_BIG_ENDIAN)
13557    if (TARGET_MFCRF)
13558      {
13559        return "mfspr %0,269\;"
13560	       "mfspr %L0,268\;"
13561	       "mfspr %1,269\;"
13562	       "cmpw %2,%0,%1\;"
13563	       "bne- %2,$-16";
13564      }
13565    else
13566      {
13567        return "mftbu %0\;"
13568	       "mftb %L0\;"
13569	       "mftbu %1\;"
13570	       "cmpw %2,%0,%1\;"
13571	       "bne- %2,$-16";
13572      }
13573  else
13574    if (TARGET_MFCRF)
13575      {
13576        return "mfspr %L0,269\;"
13577	       "mfspr %0,268\;"
13578	       "mfspr %1,269\;"
13579	       "cmpw %2,%L0,%1\;"
13580	       "bne- %2,$-16";
13581      }
13582    else
13583      {
13584        return "mftbu %L0\;"
13585	       "mftb %0\;"
13586	       "mftbu %1\;"
13587	       "cmpw %2,%L0,%1\;"
13588	       "bne- %2,$-16";
13589      }
13590}
13591  [(set_attr "length" "20")])
13592
13593(define_insn "rs6000_mftb_<mode>"
13594  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13595        (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13596  ""
13597{
13598  if (TARGET_MFCRF)
13599    return "mfspr %0,268";
13600  else
13601    return "mftb %0";
13602})
13603
13604
13605;; The ISA 3.0 mffsl instruction is a lower latency instruction
13606;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13607(define_insn "rs6000_mffsl_hw"
13608  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13609        (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13610  "TARGET_HARD_FLOAT"
13611  "mffsl %0")
13612
13613(define_expand "rs6000_mffsl"
13614  [(set (match_operand:DF 0 "gpc_reg_operand")
13615	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13616  "TARGET_HARD_FLOAT"
13617{
13618  /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13619     otherwise fall back to the older mffs instruction to emulate the mffsl
13620     instruction.  */
13621
13622  if (!TARGET_P9_MISC)
13623    {
13624      rtx tmp1 = gen_reg_rtx (DFmode);
13625
13626      /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13627	 instruction using the mffs instruction and masking the result.  */
13628      emit_insn (gen_rs6000_mffs (tmp1));
13629
13630      rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
13631      rtx tmp2 = gen_reg_rtx (DImode);
13632      emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
13633
13634      rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
13635      emit_move_insn (operands[0], tmp2df);
13636      DONE;
13637    }
13638
13639    emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13640    DONE;
13641})
13642
13643(define_insn "rs6000_mffs"
13644  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13645	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13646  "TARGET_HARD_FLOAT"
13647  "mffs %0")
13648
13649(define_insn "rs6000_mtfsf"
13650  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13651		     (match_operand:DF 1 "gpc_reg_operand" "d")]
13652		    UNSPECV_MTFSF)]
13653  "TARGET_HARD_FLOAT"
13654  "mtfsf %0,%1")
13655
13656(define_insn "rs6000_mtfsf_hi"
13657  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13658		     (match_operand:DF 1 "gpc_reg_operand" "d")]
13659		    UNSPECV_MTFSF_HI)]
13660  "TARGET_HARD_FLOAT"
13661  "mtfsf %0,%1,0,1")
13662
13663
13664;; Power8 fusion support for fusing an addis instruction with a D-form load of
13665;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13666;; register that is being loaded.  The fused ops must be physically adjacent.
13667
13668;; On Power8 GPR loads, we try to use the register that is being load.  The
13669;; peephole2 then gathers any other fused possibilities that it can find after
13670;; register allocation.  If power9 fusion is selected, we also fuse floating
13671;; point loads/stores.
13672
13673;; Find cases where the addis that feeds into a load instruction is either used
13674;; once or is the same as the target register, and replace it with the fusion
13675;; insn
13676
13677(define_peephole2
13678  [(set (match_operand:P 0 "base_reg_operand")
13679	(match_operand:P 1 "fusion_gpr_addis"))
13680   (set (match_operand:INT1 2 "base_reg_operand")
13681	(match_operand:INT1 3 "fusion_gpr_mem_load"))]
13682  "TARGET_P8_FUSION
13683   && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13684			 operands[3])"
13685  [(const_int 0)]
13686{
13687  expand_fusion_gpr_load (operands);
13688  DONE;
13689})
13690
13691;; Fusion insn, created by the define_peephole2 above (and eventually by
13692;; reload)
13693
13694(define_insn "*fusion_gpr_load_<mode>"
13695  [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13696	(unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13697		     UNSPEC_FUSION_GPR))]
13698  "TARGET_P8_FUSION"
13699{
13700  return emit_fusion_gpr_load (operands[0], operands[1]);
13701}
13702  [(set_attr "type" "load")
13703   (set_attr "length" "8")])
13704
13705
13706;; Optimize cases where we want to do a D-form load (register+offset) on
13707;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13708;; has generated:
13709;;	LFD 0,32(3)
13710;;	XXLOR 32,0,0
13711;;
13712;; and we change this to:
13713;;	LI 0,32
13714;;	LXSDX 32,3,9
13715
13716(define_peephole2
13717  [(match_scratch:P 0 "b")
13718   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13719	(match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13720   (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13721	(match_dup 1))]
13722  "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13723  [(set (match_dup 0)
13724	(match_dup 4))
13725   (set (match_dup 3)
13726	(match_dup 5))]
13727{
13728  rtx tmp_reg = operands[0];
13729  rtx mem = operands[2];
13730  rtx addr = XEXP (mem, 0);
13731  rtx add_op0, add_op1, new_addr;
13732
13733  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13734  add_op0 = XEXP (addr, 0);
13735  add_op1 = XEXP (addr, 1);
13736  gcc_assert (REG_P (add_op0));
13737  new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13738
13739  operands[4] = add_op1;
13740  operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13741})
13742
13743;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13744;; Altivec register, and the register allocator has generated:
13745;;	XXLOR 0,32,32
13746;;	STFD 0,32(3)
13747;;
13748;; and we change this to:
13749;;	LI 0,32
13750;;	STXSDX 32,3,9
13751
13752(define_peephole2
13753  [(match_scratch:P 0 "b")
13754   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13755	(match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13756   (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13757	(match_dup 1))]
13758  "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13759  [(set (match_dup 0)
13760	(match_dup 4))
13761   (set (match_dup 5)
13762	(match_dup 2))]
13763{
13764  rtx tmp_reg = operands[0];
13765  rtx mem = operands[3];
13766  rtx addr = XEXP (mem, 0);
13767  rtx add_op0, add_op1, new_addr;
13768
13769  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13770  add_op0 = XEXP (addr, 0);
13771  add_op1 = XEXP (addr, 1);
13772  gcc_assert (REG_P (add_op0));
13773  new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13774
13775  operands[4] = add_op1;
13776  operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13777})
13778
13779
13780;; Miscellaneous ISA 2.06 (power7) instructions
13781(define_insn "addg6s"
13782  [(set (match_operand:SI 0 "register_operand" "=r")
13783	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
13784		    (match_operand:SI 2 "register_operand" "r")]
13785		   UNSPEC_ADDG6S))]
13786  "TARGET_POPCNTD"
13787  "addg6s %0,%1,%2"
13788  [(set_attr "type" "integer")])
13789
13790(define_insn "cdtbcd"
13791  [(set (match_operand:SI 0 "register_operand" "=r")
13792	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13793		   UNSPEC_CDTBCD))]
13794  "TARGET_POPCNTD"
13795  "cdtbcd %0,%1"
13796  [(set_attr "type" "integer")])
13797
13798(define_insn "cbcdtd"
13799  [(set (match_operand:SI 0 "register_operand" "=r")
13800	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13801		   UNSPEC_CBCDTD))]
13802  "TARGET_POPCNTD"
13803  "cbcdtd %0,%1"
13804  [(set_attr "type" "integer")])
13805
13806(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13807					UNSPEC_DIVEU])
13808
13809(define_int_attr div_extend [(UNSPEC_DIVE	"e")
13810			     (UNSPEC_DIVEU	"eu")])
13811
13812(define_insn "div<div_extend>_<mode>"
13813  [(set (match_operand:GPR 0 "register_operand" "=r")
13814	(unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13815		     (match_operand:GPR 2 "register_operand" "r")]
13816		    UNSPEC_DIV_EXTEND))]
13817  "TARGET_POPCNTD"
13818  "div<wd><div_extend> %0,%1,%2"
13819  [(set_attr "type" "div")
13820   (set_attr "size" "<bits>")])
13821
13822
13823;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13824
13825; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13826(define_mode_attr FP128_64 [(TF "DF")
13827			    (IF "DF")
13828			    (TD "DI")
13829			    (KF "DI")])
13830
13831(define_expand "unpack<mode>"
13832  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13833	(unspec:<FP128_64>
13834	 [(match_operand:FMOVE128 1 "register_operand")
13835	  (match_operand:QI 2 "const_0_to_1_operand")]
13836	 UNSPEC_UNPACK_128BIT))]
13837  "FLOAT128_2REG_P (<MODE>mode)"
13838  "")
13839
13840(define_insn_and_split "unpack<mode>_dm"
13841  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13842	(unspec:<FP128_64>
13843	 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13844	  (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13845	 UNSPEC_UNPACK_128BIT))]
13846  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13847  "#"
13848  "&& reload_completed"
13849  [(set (match_dup 0) (match_dup 3))]
13850{
13851  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13852
13853  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13854    {
13855      emit_note (NOTE_INSN_DELETED);
13856      DONE;
13857    }
13858
13859  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13860}
13861  [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13862
13863(define_insn_and_split "unpack<mode>_nodm"
13864  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13865	(unspec:<FP128_64>
13866	 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13867	  (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13868	 UNSPEC_UNPACK_128BIT))]
13869  "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13870  "#"
13871  "&& reload_completed"
13872  [(set (match_dup 0) (match_dup 3))]
13873{
13874  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13875
13876  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13877    {
13878      emit_note (NOTE_INSN_DELETED);
13879      DONE;
13880    }
13881
13882  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13883}
13884  [(set_attr "type" "fp,fpstore")])
13885
13886(define_insn_and_split "pack<mode>"
13887  [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13888	(unspec:FMOVE128
13889	 [(match_operand:<FP128_64> 1 "register_operand" "d")
13890	  (match_operand:<FP128_64> 2 "register_operand" "d")]
13891	 UNSPEC_PACK_128BIT))]
13892  "FLOAT128_2REG_P (<MODE>mode)"
13893  "#"
13894  "&& reload_completed"
13895  [(set (match_dup 3) (match_dup 1))
13896   (set (match_dup 4) (match_dup 2))]
13897{
13898  unsigned dest_hi = REGNO (operands[0]);
13899  unsigned dest_lo = dest_hi + 1;
13900
13901  gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13902  gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13903
13904  operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13905  operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13906}
13907  [(set_attr "type" "fp")
13908   (set_attr "length" "8")])
13909
13910(define_insn "unpack<mode>"
13911  [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13912	(unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13913		    (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13914	 UNSPEC_UNPACK_128BIT))]
13915  "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13916{
13917  if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13918    return ASM_COMMENT_START " xxpermdi to same register";
13919
13920  operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13921  return "xxpermdi %x0,%x1,%x1,%3";
13922}
13923  [(set_attr "type" "vecperm")])
13924
13925(define_insn "pack<mode>"
13926  [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13927	(unspec:FMOVE128_VSX
13928	 [(match_operand:DI 1 "register_operand" "wa")
13929	  (match_operand:DI 2 "register_operand" "wa")]
13930	 UNSPEC_PACK_128BIT))]
13931  "TARGET_VSX"
13932  "xxpermdi %x0,%x1,%x2,0"
13933  [(set_attr "type" "vecperm")])
13934
13935
13936
13937;; ISA 2.08 IEEE 128-bit floating point support.
13938
13939(define_insn "add<mode>3"
13940  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13941	(plus:IEEE128
13942	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13943	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13944  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13945  "xsaddqp %0,%1,%2"
13946  [(set_attr "type" "vecfloat")
13947   (set_attr "size" "128")])
13948
13949(define_insn "sub<mode>3"
13950  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13951	(minus:IEEE128
13952	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13953	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13954  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13955  "xssubqp %0,%1,%2"
13956  [(set_attr "type" "vecfloat")
13957   (set_attr "size" "128")])
13958
13959(define_insn "mul<mode>3"
13960  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13961	(mult:IEEE128
13962	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13963	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13964  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13965  "xsmulqp %0,%1,%2"
13966  [(set_attr "type" "qmul")
13967   (set_attr "size" "128")])
13968
13969(define_insn "div<mode>3"
13970  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13971	(div:IEEE128
13972	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13973	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13974  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13975  "xsdivqp %0,%1,%2"
13976  [(set_attr "type" "vecdiv")
13977   (set_attr "size" "128")])
13978
13979(define_insn "sqrt<mode>2"
13980  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13981	(sqrt:IEEE128
13982	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13983  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13984   "xssqrtqp %0,%1"
13985  [(set_attr "type" "vecdiv")
13986   (set_attr "size" "128")])
13987
13988(define_expand "copysign<mode>3"
13989  [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13990   (use (match_operand:IEEE128 1 "altivec_register_operand"))
13991   (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13992  "FLOAT128_IEEE_P (<MODE>mode)"
13993{
13994  if (TARGET_FLOAT128_HW)
13995    emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13996					 operands[2]));
13997  else
13998    emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13999					 operands[2]));
14000  DONE;
14001})
14002
14003(define_insn "copysign<mode>3_hard"
14004  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14005	(unspec:IEEE128
14006	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14007	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14008	 UNSPEC_COPYSIGN))]
14009  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14010   "xscpsgnqp %0,%2,%1"
14011  [(set_attr "type" "vecmove")
14012   (set_attr "size" "128")])
14013
14014(define_insn "copysign<mode>3_soft"
14015  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14016	(unspec:IEEE128
14017	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14018	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14019	 UNSPEC_COPYSIGN))
14020   (clobber (match_scratch:IEEE128 3 "=&v"))]
14021  "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14022   "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14023  [(set_attr "type" "veccomplex")
14024   (set_attr "length" "8")])
14025
14026(define_insn "@neg<mode>2_hw"
14027  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14028	(neg:IEEE128
14029	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14030  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14031  "xsnegqp %0,%1"
14032  [(set_attr "type" "vecmove")
14033   (set_attr "size" "128")])
14034
14035
14036(define_insn "@abs<mode>2_hw"
14037  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14038	(abs:IEEE128
14039	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14040  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14041  "xsabsqp %0,%1"
14042  [(set_attr "type" "vecmove")
14043   (set_attr "size" "128")])
14044
14045
14046(define_insn "*nabs<mode>2_hw"
14047  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14048	(neg:IEEE128
14049	 (abs:IEEE128
14050	  (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14051  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14052  "xsnabsqp %0,%1"
14053  [(set_attr "type" "vecmove")
14054   (set_attr "size" "128")])
14055
14056;; Initially don't worry about doing fusion
14057(define_insn "fma<mode>4_hw"
14058  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14059	(fma:IEEE128
14060	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14061	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14062	 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14063  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14064  "xsmaddqp %0,%1,%2"
14065  [(set_attr "type" "qmul")
14066   (set_attr "size" "128")])
14067
14068(define_insn "*fms<mode>4_hw"
14069  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14070	(fma:IEEE128
14071	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14072	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14073	 (neg:IEEE128
14074	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14075  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14076  "xsmsubqp %0,%1,%2"
14077  [(set_attr "type" "qmul")
14078   (set_attr "size" "128")])
14079
14080(define_insn "*nfma<mode>4_hw"
14081  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14082	(neg:IEEE128
14083	 (fma:IEEE128
14084	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14085	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14086	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14087  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14088  "xsnmaddqp %0,%1,%2"
14089  [(set_attr "type" "qmul")
14090   (set_attr "size" "128")])
14091
14092(define_insn "*nfms<mode>4_hw"
14093  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14094	(neg:IEEE128
14095	 (fma:IEEE128
14096	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14097	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14098	  (neg:IEEE128
14099	   (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14100  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14101  "xsnmsubqp %0,%1,%2"
14102  [(set_attr "type" "qmul")
14103   (set_attr "size" "128")])
14104
14105(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14106  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14107	(float_extend:IEEE128
14108	 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14109  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14110  "xscvdpqp %0,%1"
14111  [(set_attr "type" "vecfloat")
14112   (set_attr "size" "128")])
14113
14114;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14115;; point is a simple copy.
14116(define_insn_and_split "extendkftf2"
14117  [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14118	(float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14119  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14120  "@
14121   #
14122   xxlor %x0,%x1,%x1"
14123  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14124  [(const_int 0)]
14125{
14126  emit_note (NOTE_INSN_DELETED);
14127  DONE;
14128}
14129  [(set_attr "type" "*,veclogical")
14130   (set_attr "length" "0,4")])
14131
14132(define_insn_and_split "trunctfkf2"
14133  [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14134	(float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14135  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14136  "@
14137   #
14138   xxlor %x0,%x1,%x1"
14139  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14140  [(const_int 0)]
14141{
14142  emit_note (NOTE_INSN_DELETED);
14143  DONE;
14144}
14145  [(set_attr "type" "*,veclogical")
14146   (set_attr "length" "0,4")])
14147
14148(define_insn "trunc<mode>df2_hw"
14149  [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14150	(float_truncate:DF
14151	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14152  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14153  "xscvqpdp %0,%1"
14154  [(set_attr "type" "vecfloat")
14155   (set_attr "size" "128")])
14156
14157;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14158;; the KFmode -> DFmode conversion using round to odd rather than the normal
14159;; conversion
14160(define_insn_and_split "trunc<mode>sf2_hw"
14161  [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14162	(float_truncate:SF
14163	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14164   (clobber (match_scratch:DF 2 "=v"))]
14165  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14166  "#"
14167  "&& 1"
14168  [(set (match_dup 2)
14169	(unspec:DF [(match_dup 1)]
14170		   UNSPEC_TRUNC_ROUND_TO_ODD))
14171   (set (match_dup 0)
14172	(float_truncate:SF (match_dup 2)))]
14173{
14174  if (GET_CODE (operands[2]) == SCRATCH)
14175    operands[2] = gen_reg_rtx (DFmode);
14176}
14177  [(set_attr "type" "vecfloat")
14178   (set_attr "length" "8")
14179   (set_attr "isa" "p8v")])
14180
14181;; Conversion between IEEE 128-bit and integer types
14182
14183;; The fix function for DImode and SImode was declared earlier as a
14184;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14185;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14186;; unless we have the IEEE 128-bit hardware.
14187;;
14188;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14189;; to provide a GPR target that used direct move and a conversion in the GPR
14190;; which works around QImode/HImode not being allowed in vector registers in
14191;; ISA 2.07 (power8).
14192(define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14193  [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14194	(any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14195  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14196  "xscvqp<su><wd>z %0,%1"
14197  [(set_attr "type" "vecfloat")
14198   (set_attr "size" "128")])
14199
14200(define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14201  [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14202	(any_fix:QHI
14203	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14204  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14205  "xscvqp<su>wz %0,%1"
14206  [(set_attr "type" "vecfloat")
14207   (set_attr "size" "128")])
14208
14209;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14210;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14211(define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14212  [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14213	(any_fix:QHSI
14214	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14215   (clobber (match_scratch:QHSI 2 "=v"))]
14216  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14217  "#"
14218  "&& reload_completed"
14219  [(set (match_dup 2)
14220	(any_fix:QHSI (match_dup 1)))
14221   (set (match_dup 0)
14222	(match_dup 2))])
14223
14224(define_insn "float_<mode>di2_hw"
14225  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14226	(float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14227  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14228  "xscvsdqp %0,%1"
14229  [(set_attr "type" "vecfloat")
14230   (set_attr "size" "128")])
14231
14232(define_insn_and_split "float_<mode>si2_hw"
14233  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14234	(float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14235   (clobber (match_scratch:DI 2 "=v"))]
14236  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14237  "#"
14238  "&& 1"
14239  [(set (match_dup 2)
14240	(sign_extend:DI (match_dup 1)))
14241   (set (match_dup 0)
14242	(float:IEEE128 (match_dup 2)))]
14243{
14244  if (GET_CODE (operands[2]) == SCRATCH)
14245    operands[2] = gen_reg_rtx (DImode);
14246
14247  if (MEM_P (operands[1]))
14248    operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14249})
14250
14251(define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14252  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14253	(float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14254   (clobber (match_scratch:DI 2 "=X,r,X"))]
14255  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14256  "#"
14257  "&& reload_completed"
14258  [(const_int 0)]
14259{
14260  rtx dest = operands[0];
14261  rtx src = operands[1];
14262  rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14263
14264  if (altivec_register_operand (src, <QHI:MODE>mode))
14265    emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14266  else if (int_reg_operand (src, <QHI:MODE>mode))
14267    {
14268      rtx ext_di = operands[2];
14269      emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14270      emit_move_insn (dest_di, ext_di);
14271    }
14272  else if (MEM_P (src))
14273    {
14274      rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14275      emit_move_insn (dest_qhi, src);
14276      emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14277    }
14278  else
14279    gcc_unreachable ();
14280
14281  emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14282  DONE;
14283}
14284  [(set_attr "length" "8,12,12")
14285   (set_attr "type" "vecfloat")
14286   (set_attr "size" "128")])
14287
14288(define_insn "floatuns_<mode>di2_hw"
14289  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14290	(unsigned_float:IEEE128
14291	 (match_operand:DI 1 "altivec_register_operand" "v")))]
14292  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14293  "xscvudqp %0,%1"
14294  [(set_attr "type" "vecfloat")
14295   (set_attr "size" "128")])
14296
14297(define_insn_and_split "floatuns_<mode>si2_hw"
14298  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14299	(unsigned_float:IEEE128
14300	 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14301   (clobber (match_scratch:DI 2 "=v"))]
14302  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14303  "#"
14304  "&& 1"
14305  [(set (match_dup 2)
14306	(zero_extend:DI (match_dup 1)))
14307   (set (match_dup 0)
14308	(float:IEEE128 (match_dup 2)))]
14309{
14310  if (GET_CODE (operands[2]) == SCRATCH)
14311    operands[2] = gen_reg_rtx (DImode);
14312
14313  if (MEM_P (operands[1]))
14314    operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14315})
14316
14317(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14318  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14319	(unsigned_float:IEEE128
14320	 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14321   (clobber (match_scratch:DI 2 "=X,r,X"))]
14322  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14323  "#"
14324  "&& reload_completed"
14325  [(const_int 0)]
14326{
14327  rtx dest = operands[0];
14328  rtx src = operands[1];
14329  rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14330
14331  if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14332    emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14333  else if (int_reg_operand (src, <QHI:MODE>mode))
14334    {
14335      rtx ext_di = operands[2];
14336      emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14337      emit_move_insn (dest_di, ext_di);
14338    }
14339  else
14340    gcc_unreachable ();
14341
14342  emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14343  DONE;
14344}
14345  [(set_attr "length" "8,12,8")
14346   (set_attr "type" "vecfloat")
14347   (set_attr "size" "128")])
14348
14349;; IEEE 128-bit round to integer built-in functions
14350(define_insn "floor<mode>2"
14351  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14352	(unspec:IEEE128
14353	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14354	 UNSPEC_FRIM))]
14355  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14356  "xsrqpi 1,%0,%1,3"
14357  [(set_attr "type" "vecfloat")
14358   (set_attr "size" "128")])
14359
14360(define_insn "ceil<mode>2"
14361  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14362	(unspec:IEEE128
14363	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14364	 UNSPEC_FRIP))]
14365  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14366  "xsrqpi 1,%0,%1,2"
14367  [(set_attr "type" "vecfloat")
14368   (set_attr "size" "128")])
14369
14370(define_insn "btrunc<mode>2"
14371  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14372	(unspec:IEEE128
14373	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14374	 UNSPEC_FRIZ))]
14375  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14376  "xsrqpi 1,%0,%1,1"
14377  [(set_attr "type" "vecfloat")
14378   (set_attr "size" "128")])
14379
14380(define_insn "round<mode>2"
14381  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14382	(unspec:IEEE128
14383	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14384	 UNSPEC_FRIN))]
14385  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14386  "xsrqpi 0,%0,%1,0"
14387  [(set_attr "type" "vecfloat")
14388   (set_attr "size" "128")])
14389
14390;; IEEE 128-bit instructions with round to odd semantics
14391(define_insn "add<mode>3_odd"
14392  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14393	(unspec:IEEE128
14394	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14395	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14396	 UNSPEC_ADD_ROUND_TO_ODD))]
14397  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14398  "xsaddqpo %0,%1,%2"
14399  [(set_attr "type" "vecfloat")
14400   (set_attr "size" "128")])
14401
14402(define_insn "sub<mode>3_odd"
14403  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14404	(unspec:IEEE128
14405	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14406	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14407	 UNSPEC_SUB_ROUND_TO_ODD))]
14408  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14409  "xssubqpo %0,%1,%2"
14410  [(set_attr "type" "vecfloat")
14411   (set_attr "size" "128")])
14412
14413(define_insn "mul<mode>3_odd"
14414  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14415	(unspec:IEEE128
14416	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14417	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14418	 UNSPEC_MUL_ROUND_TO_ODD))]
14419  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14420  "xsmulqpo %0,%1,%2"
14421  [(set_attr "type" "qmul")
14422   (set_attr "size" "128")])
14423
14424(define_insn "div<mode>3_odd"
14425  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14426	(unspec:IEEE128
14427	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14428	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14429	 UNSPEC_DIV_ROUND_TO_ODD))]
14430  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14431  "xsdivqpo %0,%1,%2"
14432  [(set_attr "type" "vecdiv")
14433   (set_attr "size" "128")])
14434
14435(define_insn "sqrt<mode>2_odd"
14436  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14437	(unspec:IEEE128
14438	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14439	 UNSPEC_SQRT_ROUND_TO_ODD))]
14440  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14441   "xssqrtqpo %0,%1"
14442  [(set_attr "type" "vecdiv")
14443   (set_attr "size" "128")])
14444
14445(define_insn "fma<mode>4_odd"
14446  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14447	(unspec:IEEE128
14448	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14449	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14450	  (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14451	 UNSPEC_FMA_ROUND_TO_ODD))]
14452  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14453  "xsmaddqpo %0,%1,%2"
14454  [(set_attr "type" "qmul")
14455   (set_attr "size" "128")])
14456
14457(define_insn "*fms<mode>4_odd"
14458  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14459	(unspec:IEEE128
14460	 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14461	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14462	  (neg:IEEE128
14463	   (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14464	 UNSPEC_FMA_ROUND_TO_ODD))]
14465  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14466  "xsmsubqpo %0,%1,%2"
14467  [(set_attr "type" "qmul")
14468   (set_attr "size" "128")])
14469
14470(define_insn "*nfma<mode>4_odd"
14471  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14472	(neg:IEEE128
14473	 (unspec:IEEE128
14474	  [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14475	   (match_operand:IEEE128 2 "altivec_register_operand" "v")
14476	   (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14477	  UNSPEC_FMA_ROUND_TO_ODD)))]
14478  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14479  "xsnmaddqpo %0,%1,%2"
14480  [(set_attr "type" "qmul")
14481   (set_attr "size" "128")])
14482
14483(define_insn "*nfms<mode>4_odd"
14484  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14485	(neg:IEEE128
14486	 (unspec:IEEE128
14487	  [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14488	   (match_operand:IEEE128 2 "altivec_register_operand" "v")
14489	   (neg:IEEE128
14490	    (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14491	  UNSPEC_FMA_ROUND_TO_ODD)))]
14492  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14493  "xsnmsubqpo %0,%1,%2"
14494  [(set_attr "type" "qmul")
14495   (set_attr "size" "128")])
14496
14497(define_insn "trunc<mode>df2_odd"
14498  [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14499	(unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14500		   UNSPEC_TRUNC_ROUND_TO_ODD))]
14501  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14502  "xscvqpdpo %0,%1"
14503  [(set_attr "type" "vecfloat")
14504   (set_attr "size" "128")])
14505
14506;; IEEE 128-bit comparisons
14507(define_insn "*cmp<mode>_hw"
14508  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14509	(compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14510		      (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14511  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14512   "xscmpuqp %0,%1,%2"
14513  [(set_attr "type" "veccmp")
14514   (set_attr "size" "128")])
14515
14516;; Miscellaneous ISA 3.0 (power9) instructions
14517
14518(define_insn "darn_32"
14519  [(set (match_operand:SI 0 "register_operand" "=r")
14520        (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14521  "TARGET_P9_MISC"
14522  "darn %0,0"
14523  [(set_attr "type" "integer")])
14524
14525(define_insn "darn_raw"
14526  [(set (match_operand:DI 0 "register_operand" "=r")
14527        (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14528  "TARGET_P9_MISC && TARGET_64BIT"
14529  "darn %0,2"
14530  [(set_attr "type" "integer")])
14531
14532(define_insn "darn"
14533  [(set (match_operand:DI 0 "register_operand" "=r")
14534        (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14535  "TARGET_P9_MISC && TARGET_64BIT"
14536  "darn %0,1"
14537  [(set_attr "type" "integer")])
14538
14539;; Test byte within range.
14540;;
14541;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14542;; represents a byte whose value is ignored in this context and
14543;; vv, the least significant byte, holds the byte value that is to
14544;; be tested for membership within the range specified by operand 2.
14545;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14546;;
14547;; Return in target register operand 0 a value of 1 if lo <= vv and
14548;; vv <= hi.  Otherwise, set register operand 0 to 0.
14549;;
14550;; Though the instructions to which this expansion maps operate on
14551;; 64-bit registers, the current implementation only operates on
14552;; SI-mode operands as the high-order bits provide no information
14553;; that is not already available in the low-order bits.  To avoid the
14554;; costs of data widening operations, future enhancements might allow
14555;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14556(define_expand "cmprb"
14557  [(set (match_dup 3)
14558	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14559		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14560	 UNSPEC_CMPRB))
14561   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14562	(if_then_else:SI (lt (match_dup 3)
14563			     (const_int 0))
14564			 (const_int -1)
14565			 (if_then_else (gt (match_dup 3)
14566					   (const_int 0))
14567				       (const_int 1)
14568				       (const_int 0))))]
14569  "TARGET_P9_MISC"
14570{
14571  operands[3] = gen_reg_rtx (CCmode);
14572})
14573
14574;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14575;; represents a byte whose value is ignored in this context and
14576;; vv, the least significant byte, holds the byte value that is to
14577;; be tested for membership within the range specified by operand 2.
14578;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14579;;
14580;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14581;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
14582;; 3 bits of the target CR register are all set to 0.
14583(define_insn "*cmprb_internal"
14584  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14585	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14586		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14587	 UNSPEC_CMPRB))]
14588  "TARGET_P9_MISC"
14589  "cmprb %0,0,%1,%2"
14590  [(set_attr "type" "logical")])
14591
14592;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14593;; register operand 1 is on.  Otherwise, set operand 0 register to 1
14594;; if the GT bit (0x4) of condition register operand 1 is on.
14595;; Otherwise, set operand 0 to 0.  Note that the result stored into
14596;; register operand 0 is non-zero iff either the LT or GT bits are on
14597;; within condition register operand 1.
14598(define_insn "setb_signed"
14599   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14600	 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14601			      (const_int 0))
14602			  (const_int -1)
14603			  (if_then_else (gt (match_dup 1)
14604					    (const_int 0))
14605					(const_int 1)
14606					(const_int 0))))]
14607  "TARGET_P9_MISC"
14608  "setb %0,%1"
14609  [(set_attr "type" "logical")])
14610
14611(define_insn "setb_unsigned"
14612   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14613	 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14614			      (const_int 0))
14615			  (const_int -1)
14616			  (if_then_else (gtu (match_dup 1)
14617					    (const_int 0))
14618					(const_int 1)
14619					(const_int 0))))]
14620  "TARGET_P9_MISC"
14621  "setb %0,%1"
14622  [(set_attr "type" "logical")])
14623
14624;; Test byte within two ranges.
14625;;
14626;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14627;; represents a byte whose value is ignored in this context and
14628;; vv, the least significant byte, holds the byte value that is to
14629;; be tested for membership within the range specified by operand 2.
14630;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14631;;
14632;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14633;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
14634;; 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 "cmprb2"
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_CMPRB2))
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 ranges specified by operand 2.
14664;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14665;;
14666;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14667;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14668;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
14669;; CR register are all set to 0.
14670(define_insn "*cmprb2_internal"
14671  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14672	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14673		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14674	 UNSPEC_CMPRB2))]
14675  "TARGET_P9_MISC"
14676  "cmprb %0,1,%1,%2"
14677  [(set_attr "type" "logical")])
14678
14679;; Test byte membership within set of 8 bytes.
14680;;
14681;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14682;; represents a byte whose value is ignored in this context and
14683;; vv, the least significant byte, holds the byte value that is to
14684;; be tested for membership within the set specified by operand 2.
14685;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14686;;
14687;; Return in target register operand 0 a value of 1 if vv equals one
14688;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
14689;; register operand 0 to 0.  Note that the 8 byte values held within
14690;; operand 2 need not be unique.
14691;;
14692;; Though the instructions to which this expansion maps operate on
14693;; 64-bit registers, the current implementation requires that operands
14694;; 0 and 1 have mode SI as the high-order bits provide no information
14695;; that is not already available in the low-order bits.  To avoid the
14696;; costs of data widening operations, future enhancements might allow
14697;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14698(define_expand "cmpeqb"
14699  [(set (match_dup 3)
14700	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14701		    (match_operand:DI 2 "gpc_reg_operand" "r")]
14702	 UNSPEC_CMPEQB))
14703   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14704	(if_then_else:SI (lt (match_dup 3)
14705			     (const_int 0))
14706			 (const_int -1)
14707			 (if_then_else (gt (match_dup 3)
14708					   (const_int 0))
14709				       (const_int 1)
14710				       (const_int 0))))]
14711  "TARGET_P9_MISC && TARGET_64BIT"
14712{
14713  operands[3] = gen_reg_rtx (CCmode);
14714})
14715
14716;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14717;; represents a byte whose value is ignored in this context and
14718;; vv, the least significant byte, holds the byte value that is to
14719;; be tested for membership within the set specified by operand 2.
14720;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14721;;
14722;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14723;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
14724;; set the GT bit to zero.  The other 3 bits of the target CR register
14725;; are all set to 0.
14726(define_insn "*cmpeqb_internal"
14727  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14728	 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14729		     (match_operand:DI 2 "gpc_reg_operand" "r")]
14730	  UNSPEC_CMPEQB))]
14731  "TARGET_P9_MISC && TARGET_64BIT"
14732  "cmpeqb %0,%1,%2"
14733  [(set_attr "type" "logical")])
14734
14735
14736(include "sync.md")
14737(include "vector.md")
14738(include "vsx.md")
14739(include "altivec.md")
14740(include "mma.md")
14741(include "dfp.md")
14742(include "crypto.md")
14743(include "htm.md")
14744