gcc/
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobfaae3578ca613e92a3540fe4637eadfcdc710cee
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2018 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
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.
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.
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/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (FRAME_POINTER_REGNUM        111)
54    (TFHAR_REGNO                 112)
55    (TFIAR_REGNO                 113)
56    (TEXASR_REGNO                114)
57   ])
60 ;; UNSPEC usage
63 (define_c_enum "unspec"
64   [UNSPEC_FRSP                  ; frsp for POWER machines
65    UNSPEC_PROBE_STACK           ; probe stack memory reference
66    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
67    UNSPEC_TOC                   ; address of the TOC (more-or-less)
68    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
69    UNSPEC_MOVSI_GOT
70    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
71    UNSPEC_FCTIWZ
72    UNSPEC_FRIM
73    UNSPEC_FRIN
74    UNSPEC_FRIP
75    UNSPEC_FRIZ
76    UNSPEC_XSRDPI
77    UNSPEC_LD_MPIC               ; load_macho_picbase
78    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
79    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
80    UNSPEC_TLSGD
81    UNSPEC_TLSLD
82    UNSPEC_MOVESI_FROM_CR
83    UNSPEC_MOVESI_TO_CR
84    UNSPEC_TLSDTPREL
85    UNSPEC_TLSDTPRELHA
86    UNSPEC_TLSDTPRELLO
87    UNSPEC_TLSGOTDTPREL
88    UNSPEC_TLSTPREL
89    UNSPEC_TLSTPRELHA
90    UNSPEC_TLSTPRELLO
91    UNSPEC_TLSGOTTPREL
92    UNSPEC_TLSTLS
93    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
94    UNSPEC_STFIWX
95    UNSPEC_POPCNTB
96    UNSPEC_FRES
97    UNSPEC_SP_SET
98    UNSPEC_SP_TEST
99    UNSPEC_SYNC
100    UNSPEC_LWSYNC
101    UNSPEC_SYNC_OP
102    UNSPEC_ATOMIC
103    UNSPEC_CMPXCHG
104    UNSPEC_XCHG
105    UNSPEC_AND
106    UNSPEC_DLMZB
107    UNSPEC_DLMZB_CR
108    UNSPEC_DLMZB_STRLEN
109    UNSPEC_RSQRT
110    UNSPEC_TOCREL
111    UNSPEC_MACHOPIC_OFFSET
112    UNSPEC_BPERM
113    UNSPEC_COPYSIGN
114    UNSPEC_PARITY
115    UNSPEC_CMPB
116    UNSPEC_FCTIW
117    UNSPEC_FCTID
118    UNSPEC_LFIWAX
119    UNSPEC_LFIWZX
120    UNSPEC_FCTIWUZ
121    UNSPEC_NOP
122    UNSPEC_GRP_END_NOP
123    UNSPEC_P8V_FMRGOW
124    UNSPEC_P8V_MTVSRWZ
125    UNSPEC_P8V_RELOAD_FROM_GPR
126    UNSPEC_P8V_MTVSRD
127    UNSPEC_P8V_XXPERMDI
128    UNSPEC_P8V_RELOAD_FROM_VSX
129    UNSPEC_ADDG6S
130    UNSPEC_CDTBCD
131    UNSPEC_CBCDTD
132    UNSPEC_DIVE
133    UNSPEC_DIVEU
134    UNSPEC_UNPACK_128BIT
135    UNSPEC_PACK_128BIT
136    UNSPEC_LSQ
137    UNSPEC_FUSION_GPR
138    UNSPEC_STACK_CHECK
139    UNSPEC_FUSION_P9
140    UNSPEC_FUSION_ADDIS
141    UNSPEC_ADD_ROUND_TO_ODD
142    UNSPEC_SUB_ROUND_TO_ODD
143    UNSPEC_MUL_ROUND_TO_ODD
144    UNSPEC_DIV_ROUND_TO_ODD
145    UNSPEC_FMA_ROUND_TO_ODD
146    UNSPEC_SQRT_ROUND_TO_ODD
147    UNSPEC_TRUNC_ROUND_TO_ODD
148    UNSPEC_SIGNBIT
149    UNSPEC_SF_FROM_SI
150    UNSPEC_SI_FROM_SF
151   ])
154 ;; UNSPEC_VOLATILE usage
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_NLGR                 ; non-local goto receiver
166    UNSPECV_MFFS                 ; Move from FPSCR
167    UNSPECV_MTFSF                ; Move to FPSCR Fields
168    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
169    UNSPECV_SPEC_BARRIER         ; Speculation barrier
170   ])
173 ;; Define an insn type attribute.  This is used in function unit delay
174 ;; computations.
175 (define_attr "type"
176   "integer,two,three,
177    add,logical,shift,insert,
178    mul,halfmul,div,
179    exts,cntlz,popcnt,isel,
180    load,store,fpload,fpstore,vecload,vecstore,
181    cmp,
182    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183    cr_logical,mfcr,mfcrf,mtcr,
184    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
185    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
186    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
187    veclogical,veccmpfx,vecexts,vecmove,
188    htm,htmsimple,dfp"
189   (const_string "integer"))
191 ;; What data size does this instruction work on?
192 ;; This is used for insert, mul and others as necessary.
193 (define_attr "size" "8,16,32,64,128" (const_string "32"))
195 ;; What is the insn_cost for this insn?  The target hook can still override
196 ;; this.  For optimizing for size the "length" attribute is used instead.
197 (define_attr "cost" "" (const_int 0))
199 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
200 ;; This is used for add, logical, shift, exts, mul.
201 (define_attr "dot" "no,yes" (const_string "no"))
203 ;; Does this instruction sign-extend its result?
204 ;; This is used for load insns.
205 (define_attr "sign_extend" "no,yes" (const_string "no"))
207 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
208 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
210 ;; Does this instruction use indexed (that is, reg+reg) addressing?
211 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
212 ;; it is automatically set based on that.  If a load or store instruction
213 ;; has fewer than two operands it needs to set this attribute manually
214 ;; or the compiler will crash.
215 (define_attr "indexed" "no,yes"
216   (if_then_else (ior (match_operand 0 "indexed_address_mem")
217                      (match_operand 1 "indexed_address_mem"))
218                 (const_string "yes")
219                 (const_string "no")))
221 ;; Does this instruction use update addressing?
222 ;; This is used for load and store insns.  See the comments for "indexed".
223 (define_attr "update" "no,yes"
224   (if_then_else (ior (match_operand 0 "update_address_mem")
225                      (match_operand 1 "update_address_mem"))
226                 (const_string "yes")
227                 (const_string "no")))
229 ;; Is this instruction using operands[2] as shift amount, and can that be a
230 ;; register?
231 ;; This is used for shift insns.
232 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
234 ;; Is this instruction using a shift amount from a register?
235 ;; This is used for shift insns.
236 (define_attr "var_shift" "no,yes"
237   (if_then_else (and (eq_attr "type" "shift")
238                      (eq_attr "maybe_var_shift" "yes"))
239                 (if_then_else (match_operand 2 "gpc_reg_operand")
240                               (const_string "yes")
241                               (const_string "no"))
242                 (const_string "no")))
244 ;; Is copying of this instruction disallowed?
245 (define_attr "cannot_copy" "no,yes" (const_string "no"))
247 ;; Define floating point instruction sub-types for use with Xfpu.md
248 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
250 ;; Length (in bytes).
251 ; '(pc)' in the following doesn't include the instruction itself; it is
252 ; calculated as if the instruction had zero size.
253 (define_attr "length" ""
254   (if_then_else (eq_attr "type" "branch")
255                 (if_then_else (and (ge (minus (match_dup 0) (pc))
256                                        (const_int -32768))
257                                    (lt (minus (match_dup 0) (pc))
258                                        (const_int 32764)))
259                               (const_int 4)
260                               (const_int 8))
261                 (const_int 4)))
263 ;; Processor type -- this attribute must exactly match the processor_type
264 ;; enumeration in rs6000-opts.h.
265 (define_attr "cpu"
266   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
267    ppc750,ppc7400,ppc7450,
268    ppc403,ppc405,ppc440,ppc476,
269    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
270    power4,power5,power6,power7,power8,power9,
271    rs64a,mpccore,cell,ppca2,titan"
272   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
275 ;; If this instruction is microcoded on the CELL processor
276 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
277 (define_attr "cell_micro" "not,conditional,always"
278   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
279                           (eq_attr "dot" "yes"))
280                      (and (eq_attr "type" "load")
281                           (eq_attr "sign_extend" "yes"))
282                      (and (eq_attr "type" "shift")
283                           (eq_attr "var_shift" "yes")))
284                 (const_string "always")
285                 (const_string "not")))
287 (automata_option "ndfa")
289 (include "rs64.md")
290 (include "mpc.md")
291 (include "40x.md")
292 (include "440.md")
293 (include "476.md")
294 (include "601.md")
295 (include "603.md")
296 (include "6xx.md")
297 (include "7xx.md")
298 (include "7450.md")
299 (include "8540.md")
300 (include "e300c2c3.md")
301 (include "e500mc.md")
302 (include "e500mc64.md")
303 (include "e5500.md")
304 (include "e6500.md")
305 (include "power4.md")
306 (include "power5.md")
307 (include "power6.md")
308 (include "power7.md")
309 (include "power8.md")
310 (include "power9.md")
311 (include "cell.md")
312 (include "xfpu.md")
313 (include "a2.md")
314 (include "titan.md")
316 (include "predicates.md")
317 (include "constraints.md")
319 (include "darwin.md")
322 ;; Mode iterators
324 ; This mode iterator allows :GPR to be used to indicate the allowable size
325 ; of whole values in GPRs.
326 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
328 ; And again, for patterns that need two (potentially) different integer modes.
329 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
331 ; Any supported integer mode.
332 (define_mode_iterator INT [QI HI SI DI TI PTI])
334 ; Any supported integer mode that fits in one register.
335 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
337 ; Integer modes supported in VSX registers with ISA 3.0 instructions
338 (define_mode_iterator INT_ISA3 [QI HI SI DI])
340 ; Everything we can extend QImode to.
341 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
343 ; Everything we can extend HImode to.
344 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
346 ; Everything we can extend SImode to.
347 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
349 ; QImode or HImode for small integer moves and small atomic ops
350 (define_mode_iterator QHI [QI HI])
352 ; QImode, HImode, SImode for fused ops only for GPR loads
353 (define_mode_iterator QHSI [QI HI SI])
355 ; HImode or SImode for sign extended fusion ops
356 (define_mode_iterator HSI [HI SI])
358 ; SImode or DImode, even if DImode doesn't fit in GPRs.
359 (define_mode_iterator SDI [SI DI])
361 ; Types that can be fused with an ADDIS instruction to load or store a GPR
362 ; register that has reg+offset addressing.
363 (define_mode_iterator GPR_FUSION [QI
364                                   HI
365                                   SI
366                                   (DI   "TARGET_POWERPC64")
367                                   SF
368                                   (DF   "TARGET_POWERPC64")])
370 ; Types that can be fused with an ADDIS instruction to load or store a FPR
371 ; register that has reg+offset addressing.
372 (define_mode_iterator FPR_FUSION [DI SF DF])
374 ; The size of a pointer.  Also, the size of the value that a record-condition
375 ; (one with a '.') will compare; and the size used for arithmetic carries.
376 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
378 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
379 ; PTImode is GPR only)
380 (define_mode_iterator TI2 [TI PTI])
382 ; Any hardware-supported floating-point mode
383 (define_mode_iterator FP [
384   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
385   (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
386   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
387   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
388   (KF "TARGET_FLOAT128_TYPE")
389   (DD "TARGET_DFP")
390   (TD "TARGET_DFP")])
392 ; Any fma capable floating-point mode.
393 (define_mode_iterator FMA_F [
394   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
395   (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
396        || VECTOR_UNIT_VSX_P (DFmode)")
397   (V2SF "TARGET_PAIRED_FLOAT")
398   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
399   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
400   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
401   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
402   ])
404 ; Floating point move iterators to combine binary and decimal moves
405 (define_mode_iterator FMOVE32 [SF SD])
406 (define_mode_iterator FMOVE64 [DF DD])
407 (define_mode_iterator FMOVE64X [DI DF DD])
408 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
409                                 (IF "FLOAT128_IBM_P (IFmode)")
410                                 (TD "TARGET_HARD_FLOAT")])
412 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
413                                     (IF "FLOAT128_2REG_P (IFmode)")
414                                     (TD "TARGET_HARD_FLOAT")])
416 ; Iterators for 128 bit types for direct move
417 (define_mode_iterator FMOVE128_GPR [TI
418                                     V16QI
419                                     V8HI
420                                     V4SI
421                                     V4SF
422                                     V2DI
423                                     V2DF
424                                     V1TI
425                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
426                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
428 ; Iterator for 128-bit VSX types for pack/unpack
429 (define_mode_iterator FMOVE128_VSX [V1TI KF])
431 ; Whether a floating point move is ok, don't allow SD without hardware FP
432 (define_mode_attr fmove_ok [(SF "")
433                             (DF "")
434                             (SD "TARGET_HARD_FLOAT")
435                             (DD "")])
437 ; Convert REAL_VALUE to the appropriate bits
438 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
439                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
440                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
441                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
443 ; Whether 0.0 has an all-zero bit pattern
444 (define_mode_attr zero_fp [(SF "j")
445                            (DF "j")
446                            (TF "j")
447                            (IF "j")
448                            (KF "j")
449                            (SD "wn")
450                            (DD "wn")
451                            (TD "wn")])
453 ; Definitions for 64-bit VSX
454 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
456 ; Definitions for 64-bit direct move
457 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
459 ; Definitions for 64-bit use of altivec registers
460 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
462 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
463 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
465 ; These modes do not fit in integer registers in 32-bit mode.
466 (define_mode_iterator DIFD [DI DF DD])
468 ; Iterator for reciprocal estimate instructions
469 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
471 ; Iterator for just SF/DF
472 (define_mode_iterator SFDF [SF DF])
474 ; Like SFDF, but a different name to match conditional move where the
475 ; comparison operands may be a different mode than the input operands.
476 (define_mode_iterator SFDF2 [SF DF])
478 ; Iterator for 128-bit floating point that uses the IBM double-double format
479 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
480                               (TF "FLOAT128_IBM_P (TFmode)")])
482 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
483 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
484                                (TF "FLOAT128_IEEE_P (TFmode)")])
486 ; Iterator for 128-bit floating point
487 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
488                                 (IF "TARGET_FLOAT128_TYPE")
489                                 (TF "TARGET_LONG_DOUBLE_128")])
491 ; Iterator for signbit on 64-bit machines with direct move
492 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
493                                (TF "FLOAT128_VECTOR_P (TFmode)")])
495 ; Iterator for ISA 3.0 supported floating point types
496 (define_mode_iterator FP_ISA3 [SF DF])
498 ; SF/DF suffix for traditional floating instructions
499 (define_mode_attr Ftrad         [(SF "s") (DF "")])
501 ; SF/DF suffix for VSX instructions
502 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
504 ; SF/DF constraint for arithmetic on traditional floating point registers
505 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
507 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
508 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
509 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
510 ; format.
511 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
513 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
514 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
515 ; instructions added in ISA 2.07 (power8)
516 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
518 ; SF/DF constraint for arithmetic on altivec registers
519 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
521 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
522 (define_mode_attr Fs            [(SF "s")  (DF "d")])
524 ; FRE/FRES support
525 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
526 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
528 ; Conditional returns.
529 (define_code_iterator any_return [return simple_return])
530 (define_code_attr return_pred [(return "direct_return ()")
531                                (simple_return "1")])
532 (define_code_attr return_str [(return "") (simple_return "simple_")])
534 ; Logical operators.
535 (define_code_iterator iorxor            [ior xor])
536 (define_code_iterator and_ior_xor       [and ior xor])
538 ; Signed/unsigned variants of ops.
539 (define_code_iterator any_extend        [sign_extend zero_extend])
540 (define_code_iterator any_fix           [fix unsigned_fix])
541 (define_code_iterator any_float         [float unsigned_float])
543 (define_code_attr u  [(sign_extend      "")
544                       (zero_extend      "u")
545                       (fix              "")
546                       (unsigned_fix     "u")])
548 (define_code_attr su [(sign_extend      "s")
549                       (zero_extend      "u")
550                       (fix              "s")
551                       (unsigned_fix     "u")
552                       (float            "s")
553                       (unsigned_float   "u")])
555 (define_code_attr az [(sign_extend      "a")
556                       (zero_extend      "z")
557                       (fix              "a")
558                       (unsigned_fix     "z")
559                       (float            "a")
560                       (unsigned_float   "z")])
562 (define_code_attr uns [(fix             "")
563                        (unsigned_fix    "uns")
564                        (float           "")
565                        (unsigned_float  "uns")])
567 ; Various instructions that come in SI and DI forms.
568 ; A generic w/d attribute, for things like cmpw/cmpd.
569 (define_mode_attr wd [(QI    "b")
570                       (HI    "h")
571                       (SI    "w")
572                       (DI    "d")
573                       (V16QI "b")
574                       (V8HI  "h")
575                       (V4SI  "w")
576                       (V2DI  "d")
577                       (V1TI  "q")
578                       (TI    "q")])
580 ;; How many bits in this mode?
581 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
583 ; DImode bits
584 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
586 ;; Bitmask for shift instructions
587 (define_mode_attr hH [(SI "h") (DI "H")])
589 ;; A mode twice the size of the given mode
590 (define_mode_attr dmode [(SI "di") (DI "ti")])
591 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
593 ;; Suffix for reload patterns
594 (define_mode_attr ptrsize [(SI "32bit")
595                            (DI "64bit")])
597 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
598                             (DI "TARGET_64BIT")])
600 (define_mode_attr mptrsize [(SI "si")
601                             (DI "di")])
603 (define_mode_attr ptrload [(SI "lwz")
604                            (DI "ld")])
606 (define_mode_attr ptrm [(SI "m")
607                         (DI "Y")])
609 (define_mode_attr rreg [(SF   "f")
610                         (DF   "ws")
611                         (TF   "f")
612                         (TD   "f")
613                         (V4SF "wf")
614                         (V2DF "wd")])
616 (define_mode_attr rreg2 [(SF   "f")
617                          (DF   "d")])
619 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
620                                  (DF "TARGET_FCFID")])
622 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
623                                 (DF "TARGET_DOUBLE_FLOAT")])
625 ;; Mode iterator for logical operations on 128-bit types
626 (define_mode_iterator BOOL_128          [TI
627                                          PTI
628                                          (V16QI "TARGET_ALTIVEC")
629                                          (V8HI  "TARGET_ALTIVEC")
630                                          (V4SI  "TARGET_ALTIVEC")
631                                          (V4SF  "TARGET_ALTIVEC")
632                                          (V2DI  "TARGET_ALTIVEC")
633                                          (V2DF  "TARGET_ALTIVEC")
634                                          (V1TI  "TARGET_ALTIVEC")])
636 ;; For the GPRs we use 3 constraints for register outputs, two that are the
637 ;; same as the output register, and a third where the output register is an
638 ;; early clobber, so we don't have to deal with register overlaps.  For the
639 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
640 ;; either.
642 ;; Mode attribute for boolean operation register constraints for output
643 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
644                                          (PTI   "&r,r,r")
645                                          (V16QI "wa,v,&?r,?r,?r")
646                                          (V8HI  "wa,v,&?r,?r,?r")
647                                          (V4SI  "wa,v,&?r,?r,?r")
648                                          (V4SF  "wa,v,&?r,?r,?r")
649                                          (V2DI  "wa,v,&?r,?r,?r")
650                                          (V2DF  "wa,v,&?r,?r,?r")
651                                          (V1TI  "wa,v,&?r,?r,?r")])
653 ;; Mode attribute for boolean operation register constraints for operand1
654 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
655                                          (PTI   "r,0,r")
656                                          (V16QI "wa,v,r,0,r")
657                                          (V8HI  "wa,v,r,0,r")
658                                          (V4SI  "wa,v,r,0,r")
659                                          (V4SF  "wa,v,r,0,r")
660                                          (V2DI  "wa,v,r,0,r")
661                                          (V2DF  "wa,v,r,0,r")
662                                          (V1TI  "wa,v,r,0,r")])
664 ;; Mode attribute for boolean operation register constraints for operand2
665 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
666                                          (PTI   "r,r,0")
667                                          (V16QI "wa,v,r,r,0")
668                                          (V8HI  "wa,v,r,r,0")
669                                          (V4SI  "wa,v,r,r,0")
670                                          (V4SF  "wa,v,r,r,0")
671                                          (V2DI  "wa,v,r,r,0")
672                                          (V2DF  "wa,v,r,r,0")
673                                          (V1TI  "wa,v,r,r,0")])
675 ;; Mode attribute for boolean operation register constraints for operand1
676 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
677 ;; is used for operand1 or operand2
678 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
679                                          (PTI   "r,0,0")
680                                          (V16QI "wa,v,r,0,0")
681                                          (V8HI  "wa,v,r,0,0")
682                                          (V4SI  "wa,v,r,0,0")
683                                          (V4SF  "wa,v,r,0,0")
684                                          (V2DI  "wa,v,r,0,0")
685                                          (V2DF  "wa,v,r,0,0")
686                                          (V1TI  "wa,v,r,0,0")])
688 ;; Reload iterator for creating the function to allocate a base register to
689 ;; supplement addressing modes.
690 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
691                               SF SD SI DF DD DI TI PTI KF IF TF])
693 ;; Iterate over smin, smax
694 (define_code_iterator fp_minmax [smin smax])
696 (define_code_attr     minmax    [(smin "min")
697                                  (smax "max")])
699 (define_code_attr     SMINMAX   [(smin "SMIN")
700                                  (smax "SMAX")])
702 ;; Iterator to optimize the following cases:
703 ;;      D-form load to FPR register & move to Altivec register
704 ;;      Move Altivec register to FPR register and store
705 (define_mode_iterator ALTIVEC_DFORM [DF
706                                      (SF "TARGET_P8_VECTOR")
707                                      (DI "TARGET_POWERPC64")])
710 ;; Start with fixed-point load and store insns.  Here we put only the more
711 ;; complex forms.  Basic data transfer is done later.
713 (define_insn "zero_extendqi<mode>2"
714   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
715         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
716   ""
717   "@
718    lbz%U1%X1 %0,%1
719    rlwinm %0,%1,0,0xff
720    lxsibzx %x0,%y1
721    vextractub %0,%1,7"
722   [(set_attr "type" "load,shift,fpload,vecperm")])
724 (define_insn_and_split "*zero_extendqi<mode>2_dot"
725   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
727                     (const_int 0)))
728    (clobber (match_scratch:EXTQI 0 "=r,r"))]
729   ""
730   "@
731    andi. %0,%1,0xff
732    #"
733   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
734   [(set (match_dup 0)
735         (zero_extend:EXTQI (match_dup 1)))
736    (set (match_dup 2)
737         (compare:CC (match_dup 0)
738                     (const_int 0)))]
739   ""
740   [(set_attr "type" "logical")
741    (set_attr "dot" "yes")
742    (set_attr "length" "4,8")])
744 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
745   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
746         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
747                     (const_int 0)))
748    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
749         (zero_extend:EXTQI (match_dup 1)))]
750   ""
751   "@
752    andi. %0,%1,0xff
753    #"
754   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
755   [(set (match_dup 0)
756         (zero_extend:EXTQI (match_dup 1)))
757    (set (match_dup 2)
758         (compare:CC (match_dup 0)
759                     (const_int 0)))]
760   ""
761   [(set_attr "type" "logical")
762    (set_attr "dot" "yes")
763    (set_attr "length" "4,8")])
766 (define_insn "zero_extendhi<mode>2"
767   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
768         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
769   ""
770   "@
771    lhz%U1%X1 %0,%1
772    rlwinm %0,%1,0,0xffff
773    lxsihzx %x0,%y1
774    vextractuh %0,%1,6"
775   [(set_attr "type" "load,shift,fpload,vecperm")])
777 (define_insn_and_split "*zero_extendhi<mode>2_dot"
778   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
779         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
780                     (const_int 0)))
781    (clobber (match_scratch:EXTHI 0 "=r,r"))]
782   ""
783   "@
784    andi. %0,%1,0xffff
785    #"
786   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
787   [(set (match_dup 0)
788         (zero_extend:EXTHI (match_dup 1)))
789    (set (match_dup 2)
790         (compare:CC (match_dup 0)
791                     (const_int 0)))]
792   ""
793   [(set_attr "type" "logical")
794    (set_attr "dot" "yes")
795    (set_attr "length" "4,8")])
797 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
798   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
799         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
800                     (const_int 0)))
801    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
802         (zero_extend:EXTHI (match_dup 1)))]
803   ""
804   "@
805    andi. %0,%1,0xffff
806    #"
807   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
808   [(set (match_dup 0)
809         (zero_extend:EXTHI (match_dup 1)))
810    (set (match_dup 2)
811         (compare:CC (match_dup 0)
812                     (const_int 0)))]
813   ""
814   [(set_attr "type" "logical")
815    (set_attr "dot" "yes")
816    (set_attr "length" "4,8")])
819 (define_insn "zero_extendsi<mode>2"
820   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
821         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
822   ""
823   "@
824    lwz%U1%X1 %0,%1
825    rldicl %0,%1,0,32
826    lfiwzx %0,%y1
827    lxsiwzx %x0,%y1
828    mtvsrwz %x0,%1
829    mfvsrwz %0,%x1
830    xxextractuw %x0,%x1,4"
831   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
833 (define_insn_and_split "*zero_extendsi<mode>2_dot"
834   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
835         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
836                     (const_int 0)))
837    (clobber (match_scratch:EXTSI 0 "=r,r"))]
838   ""
839   "@
840    rldicl. %0,%1,0,32
841    #"
842   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
843   [(set (match_dup 0)
844         (zero_extend:DI (match_dup 1)))
845    (set (match_dup 2)
846         (compare:CC (match_dup 0)
847                     (const_int 0)))]
848   ""
849   [(set_attr "type" "shift")
850    (set_attr "dot" "yes")
851    (set_attr "length" "4,8")])
853 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
854   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
855         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
856                     (const_int 0)))
857    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
858         (zero_extend:EXTSI (match_dup 1)))]
859   ""
860   "@
861    rldicl. %0,%1,0,32
862    #"
863   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
864   [(set (match_dup 0)
865         (zero_extend:EXTSI (match_dup 1)))
866    (set (match_dup 2)
867         (compare:CC (match_dup 0)
868                     (const_int 0)))]
869   ""
870   [(set_attr "type" "shift")
871    (set_attr "dot" "yes")
872    (set_attr "length" "4,8")])
875 (define_insn "extendqi<mode>2"
876   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
877         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
878   ""
879   "@
880    extsb %0,%1
881    vextsb2d %0,%1"
882   [(set_attr "type" "exts,vecperm")])
884 (define_insn_and_split "*extendqi<mode>2_dot"
885   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
886         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
887                     (const_int 0)))
888    (clobber (match_scratch:EXTQI 0 "=r,r"))]
889   ""
890   "@
891    extsb. %0,%1
892    #"
893   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
894   [(set (match_dup 0)
895         (sign_extend:EXTQI (match_dup 1)))
896    (set (match_dup 2)
897         (compare:CC (match_dup 0)
898                     (const_int 0)))]
899   ""
900   [(set_attr "type" "exts")
901    (set_attr "dot" "yes")
902    (set_attr "length" "4,8")])
904 (define_insn_and_split "*extendqi<mode>2_dot2"
905   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
906         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
907                     (const_int 0)))
908    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
909         (sign_extend:EXTQI (match_dup 1)))]
910   ""
911   "@
912    extsb. %0,%1
913    #"
914   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
915   [(set (match_dup 0)
916         (sign_extend:EXTQI (match_dup 1)))
917    (set (match_dup 2)
918         (compare:CC (match_dup 0)
919                     (const_int 0)))]
920   ""
921   [(set_attr "type" "exts")
922    (set_attr "dot" "yes")
923    (set_attr "length" "4,8")])
926 (define_expand "extendhi<mode>2"
927   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
928         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
929   ""
930   "")
932 (define_insn "*extendhi<mode>2"
933   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
934         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
935   ""
936   "@
937    lha%U1%X1 %0,%1
938    extsh %0,%1
939    #
940    vextsh2d %0,%1"
941   [(set_attr "type" "load,exts,fpload,vecperm")
942    (set_attr "sign_extend" "yes")
943    (set_attr "length" "4,4,8,4")])
945 (define_split
946   [(set (match_operand:EXTHI 0 "altivec_register_operand")
947         (sign_extend:EXTHI
948          (match_operand:HI 1 "indexed_or_indirect_operand")))]
949   "TARGET_P9_VECTOR && reload_completed"
950   [(set (match_dup 2)
951         (match_dup 1))
952    (set (match_dup 0)
953         (sign_extend:EXTHI (match_dup 2)))]
955   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
958 (define_insn_and_split "*extendhi<mode>2_dot"
959   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
960         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
961                     (const_int 0)))
962    (clobber (match_scratch:EXTHI 0 "=r,r"))]
963   ""
964   "@
965    extsh. %0,%1
966    #"
967   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
968   [(set (match_dup 0)
969         (sign_extend:EXTHI (match_dup 1)))
970    (set (match_dup 2)
971         (compare:CC (match_dup 0)
972                     (const_int 0)))]
973   ""
974   [(set_attr "type" "exts")
975    (set_attr "dot" "yes")
976    (set_attr "length" "4,8")])
978 (define_insn_and_split "*extendhi<mode>2_dot2"
979   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
981                     (const_int 0)))
982    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
983         (sign_extend:EXTHI (match_dup 1)))]
984   ""
985   "@
986    extsh. %0,%1
987    #"
988   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
989   [(set (match_dup 0)
990         (sign_extend:EXTHI (match_dup 1)))
991    (set (match_dup 2)
992         (compare:CC (match_dup 0)
993                     (const_int 0)))]
994   ""
995   [(set_attr "type" "exts")
996    (set_attr "dot" "yes")
997    (set_attr "length" "4,8")])
1000 (define_insn "extendsi<mode>2"
1001   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1002                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
1004         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1005                      "Y,  r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
1006   ""
1007   "@
1008    lwa%U1%X1 %0,%1
1009    extsw %0,%1
1010    lfiwax %0,%y1
1011    lxsiwax %x0,%y1
1012    mtvsrwa %x0,%1
1013    vextsw2d %0,%1
1014    #
1015    #"
1016   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1017    (set_attr "sign_extend" "yes")
1018    (set_attr "length" "4,4,4,4,4,4,8,8")])
1020 (define_split
1021   [(set (match_operand:EXTSI 0 "int_reg_operand")
1022         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1023   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1024   [(set (match_dup 2)
1025         (match_dup 1))
1026    (set (match_dup 0)
1027         (sign_extend:DI (match_dup 2)))]
1029   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1032 (define_split
1033   [(set (match_operand:DI 0 "altivec_register_operand")
1034         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1035   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1036   [(const_int 0)]
1038   rtx dest = operands[0];
1039   rtx src = operands[1];
1040   int dest_regno = REGNO (dest);
1041   int src_regno = REGNO (src);
1042   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1043   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1045   if (VECTOR_ELT_ORDER_BIG)
1046     {
1047       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1048       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1049     }
1050   else
1051     {
1052       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1053       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1054     }
1055   DONE;
1058 (define_insn_and_split "*extendsi<mode>2_dot"
1059   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1060         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1061                     (const_int 0)))
1062    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1063   ""
1064   "@
1065    extsw. %0,%1
1066    #"
1067   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1068   [(set (match_dup 0)
1069         (sign_extend:EXTSI (match_dup 1)))
1070    (set (match_dup 2)
1071         (compare:CC (match_dup 0)
1072                     (const_int 0)))]
1073   ""
1074   [(set_attr "type" "exts")
1075    (set_attr "dot" "yes")
1076    (set_attr "length" "4,8")])
1078 (define_insn_and_split "*extendsi<mode>2_dot2"
1079   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1080         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1081                     (const_int 0)))
1082    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1083         (sign_extend:EXTSI (match_dup 1)))]
1084   ""
1085   "@
1086    extsw. %0,%1
1087    #"
1088   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1089   [(set (match_dup 0)
1090         (sign_extend:EXTSI (match_dup 1)))
1091    (set (match_dup 2)
1092         (compare:CC (match_dup 0)
1093                     (const_int 0)))]
1094   ""
1095   [(set_attr "type" "exts")
1096    (set_attr "dot" "yes")
1097    (set_attr "length" "4,8")])
1099 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1101 (define_insn "*macchwc"
1102   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1103         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1104                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1105                                        (const_int 16))
1106                                       (sign_extend:SI
1107                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1108                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1109                     (const_int 0)))
1110    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1111         (plus:SI (mult:SI (ashiftrt:SI
1112                            (match_dup 2)
1113                            (const_int 16))
1114                           (sign_extend:SI
1115                            (match_dup 1)))
1116                  (match_dup 4)))]
1117   "TARGET_MULHW"
1118   "macchw. %0,%1,%2"
1119   [(set_attr "type" "halfmul")])
1121 (define_insn "*macchw"
1122   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1123         (plus:SI (mult:SI (ashiftrt:SI
1124                            (match_operand:SI 2 "gpc_reg_operand" "r")
1125                            (const_int 16))
1126                           (sign_extend:SI
1127                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1128                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1129   "TARGET_MULHW"
1130   "macchw %0,%1,%2"
1131   [(set_attr "type" "halfmul")])
1133 (define_insn "*macchwuc"
1134   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1135         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1136                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1137                                        (const_int 16))
1138                                       (zero_extend:SI
1139                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1140                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1141                     (const_int 0)))
1142    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1143         (plus:SI (mult:SI (lshiftrt:SI
1144                            (match_dup 2)
1145                            (const_int 16))
1146                           (zero_extend:SI
1147                            (match_dup 1)))
1148                  (match_dup 4)))]
1149   "TARGET_MULHW"
1150   "macchwu. %0,%1,%2"
1151   [(set_attr "type" "halfmul")])
1153 (define_insn "*macchwu"
1154   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1155         (plus:SI (mult:SI (lshiftrt:SI
1156                            (match_operand:SI 2 "gpc_reg_operand" "r")
1157                            (const_int 16))
1158                           (zero_extend:SI
1159                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1160                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1161   "TARGET_MULHW"
1162   "macchwu %0,%1,%2"
1163   [(set_attr "type" "halfmul")])
1165 (define_insn "*machhwc"
1166   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1167         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1168                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1169                                        (const_int 16))
1170                                       (ashiftrt:SI
1171                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1172                                        (const_int 16)))
1173                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1174                     (const_int 0)))
1175    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1176         (plus:SI (mult:SI (ashiftrt:SI
1177                            (match_dup 1)
1178                            (const_int 16))
1179                           (ashiftrt:SI
1180                            (match_dup 2)
1181                            (const_int 16)))
1182                  (match_dup 4)))]
1183   "TARGET_MULHW"
1184   "machhw. %0,%1,%2"
1185   [(set_attr "type" "halfmul")])
1187 (define_insn "*machhw"
1188   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1189         (plus:SI (mult:SI (ashiftrt:SI
1190                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1191                            (const_int 16))
1192                           (ashiftrt:SI
1193                            (match_operand:SI 2 "gpc_reg_operand" "r")
1194                            (const_int 16)))
1195                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1196   "TARGET_MULHW"
1197   "machhw %0,%1,%2"
1198   [(set_attr "type" "halfmul")])
1200 (define_insn "*machhwuc"
1201   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1202         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1203                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1204                                        (const_int 16))
1205                                       (lshiftrt:SI
1206                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1207                                        (const_int 16)))
1208                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1209                     (const_int 0)))
1210    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1211         (plus:SI (mult:SI (lshiftrt:SI
1212                            (match_dup 1)
1213                            (const_int 16))
1214                           (lshiftrt:SI
1215                            (match_dup 2)
1216                            (const_int 16)))
1217                  (match_dup 4)))]
1218   "TARGET_MULHW"
1219   "machhwu. %0,%1,%2"
1220   [(set_attr "type" "halfmul")])
1222 (define_insn "*machhwu"
1223   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1224         (plus:SI (mult:SI (lshiftrt:SI
1225                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1226                            (const_int 16))
1227                           (lshiftrt:SI
1228                            (match_operand:SI 2 "gpc_reg_operand" "r")
1229                            (const_int 16)))
1230                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1231   "TARGET_MULHW"
1232   "machhwu %0,%1,%2"
1233   [(set_attr "type" "halfmul")])
1235 (define_insn "*maclhwc"
1236   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1237         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1238                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1239                                       (sign_extend:SI
1240                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1241                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1242                     (const_int 0)))
1243    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1244         (plus:SI (mult:SI (sign_extend:SI
1245                            (match_dup 1))
1246                           (sign_extend:SI
1247                            (match_dup 2)))
1248                  (match_dup 4)))]
1249   "TARGET_MULHW"
1250   "maclhw. %0,%1,%2"
1251   [(set_attr "type" "halfmul")])
1253 (define_insn "*maclhw"
1254   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1255         (plus:SI (mult:SI (sign_extend:SI
1256                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1257                           (sign_extend:SI
1258                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1259                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1260   "TARGET_MULHW"
1261   "maclhw %0,%1,%2"
1262   [(set_attr "type" "halfmul")])
1264 (define_insn "*maclhwuc"
1265   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1266         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1267                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1268                                       (zero_extend:SI
1269                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1270                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1271                     (const_int 0)))
1272    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1273         (plus:SI (mult:SI (zero_extend:SI
1274                            (match_dup 1))
1275                           (zero_extend:SI
1276                            (match_dup 2)))
1277                  (match_dup 4)))]
1278   "TARGET_MULHW"
1279   "maclhwu. %0,%1,%2"
1280   [(set_attr "type" "halfmul")])
1282 (define_insn "*maclhwu"
1283   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1284         (plus:SI (mult:SI (zero_extend:SI
1285                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1286                           (zero_extend:SI
1287                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1288                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1289   "TARGET_MULHW"
1290   "maclhwu %0,%1,%2"
1291   [(set_attr "type" "halfmul")])
1293 (define_insn "*nmacchwc"
1294   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1295         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1296                               (mult:SI (ashiftrt:SI
1297                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1298                                         (const_int 16))
1299                                        (sign_extend:SI
1300                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1301                     (const_int 0)))
1302    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1303         (minus:SI (match_dup 4)
1304                   (mult:SI (ashiftrt:SI
1305                             (match_dup 2)
1306                             (const_int 16))
1307                            (sign_extend:SI
1308                             (match_dup 1)))))]
1309   "TARGET_MULHW"
1310   "nmacchw. %0,%1,%2"
1311   [(set_attr "type" "halfmul")])
1313 (define_insn "*nmacchw"
1314   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1315         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1316                   (mult:SI (ashiftrt:SI
1317                             (match_operand:SI 2 "gpc_reg_operand" "r")
1318                             (const_int 16))
1319                            (sign_extend:SI
1320                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1321   "TARGET_MULHW"
1322   "nmacchw %0,%1,%2"
1323   [(set_attr "type" "halfmul")])
1325 (define_insn "*nmachhwc"
1326   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1327         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1328                               (mult:SI (ashiftrt:SI
1329                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1330                                         (const_int 16))
1331                                        (ashiftrt:SI
1332                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1333                                         (const_int 16))))
1334                     (const_int 0)))
1335    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1336         (minus:SI (match_dup 4)
1337                   (mult:SI (ashiftrt:SI
1338                             (match_dup 1)
1339                             (const_int 16))
1340                            (ashiftrt:SI
1341                             (match_dup 2)
1342                             (const_int 16)))))]
1343   "TARGET_MULHW"
1344   "nmachhw. %0,%1,%2"
1345   [(set_attr "type" "halfmul")])
1347 (define_insn "*nmachhw"
1348   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1349         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1350                   (mult:SI (ashiftrt:SI
1351                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1352                             (const_int 16))
1353                            (ashiftrt:SI
1354                             (match_operand:SI 2 "gpc_reg_operand" "r")
1355                             (const_int 16)))))]
1356   "TARGET_MULHW"
1357   "nmachhw %0,%1,%2"
1358   [(set_attr "type" "halfmul")])
1360 (define_insn "*nmaclhwc"
1361   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1362         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1363                               (mult:SI (sign_extend:SI
1364                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1365                                        (sign_extend:SI
1366                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1367                     (const_int 0)))
1368    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1369         (minus:SI (match_dup 4)
1370                   (mult:SI (sign_extend:SI
1371                             (match_dup 1))
1372                            (sign_extend:SI
1373                             (match_dup 2)))))]
1374   "TARGET_MULHW"
1375   "nmaclhw. %0,%1,%2"
1376   [(set_attr "type" "halfmul")])
1378 (define_insn "*nmaclhw"
1379   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1380         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1381                   (mult:SI (sign_extend:SI
1382                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1383                            (sign_extend:SI
1384                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1385   "TARGET_MULHW"
1386   "nmaclhw %0,%1,%2"
1387   [(set_attr "type" "halfmul")])
1389 (define_insn "*mulchwc"
1390   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1391         (compare:CC (mult:SI (ashiftrt:SI
1392                               (match_operand:SI 2 "gpc_reg_operand" "r")
1393                               (const_int 16))
1394                              (sign_extend:SI
1395                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1396                     (const_int 0)))
1397    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1398         (mult:SI (ashiftrt:SI
1399                   (match_dup 2)
1400                   (const_int 16))
1401                  (sign_extend:SI
1402                   (match_dup 1))))]
1403   "TARGET_MULHW"
1404   "mulchw. %0,%1,%2"
1405   [(set_attr "type" "halfmul")])
1407 (define_insn "*mulchw"
1408   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1409         (mult:SI (ashiftrt:SI
1410                   (match_operand:SI 2 "gpc_reg_operand" "r")
1411                   (const_int 16))
1412                  (sign_extend:SI
1413                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1414   "TARGET_MULHW"
1415   "mulchw %0,%1,%2"
1416   [(set_attr "type" "halfmul")])
1418 (define_insn "*mulchwuc"
1419   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1420         (compare:CC (mult:SI (lshiftrt:SI
1421                               (match_operand:SI 2 "gpc_reg_operand" "r")
1422                               (const_int 16))
1423                              (zero_extend:SI
1424                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1425                     (const_int 0)))
1426    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1427         (mult:SI (lshiftrt:SI
1428                   (match_dup 2)
1429                   (const_int 16))
1430                  (zero_extend:SI
1431                   (match_dup 1))))]
1432   "TARGET_MULHW"
1433   "mulchwu. %0,%1,%2"
1434   [(set_attr "type" "halfmul")])
1436 (define_insn "*mulchwu"
1437   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1438         (mult:SI (lshiftrt:SI
1439                   (match_operand:SI 2 "gpc_reg_operand" "r")
1440                   (const_int 16))
1441                  (zero_extend:SI
1442                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1443   "TARGET_MULHW"
1444   "mulchwu %0,%1,%2"
1445   [(set_attr "type" "halfmul")])
1447 (define_insn "*mulhhwc"
1448   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1449         (compare:CC (mult:SI (ashiftrt:SI
1450                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1451                               (const_int 16))
1452                              (ashiftrt:SI
1453                               (match_operand:SI 2 "gpc_reg_operand" "r")
1454                               (const_int 16)))
1455                     (const_int 0)))
1456    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1457         (mult:SI (ashiftrt:SI
1458                   (match_dup 1)
1459                   (const_int 16))
1460                  (ashiftrt:SI
1461                   (match_dup 2)
1462                   (const_int 16))))]
1463   "TARGET_MULHW"
1464   "mulhhw. %0,%1,%2"
1465   [(set_attr "type" "halfmul")])
1467 (define_insn "*mulhhw"
1468   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1469         (mult:SI (ashiftrt:SI
1470                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1471                   (const_int 16))
1472                  (ashiftrt:SI
1473                   (match_operand:SI 2 "gpc_reg_operand" "r")
1474                   (const_int 16))))]
1475   "TARGET_MULHW"
1476   "mulhhw %0,%1,%2"
1477   [(set_attr "type" "halfmul")])
1479 (define_insn "*mulhhwuc"
1480   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1481         (compare:CC (mult:SI (lshiftrt:SI
1482                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1483                               (const_int 16))
1484                              (lshiftrt:SI
1485                               (match_operand:SI 2 "gpc_reg_operand" "r")
1486                               (const_int 16)))
1487                     (const_int 0)))
1488    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1489         (mult:SI (lshiftrt:SI
1490                   (match_dup 1)
1491                   (const_int 16))
1492                  (lshiftrt:SI
1493                   (match_dup 2)
1494                   (const_int 16))))]
1495   "TARGET_MULHW"
1496   "mulhhwu. %0,%1,%2"
1497   [(set_attr "type" "halfmul")])
1499 (define_insn "*mulhhwu"
1500   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1501         (mult:SI (lshiftrt:SI
1502                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1503                   (const_int 16))
1504                  (lshiftrt:SI
1505                   (match_operand:SI 2 "gpc_reg_operand" "r")
1506                   (const_int 16))))]
1507   "TARGET_MULHW"
1508   "mulhhwu %0,%1,%2"
1509   [(set_attr "type" "halfmul")])
1511 (define_insn "*mullhwc"
1512   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1513         (compare:CC (mult:SI (sign_extend:SI
1514                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1515                              (sign_extend:SI
1516                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1517                     (const_int 0)))
1518    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1519         (mult:SI (sign_extend:SI
1520                   (match_dup 1))
1521                  (sign_extend:SI
1522                   (match_dup 2))))]
1523   "TARGET_MULHW"
1524   "mullhw. %0,%1,%2"
1525   [(set_attr "type" "halfmul")])
1527 (define_insn "*mullhw"
1528   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1529         (mult:SI (sign_extend:SI
1530                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1531                  (sign_extend:SI
1532                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1533   "TARGET_MULHW"
1534   "mullhw %0,%1,%2"
1535   [(set_attr "type" "halfmul")])
1537 (define_insn "*mullhwuc"
1538   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1539         (compare:CC (mult:SI (zero_extend:SI
1540                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1541                              (zero_extend:SI
1542                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1543                     (const_int 0)))
1544    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1545         (mult:SI (zero_extend:SI
1546                   (match_dup 1))
1547                  (zero_extend:SI
1548                   (match_dup 2))))]
1549   "TARGET_MULHW"
1550   "mullhwu. %0,%1,%2"
1551   [(set_attr "type" "halfmul")])
1553 (define_insn "*mullhwu"
1554   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555         (mult:SI (zero_extend:SI
1556                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1557                  (zero_extend:SI
1558                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1559   "TARGET_MULHW"
1560   "mullhwu %0,%1,%2"
1561   [(set_attr "type" "halfmul")])
1563 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1564 (define_insn "dlmzb"
1565   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1566         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1567                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1568                    UNSPEC_DLMZB_CR))
1569    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1570         (unspec:SI [(match_dup 1)
1571                     (match_dup 2)]
1572                    UNSPEC_DLMZB))]
1573   "TARGET_DLMZB"
1574   "dlmzb. %0,%1,%2")
1576 (define_expand "strlensi"
1577   [(set (match_operand:SI 0 "gpc_reg_operand")
1578         (unspec:SI [(match_operand:BLK 1 "general_operand")
1579                     (match_operand:QI 2 "const_int_operand")
1580                     (match_operand 3 "const_int_operand")]
1581                    UNSPEC_DLMZB_STRLEN))
1582    (clobber (match_scratch:CC 4))]
1583   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1585   rtx result = operands[0];
1586   rtx src = operands[1];
1587   rtx search_char = operands[2];
1588   rtx align = operands[3];
1589   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1590   rtx loop_label, end_label, mem, cr0, cond;
1591   if (search_char != const0_rtx
1592       || GET_CODE (align) != CONST_INT
1593       || INTVAL (align) < 8)
1594         FAIL;
1595   word1 = gen_reg_rtx (SImode);
1596   word2 = gen_reg_rtx (SImode);
1597   scratch_dlmzb = gen_reg_rtx (SImode);
1598   scratch_string = gen_reg_rtx (Pmode);
1599   loop_label = gen_label_rtx ();
1600   end_label = gen_label_rtx ();
1601   addr = force_reg (Pmode, XEXP (src, 0));
1602   emit_move_insn (scratch_string, addr);
1603   emit_label (loop_label);
1604   mem = change_address (src, SImode, scratch_string);
1605   emit_move_insn (word1, mem);
1606   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1607   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1608   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1609   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1610   emit_jump_insn (gen_rtx_SET (pc_rtx,
1611                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1612                                                      cond,
1613                                                      gen_rtx_LABEL_REF
1614                                                        (VOIDmode,
1615                                                         end_label),
1616                                                      pc_rtx)));
1617   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1618   emit_jump_insn (gen_rtx_SET (pc_rtx,
1619                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1620   emit_barrier ();
1621   emit_label (end_label);
1622   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1623   emit_insn (gen_subsi3 (result, scratch_string, addr));
1624   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1625   DONE;
1628 ;; Fixed-point arithmetic insns.
1630 (define_expand "add<mode>3"
1631   [(set (match_operand:SDI 0 "gpc_reg_operand")
1632         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1633                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1634   ""
1636   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1637     {
1638       rtx lo0 = gen_lowpart (SImode, operands[0]);
1639       rtx lo1 = gen_lowpart (SImode, operands[1]);
1640       rtx lo2 = gen_lowpart (SImode, operands[2]);
1641       rtx hi0 = gen_highpart (SImode, operands[0]);
1642       rtx hi1 = gen_highpart (SImode, operands[1]);
1643       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1645       if (!reg_or_short_operand (lo2, SImode))
1646         lo2 = force_reg (SImode, lo2);
1647       if (!adde_operand (hi2, SImode))
1648         hi2 = force_reg (SImode, hi2);
1650       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1651       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1652       DONE;
1653     }
1655   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1656     {
1657       rtx tmp = ((!can_create_pseudo_p ()
1658                   || rtx_equal_p (operands[0], operands[1]))
1659                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1661       /* Adding a constant to r0 is not a valid insn, so use a different
1662          strategy in that case.  */
1663       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1664         {
1665           if (operands[0] == operands[1])
1666             FAIL;
1667           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1668           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1669           DONE;
1670         }
1672       HOST_WIDE_INT val = INTVAL (operands[2]);
1673       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1674       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1676       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1677         FAIL;
1679       /* The ordering here is important for the prolog expander.
1680          When space is allocated from the stack, adding 'low' first may
1681          produce a temporary deallocation (which would be bad).  */
1682       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1683       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1684       DONE;
1685     }
1688 (define_insn "*add<mode>3"
1689   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1690         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1691                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1692   ""
1693   "@
1694    add %0,%1,%2
1695    addi %0,%1,%2
1696    addis %0,%1,%v2"
1697   [(set_attr "type" "add")])
1699 (define_insn "addsi3_high"
1700   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1701         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1702                  (high:SI (match_operand 2 "" ""))))]
1703   "TARGET_MACHO && !TARGET_64BIT"
1704   "addis %0,%1,ha16(%2)"
1705   [(set_attr "type" "add")])
1707 (define_insn_and_split "*add<mode>3_dot"
1708   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1709         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1710                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1711                     (const_int 0)))
1712    (clobber (match_scratch:GPR 0 "=r,r"))]
1713   "<MODE>mode == Pmode"
1714   "@
1715    add. %0,%1,%2
1716    #"
1717   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1718   [(set (match_dup 0)
1719         (plus:GPR (match_dup 1)
1720                  (match_dup 2)))
1721    (set (match_dup 3)
1722         (compare:CC (match_dup 0)
1723                     (const_int 0)))]
1724   ""
1725   [(set_attr "type" "add")
1726    (set_attr "dot" "yes")
1727    (set_attr "length" "4,8")])
1729 (define_insn_and_split "*add<mode>3_dot2"
1730   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1731         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1732                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1733                     (const_int 0)))
1734    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1735         (plus:GPR (match_dup 1)
1736                   (match_dup 2)))]
1737   "<MODE>mode == Pmode"
1738   "@
1739    add. %0,%1,%2
1740    #"
1741   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1742   [(set (match_dup 0)
1743         (plus:GPR (match_dup 1)
1744                   (match_dup 2)))
1745    (set (match_dup 3)
1746         (compare:CC (match_dup 0)
1747                     (const_int 0)))]
1748   ""
1749   [(set_attr "type" "add")
1750    (set_attr "dot" "yes")
1751    (set_attr "length" "4,8")])
1753 (define_insn_and_split "*add<mode>3_imm_dot"
1754   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1755         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1756                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1757                     (const_int 0)))
1758    (clobber (match_scratch:GPR 0 "=r,r"))
1759    (clobber (reg:GPR CA_REGNO))]
1760   "<MODE>mode == Pmode"
1761   "@
1762    addic. %0,%1,%2
1763    #"
1764   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1765   [(set (match_dup 0)
1766         (plus:GPR (match_dup 1)
1767                   (match_dup 2)))
1768    (set (match_dup 3)
1769         (compare:CC (match_dup 0)
1770                     (const_int 0)))]
1771   ""
1772   [(set_attr "type" "add")
1773    (set_attr "dot" "yes")
1774    (set_attr "length" "4,8")])
1776 (define_insn_and_split "*add<mode>3_imm_dot2"
1777   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1778         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1779                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1780                     (const_int 0)))
1781    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1782         (plus:GPR (match_dup 1)
1783                   (match_dup 2)))
1784    (clobber (reg:GPR CA_REGNO))]
1785   "<MODE>mode == Pmode"
1786   "@
1787    addic. %0,%1,%2
1788    #"
1789   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1790   [(set (match_dup 0)
1791         (plus:GPR (match_dup 1)
1792                   (match_dup 2)))
1793    (set (match_dup 3)
1794         (compare:CC (match_dup 0)
1795                     (const_int 0)))]
1796   ""
1797   [(set_attr "type" "add")
1798    (set_attr "dot" "yes")
1799    (set_attr "length" "4,8")])
1801 ;; Split an add that we can't do in one insn into two insns, each of which
1802 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1803 ;; add should be last in case the result gets used in an address.
1805 (define_split
1806   [(set (match_operand:GPR 0 "gpc_reg_operand")
1807         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1808                   (match_operand:GPR 2 "non_add_cint_operand")))]
1809   ""
1810   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1811    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1813   HOST_WIDE_INT val = INTVAL (operands[2]);
1814   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1815   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1817   operands[4] = GEN_INT (low);
1818   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1819     operands[3] = GEN_INT (rest);
1820   else if (can_create_pseudo_p ())
1821     {
1822       operands[3] = gen_reg_rtx (DImode);
1823       emit_move_insn (operands[3], operands[2]);
1824       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1825       DONE;
1826     }
1827   else
1828     FAIL;
1832 (define_insn "add<mode>3_carry"
1833   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1834         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1835                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1836    (set (reg:P CA_REGNO)
1837         (ltu:P (plus:P (match_dup 1)
1838                        (match_dup 2))
1839                (match_dup 1)))]
1840   ""
1841   "add%I2c %0,%1,%2"
1842   [(set_attr "type" "add")])
1844 (define_insn "*add<mode>3_imm_carry_pos"
1845   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1846         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1847                 (match_operand:P 2 "short_cint_operand" "n")))
1848    (set (reg:P CA_REGNO)
1849         (geu:P (match_dup 1)
1850                (match_operand:P 3 "const_int_operand" "n")))]
1851   "INTVAL (operands[2]) > 0
1852    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1853   "addic %0,%1,%2"
1854   [(set_attr "type" "add")])
1856 (define_insn "*add<mode>3_imm_carry_0"
1857   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1858         (match_operand:P 1 "gpc_reg_operand" "r"))
1859    (set (reg:P CA_REGNO)
1860         (const_int 0))]
1861   ""
1862   "addic %0,%1,0"
1863   [(set_attr "type" "add")])
1865 (define_insn "*add<mode>3_imm_carry_m1"
1866   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1867         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1868                 (const_int -1)))
1869    (set (reg:P CA_REGNO)
1870         (ne:P (match_dup 1)
1871               (const_int 0)))]
1872   ""
1873   "addic %0,%1,-1"
1874   [(set_attr "type" "add")])
1876 (define_insn "*add<mode>3_imm_carry_neg"
1877   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1878         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1879                 (match_operand:P 2 "short_cint_operand" "n")))
1880    (set (reg:P CA_REGNO)
1881         (gtu:P (match_dup 1)
1882                (match_operand:P 3 "const_int_operand" "n")))]
1883   "INTVAL (operands[2]) < 0
1884    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1885   "addic %0,%1,%2"
1886   [(set_attr "type" "add")])
1889 (define_expand "add<mode>3_carry_in"
1890   [(parallel [
1891      (set (match_operand:GPR 0 "gpc_reg_operand")
1892           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1893                               (match_operand:GPR 2 "adde_operand"))
1894                     (reg:GPR CA_REGNO)))
1895      (clobber (reg:GPR CA_REGNO))])]
1896   ""
1898   if (operands[2] == const0_rtx)
1899     {
1900       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1901       DONE;
1902     }
1903   if (operands[2] == constm1_rtx)
1904     {
1905       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1906       DONE;
1907     }
1910 (define_insn "*add<mode>3_carry_in_internal"
1911   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1912         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1913                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1914                   (reg:GPR CA_REGNO)))
1915    (clobber (reg:GPR CA_REGNO))]
1916   ""
1917   "adde %0,%1,%2"
1918   [(set_attr "type" "add")])
1920 (define_insn "*add<mode>3_carry_in_internal2"
1921   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1922         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1923                             (reg:GPR CA_REGNO))
1924                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1925    (clobber (reg:GPR CA_REGNO))]
1926   ""
1927   "adde %0,%1,%2"
1928   [(set_attr "type" "add")])
1930 (define_insn "add<mode>3_carry_in_0"
1931   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1932         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1933                   (reg:GPR CA_REGNO)))
1934    (clobber (reg:GPR CA_REGNO))]
1935   ""
1936   "addze %0,%1"
1937   [(set_attr "type" "add")])
1939 (define_insn "add<mode>3_carry_in_m1"
1940   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1941         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1942                             (reg:GPR CA_REGNO))
1943                   (const_int -1)))
1944    (clobber (reg:GPR CA_REGNO))]
1945   ""
1946   "addme %0,%1"
1947   [(set_attr "type" "add")])
1950 (define_expand "one_cmpl<mode>2"
1951   [(set (match_operand:SDI 0 "gpc_reg_operand")
1952         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1953   ""
1955   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1956     {
1957       rs6000_split_logical (operands, NOT, false, false, false);
1958       DONE;
1959     }
1962 (define_insn "*one_cmpl<mode>2"
1963   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1964         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1965   ""
1966   "not %0,%1")
1968 (define_insn_and_split "*one_cmpl<mode>2_dot"
1969   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1970         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1971                     (const_int 0)))
1972    (clobber (match_scratch:GPR 0 "=r,r"))]
1973   "<MODE>mode == Pmode"
1974   "@
1975    not. %0,%1
1976    #"
1977   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1978   [(set (match_dup 0)
1979         (not:GPR (match_dup 1)))
1980    (set (match_dup 2)
1981         (compare:CC (match_dup 0)
1982                     (const_int 0)))]
1983   ""
1984   [(set_attr "type" "logical")
1985    (set_attr "dot" "yes")
1986    (set_attr "length" "4,8")])
1988 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1989   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1990         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1991                     (const_int 0)))
1992    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1993         (not:GPR (match_dup 1)))]
1994   "<MODE>mode == Pmode"
1995   "@
1996    not. %0,%1
1997    #"
1998   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1999   [(set (match_dup 0)
2000         (not:GPR (match_dup 1)))
2001    (set (match_dup 2)
2002         (compare:CC (match_dup 0)
2003                     (const_int 0)))]
2004   ""
2005   [(set_attr "type" "logical")
2006    (set_attr "dot" "yes")
2007    (set_attr "length" "4,8")])
2010 (define_expand "sub<mode>3"
2011   [(set (match_operand:SDI 0 "gpc_reg_operand")
2012         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2013                    (match_operand:SDI 2 "gpc_reg_operand")))]
2014   ""
2016   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2017     {
2018       rtx lo0 = gen_lowpart (SImode, operands[0]);
2019       rtx lo1 = gen_lowpart (SImode, operands[1]);
2020       rtx lo2 = gen_lowpart (SImode, operands[2]);
2021       rtx hi0 = gen_highpart (SImode, operands[0]);
2022       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2023       rtx hi2 = gen_highpart (SImode, operands[2]);
2025       if (!reg_or_short_operand (lo1, SImode))
2026         lo1 = force_reg (SImode, lo1);
2027       if (!adde_operand (hi1, SImode))
2028         hi1 = force_reg (SImode, hi1);
2030       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2031       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2032       DONE;
2033     }
2035   if (short_cint_operand (operands[1], <MODE>mode))
2036     {
2037       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2038       DONE;
2039     }
2042 (define_insn "*subf<mode>3"
2043   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2044         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2045                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2046   ""
2047   "subf %0,%1,%2"
2048   [(set_attr "type" "add")])
2050 (define_insn_and_split "*subf<mode>3_dot"
2051   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2052         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2053                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2054                     (const_int 0)))
2055    (clobber (match_scratch:GPR 0 "=r,r"))]
2056   "<MODE>mode == Pmode"
2057   "@
2058    subf. %0,%1,%2
2059    #"
2060   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2061   [(set (match_dup 0)
2062         (minus:GPR (match_dup 2)
2063                    (match_dup 1)))
2064    (set (match_dup 3)
2065         (compare:CC (match_dup 0)
2066                     (const_int 0)))]
2067   ""
2068   [(set_attr "type" "add")
2069    (set_attr "dot" "yes")
2070    (set_attr "length" "4,8")])
2072 (define_insn_and_split "*subf<mode>3_dot2"
2073   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2074         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2075                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2076                     (const_int 0)))
2077    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2078         (minus:GPR (match_dup 2)
2079                    (match_dup 1)))]
2080   "<MODE>mode == Pmode"
2081   "@
2082    subf. %0,%1,%2
2083    #"
2084   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2085   [(set (match_dup 0)
2086         (minus:GPR (match_dup 2)
2087                    (match_dup 1)))
2088    (set (match_dup 3)
2089         (compare:CC (match_dup 0)
2090                     (const_int 0)))]
2091   ""
2092   [(set_attr "type" "add")
2093    (set_attr "dot" "yes")
2094    (set_attr "length" "4,8")])
2096 (define_insn "subf<mode>3_imm"
2097   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2098         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2099                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2100    (clobber (reg:GPR CA_REGNO))]
2101   ""
2102   "subfic %0,%1,%2"
2103   [(set_attr "type" "add")])
2105 (define_insn_and_split "subf<mode>3_carry_dot2"
2106   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2107         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2108                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2109                     (const_int 0)))
2110    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2111         (minus:P (match_dup 2)
2112                    (match_dup 1)))
2113    (set (reg:P CA_REGNO)
2114         (leu:P (match_dup 1)
2115                (match_dup 2)))]
2116   "<MODE>mode == Pmode"
2117   "@
2118    subfc. %0,%1,%2
2119    #"
2120   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2121   [(parallel [(set (match_dup 0)
2122                    (minus:P (match_dup 2)
2123                             (match_dup 1)))
2124               (set (reg:P CA_REGNO)
2125                    (leu:P (match_dup 1)
2126                           (match_dup 2)))])
2127    (set (match_dup 3)
2128         (compare:CC (match_dup 0)
2129                     (const_int 0)))]
2130   ""
2131   [(set_attr "type" "add")
2132    (set_attr "dot" "yes")
2133    (set_attr "length" "4,8")])
2135 (define_insn "subf<mode>3_carry"
2136   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2137         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2138                  (match_operand:P 1 "gpc_reg_operand" "r")))
2139    (set (reg:P CA_REGNO)
2140         (leu:P (match_dup 1)
2141                (match_dup 2)))]
2142   ""
2143   "subf%I2c %0,%1,%2"
2144   [(set_attr "type" "add")])
2146 (define_insn "*subf<mode>3_imm_carry_0"
2147   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2148         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2149    (set (reg:P CA_REGNO)
2150         (eq:P (match_dup 1)
2151               (const_int 0)))]
2152   ""
2153   "subfic %0,%1,0"
2154   [(set_attr "type" "add")])
2156 (define_insn "*subf<mode>3_imm_carry_m1"
2157   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2158         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2159    (set (reg:P CA_REGNO)
2160         (const_int 1))]
2161   ""
2162   "subfic %0,%1,-1"
2163   [(set_attr "type" "add")])
2166 (define_expand "subf<mode>3_carry_in"
2167   [(parallel [
2168      (set (match_operand:GPR 0 "gpc_reg_operand")
2169           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2170                               (reg:GPR CA_REGNO))
2171                     (match_operand:GPR 2 "adde_operand")))
2172      (clobber (reg:GPR CA_REGNO))])]
2173   ""
2175   if (operands[2] == const0_rtx)
2176     {
2177       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2178       DONE;
2179     }
2180   if (operands[2] == constm1_rtx)
2181     {
2182       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2183       DONE;
2184     }
2187 (define_insn "*subf<mode>3_carry_in_internal"
2188   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2190                             (reg:GPR CA_REGNO))
2191                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2192    (clobber (reg:GPR CA_REGNO))]
2193   ""
2194   "subfe %0,%1,%2"
2195   [(set_attr "type" "add")])
2197 (define_insn "subf<mode>3_carry_in_0"
2198   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2200                   (reg:GPR CA_REGNO)))
2201    (clobber (reg:GPR CA_REGNO))]
2202   ""
2203   "subfze %0,%1"
2204   [(set_attr "type" "add")])
2206 (define_insn "subf<mode>3_carry_in_m1"
2207   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2208         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2209                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2210                   (const_int -2)))
2211    (clobber (reg:GPR CA_REGNO))]
2212   ""
2213   "subfme %0,%1"
2214   [(set_attr "type" "add")])
2216 (define_insn "subf<mode>3_carry_in_xx"
2217   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2218         (plus:GPR (reg:GPR CA_REGNO)
2219                   (const_int -1)))
2220    (clobber (reg:GPR CA_REGNO))]
2221   ""
2222   "subfe %0,%0,%0"
2223   [(set_attr "type" "add")])
2226 (define_insn "neg<mode>2"
2227   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2228         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2229   ""
2230   "neg %0,%1"
2231   [(set_attr "type" "add")])
2233 (define_insn_and_split "*neg<mode>2_dot"
2234   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2235         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2236                     (const_int 0)))
2237    (clobber (match_scratch:GPR 0 "=r,r"))]
2238   "<MODE>mode == Pmode"
2239   "@
2240    neg. %0,%1
2241    #"
2242   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2243   [(set (match_dup 0)
2244         (neg:GPR (match_dup 1)))
2245    (set (match_dup 2)
2246         (compare:CC (match_dup 0)
2247                     (const_int 0)))]
2248   ""
2249   [(set_attr "type" "add")
2250    (set_attr "dot" "yes")
2251    (set_attr "length" "4,8")])
2253 (define_insn_and_split "*neg<mode>2_dot2"
2254   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2255         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2256                     (const_int 0)))
2257    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2258         (neg:GPR (match_dup 1)))]
2259   "<MODE>mode == Pmode"
2260   "@
2261    neg. %0,%1
2262    #"
2263   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2264   [(set (match_dup 0)
2265         (neg:GPR (match_dup 1)))
2266    (set (match_dup 2)
2267         (compare:CC (match_dup 0)
2268                     (const_int 0)))]
2269   ""
2270   [(set_attr "type" "add")
2271    (set_attr "dot" "yes")
2272    (set_attr "length" "4,8")])
2275 (define_insn "clz<mode>2"
2276   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2277         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2278   ""
2279   "cntlz<wd> %0,%1"
2280   [(set_attr "type" "cntlz")])
2282 (define_expand "ctz<mode>2"
2283    [(set (match_operand:GPR 0 "gpc_reg_operand")
2284          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2285   ""
2287   if (TARGET_CTZ)
2288     {
2289       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2290       DONE;
2291     }
2293   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2294   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2295   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2297   if (TARGET_POPCNTD)
2298     {
2299       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2300       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2301       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2302       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2303     }
2304   else
2305     {
2306       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2307       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2308       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2309       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2310     }
2312   DONE;
2315 (define_insn "ctz<mode>2_hw"
2316   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2317         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2318   "TARGET_CTZ"
2319   "cnttz<wd> %0,%1"
2320   [(set_attr "type" "cntlz")])
2322 (define_expand "ffs<mode>2"
2323   [(set (match_operand:GPR 0 "gpc_reg_operand")
2324         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2325   ""
2327   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2328   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2329   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2330   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2331   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2332   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2333   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2334   DONE;
2338 (define_expand "popcount<mode>2"
2339   [(set (match_operand:GPR 0 "gpc_reg_operand")
2340         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2341   "TARGET_POPCNTB || TARGET_POPCNTD"
2343   rs6000_emit_popcount (operands[0], operands[1]);
2344   DONE;
2347 (define_insn "popcntb<mode>2"
2348   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2349         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2350                     UNSPEC_POPCNTB))]
2351   "TARGET_POPCNTB"
2352   "popcntb %0,%1"
2353   [(set_attr "type" "popcnt")])
2355 (define_insn "popcntd<mode>2"
2356   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2357         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2358   "TARGET_POPCNTD"
2359   "popcnt<wd> %0,%1"
2360   [(set_attr "type" "popcnt")])
2363 (define_expand "parity<mode>2"
2364   [(set (match_operand:GPR 0 "gpc_reg_operand")
2365         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2366   "TARGET_POPCNTB"
2368   rs6000_emit_parity (operands[0], operands[1]);
2369   DONE;
2372 (define_insn "parity<mode>2_cmpb"
2373   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2374         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2375   "TARGET_CMPB && TARGET_POPCNTB"
2376   "prty<wd> %0,%1"
2377   [(set_attr "type" "popcnt")])
2379 (define_insn "cmpb<mode>3"
2380   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2381         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2382                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2383   "TARGET_CMPB"
2384   "cmpb %0,%1,%2"
2385   [(set_attr "type" "cmp")])
2387 ;; Since the hardware zeros the upper part of the register, save generating the
2388 ;; AND immediate if we are converting to unsigned
2389 (define_insn "*bswap<mode>2_extenddi"
2390   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2391         (zero_extend:DI
2392          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2393   "TARGET_POWERPC64"
2394   "l<wd>brx %0,%y1"
2395   [(set_attr "length" "4")
2396    (set_attr "type" "load")])
2398 (define_insn "*bswaphi2_extendsi"
2399   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2400         (zero_extend:SI
2401          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2402   ""
2403   "lhbrx %0,%y1"
2404   [(set_attr "length" "4")
2405    (set_attr "type" "load")])
2407 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2408 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2409 ;; load with byte swap, which can be slower than doing it in the registers.  It
2410 ;; also prevents certain failures with the RELOAD register allocator.
2412 (define_expand "bswap<mode>2"
2413   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2414    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2415   ""
2417   rtx dest = operands[0];
2418   rtx src = operands[1];
2420   if (!REG_P (dest) && !REG_P (src))
2421     src = force_reg (<MODE>mode, src);
2423   if (MEM_P (src))
2424     emit_insn (gen_bswap<mode>2_load (dest, src));
2425   else if (MEM_P (dest))
2426     emit_insn (gen_bswap<mode>2_store (dest, src));
2427   else
2428     emit_insn (gen_bswap<mode>2_reg (dest, src));
2429   DONE;
2432 (define_insn "bswap<mode>2_load"
2433   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2434         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2435   ""
2436   "l<wd>brx %0,%y1"
2437   [(set_attr "type" "load")])
2439 (define_insn "bswap<mode>2_store"
2440   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2441         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2442   ""
2443   "st<wd>brx %1,%y0"
2444   [(set_attr "type" "store")])
2446 (define_insn_and_split "bswaphi2_reg"
2447   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2448         (bswap:HI
2449          (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2450    (clobber (match_scratch:SI 2 "=&r,X"))]
2451   ""
2452   "@
2453    #
2454    xxbrh %x0,%x1"
2455   "reload_completed && int_reg_operand (operands[0], HImode)"
2456   [(set (match_dup 3)
2457         (and:SI (lshiftrt:SI (match_dup 4)
2458                              (const_int 8))
2459                 (const_int 255)))
2460    (set (match_dup 2)
2461         (and:SI (ashift:SI (match_dup 4)
2462                            (const_int 8))
2463                 (const_int 65280)))             ;; 0xff00
2464    (set (match_dup 3)
2465         (ior:SI (match_dup 3)
2466                 (match_dup 2)))]
2468   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2469   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2471   [(set_attr "length" "12,4")
2472    (set_attr "type" "*,vecperm")])
2474 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2475 ;; zero_extract insns do not change for -mlittle.
2476 (define_insn_and_split "bswapsi2_reg"
2477   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2478         (bswap:SI
2479          (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2480   ""
2481   "@
2482    #
2483    xxbrw %x0,%x1"
2484   "reload_completed && int_reg_operand (operands[0], SImode)"
2485   [(set (match_dup 0)                                   ; DABC
2486         (rotate:SI (match_dup 1)
2487                    (const_int 24)))
2488    (set (match_dup 0)                                   ; DCBC
2489         (ior:SI (and:SI (ashift:SI (match_dup 1)
2490                                    (const_int 8))
2491                         (const_int 16711680))
2492                 (and:SI (match_dup 0)
2493                         (const_int -16711681))))
2494    (set (match_dup 0)                                   ; DCBA
2495         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2496                                      (const_int 24))
2497                         (const_int 255))
2498                 (and:SI (match_dup 0)
2499                         (const_int -256))))]
2500   ""
2501   [(set_attr "length" "12,4")
2502    (set_attr "type" "*,vecperm")])
2504 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2505 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2506 ;; complex code.
2508 (define_expand "bswapdi2"
2509   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2510                    (bswap:DI
2511                     (match_operand:DI 1 "reg_or_mem_operand")))
2512               (clobber (match_scratch:DI 2))
2513               (clobber (match_scratch:DI 3))])]
2514   ""
2516   rtx dest = operands[0];
2517   rtx src = operands[1];
2519   if (!REG_P (dest) && !REG_P (src))
2520     operands[1] = src = force_reg (DImode, src);
2522   if (TARGET_POWERPC64 && TARGET_LDBRX)
2523     {
2524       if (MEM_P (src))
2525         emit_insn (gen_bswapdi2_load (dest, src));
2526       else if (MEM_P (dest))
2527         emit_insn (gen_bswapdi2_store (dest, src));
2528       else if (TARGET_P9_VECTOR)
2529         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2530       else
2531         emit_insn (gen_bswapdi2_reg (dest, src));
2532       DONE;
2533     }
2535   if (!TARGET_POWERPC64)
2536     {
2537       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2538          that uses 64-bit registers needs the same scratch registers as 64-bit
2539          mode.  */
2540       emit_insn (gen_bswapdi2_32bit (dest, src));
2541       DONE;
2542     }
2545 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2546 (define_insn "bswapdi2_load"
2547   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2548         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2549   "TARGET_POWERPC64 && TARGET_LDBRX"
2550   "ldbrx %0,%y1"
2551   [(set_attr "type" "load")])
2553 (define_insn "bswapdi2_store"
2554   [(set (match_operand:DI 0 "memory_operand" "=Z")
2555         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2556   "TARGET_POWERPC64 && TARGET_LDBRX"
2557   "stdbrx %1,%y0"
2558   [(set_attr "type" "store")])
2560 (define_insn "bswapdi2_xxbrd"
2561   [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2562         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2563   "TARGET_P9_VECTOR"
2564   "xxbrd %x0,%x1"
2565   [(set_attr "type" "vecperm")])
2567 (define_insn "bswapdi2_reg"
2568   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2569         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2570    (clobber (match_scratch:DI 2 "=&r"))
2571    (clobber (match_scratch:DI 3 "=&r"))]
2572   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2573   "#"
2574   [(set_attr "length" "36")])
2576 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2577 (define_insn "*bswapdi2_64bit"
2578   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2579         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2580    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2581    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2582   "TARGET_POWERPC64 && !TARGET_LDBRX
2583    && (REG_P (operands[0]) || REG_P (operands[1]))
2584    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2585    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2586   "#"
2587   [(set_attr "length" "16,12,36")])
2589 (define_split
2590   [(set (match_operand:DI 0 "gpc_reg_operand")
2591         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2592    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2593    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2594   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2595   [(const_int 0)]
2597   rtx dest   = operands[0];
2598   rtx src    = operands[1];
2599   rtx op2    = operands[2];
2600   rtx op3    = operands[3];
2601   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2602                                     BYTES_BIG_ENDIAN ? 4 : 0);
2603   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2604                                      BYTES_BIG_ENDIAN ? 4 : 0);
2605   rtx addr1;
2606   rtx addr2;
2607   rtx word1;
2608   rtx word2;
2610   addr1 = XEXP (src, 0);
2611   if (GET_CODE (addr1) == PLUS)
2612     {
2613       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2614       if (TARGET_AVOID_XFORM)
2615         {
2616           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2617           addr2 = op2;
2618         }
2619       else
2620         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2621     }
2622   else if (TARGET_AVOID_XFORM)
2623     {
2624       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2625       addr2 = op2;
2626     }
2627   else
2628     {
2629       emit_move_insn (op2, GEN_INT (4));
2630       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2631     }
2633   word1 = change_address (src, SImode, addr1);
2634   word2 = change_address (src, SImode, addr2);
2636   if (BYTES_BIG_ENDIAN)
2637     {
2638       emit_insn (gen_bswapsi2 (op3_32, word2));
2639       emit_insn (gen_bswapsi2 (dest_32, word1));
2640     }
2641   else
2642     {
2643       emit_insn (gen_bswapsi2 (op3_32, word1));
2644       emit_insn (gen_bswapsi2 (dest_32, word2));
2645     }
2647   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2648   emit_insn (gen_iordi3 (dest, dest, op3));
2649   DONE;
2652 (define_split
2653   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2654         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2655    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2656    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2657   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2658   [(const_int 0)]
2660   rtx dest   = operands[0];
2661   rtx src    = operands[1];
2662   rtx op2    = operands[2];
2663   rtx op3    = operands[3];
2664   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2665                                     BYTES_BIG_ENDIAN ? 4 : 0);
2666   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2667                                     BYTES_BIG_ENDIAN ? 4 : 0);
2668   rtx addr1;
2669   rtx addr2;
2670   rtx word1;
2671   rtx word2;
2673   addr1 = XEXP (dest, 0);
2674   if (GET_CODE (addr1) == PLUS)
2675     {
2676       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2677       if (TARGET_AVOID_XFORM)
2678         {
2679           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2680           addr2 = op2;
2681         }
2682       else
2683         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2684     }
2685   else if (TARGET_AVOID_XFORM)
2686     {
2687       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2688       addr2 = op2;
2689     }
2690   else
2691     {
2692       emit_move_insn (op2, GEN_INT (4));
2693       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2694     }
2696   word1 = change_address (dest, SImode, addr1);
2697   word2 = change_address (dest, SImode, addr2);
2699   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2701   if (BYTES_BIG_ENDIAN)
2702     {
2703       emit_insn (gen_bswapsi2 (word1, src_si));
2704       emit_insn (gen_bswapsi2 (word2, op3_si));
2705     }
2706   else
2707     {
2708       emit_insn (gen_bswapsi2 (word2, src_si));
2709       emit_insn (gen_bswapsi2 (word1, op3_si));
2710     }
2711   DONE;
2714 (define_split
2715   [(set (match_operand:DI 0 "gpc_reg_operand")
2716         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2717    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2718    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2719   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2720   [(const_int 0)]
2722   rtx dest    = operands[0];
2723   rtx src     = operands[1];
2724   rtx op2     = operands[2];
2725   rtx op3     = operands[3];
2726   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2727   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2728   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2729   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2730   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2732   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2733   emit_insn (gen_bswapsi2 (dest_si, src_si));
2734   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2735   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2736   emit_insn (gen_iordi3 (dest, dest, op3));
2737   DONE;
2740 (define_insn "bswapdi2_32bit"
2741   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2742         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2743    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2744   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2745   "#"
2746   [(set_attr "length" "16,12,36")])
2748 (define_split
2749   [(set (match_operand:DI 0 "gpc_reg_operand")
2750         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2751    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2752   "!TARGET_POWERPC64 && reload_completed"
2753   [(const_int 0)]
2755   rtx dest  = operands[0];
2756   rtx src   = operands[1];
2757   rtx op2   = operands[2];
2758   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2759   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2760   rtx addr1;
2761   rtx addr2;
2762   rtx word1;
2763   rtx word2;
2765   addr1 = XEXP (src, 0);
2766   if (GET_CODE (addr1) == PLUS)
2767     {
2768       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2769       if (TARGET_AVOID_XFORM
2770           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2771         {
2772           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2773           addr2 = op2;
2774         }
2775       else
2776         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2777     }
2778   else if (TARGET_AVOID_XFORM
2779            || REGNO (addr1) == REGNO (dest2))
2780     {
2781       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2782       addr2 = op2;
2783     }
2784   else
2785     {
2786       emit_move_insn (op2, GEN_INT (4));
2787       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2788     }
2790   word1 = change_address (src, SImode, addr1);
2791   word2 = change_address (src, SImode, addr2);
2793   emit_insn (gen_bswapsi2 (dest2, word1));
2794   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2795      thus allowing us to omit an early clobber on the output.  */
2796   emit_insn (gen_bswapsi2 (dest1, word2));
2797   DONE;
2800 (define_split
2801   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2802         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2803    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2804   "!TARGET_POWERPC64 && reload_completed"
2805   [(const_int 0)]
2807   rtx dest = operands[0];
2808   rtx src  = operands[1];
2809   rtx op2  = operands[2];
2810   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2811   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2812   rtx addr1;
2813   rtx addr2;
2814   rtx word1;
2815   rtx word2;
2817   addr1 = XEXP (dest, 0);
2818   if (GET_CODE (addr1) == PLUS)
2819     {
2820       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2821       if (TARGET_AVOID_XFORM)
2822         {
2823           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2824           addr2 = op2;
2825         }
2826       else
2827         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2828     }
2829   else if (TARGET_AVOID_XFORM)
2830     {
2831       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2832       addr2 = op2;
2833     }
2834   else
2835     {
2836       emit_move_insn (op2, GEN_INT (4));
2837       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2838     }
2840   word1 = change_address (dest, SImode, addr1);
2841   word2 = change_address (dest, SImode, addr2);
2843   emit_insn (gen_bswapsi2 (word2, src1));
2844   emit_insn (gen_bswapsi2 (word1, src2));
2845   DONE;
2848 (define_split
2849   [(set (match_operand:DI 0 "gpc_reg_operand")
2850         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2851    (clobber (match_operand:SI 2 ""))]
2852   "!TARGET_POWERPC64 && reload_completed"
2853   [(const_int 0)]
2855   rtx dest  = operands[0];
2856   rtx src   = operands[1];
2857   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2858   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2859   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2860   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2862   emit_insn (gen_bswapsi2 (dest1, src2));
2863   emit_insn (gen_bswapsi2 (dest2, src1));
2864   DONE;
2868 (define_insn "mul<mode>3"
2869   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2870         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2871                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2872   ""
2873   "@
2874    mull<wd> %0,%1,%2
2875    mulli %0,%1,%2"
2876    [(set_attr "type" "mul")
2877     (set (attr "size")
2878       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2879                 (const_string "8")
2880              (match_operand:GPR 2 "short_cint_operand")
2881                 (const_string "16")]
2882         (const_string "<bits>")))])
2884 (define_insn_and_split "*mul<mode>3_dot"
2885   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2886         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2887                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2888                     (const_int 0)))
2889    (clobber (match_scratch:GPR 0 "=r,r"))]
2890   "<MODE>mode == Pmode"
2891   "@
2892    mull<wd>. %0,%1,%2
2893    #"
2894   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2895   [(set (match_dup 0)
2896         (mult:GPR (match_dup 1)
2897                   (match_dup 2)))
2898    (set (match_dup 3)
2899         (compare:CC (match_dup 0)
2900                     (const_int 0)))]
2901   ""
2902   [(set_attr "type" "mul")
2903    (set_attr "size" "<bits>")
2904    (set_attr "dot" "yes")
2905    (set_attr "length" "4,8")])
2907 (define_insn_and_split "*mul<mode>3_dot2"
2908   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2909         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2910                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2911                     (const_int 0)))
2912    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2913         (mult:GPR (match_dup 1)
2914                   (match_dup 2)))]
2915   "<MODE>mode == Pmode"
2916   "@
2917    mull<wd>. %0,%1,%2
2918    #"
2919   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2920   [(set (match_dup 0)
2921         (mult:GPR (match_dup 1)
2922                   (match_dup 2)))
2923    (set (match_dup 3)
2924         (compare:CC (match_dup 0)
2925                     (const_int 0)))]
2926   ""
2927   [(set_attr "type" "mul")
2928    (set_attr "size" "<bits>")
2929    (set_attr "dot" "yes")
2930    (set_attr "length" "4,8")])
2933 (define_expand "<su>mul<mode>3_highpart"
2934   [(set (match_operand:GPR 0 "gpc_reg_operand")
2935         (subreg:GPR
2936           (mult:<DMODE> (any_extend:<DMODE>
2937                           (match_operand:GPR 1 "gpc_reg_operand"))
2938                         (any_extend:<DMODE>
2939                           (match_operand:GPR 2 "gpc_reg_operand")))
2940          0))]
2941   ""
2943   if (<MODE>mode == SImode && TARGET_POWERPC64)
2944     {
2945       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2946                                              operands[2]));
2947       DONE;
2948     }
2950   if (!WORDS_BIG_ENDIAN)
2951     {
2952       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2953                                                  operands[2]));
2954       DONE;
2955     }
2958 (define_insn "*<su>mul<mode>3_highpart"
2959   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2960         (subreg:GPR
2961           (mult:<DMODE> (any_extend:<DMODE>
2962                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2963                         (any_extend:<DMODE>
2964                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2965          0))]
2966   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2967   "mulh<wd><u> %0,%1,%2"
2968   [(set_attr "type" "mul")
2969    (set_attr "size" "<bits>")])
2971 (define_insn "<su>mulsi3_highpart_le"
2972   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2973         (subreg:SI
2974           (mult:DI (any_extend:DI
2975                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2976                    (any_extend:DI
2977                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2978          4))]
2979   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2980   "mulhw<u> %0,%1,%2"
2981   [(set_attr "type" "mul")])
2983 (define_insn "<su>muldi3_highpart_le"
2984   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2985         (subreg:DI
2986           (mult:TI (any_extend:TI
2987                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2988                    (any_extend:TI
2989                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2990          8))]
2991   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2992   "mulhd<u> %0,%1,%2"
2993   [(set_attr "type" "mul")
2994    (set_attr "size" "64")])
2996 (define_insn "<su>mulsi3_highpart_64"
2997   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2998         (truncate:SI
2999           (lshiftrt:DI
3000             (mult:DI (any_extend:DI
3001                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3002                      (any_extend:DI
3003                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3004             (const_int 32))))]
3005   "TARGET_POWERPC64"
3006   "mulhw<u> %0,%1,%2"
3007   [(set_attr "type" "mul")])
3009 (define_expand "<u>mul<mode><dmode>3"
3010   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3011         (mult:<DMODE> (any_extend:<DMODE>
3012                         (match_operand:GPR 1 "gpc_reg_operand"))
3013                       (any_extend:<DMODE>
3014                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3015   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3017   rtx l = gen_reg_rtx (<MODE>mode);
3018   rtx h = gen_reg_rtx (<MODE>mode);
3019   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3020   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3021   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3022   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3023   DONE;
3026 (define_insn "*maddld4"
3027   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3028         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3029                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3030                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3031   "TARGET_MADDLD"
3032   "maddld %0,%1,%2,%3"
3033   [(set_attr "type" "mul")])
3035 (define_insn "udiv<mode>3"
3036   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3037         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3038                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3039   ""
3040   "div<wd>u %0,%1,%2"
3041   [(set_attr "type" "div")
3042    (set_attr "size" "<bits>")])
3045 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3046 ;; modulus.  If it isn't a power of two, force operands into register and do
3047 ;; a normal divide.
3048 (define_expand "div<mode>3"
3049   [(set (match_operand:GPR 0 "gpc_reg_operand")
3050         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3051                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3052   ""
3054   if (CONST_INT_P (operands[2])
3055       && INTVAL (operands[2]) > 0
3056       && exact_log2 (INTVAL (operands[2])) >= 0)
3057     {
3058       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3059       DONE;
3060     }
3062   operands[2] = force_reg (<MODE>mode, operands[2]);
3065 (define_insn "*div<mode>3"
3066   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3069   ""
3070   "div<wd> %0,%1,%2"
3071   [(set_attr "type" "div")
3072    (set_attr "size" "<bits>")])
3074 (define_insn "div<mode>3_sra"
3075   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3076         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3077                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3078    (clobber (reg:GPR CA_REGNO))]
3079   ""
3080   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3081   [(set_attr "type" "two")
3082    (set_attr "length" "8")])
3084 (define_insn_and_split "*div<mode>3_sra_dot"
3085   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3086         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3087                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3088                     (const_int 0)))
3089    (clobber (match_scratch:GPR 0 "=r,r"))
3090    (clobber (reg:GPR CA_REGNO))]
3091   "<MODE>mode == Pmode"
3092   "@
3093    sra<wd>i %0,%1,%p2\;addze. %0,%0
3094    #"
3095   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3096   [(parallel [(set (match_dup 0)
3097                    (div:GPR (match_dup 1)
3098                             (match_dup 2)))
3099               (clobber (reg:GPR CA_REGNO))])
3100    (set (match_dup 3)
3101         (compare:CC (match_dup 0)
3102                     (const_int 0)))]
3103   ""
3104   [(set_attr "type" "two")
3105    (set_attr "length" "8,12")
3106    (set_attr "cell_micro" "not")])
3108 (define_insn_and_split "*div<mode>3_sra_dot2"
3109   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3110         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3111                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3112                     (const_int 0)))
3113    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3114         (div:GPR (match_dup 1)
3115                  (match_dup 2)))
3116    (clobber (reg:GPR CA_REGNO))]
3117   "<MODE>mode == Pmode"
3118   "@
3119    sra<wd>i %0,%1,%p2\;addze. %0,%0
3120    #"
3121   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3122   [(parallel [(set (match_dup 0)
3123                    (div:GPR (match_dup 1)
3124                             (match_dup 2)))
3125               (clobber (reg:GPR CA_REGNO))])
3126    (set (match_dup 3)
3127         (compare:CC (match_dup 0)
3128                     (const_int 0)))]
3129   ""
3130   [(set_attr "type" "two")
3131    (set_attr "length" "8,12")
3132    (set_attr "cell_micro" "not")])
3134 (define_expand "mod<mode>3"
3135   [(set (match_operand:GPR 0 "gpc_reg_operand")
3136         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3137                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3138   ""
3140   int i;
3141   rtx temp1;
3142   rtx temp2;
3144   if (GET_CODE (operands[2]) != CONST_INT
3145       || INTVAL (operands[2]) <= 0
3146       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3147     {
3148       if (!TARGET_MODULO)
3149         FAIL;
3151       operands[2] = force_reg (<MODE>mode, operands[2]);
3152     }
3153   else
3154     {
3155       temp1 = gen_reg_rtx (<MODE>mode);
3156       temp2 = gen_reg_rtx (<MODE>mode);
3158       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3159       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3160       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3161       DONE;
3162     }
3165 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3166 ;; mod, prefer putting the result of mod into a different register
3167 (define_insn "*mod<mode>3"
3168   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3169         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3170                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3171   "TARGET_MODULO"
3172   "mods<wd> %0,%1,%2"
3173   [(set_attr "type" "div")
3174    (set_attr "size" "<bits>")])
3177 (define_insn "umod<mode>3"
3178   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3179         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3180                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3181   "TARGET_MODULO"
3182   "modu<wd> %0,%1,%2"
3183   [(set_attr "type" "div")
3184    (set_attr "size" "<bits>")])
3186 ;; On machines with modulo support, do a combined div/mod the old fashioned
3187 ;; method, since the multiply/subtract is faster than doing the mod instruction
3188 ;; after a divide.
3190 (define_peephole2
3191   [(set (match_operand:GPR 0 "gpc_reg_operand")
3192         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3193                  (match_operand:GPR 2 "gpc_reg_operand")))
3194    (set (match_operand:GPR 3 "gpc_reg_operand")
3195         (mod:GPR (match_dup 1)
3196                  (match_dup 2)))]
3197   "TARGET_MODULO
3198    && ! reg_mentioned_p (operands[0], operands[1])
3199    && ! reg_mentioned_p (operands[0], operands[2])
3200    && ! reg_mentioned_p (operands[3], operands[1])
3201    && ! reg_mentioned_p (operands[3], operands[2])"
3202   [(set (match_dup 0)
3203         (div:GPR (match_dup 1)
3204                  (match_dup 2)))
3205    (set (match_dup 3)
3206         (mult:GPR (match_dup 0)
3207                   (match_dup 2)))
3208    (set (match_dup 3)
3209         (minus:GPR (match_dup 1)
3210                    (match_dup 3)))])
3212 (define_peephole2
3213   [(set (match_operand:GPR 0 "gpc_reg_operand")
3214         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3215                   (match_operand:GPR 2 "gpc_reg_operand")))
3216    (set (match_operand:GPR 3 "gpc_reg_operand")
3217         (umod:GPR (match_dup 1)
3218                   (match_dup 2)))]
3219   "TARGET_MODULO
3220    && ! reg_mentioned_p (operands[0], operands[1])
3221    && ! reg_mentioned_p (operands[0], operands[2])
3222    && ! reg_mentioned_p (operands[3], operands[1])
3223    && ! reg_mentioned_p (operands[3], operands[2])"
3224   [(set (match_dup 0)
3225         (udiv:GPR (match_dup 1)
3226                   (match_dup 2)))
3227    (set (match_dup 3)
3228         (mult:GPR (match_dup 0)
3229                   (match_dup 2)))
3230    (set (match_dup 3)
3231         (minus:GPR (match_dup 1)
3232                    (match_dup 3)))])
3235 ;; Logical instructions
3236 ;; The logical instructions are mostly combined by using match_operator,
3237 ;; but the plain AND insns are somewhat different because there is no
3238 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3239 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3241 (define_expand "and<mode>3"
3242   [(set (match_operand:SDI 0 "gpc_reg_operand")
3243         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3244                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3245   ""
3247   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3248     {
3249       rs6000_split_logical (operands, AND, false, false, false);
3250       DONE;
3251     }
3253   if (CONST_INT_P (operands[2]))
3254     {
3255       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3256         {
3257           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3258           DONE;
3259         }
3261       if (logical_const_operand (operands[2], <MODE>mode))
3262         {
3263           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3264           DONE;
3265         }
3267       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3268         {
3269           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3270           DONE;
3271         }
3273       operands[2] = force_reg (<MODE>mode, operands[2]);
3274     }
3278 (define_insn "and<mode>3_imm"
3279   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3280         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3281                  (match_operand:GPR 2 "logical_const_operand" "n")))
3282    (clobber (match_scratch:CC 3 "=x"))]
3283   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3284   "andi%e2. %0,%1,%u2"
3285   [(set_attr "type" "logical")
3286    (set_attr "dot" "yes")])
3288 (define_insn_and_split "*and<mode>3_imm_dot"
3289   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3290         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3291                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3292                     (const_int 0)))
3293    (clobber (match_scratch:GPR 0 "=r,r"))
3294    (clobber (match_scratch:CC 4 "=X,x"))]
3295   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3296    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3297   "@
3298    andi%e2. %0,%1,%u2
3299    #"
3300   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3301   [(parallel [(set (match_dup 0)
3302                    (and:GPR (match_dup 1)
3303                             (match_dup 2)))
3304               (clobber (match_dup 4))])
3305    (set (match_dup 3)
3306         (compare:CC (match_dup 0)
3307                     (const_int 0)))]
3308   ""
3309   [(set_attr "type" "logical")
3310    (set_attr "dot" "yes")
3311    (set_attr "length" "4,8")])
3313 (define_insn_and_split "*and<mode>3_imm_dot2"
3314   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3315         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3316                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3317                     (const_int 0)))
3318    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3319         (and:GPR (match_dup 1)
3320                  (match_dup 2)))
3321    (clobber (match_scratch:CC 4 "=X,x"))]
3322   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3323    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3324   "@
3325    andi%e2. %0,%1,%u2
3326    #"
3327   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3328   [(parallel [(set (match_dup 0)
3329                    (and:GPR (match_dup 1)
3330                             (match_dup 2)))
3331               (clobber (match_dup 4))])
3332    (set (match_dup 3)
3333         (compare:CC (match_dup 0)
3334                     (const_int 0)))]
3335   ""
3336   [(set_attr "type" "logical")
3337    (set_attr "dot" "yes")
3338    (set_attr "length" "4,8")])
3340 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3341   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3342         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3343                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3344                     (const_int 0)))
3345    (clobber (match_scratch:GPR 0 "=r,r"))]
3346   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3347    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3348   "@
3349    andi%e2. %0,%1,%u2
3350    #"
3351   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3352   [(set (match_dup 0)
3353         (and:GPR (match_dup 1)
3354                  (match_dup 2)))
3355    (set (match_dup 3)
3356         (compare:CC (match_dup 0)
3357                     (const_int 0)))]
3358   ""
3359   [(set_attr "type" "logical")
3360    (set_attr "dot" "yes")
3361    (set_attr "length" "4,8")])
3363 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3364   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3365         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3366                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3367                     (const_int 0)))
3368    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3369         (and:GPR (match_dup 1)
3370                  (match_dup 2)))]
3371   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3372    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3373   "@
3374    andi%e2. %0,%1,%u2
3375    #"
3376   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3377   [(set (match_dup 0)
3378         (and:GPR (match_dup 1)
3379                  (match_dup 2)))
3380    (set (match_dup 3)
3381         (compare:CC (match_dup 0)
3382                     (const_int 0)))]
3383   ""
3384   [(set_attr "type" "logical")
3385    (set_attr "dot" "yes")
3386    (set_attr "length" "4,8")])
3388 (define_insn "*and<mode>3_imm_dot_shifted"
3389   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3390         (compare:CC
3391           (and:GPR
3392             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3393                           (match_operand:SI 4 "const_int_operand" "n"))
3394             (match_operand:GPR 2 "const_int_operand" "n"))
3395           (const_int 0)))
3396    (clobber (match_scratch:GPR 0 "=r"))]
3397   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3398                                    << INTVAL (operands[4])),
3399                           DImode)
3400    && (<MODE>mode == Pmode
3401        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3403   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3404   return "andi%e2. %0,%1,%u2";
3406   [(set_attr "type" "logical")
3407    (set_attr "dot" "yes")])
3410 (define_insn "and<mode>3_mask"
3411   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3412         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3413                  (match_operand:GPR 2 "const_int_operand" "n")))]
3414   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3416   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3418   [(set_attr "type" "shift")])
3420 (define_insn_and_split "*and<mode>3_mask_dot"
3421   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3422         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3423                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3424                     (const_int 0)))
3425    (clobber (match_scratch:GPR 0 "=r,r"))]
3426   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3427    && !logical_const_operand (operands[2], <MODE>mode)
3428    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3430   if (which_alternative == 0)
3431     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3432   else
3433     return "#";
3435   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3436   [(set (match_dup 0)
3437         (and:GPR (match_dup 1)
3438                  (match_dup 2)))
3439    (set (match_dup 3)
3440         (compare:CC (match_dup 0)
3441                     (const_int 0)))]
3442   ""
3443   [(set_attr "type" "shift")
3444    (set_attr "dot" "yes")
3445    (set_attr "length" "4,8")])
3447 (define_insn_and_split "*and<mode>3_mask_dot2"
3448   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3449         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3450                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3451                     (const_int 0)))
3452    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3453         (and:GPR (match_dup 1)
3454                  (match_dup 2)))]
3455   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3456    && !logical_const_operand (operands[2], <MODE>mode)
3457    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3459   if (which_alternative == 0)
3460     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3461   else
3462     return "#";
3464   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3465   [(set (match_dup 0)
3466         (and:GPR (match_dup 1)
3467                  (match_dup 2)))
3468    (set (match_dup 3)
3469         (compare:CC (match_dup 0)
3470                     (const_int 0)))]
3471   ""
3472   [(set_attr "type" "shift")
3473    (set_attr "dot" "yes")
3474    (set_attr "length" "4,8")])
3477 (define_insn_and_split "*and<mode>3_2insn"
3478   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3479         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3480                  (match_operand:GPR 2 "const_int_operand" "n")))]
3481   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3482    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3483         || logical_const_operand (operands[2], <MODE>mode))"
3484   "#"
3485   "&& 1"
3486   [(pc)]
3488   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3489   DONE;
3491   [(set_attr "type" "shift")
3492    (set_attr "length" "8")])
3494 (define_insn_and_split "*and<mode>3_2insn_dot"
3495   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3496         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3497                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3498                     (const_int 0)))
3499    (clobber (match_scratch:GPR 0 "=r,r"))]
3500   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3501    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3502    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3503         || logical_const_operand (operands[2], <MODE>mode))"
3504   "#"
3505   "&& reload_completed"
3506   [(pc)]
3508   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3509   DONE;
3511   [(set_attr "type" "shift")
3512    (set_attr "dot" "yes")
3513    (set_attr "length" "8,12")])
3515 (define_insn_and_split "*and<mode>3_2insn_dot2"
3516   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3517         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3518                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3519                     (const_int 0)))
3520    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3521         (and:GPR (match_dup 1)
3522                  (match_dup 2)))]
3523   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3524    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3525    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3526         || logical_const_operand (operands[2], <MODE>mode))"
3527   "#"
3528   "&& reload_completed"
3529   [(pc)]
3531   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3532   DONE;
3534   [(set_attr "type" "shift")
3535    (set_attr "dot" "yes")
3536    (set_attr "length" "8,12")])
3539 (define_expand "<code><mode>3"
3540   [(set (match_operand:SDI 0 "gpc_reg_operand")
3541         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3542                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3543   ""
3545   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3546     {
3547       rs6000_split_logical (operands, <CODE>, false, false, false);
3548       DONE;
3549     }
3551   if (non_logical_cint_operand (operands[2], <MODE>mode))
3552     {
3553       rtx tmp = ((!can_create_pseudo_p ()
3554                   || rtx_equal_p (operands[0], operands[1]))
3555                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3557       HOST_WIDE_INT value = INTVAL (operands[2]);
3558       HOST_WIDE_INT lo = value & 0xffff;
3559       HOST_WIDE_INT hi = value - lo;
3561       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3562       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3563       DONE;
3564     }
3566   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3567     operands[2] = force_reg (<MODE>mode, operands[2]);
3570 (define_split
3571   [(set (match_operand:GPR 0 "gpc_reg_operand")
3572         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3573                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3574   ""
3575   [(set (match_dup 3)
3576         (iorxor:GPR (match_dup 1)
3577                     (match_dup 4)))
3578    (set (match_dup 0)
3579         (iorxor:GPR (match_dup 3)
3580                     (match_dup 5)))]
3582   operands[3] = ((!can_create_pseudo_p ()
3583                   || rtx_equal_p (operands[0], operands[1]))
3584                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3586   HOST_WIDE_INT value = INTVAL (operands[2]);
3587   HOST_WIDE_INT lo = value & 0xffff;
3588   HOST_WIDE_INT hi = value - lo;
3590   operands[4] = GEN_INT (hi);
3591   operands[5] = GEN_INT (lo);
3594 (define_insn "*bool<mode>3_imm"
3595   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3596         (match_operator:GPR 3 "boolean_or_operator"
3597          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3598           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3599   ""
3600   "%q3i%e2 %0,%1,%u2"
3601   [(set_attr "type" "logical")])
3603 (define_insn "*bool<mode>3"
3604   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3605         (match_operator:GPR 3 "boolean_operator"
3606          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3607           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3608   ""
3609   "%q3 %0,%1,%2"
3610   [(set_attr "type" "logical")])
3612 (define_insn_and_split "*bool<mode>3_dot"
3613   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3614         (compare:CC (match_operator:GPR 3 "boolean_operator"
3615          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3616           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3617          (const_int 0)))
3618    (clobber (match_scratch:GPR 0 "=r,r"))]
3619   "<MODE>mode == Pmode"
3620   "@
3621    %q3. %0,%1,%2
3622    #"
3623   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3624   [(set (match_dup 0)
3625         (match_dup 3))
3626    (set (match_dup 4)
3627         (compare:CC (match_dup 0)
3628                     (const_int 0)))]
3629   ""
3630   [(set_attr "type" "logical")
3631    (set_attr "dot" "yes")
3632    (set_attr "length" "4,8")])
3634 (define_insn_and_split "*bool<mode>3_dot2"
3635   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3636         (compare:CC (match_operator:GPR 3 "boolean_operator"
3637          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3638           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3639          (const_int 0)))
3640    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3641         (match_dup 3))]
3642   "<MODE>mode == Pmode"
3643   "@
3644    %q3. %0,%1,%2
3645    #"
3646   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3647   [(set (match_dup 0)
3648         (match_dup 3))
3649    (set (match_dup 4)
3650         (compare:CC (match_dup 0)
3651                     (const_int 0)))]
3652   ""
3653   [(set_attr "type" "logical")
3654    (set_attr "dot" "yes")
3655    (set_attr "length" "4,8")])
3658 (define_insn "*boolc<mode>3"
3659   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3660         (match_operator:GPR 3 "boolean_operator"
3661          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3662           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3663   ""
3664   "%q3 %0,%1,%2"
3665   [(set_attr "type" "logical")])
3667 (define_insn_and_split "*boolc<mode>3_dot"
3668   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3669         (compare:CC (match_operator:GPR 3 "boolean_operator"
3670          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3671           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3672          (const_int 0)))
3673    (clobber (match_scratch:GPR 0 "=r,r"))]
3674   "<MODE>mode == Pmode"
3675   "@
3676    %q3. %0,%1,%2
3677    #"
3678   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3679   [(set (match_dup 0)
3680         (match_dup 3))
3681    (set (match_dup 4)
3682         (compare:CC (match_dup 0)
3683                     (const_int 0)))]
3684   ""
3685   [(set_attr "type" "logical")
3686    (set_attr "dot" "yes")
3687    (set_attr "length" "4,8")])
3689 (define_insn_and_split "*boolc<mode>3_dot2"
3690   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3691         (compare:CC (match_operator:GPR 3 "boolean_operator"
3692          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3693           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3694          (const_int 0)))
3695    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3696         (match_dup 3))]
3697   "<MODE>mode == Pmode"
3698   "@
3699    %q3. %0,%1,%2
3700    #"
3701   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3702   [(set (match_dup 0)
3703         (match_dup 3))
3704    (set (match_dup 4)
3705         (compare:CC (match_dup 0)
3706                     (const_int 0)))]
3707   ""
3708   [(set_attr "type" "logical")
3709    (set_attr "dot" "yes")
3710    (set_attr "length" "4,8")])
3713 (define_insn "*boolcc<mode>3"
3714   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3715         (match_operator:GPR 3 "boolean_operator"
3716          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3717           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3718   ""
3719   "%q3 %0,%1,%2"
3720   [(set_attr "type" "logical")])
3722 (define_insn_and_split "*boolcc<mode>3_dot"
3723   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3724         (compare:CC (match_operator:GPR 3 "boolean_operator"
3725          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3726           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3727          (const_int 0)))
3728    (clobber (match_scratch:GPR 0 "=r,r"))]
3729   "<MODE>mode == Pmode"
3730   "@
3731    %q3. %0,%1,%2
3732    #"
3733   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3734   [(set (match_dup 0)
3735         (match_dup 3))
3736    (set (match_dup 4)
3737         (compare:CC (match_dup 0)
3738                     (const_int 0)))]
3739   ""
3740   [(set_attr "type" "logical")
3741    (set_attr "dot" "yes")
3742    (set_attr "length" "4,8")])
3744 (define_insn_and_split "*boolcc<mode>3_dot2"
3745   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3746         (compare:CC (match_operator:GPR 3 "boolean_operator"
3747          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3748           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3749          (const_int 0)))
3750    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3751         (match_dup 3))]
3752   "<MODE>mode == Pmode"
3753   "@
3754    %q3. %0,%1,%2
3755    #"
3756   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3757   [(set (match_dup 0)
3758         (match_dup 3))
3759    (set (match_dup 4)
3760         (compare:CC (match_dup 0)
3761                     (const_int 0)))]
3762   ""
3763   [(set_attr "type" "logical")
3764    (set_attr "dot" "yes")
3765    (set_attr "length" "4,8")])
3768 ;; TODO: Should have dots of this as well.
3769 (define_insn "*eqv<mode>3"
3770   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3771         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3772                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3773   ""
3774   "eqv %0,%1,%2"
3775   [(set_attr "type" "logical")])
3777 ;; Rotate-and-mask and insert.
3779 (define_insn "*rotl<mode>3_mask"
3780   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3781         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3782                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3783                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3784                  (match_operand:GPR 3 "const_int_operand" "n")))]
3785   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3787   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3789   [(set_attr "type" "shift")
3790    (set_attr "maybe_var_shift" "yes")])
3792 (define_insn_and_split "*rotl<mode>3_mask_dot"
3793   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3794         (compare:CC
3795           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3796                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3797                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3798                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3799           (const_int 0)))
3800    (clobber (match_scratch:GPR 0 "=r,r"))]
3801   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3802    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3804   if (which_alternative == 0)
3805     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3806   else
3807     return "#";
3809   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3810   [(set (match_dup 0)
3811         (and:GPR (match_dup 4)
3812                  (match_dup 3)))
3813    (set (match_dup 5)
3814         (compare:CC (match_dup 0)
3815                     (const_int 0)))]
3816   ""
3817   [(set_attr "type" "shift")
3818    (set_attr "maybe_var_shift" "yes")
3819    (set_attr "dot" "yes")
3820    (set_attr "length" "4,8")])
3822 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3823   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3824         (compare:CC
3825           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3826                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3827                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3828                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3829           (const_int 0)))
3830    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3831         (and:GPR (match_dup 4)
3832                  (match_dup 3)))]
3833   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3834    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3836   if (which_alternative == 0)
3837     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3838   else
3839     return "#";
3841   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3842   [(set (match_dup 0)
3843         (and:GPR (match_dup 4)
3844                  (match_dup 3)))
3845    (set (match_dup 5)
3846         (compare:CC (match_dup 0)
3847                     (const_int 0)))]
3848   ""
3849   [(set_attr "type" "shift")
3850    (set_attr "maybe_var_shift" "yes")
3851    (set_attr "dot" "yes")
3852    (set_attr "length" "4,8")])
3854 ; Special case for less-than-0.  We can do it with just one machine
3855 ; instruction, but the generic optimizers do not realise it is cheap.
3856 (define_insn "*lt0_<mode>di"
3857   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3858         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3859                 (const_int 0)))]
3860   "TARGET_POWERPC64"
3861   "srdi %0,%1,63"
3862   [(set_attr "type" "shift")])
3864 (define_insn "*lt0_<mode>si"
3865   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3867                 (const_int 0)))]
3868   ""
3869   "rlwinm %0,%1,1,31,31"
3870   [(set_attr "type" "shift")])
3874 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3875 ; both are an AND so are the same precedence).
3876 (define_insn "*rotl<mode>3_insert"
3877   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3878         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3879                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3880                             (match_operand:SI 2 "const_int_operand" "n")])
3881                           (match_operand:GPR 3 "const_int_operand" "n"))
3882                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3883                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3884   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3885    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3887   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3889   [(set_attr "type" "insert")])
3890 ; FIXME: this needs an attr "size", so that the scheduler can see the
3891 ; difference between rlwimi and rldimi.  We also might want dot forms,
3892 ; but not for rlwimi on POWER4 and similar processors.
3894 (define_insn "*rotl<mode>3_insert_2"
3895   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3896         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3897                           (match_operand:GPR 6 "const_int_operand" "n"))
3898                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3899                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3900                             (match_operand:SI 2 "const_int_operand" "n")])
3901                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3902   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3903    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3905   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3907   [(set_attr "type" "insert")])
3909 ; There are also some forms without one of the ANDs.
3910 (define_insn "*rotl<mode>3_insert_3"
3911   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3912         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3913                           (match_operand:GPR 4 "const_int_operand" "n"))
3914                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3915                              (match_operand:SI 2 "const_int_operand" "n"))))]
3916   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3918   if (<MODE>mode == SImode)
3919     return "rlwimi %0,%1,%h2,0,31-%h2";
3920   else
3921     return "rldimi %0,%1,%H2,0";
3923   [(set_attr "type" "insert")])
3925 (define_insn "*rotl<mode>3_insert_4"
3926   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3927         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3928                           (match_operand:GPR 4 "const_int_operand" "n"))
3929                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3930                                (match_operand:SI 2 "const_int_operand" "n"))))]
3931   "<MODE>mode == SImode &&
3932    GET_MODE_PRECISION (<MODE>mode)
3933    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3935   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3936                          - INTVAL (operands[2]));
3937   if (<MODE>mode == SImode)
3938     return "rlwimi %0,%1,%h2,32-%h2,31";
3939   else
3940     return "rldimi %0,%1,%H2,64-%H2";
3942   [(set_attr "type" "insert")])
3944 (define_insn "*rotlsi3_insert_5"
3945   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3946         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3947                         (match_operand:SI 2 "const_int_operand" "n,n"))
3948                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3949                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3950   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3951    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3952    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3953   "@
3954    rlwimi %0,%3,0,%4
3955    rlwimi %0,%1,0,%2"
3956   [(set_attr "type" "insert")])
3958 (define_insn "*rotldi3_insert_6"
3959   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3960         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3961                         (match_operand:DI 2 "const_int_operand" "n"))
3962                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3963                         (match_operand:DI 4 "const_int_operand" "n"))))]
3964   "exact_log2 (-UINTVAL (operands[2])) > 0
3965    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3967   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3968   return "rldimi %0,%3,0,%5";
3970   [(set_attr "type" "insert")
3971    (set_attr "size" "64")])
3973 (define_insn "*rotldi3_insert_7"
3974   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3975         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3976                         (match_operand:DI 4 "const_int_operand" "n"))
3977                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3978                         (match_operand:DI 2 "const_int_operand" "n"))))]
3979   "exact_log2 (-UINTVAL (operands[2])) > 0
3980    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3982   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3983   return "rldimi %0,%3,0,%5";
3985   [(set_attr "type" "insert")
3986    (set_attr "size" "64")])
3989 ; This handles the important case of multiple-precision shifts.  There is
3990 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3991 (define_split
3992   [(set (match_operand:GPR 0 "gpc_reg_operand")
3993         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3994                              (match_operand:SI 3 "const_int_operand"))
3995                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3996                                (match_operand:SI 4 "const_int_operand"))))]
3997   "can_create_pseudo_p ()
3998    && INTVAL (operands[3]) + INTVAL (operands[4])
3999       >= GET_MODE_PRECISION (<MODE>mode)"
4000   [(set (match_dup 5)
4001         (lshiftrt:GPR (match_dup 2)
4002                       (match_dup 4)))
4003    (set (match_dup 0)
4004         (ior:GPR (and:GPR (match_dup 5)
4005                           (match_dup 6))
4006                  (ashift:GPR (match_dup 1)
4007                              (match_dup 3))))]
4009   unsigned HOST_WIDE_INT mask = 1;
4010   mask = (mask << INTVAL (operands[3])) - 1;
4011   operands[5] = gen_reg_rtx (<MODE>mode);
4012   operands[6] = GEN_INT (mask);
4015 (define_split
4016   [(set (match_operand:GPR 0 "gpc_reg_operand")
4017         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4018                                (match_operand:SI 4 "const_int_operand"))
4019                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4020                              (match_operand:SI 3 "const_int_operand"))))]
4021   "can_create_pseudo_p ()
4022    && INTVAL (operands[3]) + INTVAL (operands[4])
4023       >= GET_MODE_PRECISION (<MODE>mode)"
4024   [(set (match_dup 5)
4025         (lshiftrt:GPR (match_dup 2)
4026                       (match_dup 4)))
4027    (set (match_dup 0)
4028         (ior:GPR (and:GPR (match_dup 5)
4029                           (match_dup 6))
4030                  (ashift:GPR (match_dup 1)
4031                              (match_dup 3))))]
4033   unsigned HOST_WIDE_INT mask = 1;
4034   mask = (mask << INTVAL (operands[3])) - 1;
4035   operands[5] = gen_reg_rtx (<MODE>mode);
4036   operands[6] = GEN_INT (mask);
4040 ; Another important case is setting some bits to 1; we can do that with
4041 ; an insert instruction, in many cases.
4042 (define_insn_and_split "*ior<mode>_mask"
4043   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4044         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4045                  (match_operand:GPR 2 "const_int_operand" "n")))
4046    (clobber (match_scratch:GPR 3 "=r"))]
4047   "!logical_const_operand (operands[2], <MODE>mode)
4048    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4049   "#"
4050   "&& 1"
4051   [(set (match_dup 3)
4052         (const_int -1))
4053    (set (match_dup 0)
4054         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4055                                       (match_dup 4))
4056                           (match_dup 2))
4057                  (and:GPR (match_dup 1)
4058                           (match_dup 5))))]
4060   int nb, ne;
4061   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4062   if (GET_CODE (operands[3]) == SCRATCH)
4063     operands[3] = gen_reg_rtx (<MODE>mode);
4064   operands[4] = GEN_INT (ne);
4065   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4067   [(set_attr "type" "two")
4068    (set_attr "length" "8")])
4071 ;; Now the simple shifts.
4073 (define_insn "rotl<mode>3"
4074   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4075         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4076                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4077   ""
4078   "rotl<wd>%I2 %0,%1,%<hH>2"
4079   [(set_attr "type" "shift")
4080    (set_attr "maybe_var_shift" "yes")])
4082 (define_insn "*rotlsi3_64"
4083   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4084         (zero_extend:DI
4085             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4086                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4087   "TARGET_POWERPC64"
4088   "rotlw%I2 %0,%1,%h2"
4089   [(set_attr "type" "shift")
4090    (set_attr "maybe_var_shift" "yes")])
4092 (define_insn_and_split "*rotl<mode>3_dot"
4093   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4094         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4095                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4096                     (const_int 0)))
4097    (clobber (match_scratch:GPR 0 "=r,r"))]
4098   "<MODE>mode == Pmode"
4099   "@
4100    rotl<wd>%I2. %0,%1,%<hH>2
4101    #"
4102   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4103   [(set (match_dup 0)
4104         (rotate:GPR (match_dup 1)
4105                     (match_dup 2)))
4106    (set (match_dup 3)
4107         (compare:CC (match_dup 0)
4108                     (const_int 0)))]
4109   ""
4110   [(set_attr "type" "shift")
4111    (set_attr "maybe_var_shift" "yes")
4112    (set_attr "dot" "yes")
4113    (set_attr "length" "4,8")])
4115 (define_insn_and_split "*rotl<mode>3_dot2"
4116   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4117         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4118                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4119                     (const_int 0)))
4120    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4121         (rotate:GPR (match_dup 1)
4122                     (match_dup 2)))]
4123   "<MODE>mode == Pmode"
4124   "@
4125    rotl<wd>%I2. %0,%1,%<hH>2
4126    #"
4127   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4128   [(set (match_dup 0)
4129         (rotate:GPR (match_dup 1)
4130                     (match_dup 2)))
4131    (set (match_dup 3)
4132         (compare:CC (match_dup 0)
4133                     (const_int 0)))]
4134   ""
4135   [(set_attr "type" "shift")
4136    (set_attr "maybe_var_shift" "yes")
4137    (set_attr "dot" "yes")
4138    (set_attr "length" "4,8")])
4141 (define_insn "ashl<mode>3"
4142   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4143         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4144                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4145   ""
4146   "sl<wd>%I2 %0,%1,%<hH>2"
4147   [(set_attr "type" "shift")
4148    (set_attr "maybe_var_shift" "yes")])
4150 (define_insn "*ashlsi3_64"
4151   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4152         (zero_extend:DI
4153             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4154                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4155   "TARGET_POWERPC64"
4156   "slw%I2 %0,%1,%h2"
4157   [(set_attr "type" "shift")
4158    (set_attr "maybe_var_shift" "yes")])
4160 (define_insn_and_split "*ashl<mode>3_dot"
4161   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4162         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4163                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4164                     (const_int 0)))
4165    (clobber (match_scratch:GPR 0 "=r,r"))]
4166   "<MODE>mode == Pmode"
4167   "@
4168    sl<wd>%I2. %0,%1,%<hH>2
4169    #"
4170   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4171   [(set (match_dup 0)
4172         (ashift:GPR (match_dup 1)
4173                     (match_dup 2)))
4174    (set (match_dup 3)
4175         (compare:CC (match_dup 0)
4176                     (const_int 0)))]
4177   ""
4178   [(set_attr "type" "shift")
4179    (set_attr "maybe_var_shift" "yes")
4180    (set_attr "dot" "yes")
4181    (set_attr "length" "4,8")])
4183 (define_insn_and_split "*ashl<mode>3_dot2"
4184   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4185         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4186                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4187                     (const_int 0)))
4188    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4189         (ashift:GPR (match_dup 1)
4190                     (match_dup 2)))]
4191   "<MODE>mode == Pmode"
4192   "@
4193    sl<wd>%I2. %0,%1,%<hH>2
4194    #"
4195   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4196   [(set (match_dup 0)
4197         (ashift:GPR (match_dup 1)
4198                     (match_dup 2)))
4199    (set (match_dup 3)
4200         (compare:CC (match_dup 0)
4201                     (const_int 0)))]
4202   ""
4203   [(set_attr "type" "shift")
4204    (set_attr "maybe_var_shift" "yes")
4205    (set_attr "dot" "yes")
4206    (set_attr "length" "4,8")])
4208 ;; Pretend we have a memory form of extswsli until register allocation is done
4209 ;; so that we use LWZ to load the value from memory, instead of LWA.
4210 (define_insn_and_split "ashdi3_extswsli"
4211   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4212         (ashift:DI
4213          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4214          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4215   "TARGET_EXTSWSLI"
4216   "@
4217    extswsli %0,%1,%2
4218    #"
4219   "&& reload_completed && MEM_P (operands[1])"
4220   [(set (match_dup 3)
4221         (match_dup 1))
4222    (set (match_dup 0)
4223         (ashift:DI (sign_extend:DI (match_dup 3))
4224                    (match_dup 2)))]
4226   operands[3] = gen_lowpart (SImode, operands[0]);
4228   [(set_attr "type" "shift")
4229    (set_attr "maybe_var_shift" "no")])
4232 (define_insn_and_split "ashdi3_extswsli_dot"
4233   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4234         (compare:CC
4235          (ashift:DI
4236           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4237           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4238          (const_int 0)))
4239    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4240   "TARGET_EXTSWSLI"
4241   "@
4242    extswsli. %0,%1,%2
4243    #
4244    #
4245    #"
4246   "&& reload_completed
4247    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4248        || memory_operand (operands[1], SImode))"
4249   [(pc)]
4251   rtx dest = operands[0];
4252   rtx src = operands[1];
4253   rtx shift = operands[2];
4254   rtx cr = operands[3];
4255   rtx src2;
4257   if (!MEM_P (src))
4258     src2 = src;
4259   else
4260     {
4261       src2 = gen_lowpart (SImode, dest);
4262       emit_move_insn (src2, src);
4263     }
4265   if (REGNO (cr) == CR0_REGNO)
4266     {
4267       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4268       DONE;
4269     }
4271   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4272   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4273   DONE;
4275   [(set_attr "type" "shift")
4276    (set_attr "maybe_var_shift" "no")
4277    (set_attr "dot" "yes")
4278    (set_attr "length" "4,8,8,12")])
4280 (define_insn_and_split "ashdi3_extswsli_dot2"
4281   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4282         (compare:CC
4283          (ashift:DI
4284           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4285           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4286          (const_int 0)))
4287    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4288         (ashift:DI (sign_extend:DI (match_dup 1))
4289                    (match_dup 2)))]
4290   "TARGET_EXTSWSLI"
4291   "@
4292    extswsli. %0,%1,%2
4293    #
4294    #
4295    #"
4296   "&& reload_completed
4297    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4298        || memory_operand (operands[1], SImode))"
4299   [(pc)]
4301   rtx dest = operands[0];
4302   rtx src = operands[1];
4303   rtx shift = operands[2];
4304   rtx cr = operands[3];
4305   rtx src2;
4307   if (!MEM_P (src))
4308     src2 = src;
4309   else
4310     {
4311       src2 = gen_lowpart (SImode, dest);
4312       emit_move_insn (src2, src);
4313     }
4315   if (REGNO (cr) == CR0_REGNO)
4316     {
4317       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4318       DONE;
4319     }
4321   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4322   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4323   DONE;
4325   [(set_attr "type" "shift")
4326    (set_attr "maybe_var_shift" "no")
4327    (set_attr "dot" "yes")
4328    (set_attr "length" "4,8,8,12")])
4330 (define_insn "lshr<mode>3"
4331   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4332         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4333                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4334   ""
4335   "sr<wd>%I2 %0,%1,%<hH>2"
4336   [(set_attr "type" "shift")
4337    (set_attr "maybe_var_shift" "yes")])
4339 (define_insn "*lshrsi3_64"
4340   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4341         (zero_extend:DI
4342             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4343                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4344   "TARGET_POWERPC64"
4345   "srw%I2 %0,%1,%h2"
4346   [(set_attr "type" "shift")
4347    (set_attr "maybe_var_shift" "yes")])
4349 (define_insn_and_split "*lshr<mode>3_dot"
4350   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4351         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4352                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4353                     (const_int 0)))
4354    (clobber (match_scratch:GPR 0 "=r,r"))]
4355   "<MODE>mode == Pmode"
4356   "@
4357    sr<wd>%I2. %0,%1,%<hH>2
4358    #"
4359   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4360   [(set (match_dup 0)
4361         (lshiftrt:GPR (match_dup 1)
4362                       (match_dup 2)))
4363    (set (match_dup 3)
4364         (compare:CC (match_dup 0)
4365                     (const_int 0)))]
4366   ""
4367   [(set_attr "type" "shift")
4368    (set_attr "maybe_var_shift" "yes")
4369    (set_attr "dot" "yes")
4370    (set_attr "length" "4,8")])
4372 (define_insn_and_split "*lshr<mode>3_dot2"
4373   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4374         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4375                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4376                     (const_int 0)))
4377    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4378         (lshiftrt:GPR (match_dup 1)
4379                       (match_dup 2)))]
4380   "<MODE>mode == Pmode"
4381   "@
4382    sr<wd>%I2. %0,%1,%<hH>2
4383    #"
4384   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4385   [(set (match_dup 0)
4386         (lshiftrt:GPR (match_dup 1)
4387                       (match_dup 2)))
4388    (set (match_dup 3)
4389         (compare:CC (match_dup 0)
4390                     (const_int 0)))]
4391   ""
4392   [(set_attr "type" "shift")
4393    (set_attr "maybe_var_shift" "yes")
4394    (set_attr "dot" "yes")
4395    (set_attr "length" "4,8")])
4398 (define_insn "ashr<mode>3"
4399   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4400         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4401                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4402    (clobber (reg:GPR CA_REGNO))]
4403   ""
4404   "sra<wd>%I2 %0,%1,%<hH>2"
4405   [(set_attr "type" "shift")
4406    (set_attr "maybe_var_shift" "yes")])
4408 (define_insn "*ashrsi3_64"
4409   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4410         (sign_extend:DI
4411             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4412                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4413    (clobber (reg:SI CA_REGNO))]
4414   "TARGET_POWERPC64"
4415   "sraw%I2 %0,%1,%h2"
4416   [(set_attr "type" "shift")
4417    (set_attr "maybe_var_shift" "yes")])
4419 (define_insn_and_split "*ashr<mode>3_dot"
4420   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4421         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4422                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4423                     (const_int 0)))
4424    (clobber (match_scratch:GPR 0 "=r,r"))
4425    (clobber (reg:GPR CA_REGNO))]
4426   "<MODE>mode == Pmode"
4427   "@
4428    sra<wd>%I2. %0,%1,%<hH>2
4429    #"
4430   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4431   [(parallel [(set (match_dup 0)
4432                    (ashiftrt:GPR (match_dup 1)
4433                                  (match_dup 2)))
4434               (clobber (reg:GPR CA_REGNO))])
4435    (set (match_dup 3)
4436         (compare:CC (match_dup 0)
4437                     (const_int 0)))]
4438   ""
4439   [(set_attr "type" "shift")
4440    (set_attr "maybe_var_shift" "yes")
4441    (set_attr "dot" "yes")
4442    (set_attr "length" "4,8")])
4444 (define_insn_and_split "*ashr<mode>3_dot2"
4445   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4446         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4447                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4448                     (const_int 0)))
4449    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4450         (ashiftrt:GPR (match_dup 1)
4451                       (match_dup 2)))
4452    (clobber (reg:GPR CA_REGNO))]
4453   "<MODE>mode == Pmode"
4454   "@
4455    sra<wd>%I2. %0,%1,%<hH>2
4456    #"
4457   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4458   [(parallel [(set (match_dup 0)
4459                    (ashiftrt:GPR (match_dup 1)
4460                                  (match_dup 2)))
4461               (clobber (reg:GPR CA_REGNO))])
4462    (set (match_dup 3)
4463         (compare:CC (match_dup 0)
4464                     (const_int 0)))]
4465   ""
4466   [(set_attr "type" "shift")
4467    (set_attr "maybe_var_shift" "yes")
4468    (set_attr "dot" "yes")
4469    (set_attr "length" "4,8")])
4471 ;; Builtins to replace a division to generate FRE reciprocal estimate
4472 ;; instructions and the necessary fixup instructions
4473 (define_expand "recip<mode>3"
4474   [(match_operand:RECIPF 0 "gpc_reg_operand")
4475    (match_operand:RECIPF 1 "gpc_reg_operand")
4476    (match_operand:RECIPF 2 "gpc_reg_operand")]
4477   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4479    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4480    DONE;
4483 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4484 ;; hardware division.  This is only done before register allocation and with
4485 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4486 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4487 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4488 (define_split
4489   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4490         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4491                     (match_operand 2 "gpc_reg_operand")))]
4492   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4493    && can_create_pseudo_p () && flag_finite_math_only
4494    && !flag_trapping_math && flag_reciprocal_math"
4495   [(const_int 0)]
4497   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4498   DONE;
4501 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4502 ;; appropriate fixup.
4503 (define_expand "rsqrt<mode>2"
4504   [(match_operand:RECIPF 0 "gpc_reg_operand")
4505    (match_operand:RECIPF 1 "gpc_reg_operand")]
4506   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4508   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4509   DONE;
4512 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4513 ;; modes here, and also add in conditional vsx/power8-vector support to access
4514 ;; values in the traditional Altivec registers if the appropriate
4515 ;; -mupper-regs-{df,sf} option is enabled.
4517 (define_expand "abs<mode>2"
4518   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4519         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4520   "TARGET_<MODE>_INSN"
4521   "")
4523 (define_insn "*abs<mode>2_fpr"
4524   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4525         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4526   "TARGET_<MODE>_FPR"
4527   "@
4528    fabs %0,%1
4529    xsabsdp %x0,%x1"
4530   [(set_attr "type" "fpsimple")
4531    (set_attr "fp_type" "fp_addsub_<Fs>")])
4533 (define_insn "*nabs<mode>2_fpr"
4534   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4535         (neg:SFDF
4536          (abs:SFDF
4537           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4538   "TARGET_<MODE>_FPR"
4539   "@
4540    fnabs %0,%1
4541    xsnabsdp %x0,%x1"
4542   [(set_attr "type" "fpsimple")
4543    (set_attr "fp_type" "fp_addsub_<Fs>")])
4545 (define_expand "neg<mode>2"
4546   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4547         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4548   "TARGET_<MODE>_INSN"
4549   "")
4551 (define_insn "*neg<mode>2_fpr"
4552   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4553         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4554   "TARGET_<MODE>_FPR"
4555   "@
4556    fneg %0,%1
4557    xsnegdp %x0,%x1"
4558   [(set_attr "type" "fpsimple")
4559    (set_attr "fp_type" "fp_addsub_<Fs>")])
4561 (define_expand "add<mode>3"
4562   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4563         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4564                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4565   "TARGET_<MODE>_INSN"
4566   "")
4568 (define_insn "*add<mode>3_fpr"
4569   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4570         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4571                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4572   "TARGET_<MODE>_FPR"
4573   "@
4574    fadd<Ftrad> %0,%1,%2
4575    xsadd<Fvsx> %x0,%x1,%x2"
4576   [(set_attr "type" "fp")
4577    (set_attr "fp_type" "fp_addsub_<Fs>")])
4579 (define_expand "sub<mode>3"
4580   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4581         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4582                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4583   "TARGET_<MODE>_INSN"
4584   "")
4586 (define_insn "*sub<mode>3_fpr"
4587   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4588         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4589                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4590   "TARGET_<MODE>_FPR"
4591   "@
4592    fsub<Ftrad> %0,%1,%2
4593    xssub<Fvsx> %x0,%x1,%x2"
4594   [(set_attr "type" "fp")
4595    (set_attr "fp_type" "fp_addsub_<Fs>")])
4597 (define_expand "mul<mode>3"
4598   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4599         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4600                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4601   "TARGET_<MODE>_INSN"
4602   "")
4604 (define_insn "*mul<mode>3_fpr"
4605   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4606         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4607                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4608   "TARGET_<MODE>_FPR"
4609   "@
4610    fmul<Ftrad> %0,%1,%2
4611    xsmul<Fvsx> %x0,%x1,%x2"
4612   [(set_attr "type" "dmul")
4613    (set_attr "fp_type" "fp_mul_<Fs>")])
4615 (define_expand "div<mode>3"
4616   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4617         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4618                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4619   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4621   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4622       && can_create_pseudo_p () && flag_finite_math_only
4623       && !flag_trapping_math && flag_reciprocal_math)
4624     {
4625       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4626       DONE;
4627     }
4630 (define_insn "*div<mode>3_fpr"
4631   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4632         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4633                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4634   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4635   "@
4636    fdiv<Ftrad> %0,%1,%2
4637    xsdiv<Fvsx> %x0,%x1,%x2"
4638   [(set_attr "type" "<Fs>div")
4639    (set_attr "fp_type" "fp_div_<Fs>")])
4641 (define_insn "*sqrt<mode>2_internal"
4642   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4643         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4644   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4645    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4646   "@
4647    fsqrt<Ftrad> %0,%1
4648    xssqrt<Fvsx> %x0,%x1"
4649   [(set_attr "type" "<Fs>sqrt")
4650    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4652 (define_expand "sqrt<mode>2"
4653   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4654         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4655   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4656    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4658   if (<MODE>mode == SFmode
4659       && TARGET_RECIP_PRECISION
4660       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4661       && !optimize_function_for_size_p (cfun)
4662       && flag_finite_math_only && !flag_trapping_math
4663       && flag_unsafe_math_optimizations)
4664     {
4665       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4666       DONE;
4667     }
4670 ;; Floating point reciprocal approximation
4671 (define_insn "fre<Fs>"
4672   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4673         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4674                      UNSPEC_FRES))]
4675   "TARGET_<FFRE>"
4676   "@
4677    fre<Ftrad> %0,%1
4678    xsre<Fvsx> %x0,%x1"
4679   [(set_attr "type" "fp")])
4681 (define_insn "*rsqrt<mode>2"
4682   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4683         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4684                      UNSPEC_RSQRT))]
4685   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4686   "@
4687    frsqrte<Ftrad> %0,%1
4688    xsrsqrte<Fvsx> %x0,%x1"
4689   [(set_attr "type" "fp")])
4691 ;; Floating point comparisons
4692 (define_insn "*cmp<mode>_fpr"
4693   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4694         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4695                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4696   "TARGET_<MODE>_FPR"
4697   "@
4698    fcmpu %0,%1,%2
4699    xscmpudp %0,%x1,%x2"
4700   [(set_attr "type" "fpcompare")])
4702 ;; Floating point conversions
4703 (define_expand "extendsfdf2"
4704   [(set (match_operand:DF 0 "gpc_reg_operand")
4705         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4706   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4708   if (HONOR_SNANS (SFmode))
4709     operands[1] = force_reg (SFmode, operands[1]);
4712 (define_insn_and_split "*extendsfdf2_fpr"
4713   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4714         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4715   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4716   "@
4717    #
4718    fmr %0,%1
4719    lfs%U1%X1 %0,%1
4720    #
4721    xscpsgndp %x0,%x1,%x1
4722    lxsspx %x0,%y1
4723    lxssp %0,%1"
4724   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4725   [(const_int 0)]
4727   emit_note (NOTE_INSN_DELETED);
4728   DONE;
4730   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4732 (define_insn "*extendsfdf2_snan"
4733   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4734         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4735   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4736   "@
4737    frsp %0,%1
4738    xsrsp %x0,%x1"
4739   [(set_attr "type" "fp")])
4741 (define_expand "truncdfsf2"
4742   [(set (match_operand:SF 0 "gpc_reg_operand")
4743         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4744   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4745   "")
4747 (define_insn "*truncdfsf2_fpr"
4748   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4749         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4750   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4751   "@
4752    frsp %0,%1
4753    xsrsp %x0,%x1"
4754   [(set_attr "type" "fp")])
4756 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4757 ;; builtins.c and optabs.c that are not correct for IBM long double
4758 ;; when little-endian.
4759 (define_expand "signbit<mode>2"
4760   [(set (match_dup 2)
4761         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4762    (set (match_dup 3)
4763         (subreg:DI (match_dup 2) 0))
4764    (set (match_dup 4)
4765         (match_dup 5))
4766    (set (match_operand:SI 0 "gpc_reg_operand")
4767         (match_dup 6))]
4768   "TARGET_HARD_FLOAT
4769    && (!FLOAT128_IEEE_P (<MODE>mode)
4770        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4772   if (FLOAT128_IEEE_P (<MODE>mode))
4773     {
4774       rtx dest = operands[0];
4775       rtx src = operands[1];
4776       rtx tmp = gen_reg_rtx (DImode);
4777       rtx dest_di = gen_lowpart (DImode, dest);
4779       if (<MODE>mode == KFmode)
4780         emit_insn (gen_signbitkf2_dm (tmp, src));
4781       else if (<MODE>mode == TFmode)
4782         emit_insn (gen_signbittf2_dm (tmp, src));
4783       else
4784         gcc_unreachable ();
4786       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4787       DONE;
4788     }
4789   operands[2] = gen_reg_rtx (DFmode);
4790   operands[3] = gen_reg_rtx (DImode);
4791   if (TARGET_POWERPC64)
4792     {
4793       operands[4] = gen_reg_rtx (DImode);
4794       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4795       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4796                                     WORDS_BIG_ENDIAN ? 4 : 0);
4797     }
4798   else
4799     {
4800       operands[4] = gen_reg_rtx (SImode);
4801       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4802                                     WORDS_BIG_ENDIAN ? 0 : 4);
4803       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4804     }
4807 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4808 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4809 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4810 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4812 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4813 ;; split allows the post reload phases to eliminate the move, and do the shift
4814 ;; directly with the register that contains the signbit.
4815 (define_insn_and_split "signbit<mode>2_dm"
4816   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4817         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4818                    UNSPEC_SIGNBIT))]
4819   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4820   "@
4821    mfvsrd %0,%x1
4822    #"
4823   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4824   [(set (match_dup 0)
4825         (match_dup 2))]
4827   operands[2] = gen_highpart (DImode, operands[1]);
4829  [(set_attr "type" "mftgpr,*")])
4831 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4832 ;; register and then doing a direct move if the value comes from memory.  On
4833 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4834 (define_insn_and_split "*signbit<mode>2_dm_mem"
4835   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4836         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4837                    UNSPEC_SIGNBIT))]
4838   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4839   "#"
4840   "&& 1"
4841   [(set (match_dup 0)
4842         (match_dup 2))]
4844   rtx dest = operands[0];
4845   rtx src = operands[1];
4846   rtx addr = XEXP (src, 0);
4848   if (WORDS_BIG_ENDIAN)
4849     operands[2] = adjust_address (src, DImode, 0);
4851   else if (REG_P (addr) || SUBREG_P (addr))
4852     operands[2] = adjust_address (src, DImode, 8);
4854   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4855            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4856     operands[2] = adjust_address (src, DImode, 8);
4858   else
4859     {
4860       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4861       emit_insn (gen_rtx_SET (tmp, addr));
4862       operands[2] = change_address (src, DImode,
4863                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4864     }
4867 (define_expand "copysign<mode>3"
4868   [(set (match_dup 3)
4869         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4870    (set (match_dup 4)
4871         (neg:SFDF (abs:SFDF (match_dup 1))))
4872    (set (match_operand:SFDF 0 "gpc_reg_operand")
4873         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4874                                (match_dup 5))
4875                          (match_dup 3)
4876                          (match_dup 4)))]
4877   "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4878    && ((TARGET_PPC_GFXOPT
4879         && !HONOR_NANS (<MODE>mode)
4880         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4881        || TARGET_CMPB
4882        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4884   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4885     {
4886       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4887                                              operands[2]));
4888       DONE;
4889     }
4891    operands[3] = gen_reg_rtx (<MODE>mode);
4892    operands[4] = gen_reg_rtx (<MODE>mode);
4893    operands[5] = CONST0_RTX (<MODE>mode);
4894   })
4896 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4897 ;; compiler from optimizing -0.0
4898 (define_insn "copysign<mode>3_fcpsgn"
4899   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4900         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4901                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4902                      UNSPEC_COPYSIGN))]
4903   "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4904   "@
4905    fcpsgn %0,%2,%1
4906    xscpsgndp %x0,%x2,%x1"
4907   [(set_attr "type" "fpsimple")])
4909 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4910 ;; fsel instruction and some auxiliary computations.  Then we just have a
4911 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4912 ;; combine.
4913 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4914 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4915 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4916 ;; define_splits to make them if made by combine.  On VSX machines we have the
4917 ;; min/max instructions.
4919 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4920 ;; to allow either DF/SF to use only traditional registers.
4922 (define_expand "s<minmax><mode>3"
4923   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4924         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4925                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4926   "TARGET_MINMAX_<MODE>"
4928   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4929   DONE;
4932 (define_insn "*s<minmax><mode>3_vsx"
4933   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4934         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4935                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4936   "TARGET_VSX && TARGET_<MODE>_FPR"
4938   return (TARGET_P9_MINMAX
4939           ? "xs<minmax>cdp %x0,%x1,%x2"
4940           : "xs<minmax>dp %x0,%x1,%x2");
4942   [(set_attr "type" "fp")])
4944 ;; The conditional move instructions allow us to perform max and min operations
4945 ;; even when we don't have the appropriate max/min instruction using the FSEL
4946 ;; instruction.
4948 (define_insn_and_split "*s<minmax><mode>3_fpr"
4949   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4950         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4951                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4952   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4953   "#"
4954   "&& 1"
4955   [(const_int 0)]
4957   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4958   DONE;
4961 (define_expand "mov<mode>cc"
4962    [(set (match_operand:GPR 0 "gpc_reg_operand")
4963          (if_then_else:GPR (match_operand 1 "comparison_operator")
4964                            (match_operand:GPR 2 "gpc_reg_operand")
4965                            (match_operand:GPR 3 "gpc_reg_operand")))]
4966   "TARGET_ISEL"
4968   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4969     DONE;
4970   else
4971     FAIL;
4974 ;; We use the BASE_REGS for the isel input operands because, if rA is
4975 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4976 ;; because we may switch the operands and rB may end up being rA.
4978 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4979 ;; leave out the mode in operand 4 and use one pattern, but reload can
4980 ;; change the mode underneath our feet and then gets confused trying
4981 ;; to reload the value.
4982 (define_insn "isel_signed_<mode>"
4983   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4984         (if_then_else:GPR
4985          (match_operator 1 "scc_comparison_operator"
4986                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4987                           (const_int 0)])
4988          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4989          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4990   "TARGET_ISEL"
4991   "isel %0,%2,%3,%j1"
4992   [(set_attr "type" "isel")])
4994 (define_insn "isel_unsigned_<mode>"
4995   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4996         (if_then_else:GPR
4997          (match_operator 1 "scc_comparison_operator"
4998                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4999                           (const_int 0)])
5000          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5001          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5002   "TARGET_ISEL"
5003   "isel %0,%2,%3,%j1"
5004   [(set_attr "type" "isel")])
5006 ;; These patterns can be useful for combine; they let combine know that
5007 ;; isel can handle reversed comparisons so long as the operands are
5008 ;; registers.
5010 (define_insn "*isel_reversed_signed_<mode>"
5011   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5012         (if_then_else:GPR
5013          (match_operator 1 "scc_rev_comparison_operator"
5014                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5015                           (const_int 0)])
5016          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5017          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5018   "TARGET_ISEL"
5020   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5021   return "isel %0,%3,%2,%j1";
5023   [(set_attr "type" "isel")])
5025 (define_insn "*isel_reversed_unsigned_<mode>"
5026   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5027         (if_then_else:GPR
5028          (match_operator 1 "scc_rev_comparison_operator"
5029                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5030                           (const_int 0)])
5031          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5032          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5033   "TARGET_ISEL"
5035   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5036   return "isel %0,%3,%2,%j1";
5038   [(set_attr "type" "isel")])
5040 ;; Floating point conditional move
5041 (define_expand "mov<mode>cc"
5042    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5043          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5044                             (match_operand:SFDF 2 "gpc_reg_operand")
5045                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5046   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5048   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5049     DONE;
5050   else
5051     FAIL;
5054 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5055   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5056         (if_then_else:SFDF
5057          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5058              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5059          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5060          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5061   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5062   "fsel %0,%1,%2,%3"
5063   [(set_attr "type" "fp")])
5065 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5066   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5067         (if_then_else:SFDF
5068          (match_operator:CCFP 1 "fpmask_comparison_operator"
5069                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5070                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5071          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5072          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5073    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5074   "TARGET_P9_MINMAX"
5075   "#"
5076   ""
5077   [(set (match_dup 6)
5078         (if_then_else:V2DI (match_dup 1)
5079                            (match_dup 7)
5080                            (match_dup 8)))
5081    (set (match_dup 0)
5082         (if_then_else:SFDF (ne (match_dup 6)
5083                                (match_dup 8))
5084                            (match_dup 4)
5085                            (match_dup 5)))]
5087   if (GET_CODE (operands[6]) == SCRATCH)
5088     operands[6] = gen_reg_rtx (V2DImode);
5090   operands[7] = CONSTM1_RTX (V2DImode);
5091   operands[8] = CONST0_RTX (V2DImode);
5093  [(set_attr "length" "8")
5094   (set_attr "type" "vecperm")])
5096 ;; Handle inverting the fpmask comparisons.
5097 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5098   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5099         (if_then_else:SFDF
5100          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5101                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5102                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5103          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5104          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5105    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5106   "TARGET_P9_MINMAX"
5107   "#"
5108   "&& 1"
5109   [(set (match_dup 6)
5110         (if_then_else:V2DI (match_dup 9)
5111                            (match_dup 7)
5112                            (match_dup 8)))
5113    (set (match_dup 0)
5114         (if_then_else:SFDF (ne (match_dup 6)
5115                                (match_dup 8))
5116                            (match_dup 5)
5117                            (match_dup 4)))]
5119   rtx op1 = operands[1];
5120   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5122   if (GET_CODE (operands[6]) == SCRATCH)
5123     operands[6] = gen_reg_rtx (V2DImode);
5125   operands[7] = CONSTM1_RTX (V2DImode);
5126   operands[8] = CONST0_RTX (V2DImode);
5128   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5130  [(set_attr "length" "8")
5131   (set_attr "type" "vecperm")])
5133 (define_insn "*fpmask<mode>"
5134   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5135         (if_then_else:V2DI
5136          (match_operator:CCFP 1 "fpmask_comparison_operator"
5137                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5138                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5139          (match_operand:V2DI 4 "all_ones_constant" "")
5140          (match_operand:V2DI 5 "zero_constant" "")))]
5141   "TARGET_P9_MINMAX"
5142   "xscmp%V1dp %x0,%x2,%x3"
5143   [(set_attr "type" "fpcompare")])
5145 (define_insn "*xxsel<mode>"
5146   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5147         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5148                                (match_operand:V2DI 2 "zero_constant" ""))
5149                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5150                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5151   "TARGET_P9_MINMAX"
5152   "xxsel %x0,%x4,%x3,%x1"
5153   [(set_attr "type" "vecmove")])
5156 ;; Conversions to and from floating-point.
5158 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5159 ; don't want to support putting SImode in FPR registers.
5160 (define_insn "lfiwax"
5161   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5162         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5163                    UNSPEC_LFIWAX))]
5164   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5165   "@
5166    lfiwax %0,%y1
5167    lxsiwax %x0,%y1
5168    mtvsrwa %x0,%1
5169    vextsw2d %0,%1"
5170   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5172 ; This split must be run before register allocation because it allocates the
5173 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5174 ; it earlier to allow for the combiner to merge insns together where it might
5175 ; not be needed and also in case the insns are deleted as dead code.
5177 (define_insn_and_split "floatsi<mode>2_lfiwax"
5178   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5179         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5180    (clobber (match_scratch:DI 2 "=wi"))]
5181   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5182    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5183   "#"
5184   ""
5185   [(pc)]
5187   rtx dest = operands[0];
5188   rtx src = operands[1];
5189   rtx tmp;
5191   if (!MEM_P (src) && TARGET_POWERPC64
5192       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5193     tmp = convert_to_mode (DImode, src, false);
5194   else
5195     {
5196       tmp = operands[2];
5197       if (GET_CODE (tmp) == SCRATCH)
5198         tmp = gen_reg_rtx (DImode);
5199       if (MEM_P (src))
5200         {
5201           src = rs6000_address_for_fpconvert (src);
5202           emit_insn (gen_lfiwax (tmp, src));
5203         }
5204       else
5205         {
5206           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5207           emit_move_insn (stack, src);
5208           emit_insn (gen_lfiwax (tmp, stack));
5209         }
5210     }
5211   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5212   DONE;
5214   [(set_attr "length" "12")
5215    (set_attr "type" "fpload")])
5217 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5218   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5219         (float:SFDF
5220          (sign_extend:DI
5221           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5222    (clobber (match_scratch:DI 2 "=wi"))]
5223   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5224   "#"
5225   ""
5226   [(pc)]
5228   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5229   if (GET_CODE (operands[2]) == SCRATCH)
5230     operands[2] = gen_reg_rtx (DImode);
5231   if (TARGET_P8_VECTOR)
5232     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5233   else
5234     emit_insn (gen_lfiwax (operands[2], operands[1]));
5235   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5236   DONE;
5238   [(set_attr "length" "8")
5239    (set_attr "type" "fpload")])
5241 (define_insn "lfiwzx"
5242   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5243         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5244                    UNSPEC_LFIWZX))]
5245   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5246   "@
5247    lfiwzx %0,%y1
5248    lxsiwzx %x0,%y1
5249    mtvsrwz %x0,%1
5250    xxextractuw %x0,%x1,4"
5251   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5253 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5254   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5255         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5256    (clobber (match_scratch:DI 2 "=wi"))]
5257   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5258   "#"
5259   ""
5260   [(pc)]
5262   rtx dest = operands[0];
5263   rtx src = operands[1];
5264   rtx tmp;
5266   if (!MEM_P (src) && TARGET_POWERPC64
5267       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5268     tmp = convert_to_mode (DImode, src, true);
5269   else
5270     {
5271       tmp = operands[2];
5272       if (GET_CODE (tmp) == SCRATCH)
5273         tmp = gen_reg_rtx (DImode);
5274       if (MEM_P (src))
5275         {
5276           src = rs6000_address_for_fpconvert (src);
5277           emit_insn (gen_lfiwzx (tmp, src));
5278         }
5279       else
5280         {
5281           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5282           emit_move_insn (stack, src);
5283           emit_insn (gen_lfiwzx (tmp, stack));
5284         }
5285     }
5286   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5287   DONE;
5289   [(set_attr "length" "12")
5290    (set_attr "type" "fpload")])
5292 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5293   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5294         (unsigned_float:SFDF
5295          (zero_extend:DI
5296           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5297    (clobber (match_scratch:DI 2 "=wi"))]
5298   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5299   "#"
5300   ""
5301   [(pc)]
5303   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5304   if (GET_CODE (operands[2]) == SCRATCH)
5305     operands[2] = gen_reg_rtx (DImode);
5306   if (TARGET_P8_VECTOR)
5307     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5308   else
5309     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5310   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5311   DONE;
5313   [(set_attr "length" "8")
5314    (set_attr "type" "fpload")])
5316 ; For each of these conversions, there is a define_expand, a define_insn
5317 ; with a '#' template, and a define_split (with C code).  The idea is
5318 ; to allow constant folding with the template of the define_insn,
5319 ; then to have the insns split later (between sched1 and final).
5321 (define_expand "floatsidf2"
5322   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5323                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5324               (use (match_dup 2))
5325               (use (match_dup 3))
5326               (clobber (match_dup 4))
5327               (clobber (match_dup 5))
5328               (clobber (match_dup 6))])]
5329   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5331   if (TARGET_LFIWAX && TARGET_FCFID)
5332     {
5333       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5334       DONE;
5335     }
5336   else if (TARGET_FCFID)
5337     {
5338       rtx dreg = operands[1];
5339       if (!REG_P (dreg))
5340         dreg = force_reg (SImode, dreg);
5341       dreg = convert_to_mode (DImode, dreg, false);
5342       emit_insn (gen_floatdidf2 (operands[0], dreg));
5343       DONE;
5344     }
5346   if (!REG_P (operands[1]))
5347     operands[1] = force_reg (SImode, operands[1]);
5348   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5349   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5350   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5351   operands[5] = gen_reg_rtx (DFmode);
5352   operands[6] = gen_reg_rtx (SImode);
5355 (define_insn_and_split "*floatsidf2_internal"
5356   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5357         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5358    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5359    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5360    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5361    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5362    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5363   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5364   "#"
5365   ""
5366   [(pc)]
5368   rtx lowword, highword;
5369   gcc_assert (MEM_P (operands[4]));
5370   highword = adjust_address (operands[4], SImode, 0);
5371   lowword = adjust_address (operands[4], SImode, 4);
5372   if (! WORDS_BIG_ENDIAN)
5373     std::swap (lowword, highword);
5375   emit_insn (gen_xorsi3 (operands[6], operands[1],
5376                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5377   emit_move_insn (lowword, operands[6]);
5378   emit_move_insn (highword, operands[2]);
5379   emit_move_insn (operands[5], operands[4]);
5380   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5381   DONE;
5383   [(set_attr "length" "24")
5384    (set_attr "type" "fp")])
5386 ;; If we don't have a direct conversion to single precision, don't enable this
5387 ;; conversion for 32-bit without fast math, because we don't have the insn to
5388 ;; generate the fixup swizzle to avoid double rounding problems.
5389 (define_expand "floatunssisf2"
5390   [(set (match_operand:SF 0 "gpc_reg_operand")
5391         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5392   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5393    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5394        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5395            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5397   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5398     {
5399       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5400       DONE;
5401     }
5402   else
5403     {
5404       rtx dreg = operands[1];
5405       if (!REG_P (dreg))
5406         dreg = force_reg (SImode, dreg);
5407       dreg = convert_to_mode (DImode, dreg, true);
5408       emit_insn (gen_floatdisf2 (operands[0], dreg));
5409       DONE;
5410     }
5413 (define_expand "floatunssidf2"
5414   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5415                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5416               (use (match_dup 2))
5417               (use (match_dup 3))
5418               (clobber (match_dup 4))
5419               (clobber (match_dup 5))])]
5420   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5422   if (TARGET_LFIWZX && TARGET_FCFID)
5423     {
5424       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5425       DONE;
5426     }
5427   else if (TARGET_FCFID)
5428     {
5429       rtx dreg = operands[1];
5430       if (!REG_P (dreg))
5431         dreg = force_reg (SImode, dreg);
5432       dreg = convert_to_mode (DImode, dreg, true);
5433       emit_insn (gen_floatdidf2 (operands[0], dreg));
5434       DONE;
5435     }
5437   if (!REG_P (operands[1]))
5438     operands[1] = force_reg (SImode, operands[1]);
5439   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5440   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5441   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5442   operands[5] = gen_reg_rtx (DFmode);
5445 (define_insn_and_split "*floatunssidf2_internal"
5446   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5447         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5448    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5449    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5450    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5451    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5452   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5453    && !(TARGET_FCFID && TARGET_POWERPC64)"
5454   "#"
5455   ""
5456   [(pc)]
5458   rtx lowword, highword;
5459   gcc_assert (MEM_P (operands[4]));
5460   highword = adjust_address (operands[4], SImode, 0);
5461   lowword = adjust_address (operands[4], SImode, 4);
5462   if (! WORDS_BIG_ENDIAN)
5463     std::swap (lowword, highword);
5465   emit_move_insn (lowword, operands[1]);
5466   emit_move_insn (highword, operands[2]);
5467   emit_move_insn (operands[5], operands[4]);
5468   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5469   DONE;
5471   [(set_attr "length" "20")
5472    (set_attr "type" "fp")])
5474 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5475 ;; vector registers.  These insns favor doing the sign/zero extension in
5476 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5477 ;; extension and then a direct move.
5479 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5480   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5481                    (float:FP_ISA3
5482                     (match_operand:QHI 1 "input_operand")))
5483               (clobber (match_scratch:DI 2))
5484               (clobber (match_scratch:DI 3))
5485               (clobber (match_scratch:<QHI:MODE> 4))])]
5486   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5488   if (MEM_P (operands[1]))
5489     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5492 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5493   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5494         (float:FP_ISA3
5495          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5496    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5497    (clobber (match_scratch:DI 3 "=X,r,X"))
5498    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5499   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5500   "#"
5501   "&& reload_completed"
5502   [(const_int 0)]
5504   rtx result = operands[0];
5505   rtx input = operands[1];
5506   rtx di = operands[2];
5508   if (!MEM_P (input))
5509     {
5510       rtx tmp = operands[3];
5511       if (altivec_register_operand (input, <QHI:MODE>mode))
5512         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5513       else if (GET_CODE (tmp) == SCRATCH)
5514         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5515       else
5516         {
5517           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5518           emit_move_insn (di, tmp);
5519         }
5520     }
5521   else
5522     {
5523       rtx tmp = operands[4];
5524       emit_move_insn (tmp, input);
5525       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5526     }
5528   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5529   DONE;
5532 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5533   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5534                    (unsigned_float:FP_ISA3
5535                     (match_operand:QHI 1 "input_operand")))
5536               (clobber (match_scratch:DI 2))
5537               (clobber (match_scratch:DI 3))])]
5538   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5540   if (MEM_P (operands[1]))
5541     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5544 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5545   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5546         (unsigned_float:FP_ISA3
5547          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5548    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5549    (clobber (match_scratch:DI 3 "=X,r,X"))]
5550   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5551   "#"
5552   "&& reload_completed"
5553   [(const_int 0)]
5555   rtx result = operands[0];
5556   rtx input = operands[1];
5557   rtx di = operands[2];
5559   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5560     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5561   else
5562     {
5563       rtx tmp = operands[3];
5564       if (GET_CODE (tmp) == SCRATCH)
5565         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5566       else
5567         {
5568           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5569           emit_move_insn (di, tmp);
5570         }
5571     }
5573   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5574   DONE;
5577 (define_expand "fix_trunc<mode>si2"
5578   [(set (match_operand:SI 0 "gpc_reg_operand")
5579         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5580   "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5582   if (!TARGET_P8_VECTOR)
5583     {
5584       rtx src = force_reg (<MODE>mode, operands[1]);
5586       if (TARGET_STFIWX)
5587         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5588       else
5589         {
5590           rtx tmp = gen_reg_rtx (DImode);
5591           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5592           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5593                                                       tmp, stack));
5594         }
5595       DONE;
5596     }
5599 ; Like the convert to float patterns, this insn must be split before
5600 ; register allocation so that it can allocate the memory slot if it
5601 ; needed
5602 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5603   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5604         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5605    (clobber (match_scratch:DI 2 "=d"))]
5606   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5607    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5608    && TARGET_STFIWX && can_create_pseudo_p ()
5609    && !TARGET_P8_VECTOR"
5610   "#"
5611   ""
5612   [(pc)]
5614   rtx dest = operands[0];
5615   rtx src = operands[1];
5616   rtx tmp = operands[2];
5618   if (GET_CODE (tmp) == SCRATCH)
5619     tmp = gen_reg_rtx (DImode);
5621   emit_insn (gen_fctiwz_<mode> (tmp, src));
5622   if (MEM_P (dest))
5623     {
5624       dest = rs6000_address_for_fpconvert (dest);
5625       emit_insn (gen_stfiwx (dest, tmp));
5626       DONE;
5627     }
5628   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5629     {
5630       dest = gen_lowpart (DImode, dest);
5631       emit_move_insn (dest, tmp);
5632       DONE;
5633     }
5634   else
5635     {
5636       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5637       emit_insn (gen_stfiwx (stack, tmp));
5638       emit_move_insn (dest, stack);
5639       DONE;
5640     }
5642   [(set_attr "length" "12")
5643    (set_attr "type" "fp")])
5645 (define_insn_and_split "fix_trunc<mode>si2_internal"
5646   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5647         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5648    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5649    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5650   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5651   "#"
5652   ""
5653   [(pc)]
5655   rtx lowword;
5656   gcc_assert (MEM_P (operands[3]));
5657   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5659   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5660   emit_move_insn (operands[3], operands[2]);
5661   emit_move_insn (operands[0], lowword);
5662   DONE;
5664   [(set_attr "length" "16")
5665    (set_attr "type" "fp")])
5667 (define_expand "fix_trunc<mode>di2"
5668   [(set (match_operand:DI 0 "gpc_reg_operand")
5669         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5670   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5671   "")
5673 (define_insn "*fix_trunc<mode>di2_fctidz"
5674   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5675         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5676   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5677   "@
5678    fctidz %0,%1
5679    xscvdpsxds %x0,%x1"
5680   [(set_attr "type" "fp")])
5682 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5683 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5684 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5685 ;; values can go in VSX registers.  Keeping the direct move part through
5686 ;; register allocation prevents the register allocator from doing a direct move
5687 ;; of the SImode value to a GPR, and then a store/load.
5688 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5689   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5690         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5691    (clobber (match_scratch:SI 2 "=X,X,wi"))]
5692   "TARGET_DIRECT_MOVE"
5693   "@
5694    fctiw<u>z %0,%1
5695    xscvdp<su>xws %x0,%x1
5696    #"
5697   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5698   [(set (match_dup 2)
5699         (any_fix:SI (match_dup 1)))
5700    (set (match_dup 3)
5701         (match_dup 2))]
5703   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5705   [(set_attr "length" "4,4,8")
5706    (set_attr "type" "fp")])
5708 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5709   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5710         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5711   "TARGET_DIRECT_MOVE"
5712   "@
5713    fctiw<u>z %0,%1
5714    xscvdp<su>xws %x0,%x1"
5715   [(set_attr "type" "fp")])
5717 ;; Keep the convert and store together through register allocation to prevent
5718 ;; the register allocator from getting clever and doing a direct move to a GPR
5719 ;; and then store for reg+offset stores.
5720 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5721   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5722         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5723    (clobber (match_scratch:SI 2 "=wa"))]
5724     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5725   "#"
5726   "&& reload_completed"
5727   [(set (match_dup 2)
5728         (any_fix:SI (match_dup 1)))
5729    (set (match_dup 0)
5730         (match_dup 3))]
5732   operands[3] = (<QHSI:MODE>mode == SImode
5733                  ? operands[2]
5734                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5737 (define_expand "fixuns_trunc<mode>si2"
5738   [(set (match_operand:SI 0 "gpc_reg_operand")
5739         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5740   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5742   if (!TARGET_P8_VECTOR)
5743     {
5744       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5745       DONE;
5746     }
5749 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5750   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5751         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5752    (clobber (match_scratch:DI 2 "=d"))]
5753   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5754    && TARGET_STFIWX && can_create_pseudo_p ()
5755    && !TARGET_P8_VECTOR"
5756   "#"
5757   ""
5758   [(pc)]
5760   rtx dest = operands[0];
5761   rtx src = operands[1];
5762   rtx tmp = operands[2];
5764   if (GET_CODE (tmp) == SCRATCH)
5765     tmp = gen_reg_rtx (DImode);
5767   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5768   if (MEM_P (dest))
5769     {
5770       dest = rs6000_address_for_fpconvert (dest);
5771       emit_insn (gen_stfiwx (dest, tmp));
5772       DONE;
5773     }
5774   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5775     {
5776       dest = gen_lowpart (DImode, dest);
5777       emit_move_insn (dest, tmp);
5778       DONE;
5779     }
5780   else
5781     {
5782       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5783       emit_insn (gen_stfiwx (stack, tmp));
5784       emit_move_insn (dest, stack);
5785       DONE;
5786     }
5788   [(set_attr "length" "12")
5789    (set_attr "type" "fp")])
5791 (define_insn "fixuns_trunc<mode>di2"
5792   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5793         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5794   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5795   "@
5796    fctiduz %0,%1
5797    xscvdpuxds %x0,%x1"
5798   [(set_attr "type" "fp")])
5800 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5801 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5802 ;; because the first makes it clear that operand 0 is not live
5803 ;; before the instruction.
5804 (define_insn "fctiwz_<mode>"
5805   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5806         (unspec:DI [(fix:SI
5807                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5808                    UNSPEC_FCTIWZ))]
5809   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5810   "@
5811    fctiwz %0,%1
5812    xscvdpsxws %x0,%x1"
5813   [(set_attr "type" "fp")])
5815 (define_insn "fctiwuz_<mode>"
5816   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5817         (unspec:DI [(unsigned_fix:SI
5818                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5819                    UNSPEC_FCTIWUZ))]
5820   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5821   "@
5822    fctiwuz %0,%1
5823    xscvdpuxws %x0,%x1"
5824   [(set_attr "type" "fp")])
5826 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5827 ;; since the friz instruction does not truncate the value if the floating
5828 ;; point value is < LONG_MIN or > LONG_MAX.
5829 (define_insn "*friz"
5830   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5831         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5832   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5833    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5834   "@
5835    friz %0,%1
5836    xsrdpiz %x0,%x1"
5837   [(set_attr "type" "fp")])
5839 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5840 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5841 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5842 ;; extend it, store it back on the stack from the GPR, load it back into the
5843 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5844 ;; disable using store and load to sign/zero extend the value.
5845 (define_insn_and_split "*round32<mode>2_fprs"
5846   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5847         (float:SFDF
5848          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5849    (clobber (match_scratch:DI 2 "=d"))
5850    (clobber (match_scratch:DI 3 "=d"))]
5851   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5852    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5853    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5854   "#"
5855   ""
5856   [(pc)]
5858   rtx dest = operands[0];
5859   rtx src = operands[1];
5860   rtx tmp1 = operands[2];
5861   rtx tmp2 = operands[3];
5862   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5864   if (GET_CODE (tmp1) == SCRATCH)
5865     tmp1 = gen_reg_rtx (DImode);
5866   if (GET_CODE (tmp2) == SCRATCH)
5867     tmp2 = gen_reg_rtx (DImode);
5869   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5870   emit_insn (gen_stfiwx (stack, tmp1));
5871   emit_insn (gen_lfiwax (tmp2, stack));
5872   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5873   DONE;
5875   [(set_attr "type" "fpload")
5876    (set_attr "length" "16")])
5878 (define_insn_and_split "*roundu32<mode>2_fprs"
5879   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5880         (unsigned_float:SFDF
5881          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5882    (clobber (match_scratch:DI 2 "=d"))
5883    (clobber (match_scratch:DI 3 "=d"))]
5884   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5885    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5886    && can_create_pseudo_p ()"
5887   "#"
5888   ""
5889   [(pc)]
5891   rtx dest = operands[0];
5892   rtx src = operands[1];
5893   rtx tmp1 = operands[2];
5894   rtx tmp2 = operands[3];
5895   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5897   if (GET_CODE (tmp1) == SCRATCH)
5898     tmp1 = gen_reg_rtx (DImode);
5899   if (GET_CODE (tmp2) == SCRATCH)
5900     tmp2 = gen_reg_rtx (DImode);
5902   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5903   emit_insn (gen_stfiwx (stack, tmp1));
5904   emit_insn (gen_lfiwzx (tmp2, stack));
5905   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5906   DONE;
5908   [(set_attr "type" "fpload")
5909    (set_attr "length" "16")])
5911 (define_insn "lrintsfsi2"
5912   [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
5913         (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
5914                    UNSPEC_FCTIW))]
5915   "TARGET_SF_FPR && TARGET_FPRND"
5916   "fctiw %0,%1"
5917   [(set_attr "type" "fp")])
5919 ;; No VSX equivalent to fctid
5920 (define_insn "lrint<mode>di2"
5921   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5922         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5923                    UNSPEC_FCTID))]
5924   "TARGET_<MODE>_FPR && TARGET_FPRND"
5925   "fctid %0,%1"
5926   [(set_attr "type" "fp")])
5928 (define_insn "btrunc<mode>2"
5929   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5930         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5931                      UNSPEC_FRIZ))]
5932   "TARGET_<MODE>_FPR && TARGET_FPRND"
5933   "@
5934    friz %0,%1
5935    xsrdpiz %x0,%x1"
5936   [(set_attr "type" "fp")
5937    (set_attr "fp_type" "fp_addsub_<Fs>")])
5939 (define_insn "ceil<mode>2"
5940   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5941         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5942                      UNSPEC_FRIP))]
5943   "TARGET_<MODE>_FPR && TARGET_FPRND"
5944   "@
5945    frip %0,%1
5946    xsrdpip %x0,%x1"
5947   [(set_attr "type" "fp")
5948    (set_attr "fp_type" "fp_addsub_<Fs>")])
5950 (define_insn "floor<mode>2"
5951   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5952         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5953                      UNSPEC_FRIM))]
5954   "TARGET_<MODE>_FPR && TARGET_FPRND"
5955   "@
5956    frim %0,%1
5957    xsrdpim %x0,%x1"
5958   [(set_attr "type" "fp")
5959    (set_attr "fp_type" "fp_addsub_<Fs>")])
5961 ;; No VSX equivalent to frin
5962 (define_insn "round<mode>2"
5963   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5964         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5965                      UNSPEC_FRIN))]
5966   "TARGET_<MODE>_FPR && TARGET_FPRND"
5967   "frin %0,%1"
5968   [(set_attr "type" "fp")
5969    (set_attr "fp_type" "fp_addsub_<Fs>")])
5971 (define_insn "*xsrdpi<mode>2"
5972   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5973         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5974                      UNSPEC_XSRDPI))]
5975   "TARGET_<MODE>_FPR && TARGET_VSX"
5976   "xsrdpi %x0,%x1"
5977   [(set_attr "type" "fp")
5978    (set_attr "fp_type" "fp_addsub_<Fs>")])
5980 (define_expand "lround<mode>di2"
5981   [(set (match_dup 2)
5982         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
5983                      UNSPEC_XSRDPI))
5984    (set (match_operand:DI 0 "gpc_reg_operand")
5985         (unspec:DI [(match_dup 2)]
5986                    UNSPEC_FCTID))]
5987   "TARGET_<MODE>_FPR && TARGET_VSX"
5989   operands[2] = gen_reg_rtx (<MODE>mode);
5992 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5993 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5994 ; is only generated for Power8 or later.
5995 (define_insn "stfiwx"
5996   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5997         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5998                    UNSPEC_STFIWX))]
5999   "TARGET_PPC_GFXOPT"
6000   "@
6001    stfiwx %1,%y0
6002    stxsiwx %x1,%y0"
6003   [(set_attr "type" "fpstore")])
6005 ;; If we don't have a direct conversion to single precision, don't enable this
6006 ;; conversion for 32-bit without fast math, because we don't have the insn to
6007 ;; generate the fixup swizzle to avoid double rounding problems.
6008 (define_expand "floatsisf2"
6009   [(set (match_operand:SF 0 "gpc_reg_operand")
6010         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6011   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6012    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6013        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6014            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6016   if (TARGET_FCFIDS && TARGET_LFIWAX)
6017     {
6018       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6019       DONE;
6020     }
6021   else if (TARGET_FCFID && TARGET_LFIWAX)
6022     {
6023       rtx dfreg = gen_reg_rtx (DFmode);
6024       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6025       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6026       DONE;
6027     }
6028   else
6029     {
6030       rtx dreg = operands[1];
6031       if (!REG_P (dreg))
6032         dreg = force_reg (SImode, dreg);
6033       dreg = convert_to_mode (DImode, dreg, false);
6034       emit_insn (gen_floatdisf2 (operands[0], dreg));
6035       DONE;
6036     }
6039 (define_insn "floatdidf2"
6040   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6041         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6042   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6043   "@
6044    fcfid %0,%1
6045    xscvsxddp %x0,%x1"
6046   [(set_attr "type" "fp")])
6048 ; Allow the combiner to merge source memory operands to the conversion so that
6049 ; the optimizer/register allocator doesn't try to load the value too early in a
6050 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6051 ; hit.  We will split after reload to avoid the trip through the GPRs
6053 (define_insn_and_split "*floatdidf2_mem"
6054   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6055         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6056    (clobber (match_scratch:DI 2 "=d,wi"))]
6057   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6058   "#"
6059   "&& reload_completed"
6060   [(set (match_dup 2) (match_dup 1))
6061    (set (match_dup 0) (float:DF (match_dup 2)))]
6062   ""
6063   [(set_attr "length" "8")
6064    (set_attr "type" "fpload")])
6066 (define_expand "floatunsdidf2"
6067   [(set (match_operand:DF 0 "gpc_reg_operand")
6068         (unsigned_float:DF
6069          (match_operand:DI 1 "gpc_reg_operand")))]
6070   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6071   "")
6073 (define_insn "*floatunsdidf2_fcfidu"
6074   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6075         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6076   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6077   "@
6078    fcfidu %0,%1
6079    xscvuxddp %x0,%x1"
6080   [(set_attr "type" "fp")
6081    (set_attr "length" "4")])
6083 (define_insn_and_split "*floatunsdidf2_mem"
6084   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6085         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6086    (clobber (match_scratch:DI 2 "=d,wi"))]
6087   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6088   "#"
6089   "&& reload_completed"
6090   [(set (match_dup 2) (match_dup 1))
6091    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6092   ""
6093   [(set_attr "length" "8")
6094    (set_attr "type" "fpload")])
6096 (define_expand "floatdisf2"
6097   [(set (match_operand:SF 0 "gpc_reg_operand")
6098         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6099   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6100    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6102   if (!TARGET_FCFIDS)
6103     {
6104       rtx val = operands[1];
6105       if (!flag_unsafe_math_optimizations)
6106         {
6107           rtx label = gen_label_rtx ();
6108           val = gen_reg_rtx (DImode);
6109           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6110           emit_label (label);
6111         }
6112       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6113       DONE;
6114     }
6117 (define_insn "floatdisf2_fcfids"
6118   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6119         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6120   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6121    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6122   "@
6123    fcfids %0,%1
6124    xscvsxdsp %x0,%x1"
6125   [(set_attr "type" "fp")])
6127 (define_insn_and_split "*floatdisf2_mem"
6128   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6129         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6130    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6131   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6132    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6133   "#"
6134   "&& reload_completed"
6135   [(pc)]
6137   emit_move_insn (operands[2], operands[1]);
6138   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6139   DONE;
6141   [(set_attr "length" "8")])
6143 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6144 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6145 ;; from double rounding.
6146 ;; Instead of creating a new cpu type for two FP operations, just use fp
6147 (define_insn_and_split "floatdisf2_internal1"
6148   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6149         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6150    (clobber (match_scratch:DF 2 "=d"))]
6151   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6152   "#"
6153   "&& reload_completed"
6154   [(set (match_dup 2)
6155         (float:DF (match_dup 1)))
6156    (set (match_dup 0)
6157         (float_truncate:SF (match_dup 2)))]
6158   ""
6159   [(set_attr "length" "8")
6160    (set_attr "type" "fp")])
6162 ;; Twiddles bits to avoid double rounding.
6163 ;; Bits that might be truncated when converting to DFmode are replaced
6164 ;; by a bit that won't be lost at that stage, but is below the SFmode
6165 ;; rounding position.
6166 (define_expand "floatdisf2_internal2"
6167   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6168                                               (const_int 53)))
6169               (clobber (reg:DI CA_REGNO))])
6170    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6171                                         (const_int 2047)))
6172    (set (match_dup 3) (plus:DI (match_dup 3)
6173                                (const_int 1)))
6174    (set (match_dup 0) (plus:DI (match_dup 0)
6175                                (const_int 2047)))
6176    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6177                                      (const_int 2)))
6178    (set (match_dup 0) (ior:DI (match_dup 0)
6179                               (match_dup 1)))
6180    (set (match_dup 0) (and:DI (match_dup 0)
6181                               (const_int -2048)))
6182    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6183                            (label_ref (match_operand:DI 2 ""))
6184                            (pc)))
6185    (set (match_dup 0) (match_dup 1))]
6186   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6187    && !TARGET_FCFIDS"
6189   operands[3] = gen_reg_rtx (DImode);
6190   operands[4] = gen_reg_rtx (CCUNSmode);
6193 (define_expand "floatunsdisf2"
6194   [(set (match_operand:SF 0 "gpc_reg_operand")
6195         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6196   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6197    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6198   "")
6200 (define_insn "floatunsdisf2_fcfidus"
6201   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6202         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6203   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6204    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6205   "@
6206    fcfidus %0,%1
6207    xscvuxdsp %x0,%x1"
6208   [(set_attr "type" "fp")])
6210 (define_insn_and_split "*floatunsdisf2_mem"
6211   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6212         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6213    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6214   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6215    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6216   "#"
6217   "&& reload_completed"
6218   [(pc)]
6220   emit_move_insn (operands[2], operands[1]);
6221   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6222   DONE;
6224   [(set_attr "length" "8")
6225    (set_attr "type" "fpload")])
6227 ;; Define the TImode operations that can be done in a small number
6228 ;; of instructions.  The & constraints are to prevent the register
6229 ;; allocator from allocating registers that overlap with the inputs
6230 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6231 ;; also allow for the output being the same as one of the inputs.
6233 (define_expand "addti3"
6234   [(set (match_operand:TI 0 "gpc_reg_operand")
6235         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6236                  (match_operand:TI 2 "reg_or_short_operand")))]
6237   "TARGET_64BIT"
6239   rtx lo0 = gen_lowpart (DImode, operands[0]);
6240   rtx lo1 = gen_lowpart (DImode, operands[1]);
6241   rtx lo2 = gen_lowpart (DImode, operands[2]);
6242   rtx hi0 = gen_highpart (DImode, operands[0]);
6243   rtx hi1 = gen_highpart (DImode, operands[1]);
6244   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6246   if (!reg_or_short_operand (lo2, DImode))
6247     lo2 = force_reg (DImode, lo2);
6248   if (!adde_operand (hi2, DImode))
6249     hi2 = force_reg (DImode, hi2);
6251   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6252   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6253   DONE;
6256 (define_expand "subti3"
6257   [(set (match_operand:TI 0 "gpc_reg_operand")
6258         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6259                   (match_operand:TI 2 "gpc_reg_operand")))]
6260   "TARGET_64BIT"
6262   rtx lo0 = gen_lowpart (DImode, operands[0]);
6263   rtx lo1 = gen_lowpart (DImode, operands[1]);
6264   rtx lo2 = gen_lowpart (DImode, operands[2]);
6265   rtx hi0 = gen_highpart (DImode, operands[0]);
6266   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6267   rtx hi2 = gen_highpart (DImode, operands[2]);
6269   if (!reg_or_short_operand (lo1, DImode))
6270     lo1 = force_reg (DImode, lo1);
6271   if (!adde_operand (hi1, DImode))
6272     hi1 = force_reg (DImode, hi1);
6274   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6275   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6276   DONE;
6279 ;; 128-bit logical operations expanders
6281 (define_expand "and<mode>3"
6282   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6283         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6284                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6285   ""
6286   "")
6288 (define_expand "ior<mode>3"
6289   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6290         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6291                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6292   ""
6293   "")
6295 (define_expand "xor<mode>3"
6296   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6297         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6298                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6299   ""
6300   "")
6302 (define_expand "one_cmpl<mode>2"
6303   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6304         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6305   ""
6306   "")
6308 (define_expand "nor<mode>3"
6309   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6310         (and:BOOL_128
6311          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6312          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6313   ""
6314   "")
6316 (define_expand "andc<mode>3"
6317   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6318         (and:BOOL_128
6319          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6320          (match_operand:BOOL_128 1 "vlogical_operand")))]
6321   ""
6322   "")
6324 ;; Power8 vector logical instructions.
6325 (define_expand "eqv<mode>3"
6326   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6327         (not:BOOL_128
6328          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6329                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6330   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6331   "")
6333 ;; Rewrite nand into canonical form
6334 (define_expand "nand<mode>3"
6335   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6336         (ior:BOOL_128
6337          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6338          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6339   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6340   "")
6342 ;; The canonical form is to have the negated element first, so we need to
6343 ;; reverse arguments.
6344 (define_expand "orc<mode>3"
6345   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6346         (ior:BOOL_128
6347          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6348          (match_operand:BOOL_128 1 "vlogical_operand")))]
6349   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6350   "")
6352 ;; 128-bit logical operations insns and split operations
6353 (define_insn_and_split "*and<mode>3_internal"
6354   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6355         (and:BOOL_128
6356          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6357          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6358   ""
6360   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6361     return "xxland %x0,%x1,%x2";
6363   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6364     return "vand %0,%1,%2";
6366   return "#";
6368   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6369   [(const_int 0)]
6371   rs6000_split_logical (operands, AND, false, false, false);
6372   DONE;
6374   [(set (attr "type")
6375       (if_then_else
6376         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6377         (const_string "veclogical")
6378         (const_string "integer")))
6379    (set (attr "length")
6380       (if_then_else
6381         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6382         (const_string "4")
6383         (if_then_else
6384          (match_test "TARGET_POWERPC64")
6385          (const_string "8")
6386          (const_string "16"))))])
6388 ;; 128-bit IOR/XOR
6389 (define_insn_and_split "*bool<mode>3_internal"
6390   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6391         (match_operator:BOOL_128 3 "boolean_or_operator"
6392          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6393           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6394   ""
6396   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6397     return "xxl%q3 %x0,%x1,%x2";
6399   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6400     return "v%q3 %0,%1,%2";
6402   return "#";
6404   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6405   [(const_int 0)]
6407   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6408   DONE;
6410   [(set (attr "type")
6411       (if_then_else
6412         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6413         (const_string "veclogical")
6414         (const_string "integer")))
6415    (set (attr "length")
6416       (if_then_else
6417         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6418         (const_string "4")
6419         (if_then_else
6420          (match_test "TARGET_POWERPC64")
6421          (const_string "8")
6422          (const_string "16"))))])
6424 ;; 128-bit ANDC/ORC
6425 (define_insn_and_split "*boolc<mode>3_internal1"
6426   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6427         (match_operator:BOOL_128 3 "boolean_operator"
6428          [(not:BOOL_128
6429            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6430           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6431   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6433   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6434     return "xxl%q3 %x0,%x1,%x2";
6436   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6437     return "v%q3 %0,%1,%2";
6439   return "#";
6441   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6442    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6443   [(const_int 0)]
6445   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6446   DONE;
6448   [(set (attr "type")
6449       (if_then_else
6450         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6451         (const_string "veclogical")
6452         (const_string "integer")))
6453    (set (attr "length")
6454       (if_then_else
6455         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6456         (const_string "4")
6457         (if_then_else
6458          (match_test "TARGET_POWERPC64")
6459          (const_string "8")
6460          (const_string "16"))))])
6462 (define_insn_and_split "*boolc<mode>3_internal2"
6463   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6464         (match_operator:TI2 3 "boolean_operator"
6465          [(not:TI2
6466            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6467           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6468   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6469   "#"
6470   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6471   [(const_int 0)]
6473   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6474   DONE;
6476   [(set_attr "type" "integer")
6477    (set (attr "length")
6478         (if_then_else
6479          (match_test "TARGET_POWERPC64")
6480          (const_string "8")
6481          (const_string "16")))])
6483 ;; 128-bit NAND/NOR
6484 (define_insn_and_split "*boolcc<mode>3_internal1"
6485   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6486         (match_operator:BOOL_128 3 "boolean_operator"
6487          [(not:BOOL_128
6488            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6489           (not:BOOL_128
6490            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6491   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6493   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6494     return "xxl%q3 %x0,%x1,%x2";
6496   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6497     return "v%q3 %0,%1,%2";
6499   return "#";
6501   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6502    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6503   [(const_int 0)]
6505   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6506   DONE;
6508   [(set (attr "type")
6509       (if_then_else
6510         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6511         (const_string "veclogical")
6512         (const_string "integer")))
6513    (set (attr "length")
6514       (if_then_else
6515         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6516         (const_string "4")
6517         (if_then_else
6518          (match_test "TARGET_POWERPC64")
6519          (const_string "8")
6520          (const_string "16"))))])
6522 (define_insn_and_split "*boolcc<mode>3_internal2"
6523   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6524         (match_operator:TI2 3 "boolean_operator"
6525          [(not:TI2
6526            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6527           (not:TI2
6528            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6529   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6530   "#"
6531   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6532   [(const_int 0)]
6534   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6535   DONE;
6537   [(set_attr "type" "integer")
6538    (set (attr "length")
6539         (if_then_else
6540          (match_test "TARGET_POWERPC64")
6541          (const_string "8")
6542          (const_string "16")))])
6545 ;; 128-bit EQV
6546 (define_insn_and_split "*eqv<mode>3_internal1"
6547   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6548         (not:BOOL_128
6549          (xor:BOOL_128
6550           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6551           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6552   "TARGET_P8_VECTOR"
6554   if (vsx_register_operand (operands[0], <MODE>mode))
6555     return "xxleqv %x0,%x1,%x2";
6557   return "#";
6559   "TARGET_P8_VECTOR && reload_completed
6560    && int_reg_operand (operands[0], <MODE>mode)"
6561   [(const_int 0)]
6563   rs6000_split_logical (operands, XOR, true, false, false);
6564   DONE;
6566   [(set (attr "type")
6567       (if_then_else
6568         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6569         (const_string "veclogical")
6570         (const_string "integer")))
6571    (set (attr "length")
6572       (if_then_else
6573         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6574         (const_string "4")
6575         (if_then_else
6576          (match_test "TARGET_POWERPC64")
6577          (const_string "8")
6578          (const_string "16"))))])
6580 (define_insn_and_split "*eqv<mode>3_internal2"
6581   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6582         (not:TI2
6583          (xor:TI2
6584           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6585           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6586   "!TARGET_P8_VECTOR"
6587   "#"
6588   "reload_completed && !TARGET_P8_VECTOR"
6589   [(const_int 0)]
6591   rs6000_split_logical (operands, XOR, true, false, false);
6592   DONE;
6594   [(set_attr "type" "integer")
6595    (set (attr "length")
6596         (if_then_else
6597          (match_test "TARGET_POWERPC64")
6598          (const_string "8")
6599          (const_string "16")))])
6601 ;; 128-bit one's complement
6602 (define_insn_and_split "*one_cmpl<mode>3_internal"
6603   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6604         (not:BOOL_128
6605           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6606   ""
6608   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6609     return "xxlnor %x0,%x1,%x1";
6611   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6612     return "vnor %0,%1,%1";
6614   return "#";
6616   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6617   [(const_int 0)]
6619   rs6000_split_logical (operands, NOT, false, false, false);
6620   DONE;
6622   [(set (attr "type")
6623       (if_then_else
6624         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6625         (const_string "veclogical")
6626         (const_string "integer")))
6627    (set (attr "length")
6628       (if_then_else
6629         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6630         (const_string "4")
6631         (if_then_else
6632          (match_test "TARGET_POWERPC64")
6633          (const_string "8")
6634          (const_string "16"))))])
6637 ;; Now define ways of moving data around.
6639 ;; Set up a register with a value from the GOT table
6641 (define_expand "movsi_got"
6642   [(set (match_operand:SI 0 "gpc_reg_operand")
6643         (unspec:SI [(match_operand:SI 1 "got_operand")
6644                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6645   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6647   if (GET_CODE (operands[1]) == CONST)
6648     {
6649       rtx offset = const0_rtx;
6650       HOST_WIDE_INT value;
6652       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6653       value = INTVAL (offset);
6654       if (value != 0)
6655         {
6656           rtx tmp = (!can_create_pseudo_p ()
6657                      ? operands[0]
6658                      : gen_reg_rtx (Pmode));
6659           emit_insn (gen_movsi_got (tmp, operands[1]));
6660           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6661           DONE;
6662         }
6663     }
6665   operands[2] = rs6000_got_register (operands[1]);
6668 (define_insn "*movsi_got_internal"
6669   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6670         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6671                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6672                    UNSPEC_MOVSI_GOT))]
6673   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6674   "lwz %0,%a1@got(%2)"
6675   [(set_attr "type" "load")])
6677 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6678 ;; didn't get allocated to a hard register.
6679 (define_split
6680   [(set (match_operand:SI 0 "gpc_reg_operand")
6681         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6682                     (match_operand:SI 2 "memory_operand")]
6683                    UNSPEC_MOVSI_GOT))]
6684   "DEFAULT_ABI == ABI_V4
6685     && flag_pic == 1
6686     && reload_completed"
6687   [(set (match_dup 0) (match_dup 2))
6688    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6689                                  UNSPEC_MOVSI_GOT))]
6690   "")
6692 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6693 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6694 ;; and this is even supposed to be faster, but it is simpler not to get
6695 ;; integers in the TOC.
6696 (define_insn "movsi_low"
6697   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6698         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6699                            (match_operand 2 "" ""))))]
6700   "TARGET_MACHO && ! TARGET_64BIT"
6701   "lwz %0,lo16(%2)(%1)"
6702   [(set_attr "type" "load")
6703    (set_attr "length" "4")])
6705 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6706 ;;              STW          STFIWX       STXSIWX      LI           LIS
6707 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6708 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6709 ;;              MF%1         MT%0         MT%0         NOP
6710 (define_insn "*movsi_internal1"
6711   [(set (match_operand:SI 0 "nonimmediate_operand"
6712                 "=r,         r,           r,           ?*wI,        ?*wH,
6713                  m,          ?Z,          ?Z,          r,           r,
6714                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6715                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6716                  r,          *c*l,        *h,          *h")
6718         (match_operand:SI 1 "input_operand"
6719                 "r,          U,           m,           Z,           Z,
6720                  r,          wI,          wH,          I,           L,
6721                  n,          wIwH,        O,           wM,          wB,
6722                  O,          wM,          wS,          r,           wIwH,
6723                  *h,         r,           r,           0"))]
6725   "!TARGET_SINGLE_FPU &&
6726    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6727   "@
6728    mr %0,%1
6729    la %0,%a1
6730    lwz%U1%X1 %0,%1
6731    lfiwzx %0,%y1
6732    lxsiwzx %x0,%y1
6733    stw%U0%X0 %1,%0
6734    stfiwx %1,%y0
6735    stxsiwx %x1,%y0
6736    li %0,%1
6737    lis %0,%v1
6738    #
6739    xxlor %x0,%x1,%x1
6740    xxspltib %x0,0
6741    xxspltib %x0,255
6742    vspltisw %0,%1
6743    xxlxor %x0,%x0,%x0
6744    xxlorc %x0,%x0,%x0
6745    #
6746    mtvsrwz %x0,%1
6747    mfvsrwz %0,%x1
6748    mf%1 %0
6749    mt%0 %1
6750    mt%0 %1
6751    nop"
6752   [(set_attr "type"
6753                 "*,          *,           load,        fpload,      fpload,
6754                  store,      fpstore,     fpstore,     *,           *,
6755                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6756                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6757                  *,           *,           *,           *")
6759    (set_attr "length"
6760                 "4,          4,           4,           4,           4,
6761                  4,          4,           4,           4,           4,
6762                  8,          4,           4,           4,           4,
6763                  4,          4,           8,           4,           4,
6764                  4,          4,           4,           4")])
6766 (define_insn "*movsi_internal1_single"
6767   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6768         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6769   "TARGET_SINGLE_FPU &&
6770    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6771   "@
6772    mr %0,%1
6773    la %0,%a1
6774    lwz%U1%X1 %0,%1
6775    stw%U0%X0 %1,%0
6776    li %0,%1
6777    lis %0,%v1
6778    #
6779    mf%1 %0
6780    mt%0 %1
6781    mt%0 %1
6782    nop
6783    stfs%U0%X0 %1,%0
6784    lfs%U1%X1 %0,%1"
6785   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6786    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6788 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6789 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6791 ;; Because SF values are actually stored as DF values within the vector
6792 ;; registers, we need to convert the value to the vector SF format when
6793 ;; we need to use the bits in a union or similar cases.  We only need
6794 ;; to do this transformation when the value is a vector register.  Loads,
6795 ;; stores, and transfers within GPRs are assumed to be safe.
6797 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6798 ;; no alternatives, because the call is created as part of secondary_reload,
6799 ;; and operand #2's register class is used to allocate the temporary register.
6800 ;; This function is called before reload, and it creates the temporary as
6801 ;; needed.
6803 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6804 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6805 ;;              MTVSRWZ
6807 (define_insn_and_split "movsi_from_sf"
6808   [(set (match_operand:SI 0 "nonimmediate_operand"
6809                 "=r,         r,           ?*wI,        ?*wH,     m,
6810                  m,          wY,          Z,           r,        ?*wIwH,
6811                  wIwH")
6813         (unspec:SI [(match_operand:SF 1 "input_operand"
6814                 "r,          m,           Z,           Z,        r,
6815                  f,          wb,          wu,          wIwH,     wIwH,
6816                  r")]
6817                     UNSPEC_SI_FROM_SF))
6819    (clobber (match_scratch:V4SF 2
6820                 "=X,         X,           X,           X,        X,
6821                  X,          X,           X,           wIwH,     X,
6822                  X"))]
6824   "TARGET_NO_SF_SUBREG
6825    && (register_operand (operands[0], SImode)
6826        || register_operand (operands[1], SFmode))"
6827   "@
6828    mr %0,%1
6829    lwz%U1%X1 %0,%1
6830    lfiwzx %0,%y1
6831    lxsiwzx %x0,%y1
6832    stw%U0%X0 %1,%0
6833    stfs%U0%X0 %1,%0
6834    stxssp %1,%0
6835    stxsspx %x1,%y0
6836    #
6837    xscvdpspn %x0,%x1
6838    mtvsrwz %x0,%1"
6839   "&& reload_completed
6840    && int_reg_operand (operands[0], SImode)
6841    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6842   [(const_int 0)]
6844   rtx op0 = operands[0];
6845   rtx op1 = operands[1];
6846   rtx op2 = operands[2];
6847   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6848   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6850   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6851   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6852   DONE;
6854   [(set_attr "type"
6855                 "*,          load,        fpload,      fpload,   store,
6856                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6857                  mffgpr")
6859    (set_attr "length"
6860                 "4,          4,           4,           4,        4,
6861                  4,          4,           4,           8,        4,
6862                  4")])
6864 ;; movsi_from_sf with zero extension
6866 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6867 ;;              VSX->VSX     MTVSRWZ
6869 (define_insn_and_split "*movdi_from_sf_zero_ext"
6870   [(set (match_operand:DI 0 "gpc_reg_operand"
6871                 "=r,         r,           ?*wI,        ?*wH,     r,
6872                  ?wK,        wIwH")
6874         (zero_extend:DI
6875          (unspec:SI [(match_operand:SF 1 "input_operand"
6876                 "r,          m,           Z,           Z,        wIwH,
6877                  wIwH,       r")]
6878                     UNSPEC_SI_FROM_SF)))
6880    (clobber (match_scratch:V4SF 2
6881                 "=X,         X,           X,           X,        wa,
6882                  wIwH,       X"))]
6884   "TARGET_DIRECT_MOVE_64BIT
6885    && (register_operand (operands[0], DImode)
6886        || register_operand (operands[1], SImode))"
6887   "@
6888    rldicl %0,%1,0,32
6889    lwz%U1%X1 %0,%1
6890    lfiwzx %0,%y1
6891    lxsiwzx %x0,%y1
6892    #
6893    #
6894    mtvsrwz %x0,%1"
6895   "&& reload_completed
6896    && register_operand (operands[0], DImode)
6897    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6898   [(const_int 0)]
6900   rtx op0 = operands[0];
6901   rtx op1 = operands[1];
6902   rtx op2 = operands[2];
6903   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6905   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6906   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6907   DONE;
6909   [(set_attr "type"
6910                 "*,          load,        fpload,      fpload,   two,
6911                  two,        mffgpr")
6913    (set_attr "length"
6914                 "4,          4,           4,           4,        8,
6915                  8,          4")])
6917 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6918 ;; moving it to SImode.  We can do a SFmode store without having to do the
6919 ;; conversion explicitly.  If we are doing a register->register conversion, use
6920 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6921 ;; input will not fit in a SFmode, and the later assumes the value has already
6922 ;; been rounded.
6923 (define_insn "*movsi_from_df"
6924   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
6925         (unspec:SI [(float_truncate:SF
6926                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6927                     UNSPEC_SI_FROM_SF))]
6929   "TARGET_NO_SF_SUBREG"
6930   "@
6931    xscvdpsp %x0,%x1
6932    stfs%U0%X0 %1,%0
6933    stxssp %1,%0
6934    stxsspx %x1,%y0"
6935   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
6937 ;; Split a load of a large constant into the appropriate two-insn
6938 ;; sequence.
6940 (define_split
6941   [(set (match_operand:SI 0 "gpc_reg_operand")
6942         (match_operand:SI 1 "const_int_operand"))]
6943   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6944    && (INTVAL (operands[1]) & 0xffff) != 0"
6945   [(set (match_dup 0)
6946         (match_dup 2))
6947    (set (match_dup 0)
6948         (ior:SI (match_dup 0)
6949                 (match_dup 3)))]
6951   if (rs6000_emit_set_const (operands[0], operands[1]))
6952     DONE;
6953   else
6954     FAIL;
6957 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6958 (define_split
6959   [(set (match_operand:DI 0 "altivec_register_operand")
6960         (match_operand:DI 1 "xxspltib_constant_split"))]
6961   "TARGET_P9_VECTOR && reload_completed"
6962   [(const_int 0)]
6964   rtx op0 = operands[0];
6965   rtx op1 = operands[1];
6966   int r = REGNO (op0);
6967   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6969   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6970   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6971   DONE;
6974 (define_insn "*mov<mode>_internal2"
6975   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6976         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6977                     (const_int 0)))
6978    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6979   ""
6980   "@
6981    cmp<wd>i %2,%0,0
6982    mr. %0,%1
6983    #"
6984   [(set_attr "type" "cmp,logical,cmp")
6985    (set_attr "dot" "yes")
6986    (set_attr "length" "4,4,8")])
6988 (define_split
6989   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6990         (compare:CC (match_operand:P 1 "gpc_reg_operand")
6991                     (const_int 0)))
6992    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6993   "reload_completed"
6994   [(set (match_dup 0) (match_dup 1))
6995    (set (match_dup 2)
6996         (compare:CC (match_dup 0)
6997                     (const_int 0)))]
6998   "")
7000 (define_expand "mov<mode>"
7001   [(set (match_operand:INT 0 "general_operand")
7002         (match_operand:INT 1 "any_operand"))]
7003   ""
7005   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7006   DONE;
7009 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7010 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7011 ;;              MTVSRWZ     MF%1       MT%1       NOP
7012 (define_insn "*mov<mode>_internal"
7013   [(set (match_operand:QHI 0 "nonimmediate_operand"
7014                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7015                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7016                  ?*wJwK,    r,         *c*l,      *h")
7018         (match_operand:QHI 1 "input_operand"
7019                 "r,         m,         Z,         r,         wJwK,      i,
7020                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7021                  r,         *h,        r,         0"))]
7023   "gpc_reg_operand (operands[0], <MODE>mode)
7024    || gpc_reg_operand (operands[1], <MODE>mode)"
7025   "@
7026    mr %0,%1
7027    l<wd>z%U1%X1 %0,%1
7028    lxsi<wd>zx %x0,%y1
7029    st<wd>%U0%X0 %1,%0
7030    stxsi<wd>x %x1,%y0
7031    li %0,%1
7032    xxlor %x0,%x1,%x1
7033    xxspltib %x0,0
7034    xxspltib %x0,255
7035    vspltis<wd> %0,%1
7036    #
7037    mfvsrwz %0,%x1
7038    mtvsrwz %x0,%1
7039    mf%1 %0
7040    mt%0 %1
7041    nop"
7042   [(set_attr "type"
7043                 "*,         load,      fpload,    store,     fpstore,   *,
7044                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7045                  mffgpr,    mfjmpr,    mtjmpr,    *")
7047    (set_attr "length"
7048                 "4,         4,         4,         4,         4,         4,
7049                  4,         4,         4,         4,         8,         4,
7050                  4,         4,         4,         4")])
7053 ;; Here is how to move condition codes around.  When we store CC data in
7054 ;; an integer register or memory, we store just the high-order 4 bits.
7055 ;; This lets us not shift in the most common case of CR0.
7056 (define_expand "movcc"
7057   [(set (match_operand:CC 0 "nonimmediate_operand")
7058         (match_operand:CC 1 "nonimmediate_operand"))]
7059   ""
7060   "")
7062 (define_insn "*movcc_internal1"
7063   [(set (match_operand:CC 0 "nonimmediate_operand"
7064                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7065         (match_operand:CC 1 "general_operand"
7066                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7067   "register_operand (operands[0], CCmode)
7068    || register_operand (operands[1], CCmode)"
7069   "@
7070    mcrf %0,%1
7071    mtcrf 128,%1
7072    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7073    crxor %0,%0,%0
7074    mfcr %0%Q1
7075    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7076    mr %0,%1
7077    li %0,%1
7078    mf%1 %0
7079    mt%0 %1
7080    lwz%U1%X1 %0,%1
7081    stw%U0%X0 %1,%0"
7082   [(set (attr "type")
7083      (cond [(eq_attr "alternative" "0,3")
7084                 (const_string "cr_logical")
7085             (eq_attr "alternative" "1,2")
7086                 (const_string "mtcr")
7087             (eq_attr "alternative" "6,7")
7088                 (const_string "integer")
7089             (eq_attr "alternative" "8")
7090                 (const_string "mfjmpr")
7091             (eq_attr "alternative" "9")
7092                 (const_string "mtjmpr")
7093             (eq_attr "alternative" "10")
7094                 (const_string "load")
7095             (eq_attr "alternative" "11")
7096                 (const_string "store")
7097             (match_test "TARGET_MFCRF")
7098                 (const_string "mfcrf")
7099            ]
7100         (const_string "mfcr")))
7101    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7103 ;; For floating-point, we normally deal with the floating-point registers
7104 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7105 ;; can produce floating-point values in fixed-point registers.  Unless the
7106 ;; value is a simple constant or already in memory, we deal with this by
7107 ;; allocating memory and copying the value explicitly via that memory location.
7109 ;; Move 32-bit binary/decimal floating point
7110 (define_expand "mov<mode>"
7111   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7112         (match_operand:FMOVE32 1 "any_operand"))]
7113   "<fmove_ok>"
7115   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7116   DONE;
7119 (define_split
7120   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7121         (match_operand:FMOVE32 1 "const_double_operand"))]
7122   "reload_completed
7123    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7124        || (GET_CODE (operands[0]) == SUBREG
7125            && GET_CODE (SUBREG_REG (operands[0])) == REG
7126            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7127   [(set (match_dup 2) (match_dup 3))]
7129   long l;
7131   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7133   if (! TARGET_POWERPC64)
7134     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7135   else
7136     operands[2] = gen_lowpart (SImode, operands[0]);
7138   operands[3] = gen_int_mode (l, SImode);
7141 ;; Originally, we tried to keep movsf and movsd common, but the differences
7142 ;; addressing was making it rather difficult to hide with mode attributes.  In
7143 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7144 ;; before the VSX stores meant that the register allocator would tend to do a
7145 ;; direct move to the GPR (which involves conversion from scalar to
7146 ;; vector/memory formats) to save values in the traditional Altivec registers,
7147 ;; while SDmode had problems on power6 if the GPR store was not first due to
7148 ;; the power6 not having an integer store operation.
7150 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7151 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7152 ;;      MR           MT<x>      MF<x>       NOP
7154 (define_insn "movsf_hardfloat"
7155   [(set (match_operand:SF 0 "nonimmediate_operand"
7156          "=!r,       f,         wb,         wu,        m,         wY,
7157           Z,         m,         ww,         !r,        f,         ww,
7158           !r,        *c*l,      !r,         *h")
7159         (match_operand:SF 1 "input_operand"
7160          "m,         m,         wY,         Z,         f,         wb,
7161           wu,        r,         j,          j,         f,         ww,
7162           r,         r,         *h,         0"))]
7163   "(register_operand (operands[0], SFmode)
7164    || register_operand (operands[1], SFmode))
7165    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7166    && (TARGET_ALLOW_SF_SUBREG
7167        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7168   "@
7169    lwz%U1%X1 %0,%1
7170    lfs%U1%X1 %0,%1
7171    lxssp %0,%1
7172    lxsspx %x0,%y1
7173    stfs%U0%X0 %1,%0
7174    stxssp %1,%0
7175    stxsspx %x1,%y0
7176    stw%U0%X0 %1,%0
7177    xxlxor %x0,%x0,%x0
7178    li %0,0
7179    fmr %0,%1
7180    xscpsgndp %x0,%x1,%x1
7181    mr %0,%1
7182    mt%0 %1
7183    mf%1 %0
7184    nop"
7185   [(set_attr "type"
7186         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7187          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7188          *,          mtjmpr,    mfjmpr,     *")])
7190 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7191 ;;      FMR          MR         MT%0       MF%1       NOP
7192 (define_insn "movsd_hardfloat"
7193   [(set (match_operand:SD 0 "nonimmediate_operand"
7194          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7195           f,         !r,        *c*l,      !r,        *h")
7196         (match_operand:SD 1 "input_operand"
7197          "m,         Z,         r,         wx,        r,         wh,
7198           f,         r,         r,         *h,        0"))]
7199   "(register_operand (operands[0], SDmode)
7200    || register_operand (operands[1], SDmode))
7201    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7202   "@
7203    lwz%U1%X1 %0,%1
7204    lfiwzx %0,%y1
7205    stw%U0%X0 %1,%0
7206    stfiwx %1,%y0
7207    mtvsrwz %x0,%1
7208    mfvsrwz %0,%x1
7209    fmr %0,%1
7210    mr %0,%1
7211    mt%0 %1
7212    mf%1 %0
7213    nop"
7214   [(set_attr "type"
7215         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7216          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7218 (define_insn "*mov<mode>_softfloat"
7219   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7220         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7221   "(gpc_reg_operand (operands[0], <MODE>mode)
7222    || gpc_reg_operand (operands[1], <MODE>mode))
7223    && TARGET_SOFT_FLOAT"
7224   "@
7225    mr %0,%1
7226    mt%0 %1
7227    mf%1 %0
7228    lwz%U1%X1 %0,%1
7229    stw%U0%X0 %1,%0
7230    li %0,%1
7231    lis %0,%v1
7232    #
7233    #
7234    nop"
7235   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7236    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7238 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7239 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7241 ;; Because SF values are actually stored as DF values within the vector
7242 ;; registers, we need to convert the value to the vector SF format when
7243 ;; we need to use the bits in a union or similar cases.  We only need
7244 ;; to do this transformation when the value is a vector register.  Loads,
7245 ;; stores, and transfers within GPRs are assumed to be safe.
7247 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7248 ;; no alternatives, because the call is created as part of secondary_reload,
7249 ;; and operand #2's register class is used to allocate the temporary register.
7250 ;; This function is called before reload, and it creates the temporary as
7251 ;; needed.
7253 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7254 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7255 (define_insn_and_split "movsf_from_si"
7256   [(set (match_operand:SF 0 "nonimmediate_operand"
7257             "=!r,       f,         wb,        wu,        m,         Z,
7258              Z,         wy,        ?r,        !r")
7260         (unspec:SF [(match_operand:SI 1 "input_operand" 
7261             "m,         m,         wY,        Z,         r,         f,
7262              wu,        r,         wy,        r")]
7263                    UNSPEC_SF_FROM_SI))
7265    (clobber (match_scratch:DI 2
7266             "=X,        X,         X,         X,         X,         X,
7267              X,         r,         X,         X"))]
7269   "TARGET_NO_SF_SUBREG
7270    && (register_operand (operands[0], SFmode)
7271        || register_operand (operands[1], SImode))"
7272   "@
7273    lwz%U1%X1 %0,%1
7274    lfs%U1%X1 %0,%1
7275    lxssp %0,%1
7276    lxsspx %x0,%y1
7277    stw%U0%X0 %1,%0
7278    stfiwx %1,%y0
7279    stxsiwx %x1,%y0
7280    #
7281    mfvsrwz %0,%x1
7282    mr %0,%1"
7284   "&& reload_completed
7285    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7286    && int_reg_operand_not_pseudo (operands[1], SImode)"
7287   [(const_int 0)]
7289   rtx op0 = operands[0];
7290   rtx op1 = operands[1];
7291   rtx op2 = operands[2];
7292   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7294   /* Move SF value to upper 32-bits for xscvspdpn.  */
7295   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7296   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7297   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7298   DONE;
7300   [(set_attr "length"
7301             "4,          4,         4,         4,         4,         4,
7302              4,          12,        4,         4")
7303    (set_attr "type"
7304             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7305              fpstore,    vecfloat,  mffgpr,    *")])
7308 ;; Move 64-bit binary/decimal floating point
7309 (define_expand "mov<mode>"
7310   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7311         (match_operand:FMOVE64 1 "any_operand"))]
7312   ""
7314   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7315   DONE;
7318 (define_split
7319   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7320         (match_operand:FMOVE64 1 "const_int_operand"))]
7321   "! TARGET_POWERPC64 && reload_completed
7322    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7323        || (GET_CODE (operands[0]) == SUBREG
7324            && GET_CODE (SUBREG_REG (operands[0])) == REG
7325            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7326   [(set (match_dup 2) (match_dup 4))
7327    (set (match_dup 3) (match_dup 1))]
7329   int endian = (WORDS_BIG_ENDIAN == 0);
7330   HOST_WIDE_INT value = INTVAL (operands[1]);
7332   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7333   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7334   operands[4] = GEN_INT (value >> 32);
7335   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7338 (define_split
7339   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7340         (match_operand:FMOVE64 1 "const_double_operand"))]
7341   "! TARGET_POWERPC64 && reload_completed
7342    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7343        || (GET_CODE (operands[0]) == SUBREG
7344            && GET_CODE (SUBREG_REG (operands[0])) == REG
7345            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7346   [(set (match_dup 2) (match_dup 4))
7347    (set (match_dup 3) (match_dup 5))]
7349   int endian = (WORDS_BIG_ENDIAN == 0);
7350   long l[2];
7352   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7354   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7355   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7356   operands[4] = gen_int_mode (l[endian], SImode);
7357   operands[5] = gen_int_mode (l[1 - endian], SImode);
7360 (define_split
7361   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7362         (match_operand:FMOVE64 1 "const_double_operand"))]
7363   "TARGET_POWERPC64 && reload_completed
7364    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7365        || (GET_CODE (operands[0]) == SUBREG
7366            && GET_CODE (SUBREG_REG (operands[0])) == REG
7367            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7368   [(set (match_dup 2) (match_dup 3))]
7370   int endian = (WORDS_BIG_ENDIAN == 0);
7371   long l[2];
7372   HOST_WIDE_INT val;
7374   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7376   operands[2] = gen_lowpart (DImode, operands[0]);
7377   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7378   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7379          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7381   operands[3] = gen_int_mode (val, DImode);
7384 ;; Don't have reload use general registers to load a constant.  It is
7385 ;; less efficient than loading the constant into an FP register, since
7386 ;; it will probably be used there.
7388 ;; The move constraints are ordered to prefer floating point registers before
7389 ;; general purpose registers to avoid doing a store and a load to get the value
7390 ;; into a floating point register when it is needed for a floating point
7391 ;; operation.  Prefer traditional floating point registers over VSX registers,
7392 ;; since the D-form version of the memory instructions does not need a GPR for
7393 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7394 ;; registers.
7396 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7397 ;; except for 0.0 which can be created on VSX with an xor instruction.
7399 (define_insn "*mov<mode>_hardfloat32"
7400   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7401         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7402   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 
7403    && (gpc_reg_operand (operands[0], <MODE>mode)
7404        || gpc_reg_operand (operands[1], <MODE>mode))"
7405   "@
7406    stfd%U0%X0 %1,%0
7407    lfd%U1%X1 %0,%1
7408    fmr %0,%1
7409    lxsd %0,%1
7410    stxsd %1,%0
7411    lxsd%U1x %x0,%y1
7412    stxsd%U0x %x1,%y0
7413    xxlor %x0,%x1,%x1
7414    xxlxor %x0,%x0,%x0
7415    #
7416    #
7417    #
7418    #"
7419   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7420    (set_attr "size" "64")
7421    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7423 (define_insn "*mov<mode>_softfloat32"
7424   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7425         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7426   "! TARGET_POWERPC64 
7427    && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7428    && (gpc_reg_operand (operands[0], <MODE>mode)
7429        || gpc_reg_operand (operands[1], <MODE>mode))"
7430   "#"
7431   [(set_attr "type" "store,load,two,*,*,*")
7432    (set_attr "length" "8,8,8,8,12,16")])
7434 ; ld/std require word-aligned displacements -> 'Y' constraint.
7435 ; List Y->r and r->Y before r->r for reload.
7436 (define_insn "*mov<mode>_hardfloat64"
7437   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
7438         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
7439   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7440    && (gpc_reg_operand (operands[0], <MODE>mode)
7441        || gpc_reg_operand (operands[1], <MODE>mode))"
7442   "@
7443    stfd%U0%X0 %1,%0
7444    lfd%U1%X1 %0,%1
7445    fmr %0,%1
7446    lxsd %0,%1
7447    stxsd %1,%0
7448    lxsd%U1x %x0,%y1
7449    stxsd%U0x %x1,%y0
7450    xxlor %x0,%x1,%x1
7451    xxlxor %x0,%x0,%x0
7452    li %0,0
7453    std%U0%X0 %1,%0
7454    ld%U1%X1 %0,%1
7455    mr %0,%1
7456    mt%0 %1
7457    mf%1 %0
7458    nop
7459    mftgpr %0,%1
7460    mffgpr %0,%1
7461    mfvsrd %0,%x1
7462    mtvsrd %x0,%1"
7463   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7464    (set_attr "size" "64")
7465    (set_attr "length" "4")])
7467 (define_insn "*mov<mode>_softfloat64"
7468   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7469         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7470   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7471    && (gpc_reg_operand (operands[0], <MODE>mode)
7472        || gpc_reg_operand (operands[1], <MODE>mode))"
7473   "@
7474    std%U0%X0 %1,%0
7475    ld%U1%X1 %0,%1
7476    mr %0,%1
7477    mt%0 %1
7478    mf%1 %0
7479    #
7480    #
7481    #
7482    nop"
7483   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7484    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7486 (define_expand "mov<mode>"
7487   [(set (match_operand:FMOVE128 0 "general_operand")
7488         (match_operand:FMOVE128 1 "any_operand"))]
7489   ""
7491   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7492   DONE;
7495 ;; It's important to list Y->r and r->Y before r->r because otherwise
7496 ;; reload, given m->r, will try to pick r->r and reload it, which
7497 ;; doesn't make progress.
7499 ;; We can't split little endian direct moves of TDmode, because the words are
7500 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7501 ;; problematical.  Don't allow direct move for this case.
7503 (define_insn_and_split "*mov<mode>_64bit_dm"
7504   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7505         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7506   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7507    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7508    && (gpc_reg_operand (operands[0], <MODE>mode)
7509        || gpc_reg_operand (operands[1], <MODE>mode))"
7510   "#"
7511   "&& reload_completed"
7512   [(pc)]
7513 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7514   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7516 (define_insn_and_split "*movtd_64bit_nodm"
7517   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7518         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7519   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7520    && (gpc_reg_operand (operands[0], TDmode)
7521        || gpc_reg_operand (operands[1], TDmode))"
7522   "#"
7523   "&& reload_completed"
7524   [(pc)]
7525 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7526   [(set_attr "length" "8,8,8,12,12,8")])
7528 (define_insn_and_split "*mov<mode>_32bit"
7529   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7530         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7531   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7532    && (FLOAT128_2REG_P (<MODE>mode)
7533        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7534        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7535    && (gpc_reg_operand (operands[0], <MODE>mode)
7536        || gpc_reg_operand (operands[1], <MODE>mode))"
7537   "#"
7538   "&& reload_completed"
7539   [(pc)]
7540 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7541   [(set_attr "length" "8,8,8,8,20,20,16")])
7543 (define_insn_and_split "*mov<mode>_softfloat"
7544   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7545         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7546   "TARGET_SOFT_FLOAT
7547    && (gpc_reg_operand (operands[0], <MODE>mode)
7548        || gpc_reg_operand (operands[1], <MODE>mode))"
7549   "#"
7550   "&& reload_completed"
7551   [(pc)]
7552 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7553   [(set_attr "length" "20,20,16")])
7555 (define_expand "extenddf<mode>2"
7556   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7557         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7558   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7560   if (FLOAT128_IEEE_P (<MODE>mode))
7561     rs6000_expand_float128_convert (operands[0], operands[1], false);
7562   else if (TARGET_VSX)
7563     {
7564       if (<MODE>mode == TFmode)
7565         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7566       else if (<MODE>mode == IFmode)
7567         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7568       else
7569         gcc_unreachable ();
7570     }
7571    else
7572     {
7573       rtx zero = gen_reg_rtx (DFmode);
7574       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7576       if (<MODE>mode == TFmode)
7577         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7578       else if (<MODE>mode == IFmode)
7579         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7580       else
7581         gcc_unreachable ();
7582     }
7583   DONE;
7586 ;; Allow memory operands for the source to be created by the combiner.
7587 (define_insn_and_split "extenddf<mode>2_fprs"
7588   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7589         (float_extend:IBM128
7590          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7591    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7592   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7593    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7594   "#"
7595   "&& reload_completed"
7596   [(set (match_dup 3) (match_dup 1))
7597    (set (match_dup 4) (match_dup 2))]
7599   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7600   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7602   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7603   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7606 (define_insn_and_split "extenddf<mode>2_vsx"
7607   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7608         (float_extend:IBM128
7609          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7610   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7611   "#"
7612   "&& reload_completed"
7613   [(set (match_dup 2) (match_dup 1))
7614    (set (match_dup 3) (match_dup 4))]
7616   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7617   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7619   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7620   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7621   operands[4] = CONST0_RTX (DFmode);
7624 (define_expand "extendsf<mode>2"
7625   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7626         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7627   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7629   if (FLOAT128_IEEE_P (<MODE>mode))
7630     rs6000_expand_float128_convert (operands[0], operands[1], false);
7631   else
7632     {
7633       rtx tmp = gen_reg_rtx (DFmode);
7634       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7635       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7636     }
7637   DONE;
7640 (define_expand "trunc<mode>df2"
7641   [(set (match_operand:DF 0 "gpc_reg_operand")
7642         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7643   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7645   if (FLOAT128_IEEE_P (<MODE>mode))
7646     {
7647       rs6000_expand_float128_convert (operands[0], operands[1], false);
7648       DONE;
7649     }
7652 (define_insn_and_split "trunc<mode>df2_internal1"
7653   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7654         (float_truncate:DF
7655          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7656   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7657    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7658   "@
7659    #
7660    fmr %0,%1"
7661   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7662   [(const_int 0)]
7664   emit_note (NOTE_INSN_DELETED);
7665   DONE;
7667   [(set_attr "type" "fpsimple")])
7669 (define_insn "trunc<mode>df2_internal2"
7670   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7671         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7672   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7673    && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7674   "fadd %0,%1,%L1"
7675   [(set_attr "type" "fp")
7676    (set_attr "fp_type" "fp_addsub_d")])
7678 (define_expand "trunc<mode>sf2"
7679   [(set (match_operand:SF 0 "gpc_reg_operand")
7680         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7681   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7683   if (FLOAT128_IEEE_P (<MODE>mode))
7684     rs6000_expand_float128_convert (operands[0], operands[1], false);
7685   else if (<MODE>mode == TFmode)
7686     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7687   else if (<MODE>mode == IFmode)
7688     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7689   else
7690     gcc_unreachable ();
7691   DONE;
7694 (define_insn_and_split "trunc<mode>sf2_fprs"
7695   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7696         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7697    (clobber (match_scratch:DF 2 "=d"))]
7698   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 
7699    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7700   "#"
7701   "&& reload_completed"
7702   [(set (match_dup 2)
7703         (float_truncate:DF (match_dup 1)))
7704    (set (match_dup 0)
7705         (float_truncate:SF (match_dup 2)))]
7706   "")
7708 (define_expand "floatsi<mode>2"
7709   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7710                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7711               (clobber (match_scratch:DI 2))])]
7712   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7714   rtx op0 = operands[0];
7715   rtx op1 = operands[1];
7717   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7718     ;
7719   else if (FLOAT128_IEEE_P (<MODE>mode))
7720     {
7721       rs6000_expand_float128_convert (op0, op1, false);
7722       DONE;
7723     }
7724   else
7725     {
7726       rtx tmp = gen_reg_rtx (DFmode);
7727       expand_float (tmp, op1, false);
7728       if (<MODE>mode == TFmode)
7729         emit_insn (gen_extenddftf2 (op0, tmp));
7730       else if (<MODE>mode == IFmode)
7731         emit_insn (gen_extenddfif2 (op0, tmp));
7732       else
7733         gcc_unreachable ();
7734       DONE;
7735     }
7738 ; fadd, but rounding towards zero.
7739 ; This is probably not the optimal code sequence.
7740 (define_insn "fix_trunc_helper<mode>"
7741   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7742         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7743                    UNSPEC_FIX_TRUNC_TF))
7744    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7745   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7746   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7747   [(set_attr "type" "fp")
7748    (set_attr "length" "20")])
7750 (define_expand "fix_trunc<mode>si2"
7751   [(set (match_operand:SI 0 "gpc_reg_operand")
7752         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7753   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7755   rtx op0 = operands[0];
7756   rtx op1 = operands[1];
7758   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7759     ;
7760   else
7761     {
7762       if (FLOAT128_IEEE_P (<MODE>mode))
7763         rs6000_expand_float128_convert (op0, op1, false);
7764       else if (<MODE>mode == TFmode)
7765         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7766       else if (<MODE>mode == IFmode)
7767         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7768       else
7769         gcc_unreachable ();
7770       DONE;
7771     }
7774 (define_expand "fix_trunc<mode>si2_fprs"
7775   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7776                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7777               (clobber (match_dup 2))
7778               (clobber (match_dup 3))
7779               (clobber (match_dup 4))
7780               (clobber (match_dup 5))])]
7781   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7783   operands[2] = gen_reg_rtx (DFmode);
7784   operands[3] = gen_reg_rtx (DFmode);
7785   operands[4] = gen_reg_rtx (DImode);
7786   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7789 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7790   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7791         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7792    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7793    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7794    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7795    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7796   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7797   "#"
7798   ""
7799   [(pc)]
7801   rtx lowword;
7802   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7803                                          operands[3]));
7805   gcc_assert (MEM_P (operands[5]));
7806   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7808   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7809   emit_move_insn (operands[5], operands[4]);
7810   emit_move_insn (operands[0], lowword);
7811   DONE;
7814 (define_expand "fix_trunc<mode>di2"
7815   [(set (match_operand:DI 0 "gpc_reg_operand")
7816         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7817   "TARGET_FLOAT128_TYPE"
7819   if (!TARGET_FLOAT128_HW)
7820     {
7821       rs6000_expand_float128_convert (operands[0], operands[1], false);
7822       DONE;
7823     }
7826 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7827   [(set (match_operand:SDI 0 "gpc_reg_operand")
7828         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7829   "TARGET_FLOAT128_TYPE"
7831   rs6000_expand_float128_convert (operands[0], operands[1], true);
7832   DONE;
7835 (define_expand "floatdi<mode>2"
7836   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7837         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7838   "TARGET_FLOAT128_TYPE"
7840   if (!TARGET_FLOAT128_HW)
7841     {
7842       rs6000_expand_float128_convert (operands[0], operands[1], false);
7843       DONE;
7844     }
7847 (define_expand "floatunsdi<IEEE128:mode>2"
7848   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7849         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7850   "TARGET_FLOAT128_TYPE"
7852   if (!TARGET_FLOAT128_HW)
7853     {
7854       rs6000_expand_float128_convert (operands[0], operands[1], true);
7855       DONE;
7856     }
7859 (define_expand "floatuns<IEEE128:mode>2"
7860   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7861         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
7862   "TARGET_FLOAT128_TYPE"
7864   rtx op0 = operands[0];
7865   rtx op1 = operands[1];
7867   if (TARGET_FLOAT128_HW)
7868     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7869   else
7870     rs6000_expand_float128_convert (op0, op1, true);
7871   DONE;
7874 (define_expand "neg<mode>2"
7875   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7876         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7877   "FLOAT128_IEEE_P (<MODE>mode)
7878    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7880   if (FLOAT128_IEEE_P (<MODE>mode))
7881     {
7882       if (TARGET_FLOAT128_HW)
7883         {
7884           if (<MODE>mode == TFmode)
7885             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7886           else if (<MODE>mode == KFmode)
7887             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7888           else
7889             gcc_unreachable ();
7890         }
7891       else if (TARGET_FLOAT128_TYPE)
7892         {
7893           if (<MODE>mode == TFmode)
7894             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7895           else if (<MODE>mode == KFmode)
7896             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7897           else
7898             gcc_unreachable ();
7899         }
7900       else
7901         {
7902           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7903           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7904                                                 <MODE>mode,
7905                                                 operands[1], <MODE>mode);
7907           if (target && !rtx_equal_p (target, operands[0]))
7908             emit_move_insn (operands[0], target);
7909         }
7910       DONE;
7911     }
7914 (define_insn "neg<mode>2_internal"
7915   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7916         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7917   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7919   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7920     return "fneg %L0,%L1\;fneg %0,%1";
7921   else
7922     return "fneg %0,%1\;fneg %L0,%L1";
7924   [(set_attr "type" "fpsimple")
7925    (set_attr "length" "8")])
7927 (define_expand "abs<mode>2"
7928   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7929         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7930   "FLOAT128_IEEE_P (<MODE>mode)
7931    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7933   rtx label;
7935   if (FLOAT128_IEEE_P (<MODE>mode))
7936     {
7937       if (TARGET_FLOAT128_HW)
7938         {
7939           if (<MODE>mode == TFmode)
7940             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7941           else if (<MODE>mode == KFmode)
7942             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7943           else
7944             FAIL;
7945           DONE;
7946         }
7947       else if (TARGET_FLOAT128_TYPE)
7948         {
7949           if (<MODE>mode == TFmode)
7950             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7951           else if (<MODE>mode == KFmode)
7952             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7953           else
7954             FAIL;
7955           DONE;
7956         }
7957       else
7958         FAIL;
7959     }
7961   label = gen_label_rtx ();
7962   if (<MODE>mode == TFmode)
7963     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7964   else if (<MODE>mode == TFmode)
7965     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7966   else
7967     FAIL;
7968   emit_label (label);
7969   DONE;
7972 (define_expand "abs<mode>2_internal"
7973   [(set (match_operand:IBM128 0 "gpc_reg_operand")
7974         (match_operand:IBM128 1 "gpc_reg_operand"))
7975    (set (match_dup 3) (match_dup 5))
7976    (set (match_dup 5) (abs:DF (match_dup 5)))
7977    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7978    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7979                            (label_ref (match_operand 2 ""))
7980                            (pc)))
7981    (set (match_dup 6) (neg:DF (match_dup 6)))]
7982   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7984   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7985   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7986   operands[3] = gen_reg_rtx (DFmode);
7987   operands[4] = gen_reg_rtx (CCFPmode);
7988   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7989   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7993 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7994 ;; register
7996 (define_expand "ieee_128bit_negative_zero"
7997   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
7998   "TARGET_FLOAT128_TYPE"
8000   rtvec v = rtvec_alloc (16);
8001   int i, high;
8003   for (i = 0; i < 16; i++)
8004     RTVEC_ELT (v, i) = const0_rtx;
8006   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8007   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8009   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8010   DONE;
8013 ;; IEEE 128-bit negate
8015 ;; We have 2 insns here for negate and absolute value.  The first uses
8016 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8017 ;; insns, and second insn after the first split pass loads up the bit to
8018 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8019 ;; neg/abs to create the constant just once.
8021 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8022   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8023         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8024    (clobber (match_scratch:V16QI 2 "=v"))]
8025   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8026   "#"
8027   "&& 1"
8028   [(parallel [(set (match_dup 0)
8029                    (neg:IEEE128 (match_dup 1)))
8030               (use (match_dup 2))])]
8032   if (GET_CODE (operands[2]) == SCRATCH)
8033     operands[2] = gen_reg_rtx (V16QImode);
8035   operands[3] = gen_reg_rtx (V16QImode);
8036   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8038   [(set_attr "length" "8")
8039    (set_attr "type" "vecsimple")])
8041 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8042   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8043         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8044    (use (match_operand:V16QI 2 "register_operand" "v"))]
8045   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8046   "xxlxor %x0,%x1,%x2"
8047   [(set_attr "type" "veclogical")])
8049 ;; IEEE 128-bit absolute value
8050 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8051   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8052         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8053    (clobber (match_scratch:V16QI 2 "=v"))]
8054   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8055   "#"
8056   "&& 1"
8057   [(parallel [(set (match_dup 0)
8058                    (abs:IEEE128 (match_dup 1)))
8059               (use (match_dup 2))])]
8061   if (GET_CODE (operands[2]) == SCRATCH)
8062     operands[2] = gen_reg_rtx (V16QImode);
8064   operands[3] = gen_reg_rtx (V16QImode);
8065   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8067   [(set_attr "length" "8")
8068    (set_attr "type" "vecsimple")])
8070 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8071   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8072         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8073    (use (match_operand:V16QI 2 "register_operand" "v"))]
8074   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8075   "xxlandc %x0,%x1,%x2"
8076   [(set_attr "type" "veclogical")])
8078 ;; IEEE 128-bit negative absolute value
8079 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8080   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8081         (neg:IEEE128
8082          (abs:IEEE128
8083           (match_operand:IEEE128 1 "register_operand" "wa"))))
8084    (clobber (match_scratch:V16QI 2 "=v"))]
8085   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8086    && FLOAT128_IEEE_P (<MODE>mode)"
8087   "#"
8088   "&& 1"
8089   [(parallel [(set (match_dup 0)
8090                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8091               (use (match_dup 2))])]
8093   if (GET_CODE (operands[2]) == SCRATCH)
8094     operands[2] = gen_reg_rtx (V16QImode);
8096   operands[3] = gen_reg_rtx (V16QImode);
8097   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8099   [(set_attr "length" "8")
8100    (set_attr "type" "vecsimple")])
8102 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8103   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8104         (neg:IEEE128
8105          (abs:IEEE128
8106           (match_operand:IEEE128 1 "register_operand" "wa"))))
8107    (use (match_operand:V16QI 2 "register_operand" "v"))]
8108   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8109   "xxlor %x0,%x1,%x2"
8110   [(set_attr "type" "veclogical")])
8112 ;; Float128 conversion functions.  These expand to library function calls.
8113 ;; We use expand to convert from IBM double double to IEEE 128-bit
8114 ;; and trunc for the opposite.
8115 (define_expand "extendiftf2"
8116   [(set (match_operand:TF 0 "gpc_reg_operand")
8117         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8118   "TARGET_FLOAT128_TYPE"
8120   rs6000_expand_float128_convert (operands[0], operands[1], false);
8121   DONE;
8124 (define_expand "extendifkf2"
8125   [(set (match_operand:KF 0 "gpc_reg_operand")
8126         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8127   "TARGET_FLOAT128_TYPE"
8129   rs6000_expand_float128_convert (operands[0], operands[1], false);
8130   DONE;
8133 (define_expand "extendtfkf2"
8134   [(set (match_operand:KF 0 "gpc_reg_operand")
8135         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8136   "TARGET_FLOAT128_TYPE"
8138   rs6000_expand_float128_convert (operands[0], operands[1], false);
8139   DONE;
8142 (define_expand "trunciftf2"
8143   [(set (match_operand:IF 0 "gpc_reg_operand")
8144         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8145   "TARGET_FLOAT128_TYPE"
8147   rs6000_expand_float128_convert (operands[0], operands[1], false);
8148   DONE;
8151 (define_expand "truncifkf2"
8152   [(set (match_operand:IF 0 "gpc_reg_operand")
8153         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand")))]
8154   "TARGET_FLOAT128_TYPE"
8156   rs6000_expand_float128_convert (operands[0], operands[1], false);
8157   DONE;
8160 (define_expand "trunckftf2"
8161   [(set (match_operand:TF 0 "gpc_reg_operand")
8162         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8163   "TARGET_FLOAT128_TYPE"
8165   rs6000_expand_float128_convert (operands[0], operands[1], false);
8166   DONE;
8169 (define_expand "trunctfif2"
8170   [(set (match_operand:IF 0 "gpc_reg_operand")
8171         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8172   "TARGET_FLOAT128_TYPE"
8174   rs6000_expand_float128_convert (operands[0], operands[1], false);
8175   DONE;
8179 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8180 ;; must have 3 arguments, and scratch register constraint must be a single
8181 ;; constraint.
8183 ;; Reload patterns to support gpr load/store with misaligned mem.
8184 ;; and multiple gpr load/store at offset >= 0xfffc
8185 (define_expand "reload_<mode>_store"
8186   [(parallel [(match_operand 0 "memory_operand" "=m")
8187               (match_operand 1 "gpc_reg_operand" "r")
8188               (match_operand:GPR 2 "register_operand" "=&b")])]
8189   ""
8191   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8192   DONE;
8195 (define_expand "reload_<mode>_load"
8196   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8197               (match_operand 1 "memory_operand" "m")
8198               (match_operand:GPR 2 "register_operand" "=b")])]
8199   ""
8201   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8202   DONE;
8206 ;; Reload patterns for various types using the vector registers.  We may need
8207 ;; an additional base register to convert the reg+offset addressing to reg+reg
8208 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8209 ;; index register for gpr registers.
8210 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8211   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8212               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8213               (match_operand:P 2 "register_operand" "=b")])]
8214   "<P:tptrsize>"
8216   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8217   DONE;
8220 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8221   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8222               (match_operand:RELOAD 1 "memory_operand" "m")
8223               (match_operand:P 2 "register_operand" "=b")])]
8224   "<P:tptrsize>"
8226   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8227   DONE;
8231 ;; Reload sometimes tries to move the address to a GPR, and can generate
8232 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8233 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8235 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8236   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8237         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8238                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8239                (const_int -16)))]
8240   "TARGET_ALTIVEC && reload_completed"
8241   "#"
8242   "&& reload_completed"
8243   [(set (match_dup 0)
8244         (plus:P (match_dup 1)
8245                 (match_dup 2)))
8246    (set (match_dup 0)
8247         (and:P (match_dup 0)
8248                (const_int -16)))])
8250 ;; Power8 merge instructions to allow direct move to/from floating point
8251 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8252 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8253 ;; value, since it is allocated in reload and not all of the flow information
8254 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8255 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8256 ;; schedule other instructions between the two instructions.
8258 (define_insn "p8_fmrgow_<mode>"
8259   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8260         (unspec:FMOVE64X [
8261                 (match_operand:DF 1 "register_operand" "d")
8262                 (match_operand:DF 2 "register_operand" "d")]
8263                          UNSPEC_P8V_FMRGOW))]
8264   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8265   "fmrgow %0,%1,%2"
8266   [(set_attr "type" "fpsimple")])
8268 (define_insn "p8_mtvsrwz"
8269   [(set (match_operand:DF 0 "register_operand" "=d")
8270         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8271                    UNSPEC_P8V_MTVSRWZ))]
8272   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8273   "mtvsrwz %x0,%1"
8274   [(set_attr "type" "mftgpr")])
8276 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8277   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8278         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8279                          UNSPEC_P8V_RELOAD_FROM_GPR))
8280    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8281   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8282   "#"
8283   "&& reload_completed"
8284   [(const_int 0)]
8286   rtx dest = operands[0];
8287   rtx src = operands[1];
8288   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8289   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8290   rtx gpr_hi_reg = gen_highpart (SImode, src);
8291   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8293   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8294   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8295   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8296   DONE;
8298   [(set_attr "length" "12")
8299    (set_attr "type" "three")])
8301 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8302 (define_insn "p8_mtvsrd_df"
8303   [(set (match_operand:DF 0 "register_operand" "=wa")
8304         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8305                    UNSPEC_P8V_MTVSRD))]
8306   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8307   "mtvsrd %x0,%1"
8308   [(set_attr "type" "mftgpr")])
8310 (define_insn "p8_xxpermdi_<mode>"
8311   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8312         (unspec:FMOVE128_GPR [
8313                 (match_operand:DF 1 "register_operand" "wa")
8314                 (match_operand:DF 2 "register_operand" "wa")]
8315                 UNSPEC_P8V_XXPERMDI))]
8316   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8317   "xxpermdi %x0,%x1,%x2,0"
8318   [(set_attr "type" "vecperm")])
8320 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8321   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8322         (unspec:FMOVE128_GPR
8323          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8324          UNSPEC_P8V_RELOAD_FROM_GPR))
8325    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8326   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8327   "#"
8328   "&& reload_completed"
8329   [(const_int 0)]
8331   rtx dest = operands[0];
8332   rtx src = operands[1];
8333   /* You might think that we could use op0 as one temp and a DF clobber
8334      as op2, but you'd be wrong.  Secondary reload move patterns don't
8335      check for overlap of the clobber and the destination.  */
8336   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8337   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8338   rtx gpr_hi_reg = gen_highpart (DImode, src);
8339   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8341   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8342   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8343   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8344   DONE;
8346   [(set_attr "length" "12")
8347    (set_attr "type" "three")])
8349 (define_split
8350   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8351         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8352   "reload_completed
8353    && (int_reg_operand (operands[0], <MODE>mode)
8354        || int_reg_operand (operands[1], <MODE>mode))
8355    && (!TARGET_DIRECT_MOVE_128
8356        || (!vsx_register_operand (operands[0], <MODE>mode)
8357            && !vsx_register_operand (operands[1], <MODE>mode)))"
8358   [(pc)]
8359 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8361 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8362 ;; type is stored internally as double precision in the VSX registers, we have
8363 ;; to convert it from the vector format.
8364 (define_insn "p8_mtvsrd_sf"
8365   [(set (match_operand:SF 0 "register_operand" "=wa")
8366         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8367                    UNSPEC_P8V_MTVSRD))]
8368   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8369   "mtvsrd %x0,%1"
8370   [(set_attr "type" "mftgpr")])
8372 (define_insn_and_split "reload_vsx_from_gprsf"
8373   [(set (match_operand:SF 0 "register_operand" "=wa")
8374         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8375                    UNSPEC_P8V_RELOAD_FROM_GPR))
8376    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8377   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8378   "#"
8379   "&& reload_completed"
8380   [(const_int 0)]
8382   rtx op0 = operands[0];
8383   rtx op1 = operands[1];
8384   rtx op2 = operands[2];
8385   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8387   /* Move SF value to upper 32-bits for xscvspdpn.  */
8388   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8389   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8390   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8391   DONE;
8393   [(set_attr "length" "8")
8394    (set_attr "type" "two")])
8396 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8397 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8398 ;; and then doing a move of that.
8399 (define_insn "p8_mfvsrd_3_<mode>"
8400   [(set (match_operand:DF 0 "register_operand" "=r")
8401         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8402                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8403   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8404   "mfvsrd %0,%x1"
8405   [(set_attr "type" "mftgpr")])
8407 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8408   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8409         (unspec:FMOVE128_GPR
8410          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8411          UNSPEC_P8V_RELOAD_FROM_VSX))
8412    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8413   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8414   "#"
8415   "&& reload_completed"
8416   [(const_int 0)]
8418   rtx dest = operands[0];
8419   rtx src = operands[1];
8420   rtx tmp = operands[2];
8421   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8422   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8424   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8425   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8426   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8427   DONE;
8429   [(set_attr "length" "12")
8430    (set_attr "type" "three")])
8432 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8433 ;; type is stored internally as double precision, we have to convert it to the
8434 ;; vector format.
8436 (define_insn_and_split "reload_gpr_from_vsxsf"
8437   [(set (match_operand:SF 0 "register_operand" "=r")
8438         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8439                    UNSPEC_P8V_RELOAD_FROM_VSX))
8440    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8441   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8442   "#"
8443   "&& reload_completed"
8444   [(const_int 0)]
8446   rtx op0 = operands[0];
8447   rtx op1 = operands[1];
8448   rtx op2 = operands[2];
8449   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8450   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8452   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8453   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8454   DONE;
8456   [(set_attr "length" "8")
8457    (set_attr "type" "two")])
8460 ;; Next come the multi-word integer load and store and the load and store
8461 ;; multiple insns.
8463 ;; List r->r after r->Y, otherwise reload will try to reload a
8464 ;; non-offsettable address by using r->r which won't make progress.
8465 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8466 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8468 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8469 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8470 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8471 ;;        AVX const  
8473 (define_insn "*movdi_internal32"
8474   [(set (match_operand:DI 0 "nonimmediate_operand"
8475          "=Y,        r,         r,         ^m,        ^d,         ^d,
8476           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8477           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8478           *wv")
8480         (match_operand:DI 1 "input_operand"
8481           "r,        Y,         r,         d,         m,          d,
8482            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8483            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8484            wB"))]
8486   "! TARGET_POWERPC64
8487    && (gpc_reg_operand (operands[0], DImode)
8488        || gpc_reg_operand (operands[1], DImode))"
8489   "@
8490    #
8491    #
8492    #
8493    stfd%U0%X0 %1,%0
8494    lfd%U1%X1 %0,%1
8495    fmr %0,%1
8496    #
8497    stxsd %1,%0
8498    stxsdx %x1,%y0
8499    lxsd %0,%1
8500    lxsdx %x0,%y1
8501    xxlor %x0,%x1,%x1
8502    xxspltib %x0,0
8503    xxspltib %x0,255
8504    vspltisw %0,%1
8505    xxlxor %x0,%x0,%x0
8506    xxlorc %x0,%x0,%x0
8507    #
8508    #"
8509   [(set_attr "type"
8510                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8511                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8512                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8513                 vecsimple")
8514    (set_attr "size" "64")])
8516 (define_split
8517   [(set (match_operand:DI 0 "gpc_reg_operand")
8518         (match_operand:DI 1 "const_int_operand"))]
8519   "! TARGET_POWERPC64 && reload_completed
8520    && gpr_or_gpr_p (operands[0], operands[1])
8521    && !direct_move_p (operands[0], operands[1])"
8522   [(set (match_dup 2) (match_dup 4))
8523    (set (match_dup 3) (match_dup 1))]
8525   HOST_WIDE_INT value = INTVAL (operands[1]);
8526   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8527                                        DImode);
8528   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8529                                        DImode);
8530   operands[4] = GEN_INT (value >> 32);
8531   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8534 (define_split
8535   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8536         (match_operand:DIFD 1 "input_operand"))]
8537   "reload_completed && !TARGET_POWERPC64
8538    && gpr_or_gpr_p (operands[0], operands[1])
8539    && !direct_move_p (operands[0], operands[1])"
8540   [(pc)]
8541 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8543 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8544 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8545 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8546 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8547 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8548 (define_insn "*movdi_internal64"
8549   [(set (match_operand:DI 0 "nonimmediate_operand"
8550                "=YZ,       r,         r,         r,         r,          r,
8551                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8552                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8553                 *wi,       *wv,       *wv,       r,         *h,         *h,
8554                 ?*r,       ?*wg,      ?*r,       ?*wj")
8556         (match_operand:DI 1 "input_operand"
8557                 "r,        YZ,        r,         I,         L,          nF,
8558                  d,        m,         d,         wb,        wv,         wY,
8559                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8560                  wM,       wS,        wB,        *h,        r,          0,
8561                  wg,       r,         wj,        r"))]
8563   "TARGET_POWERPC64
8564    && (gpc_reg_operand (operands[0], DImode)
8565        || gpc_reg_operand (operands[1], DImode))"
8566   "@
8567    std%U0%X0 %1,%0
8568    ld%U1%X1 %0,%1
8569    mr %0,%1
8570    li %0,%1
8571    lis %0,%v1
8572    #
8573    stfd%U0%X0 %1,%0
8574    lfd%U1%X1 %0,%1
8575    fmr %0,%1
8576    stxsd %1,%0
8577    stxsdx %x1,%y0
8578    lxsd %0,%1
8579    lxsdx %x0,%y1
8580    xxlor %x0,%x1,%x1
8581    xxspltib %x0,0
8582    xxspltib %x0,255
8583    #
8584    xxlxor %x0,%x0,%x0
8585    xxlorc %x0,%x0,%x0
8586    #
8587    #
8588    mf%1 %0
8589    mt%0 %1
8590    nop
8591    mftgpr %0,%1
8592    mffgpr %0,%1
8593    mfvsrd %0,%x1
8594    mtvsrd %x0,%1"
8595   [(set_attr "type"
8596                "store,      load,       *,         *,         *,         *,
8597                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8598                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8599                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8600                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8602    (set_attr "size" "64")
8603    (set_attr "length"
8604                "4,         4,         4,         4,         4,          20,
8605                 4,         4,         4,         4,         4,          4,
8606                 4,         4,         4,         4,         4,          8,
8607                 8,         4,         4,         4,         4,          4,
8608                 4,         4,         4,         4")])
8610 ; Some DImode loads are best done as a load of -1 followed by a mask
8611 ; instruction.
8612 (define_split
8613   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8614         (match_operand:DI 1 "const_int_operand"))]
8615   "TARGET_POWERPC64
8616    && num_insns_constant (operands[1], DImode) > 1
8617    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8618    && rs6000_is_valid_and_mask (operands[1], DImode)"
8619   [(set (match_dup 0)
8620         (const_int -1))
8621    (set (match_dup 0)
8622         (and:DI (match_dup 0)
8623                 (match_dup 1)))]
8624   "")
8626 ;; Split a load of a large constant into the appropriate five-instruction
8627 ;; sequence.  Handle anything in a constant number of insns.
8628 ;; When non-easy constants can go in the TOC, this should use
8629 ;; easy_fp_constant predicate.
8630 (define_split
8631   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8632         (match_operand:DI 1 "const_int_operand"))]
8633   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8634   [(set (match_dup 0) (match_dup 2))
8635    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8637   if (rs6000_emit_set_const (operands[0], operands[1]))
8638     DONE;
8639   else
8640     FAIL;
8643 (define_split
8644   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8645         (match_operand:DI 1 "const_scalar_int_operand"))]
8646   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8647   [(set (match_dup 0) (match_dup 2))
8648    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8650   if (rs6000_emit_set_const (operands[0], operands[1]))
8651     DONE;
8652   else
8653     FAIL;
8656 (define_split
8657   [(set (match_operand:DI 0 "altivec_register_operand")
8658         (match_operand:DI 1 "s5bit_cint_operand"))]
8659   "TARGET_VSX && reload_completed"
8660   [(const_int 0)]
8662   rtx op0 = operands[0];
8663   rtx op1 = operands[1];
8664   int r = REGNO (op0);
8665   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8667   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8668   if (op1 != const0_rtx && op1 != constm1_rtx)
8669     {
8670       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8671       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8672     }
8673   DONE;
8676 ;; Split integer constants that can be loaded with XXSPLTIB and a
8677 ;; sign extend operation.
8678 (define_split
8679   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8680         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8681   "TARGET_P9_VECTOR && reload_completed"
8682   [(const_int 0)]
8684   rtx op0 = operands[0];
8685   rtx op1 = operands[1];
8686   int r = REGNO (op0);
8687   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8689   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8690   if (<MODE>mode == DImode)
8691     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8692   else if (<MODE>mode == SImode)
8693     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8694   else if (<MODE>mode == HImode)
8695     {
8696       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8697       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8698     }
8699   DONE;
8703 ;; TImode/PTImode is similar, except that we usually want to compute the
8704 ;; address into a register and use lsi/stsi (the exception is during reload).
8706 (define_insn "*mov<mode>_string"
8707   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8708         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8709   "! TARGET_POWERPC64
8710    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8711    && (gpc_reg_operand (operands[0], <MODE>mode)
8712        || gpc_reg_operand (operands[1], <MODE>mode))"
8713   "#"
8714   [(set_attr "type" "store,store,load,load,*,*")
8715    (set_attr "update" "yes")
8716    (set_attr "indexed" "yes")
8717    (set_attr "cell_micro" "conditional")])
8719 (define_insn "*mov<mode>_ppc64"
8720   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8721         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8722   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8723    && (gpc_reg_operand (operands[0], <MODE>mode)
8724        || gpc_reg_operand (operands[1], <MODE>mode)))"
8726   return rs6000_output_move_128bit (operands);
8728   [(set_attr "type" "store,store,load,load,*,*")
8729    (set_attr "length" "8")])
8731 (define_split
8732   [(set (match_operand:TI2 0 "int_reg_operand")
8733         (match_operand:TI2 1 "const_scalar_int_operand"))]
8734   "TARGET_POWERPC64
8735    && (VECTOR_MEM_NONE_P (<MODE>mode)
8736        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8737   [(set (match_dup 2) (match_dup 4))
8738    (set (match_dup 3) (match_dup 5))]
8740   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8741                                        <MODE>mode);
8742   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8743                                        <MODE>mode);
8744   if (CONST_WIDE_INT_P (operands[1]))
8745     {
8746       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8747       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8748     }
8749   else if (CONST_INT_P (operands[1]))
8750     {
8751       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8752       operands[5] = operands[1];
8753     }
8754   else
8755     FAIL;
8758 (define_split
8759   [(set (match_operand:TI2 0 "nonimmediate_operand")
8760         (match_operand:TI2 1 "input_operand"))]
8761   "reload_completed
8762    && gpr_or_gpr_p (operands[0], operands[1])
8763    && !direct_move_p (operands[0], operands[1])
8764    && !quad_load_store_p (operands[0], operands[1])"
8765   [(pc)]
8766 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8768 (define_expand "setmemsi"
8769   [(parallel [(set (match_operand:BLK 0 "")
8770                    (match_operand 2 "const_int_operand"))
8771               (use (match_operand:SI 1 ""))
8772               (use (match_operand:SI 3 ""))])]
8773   ""
8775   /* If value to set is not zero, use the library routine.  */
8776   if (operands[2] != const0_rtx)
8777     FAIL;
8779   if (expand_block_clear (operands))
8780     DONE;
8781   else
8782     FAIL;
8785 ;; String compare N insn.
8786 ;; Argument 0 is the target (result)
8787 ;; Argument 1 is the destination
8788 ;; Argument 2 is the source
8789 ;; Argument 3 is the length
8790 ;; Argument 4 is the alignment
8792 (define_expand "cmpstrnsi"
8793   [(parallel [(set (match_operand:SI 0)
8794                (compare:SI (match_operand:BLK 1)
8795                            (match_operand:BLK 2)))
8796               (use (match_operand:SI 3))
8797               (use (match_operand:SI 4))])]
8798   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8800   if (optimize_insn_for_size_p ())
8801     FAIL;
8803   if (expand_strn_compare (operands, 0))
8804     DONE;
8805   else  
8806     FAIL;
8809 ;; String compare insn.
8810 ;; Argument 0 is the target (result)
8811 ;; Argument 1 is the destination
8812 ;; Argument 2 is the source
8813 ;; Argument 3 is the alignment
8815 (define_expand "cmpstrsi"
8816   [(parallel [(set (match_operand:SI 0)
8817                (compare:SI (match_operand:BLK 1)
8818                            (match_operand:BLK 2)))
8819               (use (match_operand:SI 3))])]
8820   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8822   if (optimize_insn_for_size_p ())
8823     FAIL;
8825   if (expand_strn_compare (operands, 1))
8826     DONE;
8827   else  
8828     FAIL;
8831 ;; Block compare insn.
8832 ;; Argument 0 is the target (result)
8833 ;; Argument 1 is the destination
8834 ;; Argument 2 is the source
8835 ;; Argument 3 is the length
8836 ;; Argument 4 is the alignment
8838 (define_expand "cmpmemsi"
8839   [(parallel [(set (match_operand:SI 0)
8840                (compare:SI (match_operand:BLK 1)
8841                            (match_operand:BLK 2)))
8842               (use (match_operand:SI 3))
8843               (use (match_operand:SI 4))])]
8844   "TARGET_POPCNTD"
8846   if (expand_block_compare (operands))
8847     DONE;
8848   else
8849     FAIL;
8852 ;; String/block move insn.
8853 ;; Argument 0 is the destination
8854 ;; Argument 1 is the source
8855 ;; Argument 2 is the length
8856 ;; Argument 3 is the alignment
8858 (define_expand "movmemsi"
8859   [(parallel [(set (match_operand:BLK 0 "")
8860                    (match_operand:BLK 1 ""))
8861               (use (match_operand:SI 2 ""))
8862               (use (match_operand:SI 3 ""))])]
8863   ""
8865   if (expand_block_move (operands))
8866     DONE;
8867   else
8868     FAIL;
8871 ;; Define insns that do load or store with update.  Some of these we can
8872 ;; get by using pre-decrement or pre-increment, but the hardware can also
8873 ;; do cases where the increment is not the size of the object.
8875 ;; In all these cases, we use operands 0 and 1 for the register being
8876 ;; incremented because those are the operands that local-alloc will
8877 ;; tie and these are the pair most likely to be tieable (and the ones
8878 ;; that will benefit the most).
8880 (define_insn "*movdi_update1"
8881   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8882         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8883                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8884    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8885         (plus:DI (match_dup 1) (match_dup 2)))]
8886   "TARGET_POWERPC64 && TARGET_UPDATE
8887    && (!avoiding_indexed_address_p (DImode)
8888        || !gpc_reg_operand (operands[2], DImode))"
8889   "@
8890    ldux %3,%0,%2
8891    ldu %3,%2(%0)"
8892   [(set_attr "type" "load")
8893    (set_attr "update" "yes")
8894    (set_attr "indexed" "yes,no")])
8896 (define_insn "movdi_<mode>_update"
8897   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8898                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8899         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8900    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8901         (plus:P (match_dup 1) (match_dup 2)))]
8902   "TARGET_POWERPC64 && TARGET_UPDATE
8903    && (!avoiding_indexed_address_p (Pmode)
8904        || !gpc_reg_operand (operands[2], Pmode)
8905        || (REG_P (operands[0])
8906            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8907   "@
8908    stdux %3,%0,%2
8909    stdu %3,%2(%0)"
8910   [(set_attr "type" "store")
8911    (set_attr "update" "yes")
8912    (set_attr "indexed" "yes,no")])
8914 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8915 ;; needed for stack allocation, even if the user passes -mno-update.
8916 (define_insn "movdi_<mode>_update_stack"
8917   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8918                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8919         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8920    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8921         (plus:P (match_dup 1) (match_dup 2)))]
8922   "TARGET_POWERPC64"
8923   "@
8924    stdux %3,%0,%2
8925    stdu %3,%2(%0)"
8926   [(set_attr "type" "store")
8927    (set_attr "update" "yes")
8928    (set_attr "indexed" "yes,no")])
8930 (define_insn "*movsi_update1"
8931   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8932         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8933                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8934    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8935         (plus:SI (match_dup 1) (match_dup 2)))]
8936   "TARGET_UPDATE
8937    && (!avoiding_indexed_address_p (SImode)
8938        || !gpc_reg_operand (operands[2], SImode))"
8939   "@
8940    lwzux %3,%0,%2
8941    lwzu %3,%2(%0)"
8942   [(set_attr "type" "load")
8943    (set_attr "update" "yes")
8944    (set_attr "indexed" "yes,no")])
8946 (define_insn "*movsi_update2"
8947   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8948         (sign_extend:DI
8949          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8950                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8951    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8952         (plus:DI (match_dup 1) (match_dup 2)))]
8953   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
8954   "lwaux %3,%0,%2"
8955   [(set_attr "type" "load")
8956    (set_attr "sign_extend" "yes")
8957    (set_attr "update" "yes")
8958    (set_attr "indexed" "yes")])
8960 (define_insn "movsi_update"
8961   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8962                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8963         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8964    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8965         (plus:SI (match_dup 1) (match_dup 2)))]
8966   "TARGET_UPDATE
8967    && (!avoiding_indexed_address_p (SImode)
8968        || !gpc_reg_operand (operands[2], SImode)
8969        || (REG_P (operands[0])
8970            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8971   "@
8972    stwux %3,%0,%2
8973    stwu %3,%2(%0)"
8974   [(set_attr "type" "store")
8975    (set_attr "update" "yes")
8976    (set_attr "indexed" "yes,no")])
8978 ;; This is an unconditional pattern; needed for stack allocation, even
8979 ;; if the user passes -mno-update.
8980 (define_insn "movsi_update_stack"
8981   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8982                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8983         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8984    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8985         (plus:SI (match_dup 1) (match_dup 2)))]
8986   ""
8987   "@
8988    stwux %3,%0,%2
8989    stwu %3,%2(%0)"
8990   [(set_attr "type" "store")
8991    (set_attr "update" "yes")
8992    (set_attr "indexed" "yes,no")])
8994 (define_insn "*movhi_update1"
8995   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8996         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8997                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8998    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8999         (plus:SI (match_dup 1) (match_dup 2)))]
9000   "TARGET_UPDATE
9001    && (!avoiding_indexed_address_p (SImode)
9002        || !gpc_reg_operand (operands[2], SImode))"
9003   "@
9004    lhzux %3,%0,%2
9005    lhzu %3,%2(%0)"
9006   [(set_attr "type" "load")
9007    (set_attr "update" "yes")
9008    (set_attr "indexed" "yes,no")])
9010 (define_insn "*movhi_update2"
9011   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9012         (zero_extend:SI
9013          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9014                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9015    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9016         (plus:SI (match_dup 1) (match_dup 2)))]
9017   "TARGET_UPDATE
9018    && (!avoiding_indexed_address_p (SImode)
9019        || !gpc_reg_operand (operands[2], SImode))"
9020   "@
9021    lhzux %3,%0,%2
9022    lhzu %3,%2(%0)"
9023   [(set_attr "type" "load")
9024    (set_attr "update" "yes")
9025    (set_attr "indexed" "yes,no")])
9027 (define_insn "*movhi_update3"
9028   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9029         (sign_extend:SI
9030          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9031                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9032    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9033         (plus:SI (match_dup 1) (match_dup 2)))]
9034   "TARGET_UPDATE
9035    && !(avoiding_indexed_address_p (SImode)
9036         && gpc_reg_operand (operands[2], SImode))"
9037   "@
9038    lhaux %3,%0,%2
9039    lhau %3,%2(%0)"
9040   [(set_attr "type" "load")
9041    (set_attr "sign_extend" "yes")
9042    (set_attr "update" "yes")
9043    (set_attr "indexed" "yes,no")])
9045 (define_insn "*movhi_update4"
9046   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9047                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9048         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9049    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9050         (plus:SI (match_dup 1) (match_dup 2)))]
9051   "TARGET_UPDATE
9052    && (!avoiding_indexed_address_p (SImode)
9053        || !gpc_reg_operand (operands[2], SImode))"
9054   "@
9055    sthux %3,%0,%2
9056    sthu %3,%2(%0)"
9057   [(set_attr "type" "store")
9058    (set_attr "update" "yes")
9059    (set_attr "indexed" "yes,no")])
9061 (define_insn "*movqi_update1"
9062   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9063         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9064                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9065    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9066         (plus:SI (match_dup 1) (match_dup 2)))]
9067   "TARGET_UPDATE
9068    && (!avoiding_indexed_address_p (SImode)
9069        || !gpc_reg_operand (operands[2], SImode))"
9070   "@
9071    lbzux %3,%0,%2
9072    lbzu %3,%2(%0)"
9073   [(set_attr "type" "load")
9074    (set_attr "update" "yes")
9075    (set_attr "indexed" "yes,no")])
9077 (define_insn "*movqi_update2"
9078   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9079         (zero_extend:SI
9080          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9081                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9082    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9083         (plus:SI (match_dup 1) (match_dup 2)))]
9084   "TARGET_UPDATE
9085    && (!avoiding_indexed_address_p (SImode)
9086        || !gpc_reg_operand (operands[2], SImode))"
9087   "@
9088    lbzux %3,%0,%2
9089    lbzu %3,%2(%0)"
9090   [(set_attr "type" "load")
9091    (set_attr "update" "yes")
9092    (set_attr "indexed" "yes,no")])
9094 (define_insn "*movqi_update3"
9095   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9096                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9097         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9098    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9099         (plus:SI (match_dup 1) (match_dup 2)))]
9100   "TARGET_UPDATE
9101    && (!avoiding_indexed_address_p (SImode)
9102        || !gpc_reg_operand (operands[2], SImode))"
9103   "@
9104    stbux %3,%0,%2
9105    stbu %3,%2(%0)"
9106   [(set_attr "type" "store")
9107    (set_attr "update" "yes")
9108    (set_attr "indexed" "yes,no")])
9110 (define_insn "*movsf_update1"
9111   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9112         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9113                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9114    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9115         (plus:SI (match_dup 1) (match_dup 2)))]
9116   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9117    && (!avoiding_indexed_address_p (SImode)
9118        || !gpc_reg_operand (operands[2], SImode))"
9119   "@
9120    lfsux %3,%0,%2
9121    lfsu %3,%2(%0)"
9122   [(set_attr "type" "fpload")
9123    (set_attr "update" "yes")
9124    (set_attr "indexed" "yes,no")])
9126 (define_insn "*movsf_update2"
9127   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9128                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9129         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9130    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9131         (plus:SI (match_dup 1) (match_dup 2)))]
9132   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9133    && (!avoiding_indexed_address_p (SImode)
9134        || !gpc_reg_operand (operands[2], SImode))"
9135   "@
9136    stfsux %3,%0,%2
9137    stfsu %3,%2(%0)"
9138   [(set_attr "type" "fpstore")
9139    (set_attr "update" "yes")
9140    (set_attr "indexed" "yes,no")])
9142 (define_insn "*movsf_update3"
9143   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9144         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9145                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9146    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9147         (plus:SI (match_dup 1) (match_dup 2)))]
9148   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9149    && (!avoiding_indexed_address_p (SImode)
9150        || !gpc_reg_operand (operands[2], SImode))"
9151   "@
9152    lwzux %3,%0,%2
9153    lwzu %3,%2(%0)"
9154   [(set_attr "type" "load")
9155    (set_attr "update" "yes")
9156    (set_attr "indexed" "yes,no")])
9158 (define_insn "*movsf_update4"
9159   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9160                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9161         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9162    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9163         (plus:SI (match_dup 1) (match_dup 2)))]
9164   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9165    && (!avoiding_indexed_address_p (SImode)
9166        || !gpc_reg_operand (operands[2], SImode))"
9167   "@
9168    stwux %3,%0,%2
9169    stwu %3,%2(%0)"
9170   [(set_attr "type" "store")
9171    (set_attr "update" "yes")
9172    (set_attr "indexed" "yes,no")])
9174 (define_insn "*movdf_update1"
9175   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9176         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9177                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9178    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9179         (plus:SI (match_dup 1) (match_dup 2)))]
9180   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9181    && (!avoiding_indexed_address_p (SImode)
9182        || !gpc_reg_operand (operands[2], SImode))"
9183   "@
9184    lfdux %3,%0,%2
9185    lfdu %3,%2(%0)"
9186   [(set_attr "type" "fpload")
9187    (set_attr "update" "yes")
9188    (set_attr "indexed" "yes,no")
9189    (set_attr "size" "64")])
9191 (define_insn "*movdf_update2"
9192   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9193                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9194         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9195    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9196         (plus:SI (match_dup 1) (match_dup 2)))]
9197   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9198    && (!avoiding_indexed_address_p (SImode)
9199        || !gpc_reg_operand (operands[2], SImode))"
9200   "@
9201    stfdux %3,%0,%2
9202    stfdu %3,%2(%0)"
9203   [(set_attr "type" "fpstore")
9204    (set_attr "update" "yes")
9205    (set_attr "indexed" "yes,no")])
9208 ;; After inserting conditional returns we can sometimes have
9209 ;; unnecessary register moves.  Unfortunately we cannot have a
9210 ;; modeless peephole here, because some single SImode sets have early
9211 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9212 ;; sequences, using get_attr_length here will smash the operands
9213 ;; array.  Neither is there an early_cobbler_p predicate.
9214 ;; Also this optimization interferes with scalars going into
9215 ;; altivec registers (the code does reloading through the FPRs).
9216 (define_peephole2
9217   [(set (match_operand:DF 0 "gpc_reg_operand")
9218         (match_operand:DF 1 "any_operand"))
9219    (set (match_operand:DF 2 "gpc_reg_operand")
9220         (match_dup 0))]
9221   "!TARGET_VSX
9222    && peep2_reg_dead_p (2, operands[0])"
9223   [(set (match_dup 2) (match_dup 1))])
9225 (define_peephole2
9226   [(set (match_operand:SF 0 "gpc_reg_operand")
9227         (match_operand:SF 1 "any_operand"))
9228    (set (match_operand:SF 2 "gpc_reg_operand")
9229         (match_dup 0))]
9230   "!TARGET_P8_VECTOR
9231    && peep2_reg_dead_p (2, operands[0])"
9232   [(set (match_dup 2) (match_dup 1))])
9235 ;; TLS support.
9237 ;; Mode attributes for different ABIs.
9238 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9239 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9240 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9241 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9243 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9244   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9245         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9246               (match_operand 4 "" "g")))
9247    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9248                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9249                    UNSPEC_TLSGD)
9250    (clobber (reg:SI LR_REGNO))]
9251   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9253   if (TARGET_CMODEL != CMODEL_SMALL)
9254     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9255            "bl %z3\;nop";
9256   else
9257     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9259   "&& TARGET_TLS_MARKERS"
9260   [(set (match_dup 0)
9261         (unspec:TLSmode [(match_dup 1)
9262                          (match_dup 2)]
9263                         UNSPEC_TLSGD))
9264    (parallel [(set (match_dup 0)
9265                    (call (mem:TLSmode (match_dup 3))
9266                          (match_dup 4)))
9267               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9268               (clobber (reg:SI LR_REGNO))])]
9269   ""
9270   [(set_attr "type" "two")
9271    (set (attr "length")
9272      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9273                    (const_int 16)
9274                    (const_int 12)))])
9276 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9277   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9278         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9279               (match_operand 4 "" "g")))
9280    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9281                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9282                    UNSPEC_TLSGD)
9283    (clobber (reg:SI LR_REGNO))]
9284   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9286   if (flag_pic)
9287     {
9288       if (TARGET_SECURE_PLT && flag_pic == 2)
9289         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9290       else
9291         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9292     }
9293   else
9294     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9296   "&& TARGET_TLS_MARKERS"
9297   [(set (match_dup 0)
9298         (unspec:TLSmode [(match_dup 1)
9299                          (match_dup 2)]
9300                         UNSPEC_TLSGD))
9301    (parallel [(set (match_dup 0)
9302                    (call (mem:TLSmode (match_dup 3))
9303                          (match_dup 4)))
9304               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9305               (clobber (reg:SI LR_REGNO))])]
9306   ""
9307   [(set_attr "type" "two")
9308    (set_attr "length" "8")])
9310 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9311   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9312         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9313                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9314                         UNSPEC_TLSGD))]
9315   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9316   "addi %0,%1,%2@got@tlsgd"
9317   "&& TARGET_CMODEL != CMODEL_SMALL"
9318   [(set (match_dup 3)
9319         (high:TLSmode
9320             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9321    (set (match_dup 0)
9322         (lo_sum:TLSmode (match_dup 3)
9323             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9325   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9327   [(set (attr "length")
9328      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9329                    (const_int 8)
9330                    (const_int 4)))])
9332 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9333   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9334      (high:TLSmode
9335        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9336                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9337                        UNSPEC_TLSGD)))]
9338   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9339   "addis %0,%1,%2@got@tlsgd@ha"
9340   [(set_attr "length" "4")])
9342 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9343   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9344      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9345        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9346                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9347                        UNSPEC_TLSGD)))]
9348   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9349   "addi %0,%1,%2@got@tlsgd@l"
9350   [(set_attr "length" "4")])
9352 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9353   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9354         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9355               (match_operand 2 "" "g")))
9356    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9357                    UNSPEC_TLSGD)
9358    (clobber (reg:SI LR_REGNO))]
9359   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9360    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9361   "bl %z1(%3@tlsgd)\;nop"
9362   [(set_attr "type" "branch")
9363    (set_attr "length" "8")])
9365 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9366   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9367         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9368               (match_operand 2 "" "g")))
9369    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9370                    UNSPEC_TLSGD)
9371    (clobber (reg:SI LR_REGNO))]
9372   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9374   if (flag_pic)
9375     {
9376       if (TARGET_SECURE_PLT && flag_pic == 2)
9377         return "bl %z1+32768(%3@tlsgd)@plt";
9378       return "bl %z1(%3@tlsgd)@plt";
9379     }
9380   return "bl %z1(%3@tlsgd)";
9382   [(set_attr "type" "branch")
9383    (set_attr "length" "4")])
9385 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9386   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9387         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9388               (match_operand 3 "" "g")))
9389    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9390                    UNSPEC_TLSLD)
9391    (clobber (reg:SI LR_REGNO))]
9392   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9394   if (TARGET_CMODEL != CMODEL_SMALL)
9395     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9396            "bl %z2\;nop";
9397   else
9398     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9400   "&& TARGET_TLS_MARKERS"
9401   [(set (match_dup 0)
9402         (unspec:TLSmode [(match_dup 1)]
9403                         UNSPEC_TLSLD))
9404    (parallel [(set (match_dup 0)
9405                    (call (mem:TLSmode (match_dup 2))
9406                          (match_dup 3)))
9407               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9408               (clobber (reg:SI LR_REGNO))])]
9409   ""
9410   [(set_attr "type" "two")
9411    (set (attr "length")
9412      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9413                    (const_int 16)
9414                    (const_int 12)))])
9416 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9417   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9418         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9419               (match_operand 3 "" "g")))
9420    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9421                    UNSPEC_TLSLD)
9422    (clobber (reg:SI LR_REGNO))]
9423   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9425   if (flag_pic)
9426     {
9427       if (TARGET_SECURE_PLT && flag_pic == 2)
9428         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9429       else
9430         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9431     }
9432   else
9433     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9435   "&& TARGET_TLS_MARKERS"
9436   [(set (match_dup 0)
9437         (unspec:TLSmode [(match_dup 1)]
9438                         UNSPEC_TLSLD))
9439    (parallel [(set (match_dup 0)
9440                    (call (mem:TLSmode (match_dup 2))
9441                          (match_dup 3)))
9442               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9443               (clobber (reg:SI LR_REGNO))])]
9444   ""
9445   [(set_attr "length" "8")])
9447 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9448   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9449         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9450                         UNSPEC_TLSLD))]
9451   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9452   "addi %0,%1,%&@got@tlsld"
9453   "&& TARGET_CMODEL != CMODEL_SMALL"
9454   [(set (match_dup 2)
9455         (high:TLSmode
9456             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9457    (set (match_dup 0)
9458         (lo_sum:TLSmode (match_dup 2)
9459             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9461   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9463   [(set (attr "length")
9464      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9465                    (const_int 8)
9466                    (const_int 4)))])
9468 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9469   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9470      (high:TLSmode
9471        (unspec:TLSmode [(const_int 0)
9472                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9473                        UNSPEC_TLSLD)))]
9474   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9475   "addis %0,%1,%&@got@tlsld@ha"
9476   [(set_attr "length" "4")])
9478 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9479   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9480      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9481        (unspec:TLSmode [(const_int 0)
9482                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9483                        UNSPEC_TLSLD)))]
9484   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9485   "addi %0,%1,%&@got@tlsld@l"
9486   [(set_attr "length" "4")])
9488 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9489   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9490         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9491               (match_operand 2 "" "g")))
9492    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9493    (clobber (reg:SI LR_REGNO))]
9494   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9495    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9496   "bl %z1(%&@tlsld)\;nop"
9497   [(set_attr "type" "branch")
9498    (set_attr "length" "8")])
9500 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9501   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9502         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9503               (match_operand 2 "" "g")))
9504    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9505    (clobber (reg:SI LR_REGNO))]
9506   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9508   if (flag_pic)
9509     {
9510       if (TARGET_SECURE_PLT && flag_pic == 2)
9511         return "bl %z1+32768(%&@tlsld)@plt";
9512       return "bl %z1(%&@tlsld)@plt";
9513     }
9514   return "bl %z1(%&@tlsld)";
9516   [(set_attr "type" "branch")
9517    (set_attr "length" "4")])
9519 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9520   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9521         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9522                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9523                         UNSPEC_TLSDTPREL))]
9524   "HAVE_AS_TLS"
9525   "addi %0,%1,%2@dtprel")
9527 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9528   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9529         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9530                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9531                         UNSPEC_TLSDTPRELHA))]
9532   "HAVE_AS_TLS"
9533   "addis %0,%1,%2@dtprel@ha")
9535 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9536   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9537         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9538                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9539                         UNSPEC_TLSDTPRELLO))]
9540   "HAVE_AS_TLS"
9541   "addi %0,%1,%2@dtprel@l")
9543 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9544   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9545         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9546                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9547                         UNSPEC_TLSGOTDTPREL))]
9548   "HAVE_AS_TLS"
9549   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9550   "&& TARGET_CMODEL != CMODEL_SMALL"
9551   [(set (match_dup 3)
9552         (high:TLSmode
9553             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9554    (set (match_dup 0)
9555         (lo_sum:TLSmode (match_dup 3)
9556             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9558   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9560   [(set (attr "length")
9561      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9562                    (const_int 8)
9563                    (const_int 4)))])
9565 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9566   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9567      (high:TLSmode
9568        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9569                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9570                        UNSPEC_TLSGOTDTPREL)))]
9571   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9572   "addis %0,%1,%2@got@dtprel@ha"
9573   [(set_attr "length" "4")])
9575 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9576   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9577      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9578          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9579                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9580                          UNSPEC_TLSGOTDTPREL)))]
9581   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9582   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9583   [(set_attr "length" "4")])
9585 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9586   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9587         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9588                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9589                         UNSPEC_TLSTPREL))]
9590   "HAVE_AS_TLS"
9591   "addi %0,%1,%2@tprel")
9593 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9594   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9595         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9596                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9597                         UNSPEC_TLSTPRELHA))]
9598   "HAVE_AS_TLS"
9599   "addis %0,%1,%2@tprel@ha")
9601 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9602   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9603         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9604                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9605                         UNSPEC_TLSTPRELLO))]
9606   "HAVE_AS_TLS"
9607   "addi %0,%1,%2@tprel@l")
9609 ;; "b" output constraint here and on tls_tls input to support linker tls
9610 ;; optimization.  The linker may edit the instructions emitted by a
9611 ;; tls_got_tprel/tls_tls pair to addis,addi.
9612 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9613   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9614         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9615                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9616                         UNSPEC_TLSGOTTPREL))]
9617   "HAVE_AS_TLS"
9618   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9619   "&& TARGET_CMODEL != CMODEL_SMALL"
9620   [(set (match_dup 3)
9621         (high:TLSmode
9622             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9623    (set (match_dup 0)
9624         (lo_sum:TLSmode (match_dup 3)
9625             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9627   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9629   [(set (attr "length")
9630      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9631                    (const_int 8)
9632                    (const_int 4)))])
9634 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9635   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9636      (high:TLSmode
9637        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9638                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9639                        UNSPEC_TLSGOTTPREL)))]
9640   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9641   "addis %0,%1,%2@got@tprel@ha"
9642   [(set_attr "length" "4")])
9644 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9645   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9646      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9647          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9648                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9649                          UNSPEC_TLSGOTTPREL)))]
9650   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9651   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9652   [(set_attr "length" "4")])
9654 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9655   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9656         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9657                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9658                         UNSPEC_TLSTLS))]
9659   "TARGET_ELF && HAVE_AS_TLS"
9660   "add %0,%1,%2@tls")
9662 (define_expand "tls_get_tpointer"
9663   [(set (match_operand:SI 0 "gpc_reg_operand")
9664         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9665   "TARGET_XCOFF && HAVE_AS_TLS"
9667   emit_insn (gen_tls_get_tpointer_internal ());
9668   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9669   DONE;
9672 (define_insn "tls_get_tpointer_internal"
9673   [(set (reg:SI 3)
9674         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9675    (clobber (reg:SI LR_REGNO))]
9676   "TARGET_XCOFF && HAVE_AS_TLS"
9677   "bla __get_tpointer")
9679 (define_expand "tls_get_addr<mode>"
9680   [(set (match_operand:P 0 "gpc_reg_operand")
9681         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9682                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9683   "TARGET_XCOFF && HAVE_AS_TLS"
9685   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9686   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9687   emit_insn (gen_tls_get_addr_internal<mode> ());
9688   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9689   DONE;
9692 (define_insn "tls_get_addr_internal<mode>"
9693   [(set (reg:P 3)
9694         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9695    (clobber (reg:P 0))
9696    (clobber (reg:P 4))
9697    (clobber (reg:P 5))
9698    (clobber (reg:P 11))
9699    (clobber (reg:CC CR0_REGNO))
9700    (clobber (reg:P LR_REGNO))]
9701   "TARGET_XCOFF && HAVE_AS_TLS"
9702   "bla __tls_get_addr")
9704 ;; Next come insns related to the calling sequence.
9706 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9707 ;; We move the back-chain and decrement the stack pointer.
9709 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9710 ;; constant alloca, using that predicate will force the generic code to put
9711 ;; the constant size into a register before calling the expander.
9713 ;; As a result the expander would not have the constant size information
9714 ;; in those cases and would have to generate less efficient code.
9716 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9717 ;; the constant size.  The value is forced into a register if necessary.
9719 (define_expand "allocate_stack"
9720   [(set (match_operand 0 "gpc_reg_operand")
9721         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9722    (set (reg 1)
9723         (minus (reg 1) (match_dup 1)))]
9724   ""
9726   rtx chain = gen_reg_rtx (Pmode);
9727   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9728   rtx neg_op0;
9729   rtx insn, par, set, mem;
9731   /* By allowing reg_or_cint_operand as the predicate we can get
9732      better code for stack-clash-protection because we do not lose
9733      size information.  But the rest of the code expects the operand
9734      to be reg_or_short_operand.  If it isn't, then force it into
9735      a register.  */
9736   rtx orig_op1 = operands[1];
9737   if (!reg_or_short_operand (operands[1], Pmode))
9738     operands[1] = force_reg (Pmode, operands[1]);
9740   emit_move_insn (chain, stack_bot);
9742   /* Check stack bounds if necessary.  */
9743   if (crtl->limit_stack)
9744     {
9745       rtx available;
9746       available = expand_binop (Pmode, sub_optab,
9747                                 stack_pointer_rtx, stack_limit_rtx,
9748                                 NULL_RTX, 1, OPTAB_WIDEN);
9749       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9750     }
9752   /* Allocate and probe if requested.
9753      This may look similar to the loop we use for prologue allocations,
9754      but it is critically different.  For the former we know the loop
9755      will iterate, but do not know that generally here.  The former
9756      uses that knowledge to rotate the loop.  Combining them would be
9757      possible with some performance cost.  */
9758   if (flag_stack_clash_protection)
9759     {
9760       rtx rounded_size, last_addr, residual;
9761       HOST_WIDE_INT probe_interval;
9762       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9763                                                 &residual, &probe_interval,
9764                                                 orig_op1);
9765       
9766       /* We do occasionally get in here with constant sizes, we might
9767          as well do a reasonable job when we obviously can.  */
9768       if (rounded_size != const0_rtx)
9769         {
9770           rtx loop_lab, end_loop;
9771           bool rotated = CONST_INT_P (rounded_size);
9772           rtx update = GEN_INT (-probe_interval);
9773           if (probe_interval > 32768)
9774             update = force_reg (Pmode, update);
9776           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9777                                                         last_addr, rotated);
9779           if (Pmode == SImode)
9780             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9781                                                stack_pointer_rtx,
9782                                                update, chain));
9783           else
9784             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9785                                                   stack_pointer_rtx,
9786                                                   update, chain));
9787           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9788                                                       last_addr, rotated);
9789         }
9791       /* Now handle residuals.  We just have to set operands[1] correctly
9792          and let the rest of the expander run.  */
9793       operands[1] = residual;
9794       if (!CONST_INT_P (residual))
9795         operands[1] = force_reg (Pmode, operands[1]);
9796     }
9798   if (GET_CODE (operands[1]) != CONST_INT
9799       || INTVAL (operands[1]) < -32767
9800       || INTVAL (operands[1]) > 32768)
9801     {
9802       neg_op0 = gen_reg_rtx (Pmode);
9803       if (TARGET_32BIT)
9804         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9805       else
9806         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9807     }
9808   else
9809     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9811   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9812                                        : gen_movdi_di_update_stack))
9813                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9814                          chain));
9815   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9816      it now and set the alias set/attributes. The above gen_*_update
9817      calls will generate a PARALLEL with the MEM set being the first
9818      operation. */
9819   par = PATTERN (insn);
9820   gcc_assert (GET_CODE (par) == PARALLEL);
9821   set = XVECEXP (par, 0, 0);
9822   gcc_assert (GET_CODE (set) == SET);
9823   mem = SET_DEST (set);
9824   gcc_assert (MEM_P (mem));
9825   MEM_NOTRAP_P (mem) = 1;
9826   set_mem_alias_set (mem, get_frame_alias_set ());
9828   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9829   DONE;
9832 ;; These patterns say how to save and restore the stack pointer.  We need not
9833 ;; save the stack pointer at function level since we are careful to
9834 ;; preserve the backchain.  At block level, we have to restore the backchain
9835 ;; when we restore the stack pointer.
9837 ;; For nonlocal gotos, we must save both the stack pointer and its
9838 ;; backchain and restore both.  Note that in the nonlocal case, the
9839 ;; save area is a memory location.
9841 (define_expand "save_stack_function"
9842   [(match_operand 0 "any_operand")
9843    (match_operand 1 "any_operand")]
9844   ""
9845   "DONE;")
9847 (define_expand "restore_stack_function"
9848   [(match_operand 0 "any_operand")
9849    (match_operand 1 "any_operand")]
9850   ""
9851   "DONE;")
9853 ;; Adjust stack pointer (op0) to a new value (op1).
9854 ;; First copy old stack backchain to new location, and ensure that the
9855 ;; scheduler won't reorder the sp assignment before the backchain write.
9856 (define_expand "restore_stack_block"
9857   [(set (match_dup 2) (match_dup 3))
9858    (set (match_dup 4) (match_dup 2))
9859    (match_dup 5)
9860    (set (match_operand 0 "register_operand")
9861         (match_operand 1 "register_operand"))]
9862   ""
9864   rtvec p;
9866   operands[1] = force_reg (Pmode, operands[1]);
9867   operands[2] = gen_reg_rtx (Pmode);
9868   operands[3] = gen_frame_mem (Pmode, operands[0]);
9869   operands[4] = gen_frame_mem (Pmode, operands[1]);
9870   p = rtvec_alloc (1);
9871   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9872                                   const0_rtx);
9873   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9876 (define_expand "save_stack_nonlocal"
9877   [(set (match_dup 3) (match_dup 4))
9878    (set (match_operand 0 "memory_operand") (match_dup 3))
9879    (set (match_dup 2) (match_operand 1 "register_operand"))]
9880   ""
9882   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9884   /* Copy the backchain to the first word, sp to the second.  */
9885   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9886   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9887   operands[3] = gen_reg_rtx (Pmode);
9888   operands[4] = gen_frame_mem (Pmode, operands[1]);
9891 (define_expand "restore_stack_nonlocal"
9892   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9893    (set (match_dup 3) (match_dup 4))
9894    (set (match_dup 5) (match_dup 2))
9895    (match_dup 6)
9896    (set (match_operand 0 "register_operand") (match_dup 3))]
9897   ""
9899   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9900   rtvec p;
9902   /* Restore the backchain from the first word, sp from the second.  */
9903   operands[2] = gen_reg_rtx (Pmode);
9904   operands[3] = gen_reg_rtx (Pmode);
9905   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9906   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9907   operands[5] = gen_frame_mem (Pmode, operands[3]);
9908   p = rtvec_alloc (1);
9909   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9910                                   const0_rtx);
9911   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9914 ;; TOC register handling.
9916 ;; Code to initialize the TOC register...
9918 (define_insn "load_toc_aix_si"
9919   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9920                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9921               (use (reg:SI 2))])]
9922   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9924   char buf[30];
9925   extern int need_toc_init;
9926   need_toc_init = 1;
9927   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9928   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9929   operands[2] = gen_rtx_REG (Pmode, 2);
9930   return "lwz %0,%1(%2)";
9932   [(set_attr "type" "load")
9933    (set_attr "update" "no")
9934    (set_attr "indexed" "no")])
9936 (define_insn "load_toc_aix_di"
9937   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9938                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9939               (use (reg:DI 2))])]
9940   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9942   char buf[30];
9943   extern int need_toc_init;
9944   need_toc_init = 1;
9945   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9946                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9947   if (TARGET_ELF)
9948     strcat (buf, "@toc");
9949   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9950   operands[2] = gen_rtx_REG (Pmode, 2);
9951   return "ld %0,%1(%2)";
9953   [(set_attr "type" "load")
9954    (set_attr "update" "no")
9955    (set_attr "indexed" "no")])
9957 (define_insn "load_toc_v4_pic_si"
9958   [(set (reg:SI LR_REGNO)
9959         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9960   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9961   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9962   [(set_attr "type" "branch")
9963    (set_attr "length" "4")])
9965 (define_expand "load_toc_v4_PIC_1"
9966   [(parallel [(set (reg:SI LR_REGNO)
9967                    (match_operand:SI 0 "immediate_operand" "s"))
9968               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9969   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9970    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9971   "")
9973 (define_insn "load_toc_v4_PIC_1_normal"
9974   [(set (reg:SI LR_REGNO)
9975         (match_operand:SI 0 "immediate_operand" "s"))
9976    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9977   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9978    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9979   "bcl 20,31,%0\n%0:"
9980   [(set_attr "type" "branch")
9981    (set_attr "length" "4")
9982    (set_attr "cannot_copy" "yes")])
9984 (define_insn "load_toc_v4_PIC_1_476"
9985   [(set (reg:SI LR_REGNO)
9986         (match_operand:SI 0 "immediate_operand" "s"))
9987    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9988   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9989    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9991   char name[32];
9992   static char templ[32];
9994   get_ppc476_thunk_name (name);
9995   sprintf (templ, "bl %s\n%%0:", name);
9996   return templ;
9998   [(set_attr "type" "branch")
9999    (set_attr "length" "4")
10000    (set_attr "cannot_copy" "yes")])
10002 (define_expand "load_toc_v4_PIC_1b"
10003   [(parallel [(set (reg:SI LR_REGNO)
10004                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10005                                (label_ref (match_operand 1 ""))]
10006                            UNSPEC_TOCPTR))
10007               (match_dup 1)])]
10008   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10009   "")
10011 (define_insn "load_toc_v4_PIC_1b_normal"
10012   [(set (reg:SI LR_REGNO)
10013         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10014                     (label_ref (match_operand 1 "" ""))]
10015                 UNSPEC_TOCPTR))
10016    (match_dup 1)]
10017   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10018   "bcl 20,31,$+8\;.long %0-$"
10019   [(set_attr "type" "branch")
10020    (set_attr "length" "8")])
10022 (define_insn "load_toc_v4_PIC_1b_476"
10023   [(set (reg:SI LR_REGNO)
10024         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10025                     (label_ref (match_operand 1 "" ""))]
10026                 UNSPEC_TOCPTR))
10027    (match_dup 1)]
10028   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10030   char name[32];
10031   static char templ[32];
10033   get_ppc476_thunk_name (name);
10034   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10035   return templ;
10037   [(set_attr "type" "branch")
10038    (set_attr "length" "16")])
10040 (define_insn "load_toc_v4_PIC_2"
10041   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10042         (mem:SI (plus:SI
10043                   (match_operand:SI 1 "gpc_reg_operand" "b")
10044                   (const
10045                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10046                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10047   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10048   "lwz %0,%2-%3(%1)"
10049   [(set_attr "type" "load")])
10051 (define_insn "load_toc_v4_PIC_3b"
10052   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10053         (plus:SI
10054           (match_operand:SI 1 "gpc_reg_operand" "b")
10055           (high:SI
10056             (const
10057               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10058                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10059   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10060   "addis %0,%1,%2-%3@ha")
10062 (define_insn "load_toc_v4_PIC_3c"
10063   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10064         (lo_sum:SI
10065           (match_operand:SI 1 "gpc_reg_operand" "b")
10066           (const
10067             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10068                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10069   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10070   "addi %0,%1,%2-%3@l")
10072 ;; If the TOC is shared over a translation unit, as happens with all
10073 ;; the kinds of PIC that we support, we need to restore the TOC
10074 ;; pointer only when jumping over units of translation.
10075 ;; On Darwin, we need to reload the picbase.
10077 (define_expand "builtin_setjmp_receiver"
10078   [(use (label_ref (match_operand 0 "")))]
10079   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10080    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10081    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10083 #if TARGET_MACHO
10084   if (DEFAULT_ABI == ABI_DARWIN)
10085     {
10086       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10087       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10088       rtx tmplabrtx;
10089       char tmplab[20];
10091       crtl->uses_pic_offset_table = 1;
10092       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10093                                   CODE_LABEL_NUMBER (operands[0]));
10094       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10096       emit_insn (gen_load_macho_picbase (tmplabrtx));
10097       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10098       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10099     }
10100   else
10101 #endif
10102     rs6000_emit_load_toc_table (FALSE);
10103   DONE;
10106 ;; Largetoc support
10107 (define_insn "*largetoc_high"
10108   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10109         (high:DI
10110           (unspec [(match_operand:DI 1 "" "")
10111                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10112                   UNSPEC_TOCREL)))]
10113    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10114    "addis %0,%2,%1@toc@ha")
10116 (define_insn "*largetoc_high_aix<mode>"
10117   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10118         (high:P
10119           (unspec [(match_operand:P 1 "" "")
10120                    (match_operand:P 2 "gpc_reg_operand" "b")]
10121                   UNSPEC_TOCREL)))]
10122    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10123    "addis %0,%1@u(%2)")
10125 (define_insn "*largetoc_high_plus"
10126   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10127         (high:DI
10128           (plus:DI
10129             (unspec [(match_operand:DI 1 "" "")
10130                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10131                     UNSPEC_TOCREL)
10132             (match_operand:DI 3 "add_cint_operand" "n"))))]
10133    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10134    "addis %0,%2,%1+%3@toc@ha")
10136 (define_insn "*largetoc_high_plus_aix<mode>"
10137   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10138         (high:P
10139           (plus:P
10140             (unspec [(match_operand:P 1 "" "")
10141                      (match_operand:P 2 "gpc_reg_operand" "b")]
10142                     UNSPEC_TOCREL)
10143             (match_operand:P 3 "add_cint_operand" "n"))))]
10144    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10145    "addis %0,%1+%3@u(%2)")
10147 (define_insn "*largetoc_low"
10148   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10149         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10150                    (match_operand:DI 2 "" "")))]
10151    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10152    "addi %0,%1,%2@l")
10154 (define_insn "*largetoc_low_aix<mode>"
10155   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10156         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10157                    (match_operand:P 2 "" "")))]
10158    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10159    "la %0,%2@l(%1)")
10161 (define_insn_and_split "*tocref<mode>"
10162   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10163         (match_operand:P 1 "small_toc_ref" "R"))]
10164    "TARGET_TOC"
10165    "la %0,%a1"
10166    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10167   [(set (match_dup 0) (high:P (match_dup 1)))
10168    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10170 ;; Elf specific ways of loading addresses for non-PIC code.
10171 ;; The output of this could be r0, but we make a very strong
10172 ;; preference for a base register because it will usually
10173 ;; be needed there.
10174 (define_insn "elf_high"
10175   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10176         (high:SI (match_operand 1 "" "")))]
10177   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10178   "lis %0,%1@ha")
10180 (define_insn "elf_low"
10181   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10182         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10183                    (match_operand 2 "" "")))]
10184    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10185    "la %0,%2@l(%1)")
10187 ;; Call and call_value insns
10188 (define_expand "call"
10189   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10190                     (match_operand 1 ""))
10191               (use (match_operand 2 ""))
10192               (clobber (reg:SI LR_REGNO))])]
10193   ""
10195 #if TARGET_MACHO
10196   if (MACHOPIC_INDIRECT)
10197     operands[0] = machopic_indirect_call_target (operands[0]);
10198 #endif
10200   gcc_assert (GET_CODE (operands[0]) == MEM);
10201   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10203   operands[0] = XEXP (operands[0], 0);
10205   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10206     {
10207       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10208       DONE;
10209     }
10211   if (GET_CODE (operands[0]) != SYMBOL_REF
10212       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10213     {
10214       if (INTVAL (operands[2]) & CALL_LONG)
10215         operands[0] = rs6000_longcall_ref (operands[0]);
10217       switch (DEFAULT_ABI)
10218         {
10219         case ABI_V4:
10220         case ABI_DARWIN:
10221           operands[0] = force_reg (Pmode, operands[0]);
10222           break;
10224         default:
10225           gcc_unreachable ();
10226         }
10227     }
10230 (define_expand "call_value"
10231   [(parallel [(set (match_operand 0 "")
10232                    (call (mem:SI (match_operand 1 "address_operand"))
10233                          (match_operand 2 "")))
10234               (use (match_operand 3 ""))
10235               (clobber (reg:SI LR_REGNO))])]
10236   ""
10238 #if TARGET_MACHO
10239   if (MACHOPIC_INDIRECT)
10240     operands[1] = machopic_indirect_call_target (operands[1]);
10241 #endif
10243   gcc_assert (GET_CODE (operands[1]) == MEM);
10244   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10246   operands[1] = XEXP (operands[1], 0);
10248   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10249     {
10250       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10251       DONE;
10252     }
10254   if (GET_CODE (operands[1]) != SYMBOL_REF
10255       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10256     {
10257       if (INTVAL (operands[3]) & CALL_LONG)
10258         operands[1] = rs6000_longcall_ref (operands[1]);
10260       switch (DEFAULT_ABI)
10261         {
10262         case ABI_V4:
10263         case ABI_DARWIN:
10264           operands[1] = force_reg (Pmode, operands[1]);
10265           break;
10267         default:
10268           gcc_unreachable ();
10269         }
10270     }
10273 ;; Call to function in current module.  No TOC pointer reload needed.
10274 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10275 ;; either the function was not prototyped, or it was prototyped as a
10276 ;; variable argument function.  It is > 0 if FP registers were passed
10277 ;; and < 0 if they were not.
10279 (define_insn "*call_local32"
10280   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10281          (match_operand 1 "" "g,g"))
10282    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10283    (clobber (reg:SI LR_REGNO))]
10284   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10286   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10287     output_asm_insn ("crxor 6,6,6", operands);
10289   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10290     output_asm_insn ("creqv 6,6,6", operands);
10292   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10294   [(set_attr "type" "branch")
10295    (set_attr "length" "4,8")])
10297 (define_insn "*call_local64"
10298   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10299          (match_operand 1 "" "g,g"))
10300    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10301    (clobber (reg:SI LR_REGNO))]
10302   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10304   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10305     output_asm_insn ("crxor 6,6,6", operands);
10307   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10308     output_asm_insn ("creqv 6,6,6", operands);
10310   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10312   [(set_attr "type" "branch")
10313    (set_attr "length" "4,8")])
10315 (define_insn "*call_value_local32"
10316   [(set (match_operand 0 "" "")
10317         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10318               (match_operand 2 "" "g,g")))
10319    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10320    (clobber (reg:SI LR_REGNO))]
10321   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10323   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10324     output_asm_insn ("crxor 6,6,6", operands);
10326   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10327     output_asm_insn ("creqv 6,6,6", operands);
10329   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10331   [(set_attr "type" "branch")
10332    (set_attr "length" "4,8")])
10335 (define_insn "*call_value_local64"
10336   [(set (match_operand 0 "" "")
10337         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10338               (match_operand 2 "" "g,g")))
10339    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10340    (clobber (reg:SI LR_REGNO))]
10341   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10343   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10344     output_asm_insn ("crxor 6,6,6", operands);
10346   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10347     output_asm_insn ("creqv 6,6,6", operands);
10349   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10351   [(set_attr "type" "branch")
10352    (set_attr "length" "4,8")])
10355 ;; A function pointer under System V is just a normal pointer
10356 ;; operands[0] is the function pointer
10357 ;; operands[1] is the stack size to clean up
10358 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10359 ;; which indicates how to set cr1
10361 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10362   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10363          (match_operand 1 "" "g,g,g,g"))
10364    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10365    (clobber (reg:SI LR_REGNO))]
10366   "DEFAULT_ABI == ABI_V4
10367    || DEFAULT_ABI == ABI_DARWIN"
10369   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10370     output_asm_insn ("crxor 6,6,6", operands);
10372   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10373     output_asm_insn ("creqv 6,6,6", operands);
10375   if (rs6000_speculate_indirect_jumps
10376       || which_alternative == 1 || which_alternative == 3)
10377     return "b%T0l";
10378   else
10379     return "crset 2\;beq%T0l-";
10381   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10382    (set (attr "length")
10383         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10384                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10385                         (const_int 0)))
10386                   (const_string "8")
10387                (and (eq (symbol_ref "which_alternative") (const_int 2))
10388                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10389                         (const_int 0)))
10390                   (const_string "8")
10391                (and (eq (symbol_ref "which_alternative") (const_int 2))
10392                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10393                         (const_int 0)))
10394                   (const_string "12")
10395                (eq (symbol_ref "which_alternative") (const_int 3))
10396                   (const_string "8")]
10397               (const_string "4")))])
10399 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10400   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10401          (match_operand 1 "" "g,g"))
10402    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10403    (clobber (reg:SI LR_REGNO))]
10404   "(DEFAULT_ABI == ABI_DARWIN
10405    || (DEFAULT_ABI == ABI_V4
10406        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10408   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10409     output_asm_insn ("crxor 6,6,6", operands);
10411   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10412     output_asm_insn ("creqv 6,6,6", operands);
10414 #if TARGET_MACHO
10415   return output_call(insn, operands, 0, 2);
10416 #else
10417   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10418     {
10419       gcc_assert (!TARGET_SECURE_PLT);
10420       return "bl %z0@plt";
10421     }
10422   else
10423     return "bl %z0";
10424 #endif
10426   "DEFAULT_ABI == ABI_V4
10427    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10428    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10429   [(parallel [(call (mem:SI (match_dup 0))
10430                     (match_dup 1))
10431               (use (match_dup 2))
10432               (use (match_dup 3))
10433               (clobber (reg:SI LR_REGNO))])]
10435   operands[3] = pic_offset_table_rtx;
10437   [(set_attr "type" "branch,branch")
10438    (set_attr "length" "4,8")])
10440 (define_insn "*call_nonlocal_sysv_secure<mode>"
10441   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10442          (match_operand 1 "" "g,g"))
10443    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10444    (use (match_operand:SI 3 "register_operand" "r,r"))
10445    (clobber (reg:SI LR_REGNO))]
10446   "(DEFAULT_ABI == ABI_V4
10447     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10448     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10450   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10451     output_asm_insn ("crxor 6,6,6", operands);
10453   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10454     output_asm_insn ("creqv 6,6,6", operands);
10456   if (flag_pic == 2)
10457     /* The magic 32768 offset here and in the other sysv call insns
10458        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10459        See sysv4.h:toc_section.  */
10460     return "bl %z0+32768@plt";
10461   else
10462     return "bl %z0@plt";
10464   [(set_attr "type" "branch,branch")
10465    (set_attr "length" "4,8")])
10467 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10468   [(set (match_operand 0 "" "")
10469         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10470               (match_operand 2 "" "g,g,g,g")))
10471    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10472    (clobber (reg:SI LR_REGNO))]
10473   "DEFAULT_ABI == ABI_V4
10474    || DEFAULT_ABI == ABI_DARWIN"
10476   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10477     output_asm_insn ("crxor 6,6,6", operands);
10479   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10480     output_asm_insn ("creqv 6,6,6", operands);
10482   if (rs6000_speculate_indirect_jumps
10483       || which_alternative == 1 || which_alternative == 3)
10484     return "b%T1l";
10485   else
10486     return "crset 2\;beq%T1l-";
10488   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10489    (set (attr "length")
10490         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10491                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10492                         (const_int 0)))
10493                   (const_string "8")
10494                (and (eq (symbol_ref "which_alternative") (const_int 2))
10495                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10496                         (const_int 0)))
10497                   (const_string "8")
10498                (and (eq (symbol_ref "which_alternative") (const_int 2))
10499                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10500                         (const_int 0)))
10501                   (const_string "12")
10502                (eq (symbol_ref "which_alternative") (const_int 3))
10503                   (const_string "8")]
10504               (const_string "4")))])
10506 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10507   [(set (match_operand 0 "" "")
10508         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10509               (match_operand 2 "" "g,g")))
10510    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10511    (clobber (reg:SI LR_REGNO))]
10512   "(DEFAULT_ABI == ABI_DARWIN
10513    || (DEFAULT_ABI == ABI_V4
10514        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10516   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10517     output_asm_insn ("crxor 6,6,6", operands);
10519   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10520     output_asm_insn ("creqv 6,6,6", operands);
10522 #if TARGET_MACHO
10523   return output_call(insn, operands, 1, 3);
10524 #else
10525   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10526     {
10527       gcc_assert (!TARGET_SECURE_PLT);
10528       return "bl %z1@plt";
10529     }
10530   else
10531     return "bl %z1";
10532 #endif
10534   "DEFAULT_ABI == ABI_V4
10535    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10536    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10537   [(parallel [(set (match_dup 0)
10538                    (call (mem:SI (match_dup 1))
10539                          (match_dup 2)))
10540               (use (match_dup 3))
10541               (use (match_dup 4))
10542               (clobber (reg:SI LR_REGNO))])]
10544   operands[4] = pic_offset_table_rtx;
10546   [(set_attr "type" "branch,branch")
10547    (set_attr "length" "4,8")])
10549 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10550   [(set (match_operand 0 "" "")
10551         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10552               (match_operand 2 "" "g,g")))
10553    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10554    (use (match_operand:SI 4 "register_operand" "r,r"))
10555    (clobber (reg:SI LR_REGNO))]
10556   "(DEFAULT_ABI == ABI_V4
10557     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10558     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10560   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10561     output_asm_insn ("crxor 6,6,6", operands);
10563   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10564     output_asm_insn ("creqv 6,6,6", operands);
10566   if (flag_pic == 2)
10567     return "bl %z1+32768@plt";
10568   else
10569     return "bl %z1@plt";
10571   [(set_attr "type" "branch,branch")
10572    (set_attr "length" "4,8")])
10575 ;; Call to AIX abi function in the same module.
10577 (define_insn "*call_local_aix<mode>"
10578   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10579          (match_operand 1 "" "g"))
10580    (clobber (reg:P LR_REGNO))]
10581   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10582   "bl %z0"
10583   [(set_attr "type" "branch")
10584    (set_attr "length" "4")])
10586 (define_insn "*call_value_local_aix<mode>"
10587   [(set (match_operand 0 "" "")
10588         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10589               (match_operand 2 "" "g")))
10590    (clobber (reg:P LR_REGNO))]
10591   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10592   "bl %z1"
10593   [(set_attr "type" "branch")
10594    (set_attr "length" "4")])
10596 ;; Call to AIX abi function which may be in another module.
10597 ;; Restore the TOC pointer (r2) after the call.
10599 (define_insn "*call_nonlocal_aix<mode>"
10600   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10601          (match_operand 1 "" "g"))
10602    (clobber (reg:P LR_REGNO))]
10603   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10604   "bl %z0\;nop"
10605   [(set_attr "type" "branch")
10606    (set_attr "length" "8")])
10608 (define_insn "*call_value_nonlocal_aix<mode>"
10609   [(set (match_operand 0 "" "")
10610         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10611               (match_operand 2 "" "g")))
10612    (clobber (reg:P LR_REGNO))]
10613   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10614   "bl %z1\;nop"
10615   [(set_attr "type" "branch")
10616    (set_attr "length" "8")])
10618 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10619 ;; Operand0 is the addresss of the function to call
10620 ;; Operand2 is the location in the function descriptor to load r2 from
10621 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10623 (define_insn "*call_indirect_aix<mode>"
10624   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10625          (match_operand 1 "" "g,g"))
10626    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10627    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10628    (clobber (reg:P LR_REGNO))]
10629   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10630   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10631   [(set_attr "type" "jmpreg")
10632    (set_attr "length" "12")])
10634 (define_insn "*call_indirect_aix<mode>_nospec"
10635   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10636          (match_operand 1 "" "g,g"))
10637    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10638    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10639    (clobber (reg:P LR_REGNO))]
10640   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10641   "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10642   [(set_attr "type" "jmpreg")
10643    (set_attr "length" "16")])
10645 (define_insn "*call_value_indirect_aix<mode>"
10646   [(set (match_operand 0 "" "")
10647         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10648               (match_operand 2 "" "g,g")))
10649    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10650    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10651    (clobber (reg:P LR_REGNO))]
10652   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10653   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10654   [(set_attr "type" "jmpreg")
10655    (set_attr "length" "12")])
10657 (define_insn "*call_value_indirect_aix<mode>_nospec"
10658   [(set (match_operand 0 "" "")
10659         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10660               (match_operand 2 "" "g,g")))
10661    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10662    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10663    (clobber (reg:P LR_REGNO))]
10664   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10665   "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10666   [(set_attr "type" "jmpreg")
10667    (set_attr "length" "16")])
10669 ;; Call to indirect functions with the ELFv2 ABI.
10670 ;; Operand0 is the addresss of the function to call
10671 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10673 (define_insn "*call_indirect_elfv2<mode>"
10674   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10675          (match_operand 1 "" "g,g"))
10676    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10677    (clobber (reg:P LR_REGNO))]
10678   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10679   "b%T0l\;<ptrload> 2,%2(1)"
10680   [(set_attr "type" "jmpreg")
10681    (set_attr "length" "8")])
10683 ;; Variant with deliberate misprediction.
10684 (define_insn "*call_indirect_elfv2<mode>_nospec"
10685   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10686          (match_operand 1 "" "g,g"))
10687    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10688    (clobber (reg:P LR_REGNO))]
10689   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10690   "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10691   [(set_attr "type" "jmpreg")
10692    (set_attr "length" "12")])
10694 (define_insn "*call_value_indirect_elfv2<mode>"
10695   [(set (match_operand 0 "" "")
10696         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10697               (match_operand 2 "" "g,g")))
10698    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10699    (clobber (reg:P LR_REGNO))]
10700   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10701   "b%T1l\;<ptrload> 2,%3(1)"
10702   [(set_attr "type" "jmpreg")
10703    (set_attr "length" "8")])
10705 ; Variant with deliberate misprediction.
10706 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10707   [(set (match_operand 0 "" "")
10708         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10709               (match_operand 2 "" "g,g")))
10710    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10711    (clobber (reg:P LR_REGNO))]
10712   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10713   "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10714   [(set_attr "type" "jmpreg")
10715    (set_attr "length" "12")])
10717 ;; Call subroutine returning any type.
10718 (define_expand "untyped_call"
10719   [(parallel [(call (match_operand 0 "")
10720                     (const_int 0))
10721               (match_operand 1 "")
10722               (match_operand 2 "")])]
10723   ""
10725   int i;
10727   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10729   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10730     {
10731       rtx set = XVECEXP (operands[2], 0, i);
10732       emit_move_insn (SET_DEST (set), SET_SRC (set));
10733     }
10735   /* The optimizer does not know that the call sets the function value
10736      registers we stored in the result block.  We avoid problems by
10737      claiming that all hard registers are used and clobbered at this
10738      point.  */
10739   emit_insn (gen_blockage ());
10741   DONE;
10744 ;; sibling call patterns
10745 (define_expand "sibcall"
10746   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10747                     (match_operand 1 ""))
10748               (use (match_operand 2 ""))
10749               (simple_return)])]
10750   ""
10752 #if TARGET_MACHO
10753   if (MACHOPIC_INDIRECT)
10754     operands[0] = machopic_indirect_call_target (operands[0]);
10755 #endif
10757   gcc_assert (GET_CODE (operands[0]) == MEM);
10758   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10760   operands[0] = XEXP (operands[0], 0);
10762   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10763     {
10764       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10765       DONE;
10766     }
10769 (define_expand "sibcall_value"
10770   [(parallel [(set (match_operand 0 "register_operand")
10771                 (call (mem:SI (match_operand 1 "address_operand"))
10772                       (match_operand 2 "")))
10773               (use (match_operand 3 ""))
10774               (simple_return)])]
10775   ""
10777 #if TARGET_MACHO
10778   if (MACHOPIC_INDIRECT)
10779     operands[1] = machopic_indirect_call_target (operands[1]);
10780 #endif
10782   gcc_assert (GET_CODE (operands[1]) == MEM);
10783   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10785   operands[1] = XEXP (operands[1], 0);
10787   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10788     {
10789       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10790       DONE;
10791     }
10794 (define_insn "*sibcall_local32"
10795   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10796          (match_operand 1 "" "g,g"))
10797    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10798    (simple_return)]
10799   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10801   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10802     output_asm_insn ("crxor 6,6,6", operands);
10804   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10805     output_asm_insn ("creqv 6,6,6", operands);
10807   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10809   [(set_attr "type" "branch")
10810    (set_attr "length" "4,8")])
10812 (define_insn "*sibcall_local64"
10813   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10814          (match_operand 1 "" "g,g"))
10815    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10816    (simple_return)]
10817   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10819   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10820     output_asm_insn ("crxor 6,6,6", operands);
10822   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10823     output_asm_insn ("creqv 6,6,6", operands);
10825   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10827   [(set_attr "type" "branch")
10828    (set_attr "length" "4,8")])
10830 (define_insn "*sibcall_value_local32"
10831   [(set (match_operand 0 "" "")
10832         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10833               (match_operand 2 "" "g,g")))
10834    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10835    (simple_return)]
10836   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10838   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10839     output_asm_insn ("crxor 6,6,6", operands);
10841   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10842     output_asm_insn ("creqv 6,6,6", operands);
10844   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10846   [(set_attr "type" "branch")
10847    (set_attr "length" "4,8")])
10849 (define_insn "*sibcall_value_local64"
10850   [(set (match_operand 0 "" "")
10851         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10852               (match_operand 2 "" "g,g")))
10853    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10854    (simple_return)]
10855   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10857   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10858     output_asm_insn ("crxor 6,6,6", operands);
10860   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10861     output_asm_insn ("creqv 6,6,6", operands);
10863   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10865   [(set_attr "type" "branch")
10866    (set_attr "length" "4,8")])
10868 (define_insn "*sibcall_nonlocal_sysv<mode>"
10869   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10870          (match_operand 1 "" ""))
10871    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10872    (simple_return)]
10873   "(DEFAULT_ABI == ABI_DARWIN
10874     || DEFAULT_ABI == ABI_V4)
10875    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10877   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10878     output_asm_insn ("crxor 6,6,6", operands);
10880   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10881     output_asm_insn ("creqv 6,6,6", operands);
10883   if (which_alternative >= 2)
10884     {
10885       if (rs6000_speculate_indirect_jumps)
10886         return "b%T0";
10887       else
10888         /* Can use CR0 since it is volatile across sibcalls.  */
10889         return "crset 2\;beq%T0-\;b $";
10890     }
10891   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10892     {
10893       gcc_assert (!TARGET_SECURE_PLT);
10894       return "b %z0@plt";
10895     }
10896   else
10897     return "b %z0";
10899   [(set_attr "type" "branch")
10900    (set (attr "length")
10901         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10902                   (const_string "8")
10903                (and (eq (symbol_ref "which_alternative") (const_int 2))
10904                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10905                         (const_int 0)))
10906                   (const_string "12")
10907                (and (eq (symbol_ref "which_alternative") (const_int 3))
10908                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10909                         (const_int 0)))
10910                   (const_string "8")
10911                (and (eq (symbol_ref "which_alternative") (const_int 3))
10912                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10913                         (const_int 0)))
10914                   (const_string "16")]
10915               (const_string "4")))])
10917 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10918   [(set (match_operand 0 "" "")
10919         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10920               (match_operand 2 "" "")))
10921    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10922    (simple_return)]
10923   "(DEFAULT_ABI == ABI_DARWIN
10924     || DEFAULT_ABI == ABI_V4)
10925    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10927   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10928     output_asm_insn ("crxor 6,6,6", operands);
10930   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10931     output_asm_insn ("creqv 6,6,6", operands);
10933   if (which_alternative >= 2)
10934     {
10935       if (rs6000_speculate_indirect_jumps)
10936         return "b%T1";
10937       else
10938         /* Can use CR0 since it is volatile across sibcalls.  */
10939         return "crset 2\;beq%T1-\;b $";
10940     }
10941   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10942     {
10943       gcc_assert (!TARGET_SECURE_PLT);
10944       return "b %z1@plt";
10945     }
10946   else
10947     return "b %z1";
10949   [(set_attr "type" "branch")
10950    (set (attr "length")
10951         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10952                   (const_string "8")
10953                (and (eq (symbol_ref "which_alternative") (const_int 2))
10954                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10955                         (const_int 0)))
10956                   (const_string "12")
10957                (and (eq (symbol_ref "which_alternative") (const_int 3))
10958                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10959                         (const_int 0)))
10960                   (const_string "8")
10961                (and (eq (symbol_ref "which_alternative") (const_int 3))
10962                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10963                         (const_int 0)))
10964                   (const_string "16")]
10965               (const_string "4")))])
10967 ;; AIX ABI sibling call patterns.
10969 (define_insn "*sibcall_aix<mode>"
10970   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10971          (match_operand 1 "" "g,g"))
10972    (simple_return)]
10973   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10974   "@
10975    b %z0
10976    b%T0"
10977   [(set_attr "type" "branch")
10978    (set_attr "length" "4")])
10980 (define_insn "*sibcall_value_aix<mode>"
10981   [(set (match_operand 0 "" "")
10982         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10983               (match_operand 2 "" "g,g")))
10984    (simple_return)]
10985   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10986   "@
10987    b %z1
10988    b%T1"
10989   [(set_attr "type" "branch")
10990    (set_attr "length" "4")])
10992 (define_expand "sibcall_epilogue"
10993   [(use (const_int 0))]
10994   ""
10996   if (!TARGET_SCHED_PROLOG)
10997     emit_insn (gen_blockage ());
10998   rs6000_emit_epilogue (TRUE);
10999   DONE;
11002 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11003 ;; all of memory.  This blocks insns from being moved across this point.
11005 (define_insn "blockage"
11006   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11007   ""
11008   ""
11009   [(set_attr "length" "0")])
11011 (define_expand "probe_stack_address"
11012   [(use (match_operand 0 "address_operand"))]
11013   ""
11015   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11016   MEM_VOLATILE_P (operands[0]) = 1;
11018   if (TARGET_64BIT)
11019     emit_insn (gen_probe_stack_di (operands[0]));
11020   else
11021     emit_insn (gen_probe_stack_si (operands[0]));
11022   DONE;
11025 (define_insn "probe_stack_<mode>"
11026   [(set (match_operand:P 0 "memory_operand" "=m")
11027         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11028   ""
11030   operands[1] = gen_rtx_REG (Pmode, 0);
11031   return "st<wd>%U0%X0 %1,%0";
11033   [(set_attr "type" "store")
11034    (set (attr "update")
11035         (if_then_else (match_operand 0 "update_address_mem")
11036                       (const_string "yes")
11037                       (const_string "no")))
11038    (set (attr "indexed")
11039         (if_then_else (match_operand 0 "indexed_address_mem")
11040                       (const_string "yes")
11041                       (const_string "no")))
11042    (set_attr "length" "4")])
11044 (define_insn "probe_stack_range<P:mode>"
11045   [(set (match_operand:P 0 "register_operand" "=&r")
11046         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11047                             (match_operand:P 2 "register_operand" "r")
11048                             (match_operand:P 3 "register_operand" "r")]
11049                            UNSPECV_PROBE_STACK_RANGE))]
11050   ""
11051   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11052   [(set_attr "type" "three")])
11054 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11055 ;; signed & unsigned, and one type of branch.
11057 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11058 ;; insns, and branches.
11060 (define_expand "cbranch<mode>4"
11061   [(use (match_operator 0 "comparison_operator"
11062          [(match_operand:GPR 1 "gpc_reg_operand")
11063           (match_operand:GPR 2 "reg_or_short_operand")]))
11064    (use (match_operand 3))]
11065   ""
11067   /* Take care of the possibility that operands[2] might be negative but
11068      this might be a logical operation.  That insn doesn't exist.  */
11069   if (GET_CODE (operands[2]) == CONST_INT
11070       && INTVAL (operands[2]) < 0)
11071     {
11072       operands[2] = force_reg (<MODE>mode, operands[2]);
11073       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11074                                     GET_MODE (operands[0]),
11075                                     operands[1], operands[2]);
11076    }
11078   rs6000_emit_cbranch (<MODE>mode, operands);
11079   DONE;
11082 (define_expand "cbranch<mode>4"
11083   [(use (match_operator 0 "comparison_operator"
11084          [(match_operand:FP 1 "gpc_reg_operand")
11085           (match_operand:FP 2 "gpc_reg_operand")]))
11086    (use (match_operand 3))]
11087   ""
11089   rs6000_emit_cbranch (<MODE>mode, operands);
11090   DONE;
11093 (define_expand "cstore<mode>4_signed"
11094   [(use (match_operator 1 "signed_comparison_operator"
11095          [(match_operand:P 2 "gpc_reg_operand")
11096           (match_operand:P 3 "gpc_reg_operand")]))
11097    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11098   ""
11100   enum rtx_code cond_code = GET_CODE (operands[1]);
11102   rtx op0 = operands[0];
11103   rtx op1 = operands[2];
11104   rtx op2 = operands[3];
11106   if (cond_code == GE || cond_code == LT)
11107     {
11108       cond_code = swap_condition (cond_code);
11109       std::swap (op1, op2);
11110     }
11112   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11113   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11114   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11116   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11117   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11118   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11120   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11122   if (cond_code == LE)
11123     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11124   else
11125     {
11126       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11127       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11128       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11129     }
11131   DONE;
11134 (define_expand "cstore<mode>4_unsigned"
11135   [(use (match_operator 1 "unsigned_comparison_operator"
11136          [(match_operand:P 2 "gpc_reg_operand")
11137           (match_operand:P 3 "reg_or_short_operand")]))
11138    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11139   ""
11141   enum rtx_code cond_code = GET_CODE (operands[1]);
11143   rtx op0 = operands[0];
11144   rtx op1 = operands[2];
11145   rtx op2 = operands[3];
11147   if (cond_code == GEU || cond_code == LTU)
11148     {
11149       cond_code = swap_condition (cond_code);
11150       std::swap (op1, op2);
11151     }
11153   if (!gpc_reg_operand (op1, <MODE>mode))
11154     op1 = force_reg (<MODE>mode, op1);
11155   if (!reg_or_short_operand (op2, <MODE>mode))
11156     op2 = force_reg (<MODE>mode, op2);
11158   rtx tmp = gen_reg_rtx (<MODE>mode);
11159   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11161   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11162   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11164   if (cond_code == LEU)
11165     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11166   else
11167     emit_insn (gen_neg<mode>2 (op0, tmp2));
11169   DONE;
11172 (define_expand "cstore_si_as_di"
11173   [(use (match_operator 1 "unsigned_comparison_operator"
11174          [(match_operand:SI 2 "gpc_reg_operand")
11175           (match_operand:SI 3 "reg_or_short_operand")]))
11176    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11177   ""
11179   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11180   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11182   operands[2] = force_reg (SImode, operands[2]);
11183   operands[3] = force_reg (SImode, operands[3]);
11184   rtx op1 = gen_reg_rtx (DImode);
11185   rtx op2 = gen_reg_rtx (DImode);
11186   convert_move (op1, operands[2], uns_flag);
11187   convert_move (op2, operands[3], uns_flag);
11189   if (cond_code == GT || cond_code == LE)
11190     {
11191       cond_code = swap_condition (cond_code);
11192       std::swap (op1, op2);
11193     }
11195   rtx tmp = gen_reg_rtx (DImode);
11196   rtx tmp2 = gen_reg_rtx (DImode);
11197   emit_insn (gen_subdi3 (tmp, op1, op2));
11198   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11200   rtx tmp3;
11201   switch (cond_code)
11202     {
11203     default:
11204       gcc_unreachable ();
11205     case LT:
11206       tmp3 = tmp2;
11207       break;
11208     case GE:
11209       tmp3 = gen_reg_rtx (DImode);
11210       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11211       break;
11212     }
11214   convert_move (operands[0], tmp3, 1);
11216   DONE;
11219 (define_expand "cstore<mode>4_signed_imm"
11220   [(use (match_operator 1 "signed_comparison_operator"
11221          [(match_operand:GPR 2 "gpc_reg_operand")
11222           (match_operand:GPR 3 "immediate_operand")]))
11223    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11224   ""
11226   bool invert = false;
11228   enum rtx_code cond_code = GET_CODE (operands[1]);
11230   rtx op0 = operands[0];
11231   rtx op1 = operands[2];
11232   HOST_WIDE_INT val = INTVAL (operands[3]);
11234   if (cond_code == GE || cond_code == GT)
11235     {
11236       cond_code = reverse_condition (cond_code);
11237       invert = true;
11238     }
11240   if (cond_code == LE)
11241     val++;
11243   rtx tmp = gen_reg_rtx (<MODE>mode);
11244   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11245   rtx x = gen_reg_rtx (<MODE>mode);
11246   if (val < 0)
11247     emit_insn (gen_and<mode>3 (x, op1, tmp));
11248   else
11249     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11251   if (invert)
11252     {
11253       rtx tmp = gen_reg_rtx (<MODE>mode);
11254       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11255       x = tmp;
11256     }
11258   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11259   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11261   DONE;
11264 (define_expand "cstore<mode>4_unsigned_imm"
11265   [(use (match_operator 1 "unsigned_comparison_operator"
11266          [(match_operand:GPR 2 "gpc_reg_operand")
11267           (match_operand:GPR 3 "immediate_operand")]))
11268    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11269   ""
11271   bool invert = false;
11273   enum rtx_code cond_code = GET_CODE (operands[1]);
11275   rtx op0 = operands[0];
11276   rtx op1 = operands[2];
11277   HOST_WIDE_INT val = INTVAL (operands[3]);
11279   if (cond_code == GEU || cond_code == GTU)
11280     {
11281       cond_code = reverse_condition (cond_code);
11282       invert = true;
11283     }
11285   if (cond_code == LEU)
11286     val++;
11288   rtx tmp = gen_reg_rtx (<MODE>mode);
11289   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11290   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11291   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11292   rtx x = gen_reg_rtx (<MODE>mode);
11293   if (val < 0)
11294     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11295   else
11296     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11298   if (invert)
11299     {
11300       rtx tmp = gen_reg_rtx (<MODE>mode);
11301       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11302       x = tmp;
11303     }
11305   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11306   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11308   DONE;
11311 (define_expand "cstore<mode>4"
11312   [(use (match_operator 1 "comparison_operator"
11313          [(match_operand:GPR 2 "gpc_reg_operand")
11314           (match_operand:GPR 3 "reg_or_short_operand")]))
11315    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11316   ""
11318   /* Expanding EQ and NE directly to some machine instructions does not help
11319      but does hurt combine.  So don't.  */
11320   if (GET_CODE (operands[1]) == EQ)
11321     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11322   else if (<MODE>mode == Pmode
11323            && GET_CODE (operands[1]) == NE)
11324     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11325   else if (GET_CODE (operands[1]) == NE)
11326     {
11327       rtx tmp = gen_reg_rtx (<MODE>mode);
11328       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11329       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11330     }
11332   /* If ISEL is fast, expand to it.  */
11333   else if (TARGET_ISEL)
11334     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11336   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11337      etc. combinations magically work out just right.  */
11338   else if (<MODE>mode == Pmode
11339            && unsigned_comparison_operator (operands[1], VOIDmode))
11340     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11341                                            operands[2], operands[3]));
11343   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11344   else if (<MODE>mode == SImode && Pmode == DImode)
11345     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11346                                     operands[2], operands[3]));
11348   /* For signed comparisons against a constant, we can do some simple
11349      bit-twiddling.  */
11350   else if (signed_comparison_operator (operands[1], VOIDmode)
11351            && CONST_INT_P (operands[3]))
11352     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11353                                              operands[2], operands[3]));
11355   /* And similarly for unsigned comparisons.  */
11356   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11357            && CONST_INT_P (operands[3]))
11358     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11359                                                operands[2], operands[3]));
11361   /* We also do not want to use mfcr for signed comparisons.  */
11362   else if (<MODE>mode == Pmode
11363            && signed_comparison_operator (operands[1], VOIDmode))
11364     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11365                                          operands[2], operands[3]));
11367   /* Everything else, use the mfcr brute force.  */
11368   else
11369     rs6000_emit_sCOND (<MODE>mode, operands);
11371   DONE;
11374 (define_expand "cstore<mode>4"
11375   [(use (match_operator 1 "comparison_operator"
11376          [(match_operand:FP 2 "gpc_reg_operand")
11377           (match_operand:FP 3 "gpc_reg_operand")]))
11378    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11379   ""
11381   rs6000_emit_sCOND (<MODE>mode, operands);
11382   DONE;
11386 (define_expand "stack_protect_set"
11387   [(match_operand 0 "memory_operand")
11388    (match_operand 1 "memory_operand")]
11389   ""
11391   if (rs6000_stack_protector_guard == SSP_TLS)
11392     {
11393       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11394       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11395       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11396       operands[1] = gen_rtx_MEM (Pmode, addr);
11397     }
11399   if (TARGET_64BIT)
11400     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11401   else
11402     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11404   DONE;
11407 (define_insn "stack_protect_setsi"
11408   [(set (match_operand:SI 0 "memory_operand" "=m")
11409         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11410    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11411   "TARGET_32BIT"
11412   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11413   [(set_attr "type" "three")
11414    (set_attr "length" "12")])
11416 (define_insn "stack_protect_setdi"
11417   [(set (match_operand:DI 0 "memory_operand" "=Y")
11418         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11419    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11420   "TARGET_64BIT"
11421   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11422   [(set_attr "type" "three")
11423    (set_attr "length" "12")])
11425 (define_expand "stack_protect_test"
11426   [(match_operand 0 "memory_operand")
11427    (match_operand 1 "memory_operand")
11428    (match_operand 2 "")]
11429   ""
11431   rtx guard = operands[1];
11433   if (rs6000_stack_protector_guard == SSP_TLS)
11434     {
11435       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11436       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11437       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11438       guard = gen_rtx_MEM (Pmode, addr);
11439     }
11441   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11442   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11443   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11444   emit_jump_insn (jump);
11446   DONE;
11449 (define_insn "stack_protect_testsi"
11450   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11451         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11452                       (match_operand:SI 2 "memory_operand" "m,m")]
11453                      UNSPEC_SP_TEST))
11454    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11455    (clobber (match_scratch:SI 3 "=&r,&r"))]
11456   "TARGET_32BIT"
11457   "@
11458    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11459    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11460   [(set_attr "length" "16,20")])
11462 (define_insn "stack_protect_testdi"
11463   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11464         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11465                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11466                      UNSPEC_SP_TEST))
11467    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11468    (clobber (match_scratch:DI 3 "=&r,&r"))]
11469   "TARGET_64BIT"
11470   "@
11471    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11472    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11473   [(set_attr "length" "16,20")])
11476 ;; Here are the actual compare insns.
11477 (define_insn "*cmp<mode>_signed"
11478   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11479         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11480                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11481   ""
11482   "cmp<wd>%I2 %0,%1,%2"
11483   [(set_attr "type" "cmp")])
11485 (define_insn "*cmp<mode>_unsigned"
11486   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11487         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11488                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11489   ""
11490   "cmpl<wd>%I2 %0,%1,%2"
11491   [(set_attr "type" "cmp")])
11493 ;; If we are comparing a register for equality with a large constant,
11494 ;; we can do this with an XOR followed by a compare.  But this is profitable
11495 ;; only if the large constant is only used for the comparison (and in this
11496 ;; case we already have a register to reuse as scratch).
11498 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11499 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11501 (define_peephole2
11502   [(set (match_operand:SI 0 "register_operand")
11503         (match_operand:SI 1 "logical_const_operand"))
11504    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11505                        [(match_dup 0)
11506                         (match_operand:SI 2 "logical_const_operand")]))
11507    (set (match_operand:CC 4 "cc_reg_operand")
11508         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11509                     (match_dup 0)))
11510    (set (pc)
11511         (if_then_else (match_operator 6 "equality_operator"
11512                        [(match_dup 4) (const_int 0)])
11513                       (match_operand 7 "")
11514                       (match_operand 8 "")))]
11515   "peep2_reg_dead_p (3, operands[0])
11516    && peep2_reg_dead_p (4, operands[4])
11517    && REGNO (operands[0]) != REGNO (operands[5])"
11518  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11519   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11520   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11523   /* Get the constant we are comparing against, and see what it looks like
11524      when sign-extended from 16 to 32 bits.  Then see what constant we could
11525      XOR with SEXTC to get the sign-extended value.  */
11526   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11527                                               SImode,
11528                                               operands[1], operands[2]);
11529   HOST_WIDE_INT c = INTVAL (cnst);
11530   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11531   HOST_WIDE_INT xorv = c ^ sextc;
11533   operands[9] = GEN_INT (xorv);
11534   operands[10] = GEN_INT (sextc);
11537 ;; The following two insns don't exist as single insns, but if we provide
11538 ;; them, we can swap an add and compare, which will enable us to overlap more
11539 ;; of the required delay between a compare and branch.  We generate code for
11540 ;; them by splitting.
11542 (define_insn ""
11543   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11544         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11545                     (match_operand:SI 2 "short_cint_operand" "i")))
11546    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11547         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11548   ""
11549   "#"
11550   [(set_attr "length" "8")])
11552 (define_insn ""
11553   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11554         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11555                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11556    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11557         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11558   ""
11559   "#"
11560   [(set_attr "length" "8")])
11562 (define_split
11563   [(set (match_operand:CC 3 "cc_reg_operand")
11564         (compare:CC (match_operand:SI 1 "gpc_reg_operand")
11565                     (match_operand:SI 2 "short_cint_operand")))
11566    (set (match_operand:SI 0 "gpc_reg_operand")
11567         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11568   ""
11569   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11570    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11572 (define_split
11573   [(set (match_operand:CCUNS 3 "cc_reg_operand")
11574         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11575                        (match_operand:SI 2 "u_short_cint_operand")))
11576    (set (match_operand:SI 0 "gpc_reg_operand")
11577         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11578   ""
11579   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11580    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11582 ;; Only need to compare second words if first words equal
11583 (define_insn "*cmp<mode>_internal1"
11584   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11585         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11586                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11587   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11588    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11589   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11590   [(set_attr "type" "fpcompare")
11591    (set_attr "length" "12")])
11593 (define_insn_and_split "*cmp<mode>_internal2"
11594   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11595         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11596                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11597     (clobber (match_scratch:DF 3 "=d"))
11598     (clobber (match_scratch:DF 4 "=d"))
11599     (clobber (match_scratch:DF 5 "=d"))
11600     (clobber (match_scratch:DF 6 "=d"))
11601     (clobber (match_scratch:DF 7 "=d"))
11602     (clobber (match_scratch:DF 8 "=d"))
11603     (clobber (match_scratch:DF 9 "=d"))
11604     (clobber (match_scratch:DF 10 "=d"))
11605     (clobber (match_scratch:GPR 11 "=b"))]
11606   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11607    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11608   "#"
11609   "&& reload_completed"
11610   [(set (match_dup 3) (match_dup 14))
11611    (set (match_dup 4) (match_dup 15))
11612    (set (match_dup 9) (abs:DF (match_dup 5)))
11613    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11614    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11615                            (label_ref (match_dup 12))
11616                            (pc)))
11617    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11618    (set (pc) (label_ref (match_dup 13)))
11619    (match_dup 12)
11620    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11621    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11622    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11623    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11624    (match_dup 13)]
11626   REAL_VALUE_TYPE rv;
11627   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11628   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11630   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11631   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11632   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11633   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11634   operands[12] = gen_label_rtx ();
11635   operands[13] = gen_label_rtx ();
11636   real_inf (&rv);
11637   operands[14] = force_const_mem (DFmode,
11638                                   const_double_from_real_value (rv, DFmode));
11639   operands[15] = force_const_mem (DFmode,
11640                                   const_double_from_real_value (dconst0,
11641                                                                 DFmode));
11642   if (TARGET_TOC)
11643     {
11644       rtx tocref;
11645       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11646       operands[14] = gen_const_mem (DFmode, tocref);
11647       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11648       operands[15] = gen_const_mem (DFmode, tocref);
11649       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11650       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11651     }
11654 ;; Now we have the scc insns.  We can do some combinations because of the
11655 ;; way the machine works.
11657 ;; Note that this is probably faster if we can put an insn between the
11658 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11659 ;; cases the insns below which don't use an intermediate CR field will
11660 ;; be used instead.
11661 (define_insn ""
11662   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11663         (match_operator:SI 1 "scc_comparison_operator"
11664                            [(match_operand 2 "cc_reg_operand" "y")
11665                             (const_int 0)]))]
11666   ""
11667   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11668   [(set (attr "type")
11669      (cond [(match_test "TARGET_MFCRF")
11670                 (const_string "mfcrf")
11671            ]
11672         (const_string "mfcr")))
11673    (set_attr "length" "8")])
11675 ;; Same as above, but get the OV/ORDERED bit.
11676 (define_insn "move_from_CR_ov_bit"
11677   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11678         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11679                    UNSPEC_MV_CR_OV))]
11680   "TARGET_PAIRED_FLOAT"
11681   "mfcr %0\;rlwinm %0,%0,%t1,1"
11682   [(set_attr "type" "mfcr")
11683    (set_attr "length" "8")])
11685 (define_insn ""
11686   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11687         (match_operator:DI 1 "scc_comparison_operator"
11688                            [(match_operand 2 "cc_reg_operand" "y")
11689                             (const_int 0)]))]
11690   "TARGET_POWERPC64"
11691   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11692   [(set (attr "type")
11693      (cond [(match_test "TARGET_MFCRF")
11694                 (const_string "mfcrf")
11695            ]
11696         (const_string "mfcr")))
11697    (set_attr "length" "8")])
11699 (define_insn ""
11700   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11701         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11702                                        [(match_operand 2 "cc_reg_operand" "y,y")
11703                                         (const_int 0)])
11704                     (const_int 0)))
11705    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11706         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11707   "TARGET_32BIT"
11708   "@
11709    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11710    #"
11711   [(set_attr "type" "shift")
11712    (set_attr "dot" "yes")
11713    (set_attr "length" "8,16")])
11715 (define_split
11716   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11717         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11718                                        [(match_operand 2 "cc_reg_operand")
11719                                         (const_int 0)])
11720                     (const_int 0)))
11721    (set (match_operand:SI 3 "gpc_reg_operand")
11722         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11723   "TARGET_32BIT && reload_completed"
11724   [(set (match_dup 3)
11725         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11726    (set (match_dup 0)
11727         (compare:CC (match_dup 3)
11728                     (const_int 0)))]
11729   "")
11731 (define_insn ""
11732   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11733         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11734                                       [(match_operand 2 "cc_reg_operand" "y")
11735                                        (const_int 0)])
11736                    (match_operand:SI 3 "const_int_operand" "n")))]
11737   ""
11739   int is_bit = ccr_bit (operands[1], 1);
11740   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11741   int count;
11743   if (is_bit >= put_bit)
11744     count = is_bit - put_bit;
11745   else
11746     count = 32 - (put_bit - is_bit);
11748   operands[4] = GEN_INT (count);
11749   operands[5] = GEN_INT (put_bit);
11751   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11753   [(set (attr "type")
11754      (cond [(match_test "TARGET_MFCRF")
11755                 (const_string "mfcrf")
11756            ]
11757         (const_string "mfcr")))
11758    (set_attr "length" "8")])
11760 (define_insn ""
11761   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11762         (compare:CC
11763          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11764                                        [(match_operand 2 "cc_reg_operand" "y,y")
11765                                         (const_int 0)])
11766                     (match_operand:SI 3 "const_int_operand" "n,n"))
11767          (const_int 0)))
11768    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11769         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11770                    (match_dup 3)))]
11771   ""
11773   int is_bit = ccr_bit (operands[1], 1);
11774   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11775   int count;
11777   /* Force split for non-cc0 compare.  */
11778   if (which_alternative == 1)
11779      return "#";
11781   if (is_bit >= put_bit)
11782     count = is_bit - put_bit;
11783   else
11784     count = 32 - (put_bit - is_bit);
11786   operands[5] = GEN_INT (count);
11787   operands[6] = GEN_INT (put_bit);
11789   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11791   [(set_attr "type" "shift")
11792    (set_attr "dot" "yes")
11793    (set_attr "length" "8,16")])
11795 (define_split
11796   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11797         (compare:CC
11798          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11799                                        [(match_operand 2 "cc_reg_operand")
11800                                         (const_int 0)])
11801                     (match_operand:SI 3 "const_int_operand"))
11802          (const_int 0)))
11803    (set (match_operand:SI 4 "gpc_reg_operand")
11804         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11805                    (match_dup 3)))]
11806   "reload_completed"
11807   [(set (match_dup 4)
11808         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11809                    (match_dup 3)))
11810    (set (match_dup 0)
11811         (compare:CC (match_dup 4)
11812                     (const_int 0)))]
11813   "")
11816 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11817 (define_code_attr UNS [(eq "CC")
11818                        (ne "CC")
11819                        (lt "CC") (ltu "CCUNS")
11820                        (gt "CC") (gtu "CCUNS")
11821                        (le "CC") (leu "CCUNS")
11822                        (ge "CC") (geu "CCUNS")])
11823 (define_code_attr UNSu_ [(eq "")
11824                          (ne "")
11825                          (lt "") (ltu "u_")
11826                          (gt "") (gtu "u_")
11827                          (le "") (leu "u_")
11828                          (ge "") (geu "u_")])
11829 (define_code_attr UNSIK [(eq "I")
11830                          (ne "I")
11831                          (lt "I") (ltu "K")
11832                          (gt "I") (gtu "K")
11833                          (le "I") (leu "K")
11834                          (ge "I") (geu "K")])
11836 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11837   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11838         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11839                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11840    (clobber (match_scratch:GPR 3 "=r"))
11841    (clobber (match_scratch:GPR 4 "=r"))
11842    (clobber (match_scratch:<UNS> 5 "=y"))]
11843   "TARGET_ISEL
11844    && !(<CODE> == EQ && operands[2] == const0_rtx)
11845    && !(<CODE> == NE && operands[2] == const0_rtx
11846         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11847   "#"
11848   "&& 1"
11849   [(pc)]
11851   rtx_code code = <CODE>;
11852   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11853     {
11854       HOST_WIDE_INT val = INTVAL (operands[2]);
11855       if (code == LT && val != -0x8000)
11856         {
11857           code = LE;
11858           val--;
11859         }
11860       if (code == GT && val != 0x7fff)
11861         {
11862           code = GE;
11863           val++;
11864         }
11865       if (code == LTU && val != 0)
11866         {
11867           code = LEU;
11868           val--;
11869         }
11870       if (code == GTU && val != 0xffff)
11871         {
11872           code = GEU;
11873           val++;
11874         }
11875       operands[2] = GEN_INT (val);
11876     }
11878   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11879     operands[3] = const0_rtx;
11880   else
11881     {
11882       if (GET_CODE (operands[3]) == SCRATCH)
11883         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11884       emit_move_insn (operands[3], const0_rtx);
11885     }
11887   if (GET_CODE (operands[4]) == SCRATCH)
11888     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11889   emit_move_insn (operands[4], const1_rtx);
11891   if (GET_CODE (operands[5]) == SCRATCH)
11892     operands[5] = gen_reg_rtx (<UNS>mode);
11894   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11895   emit_insn (gen_rtx_SET (operands[5], c1));
11897   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11898   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11899   emit_move_insn (operands[0], x);
11901   DONE;
11903   [(set (attr "cost")
11904         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11905                                    || <CODE> == NE
11906                                    || <CODE> == LE || <CODE> == GE
11907                                    || <CODE> == LEU || <CODE> == GEU")
11908                       (const_string "9")
11909                       (const_string "10")))])
11911 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11912                               (DI "rKJI")])
11914 (define_expand "eq<mode>3"
11915   [(parallel [
11916      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11917           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11918                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11919      (clobber (match_scratch:GPR 3 "=r"))
11920      (clobber (match_scratch:GPR 4 "=r"))])]
11921   ""
11923   if (TARGET_ISEL && operands[2] != const0_rtx)
11924     {
11925       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11926                                            operands[2]));
11927       DONE;
11928     }
11931 (define_insn_and_split "*eq<mode>3"
11932   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11933         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11934                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11935    (clobber (match_scratch:GPR 3 "=r"))
11936    (clobber (match_scratch:GPR 4 "=r"))]
11937   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11938   "#"
11939   "&& 1"
11940   [(set (match_dup 4)
11941         (clz:GPR (match_dup 3)))
11942    (set (match_dup 0)
11943         (lshiftrt:GPR (match_dup 4)
11944                       (match_dup 5)))]
11946   operands[3] = rs6000_emit_eqne (<MODE>mode,
11947                                   operands[1], operands[2], operands[3]);
11949   if (GET_CODE (operands[4]) == SCRATCH)
11950     operands[4] = gen_reg_rtx (<MODE>mode);
11952   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11954   [(set (attr "length")
11955         (if_then_else (match_test "operands[2] == const0_rtx")
11956                       (const_string "8")
11957                       (const_string "12")))])
11959 (define_expand "ne<mode>3"
11960   [(parallel [
11961      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11962           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11963                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11964      (clobber (match_scratch:P 3 "=r"))
11965      (clobber (match_scratch:P 4 "=r"))
11966      (clobber (reg:P CA_REGNO))])]
11967   ""
11969   if (TARGET_ISEL && operands[2] != const0_rtx)
11970     {
11971       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11972                                            operands[2]));
11973       DONE;
11974     }
11977 (define_insn_and_split "*ne<mode>3"
11978   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11979         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11980               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11981    (clobber (match_scratch:P 3 "=r"))
11982    (clobber (match_scratch:P 4 "=r"))
11983    (clobber (reg:P CA_REGNO))]
11984   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11985   "#"
11986   "&& 1"
11987   [(parallel [(set (match_dup 4)
11988                    (plus:P (match_dup 3)
11989                            (const_int -1)))
11990               (set (reg:P CA_REGNO)
11991                    (ne:P (match_dup 3)
11992                          (const_int 0)))])
11993    (parallel [(set (match_dup 0)
11994                    (plus:P (plus:P (not:P (match_dup 4))
11995                                    (reg:P CA_REGNO))
11996                            (match_dup 3)))
11997               (clobber (reg:P CA_REGNO))])]
11999   operands[3] = rs6000_emit_eqne (<MODE>mode,
12000                                   operands[1], operands[2], operands[3]);
12002   if (GET_CODE (operands[4]) == SCRATCH)
12003     operands[4] = gen_reg_rtx (<MODE>mode);
12005   [(set (attr "length")
12006         (if_then_else (match_test "operands[2] == const0_rtx")
12007                       (const_string "8")
12008                       (const_string "12")))])
12010 (define_insn_and_split "*neg_eq_<mode>"
12011   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12012         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12013                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12014    (clobber (match_scratch:P 3 "=r"))
12015    (clobber (match_scratch:P 4 "=r"))
12016    (clobber (reg:P CA_REGNO))]
12017   ""
12018   "#"
12019   ""
12020   [(parallel [(set (match_dup 4)
12021                    (plus:P (match_dup 3)
12022                            (const_int -1)))
12023               (set (reg:P CA_REGNO)
12024                    (ne:P (match_dup 3)
12025                          (const_int 0)))])
12026    (parallel [(set (match_dup 0)
12027                    (plus:P (reg:P CA_REGNO)
12028                            (const_int -1)))
12029               (clobber (reg:P CA_REGNO))])]
12031   operands[3] = rs6000_emit_eqne (<MODE>mode,
12032                                   operands[1], operands[2], operands[3]);
12034   if (GET_CODE (operands[4]) == SCRATCH)
12035     operands[4] = gen_reg_rtx (<MODE>mode);
12037   [(set (attr "length")
12038         (if_then_else (match_test "operands[2] == const0_rtx")
12039                       (const_string "8")
12040                       (const_string "12")))])
12042 (define_insn_and_split "*neg_ne_<mode>"
12043   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12044         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12045                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12046    (clobber (match_scratch:P 3 "=r"))
12047    (clobber (match_scratch:P 4 "=r"))
12048    (clobber (reg:P CA_REGNO))]
12049   ""
12050   "#"
12051   ""
12052   [(parallel [(set (match_dup 4)
12053                    (neg:P (match_dup 3)))
12054               (set (reg:P CA_REGNO)
12055                    (eq:P (match_dup 3)
12056                          (const_int 0)))])
12057    (parallel [(set (match_dup 0)
12058                    (plus:P (reg:P CA_REGNO)
12059                            (const_int -1)))
12060               (clobber (reg:P CA_REGNO))])]
12062   operands[3] = rs6000_emit_eqne (<MODE>mode,
12063                                   operands[1], operands[2], operands[3]);
12065   if (GET_CODE (operands[4]) == SCRATCH)
12066     operands[4] = gen_reg_rtx (<MODE>mode);
12068   [(set (attr "length")
12069         (if_then_else (match_test "operands[2] == const0_rtx")
12070                       (const_string "8")
12071                       (const_string "12")))])
12073 (define_insn_and_split "*plus_eq_<mode>"
12074   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12075         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12076                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12077                 (match_operand:P 3 "gpc_reg_operand" "r")))
12078    (clobber (match_scratch:P 4 "=r"))
12079    (clobber (match_scratch:P 5 "=r"))
12080    (clobber (reg:P CA_REGNO))]
12081   ""
12082   "#"
12083   ""
12084   [(parallel [(set (match_dup 5)
12085                    (neg:P (match_dup 4)))
12086               (set (reg:P CA_REGNO)
12087                    (eq:P (match_dup 4)
12088                          (const_int 0)))])
12089    (parallel [(set (match_dup 0)
12090                    (plus:P (match_dup 3)
12091                            (reg:P CA_REGNO)))
12092               (clobber (reg:P CA_REGNO))])]
12094   operands[4] = rs6000_emit_eqne (<MODE>mode,
12095                                   operands[1], operands[2], operands[4]);
12097   if (GET_CODE (operands[5]) == SCRATCH)
12098     operands[5] = gen_reg_rtx (<MODE>mode);
12100   [(set (attr "length")
12101         (if_then_else (match_test "operands[2] == const0_rtx")
12102                       (const_string "8")
12103                       (const_string "12")))])
12105 (define_insn_and_split "*plus_ne_<mode>"
12106   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12107         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12108                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12109                 (match_operand:P 3 "gpc_reg_operand" "r")))
12110    (clobber (match_scratch:P 4 "=r"))
12111    (clobber (match_scratch:P 5 "=r"))
12112    (clobber (reg:P CA_REGNO))]
12113   ""
12114   "#"
12115   ""
12116   [(parallel [(set (match_dup 5)
12117                    (plus:P (match_dup 4)
12118                            (const_int -1)))
12119               (set (reg:P CA_REGNO)
12120                    (ne:P (match_dup 4)
12121                          (const_int 0)))])
12122    (parallel [(set (match_dup 0)
12123                    (plus:P (match_dup 3)
12124                            (reg:P CA_REGNO)))
12125               (clobber (reg:P CA_REGNO))])]
12127   operands[4] = rs6000_emit_eqne (<MODE>mode,
12128                                   operands[1], operands[2], operands[4]);
12130   if (GET_CODE (operands[5]) == SCRATCH)
12131     operands[5] = gen_reg_rtx (<MODE>mode);
12133   [(set (attr "length")
12134         (if_then_else (match_test "operands[2] == const0_rtx")
12135                       (const_string "8")
12136                       (const_string "12")))])
12138 (define_insn_and_split "*minus_eq_<mode>"
12139   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12140         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12141                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12142                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12143    (clobber (match_scratch:P 4 "=r"))
12144    (clobber (match_scratch:P 5 "=r"))
12145    (clobber (reg:P CA_REGNO))]
12146   ""
12147   "#"
12148   ""
12149   [(parallel [(set (match_dup 5)
12150                    (plus:P (match_dup 4)
12151                            (const_int -1)))
12152               (set (reg:P CA_REGNO)
12153                    (ne:P (match_dup 4)
12154                          (const_int 0)))])
12155    (parallel [(set (match_dup 0)
12156                    (plus:P (plus:P (match_dup 3)
12157                                    (reg:P CA_REGNO))
12158                            (const_int -1)))
12159               (clobber (reg:P CA_REGNO))])]
12161   operands[4] = rs6000_emit_eqne (<MODE>mode,
12162                                   operands[1], operands[2], operands[4]);
12164   if (GET_CODE (operands[5]) == SCRATCH)
12165     operands[5] = gen_reg_rtx (<MODE>mode);
12167   [(set (attr "length")
12168         (if_then_else (match_test "operands[2] == const0_rtx")
12169                       (const_string "8")
12170                       (const_string "12")))])
12172 (define_insn_and_split "*minus_ne_<mode>"
12173   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12174         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12175                  (ne: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                    (neg:P (match_dup 4)))
12185               (set (reg:P CA_REGNO)
12186                    (eq:P (match_dup 4)
12187                          (const_int 0)))])
12188    (parallel [(set (match_dup 0)
12189                    (plus:P (plus:P (match_dup 3)
12190                                    (reg:P CA_REGNO))
12191                            (const_int -1)))
12192               (clobber (reg:P CA_REGNO))])]
12194   operands[4] = rs6000_emit_eqne (<MODE>mode,
12195                                   operands[1], operands[2], operands[4]);
12197   if (GET_CODE (operands[5]) == SCRATCH)
12198     operands[5] = gen_reg_rtx (<MODE>mode);
12200   [(set (attr "length")
12201         (if_then_else (match_test "operands[2] == const0_rtx")
12202                       (const_string "8")
12203                       (const_string "12")))])
12205 (define_insn_and_split "*eqsi3_ext<mode>"
12206   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12207         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12208                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12209    (clobber (match_scratch:SI 3 "=r"))
12210    (clobber (match_scratch:SI 4 "=r"))]
12211   ""
12212   "#"
12213   ""
12214   [(set (match_dup 4)
12215         (clz:SI (match_dup 3)))
12216    (set (match_dup 0)
12217         (zero_extend:EXTSI
12218           (lshiftrt:SI (match_dup 4)
12219                        (const_int 5))))]
12221   operands[3] = rs6000_emit_eqne (SImode,
12222                                   operands[1], operands[2], operands[3]);
12224   if (GET_CODE (operands[4]) == SCRATCH)
12225     operands[4] = gen_reg_rtx (SImode);
12227   [(set (attr "length")
12228         (if_then_else (match_test "operands[2] == const0_rtx")
12229                       (const_string "8")
12230                       (const_string "12")))])
12232 (define_insn_and_split "*nesi3_ext<mode>"
12233   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12234         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12235                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12236    (clobber (match_scratch:SI 3 "=r"))
12237    (clobber (match_scratch:SI 4 "=r"))
12238    (clobber (match_scratch:EXTSI 5 "=r"))]
12239   "!TARGET_ISEL"
12240   "#"
12241   "&& 1"
12242   [(set (match_dup 4)
12243         (clz:SI (match_dup 3)))
12244    (set (match_dup 5)
12245         (zero_extend:EXTSI
12246           (lshiftrt:SI (match_dup 4)
12247                        (const_int 5))))
12248    (set (match_dup 0)
12249         (xor:EXTSI (match_dup 5)
12250                    (const_int 1)))]
12252   operands[3] = rs6000_emit_eqne (SImode,
12253                                   operands[1], operands[2], operands[3]);
12255   if (GET_CODE (operands[4]) == SCRATCH)
12256     operands[4] = gen_reg_rtx (SImode);
12257   if (GET_CODE (operands[5]) == SCRATCH)
12258     operands[5] = gen_reg_rtx (<MODE>mode);
12260   [(set (attr "length")
12261         (if_then_else (match_test "operands[2] == const0_rtx")
12262                       (const_string "12")
12263                       (const_string "16")))])
12265 ;; Define both directions of branch and return.  If we need a reload
12266 ;; register, we'd rather use CR0 since it is much easier to copy a
12267 ;; register CC value to there.
12269 (define_insn ""
12270   [(set (pc)
12271         (if_then_else (match_operator 1 "branch_comparison_operator"
12272                                       [(match_operand 2 "cc_reg_operand" "y")
12273                                        (const_int 0)])
12274                       (label_ref (match_operand 0))
12275                       (pc)))]
12276   ""
12278   return output_cbranch (operands[1], "%l0", 0, insn);
12280   [(set_attr "type" "branch")])
12282 (define_insn ""
12283   [(set (pc)
12284         (if_then_else (match_operator 0 "branch_comparison_operator"
12285                                       [(match_operand 1 "cc_reg_operand" "y")
12286                                        (const_int 0)])
12287                       (any_return)
12288                       (pc)))]
12289   "<return_pred>"
12291   return output_cbranch (operands[0], NULL, 0, insn);
12293   [(set_attr "type" "jmpreg")
12294    (set_attr "length" "4")])
12296 ;; Logic on condition register values.
12298 ; This pattern matches things like
12299 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12300 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12301 ;                                  (const_int 1)))
12302 ; which are generated by the branch logic.
12303 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12305 (define_insn "cceq_ior_compare"
12306   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12307         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12308                         [(match_operator:SI 2
12309                                       "branch_positive_comparison_operator"
12310                                       [(match_operand 3
12311                                                       "cc_reg_operand" "y,y")
12312                                        (const_int 0)])
12313                          (match_operator:SI 4
12314                                       "branch_positive_comparison_operator"
12315                                       [(match_operand 5
12316                                                       "cc_reg_operand" "0,y")
12317                                        (const_int 0)])])
12318                       (const_int 1)))]
12319   ""
12320   "cr%q1 %E0,%j2,%j4"
12321   [(set_attr "type" "cr_logical")
12322    (set_attr "cr_logical_3op" "no,yes")])
12324 ; Why is the constant -1 here, but 1 in the previous pattern?
12325 ; Because ~1 has all but the low bit set.
12326 (define_insn "cceq_ior_compare_complement"
12327   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12328         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12329                         [(not:SI (match_operator:SI 2
12330                                       "branch_positive_comparison_operator"
12331                                       [(match_operand 3
12332                                                       "cc_reg_operand" "y,y")
12333                                        (const_int 0)]))
12334                          (match_operator:SI 4
12335                                 "branch_positive_comparison_operator"
12336                                 [(match_operand 5
12337                                                 "cc_reg_operand" "0,y")
12338                                  (const_int 0)])])
12339                       (const_int -1)))]
12340   ""
12341   "cr%q1 %E0,%j2,%j4"
12342   [(set_attr "type" "cr_logical")
12343    (set_attr "cr_logical_3op" "no,yes")])
12345 (define_insn "*cceq_rev_compare"
12346   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12347         (compare:CCEQ (match_operator:SI 1
12348                                       "branch_positive_comparison_operator"
12349                                       [(match_operand 2
12350                                                       "cc_reg_operand" "0,y")
12351                                        (const_int 0)])
12352                       (const_int 0)))]
12353   ""
12354   "crnot %E0,%j1"
12355   [(set_attr "type" "cr_logical")
12356    (set_attr "cr_logical_3op" "no,yes")])
12358 ;; If we are comparing the result of two comparisons, this can be done
12359 ;; using creqv or crxor.
12361 (define_insn_and_split ""
12362   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12363         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12364                               [(match_operand 2 "cc_reg_operand" "y")
12365                                (const_int 0)])
12366                       (match_operator 3 "branch_comparison_operator"
12367                               [(match_operand 4 "cc_reg_operand" "y")
12368                                (const_int 0)])))]
12369   ""
12370   "#"
12371   ""
12372   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12373                                     (match_dup 5)))]
12375   int positive_1, positive_2;
12377   positive_1 = branch_positive_comparison_operator (operands[1],
12378                                                     GET_MODE (operands[1]));
12379   positive_2 = branch_positive_comparison_operator (operands[3],
12380                                                     GET_MODE (operands[3]));
12382   if (! positive_1)
12383     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12384                                                             GET_CODE (operands[1])),
12385                                   SImode,
12386                                   operands[2], const0_rtx);
12387   else if (GET_MODE (operands[1]) != SImode)
12388     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12389                                   operands[2], const0_rtx);
12391   if (! positive_2)
12392     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12393                                                             GET_CODE (operands[3])),
12394                                   SImode,
12395                                   operands[4], const0_rtx);
12396   else if (GET_MODE (operands[3]) != SImode)
12397     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12398                                   operands[4], const0_rtx);
12400   if (positive_1 == positive_2)
12401     {
12402       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12403       operands[5] = constm1_rtx;
12404     }
12405   else
12406     {
12407       operands[5] = const1_rtx;
12408     }
12411 ;; Unconditional branch and return.
12413 (define_insn "jump"
12414   [(set (pc)
12415         (label_ref (match_operand 0)))]
12416   ""
12417   "b %l0"
12418   [(set_attr "type" "branch")])
12420 (define_insn "<return_str>return"
12421   [(any_return)]
12422   "<return_pred>"
12423   "blr"
12424   [(set_attr "type" "jmpreg")])
12426 (define_expand "indirect_jump"
12427   [(set (pc) (match_operand 0 "register_operand"))]
12428  ""
12430   if (!rs6000_speculate_indirect_jumps) {
12431     rtx ccreg = gen_reg_rtx (CCmode);
12432     if (Pmode == DImode)
12433       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12434     else
12435       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12436     DONE;
12437   }
12440 (define_insn "*indirect_jump<mode>"
12441   [(set (pc)
12442         (match_operand:P 0 "register_operand" "c,*l"))]
12443   "rs6000_speculate_indirect_jumps"
12444   "b%T0"
12445   [(set_attr "type" "jmpreg")])
12447 (define_insn "indirect_jump<mode>_nospec"
12448   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12449    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12450   "!rs6000_speculate_indirect_jumps"
12451   "crset %E1\;beq%T0- %1\;b $"
12452   [(set_attr "type" "jmpreg")
12453    (set_attr "length" "12")])
12455 ;; Table jump for switch statements:
12456 (define_expand "tablejump"
12457   [(use (match_operand 0))
12458    (use (label_ref (match_operand 1)))]
12459   ""
12461   if (rs6000_speculate_indirect_jumps)
12462     {
12463       if (TARGET_32BIT)
12464         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12465       else
12466         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12467     }
12468   else
12469     {
12470       rtx ccreg = gen_reg_rtx (CCmode);
12471       rtx jump;
12472       if (TARGET_32BIT)
12473         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12474       else
12475         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12476       emit_jump_insn (jump);
12477     }
12478   DONE;
12481 (define_expand "tablejumpsi"
12482   [(set (match_dup 3)
12483         (plus:SI (match_operand:SI 0)
12484                  (match_dup 2)))
12485    (parallel [(set (pc)
12486                    (match_dup 3))
12487               (use (label_ref (match_operand 1)))])]
12488   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12490   operands[0] = force_reg (SImode, operands[0]);
12491   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12492   operands[3] = gen_reg_rtx (SImode);
12495 (define_expand "tablejumpsi_nospec"
12496   [(set (match_dup 4)
12497         (plus:SI (match_operand:SI 0)
12498                  (match_dup 3)))
12499    (parallel [(set (pc)
12500                    (match_dup 4))
12501               (use (label_ref (match_operand 1)))
12502               (clobber (match_operand 2))])]
12503   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12505   operands[0] = force_reg (SImode, operands[0]);
12506   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12507   operands[4] = gen_reg_rtx (SImode);
12510 (define_expand "tablejumpdi"
12511   [(set (match_dup 4)
12512         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12513    (set (match_dup 3)
12514         (plus:DI (match_dup 4)
12515                  (match_dup 2)))
12516    (parallel [(set (pc)
12517                    (match_dup 3))
12518               (use (label_ref (match_operand 1)))])]
12519   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12521   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12522   operands[3] = gen_reg_rtx (DImode);
12523   operands[4] = gen_reg_rtx (DImode);
12526 (define_expand "tablejumpdi_nospec"
12527   [(set (match_dup 5)
12528         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12529    (set (match_dup 4)
12530         (plus:DI (match_dup 5)
12531                  (match_dup 3)))
12532    (parallel [(set (pc)
12533                    (match_dup 4))
12534               (use (label_ref (match_operand 1)))
12535               (clobber (match_operand 2))])]
12536   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12538   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12539   operands[4] = gen_reg_rtx (DImode);
12540   operands[5] = gen_reg_rtx (DImode);
12543 (define_insn "*tablejump<mode>_internal1"
12544   [(set (pc)
12545         (match_operand:P 0 "register_operand" "c,*l"))
12546    (use (label_ref (match_operand 1)))]
12547   "rs6000_speculate_indirect_jumps"
12548   "b%T0"
12549   [(set_attr "type" "jmpreg")])
12551 (define_insn "*tablejump<mode>_internal1_nospec"
12552   [(set (pc)
12553         (match_operand:P 0 "register_operand" "c,*l"))
12554    (use (label_ref (match_operand 1)))
12555    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12556   "!rs6000_speculate_indirect_jumps"
12557   "crset %E2\;beq%T0- %2\;b $"
12558   [(set_attr "type" "jmpreg")
12559    (set_attr "length" "12")])
12561 (define_insn "nop"
12562   [(unspec [(const_int 0)] UNSPEC_NOP)]
12563   ""
12564   "nop")
12566 (define_insn "group_ending_nop"
12567   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12568   ""
12570   if (rs6000_tune == PROCESSOR_POWER6)
12571     return "ori 1,1,0";
12572   return "ori 2,2,0";
12575 (define_insn "rs6000_speculation_barrier"
12576   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12577   ""
12578   "ori 31,31,0")
12580 ;; Define the subtract-one-and-jump insns, starting with the template
12581 ;; so loop.c knows what to generate.
12583 (define_expand "doloop_end"
12584   [(use (match_operand 0))      ; loop pseudo
12585    (use (match_operand 1))]     ; label
12586   ""
12588   if (TARGET_64BIT)
12589     {
12590       if (GET_MODE (operands[0]) != DImode)
12591         FAIL;
12592       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12593     }
12594   else
12595     {
12596       if (GET_MODE (operands[0]) != SImode)
12597         FAIL;
12598       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12599     }
12600   DONE;
12603 (define_expand "ctr<mode>"
12604   [(parallel [(set (pc)
12605                    (if_then_else (ne (match_operand:P 0 "register_operand")
12606                                      (const_int 1))
12607                                  (label_ref (match_operand 1))
12608                                  (pc)))
12609               (set (match_dup 0)
12610                    (plus:P (match_dup 0)
12611                             (const_int -1)))
12612               (clobber (match_scratch:CC 2))
12613               (clobber (match_scratch:P 3))])]
12614   ""
12615   "")
12617 ;; We need to be able to do this for any operand, including MEM, or we
12618 ;; will cause reload to blow up since we don't allow output reloads on
12619 ;; JUMP_INSNs.
12620 ;; For the length attribute to be calculated correctly, the
12621 ;; label MUST be operand 0.
12622 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12623 ;; the ctr<mode> insns.
12625 (define_code_iterator eqne [eq ne])
12626 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12627 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12629 (define_insn "<bd>_<mode>"
12630   [(set (pc)
12631         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12632                           (const_int 1))
12633                       (label_ref (match_operand 0))
12634                       (pc)))
12635    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12636         (plus:P (match_dup 1)
12637                 (const_int -1)))
12638    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12639    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12640   ""
12642   if (which_alternative != 0)
12643     return "#";
12644   else if (get_attr_length (insn) == 4)
12645     return "<bd> %l0";
12646   else
12647     return "<bd_neg> $+8\;b %l0";
12649   [(set_attr "type" "branch")
12650    (set_attr "length" "*,16,20,20")])
12652 ;; Now the splitter if we could not allocate the CTR register
12653 (define_split
12654   [(set (pc)
12655         (if_then_else (match_operator 2 "comparison_operator"
12656                                       [(match_operand:P 1 "gpc_reg_operand")
12657                                        (const_int 1)])
12658                       (match_operand 5)
12659                       (match_operand 6)))
12660    (set (match_operand:P 0 "nonimmediate_operand")
12661         (plus:P (match_dup 1)
12662                 (const_int -1)))
12663    (clobber (match_scratch:CC 3))
12664    (clobber (match_scratch:P 4))]
12665   "reload_completed"
12666   [(set (pc)
12667         (if_then_else (match_dup 7)
12668                       (match_dup 5)
12669                       (match_dup 6)))]
12671   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12672                                 const0_rtx);
12673   emit_insn (gen_rtx_SET (operands[3],
12674                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12675   if (gpc_reg_operand (operands[0], <MODE>mode))
12676     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12677   else
12678     {
12679       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12680       emit_move_insn (operands[0], operands[4]);
12681     } 
12682     /* No DONE so branch comes from the pattern.  */
12685 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12686 ;; Note that in the case of long branches we have to decompose this into
12687 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12688 ;; and the CR bit, which means there is no way to conveniently invert the
12689 ;; comparison as is done with plain bdnz/bdz.
12691 (define_insn "<bd>tf_<mode>"
12692   [(set (pc)
12693         (if_then_else
12694           (and
12695              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12696                    (const_int 1))
12697              (match_operator 3 "branch_comparison_operator"
12698                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12699                        (const_int 0)]))
12700           (label_ref (match_operand 0))
12701           (pc)))
12702    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12703         (plus:P (match_dup 1)
12704                 (const_int -1)))
12705    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12706    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12707    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12708   ""
12710   if (which_alternative != 0)
12711     return "#";
12712   else if (get_attr_length (insn) == 4)
12713     {
12714       if (branch_positive_comparison_operator (operands[3],
12715                                                GET_MODE (operands[3])))
12716         return "<bd>t %j3,%l0";
12717       else
12718         return "<bd>f %j3,%l0";
12719     }
12720   else
12721     {
12722       static char seq[96];
12723       char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12724       sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12725       return seq;
12726     }
12728   [(set_attr "type" "branch")
12729    (set_attr "length" "*,16,20,20")])
12731 ;; Now the splitter if we could not allocate the CTR register
12732 (define_split
12733   [(set (pc)
12734         (if_then_else
12735           (and
12736              (match_operator 1 "comparison_operator"
12737                              [(match_operand:P 0 "gpc_reg_operand")
12738                               (const_int 1)])
12739              (match_operator 3 "branch_comparison_operator"
12740                       [(match_operand 2 "cc_reg_operand")
12741                        (const_int 0)]))
12742           (match_operand 4)
12743           (match_operand 5)))
12744    (set (match_operand:P 6 "int_reg_operand")
12745         (plus:P (match_dup 0)
12746                 (const_int -1)))
12747    (clobber (match_scratch:P 7))
12748    (clobber (match_scratch:CC 8))
12749    (clobber (match_scratch:CCEQ 9))]
12750   "reload_completed"
12751 [(pc)]
12753   rtx ctr = operands[0];
12754   rtx ctrcmp = operands[1];
12755   rtx ccin = operands[2];
12756   rtx cccmp = operands[3];
12757   rtx dst1 = operands[4];
12758   rtx dst2 = operands[5];
12759   rtx ctrout = operands[6];
12760   rtx ctrtmp = operands[7];
12761   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12762   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12763   if (!ispos)
12764     cmpcode = reverse_condition (cmpcode);
12765   /* Generate crand/crandc here.  */
12766   emit_insn (gen_rtx_SET (operands[8],
12767                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12768   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12770   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12771   if (ispos)
12772      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12773                                       operands[8], cccmp, ccin));
12774   else
12775      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12776                                                  operands[8], cccmp, ccin));
12777   if (gpc_reg_operand (operands[0], <MODE>mode))
12778      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12779   else
12780     {
12781       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12782       emit_move_insn (ctrout, ctrtmp);
12783     }
12784   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12785   emit_jump_insn (gen_rtx_SET (pc_rtx,
12786                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12787                                                      dst1, dst2)));
12788   DONE;
12792 (define_insn "trap"
12793   [(trap_if (const_int 1) (const_int 0))]
12794   ""
12795   "trap"
12796   [(set_attr "type" "trap")])
12798 (define_expand "ctrap<mode>4"
12799   [(trap_if (match_operator 0 "ordered_comparison_operator"
12800                             [(match_operand:GPR 1 "register_operand")
12801                              (match_operand:GPR 2 "reg_or_short_operand")])
12802             (match_operand 3 "zero_constant" ""))]
12803   ""
12804   "")
12806 (define_insn ""
12807   [(trap_if (match_operator 0 "ordered_comparison_operator"
12808                             [(match_operand:GPR 1 "register_operand" "r")
12809                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12810             (const_int 0))]
12811   ""
12812   "t<wd>%V0%I2 %1,%2"
12813   [(set_attr "type" "trap")])
12815 ;; Insns related to generating the function prologue and epilogue.
12817 (define_expand "prologue"
12818   [(use (const_int 0))]
12819   ""
12821   rs6000_emit_prologue ();
12822   if (!TARGET_SCHED_PROLOG)
12823     emit_insn (gen_blockage ());
12824   DONE;
12827 (define_insn "*movesi_from_cr_one"
12828   [(match_parallel 0 "mfcr_operation"
12829                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12830                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12831                                      (match_operand 3 "immediate_operand" "n")]
12832                           UNSPEC_MOVESI_FROM_CR))])]
12833   "TARGET_MFCRF"
12835   int mask = 0;
12836   int i;
12837   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12838   {
12839     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12840     operands[4] = GEN_INT (mask);
12841     output_asm_insn ("mfcr %1,%4", operands);
12842   }
12843   return "";
12845   [(set_attr "type" "mfcrf")])
12847 ;; Don't include the volatile CRs since their values are not used wrt CR save
12848 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12849 ;; prologue past an insn (early exit test) that defines a register used in the
12850 ;; prologue.
12851 (define_insn "prologue_movesi_from_cr"
12852   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12853         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12854                     (reg:CC CR4_REGNO)]
12855                    UNSPEC_MOVESI_FROM_CR))]
12856   ""
12857   "mfcr %0"
12858   [(set_attr "type" "mfcr")])
12860 (define_insn "*crsave"
12861   [(match_parallel 0 "crsave_operation"
12862                    [(set (match_operand:SI 1 "memory_operand" "=m")
12863                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12864   ""
12865   "stw %2,%1"
12866   [(set_attr "type" "store")])
12868 (define_insn "*stmw"
12869   [(match_parallel 0 "stmw_operation"
12870                    [(set (match_operand:SI 1 "memory_operand" "=m")
12871                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12872   "TARGET_MULTIPLE"
12873   "stmw %2,%1"
12874   [(set_attr "type" "store")
12875    (set_attr "update" "yes")
12876    (set_attr "indexed" "yes")])
12878 ; The following comment applies to:
12879 ;     save_gpregs_*
12880 ;     save_fpregs_*
12881 ;     restore_gpregs*
12882 ;     return_and_restore_gpregs*
12883 ;     return_and_restore_fpregs*
12884 ;     return_and_restore_fpregs_aix*
12886 ; The out-of-line save / restore functions expects one input argument.
12887 ; Since those are not standard call_insn's, we must avoid using
12888 ; MATCH_OPERAND for that argument. That way the register rename
12889 ; optimization will not try to rename this register.
12890 ; Each pattern is repeated for each possible register number used in 
12891 ; various ABIs (r11, r1, and for some functions r12)
12893 (define_insn "*save_gpregs_<mode>_r11"
12894   [(match_parallel 0 "any_parallel_operand"
12895                    [(clobber (reg:P LR_REGNO))
12896                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12897                     (use (reg:P 11))
12898                     (set (match_operand:P 2 "memory_operand" "=m")
12899                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12900   ""
12901   "bl %1"
12902   [(set_attr "type" "branch")
12903    (set_attr "length" "4")])
12905 (define_insn "*save_gpregs_<mode>_r12"
12906   [(match_parallel 0 "any_parallel_operand"
12907                    [(clobber (reg:P LR_REGNO))
12908                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12909                     (use (reg:P 12))
12910                     (set (match_operand:P 2 "memory_operand" "=m")
12911                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12912   ""
12913   "bl %1"
12914   [(set_attr "type" "branch")
12915    (set_attr "length" "4")])
12917 (define_insn "*save_gpregs_<mode>_r1"
12918   [(match_parallel 0 "any_parallel_operand"
12919                    [(clobber (reg:P LR_REGNO))
12920                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12921                     (use (reg:P 1))
12922                     (set (match_operand:P 2 "memory_operand" "=m")
12923                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12924   ""
12925   "bl %1"
12926   [(set_attr "type" "branch")
12927    (set_attr "length" "4")])
12929 (define_insn "*save_fpregs_<mode>_r11"
12930   [(match_parallel 0 "any_parallel_operand"
12931                    [(clobber (reg:P LR_REGNO))
12932                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12933                     (use (reg:P 11))
12934                     (set (match_operand:DF 2 "memory_operand" "=m")
12935                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12936   ""
12937   "bl %1"
12938   [(set_attr "type" "branch")
12939    (set_attr "length" "4")])
12941 (define_insn "*save_fpregs_<mode>_r12"
12942   [(match_parallel 0 "any_parallel_operand"
12943                    [(clobber (reg:P LR_REGNO))
12944                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12945                     (use (reg:P 12))
12946                     (set (match_operand:DF 2 "memory_operand" "=m")
12947                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12948   ""
12949   "bl %1"
12950   [(set_attr "type" "branch")
12951    (set_attr "length" "4")])
12953 (define_insn "*save_fpregs_<mode>_r1"
12954   [(match_parallel 0 "any_parallel_operand"
12955                    [(clobber (reg:P LR_REGNO))
12956                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12957                     (use (reg:P 1))
12958                     (set (match_operand:DF 2 "memory_operand" "=m")
12959                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12960   ""
12961   "bl %1"
12962   [(set_attr "type" "branch")
12963    (set_attr "length" "4")])
12965 ; This is to explain that changes to the stack pointer should
12966 ; not be moved over loads from or stores to stack memory.
12967 (define_insn "stack_tie"
12968   [(match_parallel 0 "tie_operand"
12969                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12970   ""
12971   ""
12972   [(set_attr "length" "0")])
12974 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12975 ; stay behind all restores from the stack, it cannot be reordered to before
12976 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
12977 (define_insn "stack_restore_tie"
12978   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12979         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12980                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12981    (set (mem:BLK (scratch)) (const_int 0))]
12982   "TARGET_32BIT"
12983   "@
12984    mr %0,%1
12985    add%I2 %0,%1,%2"
12986   [(set_attr "type" "*,add")])
12988 (define_expand "epilogue"
12989   [(use (const_int 0))]
12990   ""
12992   if (!TARGET_SCHED_PROLOG)
12993     emit_insn (gen_blockage ());
12994   rs6000_emit_epilogue (FALSE);
12995   DONE;
12998 ; On some processors, doing the mtcrf one CC register at a time is
12999 ; faster (like on the 604e).  On others, doing them all at once is
13000 ; faster; for instance, on the 601 and 750.
13002 (define_expand "movsi_to_cr_one"
13003   [(set (match_operand:CC 0 "cc_reg_operand")
13004         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13005                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13006   ""
13007   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13009 (define_insn "*movsi_to_cr"
13010   [(match_parallel 0 "mtcrf_operation"
13011                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13012                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13013                                      (match_operand 3 "immediate_operand" "n")]
13014                                     UNSPEC_MOVESI_TO_CR))])]
13015  ""
13017   int mask = 0;
13018   int i;
13019   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13020     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13021   operands[4] = GEN_INT (mask);
13022   return "mtcrf %4,%2";
13024   [(set_attr "type" "mtcr")])
13026 (define_insn "*mtcrfsi"
13027   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13028         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13029                     (match_operand 2 "immediate_operand" "n")]
13030                    UNSPEC_MOVESI_TO_CR))]
13031   "GET_CODE (operands[0]) == REG
13032    && CR_REGNO_P (REGNO (operands[0]))
13033    && GET_CODE (operands[2]) == CONST_INT
13034    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13035   "mtcrf %R0,%1"
13036   [(set_attr "type" "mtcr")])
13038 ; The load-multiple instructions have similar properties.
13039 ; Note that "load_multiple" is a name known to the machine-independent
13040 ; code that actually corresponds to the PowerPC load-string.
13042 (define_insn "*lmw"
13043   [(match_parallel 0 "lmw_operation"
13044                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13045                          (match_operand:SI 2 "memory_operand" "m"))])]
13046   "TARGET_MULTIPLE"
13047   "lmw %1,%2"
13048   [(set_attr "type" "load")
13049    (set_attr "update" "yes")
13050    (set_attr "indexed" "yes")
13051    (set_attr "cell_micro" "always")])
13053 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13054 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13056 ; The following comment applies to:
13057 ;     save_gpregs_*
13058 ;     save_fpregs_*
13059 ;     restore_gpregs*
13060 ;     return_and_restore_gpregs*
13061 ;     return_and_restore_fpregs*
13062 ;     return_and_restore_fpregs_aix*
13064 ; The out-of-line save / restore functions expects one input argument.
13065 ; Since those are not standard call_insn's, we must avoid using
13066 ; MATCH_OPERAND for that argument. That way the register rename
13067 ; optimization will not try to rename this register.
13068 ; Each pattern is repeated for each possible register number used in 
13069 ; various ABIs (r11, r1, and for some functions r12)
13071 (define_insn "*restore_gpregs_<mode>_r11"
13072  [(match_parallel 0 "any_parallel_operand"
13073                   [(clobber (reg:P LR_REGNO))
13074                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13075                    (use (reg:P 11))
13076                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13077                         (match_operand:P 3 "memory_operand" "m"))])]
13078  ""
13079  "bl %1"
13080  [(set_attr "type" "branch")
13081   (set_attr "length" "4")])
13083 (define_insn "*restore_gpregs_<mode>_r12"
13084  [(match_parallel 0 "any_parallel_operand"
13085                   [(clobber (reg:P LR_REGNO))
13086                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13087                    (use (reg:P 12))
13088                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13089                         (match_operand:P 3 "memory_operand" "m"))])]
13090  ""
13091  "bl %1"
13092  [(set_attr "type" "branch")
13093   (set_attr "length" "4")])
13095 (define_insn "*restore_gpregs_<mode>_r1"
13096  [(match_parallel 0 "any_parallel_operand"
13097                   [(clobber (reg:P LR_REGNO))
13098                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13099                    (use (reg:P 1))
13100                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13101                         (match_operand:P 3 "memory_operand" "m"))])]
13102  ""
13103  "bl %1"
13104  [(set_attr "type" "branch")
13105   (set_attr "length" "4")])
13107 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13108  [(match_parallel 0 "any_parallel_operand"
13109                   [(return)
13110                    (clobber (reg:P LR_REGNO))
13111                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13112                    (use (reg:P 11))
13113                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13114                         (match_operand:P 3 "memory_operand" "m"))])]
13115  ""
13116  "b %1"
13117  [(set_attr "type" "branch")
13118   (set_attr "length" "4")])
13120 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13121  [(match_parallel 0 "any_parallel_operand"
13122                   [(return)
13123                    (clobber (reg:P LR_REGNO))
13124                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13125                    (use (reg:P 12))
13126                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13127                         (match_operand:P 3 "memory_operand" "m"))])]
13128  ""
13129  "b %1"
13130  [(set_attr "type" "branch")
13131   (set_attr "length" "4")])
13133 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13134  [(match_parallel 0 "any_parallel_operand"
13135                   [(return)
13136                    (clobber (reg:P LR_REGNO))
13137                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13138                    (use (reg:P 1))
13139                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13140                         (match_operand:P 3 "memory_operand" "m"))])]
13141  ""
13142  "b %1"
13143  [(set_attr "type" "branch")
13144   (set_attr "length" "4")])
13146 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13147  [(match_parallel 0 "any_parallel_operand"
13148                   [(return)
13149                    (clobber (reg:P LR_REGNO))
13150                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13151                    (use (reg:P 11))
13152                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13153                         (match_operand:DF 3 "memory_operand" "m"))])]
13154  ""
13155  "b %1"
13156  [(set_attr "type" "branch")
13157   (set_attr "length" "4")])
13159 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13160  [(match_parallel 0 "any_parallel_operand"
13161                   [(return)
13162                    (clobber (reg:P LR_REGNO))
13163                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13164                    (use (reg:P 12))
13165                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13166                         (match_operand:DF 3 "memory_operand" "m"))])]
13167  ""
13168  "b %1"
13169  [(set_attr "type" "branch")
13170   (set_attr "length" "4")])
13172 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13173  [(match_parallel 0 "any_parallel_operand"
13174                   [(return)
13175                    (clobber (reg:P LR_REGNO))
13176                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13177                    (use (reg:P 1))
13178                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13179                         (match_operand:DF 3 "memory_operand" "m"))])]
13180  ""
13181  "b %1"
13182  [(set_attr "type" "branch")
13183   (set_attr "length" "4")])
13185 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13186  [(match_parallel 0 "any_parallel_operand"
13187                   [(return)
13188                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13189                    (use (reg:P 11))
13190                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13191                         (match_operand:DF 3 "memory_operand" "m"))])]
13192  ""
13193  "b %1"
13194  [(set_attr "type" "branch")
13195   (set_attr "length" "4")])
13197 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13198  [(match_parallel 0 "any_parallel_operand"
13199                   [(return)
13200                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13201                    (use (reg:P 1))
13202                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13203                         (match_operand:DF 3 "memory_operand" "m"))])]
13204  ""
13205  "b %1"
13206  [(set_attr "type" "branch")
13207   (set_attr "length" "4")])
13209 ; This is used in compiling the unwind routines.
13210 (define_expand "eh_return"
13211   [(use (match_operand 0 "general_operand"))]
13212   ""
13214   if (TARGET_32BIT)
13215     emit_insn (gen_eh_set_lr_si (operands[0]));
13216   else
13217     emit_insn (gen_eh_set_lr_di (operands[0]));
13218   DONE;
13221 ; We can't expand this before we know where the link register is stored.
13222 (define_insn "eh_set_lr_<mode>"
13223   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13224                     UNSPECV_EH_RR)
13225    (clobber (match_scratch:P 1 "=&b"))]
13226   ""
13227   "#")
13229 (define_split
13230   [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13231    (clobber (match_scratch 1))]
13232   "reload_completed"
13233   [(const_int 0)]
13235   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13236   DONE;
13239 (define_insn "prefetch"
13240   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13241              (match_operand:SI 1 "const_int_operand" "n")
13242              (match_operand:SI 2 "const_int_operand" "n"))]
13243   ""
13245   if (GET_CODE (operands[0]) == REG)
13246     return INTVAL (operands[1]) ? "dcbtst 0,%0" : "dcbt 0,%0";
13247   return INTVAL (operands[1]) ? "dcbtst %a0" : "dcbt %a0";
13249   [(set_attr "type" "load")])
13251 ;; Handle -fsplit-stack.
13253 (define_expand "split_stack_prologue"
13254   [(const_int 0)]
13255   ""
13257   rs6000_expand_split_stack_prologue ();
13258   DONE;
13261 (define_expand "load_split_stack_limit"
13262   [(set (match_operand 0)
13263         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13264   ""
13266   emit_insn (gen_rtx_SET (operands[0],
13267                           gen_rtx_UNSPEC (Pmode,
13268                                           gen_rtvec (1, const0_rtx),
13269                                           UNSPEC_STACK_CHECK)));
13270   DONE;
13273 (define_insn "load_split_stack_limit_di"
13274   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13275         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13276   "TARGET_64BIT"
13277   "ld %0,-0x7040(13)"
13278   [(set_attr "type" "load")
13279    (set_attr "update" "no")
13280    (set_attr "indexed" "no")])
13282 (define_insn "load_split_stack_limit_si"
13283   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13284         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13285   "!TARGET_64BIT"
13286   "lwz %0,-0x7020(2)"
13287   [(set_attr "type" "load")
13288    (set_attr "update" "no")
13289    (set_attr "indexed" "no")])
13291 ;; A return instruction which the middle-end doesn't see.
13292 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13293 ;; after the call to __morestack.
13294 (define_insn "split_stack_return"
13295   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13296   ""
13297   "blr"
13298   [(set_attr "type" "jmpreg")])
13300 ;; If there are operand 0 bytes available on the stack, jump to
13301 ;; operand 1.
13302 (define_expand "split_stack_space_check"
13303   [(set (match_dup 2)
13304         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13305    (set (match_dup 3)
13306         (minus (reg STACK_POINTER_REGNUM)
13307                (match_operand 0)))
13308    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13309    (set (pc) (if_then_else
13310               (geu (match_dup 4) (const_int 0))
13311               (label_ref (match_operand 1))
13312               (pc)))]
13313   ""
13315   rs6000_split_stack_space_check (operands[0], operands[1]);
13316   DONE;
13319 (define_insn "bpermd_<mode>"
13320   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13321         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13322                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13323   "TARGET_POPCNTD"
13324   "bpermd %0,%1,%2"
13325   [(set_attr "type" "popcnt")])
13328 ;; Builtin fma support.  Handle 
13329 ;; Note that the conditions for expansion are in the FMA_F iterator.
13331 (define_expand "fma<mode>4"
13332   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13333         (fma:FMA_F
13334           (match_operand:FMA_F 1 "gpc_reg_operand")
13335           (match_operand:FMA_F 2 "gpc_reg_operand")
13336           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13337   ""
13338   "")
13340 (define_insn "*fma<mode>4_fpr"
13341   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13342         (fma:SFDF
13343           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13344           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13345           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13346   "TARGET_<MODE>_FPR"
13347   "@
13348    fmadd<Ftrad> %0,%1,%2,%3
13349    xsmadda<Fvsx> %x0,%x1,%x2
13350    xsmaddm<Fvsx> %x0,%x1,%x3"
13351   [(set_attr "type" "fp")
13352    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13354 ; Altivec only has fma and nfms.
13355 (define_expand "fms<mode>4"
13356   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13357         (fma:FMA_F
13358           (match_operand:FMA_F 1 "gpc_reg_operand")
13359           (match_operand:FMA_F 2 "gpc_reg_operand")
13360           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13361   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13362   "")
13364 (define_insn "*fms<mode>4_fpr"
13365   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13366         (fma:SFDF
13367          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13368          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13369          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13370   "TARGET_<MODE>_FPR"
13371   "@
13372    fmsub<Ftrad> %0,%1,%2,%3
13373    xsmsuba<Fvsx> %x0,%x1,%x2
13374    xsmsubm<Fvsx> %x0,%x1,%x3"
13375   [(set_attr "type" "fp")
13376    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13378 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13379 (define_expand "fnma<mode>4"
13380   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13381         (neg:FMA_F
13382           (fma:FMA_F
13383             (match_operand:FMA_F 1 "gpc_reg_operand")
13384             (match_operand:FMA_F 2 "gpc_reg_operand")
13385             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13386   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13387   "")
13389 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13390 (define_expand "fnms<mode>4"
13391   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13392         (neg:FMA_F
13393           (fma:FMA_F
13394             (match_operand:FMA_F 1 "gpc_reg_operand")
13395             (match_operand:FMA_F 2 "gpc_reg_operand")
13396             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13397   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13398   "")
13400 ; Not an official optab name, but used from builtins.
13401 (define_expand "nfma<mode>4"
13402   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13403         (neg:FMA_F
13404           (fma:FMA_F
13405             (match_operand:FMA_F 1 "gpc_reg_operand")
13406             (match_operand:FMA_F 2 "gpc_reg_operand")
13407             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13408   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13409   "")
13411 (define_insn "*nfma<mode>4_fpr"
13412   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13413         (neg:SFDF
13414          (fma:SFDF
13415           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13416           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13417           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13418   "TARGET_<MODE>_FPR"
13419   "@
13420    fnmadd<Ftrad> %0,%1,%2,%3
13421    xsnmadda<Fvsx> %x0,%x1,%x2
13422    xsnmaddm<Fvsx> %x0,%x1,%x3"
13423   [(set_attr "type" "fp")
13424    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13426 ; Not an official optab name, but used from builtins.
13427 (define_expand "nfms<mode>4"
13428   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13429         (neg:FMA_F
13430           (fma:FMA_F
13431             (match_operand:FMA_F 1 "gpc_reg_operand")
13432             (match_operand:FMA_F 2 "gpc_reg_operand")
13433             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13434   ""
13435   "")
13437 (define_insn "*nfmssf4_fpr"
13438   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13439         (neg:SFDF
13440          (fma:SFDF
13441           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13442           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13443           (neg:SFDF
13444            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13445   "TARGET_<MODE>_FPR"
13446   "@
13447    fnmsub<Ftrad> %0,%1,%2,%3
13448    xsnmsuba<Fvsx> %x0,%x1,%x2
13449    xsnmsubm<Fvsx> %x0,%x1,%x3"
13450   [(set_attr "type" "fp")
13451    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13454 (define_expand "rs6000_get_timebase"
13455   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13456   ""
13458   if (TARGET_POWERPC64)
13459     emit_insn (gen_rs6000_mftb_di (operands[0]));
13460   else
13461     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13462   DONE;
13465 (define_insn "rs6000_get_timebase_ppc32"
13466   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13467         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13468    (clobber (match_scratch:SI 1 "=r"))
13469    (clobber (match_scratch:CC 2 "=y"))]
13470   "!TARGET_POWERPC64"
13472   if (WORDS_BIG_ENDIAN)
13473     if (TARGET_MFCRF)
13474       {
13475         return "mfspr %0,269\;"
13476                "mfspr %L0,268\;"
13477                "mfspr %1,269\;"
13478                "cmpw %2,%0,%1\;"
13479                "bne- %2,$-16";
13480       }
13481     else
13482       {
13483         return "mftbu %0\;"
13484                "mftb %L0\;"
13485                "mftbu %1\;"
13486                "cmpw %2,%0,%1\;"
13487                "bne- %2,$-16";
13488       }
13489   else
13490     if (TARGET_MFCRF)
13491       {
13492         return "mfspr %L0,269\;"
13493                "mfspr %0,268\;"
13494                "mfspr %1,269\;"
13495                "cmpw %2,%L0,%1\;"
13496                "bne- %2,$-16";
13497       }
13498     else
13499       {
13500         return "mftbu %L0\;"
13501                "mftb %0\;"
13502                "mftbu %1\;"
13503                "cmpw %2,%L0,%1\;"
13504                "bne- %2,$-16";
13505       }
13507   [(set_attr "length" "20")])
13509 (define_insn "rs6000_mftb_<mode>"
13510   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13511         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13512   ""
13514   if (TARGET_MFCRF)
13515     return "mfspr %0,268";
13516   else
13517     return "mftb %0";
13521 (define_insn "rs6000_mffs"
13522   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13523         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13524   "TARGET_HARD_FLOAT"
13525   "mffs %0")
13527 (define_insn "rs6000_mtfsf"
13528   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13529                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13530                     UNSPECV_MTFSF)]
13531   "TARGET_HARD_FLOAT"
13532   "mtfsf %0,%1")
13535 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13536 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13537 ;; register that is being loaded.  The fused ops must be physically adjacent.
13539 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13540 ;; before register allocation, and is meant to reduce the lifetime for the
13541 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13542 ;; to use the register that is being load.  The peephole2 then gathers any
13543 ;; other fused possibilities that it can find after register allocation.  If
13544 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13546 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13547 ;; before register allocation, so that we can avoid allocating a temporary base
13548 ;; register that won't be used, and that we try to load into base registers,
13549 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13550 ;; (addis followed by load) even on power8.
13552 (define_split
13553   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13554         (match_operand:INT1 1 "toc_fusion_mem_raw"))]
13555   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13556   [(parallel [(set (match_dup 0) (match_dup 2))
13557               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13558               (use (match_dup 3))
13559               (clobber (scratch:DI))])]
13561   operands[2] = fusion_wrap_memory_address (operands[1]);
13562   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13565 (define_insn "*toc_fusionload_<mode>"
13566   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13567         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13568    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13569    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13570    (clobber (match_scratch:DI 3 "=X,&b"))]
13571   "TARGET_TOC_FUSION_INT"
13573   if (base_reg_operand (operands[0], <MODE>mode))
13574     return emit_fusion_gpr_load (operands[0], operands[1]);
13576   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13578   [(set_attr "type" "load")
13579    (set_attr "length" "8")])
13581 (define_insn "*toc_fusionload_di"
13582   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13583         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13584    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13585    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13586    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13587   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13588    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13590   if (base_reg_operand (operands[0], DImode))
13591     return emit_fusion_gpr_load (operands[0], operands[1]);
13593   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13595   [(set_attr "type" "load")
13596    (set_attr "length" "8")])
13599 ;; Find cases where the addis that feeds into a load instruction is either used
13600 ;; once or is the same as the target register, and replace it with the fusion
13601 ;; insn
13603 (define_peephole2
13604   [(set (match_operand:P 0 "base_reg_operand")
13605         (match_operand:P 1 "fusion_gpr_addis"))
13606    (set (match_operand:INT1 2 "base_reg_operand")
13607         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13608   "TARGET_P8_FUSION
13609    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13610                          operands[3])"
13611   [(const_int 0)]
13613   expand_fusion_gpr_load (operands);
13614   DONE;
13617 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13618 ;; reload)
13620 (define_insn "fusion_gpr_load_<mode>"
13621   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13622         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13623                      UNSPEC_FUSION_GPR))]
13624   "TARGET_P8_FUSION"
13626   return emit_fusion_gpr_load (operands[0], operands[1]);
13628   [(set_attr "type" "load")
13629    (set_attr "length" "8")])
13632 ;; ISA 3.0 (power9) fusion support
13633 ;; Merge addis with floating load/store to FPRs (or GPRs).
13634 (define_peephole2
13635   [(set (match_operand:P 0 "base_reg_operand")
13636         (match_operand:P 1 "fusion_gpr_addis"))
13637    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13638         (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13639   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13640    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13641   [(const_int 0)]
13643   expand_fusion_p9_load (operands);
13644   DONE;
13647 (define_peephole2
13648   [(set (match_operand:P 0 "base_reg_operand")
13649         (match_operand:P 1 "fusion_gpr_addis"))
13650    (set (match_operand:SFDF 2 "offsettable_mem_operand")
13651         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13652   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13653    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13654    && !rtx_equal_p (operands[0], operands[3])"
13655   [(const_int 0)]
13657   expand_fusion_p9_store (operands);
13658   DONE;
13661 (define_peephole2
13662   [(set (match_operand:SDI 0 "int_reg_operand")
13663         (match_operand:SDI 1 "upper16_cint_operand"))
13664    (set (match_dup 0)
13665         (ior:SDI (match_dup 0)
13666                  (match_operand:SDI 2 "u_short_cint_operand")))]
13667   "TARGET_P9_FUSION"
13668   [(set (match_dup 0)
13669         (unspec:SDI [(match_dup 1)
13670                      (match_dup 2)] UNSPEC_FUSION_P9))])
13672 (define_peephole2
13673   [(set (match_operand:SDI 0 "int_reg_operand")
13674         (match_operand:SDI 1 "upper16_cint_operand"))
13675    (set (match_operand:SDI 2 "int_reg_operand")
13676         (ior:SDI (match_dup 0)
13677                  (match_operand:SDI 3 "u_short_cint_operand")))]
13678   "TARGET_P9_FUSION
13679    && !rtx_equal_p (operands[0], operands[2])
13680    && peep2_reg_dead_p (2, operands[0])"
13681   [(set (match_dup 2)
13682         (unspec:SDI [(match_dup 1)
13683                      (match_dup 3)] UNSPEC_FUSION_P9))])
13685 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13686 ;; reload).  Because we want to eventually have secondary_reload generate
13687 ;; these, they have to have a single alternative that gives the register
13688 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13689 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13690   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13691         (unspec:GPR_FUSION
13692          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13693          UNSPEC_FUSION_P9))
13694    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13695   "TARGET_P9_FUSION"
13697   /* This insn is a secondary reload insn, which cannot have alternatives.
13698      If we are not loading up register 0, use the power8 fusion instead.  */
13699   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13700     return emit_fusion_gpr_load (operands[0], operands[1]);
13702   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13704   [(set_attr "type" "load")
13705    (set_attr "length" "8")])
13707 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13708   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13709         (unspec:GPR_FUSION
13710          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13711          UNSPEC_FUSION_P9))
13712    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13713   "TARGET_P9_FUSION"
13715   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13717   [(set_attr "type" "store")
13718    (set_attr "length" "8")])
13720 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13721   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13722         (unspec:FPR_FUSION
13723          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13724          UNSPEC_FUSION_P9))
13725    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13726   "TARGET_P9_FUSION"
13728   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13730   [(set_attr "type" "fpload")
13731    (set_attr "length" "8")])
13733 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13734   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13735         (unspec:FPR_FUSION
13736          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13737          UNSPEC_FUSION_P9))
13738    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13739   "TARGET_P9_FUSION"
13741   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13743   [(set_attr "type" "fpstore")
13744    (set_attr "length" "8")])
13746 (define_insn "*fusion_p9_<mode>_constant"
13747   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13748         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13749                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13750                     UNSPEC_FUSION_P9))] 
13751   "TARGET_P9_FUSION"
13753   emit_fusion_addis (operands[0], operands[1]);
13754   return "ori %0,%0,%2";
13756   [(set_attr "type" "two")
13757    (set_attr "length" "8")])
13760 ;; Optimize cases where we want to do a D-form load (register+offset) on
13761 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13762 ;; has generated:
13763 ;;      LFD 0,32(3)
13764 ;;      XXLOR 32,0,0
13766 ;; and we change this to:
13767 ;;      LI 0,32
13768 ;;      LXSDX 32,3,9
13770 (define_peephole2
13771   [(match_scratch:P 0 "b")
13772    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13773         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13774    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13775         (match_dup 1))]
13776   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13777   [(set (match_dup 0)
13778         (match_dup 4))
13779    (set (match_dup 3)
13780         (match_dup 5))]
13782   rtx tmp_reg = operands[0];
13783   rtx mem = operands[2];
13784   rtx addr = XEXP (mem, 0);
13785   rtx add_op0, add_op1, new_addr;
13787   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13788   add_op0 = XEXP (addr, 0);
13789   add_op1 = XEXP (addr, 1);
13790   gcc_assert (REG_P (add_op0));
13791   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13793   operands[4] = add_op1;
13794   operands[5] = change_address (mem, <MODE>mode, new_addr);
13797 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13798 ;; Altivec register, and the register allocator has generated:
13799 ;;      XXLOR 0,32,32
13800 ;;      STFD 0,32(3)
13802 ;; and we change this to:
13803 ;;      LI 0,32
13804 ;;      STXSDX 32,3,9
13806 (define_peephole2
13807   [(match_scratch:P 0 "b")
13808    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13809         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13810    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13811         (match_dup 1))]
13812   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13813   [(set (match_dup 0)
13814         (match_dup 4))
13815    (set (match_dup 5)
13816         (match_dup 2))]
13818   rtx tmp_reg = operands[0];
13819   rtx mem = operands[3];
13820   rtx addr = XEXP (mem, 0);
13821   rtx add_op0, add_op1, new_addr;
13823   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13824   add_op0 = XEXP (addr, 0);
13825   add_op1 = XEXP (addr, 1);
13826   gcc_assert (REG_P (add_op0));
13827   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13829   operands[4] = add_op1;
13830   operands[5] = change_address (mem, <MODE>mode, new_addr);
13832    
13834 ;; Miscellaneous ISA 2.06 (power7) instructions
13835 (define_insn "addg6s"
13836   [(set (match_operand:SI 0 "register_operand" "=r")
13837         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13838                     (match_operand:SI 2 "register_operand" "r")]
13839                    UNSPEC_ADDG6S))]
13840   "TARGET_POPCNTD"
13841   "addg6s %0,%1,%2"
13842   [(set_attr "type" "integer")
13843    (set_attr "length" "4")])
13845 (define_insn "cdtbcd"
13846   [(set (match_operand:SI 0 "register_operand" "=r")
13847         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13848                    UNSPEC_CDTBCD))]
13849   "TARGET_POPCNTD"
13850   "cdtbcd %0,%1"
13851   [(set_attr "type" "integer")
13852    (set_attr "length" "4")])
13854 (define_insn "cbcdtd"
13855   [(set (match_operand:SI 0 "register_operand" "=r")
13856         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13857                    UNSPEC_CBCDTD))]
13858   "TARGET_POPCNTD"
13859   "cbcdtd %0,%1"
13860   [(set_attr "type" "integer")
13861    (set_attr "length" "4")])
13863 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13864                                         UNSPEC_DIVEU])
13866 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13867                              (UNSPEC_DIVEU      "eu")])
13869 (define_insn "div<div_extend>_<mode>"
13870   [(set (match_operand:GPR 0 "register_operand" "=r")
13871         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13872                      (match_operand:GPR 2 "register_operand" "r")]
13873                     UNSPEC_DIV_EXTEND))]
13874   "TARGET_POPCNTD"
13875   "div<wd><div_extend> %0,%1,%2"
13876   [(set_attr "type" "div")
13877    (set_attr "size" "<bits>")])
13880 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13882 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13883 (define_mode_attr FP128_64 [(TF "DF")
13884                             (IF "DF")
13885                             (TD "DI")
13886                             (KF "DI")])
13888 (define_expand "unpack<mode>"
13889   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13890         (unspec:<FP128_64>
13891          [(match_operand:FMOVE128 1 "register_operand")
13892           (match_operand:QI 2 "const_0_to_1_operand")]
13893          UNSPEC_UNPACK_128BIT))]
13894   "FLOAT128_2REG_P (<MODE>mode)"
13895   "")
13897 (define_insn_and_split "unpack<mode>_dm"
13898   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13899         (unspec:<FP128_64>
13900          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13901           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13902          UNSPEC_UNPACK_128BIT))]
13903   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13904   "#"
13905   "&& reload_completed"
13906   [(set (match_dup 0) (match_dup 3))]
13908   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13910   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13911     {
13912       emit_note (NOTE_INSN_DELETED);
13913       DONE;
13914     }
13916   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13918   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13919    (set_attr "length" "4")])
13921 (define_insn_and_split "unpack<mode>_nodm"
13922   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13923         (unspec:<FP128_64>
13924          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13925           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13926          UNSPEC_UNPACK_128BIT))]
13927   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13928   "#"
13929   "&& reload_completed"
13930   [(set (match_dup 0) (match_dup 3))]
13932   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13934   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13935     {
13936       emit_note (NOTE_INSN_DELETED);
13937       DONE;
13938     }
13940   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13942   [(set_attr "type" "fp,fpstore")
13943    (set_attr "length" "4")])
13945 (define_insn_and_split "pack<mode>"
13946   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13947         (unspec:FMOVE128
13948          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13949           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13950          UNSPEC_PACK_128BIT))]
13951   "FLOAT128_2REG_P (<MODE>mode)"
13952   "@
13953    fmr %L0,%2
13954    #"
13955   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13956   [(set (match_dup 3) (match_dup 1))
13957    (set (match_dup 4) (match_dup 2))]
13959   unsigned dest_hi = REGNO (operands[0]);
13960   unsigned dest_lo = dest_hi + 1;
13962   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13963   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13965   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13966   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13968   [(set_attr "type" "fpsimple,fp")
13969    (set_attr "length" "4,8")])
13971 (define_insn "unpack<mode>"
13972   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13973         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13974                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13975          UNSPEC_UNPACK_128BIT))]
13976   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13978   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13979     return ASM_COMMENT_START " xxpermdi to same register";
13981   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13982   return "xxpermdi %x0,%x1,%x1,%3";
13984   [(set_attr "type" "vecperm")])
13986 (define_insn "pack<mode>"
13987   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13988         (unspec:FMOVE128_VSX
13989          [(match_operand:DI 1 "register_operand" "wa")
13990           (match_operand:DI 2 "register_operand" "wa")]
13991          UNSPEC_PACK_128BIT))]
13992   "TARGET_VSX"
13993   "xxpermdi %x0,%x1,%x2,0"
13994   [(set_attr "type" "vecperm")])
13998 ;; ISA 2.08 IEEE 128-bit floating point support.
14000 (define_insn "add<mode>3"
14001   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14002         (plus:IEEE128
14003          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14004          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14005   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14006   "xsaddqp %0,%1,%2"
14007   [(set_attr "type" "vecfloat")
14008    (set_attr "size" "128")])
14010 (define_insn "sub<mode>3"
14011   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14012         (minus:IEEE128
14013          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14014          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14015   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14016   "xssubqp %0,%1,%2"
14017   [(set_attr "type" "vecfloat")
14018    (set_attr "size" "128")])
14020 (define_insn "mul<mode>3"
14021   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14022         (mult:IEEE128
14023          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14024          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14025   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14026   "xsmulqp %0,%1,%2"
14027   [(set_attr "type" "qmul")
14028    (set_attr "size" "128")])
14030 (define_insn "div<mode>3"
14031   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14032         (div:IEEE128
14033          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14034          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14035   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14036   "xsdivqp %0,%1,%2"
14037   [(set_attr "type" "vecdiv")
14038    (set_attr "size" "128")])
14040 (define_insn "sqrt<mode>2"
14041   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14042         (sqrt:IEEE128
14043          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14044   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14045    "xssqrtqp %0,%1"
14046   [(set_attr "type" "vecdiv")
14047    (set_attr "size" "128")])
14049 (define_expand "copysign<mode>3"
14050   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14051    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14052    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14053   "FLOAT128_IEEE_P (<MODE>mode)"
14055   if (TARGET_FLOAT128_HW)
14056     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14057                                          operands[2]));
14058   else
14059     {
14060       rtx tmp = gen_reg_rtx (<MODE>mode);
14061       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14062                                            operands[2], tmp));
14063     }
14064   DONE;
14067 (define_insn "copysign<mode>3_hard"
14068   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14069         (unspec:IEEE128
14070          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14071           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14072          UNSPEC_COPYSIGN))]
14073   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14074    "xscpsgnqp %0,%2,%1"
14075   [(set_attr "type" "vecmove")
14076    (set_attr "size" "128")])
14078 (define_insn "copysign<mode>3_soft"
14079   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14080         (unspec:IEEE128
14081          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14082           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14083           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14084          UNSPEC_COPYSIGN))]
14085   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14086    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14087   [(set_attr "type" "veccomplex")
14088    (set_attr "length" "8")])
14090 (define_insn "neg<mode>2_hw"
14091   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14092         (neg:IEEE128
14093          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14094   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14095   "xsnegqp %0,%1"
14096   [(set_attr "type" "vecmove")
14097    (set_attr "size" "128")])
14100 (define_insn "abs<mode>2_hw"
14101   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14102         (abs:IEEE128
14103          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14104   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14105   "xsabsqp %0,%1"
14106   [(set_attr "type" "vecmove")
14107    (set_attr "size" "128")])
14110 (define_insn "*nabs<mode>2_hw"
14111   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14112         (neg:IEEE128
14113          (abs:IEEE128
14114           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14115   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14116   "xsnabsqp %0,%1"
14117   [(set_attr "type" "vecmove")
14118    (set_attr "size" "128")])
14120 ;; Initially don't worry about doing fusion
14121 (define_insn "fma<mode>4_hw"
14122   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14123         (fma:IEEE128
14124          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14125          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14126          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14127   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14128   "xsmaddqp %0,%1,%2"
14129   [(set_attr "type" "qmul")
14130    (set_attr "size" "128")])
14132 (define_insn "*fms<mode>4_hw"
14133   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14134         (fma:IEEE128
14135          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14136          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14137          (neg:IEEE128
14138           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14139   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14140   "xsmsubqp %0,%1,%2"
14141   [(set_attr "type" "qmul")
14142    (set_attr "size" "128")])
14144 (define_insn "*nfma<mode>4_hw"
14145   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14146         (neg:IEEE128
14147          (fma:IEEE128
14148           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14149           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14150           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14151   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14152   "xsnmaddqp %0,%1,%2"
14153   [(set_attr "type" "qmul")
14154    (set_attr "size" "128")])
14156 (define_insn "*nfms<mode>4_hw"
14157   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14158         (neg:IEEE128
14159          (fma:IEEE128
14160           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14161           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14162           (neg:IEEE128
14163            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14164   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14165   "xsnmsubqp %0,%1,%2"
14166   [(set_attr "type" "qmul")
14167    (set_attr "size" "128")])
14169 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14170   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14171         (float_extend:IEEE128
14172          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14173   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14174   "xscvdpqp %0,%1"
14175   [(set_attr "type" "vecfloat")
14176    (set_attr "size" "128")])
14178 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14179 ;; point is a simple copy.
14180 (define_insn_and_split "extendkftf2"
14181   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14182         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14183   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14184   "@
14185    #
14186    xxlor %x0,%x1,%x1"
14187   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14188   [(const_int 0)]
14190   emit_note (NOTE_INSN_DELETED);
14191   DONE;
14193   [(set_attr "type" "*,veclogical")
14194    (set_attr "length" "0,4")])
14196 (define_insn_and_split "trunctfkf2"
14197   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14198         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14199   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14200   "@
14201    #
14202    xxlor %x0,%x1,%x1"
14203   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14204   [(const_int 0)]
14206   emit_note (NOTE_INSN_DELETED);
14207   DONE;
14209   [(set_attr "type" "*,veclogical")
14210    (set_attr "length" "0,4")])
14212 (define_insn "trunc<mode>df2_hw"
14213   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14214         (float_truncate:DF
14215          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14216   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14217   "xscvqpdp %0,%1"
14218   [(set_attr "type" "vecfloat")
14219    (set_attr "size" "128")])
14221 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14222 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14223 ;; conversion
14224 (define_insn_and_split "trunc<mode>sf2_hw"
14225   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14226         (float_truncate:SF
14227          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14228    (clobber (match_scratch:DF 2 "=v"))]
14229   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14230   "#"
14231   "&& 1"
14232   [(set (match_dup 2)
14233         (unspec:DF [(match_dup 1)]
14234                    UNSPEC_TRUNC_ROUND_TO_ODD))
14235    (set (match_dup 0)
14236         (float_truncate:SF (match_dup 2)))]
14238   if (GET_CODE (operands[2]) == SCRATCH)
14239     operands[2] = gen_reg_rtx (DFmode);
14241   [(set_attr "type" "vecfloat")
14242    (set_attr "length" "8")])
14244 ;; Conversion between IEEE 128-bit and integer types
14246 ;; The fix function for DImode and SImode was declared earlier as a
14247 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14248 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14249 ;; unless we have the IEEE 128-bit hardware.
14251 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14252 ;; to provide a GPR target that used direct move and a conversion in the GPR
14253 ;; which works around QImode/HImode not being allowed in vector registers in
14254 ;; ISA 2.07 (power8).
14255 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14256   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14257         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14258   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14259   "xscvqp<su><wd>z %0,%1"
14260   [(set_attr "type" "vecfloat")
14261    (set_attr "size" "128")])
14263 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14264   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14265         (any_fix:QHI
14266          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14267   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14268   "xscvqp<su>wz %0,%1"
14269   [(set_attr "type" "vecfloat")
14270    (set_attr "size" "128")])
14272 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14273 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14274 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14275   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14276         (any_fix:QHSI
14277          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14278    (clobber (match_scratch:QHSI 2 "=v"))]
14279   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14280   "#"
14281   "&& reload_completed"
14282   [(set (match_dup 2)
14283         (any_fix:QHSI (match_dup 1)))
14284    (set (match_dup 0)
14285         (match_dup 2))])
14287 (define_insn "float_<mode>di2_hw"
14288   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14289         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14290   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14291   "xscvsdqp %0,%1"
14292   [(set_attr "type" "vecfloat")
14293    (set_attr "size" "128")])
14295 (define_insn_and_split "float_<mode>si2_hw"
14296   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14297         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14298    (clobber (match_scratch:DI 2 "=v"))]
14299   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14300   "#"
14301   "&& 1"
14302   [(set (match_dup 2)
14303         (sign_extend:DI (match_dup 1)))
14304    (set (match_dup 0)
14305         (float:IEEE128 (match_dup 2)))]
14307   if (GET_CODE (operands[2]) == SCRATCH)
14308     operands[2] = gen_reg_rtx (DImode);
14310   if (MEM_P (operands[1]))
14311     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14314 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14315   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14316         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14317    (clobber (match_scratch:DI 2 "=X,r,X"))]
14318   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14319   "#"
14320   "&& reload_completed"
14321   [(const_int 0)]
14323   rtx dest = operands[0];
14324   rtx src = operands[1];
14325   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14327   if (altivec_register_operand (src, <QHI:MODE>mode))
14328     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14329   else if (int_reg_operand (src, <QHI:MODE>mode))
14330     {
14331       rtx ext_di = operands[2];
14332       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14333       emit_move_insn (dest_di, ext_di);
14334     }
14335   else if (MEM_P (src))
14336     {
14337       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14338       emit_move_insn (dest_qhi, src);
14339       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14340     }
14341   else
14342     gcc_unreachable ();
14344   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14345   DONE;
14347   [(set_attr "length" "8,12,12")
14348    (set_attr "type" "vecfloat")
14349    (set_attr "size" "128")])
14351 (define_insn "floatuns_<mode>di2_hw"
14352   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14353         (unsigned_float:IEEE128
14354          (match_operand:DI 1 "altivec_register_operand" "v")))]
14355   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14356   "xscvudqp %0,%1"
14357   [(set_attr "type" "vecfloat")
14358    (set_attr "size" "128")])
14360 (define_insn_and_split "floatuns_<mode>si2_hw"
14361   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14362         (unsigned_float:IEEE128
14363          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14364    (clobber (match_scratch:DI 2 "=v"))]
14365   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14366   "#"
14367   "&& 1"
14368   [(set (match_dup 2)
14369         (zero_extend:DI (match_dup 1)))
14370    (set (match_dup 0)
14371         (float:IEEE128 (match_dup 2)))]
14373   if (GET_CODE (operands[2]) == SCRATCH)
14374     operands[2] = gen_reg_rtx (DImode);
14376   if (MEM_P (operands[1]))
14377     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14380 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14381   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14382         (unsigned_float:IEEE128
14383          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14384    (clobber (match_scratch:DI 2 "=X,r,X"))]
14385   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14386   "#"
14387   "&& reload_completed"
14388   [(const_int 0)]
14390   rtx dest = operands[0];
14391   rtx src = operands[1];
14392   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14394   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14395     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14396   else if (int_reg_operand (src, <QHI:MODE>mode))
14397     {
14398       rtx ext_di = operands[2];
14399       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14400       emit_move_insn (dest_di, ext_di);
14401     }
14402   else
14403     gcc_unreachable ();
14405   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14406   DONE;
14408   [(set_attr "length" "8,12,8")
14409    (set_attr "type" "vecfloat")
14410    (set_attr "size" "128")])
14412 ;; IEEE 128-bit round to integer built-in functions
14413 (define_insn "floor<mode>2"
14414   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14415         (unspec:IEEE128
14416          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14417          UNSPEC_FRIM))]
14418   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14419   "xsrqpi 1,%0,%1,3"
14420   [(set_attr "type" "vecfloat")
14421    (set_attr "size" "128")])
14423 (define_insn "ceil<mode>2"
14424   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14425         (unspec:IEEE128
14426          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14427          UNSPEC_FRIP))]
14428   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14429   "xsrqpi 1,%0,%1,2"
14430   [(set_attr "type" "vecfloat")
14431    (set_attr "size" "128")])
14433 (define_insn "btrunc<mode>2"
14434   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14435         (unspec:IEEE128
14436          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14437          UNSPEC_FRIZ))]
14438   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14439   "xsrqpi 1,%0,%1,1"
14440   [(set_attr "type" "vecfloat")
14441    (set_attr "size" "128")])
14443 (define_insn "round<mode>2"
14444   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14445         (unspec:IEEE128
14446          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14447          UNSPEC_FRIN))]
14448   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14449   "xsrqpi 0,%0,%1,0"
14450   [(set_attr "type" "vecfloat")
14451    (set_attr "size" "128")])
14453 ;; IEEE 128-bit instructions with round to odd semantics
14454 (define_insn "add<mode>3_odd"
14455   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14456         (unspec:IEEE128
14457          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14458           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14459          UNSPEC_ADD_ROUND_TO_ODD))]
14460   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14461   "xsaddqpo %0,%1,%2"
14462   [(set_attr "type" "vecfloat")
14463    (set_attr "size" "128")])
14465 (define_insn "sub<mode>3_odd"
14466   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14467         (unspec:IEEE128
14468          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14469           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14470          UNSPEC_SUB_ROUND_TO_ODD))]
14471   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14472   "xssubqpo %0,%1,%2"
14473   [(set_attr "type" "vecfloat")
14474    (set_attr "size" "128")])
14476 (define_insn "mul<mode>3_odd"
14477   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14478         (unspec:IEEE128
14479          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14480           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14481          UNSPEC_MUL_ROUND_TO_ODD))]
14482   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14483   "xsmulqpo %0,%1,%2"
14484   [(set_attr "type" "qmul")
14485    (set_attr "size" "128")])
14487 (define_insn "div<mode>3_odd"
14488   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14489         (unspec:IEEE128
14490          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14491           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14492          UNSPEC_DIV_ROUND_TO_ODD))]
14493   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14494   "xsdivqpo %0,%1,%2"
14495   [(set_attr "type" "vecdiv")
14496    (set_attr "size" "128")])
14498 (define_insn "sqrt<mode>2_odd"
14499   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14500         (unspec:IEEE128
14501          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14502          UNSPEC_SQRT_ROUND_TO_ODD))]
14503   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14504    "xssqrtqpo %0,%1"
14505   [(set_attr "type" "vecdiv")
14506    (set_attr "size" "128")])
14508 (define_insn "fma<mode>4_odd"
14509   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14510         (unspec:IEEE128
14511          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14512           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14513           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14514          UNSPEC_FMA_ROUND_TO_ODD))]
14515   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14516   "xsmaddqpo %0,%1,%2"
14517   [(set_attr "type" "qmul")
14518    (set_attr "size" "128")])
14520 (define_insn "*fms<mode>4_odd"
14521   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
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   "xsmsubqpo %0,%1,%2"
14530   [(set_attr "type" "qmul")
14531    (set_attr "size" "128")])
14533 (define_insn "*nfma<mode>4_odd"
14534   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14535         (neg:IEEE128
14536          (unspec:IEEE128
14537           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14538            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14539            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14540           UNSPEC_FMA_ROUND_TO_ODD)))]
14541   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14542   "xsnmaddqpo %0,%1,%2"
14543   [(set_attr "type" "qmul")
14544    (set_attr "size" "128")])
14546 (define_insn "*nfms<mode>4_odd"
14547   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14548         (neg:IEEE128
14549          (unspec:IEEE128
14550           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14551            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14552            (neg:IEEE128
14553             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14554           UNSPEC_FMA_ROUND_TO_ODD)))]
14555   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14556   "xsnmsubqpo %0,%1,%2"
14557   [(set_attr "type" "qmul")
14558    (set_attr "size" "128")])
14560 (define_insn "trunc<mode>df2_odd"
14561   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14562         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14563                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14564   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14565   "xscvqpdpo %0,%1"
14566   [(set_attr "type" "vecfloat")
14567    (set_attr "size" "128")])
14569 ;; IEEE 128-bit comparisons
14570 (define_insn "*cmp<mode>_hw"
14571   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14572         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14573                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14574   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14575    "xscmpuqp %0,%1,%2"
14576   [(set_attr "type" "veccmp")
14577    (set_attr "size" "128")])
14581 (include "sync.md")
14582 (include "vector.md")
14583 (include "vsx.md")
14584 (include "altivec.md")
14585 (include "dfp.md")
14586 (include "paired.md")
14587 (include "crypto.md")
14588 (include "htm.md")