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_expand "fmod<mode>3"
4810  [(use (match_operand:SFDF 0 "gpc_reg_operand"))
4811	(use (match_operand:SFDF 1 "gpc_reg_operand"))
4812	(use (match_operand:SFDF 2 "gpc_reg_operand"))]
4813  "TARGET_HARD_FLOAT
4814   && TARGET_FPRND
4815   && flag_unsafe_math_optimizations"
4816{
4817  rtx div = gen_reg_rtx (<MODE>mode);
4818  emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
4819
4820  rtx friz = gen_reg_rtx (<MODE>mode);
4821  emit_insn (gen_btrunc<mode>2 (friz, div));
4822
4823  emit_insn (gen_nfms<mode>4 (operands[0], operands[2], friz, operands[1]));
4824  DONE;
4825 })
4826
4827(define_expand "remainder<mode>3"
4828  [(use (match_operand:SFDF 0 "gpc_reg_operand"))
4829	(use (match_operand:SFDF 1 "gpc_reg_operand"))
4830	(use (match_operand:SFDF 2 "gpc_reg_operand"))]
4831  "TARGET_HARD_FLOAT
4832   && TARGET_FPRND
4833   && flag_unsafe_math_optimizations"
4834{
4835  rtx div = gen_reg_rtx (<MODE>mode);
4836  emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
4837
4838  rtx frin = gen_reg_rtx (<MODE>mode);
4839  emit_insn (gen_round<mode>2 (frin, div));
4840
4841  emit_insn (gen_nfms<mode>4 (operands[0], operands[2], frin, operands[1]));
4842  DONE;
4843 })
4844
4845(define_insn "*rsqrt<mode>2"
4846  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4847	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4848		     UNSPEC_RSQRT))]
4849  "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4850  "@
4851   frsqrte<s> %0,%1
4852   xsrsqrte<sd>p %x0,%x1"
4853  [(set_attr "type" "fp")
4854   (set_attr "isa" "*,<Fisa>")])
4855
4856;; Floating point comparisons
4857(define_insn "*cmp<mode>_fpr"
4858  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4859	(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4860		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4861  "TARGET_HARD_FLOAT"
4862  "@
4863   fcmpu %0,%1,%2
4864   xscmpudp %0,%x1,%x2"
4865  [(set_attr "type" "fpcompare")
4866   (set_attr "isa" "*,<Fisa>")])
4867
4868;; Floating point conversions
4869(define_expand "extendsfdf2"
4870  [(set (match_operand:DF 0 "gpc_reg_operand")
4871	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4872  "TARGET_HARD_FLOAT"
4873{
4874  if (HONOR_SNANS (SFmode))
4875    operands[1] = force_reg (SFmode, operands[1]);
4876})
4877
4878(define_insn_and_split "*extendsfdf2_fpr"
4879  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4880	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4881  "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4882  "@
4883   #
4884   fmr %0,%1
4885   lfs%U1%X1 %0,%1
4886   #
4887   xscpsgndp %x0,%x1,%x1
4888   lxsspx %x0,%y1
4889   lxssp %0,%1"
4890  "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4891  [(const_int 0)]
4892{
4893  emit_note (NOTE_INSN_DELETED);
4894  DONE;
4895}
4896  [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4897   (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4898
4899(define_insn "*extendsfdf2_snan"
4900  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4901	(float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4902  "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4903  "@
4904   frsp %0,%1
4905   xsrsp %x0,%x1"
4906  [(set_attr "type" "fp")
4907   (set_attr "isa" "*,p8v")])
4908
4909(define_expand "truncdfsf2"
4910  [(set (match_operand:SF 0 "gpc_reg_operand")
4911	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4912  "TARGET_HARD_FLOAT"
4913  "")
4914
4915(define_insn "*truncdfsf2_fpr"
4916  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4917	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4918  "TARGET_HARD_FLOAT"
4919  "@
4920   frsp %0,%1
4921   xsrsp %x0,%x1"
4922  [(set_attr "type" "fp")
4923   (set_attr "isa" "*,p8v")])
4924
4925;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4926;; builtins.c and optabs.c that are not correct for IBM long double
4927;; when little-endian.
4928(define_expand "signbit<mode>2"
4929  [(set (match_dup 2)
4930	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4931   (set (match_dup 3)
4932   	(subreg:DI (match_dup 2) 0))
4933   (set (match_dup 4)
4934   	(match_dup 5))
4935   (set (match_operand:SI 0 "gpc_reg_operand")
4936  	(match_dup 6))]
4937  "TARGET_HARD_FLOAT
4938   && (!FLOAT128_IEEE_P (<MODE>mode)
4939       || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4940{
4941  if (FLOAT128_IEEE_P (<MODE>mode))
4942    {
4943      rtx dest = operands[0];
4944      rtx src = operands[1];
4945      rtx tmp = gen_reg_rtx (DImode);
4946      rtx dest_di = gen_lowpart (DImode, dest);
4947
4948      emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4949      emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4950      DONE;
4951    }
4952  operands[2] = gen_reg_rtx (DFmode);
4953  operands[3] = gen_reg_rtx (DImode);
4954  if (TARGET_POWERPC64)
4955    {
4956      operands[4] = gen_reg_rtx (DImode);
4957      operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4958      operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4959				    WORDS_BIG_ENDIAN ? 4 : 0);
4960    }
4961  else
4962    {
4963      operands[4] = gen_reg_rtx (SImode);
4964      operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4965				    WORDS_BIG_ENDIAN ? 0 : 4);
4966      operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4967    }
4968})
4969
4970;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4971;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4972;; register allocator would typically move the entire _Float128 item to GPRs (2
4973;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4974;;
4975;; After register allocation, if the _Float128 had originally been in GPRs, the
4976;; split allows the post reload phases to eliminate the move, and do the shift
4977;; directly with the register that contains the signbit.
4978(define_insn_and_split "@signbit<mode>2_dm"
4979  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4980	(unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4981		   UNSPEC_SIGNBIT))]
4982  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4983  "@
4984   mfvsrd %0,%x1
4985   #"
4986  "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4987  [(set (match_dup 0)
4988	(match_dup 2))]
4989{
4990  operands[2] = gen_highpart (DImode, operands[1]);
4991}
4992 [(set_attr "type" "mftgpr,*")])
4993
4994;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4995;; register and then doing a direct move if the value comes from memory.  On
4996;; little endian, we have to load the 2nd double-word to get the sign bit.
4997(define_insn_and_split "*signbit<mode>2_dm_mem"
4998  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4999	(unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5000		   UNSPEC_SIGNBIT))]
5001  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5002  "#"
5003  "&& 1"
5004  [(set (match_dup 0)
5005	(match_dup 2))]
5006{
5007  rtx dest = operands[0];
5008  rtx src = operands[1];
5009  rtx addr = XEXP (src, 0);
5010
5011  if (WORDS_BIG_ENDIAN)
5012    operands[2] = adjust_address (src, DImode, 0);
5013
5014  else if (REG_P (addr) || SUBREG_P (addr))
5015    operands[2] = adjust_address (src, DImode, 8);
5016
5017  else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5018	   && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5019    operands[2] = adjust_address (src, DImode, 8);
5020
5021  else
5022    {
5023      rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5024      emit_insn (gen_rtx_SET (tmp, addr));
5025      operands[2] = change_address (src, DImode,
5026				    gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5027    }
5028})
5029
5030(define_expand "copysign<mode>3"
5031  [(set (match_dup 3)
5032        (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5033   (set (match_dup 4)
5034	(neg:SFDF (abs:SFDF (match_dup 1))))
5035   (set (match_operand:SFDF 0 "gpc_reg_operand")
5036        (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5037			       (match_dup 5))
5038			 (match_dup 3)
5039			 (match_dup 4)))]
5040  "TARGET_HARD_FLOAT
5041   && ((TARGET_PPC_GFXOPT
5042        && !HONOR_NANS (<MODE>mode)
5043        && !HONOR_SIGNED_ZEROS (<MODE>mode))
5044       || TARGET_CMPB
5045       || VECTOR_UNIT_VSX_P (<MODE>mode))"
5046{
5047  if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5048    {
5049      emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5050					     operands[2]));
5051      DONE;
5052    }
5053
5054   operands[3] = gen_reg_rtx (<MODE>mode);
5055   operands[4] = gen_reg_rtx (<MODE>mode);
5056   operands[5] = CONST0_RTX (<MODE>mode);
5057  })
5058
5059;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5060;; compiler from optimizing -0.0
5061(define_insn "copysign<mode>3_fcpsgn"
5062  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5063	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5064		      (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5065		     UNSPEC_COPYSIGN))]
5066  "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5067  "@
5068   fcpsgn %0,%2,%1
5069   xscpsgndp %x0,%x2,%x1"
5070  [(set_attr "type" "fpsimple")])
5071
5072;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5073;; fsel instruction and some auxiliary computations.  Then we just have a
5074;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5075;; combine.
5076;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5077;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5078;; computations.  Then we just have a single DEFINE_INSN for fsel and the
5079;; define_splits to make them if made by combine.  On VSX machines we have the
5080;; min/max instructions.
5081;;
5082;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5083;; to allow either DF/SF to use only traditional registers.
5084
5085(define_expand "s<minmax><mode>3"
5086  [(set (match_operand:SFDF 0 "gpc_reg_operand")
5087	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5088			(match_operand:SFDF 2 "gpc_reg_operand")))]
5089  "TARGET_MINMAX"
5090{
5091  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5092  DONE;
5093})
5094
5095(define_insn "*s<minmax><mode>3_vsx"
5096  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5097	(fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5098			(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5099  "TARGET_VSX && TARGET_HARD_FLOAT"
5100{
5101  return (TARGET_P9_MINMAX
5102	  ? "xs<minmax>cdp %x0,%x1,%x2"
5103	  : "xs<minmax>dp %x0,%x1,%x2");
5104}
5105  [(set_attr "type" "fp")])
5106
5107;; The conditional move instructions allow us to perform max and min operations
5108;; even when we don't have the appropriate max/min instruction using the FSEL
5109;; instruction.
5110
5111(define_insn_and_split "*s<minmax><mode>3_fpr"
5112  [(set (match_operand:SFDF 0 "gpc_reg_operand")
5113	(fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5114			(match_operand:SFDF 2 "gpc_reg_operand")))]
5115  "!TARGET_VSX && TARGET_MINMAX"
5116  "#"
5117  "&& 1"
5118  [(const_int 0)]
5119{
5120  rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5121  DONE;
5122})
5123
5124(define_expand "mov<mode>cc"
5125   [(set (match_operand:GPR 0 "gpc_reg_operand")
5126	 (if_then_else:GPR (match_operand 1 "comparison_operator")
5127			   (match_operand:GPR 2 "gpc_reg_operand")
5128			   (match_operand:GPR 3 "gpc_reg_operand")))]
5129  "TARGET_ISEL"
5130{
5131  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5132    DONE;
5133  else
5134    FAIL;
5135})
5136
5137;; We use the BASE_REGS for the isel input operands because, if rA is
5138;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5139;; because we may switch the operands and rB may end up being rA.
5140;;
5141;; We need 2 patterns: an unsigned and a signed pattern.  We could
5142;; leave out the mode in operand 4 and use one pattern, but reload can
5143;; change the mode underneath our feet and then gets confused trying
5144;; to reload the value.
5145(define_mode_iterator CCEITHER [CC CCUNS])
5146(define_mode_attr un [(CC "") (CCUNS "un")])
5147(define_insn "isel_<un>signed_<GPR:mode>"
5148  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5149	(if_then_else:GPR
5150	 (match_operator 1 "scc_comparison_operator"
5151			 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5152			  (const_int 0)])
5153	 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5154	 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5155  "TARGET_ISEL"
5156  "isel %0,%2,%3,%j1"
5157  [(set_attr "type" "isel")])
5158
5159;; These patterns can be useful for combine; they let combine know that
5160;; isel can handle reversed comparisons so long as the operands are
5161;; registers.
5162
5163(define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5164  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5165	(if_then_else:GPR
5166	 (match_operator 1 "scc_rev_comparison_operator"
5167			 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5168			  (const_int 0)])
5169	 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5170	 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5171  "TARGET_ISEL"
5172{
5173  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5174  return "isel %0,%3,%2,%j1";
5175}
5176  [(set_attr "type" "isel")])
5177
5178;; Floating point conditional move
5179(define_expand "mov<mode>cc"
5180   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5181	 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5182			    (match_operand:SFDF 2 "gpc_reg_operand")
5183			    (match_operand:SFDF 3 "gpc_reg_operand")))]
5184  "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5185{
5186  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5187    DONE;
5188  else
5189    FAIL;
5190})
5191
5192(define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5193  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5194	(if_then_else:SFDF
5195	 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5196	     (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5197	 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5198	 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5199  "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5200  "fsel %0,%1,%2,%3"
5201  [(set_attr "type" "fp")])
5202
5203(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5204  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5205	(if_then_else:SFDF
5206	 (match_operator:CCFP 1 "fpmask_comparison_operator"
5207		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5208		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5209	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5210	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5211   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5212  "TARGET_P9_MINMAX"
5213  "#"
5214  ""
5215  [(set (match_dup 6)
5216	(if_then_else:V2DI (match_dup 1)
5217			   (match_dup 7)
5218			   (match_dup 8)))
5219   (set (match_dup 0)
5220	(if_then_else:SFDF (ne (match_dup 6)
5221			       (match_dup 8))
5222			   (match_dup 4)
5223			   (match_dup 5)))]
5224{
5225  if (GET_CODE (operands[6]) == SCRATCH)
5226    operands[6] = gen_reg_rtx (V2DImode);
5227
5228  operands[7] = CONSTM1_RTX (V2DImode);
5229  operands[8] = CONST0_RTX (V2DImode);
5230}
5231 [(set_attr "length" "8")
5232  (set_attr "type" "vecperm")])
5233
5234;; Handle inverting the fpmask comparisons.
5235(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5236  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5237	(if_then_else:SFDF
5238	 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5239		[(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5240		 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5241	 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5242	 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5243   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5244  "TARGET_P9_MINMAX"
5245  "#"
5246  "&& 1"
5247  [(set (match_dup 6)
5248	(if_then_else:V2DI (match_dup 9)
5249			   (match_dup 7)
5250			   (match_dup 8)))
5251   (set (match_dup 0)
5252	(if_then_else:SFDF (ne (match_dup 6)
5253			       (match_dup 8))
5254			   (match_dup 5)
5255			   (match_dup 4)))]
5256{
5257  rtx op1 = operands[1];
5258  enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5259
5260  if (GET_CODE (operands[6]) == SCRATCH)
5261    operands[6] = gen_reg_rtx (V2DImode);
5262
5263  operands[7] = CONSTM1_RTX (V2DImode);
5264  operands[8] = CONST0_RTX (V2DImode);
5265
5266  operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5267}
5268 [(set_attr "length" "8")
5269  (set_attr "type" "vecperm")])
5270
5271(define_insn "*fpmask<mode>"
5272  [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5273	(if_then_else:V2DI
5274	 (match_operator:CCFP 1 "fpmask_comparison_operator"
5275		[(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5276		 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5277	 (match_operand:V2DI 4 "all_ones_constant" "")
5278	 (match_operand:V2DI 5 "zero_constant" "")))]
5279  "TARGET_P9_MINMAX"
5280  "xscmp%V1dp %x0,%x2,%x3"
5281  [(set_attr "type" "fpcompare")])
5282
5283(define_insn "*xxsel<mode>"
5284  [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5285	(if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5286			       (match_operand:V2DI 2 "zero_constant" ""))
5287			   (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5288			   (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5289  "TARGET_P9_MINMAX"
5290  "xxsel %x0,%x4,%x3,%x1"
5291  [(set_attr "type" "vecmove")])
5292
5293
5294;; Conversions to and from floating-point.
5295
5296; We don't define lfiwax/lfiwzx with the normal definition, because we
5297; don't want to support putting SImode in FPR registers.
5298(define_insn "lfiwax"
5299  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5300	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5301		   UNSPEC_LFIWAX))]
5302  "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5303  "@
5304   lfiwax %0,%y1
5305   lxsiwax %x0,%y1
5306   mtvsrwa %x0,%1
5307   vextsw2d %0,%1"
5308  [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5309   (set_attr "isa" "*,p8v,p8v,p9v")])
5310
5311; This split must be run before register allocation because it allocates the
5312; memory slot that is needed to move values to/from the FPR.  We don't allocate
5313; it earlier to allow for the combiner to merge insns together where it might
5314; not be needed and also in case the insns are deleted as dead code.
5315
5316(define_insn_and_split "floatsi<mode>2_lfiwax"
5317  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5318	(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5319   (clobber (match_scratch:DI 2 "=d,wa"))]
5320  "TARGET_HARD_FLOAT && TARGET_LFIWAX
5321   && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5322  "#"
5323  ""
5324  [(pc)]
5325{
5326  rtx dest = operands[0];
5327  rtx src = operands[1];
5328  rtx tmp;
5329
5330  if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5331    tmp = convert_to_mode (DImode, src, false);
5332  else
5333    {
5334      tmp = operands[2];
5335      if (GET_CODE (tmp) == SCRATCH)
5336	tmp = gen_reg_rtx (DImode);
5337      if (MEM_P (src))
5338	{
5339	  src = rs6000_force_indexed_or_indirect_mem (src);
5340	  emit_insn (gen_lfiwax (tmp, src));
5341	}
5342      else
5343	{
5344	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5345	  emit_move_insn (stack, src);
5346	  emit_insn (gen_lfiwax (tmp, stack));
5347	}
5348    }
5349  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5350  DONE;
5351}
5352  [(set_attr "length" "12")
5353   (set_attr "type" "fpload")])
5354
5355(define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5356  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5357	(float:SFDF
5358	 (sign_extend:DI
5359	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5360   (clobber (match_scratch:DI 2 "=d,wa"))]
5361  "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5362  "#"
5363  ""
5364  [(pc)]
5365{
5366  operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5367  if (GET_CODE (operands[2]) == SCRATCH)
5368    operands[2] = gen_reg_rtx (DImode);
5369  if (TARGET_P8_VECTOR)
5370    emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5371  else
5372    emit_insn (gen_lfiwax (operands[2], operands[1]));
5373  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5374  DONE;
5375}
5376  [(set_attr "length" "8")
5377   (set_attr "type" "fpload")])
5378
5379(define_insn "lfiwzx"
5380  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5381	(unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5382		   UNSPEC_LFIWZX))]
5383  "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5384  "@
5385   lfiwzx %0,%y1
5386   lxsiwzx %x0,%y1
5387   mtvsrwz %x0,%1
5388   xxextractuw %x0,%x1,4"
5389  [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5390   (set_attr "isa" "*,p8v,p8v,p9v")])
5391
5392(define_insn_and_split "floatunssi<mode>2_lfiwzx"
5393  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5394	(unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5395   (clobber (match_scratch:DI 2 "=d,wa"))]
5396  "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5397  "#"
5398  ""
5399  [(pc)]
5400{
5401  rtx dest = operands[0];
5402  rtx src = operands[1];
5403  rtx tmp;
5404
5405  if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5406    tmp = convert_to_mode (DImode, src, true);
5407  else
5408    {
5409      tmp = operands[2];
5410      if (GET_CODE (tmp) == SCRATCH)
5411	tmp = gen_reg_rtx (DImode);
5412      if (MEM_P (src))
5413	{
5414	  src = rs6000_force_indexed_or_indirect_mem (src);
5415	  emit_insn (gen_lfiwzx (tmp, src));
5416	}
5417      else
5418	{
5419	  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5420	  emit_move_insn (stack, src);
5421	  emit_insn (gen_lfiwzx (tmp, stack));
5422	}
5423    }
5424  emit_insn (gen_floatdi<mode>2 (dest, tmp));
5425  DONE;
5426}
5427  [(set_attr "length" "12")
5428   (set_attr "type" "fpload")])
5429
5430(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5431  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5432	(unsigned_float:SFDF
5433	 (zero_extend:DI
5434	  (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5435   (clobber (match_scratch:DI 2 "=d,wa"))]
5436  "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5437  "#"
5438  ""
5439  [(pc)]
5440{
5441  operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5442  if (GET_CODE (operands[2]) == SCRATCH)
5443    operands[2] = gen_reg_rtx (DImode);
5444  if (TARGET_P8_VECTOR)
5445    emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5446  else
5447    emit_insn (gen_lfiwzx (operands[2], operands[1]));
5448  emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5449  DONE;
5450}
5451  [(set_attr "length" "8")
5452   (set_attr "type" "fpload")])
5453
5454; For each of these conversions, there is a define_expand, a define_insn
5455; with a '#' template, and a define_split (with C code).  The idea is
5456; to allow constant folding with the template of the define_insn,
5457; then to have the insns split later (between sched1 and final).
5458
5459(define_expand "floatsidf2"
5460  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5461		   (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5462	      (use (match_dup 2))
5463	      (use (match_dup 3))
5464	      (clobber (match_dup 4))
5465	      (clobber (match_dup 5))
5466	      (clobber (match_dup 6))])]
5467  "TARGET_HARD_FLOAT"
5468{
5469  if (TARGET_LFIWAX && TARGET_FCFID)
5470    {
5471      emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5472      DONE;
5473    }
5474  else if (TARGET_FCFID)
5475    {
5476      rtx dreg = operands[1];
5477      if (!REG_P (dreg))
5478	dreg = force_reg (SImode, dreg);
5479      dreg = convert_to_mode (DImode, dreg, false);
5480      emit_insn (gen_floatdidf2 (operands[0], dreg));
5481      DONE;
5482    }
5483
5484  if (!REG_P (operands[1]))
5485    operands[1] = force_reg (SImode, operands[1]);
5486  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5487  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5488  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5489  operands[5] = gen_reg_rtx (DFmode);
5490  operands[6] = gen_reg_rtx (SImode);
5491})
5492
5493(define_insn_and_split "*floatsidf2_internal"
5494  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5495	(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5496   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5497   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5498   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5499   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5500   (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5501  "!TARGET_FCFID && TARGET_HARD_FLOAT"
5502  "#"
5503  ""
5504  [(pc)]
5505{
5506  rtx lowword, highword;
5507  gcc_assert (MEM_P (operands[4]));
5508  highword = adjust_address (operands[4], SImode, 0);
5509  lowword = adjust_address (operands[4], SImode, 4);
5510  if (! WORDS_BIG_ENDIAN)
5511    std::swap (lowword, highword);
5512
5513  emit_insn (gen_xorsi3 (operands[6], operands[1],
5514			 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5515  emit_move_insn (lowword, operands[6]);
5516  emit_move_insn (highword, operands[2]);
5517  emit_move_insn (operands[5], operands[4]);
5518  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5519  DONE;
5520}
5521  [(set_attr "length" "24")
5522   (set_attr "type" "fp")])
5523
5524;; If we don't have a direct conversion to single precision, don't enable this
5525;; conversion for 32-bit without fast math, because we don't have the insn to
5526;; generate the fixup swizzle to avoid double rounding problems.
5527(define_expand "floatunssisf2"
5528  [(set (match_operand:SF 0 "gpc_reg_operand")
5529        (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5530  "TARGET_HARD_FLOAT
5531   && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5532       || (TARGET_FCFID
5533	   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5534{
5535  if (TARGET_LFIWZX && TARGET_FCFIDUS)
5536    {
5537      emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5538      DONE;
5539    }
5540  else
5541    {
5542      rtx dreg = operands[1];
5543      if (!REG_P (dreg))
5544	dreg = force_reg (SImode, dreg);
5545      dreg = convert_to_mode (DImode, dreg, true);
5546      emit_insn (gen_floatdisf2 (operands[0], dreg));
5547      DONE;
5548    }
5549})
5550
5551(define_expand "floatunssidf2"
5552  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5553		   (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5554	      (use (match_dup 2))
5555	      (use (match_dup 3))
5556	      (clobber (match_dup 4))
5557	      (clobber (match_dup 5))])]
5558  "TARGET_HARD_FLOAT"
5559{
5560  if (TARGET_LFIWZX && TARGET_FCFID)
5561    {
5562      emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5563      DONE;
5564    }
5565  else if (TARGET_FCFID)
5566    {
5567      rtx dreg = operands[1];
5568      if (!REG_P (dreg))
5569	dreg = force_reg (SImode, dreg);
5570      dreg = convert_to_mode (DImode, dreg, true);
5571      emit_insn (gen_floatdidf2 (operands[0], dreg));
5572      DONE;
5573    }
5574
5575  if (!REG_P (operands[1]))
5576    operands[1] = force_reg (SImode, operands[1]);
5577  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5578  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5579  operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5580  operands[5] = gen_reg_rtx (DFmode);
5581})
5582
5583(define_insn_and_split "*floatunssidf2_internal"
5584  [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5585	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5586   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5587   (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5588   (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5589   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5590  "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5591   && !(TARGET_FCFID && TARGET_POWERPC64)"
5592  "#"
5593  ""
5594  [(pc)]
5595{
5596  rtx lowword, highword;
5597  gcc_assert (MEM_P (operands[4]));
5598  highword = adjust_address (operands[4], SImode, 0);
5599  lowword = adjust_address (operands[4], SImode, 4);
5600  if (! WORDS_BIG_ENDIAN)
5601    std::swap (lowword, highword);
5602
5603  emit_move_insn (lowword, operands[1]);
5604  emit_move_insn (highword, operands[2]);
5605  emit_move_insn (operands[5], operands[4]);
5606  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5607  DONE;
5608}
5609  [(set_attr "length" "20")
5610   (set_attr "type" "fp")])
5611
5612;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5613;; vector registers.  These insns favor doing the sign/zero extension in
5614;; the vector registers, rather then loading up a GPR, doing a sign/zero
5615;; extension and then a direct move.
5616
5617(define_expand "float<QHI:mode><FP_ISA3:mode>2"
5618  [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5619		   (float:FP_ISA3
5620		    (match_operand:QHI 1 "input_operand")))
5621	      (clobber (match_scratch:DI 2))
5622	      (clobber (match_scratch:DI 3))
5623	      (clobber (match_scratch:<QHI:MODE> 4))])]
5624  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5625{
5626  if (MEM_P (operands[1]))
5627    operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5628})
5629
5630(define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5631  [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5632	(float:FP_ISA3
5633	 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5634   (clobber (match_scratch:DI 2 "=v,wa,v"))
5635   (clobber (match_scratch:DI 3 "=X,r,X"))
5636   (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5637  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5638  "#"
5639  "&& reload_completed"
5640  [(const_int 0)]
5641{
5642  rtx result = operands[0];
5643  rtx input = operands[1];
5644  rtx di = operands[2];
5645
5646  if (!MEM_P (input))
5647    {
5648      rtx tmp = operands[3];
5649      if (altivec_register_operand (input, <QHI:MODE>mode))
5650	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5651      else if (GET_CODE (tmp) == SCRATCH)
5652	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5653      else
5654	{
5655	  emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5656	  emit_move_insn (di, tmp);
5657	}
5658    }
5659  else
5660    {
5661      rtx tmp = operands[4];
5662      emit_move_insn (tmp, input);
5663      emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5664    }
5665
5666  emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5667  DONE;
5668}
5669  [(set_attr "isa" "p9v,*,p9v")])
5670
5671(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5672  [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5673		   (unsigned_float:FP_ISA3
5674		    (match_operand:QHI 1 "input_operand")))
5675	      (clobber (match_scratch:DI 2))
5676	      (clobber (match_scratch:DI 3))])]
5677  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5678{
5679  if (MEM_P (operands[1]))
5680    operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5681})
5682
5683(define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5684  [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5685	(unsigned_float:FP_ISA3
5686	 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5687   (clobber (match_scratch:DI 2 "=v,wa,wa"))
5688   (clobber (match_scratch:DI 3 "=X,r,X"))]
5689  "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5690  "#"
5691  "&& reload_completed"
5692  [(const_int 0)]
5693{
5694  rtx result = operands[0];
5695  rtx input = operands[1];
5696  rtx di = operands[2];
5697
5698  if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5699    emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5700  else
5701    {
5702      rtx tmp = operands[3];
5703      if (GET_CODE (tmp) == SCRATCH)
5704	emit_insn (gen_extend<QHI:mode>di2 (di, input));
5705      else
5706	{
5707	  emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5708	  emit_move_insn (di, tmp);
5709	}
5710    }
5711
5712  emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5713  DONE;
5714}
5715  [(set_attr "isa" "p9v,*,p9v")])
5716
5717(define_expand "fix_trunc<mode>si2"
5718  [(set (match_operand:SI 0 "gpc_reg_operand")
5719	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5720  "TARGET_HARD_FLOAT"
5721{
5722  if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5723    {
5724      rtx src = force_reg (<MODE>mode, operands[1]);
5725
5726      if (TARGET_STFIWX)
5727	emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5728      else
5729	{
5730	  rtx tmp = gen_reg_rtx (DImode);
5731	  rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5732	  emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5733						      tmp, stack));
5734	}
5735      DONE;
5736    }
5737})
5738
5739; Like the convert to float patterns, this insn must be split before
5740; register allocation so that it can allocate the memory slot if it
5741; needed
5742(define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5743  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5744	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5745   (clobber (match_scratch:DI 2 "=d"))]
5746  "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5747   && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5748  "#"
5749  ""
5750  [(pc)]
5751{
5752  rtx dest = operands[0];
5753  rtx src = operands[1];
5754  rtx tmp = operands[2];
5755
5756  if (GET_CODE (tmp) == SCRATCH)
5757    tmp = gen_reg_rtx (DImode);
5758
5759  emit_insn (gen_fctiwz_<mode> (tmp, src));
5760  if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5761    {
5762      dest = rs6000_force_indexed_or_indirect_mem (dest);
5763      emit_insn (gen_stfiwx (dest, tmp));
5764      DONE;
5765    }
5766  else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5767    {
5768      dest = gen_lowpart (DImode, dest);
5769      emit_move_insn (dest, tmp);
5770      DONE;
5771    }
5772  else
5773    {
5774      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5775      emit_insn (gen_stfiwx (stack, tmp));
5776      emit_move_insn (dest, stack);
5777      DONE;
5778    }
5779}
5780  [(set_attr "length" "12")
5781   (set_attr "type" "fp")])
5782
5783(define_insn_and_split "fix_trunc<mode>si2_internal"
5784  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5785	(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5786   (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5787   (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5788  "TARGET_HARD_FLOAT
5789   && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5790  "#"
5791  ""
5792  [(pc)]
5793{
5794  rtx lowword;
5795  gcc_assert (MEM_P (operands[3]));
5796  lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5797
5798  emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5799  emit_move_insn (operands[3], operands[2]);
5800  emit_move_insn (operands[0], lowword);
5801  DONE;
5802}
5803  [(set_attr "length" "16")
5804   (set_attr "type" "fp")])
5805
5806(define_expand "fix_trunc<mode>di2"
5807  [(set (match_operand:DI 0 "gpc_reg_operand")
5808	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5809  "TARGET_HARD_FLOAT && TARGET_FCFID"
5810  "")
5811
5812(define_insn "*fix_trunc<mode>di2_fctidz"
5813  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5814	(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5815  "TARGET_HARD_FLOAT && TARGET_FCFID"
5816  "@
5817   fctidz %0,%1
5818   xscvdpsxds %x0,%x1"
5819  [(set_attr "type" "fp")])
5820
5821;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5822;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5823;; vector registers, so we need to do direct moves to the GPRs, but SImode
5824;; values can go in VSX registers.  Keeping the direct move part through
5825;; register allocation prevents the register allocator from doing a direct move
5826;; of the SImode value to a GPR, and then a store/load.
5827(define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5828  [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5829	(any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5830   (clobber (match_scratch:SI 2 "=X,X,wa"))]
5831  "TARGET_DIRECT_MOVE"
5832  "@
5833   fctiw<u>z %0,%1
5834   xscvdp<su>xws %x0,%x1
5835   #"
5836  "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5837  [(set (match_dup 2)
5838	(any_fix:SI (match_dup 1)))
5839   (set (match_dup 3)
5840	(match_dup 2))]
5841{
5842  operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5843}
5844  [(set_attr "type" "fp")
5845   (set_attr "length" "4,4,8")
5846   (set_attr "isa" "p9v,p9v,*")])
5847
5848(define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5849  [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5850	(any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5851  "TARGET_DIRECT_MOVE"
5852  "@
5853   fctiw<u>z %0,%1
5854   xscvdp<su>xws %x0,%x1"
5855  [(set_attr "type" "fp")])
5856
5857;; Keep the convert and store together through register allocation to prevent
5858;; the register allocator from getting clever and doing a direct move to a GPR
5859;; and then store for reg+offset stores.
5860(define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5861  [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5862	(any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5863   (clobber (match_scratch:SI 2 "=wa"))]
5864    "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5865  "#"
5866  "&& reload_completed"
5867  [(set (match_dup 2)
5868	(any_fix:SI (match_dup 1)))
5869   (set (match_dup 0)
5870	(match_dup 3))]
5871{
5872  operands[3] = (<QHSI:MODE>mode == SImode
5873		 ? operands[2]
5874		 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5875})
5876
5877(define_expand "fixuns_trunc<mode>si2"
5878  [(set (match_operand:SI 0 "gpc_reg_operand")
5879	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5880  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5881{
5882  if (!TARGET_P8_VECTOR)
5883    {
5884      emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5885      DONE;
5886    }
5887})
5888
5889(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5890  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5891	(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5892   (clobber (match_scratch:DI 2 "=d"))]
5893  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5894   && TARGET_STFIWX && can_create_pseudo_p ()
5895   && !TARGET_P8_VECTOR"
5896  "#"
5897  ""
5898  [(pc)]
5899{
5900  rtx dest = operands[0];
5901  rtx src = operands[1];
5902  rtx tmp = operands[2];
5903
5904  if (GET_CODE (tmp) == SCRATCH)
5905    tmp = gen_reg_rtx (DImode);
5906
5907  emit_insn (gen_fctiwuz_<mode> (tmp, src));
5908  if (MEM_P (dest))
5909    {
5910      dest = rs6000_force_indexed_or_indirect_mem (dest);
5911      emit_insn (gen_stfiwx (dest, tmp));
5912      DONE;
5913    }
5914  else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5915    {
5916      dest = gen_lowpart (DImode, dest);
5917      emit_move_insn (dest, tmp);
5918      DONE;
5919    }
5920  else
5921    {
5922      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5923      emit_insn (gen_stfiwx (stack, tmp));
5924      emit_move_insn (dest, stack);
5925      DONE;
5926    }
5927}
5928  [(set_attr "length" "12")
5929   (set_attr "type" "fp")])
5930
5931(define_insn "fixuns_trunc<mode>di2"
5932  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5933	(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5934  "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5935  "@
5936   fctiduz %0,%1
5937   xscvdpuxds %x0,%x1"
5938  [(set_attr "type" "fp")])
5939
5940(define_insn "rs6000_mtfsb0"
5941  [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5942		    UNSPECV_MTFSB0)]
5943  "TARGET_HARD_FLOAT"
5944  "mtfsb0 %0"
5945  [(set_attr "type" "fp")])
5946
5947(define_insn "rs6000_mtfsb1"
5948  [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5949		    UNSPECV_MTFSB1)]
5950  "TARGET_HARD_FLOAT"
5951  "mtfsb1 %0"
5952  [(set_attr "type" "fp")])
5953
5954(define_insn "rs6000_mffscrn"
5955  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5956	(unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5957			    UNSPECV_MFFSCRN))]
5958   "TARGET_P9_MISC"
5959   "mffscrn %0,%1"
5960  [(set_attr "type" "fp")])
5961
5962(define_insn "rs6000_mffscdrn"
5963  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5964   (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5965   (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5966  "TARGET_P9_MISC"
5967  "mffscdrn %0,%1"
5968  [(set_attr "type" "fp")])
5969
5970(define_expand "rs6000_set_fpscr_rn"
5971 [(match_operand:DI 0 "reg_or_cint_operand")]
5972  "TARGET_HARD_FLOAT"
5973{
5974  rtx tmp_df = gen_reg_rtx (DFmode);
5975
5976  /* The floating point rounding control bits are FPSCR[62:63]. Put the
5977     new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5978  if (TARGET_P9_MISC)
5979    {
5980      rtx src_df = force_reg (DImode, operands[0]);
5981      src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5982      emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5983      DONE;
5984    }
5985
5986  if (CONST_INT_P (operands[0]))
5987    {
5988      if ((INTVAL (operands[0]) & 0x1) == 0x1)
5989	emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5990      else
5991	emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5992
5993      if ((INTVAL (operands[0]) & 0x2) == 0x2)
5994	emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5995      else
5996	emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5997    }
5998  else
5999    {
6000      rtx tmp_rn = gen_reg_rtx (DImode);
6001      rtx tmp_di = gen_reg_rtx (DImode);
6002
6003      /* Extract new RN mode from operand.  */
6004      emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
6005
6006      /* Insert new RN mode into FSCPR.  */
6007      emit_insn (gen_rs6000_mffs (tmp_df));
6008      tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6009      emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
6010      emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6011
6012      /* Need to write to field k=15.  The fields are [0:15].  Hence with
6013	 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
6014	 8-bit field[0:7]. Need to set the bit that corresponds to the
6015	 value of i that you want [0:7].  */
6016      tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6017      emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6018    }
6019  DONE;
6020})
6021
6022(define_expand "rs6000_set_fpscr_drn"
6023  [(match_operand:DI 0  "gpc_reg_operand")]
6024  "TARGET_HARD_FLOAT"
6025{
6026  rtx tmp_df = gen_reg_rtx (DFmode);
6027
6028  /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6029     new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
6030  if (TARGET_P9_MISC)
6031    {
6032      rtx src_df = gen_reg_rtx (DFmode);
6033
6034      emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6035      src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6036      emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6037    }
6038  else
6039    {
6040      rtx tmp_rn = gen_reg_rtx (DImode);
6041      rtx tmp_di = gen_reg_rtx (DImode);
6042
6043      /* Extract new DRN mode from operand.  */
6044      emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6045      emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6046
6047      /* Insert new RN mode into FSCPR.  */
6048      emit_insn (gen_rs6000_mffs (tmp_df));
6049      tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6050      emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6051      emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6052
6053      /* Need to write to field 7.  The fields are [0:15].  The equation to
6054	 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6055	 i to 0x1 to get field 7 where i selects the field.  */
6056      tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6057      emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6058    }
6059  DONE;
6060})
6061
6062;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6063;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6064;; because the first makes it clear that operand 0 is not live
6065;; before the instruction.
6066(define_insn "fctiwz_<mode>"
6067  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6068	(unspec:DI [(fix:SI
6069		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6070		   UNSPEC_FCTIWZ))]
6071  "TARGET_HARD_FLOAT"
6072  "@
6073   fctiwz %0,%1
6074   xscvdpsxws %x0,%x1"
6075  [(set_attr "type" "fp")])
6076
6077(define_insn "fctiwuz_<mode>"
6078  [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6079	(unspec:DI [(unsigned_fix:SI
6080		     (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6081		   UNSPEC_FCTIWUZ))]
6082  "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6083  "@
6084   fctiwuz %0,%1
6085   xscvdpuxws %x0,%x1"
6086  [(set_attr "type" "fp")])
6087
6088;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6089;; since the friz instruction does not truncate the value if the floating
6090;; point value is < LONG_MIN or > LONG_MAX.
6091(define_insn "*friz"
6092  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6093	(float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6094  "TARGET_HARD_FLOAT && TARGET_FPRND
6095   && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6096  "@
6097   friz %0,%1
6098   xsrdpiz %x0,%x1"
6099  [(set_attr "type" "fp")])
6100
6101;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
6102;; optimization prevents on ISA 2.06 systems and earlier having to store the
6103;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6104;; extend it, store it back on the stack from the GPR, load it back into the
6105;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6106;; disable using store and load to sign/zero extend the value.
6107(define_insn_and_split "*round32<mode>2_fprs"
6108  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6109	(float:SFDF
6110	 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6111   (clobber (match_scratch:DI 2 "=d"))
6112   (clobber (match_scratch:DI 3 "=d"))]
6113  "TARGET_HARD_FLOAT
6114   && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6115   && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6116  "#"
6117  ""
6118  [(pc)]
6119{
6120  rtx dest = operands[0];
6121  rtx src = operands[1];
6122  rtx tmp1 = operands[2];
6123  rtx tmp2 = operands[3];
6124  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6125
6126  if (GET_CODE (tmp1) == SCRATCH)
6127    tmp1 = gen_reg_rtx (DImode);
6128  if (GET_CODE (tmp2) == SCRATCH)
6129    tmp2 = gen_reg_rtx (DImode);
6130
6131  emit_insn (gen_fctiwz_<mode> (tmp1, src));
6132  emit_insn (gen_stfiwx (stack, tmp1));
6133  emit_insn (gen_lfiwax (tmp2, stack));
6134  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6135  DONE;
6136}
6137  [(set_attr "type" "fpload")
6138   (set_attr "length" "16")])
6139
6140(define_insn_and_split "*roundu32<mode>2_fprs"
6141  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6142	(unsigned_float:SFDF
6143	 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6144   (clobber (match_scratch:DI 2 "=d"))
6145   (clobber (match_scratch:DI 3 "=d"))]
6146  "TARGET_HARD_FLOAT
6147   && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6148   && can_create_pseudo_p ()"
6149  "#"
6150  ""
6151  [(pc)]
6152{
6153  rtx dest = operands[0];
6154  rtx src = operands[1];
6155  rtx tmp1 = operands[2];
6156  rtx tmp2 = operands[3];
6157  rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6158
6159  if (GET_CODE (tmp1) == SCRATCH)
6160    tmp1 = gen_reg_rtx (DImode);
6161  if (GET_CODE (tmp2) == SCRATCH)
6162    tmp2 = gen_reg_rtx (DImode);
6163
6164  emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6165  emit_insn (gen_stfiwx (stack, tmp1));
6166  emit_insn (gen_lfiwzx (tmp2, stack));
6167  emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6168  DONE;
6169}
6170  [(set_attr "type" "fpload")
6171   (set_attr "length" "16")])
6172
6173;; No VSX equivalent to fctid
6174(define_insn "lrint<mode>di2"
6175  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6176	(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6177		   UNSPEC_FCTID))]
6178  "TARGET_HARD_FLOAT && TARGET_FPRND"
6179  "fctid %0,%1"
6180  [(set_attr "type" "fp")])
6181
6182(define_insn "btrunc<mode>2"
6183  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6184	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6185		     UNSPEC_FRIZ))]
6186  "TARGET_HARD_FLOAT && TARGET_FPRND"
6187  "@
6188   friz %0,%1
6189   xsrdpiz %x0,%x1"
6190  [(set_attr "type" "fp")])
6191
6192(define_insn "ceil<mode>2"
6193  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6194	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6195		     UNSPEC_FRIP))]
6196  "TARGET_HARD_FLOAT && TARGET_FPRND"
6197  "@
6198   frip %0,%1
6199   xsrdpip %x0,%x1"
6200  [(set_attr "type" "fp")])
6201
6202(define_insn "floor<mode>2"
6203  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6204	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6205		     UNSPEC_FRIM))]
6206  "TARGET_HARD_FLOAT && TARGET_FPRND"
6207  "@
6208   frim %0,%1
6209   xsrdpim %x0,%x1"
6210  [(set_attr "type" "fp")])
6211
6212;; No VSX equivalent to frin
6213(define_insn "round<mode>2"
6214  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6215	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6216		     UNSPEC_FRIN))]
6217  "TARGET_HARD_FLOAT && TARGET_FPRND"
6218  "frin %0,%1"
6219  [(set_attr "type" "fp")])
6220
6221(define_insn "*xsrdpi<mode>2"
6222  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6223	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6224		     UNSPEC_XSRDPI))]
6225  "TARGET_HARD_FLOAT && TARGET_VSX"
6226  "xsrdpi %x0,%x1"
6227  [(set_attr "type" "fp")])
6228
6229(define_expand "lround<mode>di2"
6230  [(set (match_dup 2)
6231	(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6232		     UNSPEC_XSRDPI))
6233   (set (match_operand:DI 0 "gpc_reg_operand")
6234	(unspec:DI [(match_dup 2)]
6235		   UNSPEC_FCTID))]
6236  "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6237{
6238  operands[2] = gen_reg_rtx (<MODE>mode);
6239})
6240
6241; An UNSPEC is used so we don't have to support SImode in FP registers.
6242(define_insn "stfiwx"
6243  [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6244	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6245		   UNSPEC_STFIWX))]
6246  "TARGET_PPC_GFXOPT"
6247  "@
6248   stfiwx %1,%y0
6249   stxsiwx %x1,%y0"
6250  [(set_attr "type" "fpstore")
6251   (set_attr "isa" "*,p8v")])
6252
6253;; If we don't have a direct conversion to single precision, don't enable this
6254;; conversion for 32-bit without fast math, because we don't have the insn to
6255;; generate the fixup swizzle to avoid double rounding problems.
6256(define_expand "floatsisf2"
6257  [(set (match_operand:SF 0 "gpc_reg_operand")
6258        (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6259  "TARGET_HARD_FLOAT
6260   && ((TARGET_FCFIDS && TARGET_LFIWAX)
6261       || (TARGET_FCFID
6262	   && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6263{
6264  if (TARGET_FCFIDS && TARGET_LFIWAX)
6265    {
6266      emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6267      DONE;
6268    }
6269  else if (TARGET_FCFID && TARGET_LFIWAX)
6270    {
6271      rtx dfreg = gen_reg_rtx (DFmode);
6272      emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6273      emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6274      DONE;
6275    }
6276  else
6277    {
6278      rtx dreg = operands[1];
6279      if (!REG_P (dreg))
6280	dreg = force_reg (SImode, dreg);
6281      dreg = convert_to_mode (DImode, dreg, false);
6282      emit_insn (gen_floatdisf2 (operands[0], dreg));
6283      DONE;
6284    }
6285})
6286
6287(define_insn "floatdidf2"
6288  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6289	(float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6290  "TARGET_FCFID && TARGET_HARD_FLOAT"
6291  "@
6292   fcfid %0,%1
6293   xscvsxddp %x0,%x1"
6294  [(set_attr "type" "fp")])
6295
6296; Allow the combiner to merge source memory operands to the conversion so that
6297; the optimizer/register allocator doesn't try to load the value too early in a
6298; GPR and then use store/load to move it to a FPR and suffer from a store-load
6299; hit.  We will split after reload to avoid the trip through the GPRs
6300
6301(define_insn_and_split "*floatdidf2_mem"
6302  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6303	(float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6304   (clobber (match_scratch:DI 2 "=d,wa"))]
6305  "TARGET_HARD_FLOAT && TARGET_FCFID"
6306  "#"
6307  "&& reload_completed"
6308  [(set (match_dup 2) (match_dup 1))
6309   (set (match_dup 0) (float:DF (match_dup 2)))]
6310  ""
6311  [(set_attr "length" "8")
6312   (set_attr "type" "fpload")])
6313
6314(define_expand "floatunsdidf2"
6315  [(set (match_operand:DF 0 "gpc_reg_operand")
6316	(unsigned_float:DF
6317	 (match_operand:DI 1 "gpc_reg_operand")))]
6318  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6319  "")
6320
6321(define_insn "*floatunsdidf2_fcfidu"
6322  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6323	(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6324  "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6325  "@
6326   fcfidu %0,%1
6327   xscvuxddp %x0,%x1"
6328  [(set_attr "type" "fp")])
6329
6330(define_insn_and_split "*floatunsdidf2_mem"
6331  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6332	(unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6333   (clobber (match_scratch:DI 2 "=d,wa"))]
6334  "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6335  "#"
6336  "&& reload_completed"
6337  [(set (match_dup 2) (match_dup 1))
6338   (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6339  ""
6340  [(set_attr "length" "8")
6341   (set_attr "type" "fpload")])
6342
6343(define_expand "floatdisf2"
6344  [(set (match_operand:SF 0 "gpc_reg_operand")
6345        (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6346  "TARGET_FCFID && TARGET_HARD_FLOAT
6347   && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6348{
6349  if (!TARGET_FCFIDS)
6350    {
6351      rtx val = operands[1];
6352      if (!flag_unsafe_math_optimizations)
6353	{
6354	  rtx label = gen_label_rtx ();
6355	  val = gen_reg_rtx (DImode);
6356	  emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6357	  emit_label (label);
6358	}
6359      emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6360      DONE;
6361    }
6362})
6363
6364(define_insn "floatdisf2_fcfids"
6365  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6366	(float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6367  "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6368  "@
6369   fcfids %0,%1
6370   xscvsxdsp %x0,%x1"
6371  [(set_attr "type" "fp")
6372   (set_attr "isa" "*,p8v")])
6373
6374(define_insn_and_split "*floatdisf2_mem"
6375  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6376	(float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6377   (clobber (match_scratch:DI 2 "=d,d,wa"))]
6378  "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6379  "#"
6380  "&& reload_completed"
6381  [(pc)]
6382{
6383  emit_move_insn (operands[2], operands[1]);
6384  emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6385  DONE;
6386}
6387  [(set_attr "length" "8")
6388   (set_attr "isa" "*,p8v,p8v")])
6389
6390;; This is not IEEE compliant if rounding mode is "round to nearest".
6391;; If the DI->DF conversion is inexact, then it's possible to suffer
6392;; from double rounding.
6393;; Instead of creating a new cpu type for two FP operations, just use fp
6394(define_insn_and_split "floatdisf2_internal1"
6395  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6396        (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6397   (clobber (match_scratch:DF 2 "=d"))]
6398  "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6399  "#"
6400  "&& reload_completed"
6401  [(set (match_dup 2)
6402        (float:DF (match_dup 1)))
6403   (set (match_dup 0)
6404        (float_truncate:SF (match_dup 2)))]
6405  ""
6406  [(set_attr "length" "8")
6407   (set_attr "type" "fp")])
6408
6409;; Twiddles bits to avoid double rounding.
6410;; Bits that might be truncated when converting to DFmode are replaced
6411;; by a bit that won't be lost at that stage, but is below the SFmode
6412;; rounding position.
6413(define_expand "floatdisf2_internal2"
6414  [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6415					      (const_int 53)))
6416	      (clobber (reg:DI CA_REGNO))])
6417   (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6418					(const_int 2047)))
6419   (set (match_dup 3) (plus:DI (match_dup 3)
6420			       (const_int 1)))
6421   (set (match_dup 0) (plus:DI (match_dup 0)
6422			       (const_int 2047)))
6423   (set (match_dup 4) (compare:CCUNS (match_dup 3)
6424				     (const_int 2)))
6425   (set (match_dup 0) (ior:DI (match_dup 0)
6426			      (match_dup 1)))
6427   (set (match_dup 0) (and:DI (match_dup 0)
6428			      (const_int -2048)))
6429   (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6430			   (label_ref (match_operand:DI 2 ""))
6431			   (pc)))
6432   (set (match_dup 0) (match_dup 1))]
6433  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6434{
6435  operands[3] = gen_reg_rtx (DImode);
6436  operands[4] = gen_reg_rtx (CCUNSmode);
6437})
6438
6439(define_expand "floatunsdisf2"
6440  [(set (match_operand:SF 0 "gpc_reg_operand")
6441        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6442  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6443  "")
6444
6445(define_insn "floatunsdisf2_fcfidus"
6446  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6447        (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6448  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6449  "@
6450   fcfidus %0,%1
6451   xscvuxdsp %x0,%x1"
6452  [(set_attr "type" "fp")
6453   (set_attr "isa" "*,p8v")])
6454
6455(define_insn_and_split "*floatunsdisf2_mem"
6456  [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6457	(unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6458   (clobber (match_scratch:DI 2 "=d,d,wa"))]
6459  "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6460  "#"
6461  "&& reload_completed"
6462  [(pc)]
6463{
6464  emit_move_insn (operands[2], operands[1]);
6465  emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6466  DONE;
6467}
6468  [(set_attr "type" "fpload")
6469   (set_attr "length" "8")
6470   (set_attr "isa" "*,p8v,p8v")])
6471
6472;; Define the TImode operations that can be done in a small number
6473;; of instructions.  The & constraints are to prevent the register
6474;; allocator from allocating registers that overlap with the inputs
6475;; (for example, having an input in 7,8 and an output in 6,7).  We
6476;; also allow for the output being the same as one of the inputs.
6477
6478(define_expand "addti3"
6479  [(set (match_operand:TI 0 "gpc_reg_operand")
6480	(plus:TI (match_operand:TI 1 "gpc_reg_operand")
6481		 (match_operand:TI 2 "reg_or_short_operand")))]
6482  "TARGET_64BIT"
6483{
6484  rtx lo0 = gen_lowpart (DImode, operands[0]);
6485  rtx lo1 = gen_lowpart (DImode, operands[1]);
6486  rtx lo2 = gen_lowpart (DImode, operands[2]);
6487  rtx hi0 = gen_highpart (DImode, operands[0]);
6488  rtx hi1 = gen_highpart (DImode, operands[1]);
6489  rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6490
6491  if (!reg_or_short_operand (lo2, DImode))
6492    lo2 = force_reg (DImode, lo2);
6493  if (!adde_operand (hi2, DImode))
6494    hi2 = force_reg (DImode, hi2);
6495
6496  emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6497  emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6498  DONE;
6499})
6500
6501(define_expand "subti3"
6502  [(set (match_operand:TI 0 "gpc_reg_operand")
6503	(minus:TI (match_operand:TI 1 "reg_or_short_operand")
6504		  (match_operand:TI 2 "gpc_reg_operand")))]
6505  "TARGET_64BIT"
6506{
6507  rtx lo0 = gen_lowpart (DImode, operands[0]);
6508  rtx lo1 = gen_lowpart (DImode, operands[1]);
6509  rtx lo2 = gen_lowpart (DImode, operands[2]);
6510  rtx hi0 = gen_highpart (DImode, operands[0]);
6511  rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6512  rtx hi2 = gen_highpart (DImode, operands[2]);
6513
6514  if (!reg_or_short_operand (lo1, DImode))
6515    lo1 = force_reg (DImode, lo1);
6516  if (!adde_operand (hi1, DImode))
6517    hi1 = force_reg (DImode, hi1);
6518
6519  emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6520  emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6521  DONE;
6522})
6523
6524;; 128-bit logical operations expanders
6525
6526(define_expand "and<mode>3"
6527  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6528	(and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6529		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6530  ""
6531  "")
6532
6533(define_expand "ior<mode>3"
6534  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6535        (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6536		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6537  ""
6538  "")
6539
6540(define_expand "xor<mode>3"
6541  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6542        (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6543		      (match_operand:BOOL_128 2 "vlogical_operand")))]
6544  ""
6545  "")
6546
6547(define_expand "nor<mode>3"
6548  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6549	(and:BOOL_128
6550	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6551	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6552  ""
6553  "")
6554
6555(define_expand "andc<mode>3"
6556  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6557        (and:BOOL_128
6558	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6559	 (match_operand:BOOL_128 1 "vlogical_operand")))]
6560  ""
6561  "")
6562
6563;; Power8 vector logical instructions.
6564(define_expand "eqv<mode>3"
6565  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6566	(not:BOOL_128
6567	 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6568		       (match_operand:BOOL_128 2 "vlogical_operand"))))]
6569  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6570  "")
6571
6572;; Rewrite nand into canonical form
6573(define_expand "nand<mode>3"
6574  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6575	(ior:BOOL_128
6576	 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6577	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6578  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6579  "")
6580
6581;; The canonical form is to have the negated element first, so we need to
6582;; reverse arguments.
6583(define_expand "orc<mode>3"
6584  [(set (match_operand:BOOL_128 0 "vlogical_operand")
6585	(ior:BOOL_128
6586	 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6587	 (match_operand:BOOL_128 1 "vlogical_operand")))]
6588  "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6589  "")
6590
6591;; 128-bit logical operations insns and split operations
6592(define_insn_and_split "*and<mode>3_internal"
6593  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6594        (and:BOOL_128
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 "xxland %x0,%x1,%x2";
6601
6602  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6603    return "vand %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, AND, 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 IOR/XOR
6628(define_insn_and_split "*bool<mode>3_internal"
6629  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6630	(match_operator:BOOL_128 3 "boolean_or_operator"
6631	 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6632	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6633  ""
6634{
6635  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6636    return "xxl%q3 %x0,%x1,%x2";
6637
6638  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6639    return "v%q3 %0,%1,%2";
6640
6641  return "#";
6642}
6643  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6644  [(const_int 0)]
6645{
6646  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6647  DONE;
6648}
6649  [(set (attr "type")
6650      (if_then_else
6651	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6652	(const_string "veclogical")
6653	(const_string "integer")))
6654   (set (attr "length")
6655      (if_then_else
6656	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6657	(const_string "4")
6658	(if_then_else
6659	 (match_test "TARGET_POWERPC64")
6660	 (const_string "8")
6661	 (const_string "16"))))])
6662
6663;; 128-bit ANDC/ORC
6664(define_insn_and_split "*boolc<mode>3_internal1"
6665  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6666	(match_operator:BOOL_128 3 "boolean_operator"
6667	 [(not:BOOL_128
6668	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6669	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6670  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6671{
6672  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6673    return "xxl%q3 %x0,%x1,%x2";
6674
6675  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6676    return "v%q3 %0,%1,%2";
6677
6678  return "#";
6679}
6680  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6681   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6682  [(const_int 0)]
6683{
6684  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6685  DONE;
6686}
6687  [(set (attr "type")
6688      (if_then_else
6689	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6690	(const_string "veclogical")
6691	(const_string "integer")))
6692   (set (attr "length")
6693      (if_then_else
6694	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6695	(const_string "4")
6696	(if_then_else
6697	 (match_test "TARGET_POWERPC64")
6698	 (const_string "8")
6699	 (const_string "16"))))])
6700
6701(define_insn_and_split "*boolc<mode>3_internal2"
6702  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6703	(match_operator:TI2 3 "boolean_operator"
6704	 [(not:TI2
6705	   (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6706	  (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6707  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6708  "#"
6709  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6710  [(const_int 0)]
6711{
6712  rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6713  DONE;
6714}
6715  [(set_attr "type" "integer")
6716   (set (attr "length")
6717	(if_then_else
6718	 (match_test "TARGET_POWERPC64")
6719	 (const_string "8")
6720	 (const_string "16")))])
6721
6722;; 128-bit NAND/NOR
6723(define_insn_and_split "*boolcc<mode>3_internal1"
6724  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6725	(match_operator:BOOL_128 3 "boolean_operator"
6726	 [(not:BOOL_128
6727	   (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6728	  (not:BOOL_128
6729	   (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6730  "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6731{
6732  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6733    return "xxl%q3 %x0,%x1,%x2";
6734
6735  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6736    return "v%q3 %0,%1,%2";
6737
6738  return "#";
6739}
6740  "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6741   && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6742  [(const_int 0)]
6743{
6744  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6745  DONE;
6746}
6747  [(set (attr "type")
6748      (if_then_else
6749	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6750	(const_string "veclogical")
6751	(const_string "integer")))
6752   (set (attr "length")
6753      (if_then_else
6754	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6755	(const_string "4")
6756	(if_then_else
6757	 (match_test "TARGET_POWERPC64")
6758	 (const_string "8")
6759	 (const_string "16"))))])
6760
6761(define_insn_and_split "*boolcc<mode>3_internal2"
6762  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6763	(match_operator:TI2 3 "boolean_operator"
6764	 [(not:TI2
6765	   (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6766	  (not:TI2
6767	   (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6768  "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6769  "#"
6770  "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6771  [(const_int 0)]
6772{
6773  rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6774  DONE;
6775}
6776  [(set_attr "type" "integer")
6777   (set (attr "length")
6778	(if_then_else
6779	 (match_test "TARGET_POWERPC64")
6780	 (const_string "8")
6781	 (const_string "16")))])
6782
6783
6784;; 128-bit EQV
6785(define_insn_and_split "*eqv<mode>3_internal1"
6786  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6787	(not:BOOL_128
6788	 (xor:BOOL_128
6789	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6790	  (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6791  "TARGET_P8_VECTOR"
6792{
6793  if (vsx_register_operand (operands[0], <MODE>mode))
6794    return "xxleqv %x0,%x1,%x2";
6795
6796  return "#";
6797}
6798  "TARGET_P8_VECTOR && reload_completed
6799   && int_reg_operand (operands[0], <MODE>mode)"
6800  [(const_int 0)]
6801{
6802  rs6000_split_logical (operands, XOR, true, false, false);
6803  DONE;
6804}
6805  [(set (attr "type")
6806      (if_then_else
6807	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6808	(const_string "veclogical")
6809	(const_string "integer")))
6810   (set (attr "length")
6811      (if_then_else
6812	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6813	(const_string "4")
6814	(if_then_else
6815	 (match_test "TARGET_POWERPC64")
6816	 (const_string "8")
6817	 (const_string "16"))))])
6818
6819(define_insn_and_split "*eqv<mode>3_internal2"
6820  [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6821	(not:TI2
6822	 (xor:TI2
6823	  (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6824	  (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6825  "!TARGET_P8_VECTOR"
6826  "#"
6827  "reload_completed && !TARGET_P8_VECTOR"
6828  [(const_int 0)]
6829{
6830  rs6000_split_logical (operands, XOR, true, false, false);
6831  DONE;
6832}
6833  [(set_attr "type" "integer")
6834   (set (attr "length")
6835	(if_then_else
6836	 (match_test "TARGET_POWERPC64")
6837	 (const_string "8")
6838	 (const_string "16")))])
6839
6840;; 128-bit one's complement
6841(define_insn_and_split "one_cmpl<mode>2"
6842  [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6843	(not:BOOL_128
6844	  (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6845  ""
6846{
6847  if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6848    return "xxlnor %x0,%x1,%x1";
6849
6850  if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6851    return "vnor %0,%1,%1";
6852
6853  return "#";
6854}
6855  "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6856  [(const_int 0)]
6857{
6858  rs6000_split_logical (operands, NOT, false, false, false);
6859  DONE;
6860}
6861  [(set (attr "type")
6862      (if_then_else
6863	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6864	(const_string "veclogical")
6865	(const_string "integer")))
6866   (set (attr "length")
6867      (if_then_else
6868	(match_test "vsx_register_operand (operands[0], <MODE>mode)")
6869	(const_string "4")
6870	(if_then_else
6871	 (match_test "TARGET_POWERPC64")
6872	 (const_string "8")
6873	 (const_string "16"))))])
6874
6875
6876;; Now define ways of moving data around.
6877
6878;; Set up a register with a value from the GOT table
6879
6880(define_expand "movsi_got"
6881  [(set (match_operand:SI 0 "gpc_reg_operand")
6882	(unspec:SI [(match_operand:SI 1 "got_operand")
6883		    (match_dup 2)] UNSPEC_MOVSI_GOT))]
6884  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6885{
6886  if (GET_CODE (operands[1]) == CONST)
6887    {
6888      rtx offset = const0_rtx;
6889      HOST_WIDE_INT value;
6890
6891      operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6892      value = INTVAL (offset);
6893      if (value != 0)
6894	{
6895	  rtx tmp = (!can_create_pseudo_p ()
6896		     ? operands[0]
6897		     : gen_reg_rtx (Pmode));
6898	  emit_insn (gen_movsi_got (tmp, operands[1]));
6899	  emit_insn (gen_addsi3 (operands[0], tmp, offset));
6900	  DONE;
6901	}
6902    }
6903
6904  operands[2] = rs6000_got_register (operands[1]);
6905})
6906
6907(define_insn "*movsi_got_internal"
6908  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6909	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6910		    (match_operand:SI 2 "gpc_reg_operand" "b")]
6911		   UNSPEC_MOVSI_GOT))]
6912  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6913  "lwz %0,%a1@got(%2)"
6914  [(set_attr "type" "load")])
6915
6916;; Used by sched, shorten_branches and final when the GOT pseudo reg
6917;; didn't get allocated to a hard register.
6918(define_split
6919  [(set (match_operand:SI 0 "gpc_reg_operand")
6920	(unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6921		    (match_operand:SI 2 "memory_operand")]
6922		   UNSPEC_MOVSI_GOT))]
6923  "DEFAULT_ABI == ABI_V4
6924    && flag_pic == 1
6925    && reload_completed"
6926  [(set (match_dup 0) (match_dup 2))
6927   (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6928				 UNSPEC_MOVSI_GOT))]
6929  "")
6930
6931;;	   MR          LA
6932;;	   LWZ         LFIWZX      LXSIWZX
6933;;	   STW         STFIWX      STXSIWX
6934;;	   LI          LIS         PLI         #
6935;;	   XXLOR       XXSPLTIB 0  XXSPLTIB -1 VSPLTISW
6936;;	   XXLXOR 0    XXLORC -1   P9 const
6937;;	   MTVSRWZ     MFVSRWZ
6938;;	   MF%1        MT%0        NOP
6939
6940(define_insn "*movsi_internal1"
6941  [(set (match_operand:SI 0 "nonimmediate_operand"
6942	  "=r,         r,
6943	   r,          d,          v,
6944	   m,          ?Z,         ?Z,
6945	   r,          r,          r,          r,
6946	   wa,         wa,         wa,         v,
6947	   wa,         v,          v,
6948	   wa,         r,
6949	   r,          *h,         *h")
6950	(match_operand:SI 1 "input_operand"
6951	  "r,          U,
6952	   m,          ?Z,         ?Z,
6953	   r,          d,          v,
6954	   I,          L,          eI,         n,
6955	   wa,         O,          wM,         wB,
6956	   O,          wM,         wS,
6957	   r,          wa,
6958	   *h,         r,          0"))]
6959  "gpc_reg_operand (operands[0], SImode)
6960   || gpc_reg_operand (operands[1], SImode)"
6961  "@
6962   mr %0,%1
6963   la %0,%a1
6964   lwz%U1%X1 %0,%1
6965   lfiwzx %0,%y1
6966   lxsiwzx %x0,%y1
6967   stw%U0%X0 %1,%0
6968   stfiwx %1,%y0
6969   stxsiwx %x1,%y0
6970   li %0,%1
6971   lis %0,%v1
6972   li %0,%1
6973   #
6974   xxlor %x0,%x1,%x1
6975   xxspltib %x0,0
6976   xxspltib %x0,255
6977   vspltisw %0,%1
6978   xxlxor %x0,%x0,%x0
6979   xxlorc %x0,%x0,%x0
6980   #
6981   mtvsrwz %x0,%1
6982   mfvsrwz %0,%x1
6983   mf%1 %0
6984   mt%0 %1
6985   nop"
6986  [(set_attr "type"
6987	  "*,          *,
6988	   load,       fpload,     fpload,
6989	   store,      fpstore,    fpstore,
6990	   *,          *,          *,          *,
6991	   veclogical, vecsimple,  vecsimple,  vecsimple,
6992	   veclogical, veclogical, vecsimple,
6993	   mffgpr,     mftgpr,
6994	   *,          *,          *")
6995   (set_attr "length"
6996	  "*,          *,
6997	   *,          *,          *,
6998	   *,          *,          *,
6999	   *,          *,          *,          8,
7000	   *,          *,          *,          *,
7001	   *,          *,          8,
7002	   *,          *,
7003	   *,          *,          *")
7004   (set_attr "isa"
7005	  "*,          *,
7006	   *,          p8v,        p8v,
7007	   *,          p8v,        p8v,
7008	   *,          *,          p10,        *,
7009	   p8v,        p9v,        p9v,        p8v,
7010	   p9v,        p8v,        p9v,
7011	   p8v,        p8v,
7012	   *,          *,          *")])
7013
7014;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7015;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7016;;
7017;; Because SF values are actually stored as DF values within the vector
7018;; registers, we need to convert the value to the vector SF format when
7019;; we need to use the bits in a union or similar cases.  We only need
7020;; to do this transformation when the value is a vector register.  Loads,
7021;; stores, and transfers within GPRs are assumed to be safe.
7022;;
7023;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
7024;; no alternatives, because the call is created as part of secondary_reload,
7025;; and operand #2's register class is used to allocate the temporary register.
7026;; This function is called before reload, and it creates the temporary as
7027;; needed.
7028
7029;;		MR           LWZ          LFIWZX       LXSIWZX   STW
7030;;		STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
7031;;		MTVSRWZ
7032
7033(define_insn_and_split "movsi_from_sf"
7034  [(set (match_operand:SI 0 "nonimmediate_operand"
7035		"=r,         r,           ?*d,         ?*v,      m,
7036		 m,          wY,          Z,           r,        ?*wa,
7037		 wa")
7038	(unspec:SI [(match_operand:SF 1 "input_operand"
7039		"r,          m,           Z,           Z,        r,
7040		 f,          v,           wa,          wa,       wa,
7041		 r")]
7042		    UNSPEC_SI_FROM_SF))
7043   (clobber (match_scratch:V4SF 2
7044		"=X,         X,           X,           X,        X,
7045		 X,          X,           X,           wa,       X,
7046		 X"))]
7047  "TARGET_NO_SF_SUBREG
7048   && (register_operand (operands[0], SImode)
7049       || register_operand (operands[1], SFmode))"
7050  "@
7051   mr %0,%1
7052   lwz%U1%X1 %0,%1
7053   lfiwzx %0,%y1
7054   lxsiwzx %x0,%y1
7055   stw%U0%X0 %1,%0
7056   stfs%U0%X0 %1,%0
7057   stxssp %1,%0
7058   stxsspx %x1,%y0
7059   #
7060   xscvdpspn %x0,%x1
7061   mtvsrwz %x0,%1"
7062  "&& reload_completed
7063   && int_reg_operand (operands[0], SImode)
7064   && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7065  [(const_int 0)]
7066{
7067  rtx op0 = operands[0];
7068  rtx op1 = operands[1];
7069  rtx op2 = operands[2];
7070  rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7071  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7072
7073  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7074  emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7075  DONE;
7076}
7077  [(set_attr "type"
7078		"*,          load,        fpload,      fpload,   store,
7079		 fpstore,    fpstore,     fpstore,     mftgpr,   fp,
7080		 mffgpr")
7081   (set_attr "length"
7082		"*,          *,           *,           *,        *,
7083		 *,          *,           *,           8,        *,
7084		 *")
7085   (set_attr "isa"
7086		"*,          *,           p8v,         p8v,      *,
7087		 *,          p9v,         p8v,         p8v,      p8v,
7088		 p8v")])
7089
7090;; movsi_from_sf with zero extension
7091;;
7092;;		RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
7093;;		VSX->VSX     MTVSRWZ
7094
7095(define_insn_and_split "*movdi_from_sf_zero_ext"
7096  [(set (match_operand:DI 0 "gpc_reg_operand"
7097		"=r,         r,           ?*d,         ?*v,      r,
7098		 ?v,         wa")
7099	(zero_extend:DI
7100	 (unspec:SI [(match_operand:SF 1 "input_operand"
7101		"r,          m,           Z,           Z,        wa,
7102		 wa,         r")]
7103		    UNSPEC_SI_FROM_SF)))
7104   (clobber (match_scratch:V4SF 2
7105		"=X,         X,           X,           X,        wa,
7106		 wa,         X"))]
7107  "TARGET_DIRECT_MOVE_64BIT
7108   && (register_operand (operands[0], DImode)
7109       || register_operand (operands[1], SImode))"
7110  "@
7111   rldicl %0,%1,0,32
7112   lwz%U1%X1 %0,%1
7113   lfiwzx %0,%y1
7114   lxsiwzx %x0,%y1
7115   #
7116   #
7117   mtvsrwz %x0,%1"
7118  "&& reload_completed
7119   && register_operand (operands[0], DImode)
7120   && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7121  [(const_int 0)]
7122{
7123  rtx op0 = operands[0];
7124  rtx op1 = operands[1];
7125  rtx op2 = operands[2];
7126  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7127
7128  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7129  emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7130  DONE;
7131}
7132  [(set_attr "type"
7133		"*,          load,        fpload,      fpload,   two,
7134		 two,        mffgpr")
7135   (set_attr "length"
7136		"*,          *,           *,           *,        8,
7137		 8,          *")
7138   (set_attr "isa"
7139		"*,          *,           p8v,         p8v,      p8v,
7140		 p9v,        p8v")])
7141
7142;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7143;; moving it to SImode.  We cannot do a SFmode store without having to do the
7144;; conversion explicitly since that doesn't work in most cases if the input
7145;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7146;; former handles cases where the input will not fit in a SFmode, and the
7147;; latter assumes the value has already been rounded.
7148(define_insn "*movsi_from_df"
7149  [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7150	(unspec:SI [(float_truncate:SF
7151		     (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7152		    UNSPEC_SI_FROM_SF))]
7153  "TARGET_NO_SF_SUBREG"
7154  "xscvdpsp %x0,%x1"
7155  [(set_attr "type" "fp")])
7156
7157;; Split a load of a large constant into the appropriate two-insn
7158;; sequence.
7159
7160(define_split
7161  [(set (match_operand:SI 0 "gpc_reg_operand")
7162	(match_operand:SI 1 "const_int_operand"))]
7163  "num_insns_constant (operands[1], SImode) > 1"
7164  [(set (match_dup 0)
7165	(match_dup 2))
7166   (set (match_dup 0)
7167	(ior:SI (match_dup 0)
7168		(match_dup 3)))]
7169{
7170  if (rs6000_emit_set_const (operands[0], operands[1]))
7171    DONE;
7172  else
7173    FAIL;
7174})
7175
7176;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7177(define_split
7178  [(set (match_operand:DI 0 "altivec_register_operand")
7179	(match_operand:DI 1 "xxspltib_constant_split"))]
7180  "TARGET_P9_VECTOR && reload_completed"
7181  [(const_int 0)]
7182{
7183  rtx op0 = operands[0];
7184  rtx op1 = operands[1];
7185  int r = REGNO (op0);
7186  rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7187
7188  emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7189  emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7190  DONE;
7191})
7192
7193(define_insn "*mov<mode>_internal2"
7194  [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7195	(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7196		    (const_int 0)))
7197   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7198  ""
7199  "@
7200   cmp<wd>i %2,%0,0
7201   mr. %0,%1
7202   #"
7203  [(set_attr "type" "cmp,logical,cmp")
7204   (set_attr "dot" "yes")
7205   (set_attr "length" "4,4,8")])
7206
7207(define_split
7208  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7209	(compare:CC (match_operand:P 1 "gpc_reg_operand")
7210		    (const_int 0)))
7211   (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7212  "reload_completed"
7213  [(set (match_dup 0) (match_dup 1))
7214   (set (match_dup 2)
7215	(compare:CC (match_dup 0)
7216		    (const_int 0)))]
7217  "")
7218
7219(define_expand "mov<mode>"
7220  [(set (match_operand:INT 0 "general_operand")
7221	(match_operand:INT 1 "any_operand"))]
7222  ""
7223{
7224  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7225  DONE;
7226})
7227
7228;;		MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7229;;		XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7230;;		MTVSRWZ     MF%1       MT%1       NOP
7231(define_insn "*mov<mode>_internal"
7232  [(set (match_operand:QHI 0 "nonimmediate_operand"
7233		"=r,        r,         wa,        m,         ?Z,        r,
7234		 wa,        wa,        wa,        v,         ?v,        r,
7235		 wa,        r,         *c*l,      *h")
7236	(match_operand:QHI 1 "input_operand"
7237		"r,         m,         ?Z,        r,         wa,        i,
7238		 wa,        O,         wM,        wB,        wS,        wa,
7239		 r,         *h,        r,         0"))]
7240  "gpc_reg_operand (operands[0], <MODE>mode)
7241   || gpc_reg_operand (operands[1], <MODE>mode)"
7242  "@
7243   mr %0,%1
7244   l<wd>z%U1%X1 %0,%1
7245   lxsi<wd>zx %x0,%y1
7246   st<wd>%U0%X0 %1,%0
7247   stxsi<wd>x %x1,%y0
7248   li %0,%1
7249   xxlor %x0,%x1,%x1
7250   xxspltib %x0,0
7251   xxspltib %x0,255
7252   vspltis<wd> %0,%1
7253   #
7254   mfvsrwz %0,%x1
7255   mtvsrwz %x0,%1
7256   mf%1 %0
7257   mt%0 %1
7258   nop"
7259  [(set_attr "type"
7260		"*,         load,      fpload,    store,     fpstore,   *,
7261		 vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7262		 mffgpr,    mfjmpr,    mtjmpr,    *")
7263   (set_attr "length"
7264		"*,         *,         *,         *,         *,         *,
7265		 *,         *,         *,         *,         8,         *,
7266		 *,         *,         *,         *")
7267   (set_attr "isa"
7268		"*,         *,         p9v,       *,         p9v,       *,
7269		 p9v,       p9v,       p9v,       p9v,       p9v,       p9v,
7270		 p9v,       *,         *,         *")])
7271
7272
7273;; Here is how to move condition codes around.  When we store CC data in
7274;; an integer register or memory, we store just the high-order 4 bits.
7275;; This lets us not shift in the most common case of CR0.
7276(define_expand "movcc"
7277  [(set (match_operand:CC 0 "nonimmediate_operand")
7278	(match_operand:CC 1 "nonimmediate_operand"))]
7279  ""
7280  "")
7281
7282(define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7283
7284(define_insn "*movcc_<mode>"
7285  [(set (match_operand:CC_any 0 "nonimmediate_operand"
7286				"=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7287	(match_operand:CC_any 1 "general_operand"
7288				" y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7289  "register_operand (operands[0], <MODE>mode)
7290   || register_operand (operands[1], <MODE>mode)"
7291  "@
7292   mcrf %0,%1
7293   mtcrf 128,%1
7294   rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7295   crxor %0,%0,%0
7296   mfcr %0%Q1
7297   mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7298   mr %0,%1
7299   li %0,%1
7300   mf%1 %0
7301   mt%0 %1
7302   lwz%U1%X1 %0,%1
7303   stw%U0%X0 %1,%0"
7304  [(set_attr_alternative "type"
7305     [(const_string "cr_logical")
7306      (const_string "mtcr")
7307      (const_string "mtcr")
7308      (const_string "cr_logical")
7309      (if_then_else (match_test "TARGET_MFCRF")
7310		    (const_string "mfcrf") (const_string "mfcr"))
7311      (if_then_else (match_test "TARGET_MFCRF")
7312		    (const_string "mfcrf") (const_string "mfcr"))
7313      (const_string "integer")
7314      (const_string "integer")
7315      (const_string "mfjmpr")
7316      (const_string "mtjmpr")
7317      (const_string "load")
7318      (const_string "store")])
7319   (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7320
7321;; For floating-point, we normally deal with the floating-point registers
7322;; unless -msoft-float is used.  The sole exception is that parameter passing
7323;; can produce floating-point values in fixed-point registers.  Unless the
7324;; value is a simple constant or already in memory, we deal with this by
7325;; allocating memory and copying the value explicitly via that memory location.
7326
7327;; Move 32-bit binary/decimal floating point
7328(define_expand "mov<mode>"
7329  [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7330	(match_operand:FMOVE32 1 "any_operand"))]
7331  "<fmove_ok>"
7332{
7333  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7334  DONE;
7335})
7336
7337(define_split
7338  [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7339	(match_operand:FMOVE32 1 "const_double_operand"))]
7340  "reload_completed
7341   && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7342       || (SUBREG_P (operands[0])
7343	   && REG_P (SUBREG_REG (operands[0]))
7344	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7345  [(set (match_dup 2) (match_dup 3))]
7346{
7347  long l;
7348
7349  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7350
7351  if (! TARGET_POWERPC64)
7352    operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7353  else
7354    operands[2] = gen_lowpart (SImode, operands[0]);
7355
7356  operands[3] = gen_int_mode (l, SImode);
7357})
7358
7359;; Originally, we tried to keep movsf and movsd common, but the differences
7360;; addressing was making it rather difficult to hide with mode attributes.  In
7361;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7362;; before the VSX stores meant that the register allocator would tend to do a
7363;; direct move to the GPR (which involves conversion from scalar to
7364;; vector/memory formats) to save values in the traditional Altivec registers,
7365;; while SDmode had problems on power6 if the GPR store was not first due to
7366;; the power6 not having an integer store operation.
7367;;
7368;;	LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7369;;	STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7370;;	MR           MT<x>      MF<x>       NOP
7371
7372(define_insn "movsf_hardfloat"
7373  [(set (match_operand:SF 0 "nonimmediate_operand"
7374	 "=!r,       f,         v,          wa,        m,         wY,
7375	  Z,         m,         wa,         !r,        f,         wa,
7376	  !r,        *c*l,      !r,         *h")
7377	(match_operand:SF 1 "input_operand"
7378	 "m,         m,         wY,         Z,         f,         v,
7379	  wa,        r,         j,          j,         f,         wa,
7380	  r,         r,         *h,         0"))]
7381  "(register_operand (operands[0], SFmode)
7382   || register_operand (operands[1], SFmode))
7383   && TARGET_HARD_FLOAT
7384   && (TARGET_ALLOW_SF_SUBREG
7385       || valid_sf_si_move (operands[0], operands[1], SFmode))"
7386  "@
7387   lwz%U1%X1 %0,%1
7388   lfs%U1%X1 %0,%1
7389   lxssp %0,%1
7390   lxsspx %x0,%y1
7391   stfs%U0%X0 %1,%0
7392   stxssp %1,%0
7393   stxsspx %x1,%y0
7394   stw%U0%X0 %1,%0
7395   xxlxor %x0,%x0,%x0
7396   li %0,0
7397   fmr %0,%1
7398   xscpsgndp %x0,%x1,%x1
7399   mr %0,%1
7400   mt%0 %1
7401   mf%1 %0
7402   nop"
7403  [(set_attr "type"
7404	"load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7405	 fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7406	 *,          mtjmpr,    mfjmpr,     *")
7407   (set_attr "isa"
7408	"*,          *,         p9v,        p8v,       *,         p9v,
7409	 p8v,        *,         *,          *,         *,         *,
7410	 *,          *,         *,          *")])
7411
7412;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7413;;	FMR          MR         MT%0       MF%1       NOP
7414(define_insn "movsd_hardfloat"
7415  [(set (match_operand:SD 0 "nonimmediate_operand"
7416	 "=!r,       d,         m,         ?Z,        ?d,        ?r,
7417	  f,         !r,        *c*l,      !r,        *h")
7418	(match_operand:SD 1 "input_operand"
7419	 "m,         ?Z,        r,         wx,        r,         d,
7420	  f,         r,         r,         *h,        0"))]
7421  "(register_operand (operands[0], SDmode)
7422   || register_operand (operands[1], SDmode))
7423   && TARGET_HARD_FLOAT"
7424  "@
7425   lwz%U1%X1 %0,%1
7426   lfiwzx %0,%y1
7427   stw%U0%X0 %1,%0
7428   stfiwx %1,%y0
7429   mtvsrwz %x0,%1
7430   mfvsrwz %0,%x1
7431   fmr %0,%1
7432   mr %0,%1
7433   mt%0 %1
7434   mf%1 %0
7435   nop"
7436  [(set_attr "type"
7437	"load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7438	 fpsimple,   *,         mtjmpr,    mfjmpr,    *")
7439   (set_attr "isa"
7440	"*,          p7,        *,         *,         p8v,       p8v,
7441	 *,          *,         *,         *,         *")])
7442
7443;;	MR           MT%0       MF%0       LWZ        STW        LI
7444;;	LIS          G-const.   F/n-const  NOP
7445(define_insn "*mov<mode>_softfloat"
7446  [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7447	"=r,         *c*l,      r,         r,         m,         r,
7448          r,         r,         r,         *h")
7449
7450	(match_operand:FMOVE32 1 "input_operand"
7451	 "r,         r,         *h,        m,         r,         I,
7452          L,         G,         Fn,        0"))]
7453
7454  "(gpc_reg_operand (operands[0], <MODE>mode)
7455   || gpc_reg_operand (operands[1], <MODE>mode))
7456   && TARGET_SOFT_FLOAT"
7457  "@
7458   mr %0,%1
7459   mt%0 %1
7460   mf%1 %0
7461   lwz%U1%X1 %0,%1
7462   stw%U0%X0 %1,%0
7463   li %0,%1
7464   lis %0,%v1
7465   #
7466   #
7467   nop"
7468  [(set_attr "type"
7469	"*,          mtjmpr,    mfjmpr,    load,      store,     *,
7470	 *,          *,         *,         *")
7471
7472   (set_attr "length"
7473	"*,          *,         *,         *,         *,         *,
7474         *,          *,         8,         *")])
7475
7476;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7477;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7478;;
7479;; Because SF values are actually stored as DF values within the vector
7480;; registers, we need to convert the value to the vector SF format when
7481;; we need to use the bits in a union or similar cases.  We only need
7482;; to do this transformation when the value is a vector register.  Loads,
7483;; stores, and transfers within GPRs are assumed to be safe.
7484;;
7485;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7486;; no alternatives, because the call is created as part of secondary_reload,
7487;; and operand #2's register class is used to allocate the temporary register.
7488;; This function is called before reload, and it creates the temporary as
7489;; needed.
7490
7491;;	    LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7492;;	    STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7493(define_insn_and_split "movsf_from_si"
7494  [(set (match_operand:SF 0 "nonimmediate_operand"
7495	    "=!r,       f,         v,         wa,        m,         Z,
7496	     Z,         wa,        ?r,        !r")
7497	(unspec:SF [(match_operand:SI 1 "input_operand" 
7498	    "m,         m,         wY,        Z,         r,         f,
7499	     wa,        r,         wa,        r")]
7500		   UNSPEC_SF_FROM_SI))
7501   (clobber (match_scratch:DI 2
7502	    "=X,        X,         X,         X,         X,         X,
7503             X,         r,         X,         X"))]
7504  "TARGET_NO_SF_SUBREG
7505   && (register_operand (operands[0], SFmode)
7506       || register_operand (operands[1], SImode))"
7507  "@
7508   lwz%U1%X1 %0,%1
7509   lfs%U1%X1 %0,%1
7510   lxssp %0,%1
7511   lxsspx %x0,%y1
7512   stw%U0%X0 %1,%0
7513   stfiwx %1,%y0
7514   stxsiwx %x1,%y0
7515   #
7516   mfvsrwz %0,%x1
7517   mr %0,%1"
7518
7519  "&& reload_completed
7520   && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7521   && int_reg_operand_not_pseudo (operands[1], SImode)"
7522  [(const_int 0)]
7523{
7524  rtx op0 = operands[0];
7525  rtx op1 = operands[1];
7526  rtx op2 = operands[2];
7527  rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7528
7529  /* Move SF value to upper 32-bits for xscvspdpn.  */
7530  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7531  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7532  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7533  DONE;
7534}
7535  [(set_attr "length"
7536	    "*,          *,         *,         *,         *,         *,
7537	     *,          12,        *,         *")
7538   (set_attr "type"
7539	    "load,       fpload,    fpload,    fpload,    store,     fpstore,
7540	     fpstore,    vecfloat,  mffgpr,    *")
7541   (set_attr "isa"
7542	    "*,          *,         p9v,       p8v,       *,         *,
7543	     p8v,        p8v,       p8v,       *")])
7544
7545
7546;; Move 64-bit binary/decimal floating point
7547(define_expand "mov<mode>"
7548  [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7549	(match_operand:FMOVE64 1 "any_operand"))]
7550  ""
7551{
7552  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7553  DONE;
7554})
7555
7556(define_split
7557  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7558	(match_operand:FMOVE64 1 "const_int_operand"))]
7559  "! TARGET_POWERPC64 && reload_completed
7560   && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7561       || (SUBREG_P (operands[0])
7562	   && REG_P (SUBREG_REG (operands[0]))
7563	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7564  [(set (match_dup 2) (match_dup 4))
7565   (set (match_dup 3) (match_dup 1))]
7566{
7567  int endian = (WORDS_BIG_ENDIAN == 0);
7568  HOST_WIDE_INT value = INTVAL (operands[1]);
7569
7570  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7571  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7572  operands[4] = GEN_INT (value >> 32);
7573  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7574})
7575
7576(define_split
7577  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7578	(match_operand:FMOVE64 1 "const_double_operand"))]
7579  "! TARGET_POWERPC64 && reload_completed
7580   && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7581       || (SUBREG_P (operands[0])
7582	   && REG_P (SUBREG_REG (operands[0]))
7583	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7584  [(set (match_dup 2) (match_dup 4))
7585   (set (match_dup 3) (match_dup 5))]
7586{
7587  int endian = (WORDS_BIG_ENDIAN == 0);
7588  long l[2];
7589
7590  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7591
7592  operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7593  operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7594  operands[4] = gen_int_mode (l[endian], SImode);
7595  operands[5] = gen_int_mode (l[1 - endian], SImode);
7596})
7597
7598(define_split
7599  [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7600	(match_operand:FMOVE64 1 "const_double_operand"))]
7601  "TARGET_POWERPC64 && reload_completed
7602   && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7603       || (SUBREG_P (operands[0])
7604	   && REG_P (SUBREG_REG (operands[0]))
7605	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
7606  [(set (match_dup 2) (match_dup 3))]
7607{
7608  int endian = (WORDS_BIG_ENDIAN == 0);
7609  long l[2];
7610  HOST_WIDE_INT val;
7611
7612  <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7613
7614  operands[2] = gen_lowpart (DImode, operands[0]);
7615  /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7616  val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7617         | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7618
7619  operands[3] = gen_int_mode (val, DImode);
7620})
7621
7622;; Don't have reload use general registers to load a constant.  It is
7623;; less efficient than loading the constant into an FP register, since
7624;; it will probably be used there.
7625
7626;; The move constraints are ordered to prefer floating point registers before
7627;; general purpose registers to avoid doing a store and a load to get the value
7628;; into a floating point register when it is needed for a floating point
7629;; operation.  Prefer traditional floating point registers over VSX registers,
7630;; since the D-form version of the memory instructions does not need a GPR for
7631;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7632;; registers.
7633
7634;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7635;; except for 0.0 which can be created on VSX with an xor instruction.
7636
7637;;           STFD         LFD         FMR         LXSD        STXSD
7638;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7639;;           LWZ          STW         MR
7640
7641
7642(define_insn "*mov<mode>_hardfloat32"
7643  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7644            "=m,          d,          d,          <f64_p9>,   wY,
7645              <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7646              Y,          r,          !r")
7647	(match_operand:FMOVE64 1 "input_operand"
7648             "d,          m,          d,          wY,         <f64_p9>,
7649              Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7650              r,          Y,          r"))]
7651  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7652   && (gpc_reg_operand (operands[0], <MODE>mode)
7653       || gpc_reg_operand (operands[1], <MODE>mode))"
7654  "@
7655   stfd%U0%X0 %1,%0
7656   lfd%U1%X1 %0,%1
7657   fmr %0,%1
7658   lxsd %0,%1
7659   stxsd %1,%0
7660   lxsdx %x0,%y1
7661   stxsdx %x1,%y0
7662   xxlor %x0,%x1,%x1
7663   xxlxor %x0,%x0,%x0
7664   #
7665   #
7666   #
7667   #"
7668  [(set_attr "type"
7669            "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7670             fpload,      fpstore,    veclogical, veclogical, two,
7671             store,       load,       two")
7672   (set_attr "size" "64")
7673   (set_attr "length"
7674            "*,           *,          *,          *,          *,
7675             *,           *,          *,          *,          8,
7676             8,           8,          8")
7677   (set_attr "isa"
7678            "*,           *,          *,          p9v,        p9v,
7679             p7v,         p7v,        *,          *,          *,
7680             *,           *,          *")])
7681
7682;;           STW      LWZ     MR      G-const H-const F-const
7683
7684(define_insn "*mov<mode>_softfloat32"
7685  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7686           "=Y,       r,      r,      r,      r,      r")
7687
7688	(match_operand:FMOVE64 1 "input_operand"
7689            "r,       Y,      r,      G,      H,      F"))]
7690
7691  "!TARGET_POWERPC64
7692   && (gpc_reg_operand (operands[0], <MODE>mode)
7693       || gpc_reg_operand (operands[1], <MODE>mode))"
7694  "#"
7695  [(set_attr "type"
7696            "store,   load,   two,    *,      *,      *")
7697
7698   (set_attr "length"
7699             "8,      8,      8,      8,      12,     16")])
7700
7701; ld/std require word-aligned displacements -> 'Y' constraint.
7702; List Y->r and r->Y before r->r for reload.
7703
7704;;           STFD         LFD         FMR         LXSD        STXSD
7705;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7706;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7707;;           NOP          MFVSRD      MTVSRD
7708
7709(define_insn "*mov<mode>_hardfloat64"
7710  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7711           "=m,           d,          d,          <f64_p9>,   wY,
7712             <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7713             YZ,          r,          !r,         *c*l,       !r,
7714            *h,           r,          <f64_dm>")
7715	(match_operand:FMOVE64 1 "input_operand"
7716            "d,           m,          d,          wY,         <f64_p9>,
7717             Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7718             r,           YZ,         r,          r,          *h,
7719             0,           <f64_dm>,   r"))]
7720  "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7721   && (gpc_reg_operand (operands[0], <MODE>mode)
7722       || gpc_reg_operand (operands[1], <MODE>mode))"
7723  "@
7724   stfd%U0%X0 %1,%0
7725   lfd%U1%X1 %0,%1
7726   fmr %0,%1
7727   lxsd %0,%1
7728   stxsd %1,%0
7729   lxsdx %x0,%y1
7730   stxsdx %x1,%y0
7731   xxlor %x0,%x1,%x1
7732   xxlxor %x0,%x0,%x0
7733   li %0,0
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   nop
7740   mfvsrd %0,%x1
7741   mtvsrd %x0,%1"
7742  [(set_attr "type"
7743            "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7744             fpload,      fpstore,    veclogical, veclogical, integer,
7745             store,       load,       *,          mtjmpr,     mfjmpr,
7746             *,           mftgpr,     mffgpr")
7747   (set_attr "size" "64")
7748   (set_attr "isa"
7749            "*,           *,          *,          p9v,        p9v,
7750             p7v,         p7v,        *,          *,          *,
7751             *,           *,          *,          *,          *,
7752             *,           p8v,        p8v")])
7753
7754;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7755;;           H-const  F-const  Special
7756
7757(define_insn "*mov<mode>_softfloat64"
7758  [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7759           "=Y,       r,      r,      *c*l,   r,      r,
7760             r,       r,      *h")
7761
7762	(match_operand:FMOVE64 1 "input_operand"
7763            "r,       Y,      r,      r,      *h,     G,
7764             H,       F,      0"))]
7765
7766  "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7767   && (gpc_reg_operand (operands[0], <MODE>mode)
7768       || gpc_reg_operand (operands[1], <MODE>mode))"
7769  "@
7770   std%U0%X0 %1,%0
7771   ld%U1%X1 %0,%1
7772   mr %0,%1
7773   mt%0 %1
7774   mf%1 %0
7775   #
7776   #
7777   #
7778   nop"
7779  [(set_attr "type"
7780            "store,   load,   *,      mtjmpr, mfjmpr, *,
7781             *,       *,      *")
7782
7783   (set_attr "length"
7784            "*,       *,      *,      *,      *,      8,
7785             12,      16,     *")])
7786
7787(define_expand "mov<mode>"
7788  [(set (match_operand:FMOVE128 0 "general_operand")
7789	(match_operand:FMOVE128 1 "any_operand"))]
7790  ""
7791{
7792  rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7793  DONE;
7794})
7795
7796;; It's important to list Y->r and r->Y before r->r because otherwise
7797;; reload, given m->r, will try to pick r->r and reload it, which
7798;; doesn't make progress.
7799
7800;; We can't split little endian direct moves of TDmode, because the words are
7801;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7802;; problematical.  Don't allow direct move for this case.
7803
7804;;		FPR load    FPR store   FPR move    FPR zero    GPR load
7805;;		GPR zero    GPR store   GPR move    MFVSRD      MTVSRD
7806
7807(define_insn_and_split "*mov<mode>_64bit_dm"
7808  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7809		"=m,        d,          d,          d,          Y,
7810		 r,         r,          r,          r,          d")
7811
7812	(match_operand:FMOVE128_FPR 1 "input_operand"
7813		"d,         m,          d,          <zero_fp>,  r,
7814		 <zero_fp>, Y,          r,          d,          r"))]
7815
7816  "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7817   && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7818   && (gpc_reg_operand (operands[0], <MODE>mode)
7819       || gpc_reg_operand (operands[1], <MODE>mode))"
7820  "#"
7821  "&& reload_completed"
7822  [(pc)]
7823{
7824  rs6000_split_multireg_move (operands[0], operands[1]);
7825  DONE;
7826}
7827  [(set_attr "length" "8")
7828   (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7829   (set_attr "max_prefixed_insns" "2")
7830   (set_attr "num_insns" "2")])
7831
7832(define_insn_and_split "*movtd_64bit_nodm"
7833  [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7834	(match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7835  "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7836   && (gpc_reg_operand (operands[0], TDmode)
7837       || gpc_reg_operand (operands[1], TDmode))"
7838  "#"
7839  "&& reload_completed"
7840  [(pc)]
7841{
7842  rs6000_split_multireg_move (operands[0], operands[1]);
7843  DONE;
7844}
7845  [(set_attr "length" "8,8,8,12,12,8")
7846   (set_attr "max_prefixed_insns" "2")
7847   (set_attr "num_insns" "2,2,2,3,3,2")])
7848
7849(define_insn_and_split "*mov<mode>_32bit"
7850  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7851	(match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7852  "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7853   && (FLOAT128_2REG_P (<MODE>mode)
7854       || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7855       || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7856   && (gpc_reg_operand (operands[0], <MODE>mode)
7857       || gpc_reg_operand (operands[1], <MODE>mode))"
7858  "#"
7859  "&& reload_completed"
7860  [(pc)]
7861{
7862  rs6000_split_multireg_move (operands[0], operands[1]);
7863  DONE;
7864}
7865  [(set_attr "length" "8,8,8,8,20,20,16")])
7866
7867(define_insn_and_split "*mov<mode>_softfloat"
7868  [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7869	(match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7870  "TARGET_SOFT_FLOAT
7871   && (gpc_reg_operand (operands[0], <MODE>mode)
7872       || gpc_reg_operand (operands[1], <MODE>mode))"
7873  "#"
7874  "&& reload_completed"
7875  [(pc)]
7876{
7877  rs6000_split_multireg_move (operands[0], operands[1]);
7878  DONE;
7879}
7880  [(set_attr_alternative "length"
7881       [(if_then_else (match_test "TARGET_POWERPC64")
7882	    (const_string "8")
7883	    (const_string "16"))
7884	(if_then_else (match_test "TARGET_POWERPC64")
7885	    (const_string "8")
7886	    (const_string "16"))
7887	(if_then_else (match_test "TARGET_POWERPC64")
7888	    (const_string "16")
7889	    (const_string "32"))
7890	(if_then_else (match_test "TARGET_POWERPC64")
7891	    (const_string "8")
7892	    (const_string "16"))])])
7893
7894(define_expand "@extenddf<mode>2"
7895  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7896	(float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7897  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7898{
7899  if (FLOAT128_IEEE_P (<MODE>mode))
7900    rs6000_expand_float128_convert (operands[0], operands[1], false);
7901  else if (TARGET_VSX)
7902    emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7903  else
7904    {
7905      rtx zero = gen_reg_rtx (DFmode);
7906      rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7907
7908      emit_insn (gen_extenddf2_fprs (<MODE>mode,
7909				     operands[0], operands[1], zero));
7910    }
7911  DONE;
7912})
7913
7914;; Allow memory operands for the source to be created by the combiner.
7915(define_insn_and_split "@extenddf<mode>2_fprs"
7916  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7917	(float_extend:IBM128
7918	 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7919   (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7920  "!TARGET_VSX && TARGET_HARD_FLOAT
7921   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7922  "#"
7923  "&& reload_completed"
7924  [(set (match_dup 3) (match_dup 1))
7925   (set (match_dup 4) (match_dup 2))]
7926{
7927  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7928  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7929
7930  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7931  operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7932})
7933
7934(define_insn_and_split "@extenddf<mode>2_vsx"
7935  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7936	(float_extend:IBM128
7937	 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7938  "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7939  "#"
7940  "&& reload_completed"
7941  [(set (match_dup 2) (match_dup 1))
7942   (set (match_dup 3) (match_dup 4))]
7943{
7944  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7945  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7946
7947  operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7948  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7949  operands[4] = CONST0_RTX (DFmode);
7950})
7951
7952(define_expand "extendsf<mode>2"
7953  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7954	(float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7955  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7956{
7957  if (FLOAT128_IEEE_P (<MODE>mode))
7958    rs6000_expand_float128_convert (operands[0], operands[1], false);
7959  else
7960    {
7961      rtx tmp = gen_reg_rtx (DFmode);
7962      emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7963      emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7964    }
7965  DONE;
7966})
7967
7968(define_expand "trunc<mode>df2"
7969  [(set (match_operand:DF 0 "gpc_reg_operand")
7970	(float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7971  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7972{
7973  if (FLOAT128_IEEE_P (<MODE>mode))
7974    {
7975      rs6000_expand_float128_convert (operands[0], operands[1], false);
7976      DONE;
7977    }
7978})
7979
7980(define_insn_and_split "trunc<mode>df2_internal1"
7981  [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7982	(float_truncate:DF
7983	 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7984  "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7985   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7986  "@
7987   #
7988   fmr %0,%1"
7989  "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7990  [(const_int 0)]
7991{
7992  emit_note (NOTE_INSN_DELETED);
7993  DONE;
7994}
7995  [(set_attr "type" "fpsimple")])
7996
7997(define_insn "trunc<mode>df2_internal2"
7998  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7999	(float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8000  "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8001   && TARGET_LONG_DOUBLE_128"
8002  "fadd %0,%1,%L1"
8003  [(set_attr "type" "fp")])
8004
8005(define_expand "trunc<mode>sf2"
8006  [(set (match_operand:SF 0 "gpc_reg_operand")
8007	(float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8008  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8009{
8010  if (FLOAT128_IEEE_P (<MODE>mode))
8011    rs6000_expand_float128_convert (operands[0], operands[1], false);
8012  else
8013    {
8014      rtx tmp = gen_reg_rtx (DFmode);
8015      emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8016      emit_insn (gen_truncdfsf2 (operands[0], tmp));
8017    }
8018  DONE;
8019})
8020
8021(define_expand "floatsi<mode>2"
8022  [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8023		   (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8024	      (clobber (match_scratch:DI 2))])]
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 if (FLOAT128_IEEE_P (<MODE>mode))
8033    {
8034      rs6000_expand_float128_convert (op0, op1, false);
8035      DONE;
8036    }
8037  else
8038    {
8039      rtx tmp = gen_reg_rtx (DFmode);
8040      expand_float (tmp, op1, false);
8041      emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8042      DONE;
8043    }
8044})
8045
8046; fadd, but rounding towards zero.
8047; This is probably not the optimal code sequence.
8048(define_insn "fix_trunc_helper<mode>"
8049  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8050	(unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8051		   UNSPEC_FIX_TRUNC_TF))
8052   (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8053  "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8054  "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8055  [(set_attr "type" "fp")
8056   (set_attr "length" "20")])
8057
8058(define_expand "fix_trunc<mode>si2"
8059  [(set (match_operand:SI 0 "gpc_reg_operand")
8060	(fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8061  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8062{
8063  rtx op0 = operands[0];
8064  rtx op1 = operands[1];
8065
8066  if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8067    ;
8068  else
8069    {
8070      if (FLOAT128_IEEE_P (<MODE>mode))
8071	rs6000_expand_float128_convert (op0, op1, false);
8072      else
8073	emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8074      DONE;
8075    }
8076})
8077
8078(define_expand "@fix_trunc<mode>si2_fprs"
8079  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8080		   (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8081	      (clobber (match_dup 2))
8082	      (clobber (match_dup 3))
8083	      (clobber (match_dup 4))
8084	      (clobber (match_dup 5))])]
8085  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8086{
8087  operands[2] = gen_reg_rtx (DFmode);
8088  operands[3] = gen_reg_rtx (DFmode);
8089  operands[4] = gen_reg_rtx (DImode);
8090  operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8091})
8092
8093(define_insn_and_split "*fix_trunc<mode>si2_internal"
8094  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8095        (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8096   (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8097   (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8098   (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8099   (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8100  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8101  "#"
8102  ""
8103  [(pc)]
8104{
8105  rtx lowword;
8106  emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8107					 operands[3]));
8108
8109  gcc_assert (MEM_P (operands[5]));
8110  lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8111
8112  emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8113  emit_move_insn (operands[5], operands[4]);
8114  emit_move_insn (operands[0], lowword);
8115  DONE;
8116})
8117
8118(define_expand "fix_trunc<mode>di2"
8119  [(set (match_operand:DI 0 "gpc_reg_operand")
8120	(fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8121  "TARGET_FLOAT128_TYPE"
8122{
8123  if (!TARGET_FLOAT128_HW)
8124    {
8125      rs6000_expand_float128_convert (operands[0], operands[1], false);
8126      DONE;
8127    }
8128})
8129
8130(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8131  [(set (match_operand:SDI 0 "gpc_reg_operand")
8132	(unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8133  "TARGET_FLOAT128_TYPE"
8134{
8135  rs6000_expand_float128_convert (operands[0], operands[1], true);
8136  DONE;
8137})
8138
8139(define_expand "floatdi<mode>2"
8140  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8141	(float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8142  "TARGET_FLOAT128_TYPE"
8143{
8144  if (!TARGET_FLOAT128_HW)
8145    {
8146      rs6000_expand_float128_convert (operands[0], operands[1], false);
8147      DONE;
8148    }
8149})
8150
8151(define_expand "floatunsdi<IEEE128:mode>2"
8152  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8153	(unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8154  "TARGET_FLOAT128_TYPE"
8155{
8156  if (!TARGET_FLOAT128_HW)
8157    {
8158      rs6000_expand_float128_convert (operands[0], operands[1], true);
8159      DONE;
8160    }
8161})
8162
8163(define_expand "floatuns<IEEE128:mode>2"
8164  [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8165	(unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8166  "TARGET_FLOAT128_TYPE"
8167{
8168  rtx op0 = operands[0];
8169  rtx op1 = operands[1];
8170
8171  if (TARGET_FLOAT128_HW)
8172    emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8173  else
8174    rs6000_expand_float128_convert (op0, op1, true);
8175  DONE;
8176})
8177
8178(define_expand "neg<mode>2"
8179  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8180	(neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8181  "FLOAT128_IEEE_P (<MODE>mode)
8182   || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8183{
8184  if (FLOAT128_IEEE_P (<MODE>mode))
8185    {
8186      if (TARGET_FLOAT128_HW)
8187	emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8188      else if (TARGET_FLOAT128_TYPE)
8189	emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8190					     operands[0], operands[1]));
8191      else
8192	{
8193	  rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8194	  rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8195						<MODE>mode,
8196						operands[1], <MODE>mode);
8197
8198	  if (target && !rtx_equal_p (target, operands[0]))
8199	    emit_move_insn (operands[0], target);
8200	}
8201      DONE;
8202    }
8203})
8204
8205(define_insn "neg<mode>2_internal"
8206  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8207	(neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8208  "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8209{
8210  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8211    return "fneg %L0,%L1\;fneg %0,%1";
8212  else
8213    return "fneg %0,%1\;fneg %L0,%L1";
8214}
8215  [(set_attr "type" "fpsimple")
8216   (set_attr "length" "8")])
8217
8218(define_expand "abs<mode>2"
8219  [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8220	(abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8221  "FLOAT128_IEEE_P (<MODE>mode)
8222   || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8223{
8224  rtx label;
8225
8226  if (FLOAT128_IEEE_P (<MODE>mode))
8227    {
8228      if (TARGET_FLOAT128_HW)
8229	{
8230	  emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8231	  DONE;
8232	}
8233      else if (TARGET_FLOAT128_TYPE)
8234	{
8235	  emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8236					       operands[0], operands[1]));
8237	  DONE;
8238	}
8239      else
8240	FAIL;
8241    }
8242
8243  label = gen_label_rtx ();
8244  emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8245  emit_label (label);
8246  DONE;
8247})
8248
8249(define_expand "@abs<mode>2_internal"
8250  [(set (match_operand:IBM128 0 "gpc_reg_operand")
8251	(match_operand:IBM128 1 "gpc_reg_operand"))
8252   (set (match_dup 3) (match_dup 5))
8253   (set (match_dup 5) (abs:DF (match_dup 5)))
8254   (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8255   (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8256			   (label_ref (match_operand 2 ""))
8257			   (pc)))
8258   (set (match_dup 6) (neg:DF (match_dup 6)))]
8259  "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8260{
8261  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8262  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8263  operands[3] = gen_reg_rtx (DFmode);
8264  operands[4] = gen_reg_rtx (CCFPmode);
8265  operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8266  operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8267})
8268
8269
8270;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8271;; register
8272
8273(define_expand "ieee_128bit_negative_zero"
8274  [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8275  "TARGET_FLOAT128_TYPE"
8276{
8277  rtvec v = rtvec_alloc (16);
8278  int i, high;
8279
8280  for (i = 0; i < 16; i++)
8281    RTVEC_ELT (v, i) = const0_rtx;
8282
8283  high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8284  RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8285
8286  rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8287  DONE;
8288})
8289
8290;; IEEE 128-bit negate
8291
8292;; We have 2 insns here for negate and absolute value.  The first uses
8293;; match_scratch so that phases like combine can recognize neg/abs as generic
8294;; insns, and second insn after the first split pass loads up the bit to
8295;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8296;; neg/abs to create the constant just once.
8297
8298(define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8299  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8300	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8301   (clobber (match_scratch:V16QI 2 "=v"))]
8302  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8303  "#"
8304  "&& 1"
8305  [(parallel [(set (match_dup 0)
8306		   (neg:IEEE128 (match_dup 1)))
8307	      (use (match_dup 2))])]
8308{
8309  if (GET_CODE (operands[2]) == SCRATCH)
8310    operands[2] = gen_reg_rtx (V16QImode);
8311
8312  operands[3] = gen_reg_rtx (V16QImode);
8313  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8314}
8315  [(set_attr "length" "8")
8316   (set_attr "type" "vecsimple")])
8317
8318(define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8319  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8320	(neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8321   (use (match_operand:V16QI 2 "register_operand" "v"))]
8322  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8323  "xxlxor %x0,%x1,%x2"
8324  [(set_attr "type" "veclogical")])
8325
8326;; IEEE 128-bit absolute value
8327(define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8328  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8329	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8330   (clobber (match_scratch:V16QI 2 "=v"))]
8331  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8332  "#"
8333  "&& 1"
8334  [(parallel [(set (match_dup 0)
8335		   (abs:IEEE128 (match_dup 1)))
8336	      (use (match_dup 2))])]
8337{
8338  if (GET_CODE (operands[2]) == SCRATCH)
8339    operands[2] = gen_reg_rtx (V16QImode);
8340
8341  operands[3] = gen_reg_rtx (V16QImode);
8342  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8343}
8344  [(set_attr "length" "8")
8345   (set_attr "type" "vecsimple")])
8346
8347(define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8348  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8349	(abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8350   (use (match_operand:V16QI 2 "register_operand" "v"))]
8351  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8352  "xxlandc %x0,%x1,%x2"
8353  [(set_attr "type" "veclogical")])
8354
8355;; IEEE 128-bit negative absolute value
8356(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8357  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8358	(neg:IEEE128
8359	 (abs:IEEE128
8360	  (match_operand:IEEE128 1 "register_operand" "wa"))))
8361   (clobber (match_scratch:V16QI 2 "=v"))]
8362  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8363   && FLOAT128_IEEE_P (<MODE>mode)"
8364  "#"
8365  "&& 1"
8366  [(parallel [(set (match_dup 0)
8367		   (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8368	      (use (match_dup 2))])]
8369{
8370  if (GET_CODE (operands[2]) == SCRATCH)
8371    operands[2] = gen_reg_rtx (V16QImode);
8372
8373  operands[3] = gen_reg_rtx (V16QImode);
8374  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8375}
8376  [(set_attr "length" "8")
8377   (set_attr "type" "vecsimple")])
8378
8379(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8380  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8381	(neg:IEEE128
8382	 (abs:IEEE128
8383	  (match_operand:IEEE128 1 "register_operand" "wa"))))
8384   (use (match_operand:V16QI 2 "register_operand" "v"))]
8385  "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8386  "xxlor %x0,%x1,%x2"
8387  [(set_attr "type" "veclogical")])
8388
8389;; Float128 conversion functions.  These expand to library function calls.
8390;; We use expand to convert from IBM double double to IEEE 128-bit
8391;; and trunc for the opposite.
8392(define_expand "extendiftf2"
8393  [(set (match_operand:TF 0 "gpc_reg_operand")
8394	(float_extend: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 "extendifkf2"
8402  [(set (match_operand:KF 0 "gpc_reg_operand")
8403	(float_extend: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 "extendtfkf2"
8411  [(set (match_operand:KF 0 "gpc_reg_operand")
8412	(float_extend:KF (match_operand:TF 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 "extendtfif2"
8420  [(set (match_operand:IF 0 "gpc_reg_operand")
8421	(float_extend: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_expand "trunciftf2"
8429  [(set (match_operand:TF 0 "gpc_reg_operand")
8430	(float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8431  "TARGET_FLOAT128_TYPE"
8432{
8433  rs6000_expand_float128_convert (operands[0], operands[1], false);
8434  DONE;
8435})
8436
8437(define_expand "truncifkf2"
8438  [(set (match_operand:KF 0 "gpc_reg_operand")
8439	(float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8440  "TARGET_FLOAT128_TYPE"
8441{
8442  rs6000_expand_float128_convert (operands[0], operands[1], false);
8443  DONE;
8444})
8445
8446(define_expand "trunckftf2"
8447  [(set (match_operand:TF 0 "gpc_reg_operand")
8448	(float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8449  "TARGET_FLOAT128_TYPE"
8450{
8451  rs6000_expand_float128_convert (operands[0], operands[1], false);
8452  DONE;
8453})
8454
8455(define_expand "trunctfif2"
8456  [(set (match_operand:IF 0 "gpc_reg_operand")
8457	(float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8458  "TARGET_FLOAT128_TYPE"
8459{
8460  rs6000_expand_float128_convert (operands[0], operands[1], false);
8461  DONE;
8462})
8463
8464(define_insn_and_split "*extend<mode>tf2_internal"
8465  [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8466	(float_extend:TF
8467	 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8468   "TARGET_FLOAT128_TYPE
8469    && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8470  "#"
8471  "&& reload_completed"
8472  [(set (match_dup 0) (match_dup 2))]
8473{
8474  operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8475})
8476
8477(define_insn_and_split "*extendtf<mode>2_internal"
8478  [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8479	(float_extend:IFKF
8480	 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8481   "TARGET_FLOAT128_TYPE
8482    && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8483  "#"
8484  "&& reload_completed"
8485  [(set (match_dup 0) (match_dup 2))]
8486{
8487  operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8488})
8489
8490
8491;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8492;; must have 3 arguments, and scratch register constraint must be a single
8493;; constraint.
8494
8495;; Reload patterns to support gpr load/store with misaligned mem.
8496;; and multiple gpr load/store at offset >= 0xfffc
8497(define_expand "reload_<mode>_store"
8498  [(parallel [(match_operand 0 "memory_operand" "=m")
8499              (match_operand 1 "gpc_reg_operand" "r")
8500              (match_operand:GPR 2 "register_operand" "=&b")])]
8501  ""
8502{
8503  rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8504  DONE;
8505})
8506
8507(define_expand "reload_<mode>_load"
8508  [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8509              (match_operand 1 "memory_operand" "m")
8510              (match_operand:GPR 2 "register_operand" "=b")])]
8511  ""
8512{
8513  rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8514  DONE;
8515})
8516
8517
8518;; Reload patterns for various types using the vector registers.  We may need
8519;; an additional base register to convert the reg+offset addressing to reg+reg
8520;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8521;; index register for gpr registers.
8522(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8523  [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8524              (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8525              (match_operand:P 2 "register_operand" "=b")])]
8526  "<P:tptrsize>"
8527{
8528  rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8529  DONE;
8530})
8531
8532(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8533  [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8534              (match_operand:RELOAD 1 "memory_operand" "m")
8535              (match_operand:P 2 "register_operand" "=b")])]
8536  "<P:tptrsize>"
8537{
8538  rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8539  DONE;
8540})
8541
8542
8543;; Reload sometimes tries to move the address to a GPR, and can generate
8544;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8545;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8546
8547(define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8548  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8549	(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8550		       (match_operand:P 2 "reg_or_cint_operand" "rI"))
8551	       (const_int -16)))]
8552  "TARGET_ALTIVEC && reload_completed"
8553  "#"
8554  "&& reload_completed"
8555  [(set (match_dup 0)
8556	(plus:P (match_dup 1)
8557		(match_dup 2)))
8558   (set (match_dup 0)
8559	(and:P (match_dup 0)
8560	       (const_int -16)))])
8561
8562;; Power8 merge instructions to allow direct move to/from floating point
8563;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8564;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8565;; value, since it is allocated in reload and not all of the flow information
8566;; is setup for it.  We have two patterns to do the two moves between gprs and
8567;; fprs.  There isn't a dependancy between the two, but we could potentially
8568;; schedule other instructions between the two instructions.
8569
8570(define_insn "p8_fmrgow_<mode>"
8571  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8572	(unspec:FMOVE64X [
8573		(match_operand:DF 1 "register_operand" "d")
8574		(match_operand:DF 2 "register_operand" "d")]
8575			 UNSPEC_P8V_FMRGOW))]
8576  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8577  "fmrgow %0,%1,%2"
8578  [(set_attr "type" "fpsimple")])
8579
8580(define_insn "p8_mtvsrwz"
8581  [(set (match_operand:DF 0 "register_operand" "=d")
8582	(unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8583		   UNSPEC_P8V_MTVSRWZ))]
8584  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8585  "mtvsrwz %x0,%1"
8586  [(set_attr "type" "mftgpr")])
8587
8588(define_insn_and_split "reload_fpr_from_gpr<mode>"
8589  [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8590	(unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8591			 UNSPEC_P8V_RELOAD_FROM_GPR))
8592   (clobber (match_operand:IF 2 "register_operand" "=d"))]
8593  "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8594  "#"
8595  "&& reload_completed"
8596  [(const_int 0)]
8597{
8598  rtx dest = operands[0];
8599  rtx src = operands[1];
8600  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8601  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8602  rtx gpr_hi_reg = gen_highpart (SImode, src);
8603  rtx gpr_lo_reg = gen_lowpart (SImode, src);
8604
8605  emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8606  emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8607  emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8608  DONE;
8609}
8610  [(set_attr "length" "12")
8611   (set_attr "type" "three")])
8612
8613;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8614(define_insn "p8_mtvsrd_df"
8615  [(set (match_operand:DF 0 "register_operand" "=wa")
8616	(unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8617		   UNSPEC_P8V_MTVSRD))]
8618  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8619  "mtvsrd %x0,%1"
8620  [(set_attr "type" "mftgpr")])
8621
8622(define_insn "p8_xxpermdi_<mode>"
8623  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8624	(unspec:FMOVE128_GPR [
8625		(match_operand:DF 1 "register_operand" "wa")
8626		(match_operand:DF 2 "register_operand" "wa")]
8627		UNSPEC_P8V_XXPERMDI))]
8628  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8629  "xxpermdi %x0,%x1,%x2,0"
8630  [(set_attr "type" "vecperm")])
8631
8632(define_insn_and_split "reload_vsx_from_gpr<mode>"
8633  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8634	(unspec:FMOVE128_GPR
8635	 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8636	 UNSPEC_P8V_RELOAD_FROM_GPR))
8637   (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8638  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8639  "#"
8640  "&& reload_completed"
8641  [(const_int 0)]
8642{
8643  rtx dest = operands[0];
8644  rtx src = operands[1];
8645  /* You might think that we could use op0 as one temp and a DF clobber
8646     as op2, but you'd be wrong.  Secondary reload move patterns don't
8647     check for overlap of the clobber and the destination.  */
8648  rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8649  rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8650  rtx gpr_hi_reg = gen_highpart (DImode, src);
8651  rtx gpr_lo_reg = gen_lowpart (DImode, src);
8652
8653  emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8654  emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8655  emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8656  DONE;
8657}
8658  [(set_attr "length" "12")
8659   (set_attr "type" "three")])
8660
8661(define_split
8662  [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8663	(match_operand:FMOVE128_GPR 1 "input_operand"))]
8664  "reload_completed
8665   && (int_reg_operand (operands[0], <MODE>mode)
8666       || int_reg_operand (operands[1], <MODE>mode))
8667   && (!TARGET_DIRECT_MOVE_128
8668       || (!vsx_register_operand (operands[0], <MODE>mode)
8669           && !vsx_register_operand (operands[1], <MODE>mode)))"
8670  [(pc)]
8671{
8672  rs6000_split_multireg_move (operands[0], operands[1]);
8673  DONE;
8674})
8675
8676;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8677;; type is stored internally as double precision in the VSX registers, we have
8678;; to convert it from the vector format.
8679(define_insn "p8_mtvsrd_sf"
8680  [(set (match_operand:SF 0 "register_operand" "=wa")
8681	(unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8682		   UNSPEC_P8V_MTVSRD))]
8683  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8684  "mtvsrd %x0,%1"
8685  [(set_attr "type" "mftgpr")])
8686
8687(define_insn_and_split "reload_vsx_from_gprsf"
8688  [(set (match_operand:SF 0 "register_operand" "=wa")
8689	(unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8690		   UNSPEC_P8V_RELOAD_FROM_GPR))
8691   (clobber (match_operand:DI 2 "register_operand" "=r"))]
8692  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8693  "#"
8694  "&& reload_completed"
8695  [(const_int 0)]
8696{
8697  rtx op0 = operands[0];
8698  rtx op1 = operands[1];
8699  rtx op2 = operands[2];
8700  rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8701
8702  /* Move SF value to upper 32-bits for xscvspdpn.  */
8703  emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8704  emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8705  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8706  DONE;
8707}
8708  [(set_attr "length" "8")
8709   (set_attr "type" "two")])
8710
8711;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8712;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8713;; and then doing a move of that.
8714(define_insn "p8_mfvsrd_3_<mode>"
8715  [(set (match_operand:DF 0 "register_operand" "=r")
8716	(unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8717		   UNSPEC_P8V_RELOAD_FROM_VSX))]
8718  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8719  "mfvsrd %0,%x1"
8720  [(set_attr "type" "mftgpr")])
8721
8722(define_insn_and_split "reload_gpr_from_vsx<mode>"
8723  [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8724	(unspec:FMOVE128_GPR
8725	 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8726	 UNSPEC_P8V_RELOAD_FROM_VSX))
8727   (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8728  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8729  "#"
8730  "&& reload_completed"
8731  [(const_int 0)]
8732{
8733  rtx dest = operands[0];
8734  rtx src = operands[1];
8735  rtx tmp = operands[2];
8736  rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8737  rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8738
8739  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8740  emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8741  emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8742  DONE;
8743}
8744  [(set_attr "length" "12")
8745   (set_attr "type" "three")])
8746
8747;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8748;; type is stored internally as double precision, we have to convert it to the
8749;; vector format.
8750
8751(define_insn_and_split "reload_gpr_from_vsxsf"
8752  [(set (match_operand:SF 0 "register_operand" "=r")
8753	(unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8754		   UNSPEC_P8V_RELOAD_FROM_VSX))
8755   (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8756  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8757  "#"
8758  "&& reload_completed"
8759  [(const_int 0)]
8760{
8761  rtx op0 = operands[0];
8762  rtx op1 = operands[1];
8763  rtx op2 = operands[2];
8764  rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8765  rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8766
8767  emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8768  emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8769  DONE;
8770}
8771  [(set_attr "length" "8")
8772   (set_attr "type" "two")
8773   (set_attr "isa" "p8v")])
8774
8775;; Next come the multi-word integer load and store and the load and store
8776;; multiple insns.
8777
8778;; List r->r after r->Y, otherwise reload will try to reload a
8779;; non-offsettable address by using r->r which won't make progress.
8780;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8781;; a gpr into a fpr instead of reloading an invalid 'Y' address
8782
8783;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8784;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8785;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8786;;        AVX const  
8787
8788(define_insn "*movdi_internal32"
8789  [(set (match_operand:DI 0 "nonimmediate_operand"
8790         "=Y,        r,         r,         m,         ^d,        ^d,
8791          r,         wY,        Z,         ^v,        $v,        ^wa,
8792          wa,        wa,        v,         wa,        *i,        v,
8793          v")
8794	(match_operand:DI 1 "input_operand"
8795         "r,         Y,         r,         ^d,        m,         ^d,
8796          IJKnF,     ^v,        $v,        wY,        Z,         ^wa,
8797          Oj,        wM,        OjwM,      Oj,        wM,        wS,
8798          wB"))]
8799  "! TARGET_POWERPC64
8800   && (gpc_reg_operand (operands[0], DImode)
8801       || gpc_reg_operand (operands[1], DImode))"
8802  "@
8803   #
8804   #
8805   #
8806   stfd%U0%X0 %1,%0
8807   lfd%U1%X1 %0,%1
8808   fmr %0,%1
8809   #
8810   stxsd %1,%0
8811   stxsdx %x1,%y0
8812   lxsd %0,%1
8813   lxsdx %x0,%y1
8814   xxlor %x0,%x1,%x1
8815   xxspltib %x0,0
8816   xxspltib %x0,255
8817   vspltisw %0,%1
8818   xxlxor %x0,%x0,%x0
8819   xxlorc %x0,%x0,%x0
8820   #
8821   #"
8822  [(set_attr "type"
8823         "store,     load,      *,         fpstore,   fpload,    fpsimple,
8824          *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8825          vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8826          vecsimple")
8827   (set_attr "size" "64")
8828   (set_attr "length"
8829         "8,         8,         8,         *,         *,         *,
8830          16,        *,         *,         *,         *,         *,
8831          *,         *,         *,         *,         *,         8,
8832          *")
8833   (set_attr "isa"
8834         "*,         *,         *,         *,         *,         *,
8835          *,         p9v,       p7v,       p9v,       p7v,       *,
8836          p9v,       p9v,       p7v,       *,         *,         p7v,
8837          p7v")])
8838
8839(define_split
8840  [(set (match_operand:DI 0 "gpc_reg_operand")
8841	(match_operand:DI 1 "const_int_operand"))]
8842  "! TARGET_POWERPC64 && reload_completed
8843   && gpr_or_gpr_p (operands[0], operands[1])
8844   && !direct_move_p (operands[0], operands[1])"
8845  [(set (match_dup 2) (match_dup 4))
8846   (set (match_dup 3) (match_dup 1))]
8847{
8848  HOST_WIDE_INT value = INTVAL (operands[1]);
8849  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8850				       DImode);
8851  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8852				       DImode);
8853  operands[4] = GEN_INT (value >> 32);
8854  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8855})
8856
8857(define_split
8858  [(set (match_operand:DIFD 0 "nonimmediate_operand")
8859        (match_operand:DIFD 1 "input_operand"))]
8860  "reload_completed && !TARGET_POWERPC64
8861   && gpr_or_gpr_p (operands[0], operands[1])
8862   && !direct_move_p (operands[0], operands[1])"
8863  [(pc)]
8864{
8865  rs6000_split_multireg_move (operands[0], operands[1]);
8866  DONE;
8867})
8868
8869;;	   GPR store   GPR load    GPR move
8870;;	   GPR li      GPR lis     GPR pli     GPR #
8871;;	   FPR store   FPR load    FPR move
8872;;	   AVX store   AVX store   AVX load    AVX load    VSX move
8873;;	   P9 0        P9 -1       AVX 0/-1    VSX 0       VSX -1
8874;;	   P9 const    AVX const
8875;;	   From SPR    To SPR      SPR<->SPR
8876;;	   VSX->GPR    GPR->VSX
8877(define_insn "*movdi_internal64"
8878  [(set (match_operand:DI 0 "nonimmediate_operand"
8879	  "=YZ,        r,          r,
8880	   r,          r,          r,          r,
8881	   m,          ^d,         ^d,
8882	   wY,         Z,          $v,         $v,         ^wa,
8883	   wa,         wa,         v,          wa,         wa,
8884	   v,          v,
8885	   r,          *h,         *h,
8886	   ?r,         ?wa")
8887	(match_operand:DI 1 "input_operand"
8888	  "r,          YZ,         r,
8889	   I,          L,          eI,         nF,
8890	   ^d,         m,          ^d,
8891	   ^v,         $v,         wY,         Z,          ^wa,
8892	   Oj,         wM,         OjwM,       Oj,         wM,
8893	   wS,         wB,
8894	   *h,         r,          0,
8895	   wa,         r"))]
8896  "TARGET_POWERPC64
8897   && (gpc_reg_operand (operands[0], DImode)
8898       || gpc_reg_operand (operands[1], DImode))"
8899  "@
8900   std%U0%X0 %1,%0
8901   ld%U1%X1 %0,%1
8902   mr %0,%1
8903   li %0,%1
8904   lis %0,%v1
8905   li %0,%1
8906   #
8907   stfd%U0%X0 %1,%0
8908   lfd%U1%X1 %0,%1
8909   fmr %0,%1
8910   stxsd %1,%0
8911   stxsdx %x1,%y0
8912   lxsd %0,%1
8913   lxsdx %x0,%y1
8914   xxlor %x0,%x1,%x1
8915   xxspltib %x0,0
8916   xxspltib %x0,255
8917   #
8918   xxlxor %x0,%x0,%x0
8919   xxlorc %x0,%x0,%x0
8920   #
8921   #
8922   mf%1 %0
8923   mt%0 %1
8924   nop
8925   mfvsrd %0,%x1
8926   mtvsrd %x0,%1"
8927  [(set_attr "type"
8928	  "store,      load,       *,
8929	   *,          *,          *,          *,
8930	   fpstore,    fpload,     fpsimple,
8931	   fpstore,    fpstore,    fpload,     fpload,     veclogical,
8932	   vecsimple,  vecsimple,  vecsimple,  veclogical, veclogical,
8933	   vecsimple,  vecsimple,
8934	   mfjmpr,     mtjmpr,     *,
8935	   mftgpr,     mffgpr")
8936   (set_attr "size" "64")
8937   (set_attr "length"
8938	  "*,          *,          *,
8939	   *,          *,          *,          20,
8940	   *,          *,          *,
8941	   *,          *,          *,          *,          *,
8942	   *,          *,          *,          *,          *,
8943	   8,          *,
8944	   *,          *,          *,
8945	   *,          *")
8946   (set_attr "isa"
8947	  "*,          *,          *,
8948	   *,          *,          p10,        *,
8949	   *,          *,          *,
8950	   p9v,        p7v,        p9v,        p7v,        *,
8951	   p9v,        p9v,        p7v,        *,          *,
8952	   p7v,        p7v,
8953	   *,          *,          *,
8954	   p8v,        p8v")])
8955
8956; Some DImode loads are best done as a load of -1 followed by a mask
8957; instruction.
8958(define_split
8959  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8960	(match_operand:DI 1 "const_int_operand"))]
8961  "TARGET_POWERPC64
8962   && num_insns_constant (operands[1], DImode) > 1
8963   && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8964   && rs6000_is_valid_and_mask (operands[1], DImode)"
8965  [(set (match_dup 0)
8966	(const_int -1))
8967   (set (match_dup 0)
8968	(and:DI (match_dup 0)
8969		(match_dup 1)))]
8970  "")
8971
8972;; Split a load of a large constant into the appropriate five-instruction
8973;; sequence.  Handle anything in a constant number of insns.
8974;; When non-easy constants can go in the TOC, this should use
8975;; easy_fp_constant predicate.
8976(define_split
8977  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8978	(match_operand:DI 1 "const_int_operand"))]
8979  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8980  [(set (match_dup 0) (match_dup 2))
8981   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8982{
8983  if (rs6000_emit_set_const (operands[0], operands[1]))
8984    DONE;
8985  else
8986    FAIL;
8987})
8988
8989(define_split
8990  [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8991	(match_operand:DI 1 "const_scalar_int_operand"))]
8992  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8993  [(set (match_dup 0) (match_dup 2))
8994   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8995{
8996  if (rs6000_emit_set_const (operands[0], operands[1]))
8997    DONE;
8998  else
8999    FAIL;
9000})
9001
9002(define_split
9003  [(set (match_operand:DI 0 "altivec_register_operand")
9004	(match_operand:DI 1 "s5bit_cint_operand"))]
9005  "TARGET_VSX && reload_completed"
9006  [(const_int 0)]
9007{
9008  rtx op0 = operands[0];
9009  rtx op1 = operands[1];
9010  int r = REGNO (op0);
9011  rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9012
9013  emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9014  if (op1 != const0_rtx && op1 != constm1_rtx)
9015    {
9016      rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9017      emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9018    }
9019  DONE;
9020})
9021
9022;; Split integer constants that can be loaded with XXSPLTIB and a
9023;; sign extend operation.
9024(define_split
9025  [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9026	(match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9027  "TARGET_P9_VECTOR && reload_completed"
9028  [(const_int 0)]
9029{
9030  rtx op0 = operands[0];
9031  rtx op1 = operands[1];
9032  int r = REGNO (op0);
9033  rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9034
9035  emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9036  if (<MODE>mode == DImode)
9037    emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9038  else if (<MODE>mode == SImode)
9039    emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9040  else if (<MODE>mode == HImode)
9041    {
9042      rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9043      emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9044    }
9045  DONE;
9046})
9047
9048
9049;; TImode/PTImode is similar, except that we usually want to compute the
9050;; address into a register and use lsi/stsi (the exception is during reload).
9051
9052(define_insn "*mov<mode>_string"
9053  [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9054	(match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9055  "! TARGET_POWERPC64
9056   && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9057   && (gpc_reg_operand (operands[0], <MODE>mode)
9058       || gpc_reg_operand (operands[1], <MODE>mode))"
9059  "#"
9060  [(set_attr "type" "store,store,load,load,*,*")
9061   (set_attr "update" "yes")
9062   (set_attr "indexed" "yes")
9063   (set_attr "cell_micro" "conditional")])
9064
9065(define_insn "*mov<mode>_ppc64"
9066  [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9067	(match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9068  "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9069   && (gpc_reg_operand (operands[0], <MODE>mode)
9070       || gpc_reg_operand (operands[1], <MODE>mode)))"
9071{
9072  return rs6000_output_move_128bit (operands);
9073}
9074  [(set_attr "type" "store,store,load,load,*,*")
9075   (set_attr "length" "8")
9076   (set_attr "max_prefixed_insns" "2")])
9077
9078(define_split
9079  [(set (match_operand:TI2 0 "int_reg_operand")
9080	(match_operand:TI2 1 "const_scalar_int_operand"))]
9081  "TARGET_POWERPC64
9082   && (VECTOR_MEM_NONE_P (<MODE>mode)
9083       || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9084  [(set (match_dup 2) (match_dup 4))
9085   (set (match_dup 3) (match_dup 5))]
9086{
9087  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9088				       <MODE>mode);
9089  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9090				       <MODE>mode);
9091  if (CONST_WIDE_INT_P (operands[1]))
9092    {
9093      operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9094      operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9095    }
9096  else if (CONST_INT_P (operands[1]))
9097    {
9098      operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9099      operands[5] = operands[1];
9100    }
9101  else
9102    FAIL;
9103})
9104
9105(define_split
9106  [(set (match_operand:TI2 0 "nonimmediate_operand")
9107        (match_operand:TI2 1 "input_operand"))]
9108  "reload_completed
9109   && gpr_or_gpr_p (operands[0], operands[1])
9110   && !direct_move_p (operands[0], operands[1])
9111   && !quad_load_store_p (operands[0], operands[1])"
9112  [(pc)]
9113{
9114  rs6000_split_multireg_move (operands[0], operands[1]);
9115  DONE;
9116})
9117
9118(define_expand "setmemsi"
9119  [(parallel [(set (match_operand:BLK 0 "")
9120		   (match_operand 2 "const_int_operand"))
9121	      (use (match_operand:SI 1 ""))
9122	      (use (match_operand:SI 3 ""))])]
9123  ""
9124{
9125  /* If value to set is not zero, use the library routine.  */
9126  if (operands[2] != const0_rtx)
9127    FAIL;
9128
9129  if (expand_block_clear (operands))
9130    DONE;
9131  else
9132    FAIL;
9133})
9134
9135;; String compare N insn.
9136;; Argument 0 is the target (result)
9137;; Argument 1 is the destination
9138;; Argument 2 is the source
9139;; Argument 3 is the length
9140;; Argument 4 is the alignment
9141
9142(define_expand "cmpstrnsi"
9143  [(parallel [(set (match_operand:SI 0)
9144               (compare:SI (match_operand:BLK 1)
9145                           (match_operand:BLK 2)))
9146	      (use (match_operand:SI 3))
9147	      (use (match_operand:SI 4))])]
9148  "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9149{
9150  if (optimize_insn_for_size_p ())
9151    FAIL;
9152
9153  if (expand_strn_compare (operands, 0))
9154    DONE;
9155  else	
9156    FAIL;
9157})
9158
9159;; String compare insn.
9160;; Argument 0 is the target (result)
9161;; Argument 1 is the destination
9162;; Argument 2 is the source
9163;; Argument 3 is the alignment
9164
9165(define_expand "cmpstrsi"
9166  [(parallel [(set (match_operand:SI 0)
9167               (compare:SI (match_operand:BLK 1)
9168                           (match_operand:BLK 2)))
9169	      (use (match_operand:SI 3))])]
9170  "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9171{
9172  if (optimize_insn_for_size_p ())
9173    FAIL;
9174
9175  if (expand_strn_compare (operands, 1))
9176    DONE;
9177  else	
9178    FAIL;
9179})
9180
9181;; Block compare insn.
9182;; Argument 0 is the target (result)
9183;; Argument 1 is the destination
9184;; Argument 2 is the source
9185;; Argument 3 is the length
9186;; Argument 4 is the alignment
9187
9188(define_expand "cmpmemsi"
9189  [(parallel [(set (match_operand:SI 0)
9190               (compare:SI (match_operand:BLK 1)
9191                           (match_operand:BLK 2)))
9192	      (use (match_operand:SI 3))
9193	      (use (match_operand:SI 4))])]
9194  "TARGET_POPCNTD"
9195{
9196  if (expand_block_compare (operands))
9197    DONE;
9198  else
9199    FAIL;
9200})
9201
9202;; String/block copy insn (source and destination must not overlap).
9203;; Argument 0 is the destination
9204;; Argument 1 is the source
9205;; Argument 2 is the length
9206;; Argument 3 is the alignment
9207
9208(define_expand "cpymemsi"
9209  [(parallel [(set (match_operand:BLK 0 "")
9210		   (match_operand:BLK 1 ""))
9211	      (use (match_operand:SI 2 ""))
9212	      (use (match_operand:SI 3 ""))])]
9213  ""
9214{
9215  if (expand_block_move (operands, false))
9216    DONE;
9217  else
9218    FAIL;
9219})
9220
9221;; String/block move insn (source and destination may overlap).
9222;; Argument 0 is the destination
9223;; Argument 1 is the source
9224;; Argument 2 is the length
9225;; Argument 3 is the alignment
9226
9227(define_expand "movmemsi"
9228  [(parallel [(set (match_operand:BLK 0 "")
9229		   (match_operand:BLK 1 ""))
9230	      (use (match_operand:SI 2 ""))
9231	      (use (match_operand:SI 3 ""))])]
9232  ""
9233{
9234  if (expand_block_move (operands, true))
9235    DONE;
9236  else
9237    FAIL;
9238})
9239
9240
9241;; Define insns that do load or store with update.  Some of these we can
9242;; get by using pre-decrement or pre-increment, but the hardware can also
9243;; do cases where the increment is not the size of the object.
9244;;
9245;; In all these cases, we use operands 0 and 1 for the register being
9246;; incremented because those are the operands that local-alloc will
9247;; tie and these are the pair most likely to be tieable (and the ones
9248;; that will benefit the most).
9249
9250(define_insn "*movdi_update1"
9251  [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9252	(mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9253			(match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9254   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9255	(plus:P (match_dup 1) (match_dup 2)))]
9256  "TARGET_POWERPC64 && TARGET_UPDATE
9257   && (!avoiding_indexed_address_p (DImode)
9258       || !gpc_reg_operand (operands[2], Pmode))"
9259  "@
9260   ldux %3,%0,%2
9261   ldu %3,%2(%0)"
9262  [(set_attr "type" "load")
9263   (set_attr "update" "yes")
9264   (set_attr "indexed" "yes,no")])
9265
9266(define_insn "movdi_<mode>_update"
9267  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9268			(match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9269	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
9270   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9271	(plus:P (match_dup 1) (match_dup 2)))]
9272  "TARGET_POWERPC64 && TARGET_UPDATE
9273   && (!avoiding_indexed_address_p (DImode)
9274       || !gpc_reg_operand (operands[2], Pmode)
9275       || (REG_P (operands[0])
9276	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9277  "@
9278   stdux %3,%0,%2
9279   stdu %3,%2(%0)"
9280  [(set_attr "type" "store")
9281   (set_attr "update" "yes")
9282   (set_attr "indexed" "yes,no")])
9283
9284;; This pattern is only conditional on TARGET_64BIT, as it is
9285;; needed for stack allocation, even if the user passes -mno-update.
9286(define_insn "movdi_update_stack"
9287  [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9288			 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9289	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
9290   (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9291	(plus:DI (match_dup 1) (match_dup 2)))]
9292  "TARGET_64BIT"
9293  "@
9294   stdux %3,%0,%2
9295   stdu %3,%2(%0)"
9296  [(set_attr "type" "store")
9297   (set_attr "update" "yes")
9298   (set_attr "indexed" "yes,no")])
9299
9300(define_insn "*movsi_update1"
9301  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9302	(mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9303			(match_operand:P 2 "reg_or_short_operand" "r,I"))))
9304   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9305	(plus:P (match_dup 1) (match_dup 2)))]
9306  "TARGET_UPDATE
9307   && (!avoiding_indexed_address_p (SImode)
9308       || !gpc_reg_operand (operands[2], Pmode))"
9309  "@
9310   lwzux %3,%0,%2
9311   lwzu %3,%2(%0)"
9312  [(set_attr "type" "load")
9313   (set_attr "update" "yes")
9314   (set_attr "indexed" "yes,no")])
9315
9316(define_insn "*movsi_update2"
9317  [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9318	(sign_extend:EXTSI
9319	 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9320			 (match_operand:P 2 "gpc_reg_operand" "r")))))
9321   (set (match_operand:P 0 "gpc_reg_operand" "=b")
9322	(plus:P (match_dup 1) (match_dup 2)))]
9323  "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9324  "lwaux %3,%0,%2"
9325  [(set_attr "type" "load")
9326   (set_attr "sign_extend" "yes")
9327   (set_attr "update" "yes")
9328   (set_attr "indexed" "yes")])
9329
9330(define_insn "movsi_<mode>_update"
9331  [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9332			(match_operand:P 2 "reg_or_short_operand" "r,I")))
9333	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
9334   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9335	(plus:P (match_dup 1) (match_dup 2)))]
9336  "TARGET_UPDATE
9337   && (!avoiding_indexed_address_p (SImode)
9338       || !gpc_reg_operand (operands[2], Pmode)
9339       || (REG_P (operands[0])
9340	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9341  "@
9342   stwux %3,%0,%2
9343   stwu %3,%2(%0)"
9344  [(set_attr "type" "store")
9345   (set_attr "update" "yes")
9346   (set_attr "indexed" "yes,no")])
9347
9348;; This is an unconditional pattern; needed for stack allocation, even
9349;; if the user passes -mno-update.
9350(define_insn "movsi_update_stack"
9351  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9352			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9353	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
9354   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9355	(plus:SI (match_dup 1) (match_dup 2)))]
9356  "TARGET_32BIT"
9357  "@
9358   stwux %3,%0,%2
9359   stwu %3,%2(%0)"
9360  [(set_attr "type" "store")
9361   (set_attr "update" "yes")
9362   (set_attr "indexed" "yes,no")])
9363
9364(define_insn "*movhi_update1"
9365  [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9366	(mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9367			(match_operand:P 2 "reg_or_short_operand" "r,I"))))
9368   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9369	(plus:P (match_dup 1) (match_dup 2)))]
9370  "TARGET_UPDATE
9371   && (!avoiding_indexed_address_p (HImode)
9372       || !gpc_reg_operand (operands[2], SImode))"
9373  "@
9374   lhzux %3,%0,%2
9375   lhzu %3,%2(%0)"
9376  [(set_attr "type" "load")
9377   (set_attr "update" "yes")
9378   (set_attr "indexed" "yes,no")])
9379
9380(define_insn "*movhi_update2"
9381  [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9382	(zero_extend:EXTHI
9383	 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9384			 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9385   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9386	(plus:P (match_dup 1) (match_dup 2)))]
9387  "TARGET_UPDATE
9388   && (!avoiding_indexed_address_p (HImode)
9389       || !gpc_reg_operand (operands[2], Pmode))"
9390  "@
9391   lhzux %3,%0,%2
9392   lhzu %3,%2(%0)"
9393  [(set_attr "type" "load")
9394   (set_attr "update" "yes")
9395   (set_attr "indexed" "yes,no")])
9396
9397(define_insn "*movhi_update3"
9398  [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9399	(sign_extend:EXTHI
9400	 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9401			 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9402   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9403	(plus:P (match_dup 1) (match_dup 2)))]
9404  "TARGET_UPDATE
9405   && !(avoiding_indexed_address_p (HImode)
9406	&& gpc_reg_operand (operands[2], Pmode))"
9407  "@
9408   lhaux %3,%0,%2
9409   lhau %3,%2(%0)"
9410  [(set_attr "type" "load")
9411   (set_attr "sign_extend" "yes")
9412   (set_attr "update" "yes")
9413   (set_attr "indexed" "yes,no")])
9414
9415(define_insn "*movhi_update4"
9416  [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9417			(match_operand:P 2 "reg_or_short_operand" "r,I")))
9418	(match_operand:HI 3 "gpc_reg_operand" "r,r"))
9419   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9420	(plus:P (match_dup 1) (match_dup 2)))]
9421  "TARGET_UPDATE
9422   && (!avoiding_indexed_address_p (HImode)
9423       || !gpc_reg_operand (operands[2], Pmode))"
9424  "@
9425   sthux %3,%0,%2
9426   sthu %3,%2(%0)"
9427  [(set_attr "type" "store")
9428   (set_attr "update" "yes")
9429   (set_attr "indexed" "yes,no")])
9430
9431(define_insn "*movqi_update1"
9432  [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9433	(mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9434			(match_operand:P 2 "reg_or_short_operand" "r,I"))))
9435   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9436	(plus:P (match_dup 1) (match_dup 2)))]
9437  "TARGET_UPDATE
9438   && (!avoiding_indexed_address_p (QImode)
9439       || !gpc_reg_operand (operands[2], Pmode))"
9440  "@
9441   lbzux %3,%0,%2
9442   lbzu %3,%2(%0)"
9443  [(set_attr "type" "load")
9444   (set_attr "update" "yes")
9445   (set_attr "indexed" "yes,no")])
9446
9447(define_insn "*movqi_update2"
9448  [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9449	(zero_extend:EXTQI
9450	 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9451			 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9452   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9453	(plus:P (match_dup 1) (match_dup 2)))]
9454  "TARGET_UPDATE
9455   && (!avoiding_indexed_address_p (QImode)
9456       || !gpc_reg_operand (operands[2], Pmode))"
9457  "@
9458   lbzux %3,%0,%2
9459   lbzu %3,%2(%0)"
9460  [(set_attr "type" "load")
9461   (set_attr "update" "yes")
9462   (set_attr "indexed" "yes,no")])
9463
9464(define_insn "*movqi_update3"
9465  [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9466			(match_operand:P 2 "reg_or_short_operand" "r,I")))
9467	(match_operand:QI 3 "gpc_reg_operand" "r,r"))
9468   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9469	(plus:P (match_dup 1) (match_dup 2)))]
9470  "TARGET_UPDATE
9471   && (!avoiding_indexed_address_p (QImode)
9472       || !gpc_reg_operand (operands[2], Pmode))"
9473  "@
9474   stbux %3,%0,%2
9475   stbu %3,%2(%0)"
9476  [(set_attr "type" "store")
9477   (set_attr "update" "yes")
9478   (set_attr "indexed" "yes,no")])
9479
9480(define_insn "*mov<SFDF:mode>_update1"
9481  [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9482	(mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9483			  (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9484   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9485	(plus:P (match_dup 1) (match_dup 2)))]
9486  "TARGET_HARD_FLOAT && TARGET_UPDATE
9487   && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9488       || !gpc_reg_operand (operands[2], Pmode))"
9489  "@
9490   lf<sd>ux %3,%0,%2
9491   lf<sd>u %3,%2(%0)"
9492  [(set_attr "type" "fpload")
9493   (set_attr "update" "yes")
9494   (set_attr "indexed" "yes,no")
9495   (set_attr "size" "<SFDF:bits>")])
9496
9497(define_insn "*mov<SFDF:mode>_update2"
9498  [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9499			  (match_operand:P 2 "reg_or_short_operand" "r,I")))
9500	(match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9501   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9502	(plus:P (match_dup 1) (match_dup 2)))]
9503  "TARGET_HARD_FLOAT && TARGET_UPDATE
9504   && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9505       || !gpc_reg_operand (operands[2], Pmode))"
9506  "@
9507   stf<sd>ux %3,%0,%2
9508   stf<sd>u %3,%2(%0)"
9509  [(set_attr "type" "fpstore")
9510   (set_attr "update" "yes")
9511   (set_attr "indexed" "yes,no")
9512   (set_attr "size" "<SFDF:bits>")])
9513
9514(define_insn "*movsf_update3"
9515  [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9516	(mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9517			(match_operand:P 2 "reg_or_short_operand" "r,I"))))
9518   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9519	(plus:P (match_dup 1) (match_dup 2)))]
9520  "TARGET_SOFT_FLOAT && TARGET_UPDATE
9521   && (!avoiding_indexed_address_p (SFmode)
9522       || !gpc_reg_operand (operands[2], Pmode))"
9523  "@
9524   lwzux %3,%0,%2
9525   lwzu %3,%2(%0)"
9526  [(set_attr "type" "load")
9527   (set_attr "update" "yes")
9528   (set_attr "indexed" "yes,no")])
9529
9530(define_insn "*movsf_update4"
9531  [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9532			(match_operand:P 2 "reg_or_short_operand" "r,I")))
9533	(match_operand:SF 3 "gpc_reg_operand" "r,r"))
9534   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9535	(plus:P (match_dup 1) (match_dup 2)))]
9536  "TARGET_SOFT_FLOAT && TARGET_UPDATE
9537   && (!avoiding_indexed_address_p (SFmode)
9538       || !gpc_reg_operand (operands[2], Pmode))"
9539  "@
9540   stwux %3,%0,%2
9541   stwu %3,%2(%0)"
9542  [(set_attr "type" "store")
9543   (set_attr "update" "yes")
9544   (set_attr "indexed" "yes,no")])
9545
9546
9547;; After inserting conditional returns we can sometimes have
9548;; unnecessary register moves.  Unfortunately we cannot have a
9549;; modeless peephole here, because some single SImode sets have early
9550;; clobber outputs.  Although those sets expand to multi-ppc-insn
9551;; sequences, using get_attr_length here will smash the operands
9552;; array.  Neither is there an early_cobbler_p predicate.
9553;; Also this optimization interferes with scalars going into
9554;; altivec registers (the code does reloading through the FPRs).
9555(define_peephole2
9556  [(set (match_operand:DF 0 "gpc_reg_operand")
9557	(match_operand:DF 1 "any_operand"))
9558   (set (match_operand:DF 2 "gpc_reg_operand")
9559	(match_dup 0))]
9560  "!TARGET_VSX
9561   && peep2_reg_dead_p (2, operands[0])"
9562  [(set (match_dup 2) (match_dup 1))])
9563
9564(define_peephole2
9565  [(set (match_operand:SF 0 "gpc_reg_operand")
9566	(match_operand:SF 1 "any_operand"))
9567   (set (match_operand:SF 2 "gpc_reg_operand")
9568	(match_dup 0))]
9569  "!TARGET_P8_VECTOR
9570   && peep2_reg_dead_p (2, operands[0])"
9571  [(set (match_dup 2) (match_dup 1))])
9572
9573
9574;; TLS support.
9575
9576(define_insn "*tls_gd_pcrel<bits>"
9577  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9578	(unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9579		   (const_int 0)]
9580		  UNSPEC_TLSGD))]
9581  "HAVE_AS_TLS && TARGET_ELF"
9582  "la %0,%1@got@tlsgd@pcrel"
9583  [(set_attr "prefixed" "yes")])
9584
9585(define_insn_and_split "*tls_gd<bits>"
9586  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9587	(unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9588		   (match_operand:P 2 "gpc_reg_operand" "b")]
9589		  UNSPEC_TLSGD))]
9590  "HAVE_AS_TLS && TARGET_ELF"
9591  "addi %0,%2,%1@got@tlsgd"
9592  "&& TARGET_CMODEL != CMODEL_SMALL"
9593  [(set (match_dup 3)
9594	(high:P
9595	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9596   (set (match_dup 0)
9597	(lo_sum:P (match_dup 3)
9598	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9599{
9600  operands[3] = gen_reg_rtx (<MODE>mode);
9601}
9602  [(set (attr "length")
9603     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9604		   (const_int 8)
9605		   (const_int 4)))])
9606
9607(define_insn "*tls_gd_high<bits>"
9608  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9609     (high:P
9610       (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9611		  (match_operand:P 2 "gpc_reg_operand" "b")]
9612		 UNSPEC_TLSGD)))]
9613  "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9614  "addis %0,%2,%1@got@tlsgd@ha")
9615
9616(define_insn "*tls_gd_low<bits>"
9617  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9618     (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9619       (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9620		  (match_operand:P 3 "gpc_reg_operand" "b")]
9621		 UNSPEC_TLSGD)))]
9622  "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9623  "addi %0,%1,%2@got@tlsgd@l")
9624
9625(define_insn "*tls_ld_pcrel<bits>"
9626  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9627	(unspec:P [(const_int 0)]
9628		  UNSPEC_TLSLD))]
9629  "HAVE_AS_TLS && TARGET_ELF"
9630  "la %0,%&@got@tlsld@pcrel"
9631  [(set_attr "prefixed" "yes")])
9632
9633(define_insn_and_split "*tls_ld<bits>"
9634  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9635	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9636		  UNSPEC_TLSLD))]
9637  "HAVE_AS_TLS && TARGET_ELF"
9638  "addi %0,%1,%&@got@tlsld"
9639  "&& TARGET_CMODEL != CMODEL_SMALL"
9640  [(set (match_dup 2)
9641	(high:P
9642	    (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9643   (set (match_dup 0)
9644	(lo_sum:P (match_dup 2)
9645	    (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9646{
9647  operands[2] = gen_reg_rtx (<MODE>mode);
9648}
9649  [(set (attr "length")
9650     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9651		   (const_int 8)
9652		   (const_int 4)))])
9653
9654(define_insn "*tls_ld_high<bits>"
9655  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9656     (high:P
9657       (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9658		 UNSPEC_TLSLD)))]
9659  "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9660  "addis %0,%1,%&@got@tlsld@ha")
9661
9662(define_insn "*tls_ld_low<bits>"
9663  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9664     (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9665       (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9666		 UNSPEC_TLSLD)))]
9667  "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9668  "addi %0,%1,%&@got@tlsld@l")
9669
9670(define_insn "tls_dtprel_<bits>"
9671  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9672	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9673		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9674		  UNSPEC_TLSDTPREL))]
9675  "HAVE_AS_TLS"
9676  "addi %0,%1,%2@dtprel"
9677  [(set (attr "prefixed")
9678	(if_then_else (match_test "rs6000_tls_size == 16")
9679		      (const_string "no")
9680		      (const_string "yes")))])
9681
9682(define_insn "tls_dtprel_ha_<bits>"
9683  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9684	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9685		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9686		  UNSPEC_TLSDTPRELHA))]
9687  "HAVE_AS_TLS"
9688  "addis %0,%1,%2@dtprel@ha")
9689
9690(define_insn "tls_dtprel_lo_<bits>"
9691  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9692	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9693		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9694		  UNSPEC_TLSDTPRELLO))]
9695  "HAVE_AS_TLS"
9696  "addi %0,%1,%2@dtprel@l")
9697
9698(define_insn_and_split "tls_got_dtprel_<bits>"
9699  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9700	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9701		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9702		  UNSPEC_TLSGOTDTPREL))]
9703  "HAVE_AS_TLS"
9704  "<ptrload> %0,%2@got@dtprel(%1)"
9705  "&& TARGET_CMODEL != CMODEL_SMALL"
9706  [(set (match_dup 3)
9707	(high:P
9708	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9709   (set (match_dup 0)
9710	(lo_sum:P (match_dup 3)
9711	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9712{
9713  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9714}
9715  [(set (attr "length")
9716     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9717		   (const_int 8)
9718		   (const_int 4)))])
9719
9720(define_insn "*tls_got_dtprel_high<bits>"
9721  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9722     (high:P
9723       (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9724		  (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9725		 UNSPEC_TLSGOTDTPREL)))]
9726  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9727  "addis %0,%1,%2@got@dtprel@ha")
9728
9729(define_insn "*tls_got_dtprel_low<bits>"
9730  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9731     (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9732	 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9733		    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9734		   UNSPEC_TLSGOTDTPREL)))]
9735  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9736  "<ptrload> %0,%2@got@dtprel@l(%1)")
9737
9738(define_insn "tls_tprel_<bits>"
9739  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9740	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9741		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9742		  UNSPEC_TLSTPREL))]
9743  "HAVE_AS_TLS"
9744  "addi %0,%1,%2@tprel"
9745  [(set (attr "prefixed")
9746	(if_then_else (match_test "rs6000_tls_size == 16")
9747		      (const_string "no")
9748		      (const_string "yes")))])
9749
9750(define_insn "tls_tprel_ha_<bits>"
9751  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9752	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9753		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9754		  UNSPEC_TLSTPRELHA))]
9755  "HAVE_AS_TLS"
9756  "addis %0,%1,%2@tprel@ha")
9757
9758(define_insn "tls_tprel_lo_<bits>"
9759  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9760	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9761		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9762		  UNSPEC_TLSTPRELLO))]
9763  "HAVE_AS_TLS"
9764  "addi %0,%1,%2@tprel@l")
9765
9766(define_insn "*tls_got_tprel_pcrel_<bits>"
9767  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9768	(unspec:P [(const_int 0)
9769		   (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9770		  UNSPEC_TLSGOTTPREL))]
9771  "HAVE_AS_TLS"
9772  "<ptrload> %0,%1@got@tprel@pcrel"
9773  [(set_attr "prefixed" "yes")])
9774
9775;; "b" output constraint here and on tls_tls input to support linker tls
9776;; optimization.  The linker may edit the instructions emitted by a
9777;; tls_got_tprel/tls_tls pair to addis,addi.
9778(define_insn_and_split "tls_got_tprel_<bits>"
9779  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9780	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9781		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9782		  UNSPEC_TLSGOTTPREL))]
9783  "HAVE_AS_TLS"
9784  "<ptrload> %0,%2@got@tprel(%1)"
9785  "&& TARGET_CMODEL != CMODEL_SMALL"
9786  [(set (match_dup 3)
9787	(high:P
9788	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9789   (set (match_dup 0)
9790	(lo_sum:P (match_dup 3)
9791	    (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9792{
9793  operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9794}
9795  [(set (attr "length")
9796     (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9797		   (const_int 8)
9798		   (const_int 4)))])
9799
9800(define_insn "*tls_got_tprel_high<bits>"
9801  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9802     (high:P
9803       (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9804		  (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9805		 UNSPEC_TLSGOTTPREL)))]
9806  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9807  "addis %0,%1,%2@got@tprel@ha")
9808
9809(define_insn "*tls_got_tprel_low<bits>"
9810  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9811     (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9812	 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9813		    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9814		   UNSPEC_TLSGOTTPREL)))]
9815  "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9816  "<ptrload> %0,%2@got@tprel@l(%1)")
9817
9818(define_insn "tls_tls_pcrel_<bits>"
9819  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9820	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9821		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9822		  UNSPEC_TLSTLS_PCREL))]
9823  "TARGET_ELF && HAVE_AS_TLS"
9824  "add %0,%1,%2@tls@pcrel")
9825
9826(define_insn "tls_tls_<bits>"
9827  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9828	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9829		   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9830		  UNSPEC_TLSTLS))]
9831  "TARGET_ELF && HAVE_AS_TLS"
9832  "add %0,%1,%2@tls")
9833
9834(define_expand "tls_get_tpointer"
9835  [(set (match_operand:SI 0 "gpc_reg_operand")
9836	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9837  "TARGET_XCOFF && HAVE_AS_TLS"
9838{
9839  emit_insn (gen_tls_get_tpointer_internal ());
9840  emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9841  DONE;
9842})
9843
9844(define_insn "tls_get_tpointer_internal"
9845  [(set (reg:SI 3)
9846	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9847   (clobber (reg:SI LR_REGNO))]
9848  "TARGET_XCOFF && HAVE_AS_TLS"
9849  "bla __get_tpointer")
9850
9851(define_expand "tls_get_addr<mode>"
9852  [(set (match_operand:P 0 "gpc_reg_operand")
9853	(unspec:P [(match_operand:P 1 "gpc_reg_operand")
9854                   (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9855  "TARGET_XCOFF && HAVE_AS_TLS"
9856{
9857  emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9858  emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9859  emit_insn (gen_tls_get_addr_internal<mode> ());
9860  emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9861  DONE;
9862})
9863
9864(define_insn "tls_get_addr_internal<mode>"
9865  [(set (reg:P 3)
9866	(unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9867   (clobber (reg:P 0))
9868   (clobber (reg:P 4))
9869   (clobber (reg:P 5))
9870   (clobber (reg:P 11))
9871   (clobber (reg:CC CR0_REGNO))
9872   (clobber (reg:P LR_REGNO))]
9873  "TARGET_XCOFF && HAVE_AS_TLS"
9874  "bla __tls_get_addr")
9875
9876;; Next come insns related to the calling sequence.
9877;;
9878;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9879;; We move the back-chain and decrement the stack pointer.
9880;;
9881;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9882;; constant alloca, using that predicate will force the generic code to put
9883;; the constant size into a register before calling the expander.
9884;;
9885;; As a result the expander would not have the constant size information
9886;; in those cases and would have to generate less efficient code.
9887;;
9888;; Thus we allow reg_or_cint_operand instead so that the expander can see
9889;; the constant size.  The value is forced into a register if necessary.
9890;;
9891(define_expand "allocate_stack"
9892  [(set (match_operand 0 "gpc_reg_operand")
9893	(minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9894   (set (reg 1)
9895	(minus (reg 1) (match_dup 1)))]
9896  ""
9897{
9898  rtx chain = gen_reg_rtx (Pmode);
9899  rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9900  rtx neg_op0;
9901  rtx insn, par, set, mem;
9902
9903  /* By allowing reg_or_cint_operand as the predicate we can get
9904     better code for stack-clash-protection because we do not lose
9905     size information.  But the rest of the code expects the operand
9906     to be reg_or_short_operand.  If it isn't, then force it into
9907     a register.  */
9908  rtx orig_op1 = operands[1];
9909  if (!reg_or_short_operand (operands[1], Pmode))
9910    operands[1] = force_reg (Pmode, operands[1]);
9911
9912  emit_move_insn (chain, stack_bot);
9913
9914  /* Check stack bounds if necessary.  */
9915  if (crtl->limit_stack)
9916    {
9917      rtx available;
9918      available = expand_binop (Pmode, sub_optab,
9919				stack_pointer_rtx, stack_limit_rtx,
9920				NULL_RTX, 1, OPTAB_WIDEN);
9921      emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9922    }
9923
9924  /* Allocate and probe if requested.
9925     This may look similar to the loop we use for prologue allocations,
9926     but it is critically different.  For the former we know the loop
9927     will iterate, but do not know that generally here.  The former
9928     uses that knowledge to rotate the loop.  Combining them would be
9929     possible with some performance cost.  */
9930  if (flag_stack_clash_protection)
9931    {
9932      rtx rounded_size, last_addr, residual;
9933      HOST_WIDE_INT probe_interval;
9934      compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9935						&residual, &probe_interval,
9936						orig_op1);
9937      
9938      /* We do occasionally get in here with constant sizes, we might
9939	 as well do a reasonable job when we obviously can.  */
9940      if (rounded_size != const0_rtx)
9941	{
9942	  rtx loop_lab, end_loop;
9943	  bool rotated = CONST_INT_P (rounded_size);
9944	  rtx update = GEN_INT (-probe_interval);
9945	  if (probe_interval > 32768)
9946	    update = force_reg (Pmode, update);
9947
9948	  emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9949							last_addr, rotated);
9950
9951	  if (TARGET_32BIT)
9952	    emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9953					       stack_pointer_rtx,
9954					       update, chain));
9955	  else
9956	    emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9957					       stack_pointer_rtx,
9958					       update, chain));
9959	  emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9960						      last_addr, rotated);
9961	}
9962
9963      /* Now handle residuals.  We just have to set operands[1] correctly
9964	 and let the rest of the expander run.  */
9965      operands[1] = residual;
9966    }
9967
9968  if (!(CONST_INT_P (operands[1])
9969	&& IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9970    {
9971      operands[1] = force_reg (Pmode, operands[1]);
9972      neg_op0 = gen_reg_rtx (Pmode);
9973      emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9974    }
9975  else
9976    neg_op0 = GEN_INT (-INTVAL (operands[1]));
9977
9978  insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9979				       : gen_movdi_update_stack))
9980			(stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9981			 chain));
9982  /* Since we didn't use gen_frame_mem to generate the MEM, grab
9983     it now and set the alias set/attributes. The above gen_*_update
9984     calls will generate a PARALLEL with the MEM set being the first
9985     operation. */
9986  par = PATTERN (insn);
9987  gcc_assert (GET_CODE (par) == PARALLEL);
9988  set = XVECEXP (par, 0, 0);
9989  gcc_assert (GET_CODE (set) == SET);
9990  mem = SET_DEST (set);
9991  gcc_assert (MEM_P (mem));
9992  MEM_NOTRAP_P (mem) = 1;
9993  set_mem_alias_set (mem, get_frame_alias_set ());
9994
9995  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9996  DONE;
9997})
9998
9999;; These patterns say how to save and restore the stack pointer.  We need not
10000;; save the stack pointer at function level since we are careful to
10001;; preserve the backchain.  At block level, we have to restore the backchain
10002;; when we restore the stack pointer.
10003;;
10004;; For nonlocal gotos, we must save both the stack pointer and its
10005;; backchain and restore both.  Note that in the nonlocal case, the
10006;; save area is a memory location.
10007
10008(define_expand "save_stack_function"
10009  [(match_operand 0 "any_operand")
10010   (match_operand 1 "any_operand")]
10011  ""
10012  "DONE;")
10013
10014(define_expand "restore_stack_function"
10015  [(match_operand 0 "any_operand")
10016   (match_operand 1 "any_operand")]
10017  ""
10018  "DONE;")
10019
10020;; Adjust stack pointer (op0) to a new value (op1).
10021;; First copy old stack backchain to new location, and ensure that the
10022;; scheduler won't reorder the sp assignment before the backchain write.
10023(define_expand "restore_stack_block"
10024  [(set (match_dup 2) (match_dup 3))
10025   (set (match_dup 4) (match_dup 2))
10026   (match_dup 5)
10027   (set (match_operand 0 "register_operand")
10028	(match_operand 1 "register_operand"))]
10029  ""
10030{
10031  rtvec p;
10032
10033  operands[1] = force_reg (Pmode, operands[1]);
10034  operands[2] = gen_reg_rtx (Pmode);
10035  operands[3] = gen_frame_mem (Pmode, operands[0]);
10036  operands[4] = gen_frame_mem (Pmode, operands[1]);
10037  p = rtvec_alloc (1);
10038  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10039				  const0_rtx);
10040  operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10041})
10042
10043(define_expand "save_stack_nonlocal"
10044  [(set (match_dup 3) (match_dup 4))
10045   (set (match_operand 0 "memory_operand") (match_dup 3))
10046   (set (match_dup 2) (match_operand 1 "register_operand"))]
10047  ""
10048{
10049  int units_per_word = (TARGET_32BIT) ? 4 : 8;
10050
10051  /* Copy the backchain to the first word, sp to the second.  */
10052  operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10053  operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10054  operands[3] = gen_reg_rtx (Pmode);
10055  operands[4] = gen_frame_mem (Pmode, operands[1]);
10056})
10057
10058(define_expand "restore_stack_nonlocal"
10059  [(set (match_dup 2) (match_operand 1 "memory_operand"))
10060   (set (match_dup 3) (match_dup 4))
10061   (set (match_dup 5) (match_dup 2))
10062   (match_dup 6)
10063   (set (match_operand 0 "register_operand") (match_dup 3))]
10064  ""
10065{
10066  int units_per_word = (TARGET_32BIT) ? 4 : 8;
10067  rtvec p;
10068
10069  /* Restore the backchain from the first word, sp from the second.  */
10070  operands[2] = gen_reg_rtx (Pmode);
10071  operands[3] = gen_reg_rtx (Pmode);
10072  operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10073  operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10074  operands[5] = gen_frame_mem (Pmode, operands[3]);
10075  p = rtvec_alloc (1);
10076  RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10077				  const0_rtx);
10078  operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10079})
10080
10081;; Load up a PC-relative address.  Print_operand_address will append a @pcrel
10082;; to the symbol or label.
10083(define_insn "*pcrel_local_addr"
10084  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10085	(match_operand:DI 1 "pcrel_local_address"))]
10086  "TARGET_PCREL"
10087  "la %0,%a1"
10088  [(set_attr "prefixed" "yes")])
10089
10090;; Load up a PC-relative address to an external symbol.  If the symbol and the
10091;; program are both defined in the main program, the linker will optimize this
10092;; to a PADDI.  Otherwise, it will create a GOT address that is relocated by
10093;; the dynamic linker and loaded up.  Print_operand_address will append a
10094;; @got@pcrel to the symbol.
10095(define_insn "*pcrel_extern_addr"
10096  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10097	(match_operand:DI 1 "pcrel_external_address"))]
10098  "TARGET_PCREL"
10099  "ld %0,%a1"
10100  [(set_attr "prefixed" "yes")
10101   (set_attr "type" "load")])
10102
10103;; TOC register handling.
10104
10105;; Code to initialize the TOC register...
10106
10107(define_insn "load_toc_aix_si"
10108  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10109		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
10110	      (use (reg:SI 2))])]
10111  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10112{
10113  char buf[30];
10114  extern int need_toc_init;
10115  need_toc_init = 1;
10116  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10117  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10118  operands[2] = gen_rtx_REG (Pmode, 2);
10119  return "lwz %0,%1(%2)";
10120}
10121  [(set_attr "type" "load")
10122   (set_attr "update" "no")
10123   (set_attr "indexed" "no")])
10124
10125(define_insn "load_toc_aix_di"
10126  [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10127		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
10128	      (use (reg:DI 2))])]
10129  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10130{
10131  char buf[30];
10132  extern int need_toc_init;
10133  need_toc_init = 1;
10134  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10135			       !TARGET_ELF || !TARGET_MINIMAL_TOC);
10136  if (TARGET_ELF)
10137    strcat (buf, "@toc");
10138  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10139  operands[2] = gen_rtx_REG (Pmode, 2);
10140  return "ld %0,%1(%2)";
10141}
10142  [(set_attr "type" "load")
10143   (set_attr "update" "no")
10144   (set_attr "indexed" "no")])
10145
10146(define_insn "load_toc_v4_pic_si"
10147  [(set (reg:SI LR_REGNO)
10148	(unspec:SI [(const_int 0)] UNSPEC_TOC))]
10149  "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10150  "bl _GLOBAL_OFFSET_TABLE_@local-4"
10151  [(set_attr "type" "branch")])
10152
10153(define_expand "load_toc_v4_PIC_1"
10154  [(parallel [(set (reg:SI LR_REGNO)
10155		   (match_operand:SI 0 "immediate_operand" "s"))
10156	      (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10157  "TARGET_ELF && DEFAULT_ABI == ABI_V4
10158   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10159  "")
10160
10161(define_insn "load_toc_v4_PIC_1_normal"
10162  [(set (reg:SI LR_REGNO)
10163	(match_operand:SI 0 "immediate_operand" "s"))
10164   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10165  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10166   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10167  "bcl 20,31,%0\n%0:"
10168  [(set_attr "type" "branch")
10169   (set_attr "cannot_copy" "yes")])
10170
10171(define_insn "load_toc_v4_PIC_1_476"
10172  [(set (reg:SI LR_REGNO)
10173	(match_operand:SI 0 "immediate_operand" "s"))
10174   (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10175  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10176   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10177{
10178  char name[32];
10179  static char templ[32];
10180
10181  get_ppc476_thunk_name (name);
10182  sprintf (templ, "bl %s\n%%0:", name);
10183  return templ;
10184}
10185  [(set_attr "type" "branch")
10186   (set_attr "cannot_copy" "yes")])
10187
10188(define_expand "load_toc_v4_PIC_1b"
10189  [(parallel [(set (reg:SI LR_REGNO)
10190		   (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10191			       (label_ref (match_operand 1 ""))]
10192		           UNSPEC_TOCPTR))
10193	      (match_dup 1)])]
10194  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10195  "")
10196
10197(define_insn "load_toc_v4_PIC_1b_normal"
10198  [(set (reg:SI LR_REGNO)
10199	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10200		    (label_ref (match_operand 1 "" ""))]
10201		UNSPEC_TOCPTR))
10202   (match_dup 1)]
10203  "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10204  "bcl 20,31,$+8\;.long %0-$"
10205  [(set_attr "type" "branch")
10206   (set_attr "length" "8")])
10207
10208(define_insn "load_toc_v4_PIC_1b_476"
10209  [(set (reg:SI LR_REGNO)
10210	(unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10211		    (label_ref (match_operand 1 "" ""))]
10212		UNSPEC_TOCPTR))
10213   (match_dup 1)]
10214  "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10215{
10216  char name[32];
10217  static char templ[32];
10218
10219  get_ppc476_thunk_name (name);
10220  sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10221  return templ;
10222}
10223  [(set_attr "type" "branch")
10224   (set_attr "length" "16")])
10225
10226(define_insn "load_toc_v4_PIC_2"
10227  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10228	(mem:SI (plus:SI
10229		  (match_operand:SI 1 "gpc_reg_operand" "b")
10230		  (const
10231		    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10232			      (match_operand:SI 3 "immediate_operand" "s"))))))]
10233  "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10234  "lwz %0,%2-%3(%1)"
10235  [(set_attr "type" "load")])
10236
10237(define_insn "load_toc_v4_PIC_3b"
10238  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10239	(plus:SI
10240	  (match_operand:SI 1 "gpc_reg_operand" "b")
10241	  (high:SI
10242	    (const
10243	      (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10244			(match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10245  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10246  "addis %0,%1,%2-%3@ha")
10247
10248(define_insn "load_toc_v4_PIC_3c"
10249  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10250	(lo_sum:SI
10251	  (match_operand:SI 1 "gpc_reg_operand" "b")
10252	  (const
10253	    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10254		      (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10255  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10256  "addi %0,%1,%2-%3@l")
10257
10258;; If the TOC is shared over a translation unit, as happens with all
10259;; the kinds of PIC that we support, we need to restore the TOC
10260;; pointer only when jumping over units of translation.
10261;; On Darwin, we need to reload the picbase.
10262
10263(define_expand "builtin_setjmp_receiver"
10264  [(use (label_ref (match_operand 0 "")))]
10265  "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10266   || (TARGET_TOC && TARGET_MINIMAL_TOC)
10267   || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10268{
10269#if TARGET_MACHO
10270  if (DEFAULT_ABI == ABI_DARWIN)
10271    {
10272      rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10273      rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10274      rtx tmplabrtx;
10275      char tmplab[20];
10276
10277      crtl->uses_pic_offset_table = 1;
10278      ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10279				  CODE_LABEL_NUMBER (operands[0]));
10280      tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10281
10282      emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10283      emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10284      emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10285					picrtx, tmplabrtx));
10286    }
10287  else
10288#endif
10289    rs6000_emit_load_toc_table (FALSE);
10290  DONE;
10291})
10292
10293;; Largetoc support
10294(define_insn "*largetoc_high"
10295  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10296        (high:DI
10297	  (unspec [(match_operand:DI 1 "" "")
10298		   (match_operand:DI 2 "gpc_reg_operand" "b")]
10299		  UNSPEC_TOCREL)))]
10300   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10301   "addis %0,%2,%1@toc@ha")
10302
10303(define_insn "*largetoc_high_aix<mode>"
10304  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10305        (high:P
10306	  (unspec [(match_operand:P 1 "" "")
10307		   (match_operand:P 2 "gpc_reg_operand" "b")]
10308		  UNSPEC_TOCREL)))]
10309   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10310   "addis %0,%1@u(%2)")
10311
10312(define_insn "*largetoc_high_plus"
10313  [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10314        (high:DI
10315	  (plus:DI
10316	    (unspec [(match_operand:DI 1 "" "")
10317		     (match_operand:DI 2 "gpc_reg_operand" "b")]
10318		    UNSPEC_TOCREL)
10319	    (match_operand:DI 3 "add_cint_operand" "n"))))]
10320   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10321   "addis %0,%2,%1+%3@toc@ha")
10322
10323(define_insn "*largetoc_high_plus_aix<mode>"
10324  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10325        (high:P
10326	  (plus:P
10327	    (unspec [(match_operand:P 1 "" "")
10328		     (match_operand:P 2 "gpc_reg_operand" "b")]
10329		    UNSPEC_TOCREL)
10330	    (match_operand:P 3 "add_cint_operand" "n"))))]
10331   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10332   "addis %0,%1+%3@u(%2)")
10333
10334(define_insn "*largetoc_low"
10335  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10336        (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10337	           (match_operand:DI 2 "" "")))]
10338   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10339   "addi %0,%1,%2@l")
10340
10341(define_insn "*largetoc_low_aix<mode>"
10342  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10343        (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10344	           (match_operand:P 2 "" "")))]
10345   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10346   "la %0,%2@l(%1)")
10347
10348(define_insn_and_split "*tocref<mode>"
10349  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10350	(match_operand:P 1 "small_toc_ref" "R"))]
10351   "TARGET_TOC
10352    && legitimate_constant_pool_address_p (operands[1], QImode, false)"
10353   "la %0,%a1"
10354   "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10355  [(set (match_dup 0) (high:P (match_dup 1)))
10356   (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10357
10358;; Elf specific ways of loading addresses for non-PIC code.
10359;; The output of this could be r0, but we make a very strong
10360;; preference for a base register because it will usually
10361;; be needed there.
10362(define_insn "elf_high"
10363  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10364	(high:SI (match_operand 1 "" "")))]
10365  "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10366  "lis %0,%1@ha")
10367
10368(define_insn "elf_low"
10369  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10370	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10371		   (match_operand 2 "" "")))]
10372   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10373   "la %0,%2@l(%1)")
10374
10375(define_insn "*pltseq_tocsave_<mode>"
10376  [(set (match_operand:P 0 "memory_operand" "=m")
10377	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10378		   (match_operand:P 2 "symbol_ref_operand" "s")
10379		   (match_operand:P 3 "" "")]
10380		  UNSPEC_PLTSEQ))]
10381  "TARGET_PLTSEQ
10382   && DEFAULT_ABI == ABI_ELFv2"
10383{
10384  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10385})
10386
10387(define_insn "*pltseq_plt16_ha_<mode>"
10388  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10389	(unspec:P [(match_operand:P 1 "" "")
10390		   (match_operand:P 2 "symbol_ref_operand" "s")
10391		   (match_operand:P 3 "" "")]
10392		  UNSPEC_PLT16_HA))]
10393  "TARGET_PLTSEQ"
10394{
10395  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10396})
10397
10398(define_insn "*pltseq_plt16_lo_<mode>"
10399  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10400	(unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
10401			    (match_operand:P 2 "symbol_ref_operand" "s")
10402			    (match_operand:P 3 "" "")]
10403			   UNSPECV_PLT16_LO))]
10404  "TARGET_PLTSEQ"
10405{
10406  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10407}
10408  [(set_attr "type" "load")])
10409
10410(define_insn "*pltseq_mtctr_<mode>"
10411  [(set (match_operand:P 0 "register_operand" "=c")
10412	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10413		   (match_operand:P 2 "symbol_ref_operand" "s")
10414		   (match_operand:P 3 "" "")]
10415		  UNSPEC_PLTSEQ))]
10416  "TARGET_PLTSEQ"
10417{
10418  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10419})
10420
10421(define_insn "*pltseq_plt_pcrel<mode>"
10422  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10423	(unspec_volatile:P [(match_operand:P 1 "" "")
10424			    (match_operand:P 2 "symbol_ref_operand" "s")
10425			    (match_operand:P 3 "" "")]
10426			   UNSPECV_PLT_PCREL))]
10427  "HAVE_AS_PLTSEQ && TARGET_ELF
10428   && rs6000_pcrel_p (cfun)"
10429{
10430  return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10431}
10432  [(set_attr "type" "load")
10433   (set_attr "length" "12")])
10434
10435;; Call and call_value insns
10436;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10437(define_expand "call"
10438  [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10439		    (match_operand 1 ""))
10440	      (use (match_operand 2 ""))
10441	      (clobber (reg:SI LR_REGNO))])]
10442  ""
10443{
10444#if TARGET_MACHO
10445  if (MACHOPIC_INDIRECT)
10446    operands[0] = machopic_indirect_call_target (operands[0]);
10447#endif
10448
10449  gcc_assert (MEM_P (operands[0]));
10450
10451  operands[0] = XEXP (operands[0], 0);
10452
10453  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10454    rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10455  else if (DEFAULT_ABI == ABI_V4)
10456    rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10457  else if (DEFAULT_ABI == ABI_DARWIN)
10458    rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10459  else
10460    gcc_unreachable ();
10461
10462  DONE;
10463})
10464
10465(define_expand "call_value"
10466  [(parallel [(set (match_operand 0 "")
10467		   (call (mem:SI (match_operand 1 "address_operand"))
10468			 (match_operand 2 "")))
10469	      (use (match_operand 3 ""))
10470	      (clobber (reg:SI LR_REGNO))])]
10471  ""
10472{
10473#if TARGET_MACHO
10474  if (MACHOPIC_INDIRECT)
10475    operands[1] = machopic_indirect_call_target (operands[1]);
10476#endif
10477
10478  gcc_assert (MEM_P (operands[1]));
10479
10480  operands[1] = XEXP (operands[1], 0);
10481
10482  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10483    rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10484  else if (DEFAULT_ABI == ABI_V4)
10485    rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10486  else if (DEFAULT_ABI == ABI_DARWIN)
10487    rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10488  else
10489    gcc_unreachable ();
10490
10491  DONE;
10492})
10493
10494;; Call to function in current module.  No TOC pointer reload needed.
10495;; Operand2 is nonzero if we are using the V.4 calling sequence and
10496;; either the function was not prototyped, or it was prototyped as a
10497;; variable argument function.  It is > 0 if FP registers were passed
10498;; and < 0 if they were not.
10499
10500(define_insn "*call_local<mode>"
10501  [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
10502	 (match_operand 1))
10503   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10504   (clobber (reg:P LR_REGNO))]
10505  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10506{
10507  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10508    output_asm_insn ("crxor 6,6,6", operands);
10509
10510  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10511    output_asm_insn ("creqv 6,6,6", operands);
10512
10513  if (rs6000_pcrel_p (cfun))
10514    return "bl %z0@notoc";
10515  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10516}
10517  [(set_attr "type" "branch")
10518   (set_attr "length" "4,8")])
10519
10520(define_insn "*call_value_local<mode>"
10521  [(set (match_operand 0 "" "")
10522	(call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
10523	      (match_operand 2)))
10524   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10525   (clobber (reg:P LR_REGNO))]
10526  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10527{
10528  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10529    output_asm_insn ("crxor 6,6,6", operands);
10530
10531  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10532    output_asm_insn ("creqv 6,6,6", operands);
10533
10534  if (rs6000_pcrel_p (cfun))
10535    return "bl %z1@notoc";
10536  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10537}
10538  [(set_attr "type" "branch")
10539   (set_attr "length" "4,8")])
10540
10541
10542;; A function pointer under System V is just a normal pointer
10543;; operands[0] is the function pointer
10544;; operands[1] is the tls call arg
10545;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10546;; which indicates how to set cr1
10547
10548(define_insn "*call_indirect_nonlocal_sysv<mode>"
10549  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10550	 (match_operand 1))
10551   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10552   (clobber (reg:P LR_REGNO))]
10553  "DEFAULT_ABI == ABI_V4
10554   || DEFAULT_ABI == ABI_DARWIN"
10555{
10556  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10557    output_asm_insn ("crxor 6,6,6", operands);
10558
10559  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10560    output_asm_insn ("creqv 6,6,6", operands);
10561
10562  return rs6000_indirect_call_template (operands, 0);
10563}
10564  [(set_attr "type" "jmpreg")
10565   (set (attr "length")
10566	(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10567			 (match_test "which_alternative != 1"))
10568		    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10569		  (const_string "12")
10570	       (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10571			 (match_test "which_alternative != 1"))
10572		    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10573		  (const_string "8")]
10574	      (const_string "4")))])
10575
10576(define_insn "*call_nonlocal_sysv<mode>"
10577  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10578	 (match_operand 1))
10579   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10580   (clobber (reg:P LR_REGNO))]
10581  "(DEFAULT_ABI == ABI_DARWIN
10582   || (DEFAULT_ABI == ABI_V4
10583       && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10584{
10585  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10586    output_asm_insn ("crxor 6,6,6", operands);
10587
10588  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10589    output_asm_insn ("creqv 6,6,6", operands);
10590
10591  return rs6000_call_template (operands, 0);
10592}
10593  [(set_attr "type" "branch,branch")
10594   (set_attr "length" "4,8")])
10595
10596(define_insn "*call_nonlocal_sysv_secure<mode>"
10597  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10598	 (match_operand 1))
10599   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10600   (use (match_operand:SI 3 "register_operand" "r,r"))
10601   (clobber (reg:P LR_REGNO))]
10602  "(DEFAULT_ABI == ABI_V4
10603    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10604    && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10605{
10606  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10607    output_asm_insn ("crxor 6,6,6", operands);
10608
10609  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10610    output_asm_insn ("creqv 6,6,6", operands);
10611
10612  return rs6000_call_template (operands, 0);
10613}
10614  [(set_attr "type" "branch,branch")
10615   (set_attr "length" "4,8")])
10616
10617(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10618  [(set (match_operand 0 "" "")
10619	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10620	      (match_operand:P 2 "unspec_tls" "")))
10621   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10622   (clobber (reg:P LR_REGNO))]
10623  "DEFAULT_ABI == ABI_V4
10624   || DEFAULT_ABI == ABI_DARWIN"
10625{
10626  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10627    output_asm_insn ("crxor 6,6,6", operands);
10628
10629  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10630    output_asm_insn ("creqv 6,6,6", operands);
10631
10632  return rs6000_indirect_call_template (operands, 1);
10633}
10634  [(set_attr "type" "jmpreg")
10635   (set (attr "length")
10636	(plus
10637	  (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10638	    (const_int 4)
10639	    (const_int 0))
10640	  (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10641			     (match_test "which_alternative != 1"))
10642	    (const_int 8)
10643	    (const_int 4))))])
10644
10645(define_insn "*call_value_nonlocal_sysv<mode>"
10646  [(set (match_operand 0 "" "")
10647	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10648	      (match_operand:P 2 "unspec_tls" "")))
10649   (use (match_operand:SI 3 "immediate_operand" "n"))
10650   (clobber (reg:P LR_REGNO))]
10651  "(DEFAULT_ABI == ABI_DARWIN
10652    || (DEFAULT_ABI == ABI_V4
10653	&& (INTVAL (operands[3]) & CALL_LONG) == 0))"
10654{
10655  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10656    output_asm_insn ("crxor 6,6,6", operands);
10657
10658  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10659    output_asm_insn ("creqv 6,6,6", operands);
10660
10661  return rs6000_call_template (operands, 1);
10662}
10663  [(set_attr "type" "branch")
10664   (set (attr "length")
10665	(if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10666	  (const_int 8)
10667	  (const_int 4)))])
10668
10669(define_insn "*call_value_nonlocal_sysv_secure<mode>"
10670  [(set (match_operand 0 "" "")
10671	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10672	      (match_operand:P 2 "unspec_tls" "")))
10673   (use (match_operand:SI 3 "immediate_operand" "n"))
10674   (use (match_operand:SI 4 "register_operand" "r"))
10675   (clobber (reg:P LR_REGNO))]
10676  "(DEFAULT_ABI == ABI_V4
10677    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10678    && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10679{
10680  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10681    output_asm_insn ("crxor 6,6,6", operands);
10682
10683  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10684    output_asm_insn ("creqv 6,6,6", operands);
10685
10686  return rs6000_call_template (operands, 1);
10687}
10688  [(set_attr "type" "branch")
10689   (set (attr "length")
10690	(if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10691	  (const_int 8)
10692	  (const_int 4)))])
10693
10694;; Call to AIX abi function which may be in another module.
10695;; Restore the TOC pointer (r2) after the call.
10696
10697(define_insn "*call_nonlocal_aix<mode>"
10698  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10699	 (match_operand 1))
10700   (use (match_operand:SI 2 "immediate_operand" "n"))
10701   (clobber (reg:P LR_REGNO))]
10702  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10703   && (INTVAL (operands[2]) & CALL_LONG) == 0"
10704{
10705  return rs6000_call_template (operands, 0);
10706}
10707  [(set_attr "type" "branch")
10708   (set (attr "length")
10709	(if_then_else (match_test "rs6000_pcrel_p (cfun)")
10710	  (const_int 4)
10711	  (const_int 8)))])
10712
10713(define_insn "*call_value_nonlocal_aix<mode>"
10714  [(set (match_operand 0 "" "")
10715	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10716	      (match_operand:P 2 "unspec_tls" "")))
10717   (use (match_operand:SI 3 "immediate_operand" "n"))
10718   (clobber (reg:P LR_REGNO))]
10719  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10720   && (INTVAL (operands[3]) & CALL_LONG) == 0"
10721{
10722  return rs6000_call_template (operands, 1);
10723}
10724  [(set_attr "type" "branch")
10725   (set (attr "length")
10726	(if_then_else (match_test "rs6000_pcrel_p (cfun)")
10727	    (const_int 4)
10728	    (const_int 8)))])
10729
10730;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10731;; Operand0 is the addresss of the function to call
10732;; Operand3 is the location in the function descriptor to load r2 from
10733;; Operand4 is the offset of the stack location holding the current TOC pointer
10734
10735(define_insn "*call_indirect_aix<mode>"
10736  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10737	 (match_operand 1))
10738   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10739   (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10740   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10741   (clobber (reg:P LR_REGNO))]
10742  "DEFAULT_ABI == ABI_AIX"
10743{
10744  return rs6000_indirect_call_template (operands, 0);
10745}
10746  [(set_attr "type" "jmpreg")
10747   (set (attr "length")
10748	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10749			   (match_test "which_alternative != 1"))
10750		      (const_string "16")
10751		      (const_string "12")))])
10752
10753(define_insn "*call_value_indirect_aix<mode>"
10754  [(set (match_operand 0 "" "")
10755	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10756	      (match_operand:P 2 "unspec_tls" "")))
10757   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10758   (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10759   (set (reg:P TOC_REGNUM)
10760	(unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
10761		  UNSPEC_TOCSLOT))
10762   (clobber (reg:P LR_REGNO))]
10763  "DEFAULT_ABI == ABI_AIX"
10764{
10765  return rs6000_indirect_call_template (operands, 1);
10766}
10767  [(set_attr "type" "jmpreg")
10768   (set (attr "length")
10769	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10770			   (match_test "which_alternative != 1"))
10771	    (const_string "16")
10772	    (const_string "12")))])
10773
10774;; Call to indirect functions with the ELFv2 ABI.
10775;; Operand0 is the addresss of the function to call
10776;; Operand3 is the offset of the stack location holding the current TOC pointer
10777
10778(define_insn "*call_indirect_elfv2<mode>"
10779  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10780	 (match_operand 1))
10781   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10782   (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10783   (clobber (reg:P LR_REGNO))]
10784  "DEFAULT_ABI == ABI_ELFv2"
10785{
10786  return rs6000_indirect_call_template (operands, 0);
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_indirect_pcrel<mode>"
10796  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10797	 (match_operand 1))
10798   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10799   (clobber (reg:P LR_REGNO))]
10800  "rs6000_pcrel_p (cfun)"
10801{
10802  return rs6000_indirect_call_template (operands, 0);
10803}
10804  [(set_attr "type" "jmpreg")
10805   (set (attr "length")
10806	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10807			   (match_test "which_alternative != 1"))
10808		      (const_string "8")
10809		      (const_string "4")))])
10810
10811(define_insn "*call_value_indirect_elfv2<mode>"
10812  [(set (match_operand 0 "" "")
10813	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10814	      (match_operand:P 2 "unspec_tls" "")))
10815   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10816   (set (reg:P TOC_REGNUM)
10817	(unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10818		  UNSPEC_TOCSLOT))
10819   (clobber (reg:P LR_REGNO))]
10820  "DEFAULT_ABI == ABI_ELFv2"
10821{
10822  return rs6000_indirect_call_template (operands, 1);
10823}
10824  [(set_attr "type" "jmpreg")
10825   (set (attr "length")
10826	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10827			   (match_test "which_alternative != 1"))
10828	    (const_string "12")
10829	    (const_string "8")))])
10830
10831(define_insn "*call_value_indirect_pcrel<mode>"
10832  [(set (match_operand 0 "" "")
10833	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10834	      (match_operand:P 2 "unspec_tls" "")))
10835   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10836   (clobber (reg:P LR_REGNO))]
10837  "rs6000_pcrel_p (cfun)"
10838{
10839  return rs6000_indirect_call_template (operands, 1);
10840}
10841  [(set_attr "type" "jmpreg")
10842   (set (attr "length")
10843	(if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10844			   (match_test "which_alternative != 1"))
10845	    (const_string "8")
10846	    (const_string "4")))])
10847
10848;; Call subroutine returning any type.
10849(define_expand "untyped_call"
10850  [(parallel [(call (match_operand 0 "")
10851		    (const_int 0))
10852	      (match_operand 1 "")
10853	      (match_operand 2 "")])]
10854  ""
10855{
10856  int i;
10857
10858  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10859
10860  for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10861    emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
10862  emit_insn (gen_blockage ());
10863
10864  for (i = 0; i < XVECLEN (operands[2], 0); i++)
10865    {
10866      rtx set = XVECEXP (operands[2], 0, i);
10867      emit_move_insn (SET_DEST (set), SET_SRC (set));
10868    }
10869
10870  /* The optimizer does not know that the call sets the function value
10871     registers we stored in the result block.  We avoid problems by
10872     claiming that all hard registers are used and clobbered at this
10873     point.  */
10874  emit_insn (gen_blockage ());
10875
10876  DONE;
10877})
10878
10879;; sibling call patterns
10880(define_expand "sibcall"
10881  [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10882		    (match_operand 1 ""))
10883	      (use (match_operand 2 ""))
10884	      (simple_return)])]
10885  ""
10886{
10887#if TARGET_MACHO
10888  if (MACHOPIC_INDIRECT)
10889    operands[0] = machopic_indirect_call_target (operands[0]);
10890#endif
10891
10892  gcc_assert (MEM_P (operands[0]));
10893  gcc_assert (CONST_INT_P (operands[1]));
10894
10895  operands[0] = XEXP (operands[0], 0);
10896
10897  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10898    rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10899  else if (DEFAULT_ABI == ABI_V4)
10900    rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10901  else if (DEFAULT_ABI == ABI_DARWIN)
10902    rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10903  else
10904    gcc_unreachable ();
10905
10906  DONE;
10907})
10908
10909(define_expand "sibcall_value"
10910  [(parallel [(set (match_operand 0 "register_operand")
10911		(call (mem:SI (match_operand 1 "address_operand"))
10912		      (match_operand 2 "")))
10913	      (use (match_operand 3 ""))
10914	      (simple_return)])]
10915  ""
10916{
10917#if TARGET_MACHO
10918  if (MACHOPIC_INDIRECT)
10919    operands[1] = machopic_indirect_call_target (operands[1]);
10920#endif
10921
10922  gcc_assert (MEM_P (operands[1]));
10923  gcc_assert (CONST_INT_P (operands[2]));
10924
10925  operands[1] = XEXP (operands[1], 0);
10926
10927  if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10928    rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10929  else if (DEFAULT_ABI == ABI_V4)
10930    rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10931  else if (DEFAULT_ABI == ABI_DARWIN)
10932    rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10933  else
10934    gcc_unreachable ();
10935
10936  DONE;
10937})
10938
10939(define_insn "*sibcall_local32"
10940  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10941	 (match_operand 1))
10942   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10943   (simple_return)]
10944  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10945{
10946  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10947    output_asm_insn ("crxor 6,6,6", operands);
10948
10949  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10950    output_asm_insn ("creqv 6,6,6", operands);
10951
10952  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10953}
10954  [(set_attr "type" "branch")
10955   (set_attr "length" "4,8")])
10956
10957(define_insn "*sibcall_local64"
10958  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10959	 (match_operand 1))
10960   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10961   (simple_return)]
10962  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10963{
10964  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10965    output_asm_insn ("crxor 6,6,6", operands);
10966
10967  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10968    output_asm_insn ("creqv 6,6,6", operands);
10969
10970  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10971}
10972  [(set_attr "type" "branch")
10973   (set_attr "length" "4,8")])
10974
10975(define_insn "*sibcall_value_local32"
10976  [(set (match_operand 0 "" "")
10977	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10978	      (match_operand 2)))
10979   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10980   (simple_return)]
10981  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10982{
10983  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10984    output_asm_insn ("crxor 6,6,6", operands);
10985
10986  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10987    output_asm_insn ("creqv 6,6,6", operands);
10988
10989  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10990}
10991  [(set_attr "type" "branch")
10992   (set_attr "length" "4,8")])
10993
10994(define_insn "*sibcall_value_local64"
10995  [(set (match_operand 0 "" "")
10996	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10997	      (match_operand 2)))
10998   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10999   (simple_return)]
11000  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11001{
11002  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11003    output_asm_insn ("crxor 6,6,6", operands);
11004
11005  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11006    output_asm_insn ("creqv 6,6,6", operands);
11007
11008  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11009}
11010  [(set_attr "type" "branch")
11011   (set_attr "length" "4,8")])
11012
11013(define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11014  [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11015	 (match_operand 1))
11016   (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11017   (simple_return)]
11018  "DEFAULT_ABI == ABI_V4
11019   || DEFAULT_ABI == ABI_DARWIN"
11020{
11021  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11022    output_asm_insn ("crxor 6,6,6", operands);
11023
11024  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11025    output_asm_insn ("creqv 6,6,6", operands);
11026
11027  return rs6000_indirect_sibcall_template (operands, 0);
11028}
11029  [(set_attr "type" "jmpreg")
11030   (set (attr "length")
11031	(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11032			 (match_test "which_alternative != 1"))
11033		    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11034		  (const_string "12")
11035	       (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11036			 (match_test "which_alternative != 1"))
11037		   (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11038		  (const_string "8")]
11039	      (const_string "4")))])
11040
11041(define_insn "*sibcall_nonlocal_sysv<mode>"
11042  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11043	 (match_operand 1))
11044   (use (match_operand 2 "immediate_operand" "O,n"))
11045   (simple_return)]
11046  "(DEFAULT_ABI == ABI_DARWIN
11047    || DEFAULT_ABI == ABI_V4)
11048   && (INTVAL (operands[2]) & CALL_LONG) == 0"
11049{
11050  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11051    output_asm_insn ("crxor 6,6,6", operands);
11052
11053  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11054    output_asm_insn ("creqv 6,6,6", operands);
11055
11056  return rs6000_sibcall_template (operands, 0);
11057}
11058  [(set_attr "type" "branch")
11059   (set_attr "length" "4,8")])
11060
11061(define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11062  [(set (match_operand 0 "" "")
11063	(call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11064	      (match_operand 2)))
11065   (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11066   (simple_return)]
11067  "DEFAULT_ABI == ABI_V4
11068   || DEFAULT_ABI == ABI_DARWIN"
11069{
11070  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11071    output_asm_insn ("crxor 6,6,6", operands);
11072
11073  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11074    output_asm_insn ("creqv 6,6,6", operands);
11075
11076  return rs6000_indirect_sibcall_template (operands, 1);
11077}
11078  [(set_attr "type" "jmpreg")
11079   (set (attr "length")
11080	(cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11081			 (match_test "which_alternative != 1"))
11082		    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11083		  (const_string "12")
11084	       (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11085			 (match_test "which_alternative != 1"))
11086		   (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11087		  (const_string "8")]
11088	      (const_string "4")))])
11089
11090(define_insn "*sibcall_value_nonlocal_sysv<mode>"
11091  [(set (match_operand 0 "" "")
11092	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11093	      (match_operand 2)))
11094   (use (match_operand:SI 3 "immediate_operand" "O,n"))
11095   (simple_return)]
11096  "(DEFAULT_ABI == ABI_DARWIN
11097    || DEFAULT_ABI == ABI_V4)
11098   && (INTVAL (operands[3]) & CALL_LONG) == 0"
11099{
11100  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11101    output_asm_insn ("crxor 6,6,6", operands);
11102
11103  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11104    output_asm_insn ("creqv 6,6,6", operands);
11105
11106  return rs6000_sibcall_template (operands, 1);
11107}
11108  [(set_attr "type" "branch")
11109   (set_attr "length" "4,8")])
11110
11111;; AIX ABI sibling call patterns.
11112
11113(define_insn "*sibcall_aix<mode>"
11114  [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11115	 (match_operand 1))
11116   (simple_return)]
11117  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11118{
11119  if (which_alternative == 0)
11120    return rs6000_sibcall_template (operands, 0);
11121  else
11122    return "b%T0";
11123}
11124  [(set_attr "type" "branch")])
11125
11126(define_insn "*sibcall_value_aix<mode>"
11127  [(set (match_operand 0 "" "")
11128	(call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11129	      (match_operand 2)))
11130   (simple_return)]
11131  "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11132{
11133  if (which_alternative == 0)
11134    return rs6000_sibcall_template (operands, 1);
11135  else
11136    return "b%T1";
11137}
11138  [(set_attr "type" "branch")])
11139
11140(define_expand "sibcall_epilogue"
11141  [(use (const_int 0))]
11142  ""
11143{
11144  if (!TARGET_SCHED_PROLOG)
11145    emit_insn (gen_blockage ());
11146  rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11147  DONE;
11148})
11149
11150;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11151;; all of memory.  This blocks insns from being moved across this point.
11152
11153(define_insn "blockage"
11154  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11155  ""
11156  ""
11157  [(set_attr "length" "0")])
11158
11159(define_expand "probe_stack_address"
11160  [(use (match_operand 0 "address_operand"))]
11161  ""
11162{
11163  operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11164  MEM_VOLATILE_P (operands[0]) = 1;
11165
11166  if (TARGET_64BIT)
11167    emit_insn (gen_probe_stack_di (operands[0]));
11168  else
11169    emit_insn (gen_probe_stack_si (operands[0]));
11170  DONE;
11171})
11172
11173(define_insn "probe_stack_<mode>"
11174  [(set (match_operand:P 0 "memory_operand" "=m")
11175        (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11176  ""
11177{
11178  operands[1] = gen_rtx_REG (Pmode, 0);
11179  return "st<wd>%U0%X0 %1,%0";
11180}
11181  [(set_attr "type" "store")
11182   (set (attr "update")
11183	(if_then_else (match_operand 0 "update_address_mem")
11184		      (const_string "yes")
11185		      (const_string "no")))
11186   (set (attr "indexed")
11187	(if_then_else (match_operand 0 "indexed_address_mem")
11188		      (const_string "yes")
11189		      (const_string "no")))])
11190
11191(define_insn "probe_stack_range<P:mode>"
11192  [(set (match_operand:P 0 "register_operand" "=&r")
11193	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11194			    (match_operand:P 2 "register_operand" "r")
11195			    (match_operand:P 3 "register_operand" "r")]
11196			   UNSPECV_PROBE_STACK_RANGE))]
11197  ""
11198  "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11199  [(set_attr "type" "three")])
11200
11201;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11202;; signed & unsigned, and one type of branch.
11203;;
11204;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11205;; insns, and branches.
11206
11207(define_expand "cbranch<mode>4"
11208  [(use (match_operator 0 "comparison_operator"
11209         [(match_operand:GPR 1 "gpc_reg_operand")
11210          (match_operand:GPR 2 "reg_or_short_operand")]))
11211   (use (match_operand 3))]
11212  ""
11213{
11214  /* Take care of the possibility that operands[2] might be negative but
11215     this might be a logical operation.  That insn doesn't exist.  */
11216  if (CONST_INT_P (operands[2])
11217      && INTVAL (operands[2]) < 0)
11218    {
11219      operands[2] = force_reg (<MODE>mode, operands[2]);
11220      operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11221				    GET_MODE (operands[0]),
11222				    operands[1], operands[2]);
11223   }
11224
11225  rs6000_emit_cbranch (<MODE>mode, operands);
11226  DONE;
11227})
11228
11229(define_expand "cbranch<mode>4"
11230  [(use (match_operator 0 "comparison_operator"
11231         [(match_operand:FP 1 "gpc_reg_operand")
11232          (match_operand:FP 2 "gpc_reg_operand")]))
11233   (use (match_operand 3))]
11234  ""
11235{
11236  rs6000_emit_cbranch (<MODE>mode, operands);
11237  DONE;
11238})
11239
11240(define_expand "cstore<mode>4_signed"
11241  [(use (match_operator 1 "signed_comparison_operator"
11242         [(match_operand:P 2 "gpc_reg_operand")
11243          (match_operand:P 3 "gpc_reg_operand")]))
11244   (clobber (match_operand:P 0 "gpc_reg_operand"))]
11245  ""
11246{
11247  enum rtx_code cond_code = GET_CODE (operands[1]);
11248
11249  rtx op0 = operands[0];
11250  rtx op1 = operands[2];
11251  rtx op2 = operands[3];
11252
11253  if (cond_code == GE || cond_code == LT)
11254    {
11255      cond_code = swap_condition (cond_code);
11256      std::swap (op1, op2);
11257    }
11258
11259  rtx tmp1 = gen_reg_rtx (<MODE>mode);
11260  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11261  rtx tmp3 = gen_reg_rtx (<MODE>mode);
11262
11263  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11264  emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11265  emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11266
11267  emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11268
11269  if (cond_code == LE)
11270    emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11271  else
11272    {
11273      rtx tmp4 = gen_reg_rtx (<MODE>mode);
11274      emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11275      emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11276    }
11277
11278  DONE;
11279})
11280
11281(define_expand "cstore<mode>4_unsigned"
11282  [(use (match_operator 1 "unsigned_comparison_operator"
11283         [(match_operand:P 2 "gpc_reg_operand")
11284          (match_operand:P 3 "reg_or_short_operand")]))
11285   (clobber (match_operand:P 0 "gpc_reg_operand"))]
11286  ""
11287{
11288  enum rtx_code cond_code = GET_CODE (operands[1]);
11289
11290  rtx op0 = operands[0];
11291  rtx op1 = operands[2];
11292  rtx op2 = operands[3];
11293
11294  if (cond_code == GEU || cond_code == LTU)
11295    {
11296      cond_code = swap_condition (cond_code);
11297      std::swap (op1, op2);
11298    }
11299
11300  if (!gpc_reg_operand (op1, <MODE>mode))
11301    op1 = force_reg (<MODE>mode, op1);
11302  if (!reg_or_short_operand (op2, <MODE>mode))
11303    op2 = force_reg (<MODE>mode, op2);
11304
11305  rtx tmp = gen_reg_rtx (<MODE>mode);
11306  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11307
11308  emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11309  emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11310
11311  if (cond_code == LEU)
11312    emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11313  else
11314    emit_insn (gen_neg<mode>2 (op0, tmp2));
11315
11316  DONE;
11317})
11318
11319(define_expand "cstore_si_as_di"
11320  [(use (match_operator 1 "unsigned_comparison_operator"
11321         [(match_operand:SI 2 "gpc_reg_operand")
11322          (match_operand:SI 3 "reg_or_short_operand")]))
11323   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11324  ""
11325{
11326  int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11327  enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11328
11329  operands[2] = force_reg (SImode, operands[2]);
11330  operands[3] = force_reg (SImode, operands[3]);
11331  rtx op1 = gen_reg_rtx (DImode);
11332  rtx op2 = gen_reg_rtx (DImode);
11333  convert_move (op1, operands[2], uns_flag);
11334  convert_move (op2, operands[3], uns_flag);
11335
11336  if (cond_code == GT || cond_code == LE)
11337    {
11338      cond_code = swap_condition (cond_code);
11339      std::swap (op1, op2);
11340    }
11341
11342  rtx tmp = gen_reg_rtx (DImode);
11343  rtx tmp2 = gen_reg_rtx (DImode);
11344  emit_insn (gen_subdi3 (tmp, op1, op2));
11345  emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11346
11347  rtx tmp3;
11348  switch (cond_code)
11349    {
11350    default:
11351      gcc_unreachable ();
11352    case LT:
11353      tmp3 = tmp2;
11354      break;
11355    case GE:
11356      tmp3 = gen_reg_rtx (DImode);
11357      emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11358      break;
11359    }
11360
11361  convert_move (operands[0], tmp3, 1);
11362
11363  DONE;
11364})
11365
11366(define_expand "cstore<mode>4_signed_imm"
11367  [(use (match_operator 1 "signed_comparison_operator"
11368         [(match_operand:GPR 2 "gpc_reg_operand")
11369          (match_operand:GPR 3 "immediate_operand")]))
11370   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11371  ""
11372{
11373  bool invert = false;
11374
11375  enum rtx_code cond_code = GET_CODE (operands[1]);
11376
11377  rtx op0 = operands[0];
11378  rtx op1 = operands[2];
11379  HOST_WIDE_INT val = INTVAL (operands[3]);
11380
11381  if (cond_code == GE || cond_code == GT)
11382    {
11383      cond_code = reverse_condition (cond_code);
11384      invert = true;
11385    }
11386
11387  if (cond_code == LE)
11388    val++;
11389
11390  rtx tmp = gen_reg_rtx (<MODE>mode);
11391  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11392  rtx x = gen_reg_rtx (<MODE>mode);
11393  if (val < 0)
11394    emit_insn (gen_and<mode>3 (x, op1, tmp));
11395  else
11396    emit_insn (gen_ior<mode>3 (x, op1, tmp));
11397
11398  if (invert)
11399    {
11400      rtx tmp = gen_reg_rtx (<MODE>mode);
11401      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11402      x = tmp;
11403    }
11404
11405  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11406  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11407
11408  DONE;
11409})
11410
11411(define_expand "cstore<mode>4_unsigned_imm"
11412  [(use (match_operator 1 "unsigned_comparison_operator"
11413         [(match_operand:GPR 2 "gpc_reg_operand")
11414          (match_operand:GPR 3 "immediate_operand")]))
11415   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11416  ""
11417{
11418  bool invert = false;
11419
11420  enum rtx_code cond_code = GET_CODE (operands[1]);
11421
11422  rtx op0 = operands[0];
11423  rtx op1 = operands[2];
11424  HOST_WIDE_INT val = INTVAL (operands[3]);
11425
11426  if (cond_code == GEU || cond_code == GTU)
11427    {
11428      cond_code = reverse_condition (cond_code);
11429      invert = true;
11430    }
11431
11432  if (cond_code == LEU)
11433    val++;
11434
11435  rtx tmp = gen_reg_rtx (<MODE>mode);
11436  rtx tmp2 = gen_reg_rtx (<MODE>mode);
11437  emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11438  emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11439  rtx x = gen_reg_rtx (<MODE>mode);
11440  if (val < 0)
11441    emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11442  else
11443    emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11444
11445  if (invert)
11446    {
11447      rtx tmp = gen_reg_rtx (<MODE>mode);
11448      emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11449      x = tmp;
11450    }
11451
11452  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11453  emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11454
11455  DONE;
11456})
11457
11458(define_expand "cstore<mode>4"
11459  [(use (match_operator 1 "comparison_operator"
11460         [(match_operand:GPR 2 "gpc_reg_operand")
11461          (match_operand:GPR 3 "reg_or_short_operand")]))
11462   (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11463  ""
11464{
11465  /* Expanding EQ and NE directly to some machine instructions does not help
11466     but does hurt combine.  So don't.  */
11467  if (GET_CODE (operands[1]) == EQ)
11468    emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11469  else if (<MODE>mode == Pmode
11470	   && GET_CODE (operands[1]) == NE)
11471    emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11472  else if (GET_CODE (operands[1]) == NE)
11473    {
11474      rtx tmp = gen_reg_rtx (<MODE>mode);
11475      emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11476      emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11477    }
11478
11479  /* If ISEL is fast, expand to it.  */
11480  else if (TARGET_ISEL)
11481    rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11482
11483  /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11484     etc. combinations magically work out just right.  */
11485  else if (<MODE>mode == Pmode
11486	   && unsigned_comparison_operator (operands[1], VOIDmode))
11487    emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11488					   operands[2], operands[3]));
11489
11490  /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11491  else if (<MODE>mode == SImode && Pmode == DImode)
11492    emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11493				    operands[2], operands[3]));
11494
11495  /* For signed comparisons against a constant, we can do some simple
11496     bit-twiddling.  */
11497  else if (signed_comparison_operator (operands[1], VOIDmode)
11498	   && CONST_INT_P (operands[3]))
11499    emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11500					     operands[2], operands[3]));
11501
11502  /* And similarly for unsigned comparisons.  */
11503  else if (unsigned_comparison_operator (operands[1], VOIDmode)
11504	   && CONST_INT_P (operands[3]))
11505    emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11506					       operands[2], operands[3]));
11507
11508  /* We also do not want to use mfcr for signed comparisons.  */
11509  else if (<MODE>mode == Pmode
11510	   && signed_comparison_operator (operands[1], VOIDmode))
11511    emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11512					 operands[2], operands[3]));
11513
11514  /* Everything else, use the mfcr brute force.  */
11515  else
11516    rs6000_emit_sCOND (<MODE>mode, operands);
11517
11518  DONE;
11519})
11520
11521(define_expand "cstore<mode>4"
11522  [(use (match_operator 1 "comparison_operator"
11523         [(match_operand:FP 2 "gpc_reg_operand")
11524          (match_operand:FP 3 "gpc_reg_operand")]))
11525   (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11526  ""
11527{
11528  rs6000_emit_sCOND (<MODE>mode, operands);
11529  DONE;
11530})
11531
11532
11533(define_expand "stack_protect_set"
11534  [(match_operand 0 "memory_operand")
11535   (match_operand 1 "memory_operand")]
11536  ""
11537{
11538  if (rs6000_stack_protector_guard == SSP_TLS)
11539    {
11540      rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11541      rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11542      rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11543      operands[1] = gen_rtx_MEM (Pmode, addr);
11544    }
11545
11546  if (TARGET_64BIT)
11547    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11548  else
11549    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11550
11551  DONE;
11552})
11553
11554(define_insn "stack_protect_setsi"
11555  [(set (match_operand:SI 0 "memory_operand" "=m")
11556	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11557   (set (match_scratch:SI 2 "=&r") (const_int 0))]
11558  "TARGET_32BIT"
11559  "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11560  [(set_attr "type" "three")
11561   (set_attr "length" "12")])
11562
11563;; We can't use the prefixed attribute here because there are two memory
11564;; instructions.  We can't split the insn due to the fact that this operation
11565;; needs to be done in one piece.
11566(define_insn "stack_protect_setdi"
11567  [(set (match_operand:DI 0 "memory_operand" "=Y")
11568	(unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11569   (set (match_scratch:DI 2 "=&r") (const_int 0))]
11570  "TARGET_64BIT"
11571{
11572  if (prefixed_memory (operands[1], DImode))
11573    output_asm_insn ("pld %2,%1", operands);
11574  else
11575    output_asm_insn ("ld%U1%X1 %2,%1", operands);
11576
11577  if (prefixed_memory (operands[0], DImode))
11578    output_asm_insn ("pstd %2,%0", operands);
11579  else
11580    output_asm_insn ("std%U0%X0 %2,%0", operands);
11581
11582  return "li %2,0";
11583}
11584  [(set_attr "type" "three")
11585
11586  ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11587  ;; prefixed instruction + 4 bytes for the possible NOP).  Add in 4 bytes for
11588  ;; the LI 0 at the end.
11589   (set_attr "prefixed" "no")
11590   (set_attr "num_insns" "3")
11591   (set (attr "length")
11592	(cond [(and (match_operand 0 "prefixed_memory")
11593		    (match_operand 1 "prefixed_memory"))
11594	       (const_int 24)
11595
11596	       (ior (match_operand 0 "prefixed_memory")
11597		    (match_operand 1 "prefixed_memory"))
11598	       (const_int 20)]
11599
11600	      (const_int 12)))])
11601
11602(define_expand "stack_protect_test"
11603  [(match_operand 0 "memory_operand")
11604   (match_operand 1 "memory_operand")
11605   (match_operand 2 "")]
11606  ""
11607{
11608  rtx guard = operands[1];
11609
11610  if (rs6000_stack_protector_guard == SSP_TLS)
11611    {
11612      rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11613      rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11614      rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11615      guard = gen_rtx_MEM (Pmode, addr);
11616    }
11617
11618  operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11619  rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11620  rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11621  emit_jump_insn (jump);
11622
11623  DONE;
11624})
11625
11626(define_insn "stack_protect_testsi"
11627  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11628        (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11629		      (match_operand:SI 2 "memory_operand" "m,m")]
11630		     UNSPEC_SP_TEST))
11631   (set (match_scratch:SI 4 "=r,r") (const_int 0))
11632   (clobber (match_scratch:SI 3 "=&r,&r"))]
11633  "TARGET_32BIT"
11634  "@
11635   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11636   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11637  [(set_attr "length" "16,20")])
11638
11639;; We can't use the prefixed attribute here because there are two memory
11640;; instructions.  We can't split the insn due to the fact that this operation
11641;; needs to be done in one piece.
11642(define_insn "stack_protect_testdi"
11643  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11644        (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11645		      (match_operand:DI 2 "memory_operand" "Y,Y")]
11646		     UNSPEC_SP_TEST))
11647   (set (match_scratch:DI 4 "=r,r") (const_int 0))
11648   (clobber (match_scratch:DI 3 "=&r,&r"))]
11649  "TARGET_64BIT"
11650{
11651  if (prefixed_memory (operands[1], DImode))
11652    output_asm_insn ("pld %3,%1", operands);
11653  else
11654    output_asm_insn ("ld%U1%X1 %3,%1", operands);
11655
11656  if (prefixed_memory (operands[2], DImode))
11657    output_asm_insn ("pld %4,%2", operands);
11658  else
11659    output_asm_insn ("ld%U2%X2 %4,%2", operands);
11660
11661  if (which_alternative == 0)
11662    output_asm_insn ("xor. %3,%3,%4", operands);
11663  else
11664    output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11665
11666  return "li %4,0";
11667}
11668  ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11669  ;; prefixed instruction + 4 bytes for the possible NOP).  Add in either 4 or
11670  ;; 8 bytes to do the test.
11671  [(set_attr "prefixed" "no")
11672   (set_attr "num_insns" "4,5")
11673   (set (attr "length")
11674	(cond [(and (match_operand 1 "prefixed_memory")
11675		    (match_operand 2 "prefixed_memory"))
11676	       (if_then_else (eq_attr "alternative" "0")
11677			     (const_int 28)
11678			     (const_int 32))
11679
11680	       (ior (match_operand 1 "prefixed_memory")
11681		    (match_operand 2 "prefixed_memory"))
11682	       (if_then_else (eq_attr "alternative" "0")
11683			     (const_int 20)
11684			     (const_int 24))]
11685
11686	      (if_then_else (eq_attr "alternative" "0")
11687			    (const_int 16)
11688			    (const_int 20))))])
11689
11690
11691;; Here are the actual compare insns.
11692(define_insn "*cmp<mode>_signed"
11693  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11694	(compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11695		    (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11696  ""
11697  "cmp<wd>%I2 %0,%1,%2"
11698  [(set_attr "type" "cmp")])
11699
11700(define_insn "*cmp<mode>_unsigned"
11701  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11702	(compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11703		       (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11704  ""
11705  "cmpl<wd>%I2 %0,%1,%2"
11706  [(set_attr "type" "cmp")])
11707
11708;; If we are comparing a register for equality with a large constant,
11709;; we can do this with an XOR followed by a compare.  But this is profitable
11710;; only if the large constant is only used for the comparison (and in this
11711;; case we already have a register to reuse as scratch).
11712;;
11713;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11714;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11715
11716(define_peephole2
11717  [(set (match_operand:SI 0 "register_operand")
11718        (match_operand:SI 1 "logical_const_operand"))
11719   (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11720		       [(match_dup 0)
11721			(match_operand:SI 2 "logical_const_operand")]))
11722   (set (match_operand:CC 4 "cc_reg_operand")
11723        (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11724                    (match_dup 0)))
11725   (set (pc)
11726        (if_then_else (match_operator 6 "equality_operator"
11727                       [(match_dup 4) (const_int 0)])
11728                      (match_operand 7 "")
11729                      (match_operand 8 "")))]
11730  "peep2_reg_dead_p (3, operands[0])
11731   && peep2_reg_dead_p (4, operands[4])
11732   && REGNO (operands[0]) != REGNO (operands[5])"
11733 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11734  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11735  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11736 
11737{
11738  /* Get the constant we are comparing against, and see what it looks like
11739     when sign-extended from 16 to 32 bits.  Then see what constant we could
11740     XOR with SEXTC to get the sign-extended value.  */
11741  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11742					      SImode,
11743					      operands[1], operands[2]);
11744  HOST_WIDE_INT c = INTVAL (cnst);
11745  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11746  HOST_WIDE_INT xorv = c ^ sextc;
11747
11748  operands[9] = GEN_INT (xorv);
11749  operands[10] = GEN_INT (sextc);
11750})
11751
11752;; Only need to compare second words if first words equal
11753(define_insn "*cmp<mode>_internal1"
11754  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11755	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11756		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11757  "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11758   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11759  "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11760  [(set_attr "type" "fpcompare")
11761   (set_attr "length" "12")])
11762
11763(define_insn_and_split "*cmp<IBM128:mode>_internal2"
11764  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11765	(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11766		      (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11767    (clobber (match_scratch:DF 3 "=d"))
11768    (clobber (match_scratch:DF 4 "=d"))
11769    (clobber (match_scratch:DF 5 "=d"))
11770    (clobber (match_scratch:DF 6 "=d"))
11771    (clobber (match_scratch:DF 7 "=d"))
11772    (clobber (match_scratch:DF 8 "=d"))
11773    (clobber (match_scratch:DF 9 "=d"))
11774    (clobber (match_scratch:DF 10 "=d"))
11775    (clobber (match_scratch:GPR 11 "=b"))]
11776  "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11777   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11778  "#"
11779  "&& reload_completed"
11780  [(set (match_dup 3) (match_dup 14))
11781   (set (match_dup 4) (match_dup 15))
11782   (set (match_dup 9) (abs:DF (match_dup 5)))
11783   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11784   (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11785			   (label_ref (match_dup 12))
11786			   (pc)))
11787   (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11788   (set (pc) (label_ref (match_dup 13)))
11789   (match_dup 12)
11790   (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11791   (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11792   (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11793   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11794   (match_dup 13)]
11795{
11796  REAL_VALUE_TYPE rv;
11797  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11798  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11799
11800  operands[5] = simplify_gen_subreg (DFmode, operands[1],
11801				     <IBM128:MODE>mode, hi_word);
11802  operands[6] = simplify_gen_subreg (DFmode, operands[1],
11803				     <IBM128:MODE>mode, lo_word);
11804  operands[7] = simplify_gen_subreg (DFmode, operands[2],
11805				     <IBM128:MODE>mode, hi_word);
11806  operands[8] = simplify_gen_subreg (DFmode, operands[2],
11807				     <IBM128:MODE>mode, lo_word);
11808  operands[12] = gen_label_rtx ();
11809  operands[13] = gen_label_rtx ();
11810  real_inf (&rv);
11811  operands[14] = force_const_mem (DFmode,
11812				  const_double_from_real_value (rv, DFmode));
11813  operands[15] = force_const_mem (DFmode,
11814				  const_double_from_real_value (dconst0,
11815								DFmode));
11816  if (TARGET_TOC)
11817    {
11818      rtx tocref;
11819      tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11820      operands[14] = gen_const_mem (DFmode, tocref);
11821      tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11822      operands[15] = gen_const_mem (DFmode, tocref);
11823      set_mem_alias_set (operands[14], get_TOC_alias_set ());
11824      set_mem_alias_set (operands[15], get_TOC_alias_set ());
11825    }
11826})
11827
11828;; Now we have the scc insns.  We can do some combinations because of the
11829;; way the machine works.
11830;;
11831;; Note that this is probably faster if we can put an insn between the
11832;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11833;; cases the insns below which don't use an intermediate CR field will
11834;; be used instead.
11835(define_insn "set<mode>_cc"
11836  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11837	(match_operator:GPR 1 "scc_comparison_operator"
11838			    [(match_operand 2 "cc_reg_operand" "y")
11839			     (const_int 0)]))]
11840  ""
11841  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11842  [(set (attr "type")
11843     (cond [(match_test "TARGET_MFCRF")
11844		(const_string "mfcrf")
11845	   ]
11846	(const_string "mfcr")))
11847   (set_attr "length" "8")])
11848
11849
11850(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11851(define_code_attr UNS [(eq "CC")
11852		       (ne "CC")
11853		       (lt "CC") (ltu "CCUNS")
11854		       (gt "CC") (gtu "CCUNS")
11855		       (le "CC") (leu "CCUNS")
11856		       (ge "CC") (geu "CCUNS")])
11857(define_code_attr UNSu_ [(eq "")
11858			 (ne "")
11859			 (lt "") (ltu "u_")
11860			 (gt "") (gtu "u_")
11861			 (le "") (leu "u_")
11862			 (ge "") (geu "u_")])
11863(define_code_attr UNSIK [(eq "I")
11864			 (ne "I")
11865			 (lt "I") (ltu "K")
11866			 (gt "I") (gtu "K")
11867			 (le "I") (leu "K")
11868			 (ge "I") (geu "K")])
11869
11870(define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11871  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11872	(cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11873		 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11874   (clobber (match_scratch:GPR 3 "=r"))
11875   (clobber (match_scratch:GPR 4 "=r"))
11876   (clobber (match_scratch:<UNS> 5 "=y"))]
11877  "TARGET_ISEL
11878   && !(<CODE> == EQ && operands[2] == const0_rtx)
11879   && !(<CODE> == NE && operands[2] == const0_rtx
11880	&& <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11881  "#"
11882  "&& 1"
11883  [(pc)]
11884{
11885  rtx_code code = <CODE>;
11886  if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11887    {
11888      HOST_WIDE_INT val = INTVAL (operands[2]);
11889      if (code == LT && val != -0x8000)
11890	{
11891	  code = LE;
11892	  val--;
11893	}
11894      if (code == GT && val != 0x7fff)
11895	{
11896	  code = GE;
11897	  val++;
11898	}
11899      if (code == LTU && val != 0)
11900	{
11901	  code = LEU;
11902	  val--;
11903	}
11904      if (code == GTU && val != 0xffff)
11905	{
11906	  code = GEU;
11907	  val++;
11908	}
11909      operands[2] = GEN_INT (val);
11910    }
11911
11912  if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11913    operands[3] = const0_rtx;
11914  else
11915    {
11916      if (GET_CODE (operands[3]) == SCRATCH)
11917	operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11918      emit_move_insn (operands[3], const0_rtx);
11919    }
11920
11921  if (GET_CODE (operands[4]) == SCRATCH)
11922    operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11923  emit_move_insn (operands[4], const1_rtx);
11924
11925  if (GET_CODE (operands[5]) == SCRATCH)
11926    operands[5] = gen_reg_rtx (<UNS>mode);
11927
11928  rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11929  emit_insn (gen_rtx_SET (operands[5], c1));
11930
11931  rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11932  rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11933  emit_move_insn (operands[0], x);
11934
11935  DONE;
11936}
11937  [(set (attr "cost")
11938	(if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11939				   || <CODE> == NE
11940				   || <CODE> == LE || <CODE> == GE
11941				   || <CODE> == LEU || <CODE> == GEU")
11942		      (const_string "9")
11943		      (const_string "10")))])
11944
11945(define_mode_attr scc_eq_op2 [(SI "rKLI")
11946			      (DI "rKJI")])
11947
11948(define_expand "eq<mode>3"
11949  [(parallel [
11950     (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11951	  (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11952		  (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11953     (clobber (match_scratch:GPR 3 "=r"))
11954     (clobber (match_scratch:GPR 4 "=r"))])]
11955  ""
11956{
11957  if (TARGET_ISEL && operands[2] != const0_rtx)
11958    {
11959      emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11960					   operands[2]));
11961      DONE;
11962    }
11963})
11964
11965(define_insn_and_split "*eq<mode>3"
11966  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11967	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11968		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11969   (clobber (match_scratch:GPR 3 "=r"))
11970   (clobber (match_scratch:GPR 4 "=r"))]
11971  "!(TARGET_ISEL && operands[2] != const0_rtx)"
11972  "#"
11973  "&& 1"
11974  [(set (match_dup 4)
11975	(clz:GPR (match_dup 3)))
11976   (set (match_dup 0)
11977	(lshiftrt:GPR (match_dup 4)
11978		      (match_dup 5)))]
11979{
11980  operands[3] = rs6000_emit_eqne (<MODE>mode,
11981				  operands[1], operands[2], operands[3]);
11982
11983  if (GET_CODE (operands[4]) == SCRATCH)
11984    operands[4] = gen_reg_rtx (<MODE>mode);
11985
11986  operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11987}
11988  [(set (attr "length")
11989	(if_then_else (match_test "operands[2] == const0_rtx")
11990		      (const_string "8")
11991		      (const_string "12")))])
11992
11993(define_expand "ne<mode>3"
11994  [(parallel [
11995     (set (match_operand:P 0 "gpc_reg_operand" "=r")
11996	  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11997		(match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11998     (clobber (match_scratch:P 3 "=r"))
11999     (clobber (match_scratch:P 4 "=r"))
12000     (clobber (reg:P CA_REGNO))])]
12001  ""
12002{
12003  if (TARGET_ISEL && operands[2] != const0_rtx)
12004    {
12005      emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12006					   operands[2]));
12007      DONE;
12008    }
12009})
12010
12011(define_insn_and_split "*ne<mode>3"
12012  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12013	(ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12014	      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12015   (clobber (match_scratch:P 3 "=r"))
12016   (clobber (match_scratch:P 4 "=r"))
12017   (clobber (reg:P CA_REGNO))]
12018  "!(TARGET_ISEL && operands[2] != const0_rtx)"
12019  "#"
12020  "&& 1"
12021  [(parallel [(set (match_dup 4)
12022		   (plus:P (match_dup 3)
12023			   (const_int -1)))
12024	      (set (reg:P CA_REGNO)
12025		   (ne:P (match_dup 3)
12026			 (const_int 0)))])
12027   (parallel [(set (match_dup 0)
12028		   (plus:P (plus:P (not:P (match_dup 4))
12029				   (reg:P CA_REGNO))
12030			   (match_dup 3)))
12031	      (clobber (reg:P CA_REGNO))])]
12032{
12033  operands[3] = rs6000_emit_eqne (<MODE>mode,
12034				  operands[1], operands[2], operands[3]);
12035
12036  if (GET_CODE (operands[4]) == SCRATCH)
12037    operands[4] = gen_reg_rtx (<MODE>mode);
12038}
12039  [(set (attr "length")
12040	(if_then_else (match_test "operands[2] == const0_rtx")
12041		      (const_string "8")
12042		      (const_string "12")))])
12043
12044(define_insn_and_split "*neg_eq_<mode>"
12045  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12046	(neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12047		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12048   (clobber (match_scratch:P 3 "=r"))
12049   (clobber (match_scratch:P 4 "=r"))
12050   (clobber (reg:P CA_REGNO))]
12051  ""
12052  "#"
12053  ""
12054  [(parallel [(set (match_dup 4)
12055		   (plus:P (match_dup 3)
12056			   (const_int -1)))
12057	      (set (reg:P CA_REGNO)
12058		   (ne:P (match_dup 3)
12059			 (const_int 0)))])
12060   (parallel [(set (match_dup 0)
12061		   (plus:P (reg:P CA_REGNO)
12062			   (const_int -1)))
12063	      (clobber (reg:P CA_REGNO))])]
12064{
12065  operands[3] = rs6000_emit_eqne (<MODE>mode,
12066				  operands[1], operands[2], operands[3]);
12067
12068  if (GET_CODE (operands[4]) == SCRATCH)
12069    operands[4] = gen_reg_rtx (<MODE>mode);
12070}
12071  [(set (attr "length")
12072	(if_then_else (match_test "operands[2] == const0_rtx")
12073		      (const_string "8")
12074		      (const_string "12")))])
12075
12076(define_insn_and_split "*neg_ne_<mode>"
12077  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12078	(neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12079		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12080   (clobber (match_scratch:P 3 "=r"))
12081   (clobber (match_scratch:P 4 "=r"))
12082   (clobber (reg:P CA_REGNO))]
12083  ""
12084  "#"
12085  ""
12086  [(parallel [(set (match_dup 4)
12087		   (neg:P (match_dup 3)))
12088	      (set (reg:P CA_REGNO)
12089		   (eq:P (match_dup 3)
12090			 (const_int 0)))])
12091   (parallel [(set (match_dup 0)
12092		   (plus:P (reg:P CA_REGNO)
12093			   (const_int -1)))
12094	      (clobber (reg:P CA_REGNO))])]
12095{
12096  operands[3] = rs6000_emit_eqne (<MODE>mode,
12097				  operands[1], operands[2], operands[3]);
12098
12099  if (GET_CODE (operands[4]) == SCRATCH)
12100    operands[4] = gen_reg_rtx (<MODE>mode);
12101}
12102  [(set (attr "length")
12103	(if_then_else (match_test "operands[2] == const0_rtx")
12104		      (const_string "8")
12105		      (const_string "12")))])
12106
12107(define_insn_and_split "*plus_eq_<mode>"
12108  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12109	(plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12110		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12111		(match_operand:P 3 "gpc_reg_operand" "r")))
12112   (clobber (match_scratch:P 4 "=r"))
12113   (clobber (match_scratch:P 5 "=r"))
12114   (clobber (reg:P CA_REGNO))]
12115  ""
12116  "#"
12117  ""
12118  [(parallel [(set (match_dup 5)
12119		   (neg:P (match_dup 4)))
12120	      (set (reg:P CA_REGNO)
12121		   (eq:P (match_dup 4)
12122			 (const_int 0)))])
12123   (parallel [(set (match_dup 0)
12124		   (plus:P (match_dup 3)
12125			   (reg:P CA_REGNO)))
12126	      (clobber (reg:P CA_REGNO))])]
12127{
12128  operands[4] = rs6000_emit_eqne (<MODE>mode,
12129				  operands[1], operands[2], operands[4]);
12130
12131  if (GET_CODE (operands[5]) == SCRATCH)
12132    operands[5] = gen_reg_rtx (<MODE>mode);
12133}
12134  [(set (attr "length")
12135	(if_then_else (match_test "operands[2] == const0_rtx")
12136		      (const_string "8")
12137		      (const_string "12")))])
12138
12139(define_insn_and_split "*plus_ne_<mode>"
12140  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12141	(plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12142		      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12143		(match_operand:P 3 "gpc_reg_operand" "r")))
12144   (clobber (match_scratch:P 4 "=r"))
12145   (clobber (match_scratch:P 5 "=r"))
12146   (clobber (reg:P CA_REGNO))]
12147  ""
12148  "#"
12149  ""
12150  [(parallel [(set (match_dup 5)
12151		   (plus:P (match_dup 4)
12152			   (const_int -1)))
12153	      (set (reg:P CA_REGNO)
12154		   (ne:P (match_dup 4)
12155			 (const_int 0)))])
12156   (parallel [(set (match_dup 0)
12157		   (plus:P (match_dup 3)
12158			   (reg:P CA_REGNO)))
12159	      (clobber (reg:P CA_REGNO))])]
12160{
12161  operands[4] = rs6000_emit_eqne (<MODE>mode,
12162				  operands[1], operands[2], operands[4]);
12163
12164  if (GET_CODE (operands[5]) == SCRATCH)
12165    operands[5] = gen_reg_rtx (<MODE>mode);
12166}
12167  [(set (attr "length")
12168	(if_then_else (match_test "operands[2] == const0_rtx")
12169		      (const_string "8")
12170		      (const_string "12")))])
12171
12172(define_insn_and_split "*minus_eq_<mode>"
12173  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12174	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12175		 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12176		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12177   (clobber (match_scratch:P 4 "=r"))
12178   (clobber (match_scratch:P 5 "=r"))
12179   (clobber (reg:P CA_REGNO))]
12180  ""
12181  "#"
12182  ""
12183  [(parallel [(set (match_dup 5)
12184		   (plus:P (match_dup 4)
12185			   (const_int -1)))
12186	      (set (reg:P CA_REGNO)
12187		   (ne:P (match_dup 4)
12188			 (const_int 0)))])
12189   (parallel [(set (match_dup 0)
12190		   (plus:P (plus:P (match_dup 3)
12191				   (reg:P CA_REGNO))
12192			   (const_int -1)))
12193	      (clobber (reg:P CA_REGNO))])]
12194{
12195  operands[4] = rs6000_emit_eqne (<MODE>mode,
12196				  operands[1], operands[2], operands[4]);
12197
12198  if (GET_CODE (operands[5]) == SCRATCH)
12199    operands[5] = gen_reg_rtx (<MODE>mode);
12200}
12201  [(set (attr "length")
12202	(if_then_else (match_test "operands[2] == const0_rtx")
12203		      (const_string "8")
12204		      (const_string "12")))])
12205
12206(define_insn_and_split "*minus_ne_<mode>"
12207  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12208	(minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12209		 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12210		       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12211   (clobber (match_scratch:P 4 "=r"))
12212   (clobber (match_scratch:P 5 "=r"))
12213   (clobber (reg:P CA_REGNO))]
12214  ""
12215  "#"
12216  ""
12217  [(parallel [(set (match_dup 5)
12218		   (neg:P (match_dup 4)))
12219	      (set (reg:P CA_REGNO)
12220		   (eq:P (match_dup 4)
12221			 (const_int 0)))])
12222   (parallel [(set (match_dup 0)
12223		   (plus:P (plus:P (match_dup 3)
12224				   (reg:P CA_REGNO))
12225			   (const_int -1)))
12226	      (clobber (reg:P CA_REGNO))])]
12227{
12228  operands[4] = rs6000_emit_eqne (<MODE>mode,
12229				  operands[1], operands[2], operands[4]);
12230
12231  if (GET_CODE (operands[5]) == SCRATCH)
12232    operands[5] = gen_reg_rtx (<MODE>mode);
12233}
12234  [(set (attr "length")
12235	(if_then_else (match_test "operands[2] == const0_rtx")
12236		      (const_string "8")
12237		      (const_string "12")))])
12238
12239(define_insn_and_split "*eqsi3_ext<mode>"
12240  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12241	(eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12242		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12243   (clobber (match_scratch:SI 3 "=r"))
12244   (clobber (match_scratch:SI 4 "=r"))]
12245  ""
12246  "#"
12247  ""
12248  [(set (match_dup 4)
12249	(clz:SI (match_dup 3)))
12250   (set (match_dup 0)
12251	(zero_extend:EXTSI
12252	  (lshiftrt:SI (match_dup 4)
12253		       (const_int 5))))]
12254{
12255  operands[3] = rs6000_emit_eqne (SImode,
12256				  operands[1], operands[2], operands[3]);
12257
12258  if (GET_CODE (operands[4]) == SCRATCH)
12259    operands[4] = gen_reg_rtx (SImode);
12260}
12261  [(set (attr "length")
12262	(if_then_else (match_test "operands[2] == const0_rtx")
12263		      (const_string "8")
12264		      (const_string "12")))])
12265
12266(define_insn_and_split "*nesi3_ext<mode>"
12267  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12268	(ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12269		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12270   (clobber (match_scratch:SI 3 "=r"))
12271   (clobber (match_scratch:SI 4 "=r"))
12272   (clobber (match_scratch:EXTSI 5 "=r"))]
12273  "!TARGET_ISEL"
12274  "#"
12275  "&& 1"
12276  [(set (match_dup 4)
12277	(clz:SI (match_dup 3)))
12278   (set (match_dup 5)
12279	(zero_extend:EXTSI
12280	  (lshiftrt:SI (match_dup 4)
12281		       (const_int 5))))
12282   (set (match_dup 0)
12283	(xor:EXTSI (match_dup 5)
12284		   (const_int 1)))]
12285{
12286  operands[3] = rs6000_emit_eqne (SImode,
12287				  operands[1], operands[2], operands[3]);
12288
12289  if (GET_CODE (operands[4]) == SCRATCH)
12290    operands[4] = gen_reg_rtx (SImode);
12291  if (GET_CODE (operands[5]) == SCRATCH)
12292    operands[5] = gen_reg_rtx (<MODE>mode);
12293}
12294  [(set (attr "length")
12295	(if_then_else (match_test "operands[2] == const0_rtx")
12296		      (const_string "12")
12297		      (const_string "16")))])
12298
12299
12300(define_code_iterator fp_rev [ordered ne unle unge])
12301(define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12302
12303(define_insn_and_split "*<code><mode>_cc"
12304  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12305	(fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12306		    (const_int 0)))]
12307  "!flag_finite_math_only"
12308  "#"
12309  "&& 1"
12310  [(pc)]
12311{
12312  rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12313  rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12314  rtx tmp = gen_reg_rtx (<MODE>mode);
12315  emit_move_insn (tmp, eq);
12316  emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12317  DONE;
12318}
12319  [(set_attr "length" "12")])
12320
12321(define_insn_and_split "*<code><mode>_cc"
12322  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12323	(fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12324		  (const_int 0)))]
12325  "!flag_finite_math_only"
12326  "#"
12327  "&& 1"
12328  [(pc)]
12329{
12330  rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12331
12332  emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12333  DONE;
12334}
12335  [(set_attr "length" "12")])
12336
12337;; Conditional branches.
12338;; These either are a single bc insn, or a bc around a b.
12339
12340(define_insn "*cbranch"
12341  [(set (pc)
12342	(if_then_else (match_operator 1 "branch_comparison_operator"
12343				      [(match_operand 2 "cc_reg_operand" "y")
12344				       (const_int 0)])
12345		      (label_ref (match_operand 0))
12346		      (pc)))]
12347  ""
12348{
12349  return output_cbranch (operands[1], "%l0", 0, insn);
12350}
12351  [(set_attr "type" "branch")
12352   (set (attr "length")
12353	(if_then_else (and (ge (minus (match_dup 0) (pc))
12354			       (const_int -32768))
12355			   (lt (minus (match_dup 0) (pc))
12356			       (const_int 32764)))
12357		      (const_int 4)
12358		      (const_int 8)))])
12359
12360(define_insn_and_split "*cbranch_2insn"
12361  [(set (pc)
12362	(if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12363				      [(match_operand 2 "cc_reg_operand" "y")
12364				       (const_int 0)])
12365		      (label_ref (match_operand 0))
12366		      (pc)))]
12367  "!flag_finite_math_only"
12368  "#"
12369  "&& 1"
12370  [(pc)]
12371{
12372  rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12373
12374  rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12375
12376  rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12377  rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12378  rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12379  emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12380
12381  if (note)
12382    {
12383      profile_probability prob
12384	= profile_probability::from_reg_br_prob_note (XINT (note, 0));
12385
12386      add_reg_br_prob_note (get_last_insn (), prob);
12387    }
12388
12389  DONE;
12390}
12391  [(set_attr "type" "branch")
12392   (set (attr "length")
12393	(if_then_else (and (ge (minus (match_dup 0) (pc))
12394			       (const_int -32764))
12395			   (lt (minus (match_dup 0) (pc))
12396			       (const_int 32760)))
12397		      (const_int 8)
12398		      (const_int 16)))])
12399
12400;; Conditional return.
12401(define_insn "*creturn"
12402  [(set (pc)
12403	(if_then_else (match_operator 0 "branch_comparison_operator"
12404				      [(match_operand 1 "cc_reg_operand" "y")
12405				       (const_int 0)])
12406		      (any_return)
12407		      (pc)))]
12408  "<return_pred>"
12409{
12410  return output_cbranch (operands[0], NULL, 0, insn);
12411}
12412  [(set_attr "type" "jmpreg")])
12413
12414;; Logic on condition register values.
12415
12416; This pattern matches things like
12417; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12418;					   (eq:SI (reg:CCFP 68) (const_int 0)))
12419;				   (const_int 1)))
12420; which are generated by the branch logic.
12421; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12422
12423(define_insn "@cceq_ior_compare_<mode>"
12424  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12425        (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12426	                [(match_operator:GPR 2
12427				      "branch_positive_comparison_operator"
12428				      [(match_operand 3
12429						      "cc_reg_operand" "y,y")
12430				       (const_int 0)])
12431	                 (match_operator:GPR 4
12432				      "branch_positive_comparison_operator"
12433				      [(match_operand 5
12434						      "cc_reg_operand" "0,y")
12435				       (const_int 0)])])
12436		      (const_int 1)))]
12437  ""
12438  "cr%q1 %E0,%j2,%j4"
12439  [(set_attr "type" "cr_logical")
12440   (set_attr "cr_logical_3op" "no,yes")])
12441
12442; Why is the constant -1 here, but 1 in the previous pattern?
12443; Because ~1 has all but the low bit set.
12444(define_insn "cceq_ior_compare_complement"
12445  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12446        (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12447	                [(not:SI (match_operator:SI 2
12448				      "branch_positive_comparison_operator"
12449				      [(match_operand 3
12450						      "cc_reg_operand" "y,y")
12451				       (const_int 0)]))
12452	                 (match_operator:SI 4
12453				"branch_positive_comparison_operator"
12454				[(match_operand 5
12455						"cc_reg_operand" "0,y")
12456				 (const_int 0)])])
12457		      (const_int -1)))]
12458  ""
12459  "cr%q1 %E0,%j2,%j4"
12460  [(set_attr "type" "cr_logical")
12461   (set_attr "cr_logical_3op" "no,yes")])
12462
12463(define_insn "@cceq_rev_compare_<mode>"
12464  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12465	(compare:CCEQ (match_operator:GPR 1
12466				      "branch_positive_comparison_operator"
12467				      [(match_operand 2
12468						      "cc_reg_operand" "0,y")
12469				       (const_int 0)])
12470		      (const_int 0)))]
12471  ""
12472  "crnot %E0,%j1"
12473  [(set_attr "type" "cr_logical")
12474   (set_attr "cr_logical_3op" "no,yes")])
12475
12476;; If we are comparing the result of two comparisons, this can be done
12477;; using creqv or crxor.
12478
12479(define_insn_and_split ""
12480  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12481	(compare:CCEQ (match_operator 1 "branch_comparison_operator"
12482			      [(match_operand 2 "cc_reg_operand" "y")
12483			       (const_int 0)])
12484		      (match_operator 3 "branch_comparison_operator"
12485			      [(match_operand 4 "cc_reg_operand" "y")
12486			       (const_int 0)])))]
12487  ""
12488  "#"
12489  ""
12490  [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12491				    (match_dup 5)))]
12492{
12493  int positive_1, positive_2;
12494
12495  positive_1 = branch_positive_comparison_operator (operands[1],
12496						    GET_MODE (operands[1]));
12497  positive_2 = branch_positive_comparison_operator (operands[3],
12498						    GET_MODE (operands[3]));
12499
12500  if (! positive_1)
12501    operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12502							    GET_CODE (operands[1])),
12503				  SImode,
12504				  operands[2], const0_rtx);
12505  else if (GET_MODE (operands[1]) != SImode)
12506    operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12507				  operands[2], const0_rtx);
12508
12509  if (! positive_2)
12510    operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12511							    GET_CODE (operands[3])),
12512				  SImode,
12513				  operands[4], const0_rtx);
12514  else if (GET_MODE (operands[3]) != SImode)
12515    operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12516				  operands[4], const0_rtx);
12517
12518  if (positive_1 == positive_2)
12519    {
12520      operands[1] = gen_rtx_NOT (SImode, operands[1]);
12521      operands[5] = constm1_rtx;
12522    }
12523  else
12524    {
12525      operands[5] = const1_rtx;
12526    }
12527})
12528
12529;; Unconditional branch and return.
12530
12531(define_insn "jump"
12532  [(set (pc)
12533	(label_ref (match_operand 0)))]
12534  ""
12535  "b %l0"
12536  [(set_attr "type" "branch")])
12537
12538(define_insn "<return_str>return"
12539  [(any_return)]
12540  "<return_pred>"
12541  "blr"
12542  [(set_attr "type" "jmpreg")])
12543
12544(define_expand "indirect_jump"
12545  [(set (pc) (match_operand 0 "register_operand"))]
12546 ""
12547{
12548  if (!rs6000_speculate_indirect_jumps) {
12549    rtx ccreg = gen_reg_rtx (CCmode);
12550    emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12551    DONE;
12552  }
12553})
12554
12555(define_insn "*indirect_jump<mode>"
12556  [(set (pc)
12557	(match_operand:P 0 "register_operand" "c,*l"))]
12558  "rs6000_speculate_indirect_jumps"
12559  "b%T0"
12560  [(set_attr "type" "jmpreg")])
12561
12562(define_insn "@indirect_jump<mode>_nospec"
12563  [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12564   (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12565  "!rs6000_speculate_indirect_jumps"
12566  "crset %E1\;beq%T0- %1\;b $"
12567  [(set_attr "type" "jmpreg")
12568   (set_attr "length" "12")])
12569
12570;; Table jump for switch statements:
12571(define_expand "tablejump"
12572  [(use (match_operand 0))
12573   (use (label_ref (match_operand 1)))]
12574  ""
12575{
12576  if (rs6000_speculate_indirect_jumps)
12577    {
12578      if (TARGET_32BIT)
12579      	emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12580      else
12581	emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12582    }
12583  else
12584    {
12585      rtx ccreg = gen_reg_rtx (CCmode);
12586      rtx jump;
12587      if (TARGET_32BIT)
12588	jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12589      else
12590	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12591      emit_jump_insn (jump);
12592    }
12593  DONE;
12594})
12595
12596(define_expand "tablejumpsi"
12597  [(set (match_dup 3)
12598	(plus:SI (match_operand:SI 0)
12599		 (match_dup 2)))
12600   (parallel [(set (pc)
12601		   (match_dup 3))
12602	      (use (label_ref (match_operand 1)))])]
12603  "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12604{
12605  operands[0] = force_reg (SImode, operands[0]);
12606  operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12607  operands[3] = gen_reg_rtx (SImode);
12608})
12609
12610(define_expand "tablejumpsi_nospec"
12611  [(set (match_dup 4)
12612	(plus:SI (match_operand:SI 0)
12613		 (match_dup 3)))
12614   (parallel [(set (pc)
12615		   (match_dup 4))
12616	      (use (label_ref (match_operand 1)))
12617	      (clobber (match_operand 2))])]
12618  "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12619{
12620  operands[0] = force_reg (SImode, operands[0]);
12621  operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12622  operands[4] = gen_reg_rtx (SImode);
12623})
12624
12625(define_expand "tablejumpdi"
12626  [(set (match_dup 4)
12627        (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12628   (set (match_dup 3)
12629	(plus:DI (match_dup 4)
12630		 (match_dup 2)))
12631   (parallel [(set (pc)
12632		   (match_dup 3))
12633	      (use (label_ref (match_operand 1)))])]
12634  "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12635{
12636  operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12637  operands[3] = gen_reg_rtx (DImode);
12638  operands[4] = gen_reg_rtx (DImode);
12639})
12640
12641(define_expand "tablejumpdi_nospec"
12642  [(set (match_dup 5)
12643        (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12644   (set (match_dup 4)
12645	(plus:DI (match_dup 5)
12646		 (match_dup 3)))
12647   (parallel [(set (pc)
12648		   (match_dup 4))
12649	      (use (label_ref (match_operand 1)))
12650	      (clobber (match_operand 2))])]
12651  "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12652{
12653  operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12654  operands[4] = gen_reg_rtx (DImode);
12655  operands[5] = gen_reg_rtx (DImode);
12656})
12657
12658(define_insn "*tablejump<mode>_internal1"
12659  [(set (pc)
12660	(match_operand:P 0 "register_operand" "c,*l"))
12661   (use (label_ref (match_operand 1)))]
12662  "rs6000_speculate_indirect_jumps"
12663  "b%T0"
12664  [(set_attr "type" "jmpreg")])
12665
12666(define_insn "*tablejump<mode>_internal1_nospec"
12667  [(set (pc)
12668	(match_operand:P 0 "register_operand" "c,*l"))
12669   (use (label_ref (match_operand 1)))
12670   (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12671  "!rs6000_speculate_indirect_jumps"
12672  "crset %E2\;beq%T0- %2\;b $"
12673  [(set_attr "type" "jmpreg")
12674   (set_attr "length" "12")])
12675
12676(define_insn "nop"
12677  [(unspec [(const_int 0)] UNSPEC_NOP)]
12678  ""
12679  "nop")
12680
12681(define_insn "group_ending_nop"
12682  [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12683  ""
12684{
12685  operands[0] = gen_rtx_REG (Pmode,
12686			     rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12687  return "ori %0,%0,0";
12688})
12689
12690(define_insn "speculation_barrier"
12691  [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12692  ""
12693{
12694  operands[0] = gen_rtx_REG (Pmode, 31);
12695  return "ori %0,%0,0";
12696})
12697
12698;; Define the subtract-one-and-jump insns, starting with the template
12699;; so loop.c knows what to generate.
12700
12701(define_expand "doloop_end"
12702  [(use (match_operand 0))	; loop pseudo
12703   (use (match_operand 1))]	; label
12704  ""
12705{
12706  if (GET_MODE (operands[0]) != Pmode)
12707    FAIL;
12708
12709  emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12710  DONE;
12711})
12712
12713(define_expand "@ctr<mode>"
12714  [(parallel [(set (pc)
12715		   (if_then_else (ne (match_operand:P 0 "register_operand")
12716				     (const_int 1))
12717				 (label_ref (match_operand 1))
12718				 (pc)))
12719	      (set (match_dup 0)
12720		   (plus:P (match_dup 0)
12721			    (const_int -1)))
12722	      (clobber (match_scratch:CC 2))
12723	      (clobber (match_scratch:P 3))])]
12724  ""
12725  "")
12726
12727;; We need to be able to do this for any operand, including MEM, or we
12728;; will cause reload to blow up since we don't allow output reloads on
12729;; JUMP_INSNs.
12730;; For the length attribute to be calculated correctly, the
12731;; label MUST be operand 0.
12732;; rs6000_legitimate_combined_insn prevents combine creating any of
12733;; the ctr<mode> insns.
12734
12735(define_code_iterator eqne [eq ne])
12736(define_code_attr bd [(eq "bdz") (ne "bdnz")])
12737(define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12738
12739(define_insn "<bd>_<mode>"
12740  [(set (pc)
12741	(if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12742			  (const_int 1))
12743		      (label_ref (match_operand 0))
12744		      (pc)))
12745   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12746	(plus:P (match_dup 1)
12747		(const_int -1)))
12748   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12749   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12750  ""
12751{
12752  if (which_alternative != 0)
12753    return "#";
12754  else if (get_attr_length (insn) == 4)
12755    return "<bd> %l0";
12756  else
12757    return "<bd_neg> $+8\;b %l0";
12758}
12759  [(set_attr "type" "branch")
12760   (set_attr_alternative "length"
12761     [(if_then_else (and (ge (minus (match_dup 0) (pc))
12762			     (const_int -32768))
12763			 (lt (minus (match_dup 0) (pc))
12764			     (const_int 32764)))
12765		    (const_int 4)
12766		    (const_int 8))
12767      (const_string "16")
12768      (const_string "20")
12769      (const_string "20")])])
12770
12771;; Now the splitter if we could not allocate the CTR register
12772(define_split
12773  [(set (pc)
12774	(if_then_else (match_operator 2 "comparison_operator"
12775				      [(match_operand:P 1 "gpc_reg_operand")
12776				       (const_int 1)])
12777		      (match_operand 5)
12778		      (match_operand 6)))
12779   (set (match_operand:P 0 "nonimmediate_operand")
12780	(plus:P (match_dup 1)
12781		(const_int -1)))
12782   (clobber (match_scratch:CC 3))
12783   (clobber (match_scratch:P 4))]
12784  "reload_completed"
12785  [(set (pc)
12786	(if_then_else (match_dup 7)
12787		      (match_dup 5)
12788		      (match_dup 6)))]
12789{
12790  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12791				const0_rtx);
12792  emit_insn (gen_rtx_SET (operands[3],
12793			  gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12794  if (int_reg_operand (operands[0], <MODE>mode))
12795    emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12796  else
12797    {
12798      emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12799      emit_move_insn (operands[0], operands[4]);
12800    } 
12801    /* No DONE so branch comes from the pattern.  */
12802})
12803
12804;; patterns for bdnzt/bdnzf/bdzt/bdzf
12805;; Note that in the case of long branches we have to decompose this into
12806;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12807;; and the CR bit, which means there is no way to conveniently invert the
12808;; comparison as is done with plain bdnz/bdz.
12809
12810(define_insn "<bd>tf_<mode>"
12811  [(set (pc)
12812	(if_then_else
12813	  (and
12814	     (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12815		   (const_int 1))
12816	     (match_operator 3 "branch_comparison_operator"
12817		      [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12818		       (const_int 0)]))
12819	  (label_ref (match_operand 0))
12820	  (pc)))
12821   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12822	(plus:P (match_dup 1)
12823		(const_int -1)))
12824   (clobber (match_scratch:P 5 "=X,X,&r,r"))
12825   (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12826   (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12827  ""
12828{
12829  if (which_alternative != 0)
12830    return "#";
12831  else if (get_attr_length (insn) == 4)
12832    {
12833      if (branch_positive_comparison_operator (operands[3],
12834					       GET_MODE (operands[3])))
12835	return "<bd>t %j3,%l0";
12836      else
12837	return "<bd>f %j3,%l0";
12838    }
12839  else
12840    {
12841      static char seq[96];
12842      char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12843      sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12844      return seq;
12845    }
12846}
12847  [(set_attr "type" "branch")
12848   (set_attr_alternative "length"
12849     [(if_then_else (and (ge (minus (match_dup 0) (pc))
12850			     (const_int -32768))
12851			 (lt (minus (match_dup 0) (pc))
12852			     (const_int 32764)))
12853		    (const_int 4)
12854		    (const_int 8))
12855      (const_string "16")
12856      (const_string "20")
12857      (const_string "20")])])
12858
12859;; Now the splitter if we could not allocate the CTR register
12860(define_split
12861  [(set (pc)
12862	(if_then_else
12863	  (and
12864	     (match_operator 1 "comparison_operator"
12865			     [(match_operand:P 0 "gpc_reg_operand")
12866			      (const_int 1)])
12867	     (match_operator 3 "branch_comparison_operator"
12868		      [(match_operand 2 "cc_reg_operand")
12869		       (const_int 0)]))
12870	  (match_operand 4)
12871	  (match_operand 5)))
12872   (set (match_operand:P 6 "nonimmediate_operand")
12873	(plus:P (match_dup 0)
12874		(const_int -1)))
12875   (clobber (match_scratch:P 7))
12876   (clobber (match_scratch:CC 8))
12877   (clobber (match_scratch:CCEQ 9))]
12878  "reload_completed"
12879[(pc)]
12880{
12881  rtx ctr = operands[0];
12882  rtx ctrcmp = operands[1];
12883  rtx ccin = operands[2];
12884  rtx cccmp = operands[3];
12885  rtx dst1 = operands[4];
12886  rtx dst2 = operands[5];
12887  rtx ctrout = operands[6];
12888  rtx ctrtmp = operands[7];
12889  enum rtx_code cmpcode = GET_CODE (ctrcmp);
12890  bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12891  if (!ispos)
12892    cmpcode = reverse_condition (cmpcode);
12893  /* Generate crand/crandc here.  */
12894  emit_insn (gen_rtx_SET (operands[8],
12895			  gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12896  rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12897
12898  rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12899  if (ispos)
12900     emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
12901				      operands[8], cccmp, ccin));
12902  else
12903     emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12904						 operands[8], cccmp, ccin));
12905  if (int_reg_operand (ctrout, <MODE>mode))
12906     emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12907  else
12908    {
12909      emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12910      emit_move_insn (ctrout, ctrtmp);
12911    }
12912  rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12913  emit_jump_insn (gen_rtx_SET (pc_rtx,
12914			       gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12915						     dst1, dst2)));
12916  DONE;
12917})
12918
12919
12920(define_insn "trap"
12921  [(trap_if (const_int 1) (const_int 0))]
12922  ""
12923  "trap"
12924  [(set_attr "type" "trap")])
12925
12926(define_expand "ctrap<mode>4"
12927  [(trap_if (match_operator 0 "ordered_comparison_operator"
12928			    [(match_operand:GPR 1 "register_operand")
12929			     (match_operand:GPR 2 "reg_or_short_operand")])
12930	    (match_operand 3 "zero_constant" ""))]
12931  ""
12932  "")
12933
12934(define_insn ""
12935  [(trap_if (match_operator 0 "ordered_comparison_operator"
12936                            [(match_operand:GPR 1 "register_operand" "r")
12937                             (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12938	    (const_int 0))]
12939  ""
12940  "t<wd>%V0%I2 %1,%2"
12941  [(set_attr "type" "trap")])
12942
12943;; Insns related to generating the function prologue and epilogue.
12944
12945(define_expand "prologue"
12946  [(use (const_int 0))]
12947  ""
12948{
12949  rs6000_emit_prologue ();
12950  if (!TARGET_SCHED_PROLOG)
12951    emit_insn (gen_blockage ());
12952  DONE;
12953})
12954
12955(define_insn "*movesi_from_cr_one"
12956  [(match_parallel 0 "mfcr_operation"
12957		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12958			 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12959				     (match_operand 3 "immediate_operand" "n")]
12960			  UNSPEC_MOVESI_FROM_CR))])]
12961  "TARGET_MFCRF"
12962{
12963  int mask = 0;
12964  int i;
12965  for (i = 0; i < XVECLEN (operands[0], 0); i++)
12966  {
12967    mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12968    operands[4] = GEN_INT (mask);
12969    output_asm_insn ("mfcr %1,%4", operands);
12970  }
12971  return "";
12972}
12973  [(set_attr "type" "mfcrf")])
12974
12975;; Don't include the volatile CRs since their values are not used wrt CR save
12976;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12977;; prologue past an insn (early exit test) that defines a register used in the
12978;; prologue.
12979(define_insn "prologue_movesi_from_cr"
12980  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12981        (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12982		    (reg:CC CR4_REGNO)]
12983		   UNSPEC_MOVESI_FROM_CR))]
12984  ""
12985  "mfcr %0"
12986  [(set_attr "type" "mfcr")])
12987
12988(define_insn "*crsave"
12989  [(match_parallel 0 "crsave_operation"
12990		   [(set (match_operand:SI 1 "memory_operand" "=m")
12991			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12992  ""
12993  "stw %2,%1"
12994  [(set_attr "type" "store")])
12995
12996(define_insn "*stmw"
12997  [(match_parallel 0 "stmw_operation"
12998		   [(set (match_operand:SI 1 "memory_operand" "=m")
12999       			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13000  "TARGET_MULTIPLE"
13001  "stmw %2,%1"
13002  [(set_attr "type" "store")
13003   (set_attr "update" "yes")
13004   (set_attr "indexed" "yes")])
13005
13006; The following comment applies to:
13007;     save_gpregs_*
13008;     save_fpregs_*
13009;     restore_gpregs*
13010;     return_and_restore_gpregs*
13011;     return_and_restore_fpregs*
13012;     return_and_restore_fpregs_aix*
13013;
13014; The out-of-line save / restore functions expects one input argument.
13015; Since those are not standard call_insn's, we must avoid using
13016; MATCH_OPERAND for that argument. That way the register rename
13017; optimization will not try to rename this register.
13018; Each pattern is repeated for each possible register number used in 
13019; various ABIs (r11, r1, and for some functions r12)
13020
13021(define_insn "*save_gpregs_<mode>_r11"
13022  [(match_parallel 0 "any_parallel_operand"
13023		   [(clobber (reg:P LR_REGNO))
13024		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13025                    (use (reg:P 11))
13026		    (set (match_operand:P 2 "memory_operand" "=m")
13027			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13028  ""
13029  "bl %1"
13030  [(set_attr "type" "branch")])
13031
13032(define_insn "*save_gpregs_<mode>_r12"
13033  [(match_parallel 0 "any_parallel_operand"
13034		   [(clobber (reg:P LR_REGNO))
13035		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13036                    (use (reg:P 12))
13037		    (set (match_operand:P 2 "memory_operand" "=m")
13038			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13039  ""
13040  "bl %1"
13041  [(set_attr "type" "branch")])
13042
13043(define_insn "*save_gpregs_<mode>_r1"
13044  [(match_parallel 0 "any_parallel_operand"
13045		   [(clobber (reg:P LR_REGNO))
13046		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13047                    (use (reg:P 1))
13048		    (set (match_operand:P 2 "memory_operand" "=m")
13049			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13050  ""
13051  "bl %1"
13052  [(set_attr "type" "branch")])
13053
13054(define_insn "*save_fpregs_<mode>_r11"
13055  [(match_parallel 0 "any_parallel_operand"
13056		   [(clobber (reg:P LR_REGNO))
13057		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13058                    (use (reg:P 11))
13059		    (set (match_operand:DF 2 "memory_operand" "=m")
13060			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13061  ""
13062  "bl %1"
13063  [(set_attr "type" "branch")])
13064
13065(define_insn "*save_fpregs_<mode>_r12"
13066  [(match_parallel 0 "any_parallel_operand"
13067		   [(clobber (reg:P LR_REGNO))
13068		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13069                    (use (reg:P 12))
13070		    (set (match_operand:DF 2 "memory_operand" "=m")
13071			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13072  ""
13073  "bl %1"
13074  [(set_attr "type" "branch")])
13075
13076(define_insn "*save_fpregs_<mode>_r1"
13077  [(match_parallel 0 "any_parallel_operand"
13078		   [(clobber (reg:P LR_REGNO))
13079		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13080                    (use (reg:P 1))
13081		    (set (match_operand:DF 2 "memory_operand" "=m")
13082			 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13083  ""
13084  "bl %1"
13085  [(set_attr "type" "branch")])
13086
13087; This is to explain that changes to the stack pointer should
13088; not be moved over loads from or stores to stack memory.
13089(define_insn "stack_tie"
13090  [(match_parallel 0 "tie_operand"
13091		   [(set (mem:BLK (reg 1)) (const_int 0))])]
13092  ""
13093  ""
13094  [(set_attr "length" "0")])
13095
13096; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13097; stay behind all restores from the stack, it cannot be reordered to before
13098; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13099(define_insn "stack_restore_tie"
13100  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13101	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13102		 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13103   (set (mem:BLK (scratch)) (const_int 0))]
13104  "TARGET_32BIT"
13105  "@
13106   mr %0,%1
13107   add%I2 %0,%1,%2"
13108  [(set_attr "type" "*,add")])
13109
13110(define_expand "epilogue"
13111  [(use (const_int 0))]
13112  ""
13113{
13114  if (!TARGET_SCHED_PROLOG)
13115    emit_insn (gen_blockage ());
13116  rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13117  DONE;
13118})
13119
13120; On some processors, doing the mtcrf one CC register at a time is
13121; faster (like on the 604e).  On others, doing them all at once is
13122; faster; for instance, on the 601 and 750.
13123
13124(define_expand "movsi_to_cr_one"
13125  [(set (match_operand:CC 0 "cc_reg_operand")
13126        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13127		    (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13128  ""
13129  "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13130
13131(define_insn "*movsi_to_cr"
13132  [(match_parallel 0 "mtcrf_operation"
13133		   [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13134			 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13135				     (match_operand 3 "immediate_operand" "n")]
13136				    UNSPEC_MOVESI_TO_CR))])]
13137 ""
13138{
13139  int mask = 0;
13140  int i;
13141  for (i = 0; i < XVECLEN (operands[0], 0); i++)
13142    mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13143  operands[4] = GEN_INT (mask);
13144  return "mtcrf %4,%2";
13145}
13146  [(set_attr "type" "mtcr")])
13147
13148(define_insn "*mtcrfsi"
13149  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13150        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13151		    (match_operand 2 "immediate_operand" "n")]
13152		   UNSPEC_MOVESI_TO_CR))]
13153  "REG_P (operands[0])
13154   && CR_REGNO_P (REGNO (operands[0]))
13155   && CONST_INT_P (operands[2])
13156   && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13157  "mtcrf %R0,%1"
13158  [(set_attr "type" "mtcr")])
13159
13160; The load-multiple instructions have similar properties.
13161; Note that "load_multiple" is a name known to the machine-independent
13162; code that actually corresponds to the PowerPC load-string.
13163
13164(define_insn "*lmw"
13165  [(match_parallel 0 "lmw_operation"
13166		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13167       			 (match_operand:SI 2 "memory_operand" "m"))])]
13168  "TARGET_MULTIPLE"
13169  "lmw %1,%2"
13170  [(set_attr "type" "load")
13171   (set_attr "update" "yes")
13172   (set_attr "indexed" "yes")
13173   (set_attr "cell_micro" "always")])
13174
13175; FIXME: "any_parallel_operand" is a bit flexible...
13176
13177; The following comment applies to:
13178;     save_gpregs_*
13179;     save_fpregs_*
13180;     restore_gpregs*
13181;     return_and_restore_gpregs*
13182;     return_and_restore_fpregs*
13183;     return_and_restore_fpregs_aix*
13184;
13185; The out-of-line save / restore functions expects one input argument.
13186; Since those are not standard call_insn's, we must avoid using
13187; MATCH_OPERAND for that argument. That way the register rename
13188; optimization will not try to rename this register.
13189; Each pattern is repeated for each possible register number used in 
13190; various ABIs (r11, r1, and for some functions r12)
13191
13192(define_insn "*restore_gpregs_<mode>_r11"
13193 [(match_parallel 0 "any_parallel_operand"
13194		  [(clobber (reg:P LR_REGNO))
13195		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13196		   (use (reg:P 11))
13197		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13198			(match_operand:P 3 "memory_operand" "m"))])]
13199 ""
13200 "bl %1"
13201 [(set_attr "type" "branch")])
13202
13203(define_insn "*restore_gpregs_<mode>_r12"
13204 [(match_parallel 0 "any_parallel_operand"
13205		  [(clobber (reg:P LR_REGNO))
13206		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13207		   (use (reg:P 12))
13208		   (set (match_operand:P 2 "gpc_reg_operand" "=r")
13209			(match_operand:P 3 "memory_operand" "m"))])]
13210 ""
13211 "bl %1"
13212 [(set_attr "type" "branch")])
13213
13214(define_insn "*restore_gpregs_<mode>_r1"
13215 [(match_parallel 0 "any_parallel_operand"
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 "bl %1"
13223 [(set_attr "type" "branch")])
13224
13225(define_insn "*return_and_restore_gpregs_<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:P 2 "gpc_reg_operand" "=r")
13232			(match_operand:P 3 "memory_operand" "m"))])]
13233 ""
13234 "b %1"
13235 [(set_attr "type" "branch")])
13236
13237(define_insn "*return_and_restore_gpregs_<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:P 2 "gpc_reg_operand" "=r")
13244			(match_operand:P 3 "memory_operand" "m"))])]
13245 ""
13246 "b %1"
13247 [(set_attr "type" "branch")])
13248
13249(define_insn "*return_and_restore_gpregs_<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:P 2 "gpc_reg_operand" "=r")
13256			(match_operand:P 3 "memory_operand" "m"))])]
13257 ""
13258 "b %1"
13259 [(set_attr "type" "branch")])
13260
13261(define_insn "*return_and_restore_fpregs_<mode>_r11"
13262 [(match_parallel 0 "any_parallel_operand"
13263		  [(return)
13264		   (clobber (reg:P LR_REGNO))
13265		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13266		   (use (reg:P 11))
13267		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13268			(match_operand:DF 3 "memory_operand" "m"))])]
13269 ""
13270 "b %1"
13271 [(set_attr "type" "branch")])
13272
13273(define_insn "*return_and_restore_fpregs_<mode>_r12"
13274 [(match_parallel 0 "any_parallel_operand"
13275		  [(return)
13276		   (clobber (reg:P LR_REGNO))
13277		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13278		   (use (reg:P 12))
13279		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13280			(match_operand:DF 3 "memory_operand" "m"))])]
13281 ""
13282 "b %1"
13283 [(set_attr "type" "branch")])
13284
13285(define_insn "*return_and_restore_fpregs_<mode>_r1"
13286 [(match_parallel 0 "any_parallel_operand"
13287		  [(return)
13288		   (clobber (reg:P LR_REGNO))
13289		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13290		   (use (reg:P 1))
13291		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13292			(match_operand:DF 3 "memory_operand" "m"))])]
13293 ""
13294 "b %1"
13295 [(set_attr "type" "branch")])
13296
13297(define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13298 [(match_parallel 0 "any_parallel_operand"
13299		  [(return)
13300		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13301		   (use (reg:P 11))
13302		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13303			(match_operand:DF 3 "memory_operand" "m"))])]
13304 ""
13305 "b %1"
13306 [(set_attr "type" "branch")])
13307
13308(define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13309 [(match_parallel 0 "any_parallel_operand"
13310		  [(return)
13311		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
13312		   (use (reg:P 1))
13313		   (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13314			(match_operand:DF 3 "memory_operand" "m"))])]
13315 ""
13316 "b %1"
13317 [(set_attr "type" "branch")])
13318
13319; This is used in compiling the unwind routines.
13320(define_expand "eh_return"
13321  [(use (match_operand 0 "general_operand"))]
13322  ""
13323{
13324  emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13325  DONE;
13326})
13327
13328; We can't expand this before we know where the link register is stored.
13329(define_insn_and_split "@eh_set_lr_<mode>"
13330  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13331   (clobber (match_scratch:P 1 "=&b"))]
13332  ""
13333  "#"
13334  "reload_completed"
13335  [(const_int 0)]
13336{
13337  rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13338  DONE;
13339})
13340
13341(define_insn "prefetch"
13342  [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13343	     (match_operand:SI 1 "const_int_operand" "n")
13344	     (match_operand:SI 2 "const_int_operand" "n"))]
13345  ""
13346{
13347
13348
13349  /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13350     AIX does not support the dcbtstt and dcbtt extended mnemonics.
13351     The AIX assembler does not support the three operand form of dcbt
13352     and dcbtst on Power 7 (-mpwr7).  */
13353  int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13354
13355  if (REG_P (operands[0]))
13356    {
13357      if (INTVAL (operands[1]) == 0)
13358        return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13359      else
13360        return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13361    }
13362  else
13363    {
13364      if (INTVAL (operands[1]) == 0)
13365        return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13366      else
13367        return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13368    }
13369}
13370  [(set_attr "type" "load")])
13371
13372;; Handle -fsplit-stack.
13373
13374(define_expand "split_stack_prologue"
13375  [(const_int 0)]
13376  ""
13377{
13378  rs6000_expand_split_stack_prologue ();
13379  DONE;
13380})
13381
13382(define_expand "load_split_stack_limit"
13383  [(set (match_operand 0)
13384	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13385  ""
13386{
13387  emit_insn (gen_rtx_SET (operands[0],
13388			  gen_rtx_UNSPEC (Pmode,
13389					  gen_rtvec (1, const0_rtx),
13390					  UNSPEC_STACK_CHECK)));
13391  DONE;
13392})
13393
13394(define_insn "load_split_stack_limit_di"
13395  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13396	(unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13397  "TARGET_64BIT"
13398  "ld %0,-0x7040(13)"
13399  [(set_attr "type" "load")
13400   (set_attr "update" "no")
13401   (set_attr "indexed" "no")])
13402
13403(define_insn "load_split_stack_limit_si"
13404  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13405	(unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13406  "!TARGET_64BIT"
13407  "lwz %0,-0x7020(2)"
13408  [(set_attr "type" "load")
13409   (set_attr "update" "no")
13410   (set_attr "indexed" "no")])
13411
13412;; A return instruction which the middle-end doesn't see.
13413;; Use r0 to stop regrename twiddling with lr restore insns emitted
13414;; after the call to __morestack.
13415(define_insn "split_stack_return"
13416  [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13417  ""
13418  "blr"
13419  [(set_attr "type" "jmpreg")])
13420
13421;; If there are operand 0 bytes available on the stack, jump to
13422;; operand 1.
13423(define_expand "split_stack_space_check"
13424  [(set (match_dup 2)
13425	(unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13426   (set (match_dup 3)
13427	(minus (reg STACK_POINTER_REGNUM)
13428	       (match_operand 0)))
13429   (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13430   (set (pc) (if_then_else
13431	      (geu (match_dup 4) (const_int 0))
13432	      (label_ref (match_operand 1))
13433	      (pc)))]
13434  ""
13435{
13436  rs6000_split_stack_space_check (operands[0], operands[1]);
13437  DONE;
13438})
13439
13440(define_insn "bpermd_<mode>"
13441  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13442	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13443		   (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13444  "TARGET_POPCNTD"
13445  "bpermd %0,%1,%2"
13446  [(set_attr "type" "popcnt")])
13447
13448
13449;; Builtin fma support.  Handle 
13450;; Note that the conditions for expansion are in the FMA_F iterator.
13451
13452(define_expand "fma<mode>4"
13453  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13454	(fma:FMA_F
13455	  (match_operand:FMA_F 1 "gpc_reg_operand")
13456	  (match_operand:FMA_F 2 "gpc_reg_operand")
13457	  (match_operand:FMA_F 3 "gpc_reg_operand")))]
13458  ""
13459  "")
13460
13461(define_insn "*fma<mode>4_fpr"
13462  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13463	(fma:SFDF
13464	  (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13465	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13466	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13467  "TARGET_HARD_FLOAT"
13468  "@
13469   fmadd<s> %0,%1,%2,%3
13470   xsmadda<sd>p %x0,%x1,%x2
13471   xsmaddm<sd>p %x0,%x1,%x3"
13472  [(set_attr "type" "fp")
13473   (set_attr "isa" "*,<Fisa>,<Fisa>")])
13474
13475; Altivec only has fma and nfms.
13476(define_expand "fms<mode>4"
13477  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13478	(fma:FMA_F
13479	  (match_operand:FMA_F 1 "gpc_reg_operand")
13480	  (match_operand:FMA_F 2 "gpc_reg_operand")
13481	  (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13482  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13483  "")
13484
13485(define_insn "*fms<mode>4_fpr"
13486  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13487	(fma:SFDF
13488	 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13489	 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13490	 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13491  "TARGET_HARD_FLOAT"
13492  "@
13493   fmsub<s> %0,%1,%2,%3
13494   xsmsuba<sd>p %x0,%x1,%x2
13495   xsmsubm<sd>p %x0,%x1,%x3"
13496  [(set_attr "type" "fp")
13497   (set_attr "isa" "*,<Fisa>,<Fisa>")])
13498
13499;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13500(define_expand "fnma<mode>4"
13501  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13502	(neg:FMA_F
13503	  (fma:FMA_F
13504	    (match_operand:FMA_F 1 "gpc_reg_operand")
13505	    (match_operand:FMA_F 2 "gpc_reg_operand")
13506	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13507  "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13508  "")
13509
13510;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13511(define_expand "fnms<mode>4"
13512  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13513	(neg:FMA_F
13514	  (fma:FMA_F
13515	    (match_operand:FMA_F 1 "gpc_reg_operand")
13516	    (match_operand:FMA_F 2 "gpc_reg_operand")
13517	    (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13518  "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13519  "")
13520
13521; Not an official optab name, but used from builtins.
13522(define_expand "nfma<mode>4"
13523  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13524	(neg:FMA_F
13525	  (fma:FMA_F
13526	    (match_operand:FMA_F 1 "gpc_reg_operand")
13527	    (match_operand:FMA_F 2 "gpc_reg_operand")
13528	    (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13529  "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13530  "")
13531
13532(define_insn "*nfma<mode>4_fpr"
13533  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13534	(neg:SFDF
13535	 (fma:SFDF
13536	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13537	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13538	  (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13539  "TARGET_HARD_FLOAT"
13540  "@
13541   fnmadd<s> %0,%1,%2,%3
13542   xsnmadda<sd>p %x0,%x1,%x2
13543   xsnmaddm<sd>p %x0,%x1,%x3"
13544  [(set_attr "type" "fp")
13545   (set_attr "isa" "*,<Fisa>,<Fisa>")])
13546
13547; Not an official optab name, but used from builtins.
13548(define_expand "nfms<mode>4"
13549  [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13550	(neg:FMA_F
13551	  (fma:FMA_F
13552	    (match_operand:FMA_F 1 "gpc_reg_operand")
13553	    (match_operand:FMA_F 2 "gpc_reg_operand")
13554	    (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13555  ""
13556  "")
13557
13558(define_insn "*nfmssf4_fpr"
13559  [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13560	(neg:SFDF
13561	 (fma:SFDF
13562	  (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13563	  (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13564	  (neg:SFDF
13565	   (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13566  "TARGET_HARD_FLOAT"
13567  "@
13568   fnmsub<s> %0,%1,%2,%3
13569   xsnmsuba<sd>p %x0,%x1,%x2
13570   xsnmsubm<sd>p %x0,%x1,%x3"
13571  [(set_attr "type" "fp")
13572   (set_attr "isa" "*,<Fisa>,<Fisa>")])
13573
13574(define_expand "rs6000_get_timebase"
13575  [(use (match_operand:DI 0 "gpc_reg_operand"))]
13576  ""
13577{
13578  if (TARGET_POWERPC64)
13579    emit_insn (gen_rs6000_mftb_di (operands[0]));
13580  else
13581    emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13582  DONE;
13583})
13584
13585(define_insn "rs6000_get_timebase_ppc32"
13586  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13587        (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13588   (clobber (match_scratch:SI 1 "=r"))
13589   (clobber (match_scratch:CC 2 "=y"))]
13590  "!TARGET_POWERPC64"
13591{
13592  if (WORDS_BIG_ENDIAN)
13593    if (TARGET_MFCRF)
13594      {
13595        return "mfspr %0,269\;"
13596	       "mfspr %L0,268\;"
13597	       "mfspr %1,269\;"
13598	       "cmpw %2,%0,%1\;"
13599	       "bne- %2,$-16";
13600      }
13601    else
13602      {
13603        return "mftbu %0\;"
13604	       "mftb %L0\;"
13605	       "mftbu %1\;"
13606	       "cmpw %2,%0,%1\;"
13607	       "bne- %2,$-16";
13608      }
13609  else
13610    if (TARGET_MFCRF)
13611      {
13612        return "mfspr %L0,269\;"
13613	       "mfspr %0,268\;"
13614	       "mfspr %1,269\;"
13615	       "cmpw %2,%L0,%1\;"
13616	       "bne- %2,$-16";
13617      }
13618    else
13619      {
13620        return "mftbu %L0\;"
13621	       "mftb %0\;"
13622	       "mftbu %1\;"
13623	       "cmpw %2,%L0,%1\;"
13624	       "bne- %2,$-16";
13625      }
13626}
13627  [(set_attr "length" "20")])
13628
13629(define_insn "rs6000_mftb_<mode>"
13630  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13631        (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13632  ""
13633{
13634  if (TARGET_MFCRF)
13635    return "mfspr %0,268";
13636  else
13637    return "mftb %0";
13638})
13639
13640
13641;; The ISA 3.0 mffsl instruction is a lower latency instruction
13642;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13643(define_insn "rs6000_mffsl_hw"
13644  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13645        (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13646  "TARGET_HARD_FLOAT"
13647  "mffsl %0")
13648
13649(define_expand "rs6000_mffsl"
13650  [(set (match_operand:DF 0 "gpc_reg_operand")
13651	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13652  "TARGET_HARD_FLOAT"
13653{
13654  /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13655     otherwise fall back to the older mffs instruction to emulate the mffsl
13656     instruction.  */
13657
13658  if (!TARGET_P9_MISC)
13659    {
13660      rtx tmp1 = gen_reg_rtx (DFmode);
13661
13662      /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13663	 instruction using the mffs instruction and masking the result.  */
13664      emit_insn (gen_rs6000_mffs (tmp1));
13665
13666      rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
13667      rtx tmp2 = gen_reg_rtx (DImode);
13668      emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
13669
13670      rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
13671      emit_move_insn (operands[0], tmp2df);
13672      DONE;
13673    }
13674
13675    emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13676    DONE;
13677})
13678
13679(define_insn "rs6000_mffs"
13680  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13681	(unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13682  "TARGET_HARD_FLOAT"
13683  "mffs %0")
13684
13685(define_insn "rs6000_mtfsf"
13686  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13687		     (match_operand:DF 1 "gpc_reg_operand" "d")]
13688		    UNSPECV_MTFSF)]
13689  "TARGET_HARD_FLOAT"
13690  "mtfsf %0,%1")
13691
13692(define_insn "rs6000_mtfsf_hi"
13693  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13694		     (match_operand:DF 1 "gpc_reg_operand" "d")]
13695		    UNSPECV_MTFSF_HI)]
13696  "TARGET_HARD_FLOAT"
13697  "mtfsf %0,%1,0,1")
13698
13699
13700;; Power8 fusion support for fusing an addis instruction with a D-form load of
13701;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13702;; register that is being loaded.  The fused ops must be physically adjacent.
13703
13704;; On Power8 GPR loads, we try to use the register that is being load.  The
13705;; peephole2 then gathers any other fused possibilities that it can find after
13706;; register allocation.  If power9 fusion is selected, we also fuse floating
13707;; point loads/stores.
13708
13709;; Find cases where the addis that feeds into a load instruction is either used
13710;; once or is the same as the target register, and replace it with the fusion
13711;; insn
13712
13713(define_peephole2
13714  [(set (match_operand:P 0 "base_reg_operand")
13715	(match_operand:P 1 "fusion_gpr_addis"))
13716   (set (match_operand:INT1 2 "base_reg_operand")
13717	(match_operand:INT1 3 "fusion_gpr_mem_load"))]
13718  "TARGET_P8_FUSION
13719   && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13720			 operands[3])"
13721  [(const_int 0)]
13722{
13723  expand_fusion_gpr_load (operands);
13724  DONE;
13725})
13726
13727;; Fusion insn, created by the define_peephole2 above (and eventually by
13728;; reload)
13729
13730(define_insn "*fusion_gpr_load_<mode>"
13731  [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13732	(unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13733		     UNSPEC_FUSION_GPR))]
13734  "TARGET_P8_FUSION"
13735{
13736  return emit_fusion_gpr_load (operands[0], operands[1]);
13737}
13738  [(set_attr "type" "load")
13739   (set_attr "length" "8")])
13740
13741
13742;; Optimize cases where we want to do a D-form load (register+offset) on
13743;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13744;; has generated:
13745;;	LFD 0,32(3)
13746;;	XXLOR 32,0,0
13747;;
13748;; and we change this to:
13749;;	LI 0,32
13750;;	LXSDX 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 "simple_offsettable_mem_operand"))
13756   (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_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 3)
13762	(match_dup 5))]
13763{
13764  rtx tmp_reg = operands[0];
13765  rtx mem = operands[2];
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;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13780;; Altivec register, and the register allocator has generated:
13781;;	XXLOR 0,32,32
13782;;	STFD 0,32(3)
13783;;
13784;; and we change this to:
13785;;	LI 0,32
13786;;	STXSDX 32,3,9
13787
13788(define_peephole2
13789  [(match_scratch:P 0 "b")
13790   (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13791	(match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13792   (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13793	(match_dup 1))]
13794  "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13795  [(set (match_dup 0)
13796	(match_dup 4))
13797   (set (match_dup 5)
13798	(match_dup 2))]
13799{
13800  rtx tmp_reg = operands[0];
13801  rtx mem = operands[3];
13802  rtx addr = XEXP (mem, 0);
13803  rtx add_op0, add_op1, new_addr;
13804
13805  gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13806  add_op0 = XEXP (addr, 0);
13807  add_op1 = XEXP (addr, 1);
13808  gcc_assert (REG_P (add_op0));
13809  new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13810
13811  operands[4] = add_op1;
13812  operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13813})
13814   
13815
13816;; Miscellaneous ISA 2.06 (power7) instructions
13817(define_insn "addg6s"
13818  [(set (match_operand:SI 0 "register_operand" "=r")
13819	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
13820		    (match_operand:SI 2 "register_operand" "r")]
13821		   UNSPEC_ADDG6S))]
13822  "TARGET_POPCNTD"
13823  "addg6s %0,%1,%2"
13824  [(set_attr "type" "integer")])
13825
13826(define_insn "cdtbcd"
13827  [(set (match_operand:SI 0 "register_operand" "=r")
13828	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13829		   UNSPEC_CDTBCD))]
13830  "TARGET_POPCNTD"
13831  "cdtbcd %0,%1"
13832  [(set_attr "type" "integer")])
13833
13834(define_insn "cbcdtd"
13835  [(set (match_operand:SI 0 "register_operand" "=r")
13836	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13837		   UNSPEC_CBCDTD))]
13838  "TARGET_POPCNTD"
13839  "cbcdtd %0,%1"
13840  [(set_attr "type" "integer")])
13841
13842(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13843					UNSPEC_DIVEU])
13844
13845(define_int_attr div_extend [(UNSPEC_DIVE	"e")
13846			     (UNSPEC_DIVEU	"eu")])
13847
13848(define_insn "div<div_extend>_<mode>"
13849  [(set (match_operand:GPR 0 "register_operand" "=r")
13850	(unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13851		     (match_operand:GPR 2 "register_operand" "r")]
13852		    UNSPEC_DIV_EXTEND))]
13853  "TARGET_POPCNTD"
13854  "div<wd><div_extend> %0,%1,%2"
13855  [(set_attr "type" "div")
13856   (set_attr "size" "<bits>")])
13857
13858
13859;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13860
13861; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13862(define_mode_attr FP128_64 [(TF "DF")
13863			    (IF "DF")
13864			    (TD "DI")
13865			    (KF "DI")])
13866
13867(define_expand "unpack<mode>"
13868  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13869	(unspec:<FP128_64>
13870	 [(match_operand:FMOVE128 1 "register_operand")
13871	  (match_operand:QI 2 "const_0_to_1_operand")]
13872	 UNSPEC_UNPACK_128BIT))]
13873  "FLOAT128_2REG_P (<MODE>mode)"
13874  "")
13875
13876(define_insn_and_split "unpack<mode>_dm"
13877  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13878	(unspec:<FP128_64>
13879	 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13880	  (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13881	 UNSPEC_UNPACK_128BIT))]
13882  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13883  "#"
13884  "&& reload_completed"
13885  [(set (match_dup 0) (match_dup 3))]
13886{
13887  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13888
13889  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13890    {
13891      emit_note (NOTE_INSN_DELETED);
13892      DONE;
13893    }
13894
13895  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13896}
13897  [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13898
13899(define_insn_and_split "unpack<mode>_nodm"
13900  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13901	(unspec:<FP128_64>
13902	 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13903	  (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13904	 UNSPEC_UNPACK_128BIT))]
13905  "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13906  "#"
13907  "&& reload_completed"
13908  [(set (match_dup 0) (match_dup 3))]
13909{
13910  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13911
13912  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13913    {
13914      emit_note (NOTE_INSN_DELETED);
13915      DONE;
13916    }
13917
13918  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13919}
13920  [(set_attr "type" "fp,fpstore")])
13921
13922(define_insn_and_split "pack<mode>"
13923  [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13924	(unspec:FMOVE128
13925	 [(match_operand:<FP128_64> 1 "register_operand" "d")
13926	  (match_operand:<FP128_64> 2 "register_operand" "d")]
13927	 UNSPEC_PACK_128BIT))]
13928  "FLOAT128_2REG_P (<MODE>mode)"
13929  "#"
13930  "&& reload_completed"
13931  [(set (match_dup 3) (match_dup 1))
13932   (set (match_dup 4) (match_dup 2))]
13933{
13934  unsigned dest_hi = REGNO (operands[0]);
13935  unsigned dest_lo = dest_hi + 1;
13936
13937  gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13938  gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13939
13940  operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13941  operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13942}
13943  [(set_attr "type" "fp")
13944   (set_attr "length" "8")])
13945
13946(define_insn "unpack<mode>"
13947  [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13948	(unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13949		    (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13950	 UNSPEC_UNPACK_128BIT))]
13951  "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13952{
13953  if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13954    return ASM_COMMENT_START " xxpermdi to same register";
13955
13956  operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13957  return "xxpermdi %x0,%x1,%x1,%3";
13958}
13959  [(set_attr "type" "vecperm")])
13960
13961(define_insn "pack<mode>"
13962  [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13963	(unspec:FMOVE128_VSX
13964	 [(match_operand:DI 1 "register_operand" "wa")
13965	  (match_operand:DI 2 "register_operand" "wa")]
13966	 UNSPEC_PACK_128BIT))]
13967  "TARGET_VSX"
13968  "xxpermdi %x0,%x1,%x2,0"
13969  [(set_attr "type" "vecperm")])
13970
13971
13972
13973;; ISA 2.08 IEEE 128-bit floating point support.
13974
13975(define_insn "add<mode>3"
13976  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13977	(plus:IEEE128
13978	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13979	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13980  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13981  "xsaddqp %0,%1,%2"
13982  [(set_attr "type" "vecfloat")
13983   (set_attr "size" "128")])
13984
13985(define_insn "sub<mode>3"
13986  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13987	(minus:IEEE128
13988	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13989	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13990  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13991  "xssubqp %0,%1,%2"
13992  [(set_attr "type" "vecfloat")
13993   (set_attr "size" "128")])
13994
13995(define_insn "mul<mode>3"
13996  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13997	(mult:IEEE128
13998	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13999	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14000  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14001  "xsmulqp %0,%1,%2"
14002  [(set_attr "type" "qmul")
14003   (set_attr "size" "128")])
14004
14005(define_insn "div<mode>3"
14006  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14007	(div:IEEE128
14008	 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14009	 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14010  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14011  "xsdivqp %0,%1,%2"
14012  [(set_attr "type" "vecdiv")
14013   (set_attr "size" "128")])
14014
14015(define_insn "sqrt<mode>2"
14016  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14017	(sqrt:IEEE128
14018	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14019  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14020   "xssqrtqp %0,%1"
14021  [(set_attr "type" "vecdiv")
14022   (set_attr "size" "128")])
14023
14024(define_expand "copysign<mode>3"
14025  [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14026   (use (match_operand:IEEE128 1 "altivec_register_operand"))
14027   (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14028  "FLOAT128_IEEE_P (<MODE>mode)"
14029{
14030  if (TARGET_FLOAT128_HW)
14031    emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14032					 operands[2]));
14033  else
14034    emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14035					 operands[2]));
14036  DONE;
14037})
14038
14039(define_insn "copysign<mode>3_hard"
14040  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14041	(unspec:IEEE128
14042	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14043	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14044	 UNSPEC_COPYSIGN))]
14045  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14046   "xscpsgnqp %0,%2,%1"
14047  [(set_attr "type" "vecmove")
14048   (set_attr "size" "128")])
14049
14050(define_insn "copysign<mode>3_soft"
14051  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14052	(unspec:IEEE128
14053	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14054	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14055	 UNSPEC_COPYSIGN))
14056   (clobber (match_scratch:IEEE128 3 "=&v"))]
14057  "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14058   "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14059  [(set_attr "type" "veccomplex")
14060   (set_attr "length" "8")])
14061
14062(define_insn "@neg<mode>2_hw"
14063  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14064	(neg:IEEE128
14065	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14066  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14067  "xsnegqp %0,%1"
14068  [(set_attr "type" "vecmove")
14069   (set_attr "size" "128")])
14070
14071
14072(define_insn "@abs<mode>2_hw"
14073  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14074	(abs:IEEE128
14075	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14076  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14077  "xsabsqp %0,%1"
14078  [(set_attr "type" "vecmove")
14079   (set_attr "size" "128")])
14080
14081
14082(define_insn "*nabs<mode>2_hw"
14083  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14084	(neg:IEEE128
14085	 (abs:IEEE128
14086	  (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14087  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14088  "xsnabsqp %0,%1"
14089  [(set_attr "type" "vecmove")
14090   (set_attr "size" "128")])
14091
14092;; Initially don't worry about doing fusion
14093(define_insn "fma<mode>4_hw"
14094  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14095	(fma:IEEE128
14096	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14097	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14098	 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14099  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14100  "xsmaddqp %0,%1,%2"
14101  [(set_attr "type" "qmul")
14102   (set_attr "size" "128")])
14103
14104(define_insn "*fms<mode>4_hw"
14105  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14106	(fma:IEEE128
14107	 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14108	 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14109	 (neg:IEEE128
14110	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14111  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14112  "xsmsubqp %0,%1,%2"
14113  [(set_attr "type" "qmul")
14114   (set_attr "size" "128")])
14115
14116(define_insn "*nfma<mode>4_hw"
14117  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14118	(neg:IEEE128
14119	 (fma:IEEE128
14120	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14121	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14122	  (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14123  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14124  "xsnmaddqp %0,%1,%2"
14125  [(set_attr "type" "qmul")
14126   (set_attr "size" "128")])
14127
14128(define_insn "*nfms<mode>4_hw"
14129  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14130	(neg:IEEE128
14131	 (fma:IEEE128
14132	  (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14133	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14134	  (neg:IEEE128
14135	   (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14136  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14137  "xsnmsubqp %0,%1,%2"
14138  [(set_attr "type" "qmul")
14139   (set_attr "size" "128")])
14140
14141(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14142  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14143	(float_extend:IEEE128
14144	 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14145  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14146  "xscvdpqp %0,%1"
14147  [(set_attr "type" "vecfloat")
14148   (set_attr "size" "128")])
14149
14150;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14151;; point is a simple copy.
14152(define_insn_and_split "extendkftf2"
14153  [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14154	(float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14155  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14156  "@
14157   #
14158   xxlor %x0,%x1,%x1"
14159  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14160  [(const_int 0)]
14161{
14162  emit_note (NOTE_INSN_DELETED);
14163  DONE;
14164}
14165  [(set_attr "type" "*,veclogical")
14166   (set_attr "length" "0,4")])
14167
14168(define_insn_and_split "trunctfkf2"
14169  [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14170	(float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14171  "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14172  "@
14173   #
14174   xxlor %x0,%x1,%x1"
14175  "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14176  [(const_int 0)]
14177{
14178  emit_note (NOTE_INSN_DELETED);
14179  DONE;
14180}
14181  [(set_attr "type" "*,veclogical")
14182   (set_attr "length" "0,4")])
14183
14184(define_insn "trunc<mode>df2_hw"
14185  [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14186	(float_truncate:DF
14187	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14188  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14189  "xscvqpdp %0,%1"
14190  [(set_attr "type" "vecfloat")
14191   (set_attr "size" "128")])
14192
14193;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14194;; the KFmode -> DFmode conversion using round to odd rather than the normal
14195;; conversion
14196(define_insn_and_split "trunc<mode>sf2_hw"
14197  [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14198	(float_truncate:SF
14199	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14200   (clobber (match_scratch:DF 2 "=v"))]
14201  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14202  "#"
14203  "&& 1"
14204  [(set (match_dup 2)
14205	(unspec:DF [(match_dup 1)]
14206		   UNSPEC_TRUNC_ROUND_TO_ODD))
14207   (set (match_dup 0)
14208	(float_truncate:SF (match_dup 2)))]
14209{
14210  if (GET_CODE (operands[2]) == SCRATCH)
14211    operands[2] = gen_reg_rtx (DFmode);
14212}
14213  [(set_attr "type" "vecfloat")
14214   (set_attr "length" "8")
14215   (set_attr "isa" "p8v")])
14216
14217;; Conversion between IEEE 128-bit and integer types
14218
14219;; The fix function for DImode and SImode was declared earlier as a
14220;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14221;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14222;; unless we have the IEEE 128-bit hardware.
14223;;
14224;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14225;; to provide a GPR target that used direct move and a conversion in the GPR
14226;; which works around QImode/HImode not being allowed in vector registers in
14227;; ISA 2.07 (power8).
14228(define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14229  [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14230	(any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14231  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14232  "xscvqp<su><wd>z %0,%1"
14233  [(set_attr "type" "vecfloat")
14234   (set_attr "size" "128")])
14235
14236(define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14237  [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14238	(any_fix:QHI
14239	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14240  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14241  "xscvqp<su>wz %0,%1"
14242  [(set_attr "type" "vecfloat")
14243   (set_attr "size" "128")])
14244
14245;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14246;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14247(define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14248  [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14249	(any_fix:QHSI
14250	 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14251   (clobber (match_scratch:QHSI 2 "=v"))]
14252  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14253  "#"
14254  "&& reload_completed"
14255  [(set (match_dup 2)
14256	(any_fix:QHSI (match_dup 1)))
14257   (set (match_dup 0)
14258	(match_dup 2))])
14259
14260(define_insn "float_<mode>di2_hw"
14261  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14262	(float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14263  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14264  "xscvsdqp %0,%1"
14265  [(set_attr "type" "vecfloat")
14266   (set_attr "size" "128")])
14267
14268(define_insn_and_split "float_<mode>si2_hw"
14269  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14270	(float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14271   (clobber (match_scratch:DI 2 "=v"))]
14272  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14273  "#"
14274  "&& 1"
14275  [(set (match_dup 2)
14276	(sign_extend:DI (match_dup 1)))
14277   (set (match_dup 0)
14278	(float:IEEE128 (match_dup 2)))]
14279{
14280  if (GET_CODE (operands[2]) == SCRATCH)
14281    operands[2] = gen_reg_rtx (DImode);
14282
14283  if (MEM_P (operands[1]))
14284    operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14285})
14286
14287(define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14288  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14289	(float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14290   (clobber (match_scratch:DI 2 "=X,r,X"))]
14291  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14292  "#"
14293  "&& reload_completed"
14294  [(const_int 0)]
14295{
14296  rtx dest = operands[0];
14297  rtx src = operands[1];
14298  rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14299
14300  if (altivec_register_operand (src, <QHI:MODE>mode))
14301    emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14302  else if (int_reg_operand (src, <QHI:MODE>mode))
14303    {
14304      rtx ext_di = operands[2];
14305      emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14306      emit_move_insn (dest_di, ext_di);
14307    }
14308  else if (MEM_P (src))
14309    {
14310      rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14311      emit_move_insn (dest_qhi, src);
14312      emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14313    }
14314  else
14315    gcc_unreachable ();
14316
14317  emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14318  DONE;
14319}
14320  [(set_attr "length" "8,12,12")
14321   (set_attr "type" "vecfloat")
14322   (set_attr "size" "128")])
14323
14324(define_insn "floatuns_<mode>di2_hw"
14325  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14326	(unsigned_float:IEEE128
14327	 (match_operand:DI 1 "altivec_register_operand" "v")))]
14328  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14329  "xscvudqp %0,%1"
14330  [(set_attr "type" "vecfloat")
14331   (set_attr "size" "128")])
14332
14333(define_insn_and_split "floatuns_<mode>si2_hw"
14334  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14335	(unsigned_float:IEEE128
14336	 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14337   (clobber (match_scratch:DI 2 "=v"))]
14338  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14339  "#"
14340  "&& 1"
14341  [(set (match_dup 2)
14342	(zero_extend:DI (match_dup 1)))
14343   (set (match_dup 0)
14344	(float:IEEE128 (match_dup 2)))]
14345{
14346  if (GET_CODE (operands[2]) == SCRATCH)
14347    operands[2] = gen_reg_rtx (DImode);
14348
14349  if (MEM_P (operands[1]))
14350    operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14351})
14352
14353(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14354  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14355	(unsigned_float:IEEE128
14356	 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14357   (clobber (match_scratch:DI 2 "=X,r,X"))]
14358  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14359  "#"
14360  "&& reload_completed"
14361  [(const_int 0)]
14362{
14363  rtx dest = operands[0];
14364  rtx src = operands[1];
14365  rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14366
14367  if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14368    emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14369  else if (int_reg_operand (src, <QHI:MODE>mode))
14370    {
14371      rtx ext_di = operands[2];
14372      emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14373      emit_move_insn (dest_di, ext_di);
14374    }
14375  else
14376    gcc_unreachable ();
14377
14378  emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14379  DONE;
14380}
14381  [(set_attr "length" "8,12,8")
14382   (set_attr "type" "vecfloat")
14383   (set_attr "size" "128")])
14384
14385;; IEEE 128-bit round to integer built-in functions
14386(define_insn "floor<mode>2"
14387  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14388	(unspec:IEEE128
14389	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14390	 UNSPEC_FRIM))]
14391  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14392  "xsrqpi 1,%0,%1,3"
14393  [(set_attr "type" "vecfloat")
14394   (set_attr "size" "128")])
14395
14396(define_insn "ceil<mode>2"
14397  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14398	(unspec:IEEE128
14399	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14400	 UNSPEC_FRIP))]
14401  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14402  "xsrqpi 1,%0,%1,2"
14403  [(set_attr "type" "vecfloat")
14404   (set_attr "size" "128")])
14405
14406(define_insn "btrunc<mode>2"
14407  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14408	(unspec:IEEE128
14409	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14410	 UNSPEC_FRIZ))]
14411  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14412  "xsrqpi 1,%0,%1,1"
14413  [(set_attr "type" "vecfloat")
14414   (set_attr "size" "128")])
14415
14416(define_insn "round<mode>2"
14417  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14418	(unspec:IEEE128
14419	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14420	 UNSPEC_FRIN))]
14421  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14422  "xsrqpi 0,%0,%1,0"
14423  [(set_attr "type" "vecfloat")
14424   (set_attr "size" "128")])
14425
14426;; IEEE 128-bit instructions with round to odd semantics
14427(define_insn "add<mode>3_odd"
14428  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14429	(unspec:IEEE128
14430	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14431	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14432	 UNSPEC_ADD_ROUND_TO_ODD))]
14433  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14434  "xsaddqpo %0,%1,%2"
14435  [(set_attr "type" "vecfloat")
14436   (set_attr "size" "128")])
14437
14438(define_insn "sub<mode>3_odd"
14439  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14440	(unspec:IEEE128
14441	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14442	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14443	 UNSPEC_SUB_ROUND_TO_ODD))]
14444  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14445  "xssubqpo %0,%1,%2"
14446  [(set_attr "type" "vecfloat")
14447   (set_attr "size" "128")])
14448
14449(define_insn "mul<mode>3_odd"
14450  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14451	(unspec:IEEE128
14452	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14453	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14454	 UNSPEC_MUL_ROUND_TO_ODD))]
14455  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14456  "xsmulqpo %0,%1,%2"
14457  [(set_attr "type" "qmul")
14458   (set_attr "size" "128")])
14459
14460(define_insn "div<mode>3_odd"
14461  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14462	(unspec:IEEE128
14463	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14464	  (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14465	 UNSPEC_DIV_ROUND_TO_ODD))]
14466  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14467  "xsdivqpo %0,%1,%2"
14468  [(set_attr "type" "vecdiv")
14469   (set_attr "size" "128")])
14470
14471(define_insn "sqrt<mode>2_odd"
14472  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14473	(unspec:IEEE128
14474	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14475	 UNSPEC_SQRT_ROUND_TO_ODD))]
14476  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14477   "xssqrtqpo %0,%1"
14478  [(set_attr "type" "vecdiv")
14479   (set_attr "size" "128")])
14480
14481(define_insn "fma<mode>4_odd"
14482  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14483	(unspec:IEEE128
14484	 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14485	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14486	  (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14487	 UNSPEC_FMA_ROUND_TO_ODD))]
14488  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14489  "xsmaddqpo %0,%1,%2"
14490  [(set_attr "type" "qmul")
14491   (set_attr "size" "128")])
14492
14493(define_insn "*fms<mode>4_odd"
14494  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14495	(unspec:IEEE128
14496	 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14497	  (match_operand:IEEE128 2 "altivec_register_operand" "v")
14498	  (neg:IEEE128
14499	   (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14500	 UNSPEC_FMA_ROUND_TO_ODD))]
14501  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14502  "xsmsubqpo %0,%1,%2"
14503  [(set_attr "type" "qmul")
14504   (set_attr "size" "128")])
14505
14506(define_insn "*nfma<mode>4_odd"
14507  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14508	(neg:IEEE128
14509	 (unspec:IEEE128
14510	  [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14511	   (match_operand:IEEE128 2 "altivec_register_operand" "v")
14512	   (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14513	  UNSPEC_FMA_ROUND_TO_ODD)))]
14514  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14515  "xsnmaddqpo %0,%1,%2"
14516  [(set_attr "type" "qmul")
14517   (set_attr "size" "128")])
14518
14519(define_insn "*nfms<mode>4_odd"
14520  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14521	(neg:IEEE128
14522	 (unspec:IEEE128
14523	  [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14524	   (match_operand:IEEE128 2 "altivec_register_operand" "v")
14525	   (neg:IEEE128
14526	    (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14527	  UNSPEC_FMA_ROUND_TO_ODD)))]
14528  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14529  "xsnmsubqpo %0,%1,%2"
14530  [(set_attr "type" "qmul")
14531   (set_attr "size" "128")])
14532
14533(define_insn "trunc<mode>df2_odd"
14534  [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14535	(unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14536		   UNSPEC_TRUNC_ROUND_TO_ODD))]
14537  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14538  "xscvqpdpo %0,%1"
14539  [(set_attr "type" "vecfloat")
14540   (set_attr "size" "128")])
14541
14542;; IEEE 128-bit comparisons
14543(define_insn "*cmp<mode>_hw"
14544  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14545	(compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14546		      (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14547  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14548   "xscmpuqp %0,%1,%2"
14549  [(set_attr "type" "veccmp")
14550   (set_attr "size" "128")])
14551
14552;; Miscellaneous ISA 3.0 (power9) instructions
14553
14554(define_insn "darn_32"
14555  [(set (match_operand:SI 0 "register_operand" "=r")
14556        (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14557  "TARGET_P9_MISC"
14558  "darn %0,0"
14559  [(set_attr "type" "integer")])
14560
14561(define_insn "darn_raw"
14562  [(set (match_operand:DI 0 "register_operand" "=r")
14563        (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14564  "TARGET_P9_MISC && TARGET_64BIT"
14565  "darn %0,2"
14566  [(set_attr "type" "integer")])
14567
14568(define_insn "darn"
14569  [(set (match_operand:DI 0 "register_operand" "=r")
14570        (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14571  "TARGET_P9_MISC && TARGET_64BIT"
14572  "darn %0,1"
14573  [(set_attr "type" "integer")])
14574
14575;; Test byte within range.
14576;;
14577;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14578;; represents a byte whose value is ignored in this context and
14579;; vv, the least significant byte, holds the byte value that is to
14580;; be tested for membership within the range specified by operand 2.
14581;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14582;;
14583;; Return in target register operand 0 a value of 1 if lo <= vv and
14584;; vv <= hi.  Otherwise, set register operand 0 to 0.
14585;;
14586;; Though the instructions to which this expansion maps operate on
14587;; 64-bit registers, the current implementation only operates on
14588;; SI-mode operands as the high-order bits provide no information
14589;; that is not already available in the low-order bits.  To avoid the
14590;; costs of data widening operations, future enhancements might allow
14591;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14592(define_expand "cmprb"
14593  [(set (match_dup 3)
14594	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14595		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14596	 UNSPEC_CMPRB))
14597   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14598	(if_then_else:SI (lt (match_dup 3)
14599			     (const_int 0))
14600			 (const_int -1)
14601			 (if_then_else (gt (match_dup 3)
14602					   (const_int 0))
14603				       (const_int 1)
14604				       (const_int 0))))]
14605  "TARGET_P9_MISC"
14606{
14607  operands[3] = gen_reg_rtx (CCmode);
14608})
14609
14610;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14611;; represents a byte whose value is ignored in this context and
14612;; vv, the least significant byte, holds the byte value that is to
14613;; be tested for membership within the range specified by operand 2.
14614;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14615;;
14616;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14617;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
14618;; 3 bits of the target CR register are all set to 0.
14619(define_insn "*cmprb_internal"
14620  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14621	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14622		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14623	 UNSPEC_CMPRB))]
14624  "TARGET_P9_MISC"
14625  "cmprb %0,0,%1,%2"
14626  [(set_attr "type" "logical")])
14627
14628;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14629;; register operand 1 is on.  Otherwise, set operand 0 register to 1
14630;; if the GT bit (0x4) of condition register operand 1 is on.
14631;; Otherwise, set operand 0 to 0.  Note that the result stored into
14632;; register operand 0 is non-zero iff either the LT or GT bits are on
14633;; within condition register operand 1.
14634(define_insn "setb_signed"
14635   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14636	 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14637			      (const_int 0))
14638			  (const_int -1)
14639			  (if_then_else (gt (match_dup 1)
14640					    (const_int 0))
14641					(const_int 1)
14642					(const_int 0))))]
14643  "TARGET_P9_MISC"
14644  "setb %0,%1"
14645  [(set_attr "type" "logical")])
14646
14647(define_insn "setb_unsigned"
14648   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14649	 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14650			      (const_int 0))
14651			  (const_int -1)
14652			  (if_then_else (gtu (match_dup 1)
14653					    (const_int 0))
14654					(const_int 1)
14655					(const_int 0))))]
14656  "TARGET_P9_MISC"
14657  "setb %0,%1"
14658  [(set_attr "type" "logical")])
14659
14660;; Test byte within two ranges.
14661;;
14662;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14663;; represents a byte whose value is ignored in this context and
14664;; vv, the least significant byte, holds the byte value that is to
14665;; be tested for membership within the range specified by operand 2.
14666;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14667;;
14668;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14669;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
14670;; operand 0 to 0.
14671;;
14672;; Though the instructions to which this expansion maps operate on
14673;; 64-bit registers, the current implementation only operates on
14674;; SI-mode operands as the high-order bits provide no information
14675;; that is not already available in the low-order bits.  To avoid the
14676;; costs of data widening operations, future enhancements might allow
14677;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14678(define_expand "cmprb2"
14679  [(set (match_dup 3)
14680	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14681		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14682	 UNSPEC_CMPRB2))
14683   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14684	(if_then_else:SI (lt (match_dup 3)
14685			     (const_int 0))
14686			 (const_int -1)
14687			 (if_then_else (gt (match_dup 3)
14688					   (const_int 0))
14689				       (const_int 1)
14690				       (const_int 0))))]
14691  "TARGET_P9_MISC"
14692{
14693  operands[3] = gen_reg_rtx (CCmode);
14694})
14695
14696;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14697;; represents a byte whose value is ignored in this context and
14698;; vv, the least significant byte, holds the byte value that is to
14699;; be tested for membership within the ranges specified by operand 2.
14700;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14701;;
14702;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14703;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14704;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
14705;; CR register are all set to 0.
14706(define_insn "*cmprb2_internal"
14707  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14708	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14709		    (match_operand:SI 2 "gpc_reg_operand" "r")]
14710	 UNSPEC_CMPRB2))]
14711  "TARGET_P9_MISC"
14712  "cmprb %0,1,%1,%2"
14713  [(set_attr "type" "logical")])
14714
14715;; Test byte membership within set of 8 bytes.
14716;;
14717;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14718;; represents a byte whose value is ignored in this context and
14719;; vv, the least significant byte, holds the byte value that is to
14720;; be tested for membership within the set specified by operand 2.
14721;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14722;;
14723;; Return in target register operand 0 a value of 1 if vv equals one
14724;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
14725;; register operand 0 to 0.  Note that the 8 byte values held within
14726;; operand 2 need not be unique.
14727;;
14728;; Though the instructions to which this expansion maps operate on
14729;; 64-bit registers, the current implementation requires that operands
14730;; 0 and 1 have mode SI as the high-order bits provide no information
14731;; that is not already available in the low-order bits.  To avoid the
14732;; costs of data widening operations, future enhancements might allow
14733;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14734(define_expand "cmpeqb"
14735  [(set (match_dup 3)
14736	(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14737		    (match_operand:DI 2 "gpc_reg_operand" "r")]
14738	 UNSPEC_CMPEQB))
14739   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14740	(if_then_else:SI (lt (match_dup 3)
14741			     (const_int 0))
14742			 (const_int -1)
14743			 (if_then_else (gt (match_dup 3)
14744					   (const_int 0))
14745				       (const_int 1)
14746				       (const_int 0))))]
14747  "TARGET_P9_MISC && TARGET_64BIT"
14748{
14749  operands[3] = gen_reg_rtx (CCmode);
14750})
14751
14752;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14753;; represents a byte whose value is ignored in this context and
14754;; vv, the least significant byte, holds the byte value that is to
14755;; be tested for membership within the set specified by operand 2.
14756;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14757;;
14758;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14759;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
14760;; set the GT bit to zero.  The other 3 bits of the target CR register
14761;; are all set to 0.
14762(define_insn "*cmpeqb_internal"
14763  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14764	 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14765		     (match_operand:DI 2 "gpc_reg_operand" "r")]
14766	  UNSPEC_CMPEQB))]
14767  "TARGET_P9_MISC && TARGET_64BIT"
14768  "cmpeqb %0,%1,%2"
14769  [(set_attr "type" "logical")])
14770
14771
14772(include "sync.md")
14773(include "vector.md")
14774(include "vsx.md")
14775(include "altivec.md")
14776(include "mma.md")
14777(include "dfp.md")
14778(include "crypto.md")
14779(include "htm.md")
14780