* gimplify.c (nonlocal_vlas): Delete.
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobb0a88a912112a597aab2318703df807a019d874a
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 ;; Length (in bytes).
248 ; '(pc)' in the following doesn't include the instruction itself; it is
249 ; calculated as if the instruction had zero size.
250 (define_attr "length" ""
251   (if_then_else (eq_attr "type" "branch")
252                 (if_then_else (and (ge (minus (match_dup 0) (pc))
253                                        (const_int -32768))
254                                    (lt (minus (match_dup 0) (pc))
255                                        (const_int 32764)))
256                               (const_int 4)
257                               (const_int 8))
258                 (const_int 4)))
260 ;; Processor type -- this attribute must exactly match the processor_type
261 ;; enumeration in rs6000-opts.h.
262 (define_attr "cpu"
263   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
264    ppc750,ppc7400,ppc7450,
265    ppc403,ppc405,ppc440,ppc476,
266    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
267    power4,power5,power6,power7,power8,power9,
268    rs64a,mpccore,cell,ppca2,titan"
269   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
272 ;; If this instruction is microcoded on the CELL processor
273 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
274 (define_attr "cell_micro" "not,conditional,always"
275   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
276                           (eq_attr "dot" "yes"))
277                      (and (eq_attr "type" "load")
278                           (eq_attr "sign_extend" "yes"))
279                      (and (eq_attr "type" "shift")
280                           (eq_attr "var_shift" "yes")))
281                 (const_string "always")
282                 (const_string "not")))
284 (automata_option "ndfa")
286 (include "rs64.md")
287 (include "mpc.md")
288 (include "40x.md")
289 (include "440.md")
290 (include "476.md")
291 (include "601.md")
292 (include "603.md")
293 (include "6xx.md")
294 (include "7xx.md")
295 (include "7450.md")
296 (include "8540.md")
297 (include "e300c2c3.md")
298 (include "e500mc.md")
299 (include "e500mc64.md")
300 (include "e5500.md")
301 (include "e6500.md")
302 (include "power4.md")
303 (include "power5.md")
304 (include "power6.md")
305 (include "power7.md")
306 (include "power8.md")
307 (include "power9.md")
308 (include "cell.md")
309 (include "a2.md")
310 (include "titan.md")
312 (include "predicates.md")
313 (include "constraints.md")
315 (include "darwin.md")
318 ;; Mode iterators
320 ; This mode iterator allows :GPR to be used to indicate the allowable size
321 ; of whole values in GPRs.
322 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
324 ; And again, for patterns that need two (potentially) different integer modes.
325 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
327 ; Any supported integer mode.
328 (define_mode_iterator INT [QI HI SI DI TI PTI])
330 ; Any supported integer mode that fits in one register.
331 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
333 ; Integer modes supported in VSX registers with ISA 3.0 instructions
334 (define_mode_iterator INT_ISA3 [QI HI SI DI])
336 ; Everything we can extend QImode to.
337 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
339 ; Everything we can extend HImode to.
340 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
342 ; Everything we can extend SImode to.
343 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
345 ; QImode or HImode for small integer moves and small atomic ops
346 (define_mode_iterator QHI [QI HI])
348 ; QImode, HImode, SImode for fused ops only for GPR loads
349 (define_mode_iterator QHSI [QI HI SI])
351 ; HImode or SImode for sign extended fusion ops
352 (define_mode_iterator HSI [HI SI])
354 ; SImode or DImode, even if DImode doesn't fit in GPRs.
355 (define_mode_iterator SDI [SI DI])
357 ; Types that can be fused with an ADDIS instruction to load or store a GPR
358 ; register that has reg+offset addressing.
359 (define_mode_iterator GPR_FUSION [QI
360                                   HI
361                                   SI
362                                   (DI   "TARGET_POWERPC64")
363                                   SF
364                                   (DF   "TARGET_POWERPC64")])
366 ; Types that can be fused with an ADDIS instruction to load or store a FPR
367 ; register that has reg+offset addressing.
368 (define_mode_iterator FPR_FUSION [DI SF DF])
370 ; The size of a pointer.  Also, the size of the value that a record-condition
371 ; (one with a '.') will compare; and the size used for arithmetic carries.
372 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
374 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
375 ; PTImode is GPR only)
376 (define_mode_iterator TI2 [TI PTI])
378 ; Any hardware-supported floating-point mode
379 (define_mode_iterator FP [
380   (SF "TARGET_HARD_FLOAT")
381   (DF "TARGET_HARD_FLOAT")
382   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
383   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
384   (KF "TARGET_FLOAT128_TYPE")
385   (DD "TARGET_DFP")
386   (TD "TARGET_DFP")])
388 ; Any fma capable floating-point mode.
389 (define_mode_iterator FMA_F [
390   (SF "TARGET_HARD_FLOAT")
391   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
392   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
393   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
394   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
395   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
396   ])
398 ; Floating point move iterators to combine binary and decimal moves
399 (define_mode_iterator FMOVE32 [SF SD])
400 (define_mode_iterator FMOVE64 [DF DD])
401 (define_mode_iterator FMOVE64X [DI DF DD])
402 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
403                                 (IF "FLOAT128_IBM_P (IFmode)")
404                                 (TD "TARGET_HARD_FLOAT")])
406 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
407                                     (IF "FLOAT128_2REG_P (IFmode)")
408                                     (TD "TARGET_HARD_FLOAT")])
410 ; Iterators for 128 bit types for direct move
411 (define_mode_iterator FMOVE128_GPR [TI
412                                     V16QI
413                                     V8HI
414                                     V4SI
415                                     V4SF
416                                     V2DI
417                                     V2DF
418                                     V1TI
419                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
420                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
422 ; Iterator for 128-bit VSX types for pack/unpack
423 (define_mode_iterator FMOVE128_VSX [V1TI KF])
425 ; Iterators for converting to/from TFmode
426 (define_mode_iterator IFKF [IF KF])
428 ; Constraints for moving IF/KFmode.
429 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
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 sdiv/ddiv
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 ;; Mode iterator for logical operations on 128-bit types
623 (define_mode_iterator BOOL_128          [TI
624                                          PTI
625                                          (V16QI "TARGET_ALTIVEC")
626                                          (V8HI  "TARGET_ALTIVEC")
627                                          (V4SI  "TARGET_ALTIVEC")
628                                          (V4SF  "TARGET_ALTIVEC")
629                                          (V2DI  "TARGET_ALTIVEC")
630                                          (V2DF  "TARGET_ALTIVEC")
631                                          (V1TI  "TARGET_ALTIVEC")])
633 ;; For the GPRs we use 3 constraints for register outputs, two that are the
634 ;; same as the output register, and a third where the output register is an
635 ;; early clobber, so we don't have to deal with register overlaps.  For the
636 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
637 ;; either.
639 ;; Mode attribute for boolean operation register constraints for output
640 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
641                                          (PTI   "&r,r,r")
642                                          (V16QI "wa,v,&?r,?r,?r")
643                                          (V8HI  "wa,v,&?r,?r,?r")
644                                          (V4SI  "wa,v,&?r,?r,?r")
645                                          (V4SF  "wa,v,&?r,?r,?r")
646                                          (V2DI  "wa,v,&?r,?r,?r")
647                                          (V2DF  "wa,v,&?r,?r,?r")
648                                          (V1TI  "wa,v,&?r,?r,?r")])
650 ;; Mode attribute for boolean operation register constraints for operand1
651 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
652                                          (PTI   "r,0,r")
653                                          (V16QI "wa,v,r,0,r")
654                                          (V8HI  "wa,v,r,0,r")
655                                          (V4SI  "wa,v,r,0,r")
656                                          (V4SF  "wa,v,r,0,r")
657                                          (V2DI  "wa,v,r,0,r")
658                                          (V2DF  "wa,v,r,0,r")
659                                          (V1TI  "wa,v,r,0,r")])
661 ;; Mode attribute for boolean operation register constraints for operand2
662 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
663                                          (PTI   "r,r,0")
664                                          (V16QI "wa,v,r,r,0")
665                                          (V8HI  "wa,v,r,r,0")
666                                          (V4SI  "wa,v,r,r,0")
667                                          (V4SF  "wa,v,r,r,0")
668                                          (V2DI  "wa,v,r,r,0")
669                                          (V2DF  "wa,v,r,r,0")
670                                          (V1TI  "wa,v,r,r,0")])
672 ;; Mode attribute for boolean operation register constraints for operand1
673 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
674 ;; is used for operand1 or operand2
675 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
676                                          (PTI   "r,0,0")
677                                          (V16QI "wa,v,r,0,0")
678                                          (V8HI  "wa,v,r,0,0")
679                                          (V4SI  "wa,v,r,0,0")
680                                          (V4SF  "wa,v,r,0,0")
681                                          (V2DI  "wa,v,r,0,0")
682                                          (V2DF  "wa,v,r,0,0")
683                                          (V1TI  "wa,v,r,0,0")])
685 ;; Reload iterator for creating the function to allocate a base register to
686 ;; supplement addressing modes.
687 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
688                               SF SD SI DF DD DI TI PTI KF IF TF])
690 ;; Iterate over smin, smax
691 (define_code_iterator fp_minmax [smin smax])
693 (define_code_attr     minmax    [(smin "min")
694                                  (smax "max")])
696 (define_code_attr     SMINMAX   [(smin "SMIN")
697                                  (smax "SMAX")])
699 ;; Iterator to optimize the following cases:
700 ;;      D-form load to FPR register & move to Altivec register
701 ;;      Move Altivec register to FPR register and store
702 (define_mode_iterator ALTIVEC_DFORM [DF
703                                      (SF "TARGET_P8_VECTOR")
704                                      (DI "TARGET_POWERPC64")])
707 ;; Start with fixed-point load and store insns.  Here we put only the more
708 ;; complex forms.  Basic data transfer is done later.
710 (define_insn "zero_extendqi<mode>2"
711   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
712         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
713   ""
714   "@
715    lbz%U1%X1 %0,%1
716    rlwinm %0,%1,0,0xff
717    lxsibzx %x0,%y1
718    vextractub %0,%1,7"
719   [(set_attr "type" "load,shift,fpload,vecperm")])
721 (define_insn_and_split "*zero_extendqi<mode>2_dot"
722   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
723         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
724                     (const_int 0)))
725    (clobber (match_scratch:EXTQI 0 "=r,r"))]
726   ""
727   "@
728    andi. %0,%1,0xff
729    #"
730   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
731   [(set (match_dup 0)
732         (zero_extend:EXTQI (match_dup 1)))
733    (set (match_dup 2)
734         (compare:CC (match_dup 0)
735                     (const_int 0)))]
736   ""
737   [(set_attr "type" "logical")
738    (set_attr "dot" "yes")
739    (set_attr "length" "4,8")])
741 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
742   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
743         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
744                     (const_int 0)))
745    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
746         (zero_extend:EXTQI (match_dup 1)))]
747   ""
748   "@
749    andi. %0,%1,0xff
750    #"
751   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
752   [(set (match_dup 0)
753         (zero_extend:EXTQI (match_dup 1)))
754    (set (match_dup 2)
755         (compare:CC (match_dup 0)
756                     (const_int 0)))]
757   ""
758   [(set_attr "type" "logical")
759    (set_attr "dot" "yes")
760    (set_attr "length" "4,8")])
763 (define_insn "zero_extendhi<mode>2"
764   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
765         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
766   ""
767   "@
768    lhz%U1%X1 %0,%1
769    rlwinm %0,%1,0,0xffff
770    lxsihzx %x0,%y1
771    vextractuh %0,%1,6"
772   [(set_attr "type" "load,shift,fpload,vecperm")])
774 (define_insn_and_split "*zero_extendhi<mode>2_dot"
775   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
776         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
777                     (const_int 0)))
778    (clobber (match_scratch:EXTHI 0 "=r,r"))]
779   ""
780   "@
781    andi. %0,%1,0xffff
782    #"
783   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
784   [(set (match_dup 0)
785         (zero_extend:EXTHI (match_dup 1)))
786    (set (match_dup 2)
787         (compare:CC (match_dup 0)
788                     (const_int 0)))]
789   ""
790   [(set_attr "type" "logical")
791    (set_attr "dot" "yes")
792    (set_attr "length" "4,8")])
794 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
795   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
796         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
797                     (const_int 0)))
798    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
799         (zero_extend:EXTHI (match_dup 1)))]
800   ""
801   "@
802    andi. %0,%1,0xffff
803    #"
804   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
805   [(set (match_dup 0)
806         (zero_extend:EXTHI (match_dup 1)))
807    (set (match_dup 2)
808         (compare:CC (match_dup 0)
809                     (const_int 0)))]
810   ""
811   [(set_attr "type" "logical")
812    (set_attr "dot" "yes")
813    (set_attr "length" "4,8")])
816 (define_insn "zero_extendsi<mode>2"
817   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
818         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
819   ""
820   "@
821    lwz%U1%X1 %0,%1
822    rldicl %0,%1,0,32
823    lfiwzx %0,%y1
824    lxsiwzx %x0,%y1
825    mtvsrwz %x0,%1
826    mfvsrwz %0,%x1
827    xxextractuw %x0,%x1,4"
828   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
830 (define_insn_and_split "*zero_extendsi<mode>2_dot"
831   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
832         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
833                     (const_int 0)))
834    (clobber (match_scratch:EXTSI 0 "=r,r"))]
835   ""
836   "@
837    rldicl. %0,%1,0,32
838    #"
839   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
840   [(set (match_dup 0)
841         (zero_extend:DI (match_dup 1)))
842    (set (match_dup 2)
843         (compare:CC (match_dup 0)
844                     (const_int 0)))]
845   ""
846   [(set_attr "type" "shift")
847    (set_attr "dot" "yes")
848    (set_attr "length" "4,8")])
850 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
851   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
852         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
853                     (const_int 0)))
854    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
855         (zero_extend:EXTSI (match_dup 1)))]
856   ""
857   "@
858    rldicl. %0,%1,0,32
859    #"
860   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
861   [(set (match_dup 0)
862         (zero_extend:EXTSI (match_dup 1)))
863    (set (match_dup 2)
864         (compare:CC (match_dup 0)
865                     (const_int 0)))]
866   ""
867   [(set_attr "type" "shift")
868    (set_attr "dot" "yes")
869    (set_attr "length" "4,8")])
872 (define_insn "extendqi<mode>2"
873   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
874         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
875   ""
876   "@
877    extsb %0,%1
878    vextsb2d %0,%1"
879   [(set_attr "type" "exts,vecperm")])
881 (define_insn_and_split "*extendqi<mode>2_dot"
882   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
883         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
884                     (const_int 0)))
885    (clobber (match_scratch:EXTQI 0 "=r,r"))]
886   ""
887   "@
888    extsb. %0,%1
889    #"
890   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
891   [(set (match_dup 0)
892         (sign_extend:EXTQI (match_dup 1)))
893    (set (match_dup 2)
894         (compare:CC (match_dup 0)
895                     (const_int 0)))]
896   ""
897   [(set_attr "type" "exts")
898    (set_attr "dot" "yes")
899    (set_attr "length" "4,8")])
901 (define_insn_and_split "*extendqi<mode>2_dot2"
902   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
903         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
904                     (const_int 0)))
905    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
906         (sign_extend:EXTQI (match_dup 1)))]
907   ""
908   "@
909    extsb. %0,%1
910    #"
911   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
912   [(set (match_dup 0)
913         (sign_extend:EXTQI (match_dup 1)))
914    (set (match_dup 2)
915         (compare:CC (match_dup 0)
916                     (const_int 0)))]
917   ""
918   [(set_attr "type" "exts")
919    (set_attr "dot" "yes")
920    (set_attr "length" "4,8")])
923 (define_expand "extendhi<mode>2"
924   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
925         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
926   ""
927   "")
929 (define_insn "*extendhi<mode>2"
930   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
931         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
932   ""
933   "@
934    lha%U1%X1 %0,%1
935    extsh %0,%1
936    #
937    vextsh2d %0,%1"
938   [(set_attr "type" "load,exts,fpload,vecperm")
939    (set_attr "sign_extend" "yes")
940    (set_attr "length" "4,4,8,4")])
942 (define_split
943   [(set (match_operand:EXTHI 0 "altivec_register_operand")
944         (sign_extend:EXTHI
945          (match_operand:HI 1 "indexed_or_indirect_operand")))]
946   "TARGET_P9_VECTOR && reload_completed"
947   [(set (match_dup 2)
948         (match_dup 1))
949    (set (match_dup 0)
950         (sign_extend:EXTHI (match_dup 2)))]
952   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
955 (define_insn_and_split "*extendhi<mode>2_dot"
956   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
957         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
958                     (const_int 0)))
959    (clobber (match_scratch:EXTHI 0 "=r,r"))]
960   ""
961   "@
962    extsh. %0,%1
963    #"
964   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
965   [(set (match_dup 0)
966         (sign_extend:EXTHI (match_dup 1)))
967    (set (match_dup 2)
968         (compare:CC (match_dup 0)
969                     (const_int 0)))]
970   ""
971   [(set_attr "type" "exts")
972    (set_attr "dot" "yes")
973    (set_attr "length" "4,8")])
975 (define_insn_and_split "*extendhi<mode>2_dot2"
976   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
977         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
978                     (const_int 0)))
979    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
980         (sign_extend:EXTHI (match_dup 1)))]
981   ""
982   "@
983    extsh. %0,%1
984    #"
985   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
986   [(set (match_dup 0)
987         (sign_extend:EXTHI (match_dup 1)))
988    (set (match_dup 2)
989         (compare:CC (match_dup 0)
990                     (const_int 0)))]
991   ""
992   [(set_attr "type" "exts")
993    (set_attr "dot" "yes")
994    (set_attr "length" "4,8")])
997 (define_insn "extendsi<mode>2"
998   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
999                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
1001         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1002                      "Y,  r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
1003   ""
1004   "@
1005    lwa%U1%X1 %0,%1
1006    extsw %0,%1
1007    lfiwax %0,%y1
1008    lxsiwax %x0,%y1
1009    mtvsrwa %x0,%1
1010    vextsw2d %0,%1
1011    #
1012    #"
1013   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1014    (set_attr "sign_extend" "yes")
1015    (set_attr "length" "4,4,4,4,4,4,8,8")])
1017 (define_split
1018   [(set (match_operand:EXTSI 0 "int_reg_operand")
1019         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1020   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1021   [(set (match_dup 2)
1022         (match_dup 1))
1023    (set (match_dup 0)
1024         (sign_extend:DI (match_dup 2)))]
1026   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1029 (define_split
1030   [(set (match_operand:DI 0 "altivec_register_operand")
1031         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1032   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1033   [(const_int 0)]
1035   rtx dest = operands[0];
1036   rtx src = operands[1];
1037   int dest_regno = REGNO (dest);
1038   int src_regno = REGNO (src);
1039   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1040   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1042   if (BYTES_BIG_ENDIAN)
1043     {
1044       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1045       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1046     }
1047   else
1048     {
1049       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1050       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1051     }
1052   DONE;
1055 (define_insn_and_split "*extendsi<mode>2_dot"
1056   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1057         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1058                     (const_int 0)))
1059    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1060   ""
1061   "@
1062    extsw. %0,%1
1063    #"
1064   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1065   [(set (match_dup 0)
1066         (sign_extend:EXTSI (match_dup 1)))
1067    (set (match_dup 2)
1068         (compare:CC (match_dup 0)
1069                     (const_int 0)))]
1070   ""
1071   [(set_attr "type" "exts")
1072    (set_attr "dot" "yes")
1073    (set_attr "length" "4,8")])
1075 (define_insn_and_split "*extendsi<mode>2_dot2"
1076   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1077         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1078                     (const_int 0)))
1079    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1080         (sign_extend:EXTSI (match_dup 1)))]
1081   ""
1082   "@
1083    extsw. %0,%1
1084    #"
1085   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1086   [(set (match_dup 0)
1087         (sign_extend:EXTSI (match_dup 1)))
1088    (set (match_dup 2)
1089         (compare:CC (match_dup 0)
1090                     (const_int 0)))]
1091   ""
1092   [(set_attr "type" "exts")
1093    (set_attr "dot" "yes")
1094    (set_attr "length" "4,8")])
1096 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1098 (define_insn "*macchwc"
1099   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1100         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1101                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1102                                        (const_int 16))
1103                                       (sign_extend:SI
1104                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1105                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1106                     (const_int 0)))
1107    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1108         (plus:SI (mult:SI (ashiftrt:SI
1109                            (match_dup 2)
1110                            (const_int 16))
1111                           (sign_extend:SI
1112                            (match_dup 1)))
1113                  (match_dup 4)))]
1114   "TARGET_MULHW"
1115   "macchw. %0,%1,%2"
1116   [(set_attr "type" "halfmul")])
1118 (define_insn "*macchw"
1119   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1120         (plus:SI (mult:SI (ashiftrt:SI
1121                            (match_operand:SI 2 "gpc_reg_operand" "r")
1122                            (const_int 16))
1123                           (sign_extend:SI
1124                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1125                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1126   "TARGET_MULHW"
1127   "macchw %0,%1,%2"
1128   [(set_attr "type" "halfmul")])
1130 (define_insn "*macchwuc"
1131   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1132         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1133                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1134                                        (const_int 16))
1135                                       (zero_extend:SI
1136                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1137                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1138                     (const_int 0)))
1139    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1140         (plus:SI (mult:SI (lshiftrt:SI
1141                            (match_dup 2)
1142                            (const_int 16))
1143                           (zero_extend:SI
1144                            (match_dup 1)))
1145                  (match_dup 4)))]
1146   "TARGET_MULHW"
1147   "macchwu. %0,%1,%2"
1148   [(set_attr "type" "halfmul")])
1150 (define_insn "*macchwu"
1151   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1152         (plus:SI (mult:SI (lshiftrt:SI
1153                            (match_operand:SI 2 "gpc_reg_operand" "r")
1154                            (const_int 16))
1155                           (zero_extend:SI
1156                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1157                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1158   "TARGET_MULHW"
1159   "macchwu %0,%1,%2"
1160   [(set_attr "type" "halfmul")])
1162 (define_insn "*machhwc"
1163   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1164         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1165                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1166                                        (const_int 16))
1167                                       (ashiftrt:SI
1168                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1169                                        (const_int 16)))
1170                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1171                     (const_int 0)))
1172    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1173         (plus:SI (mult:SI (ashiftrt:SI
1174                            (match_dup 1)
1175                            (const_int 16))
1176                           (ashiftrt:SI
1177                            (match_dup 2)
1178                            (const_int 16)))
1179                  (match_dup 4)))]
1180   "TARGET_MULHW"
1181   "machhw. %0,%1,%2"
1182   [(set_attr "type" "halfmul")])
1184 (define_insn "*machhw"
1185   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186         (plus:SI (mult:SI (ashiftrt:SI
1187                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1188                            (const_int 16))
1189                           (ashiftrt:SI
1190                            (match_operand:SI 2 "gpc_reg_operand" "r")
1191                            (const_int 16)))
1192                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1193   "TARGET_MULHW"
1194   "machhw %0,%1,%2"
1195   [(set_attr "type" "halfmul")])
1197 (define_insn "*machhwuc"
1198   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1199         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1200                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1201                                        (const_int 16))
1202                                       (lshiftrt:SI
1203                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1204                                        (const_int 16)))
1205                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1206                     (const_int 0)))
1207    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1208         (plus:SI (mult:SI (lshiftrt:SI
1209                            (match_dup 1)
1210                            (const_int 16))
1211                           (lshiftrt:SI
1212                            (match_dup 2)
1213                            (const_int 16)))
1214                  (match_dup 4)))]
1215   "TARGET_MULHW"
1216   "machhwu. %0,%1,%2"
1217   [(set_attr "type" "halfmul")])
1219 (define_insn "*machhwu"
1220   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1221         (plus:SI (mult:SI (lshiftrt:SI
1222                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1223                            (const_int 16))
1224                           (lshiftrt:SI
1225                            (match_operand:SI 2 "gpc_reg_operand" "r")
1226                            (const_int 16)))
1227                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1228   "TARGET_MULHW"
1229   "machhwu %0,%1,%2"
1230   [(set_attr "type" "halfmul")])
1232 (define_insn "*maclhwc"
1233   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1234         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1235                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1236                                       (sign_extend:SI
1237                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1238                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1239                     (const_int 0)))
1240    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1241         (plus:SI (mult:SI (sign_extend:SI
1242                            (match_dup 1))
1243                           (sign_extend:SI
1244                            (match_dup 2)))
1245                  (match_dup 4)))]
1246   "TARGET_MULHW"
1247   "maclhw. %0,%1,%2"
1248   [(set_attr "type" "halfmul")])
1250 (define_insn "*maclhw"
1251   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1252         (plus:SI (mult:SI (sign_extend:SI
1253                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1254                           (sign_extend:SI
1255                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1256                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1257   "TARGET_MULHW"
1258   "maclhw %0,%1,%2"
1259   [(set_attr "type" "halfmul")])
1261 (define_insn "*maclhwuc"
1262   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1263         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1264                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1265                                       (zero_extend:SI
1266                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1267                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1268                     (const_int 0)))
1269    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1270         (plus:SI (mult:SI (zero_extend:SI
1271                            (match_dup 1))
1272                           (zero_extend:SI
1273                            (match_dup 2)))
1274                  (match_dup 4)))]
1275   "TARGET_MULHW"
1276   "maclhwu. %0,%1,%2"
1277   [(set_attr "type" "halfmul")])
1279 (define_insn "*maclhwu"
1280   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1281         (plus:SI (mult:SI (zero_extend:SI
1282                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1283                           (zero_extend:SI
1284                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1285                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1286   "TARGET_MULHW"
1287   "maclhwu %0,%1,%2"
1288   [(set_attr "type" "halfmul")])
1290 (define_insn "*nmacchwc"
1291   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1292         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1293                               (mult:SI (ashiftrt:SI
1294                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1295                                         (const_int 16))
1296                                        (sign_extend:SI
1297                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1298                     (const_int 0)))
1299    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300         (minus:SI (match_dup 4)
1301                   (mult:SI (ashiftrt:SI
1302                             (match_dup 2)
1303                             (const_int 16))
1304                            (sign_extend:SI
1305                             (match_dup 1)))))]
1306   "TARGET_MULHW"
1307   "nmacchw. %0,%1,%2"
1308   [(set_attr "type" "halfmul")])
1310 (define_insn "*nmacchw"
1311   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1312         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1313                   (mult:SI (ashiftrt:SI
1314                             (match_operand:SI 2 "gpc_reg_operand" "r")
1315                             (const_int 16))
1316                            (sign_extend:SI
1317                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1318   "TARGET_MULHW"
1319   "nmacchw %0,%1,%2"
1320   [(set_attr "type" "halfmul")])
1322 (define_insn "*nmachhwc"
1323   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1324         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1325                               (mult:SI (ashiftrt:SI
1326                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1327                                         (const_int 16))
1328                                        (ashiftrt:SI
1329                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1330                                         (const_int 16))))
1331                     (const_int 0)))
1332    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1333         (minus:SI (match_dup 4)
1334                   (mult:SI (ashiftrt:SI
1335                             (match_dup 1)
1336                             (const_int 16))
1337                            (ashiftrt:SI
1338                             (match_dup 2)
1339                             (const_int 16)))))]
1340   "TARGET_MULHW"
1341   "nmachhw. %0,%1,%2"
1342   [(set_attr "type" "halfmul")])
1344 (define_insn "*nmachhw"
1345   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1346         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1347                   (mult:SI (ashiftrt:SI
1348                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1349                             (const_int 16))
1350                            (ashiftrt:SI
1351                             (match_operand:SI 2 "gpc_reg_operand" "r")
1352                             (const_int 16)))))]
1353   "TARGET_MULHW"
1354   "nmachhw %0,%1,%2"
1355   [(set_attr "type" "halfmul")])
1357 (define_insn "*nmaclhwc"
1358   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1359         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1360                               (mult:SI (sign_extend:SI
1361                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1362                                        (sign_extend:SI
1363                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1364                     (const_int 0)))
1365    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1366         (minus:SI (match_dup 4)
1367                   (mult:SI (sign_extend:SI
1368                             (match_dup 1))
1369                            (sign_extend:SI
1370                             (match_dup 2)))))]
1371   "TARGET_MULHW"
1372   "nmaclhw. %0,%1,%2"
1373   [(set_attr "type" "halfmul")])
1375 (define_insn "*nmaclhw"
1376   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1378                   (mult:SI (sign_extend:SI
1379                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1380                            (sign_extend:SI
1381                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1382   "TARGET_MULHW"
1383   "nmaclhw %0,%1,%2"
1384   [(set_attr "type" "halfmul")])
1386 (define_insn "*mulchwc"
1387   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1388         (compare:CC (mult:SI (ashiftrt:SI
1389                               (match_operand:SI 2 "gpc_reg_operand" "r")
1390                               (const_int 16))
1391                              (sign_extend:SI
1392                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1393                     (const_int 0)))
1394    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1395         (mult:SI (ashiftrt:SI
1396                   (match_dup 2)
1397                   (const_int 16))
1398                  (sign_extend:SI
1399                   (match_dup 1))))]
1400   "TARGET_MULHW"
1401   "mulchw. %0,%1,%2"
1402   [(set_attr "type" "halfmul")])
1404 (define_insn "*mulchw"
1405   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1406         (mult:SI (ashiftrt:SI
1407                   (match_operand:SI 2 "gpc_reg_operand" "r")
1408                   (const_int 16))
1409                  (sign_extend:SI
1410                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1411   "TARGET_MULHW"
1412   "mulchw %0,%1,%2"
1413   [(set_attr "type" "halfmul")])
1415 (define_insn "*mulchwuc"
1416   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1417         (compare:CC (mult:SI (lshiftrt:SI
1418                               (match_operand:SI 2 "gpc_reg_operand" "r")
1419                               (const_int 16))
1420                              (zero_extend:SI
1421                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1422                     (const_int 0)))
1423    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424         (mult:SI (lshiftrt:SI
1425                   (match_dup 2)
1426                   (const_int 16))
1427                  (zero_extend:SI
1428                   (match_dup 1))))]
1429   "TARGET_MULHW"
1430   "mulchwu. %0,%1,%2"
1431   [(set_attr "type" "halfmul")])
1433 (define_insn "*mulchwu"
1434   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1435         (mult:SI (lshiftrt:SI
1436                   (match_operand:SI 2 "gpc_reg_operand" "r")
1437                   (const_int 16))
1438                  (zero_extend:SI
1439                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1440   "TARGET_MULHW"
1441   "mulchwu %0,%1,%2"
1442   [(set_attr "type" "halfmul")])
1444 (define_insn "*mulhhwc"
1445   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1446         (compare:CC (mult:SI (ashiftrt:SI
1447                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1448                               (const_int 16))
1449                              (ashiftrt:SI
1450                               (match_operand:SI 2 "gpc_reg_operand" "r")
1451                               (const_int 16)))
1452                     (const_int 0)))
1453    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454         (mult:SI (ashiftrt:SI
1455                   (match_dup 1)
1456                   (const_int 16))
1457                  (ashiftrt:SI
1458                   (match_dup 2)
1459                   (const_int 16))))]
1460   "TARGET_MULHW"
1461   "mulhhw. %0,%1,%2"
1462   [(set_attr "type" "halfmul")])
1464 (define_insn "*mulhhw"
1465   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1466         (mult:SI (ashiftrt:SI
1467                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1468                   (const_int 16))
1469                  (ashiftrt:SI
1470                   (match_operand:SI 2 "gpc_reg_operand" "r")
1471                   (const_int 16))))]
1472   "TARGET_MULHW"
1473   "mulhhw %0,%1,%2"
1474   [(set_attr "type" "halfmul")])
1476 (define_insn "*mulhhwuc"
1477   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1478         (compare:CC (mult:SI (lshiftrt:SI
1479                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1480                               (const_int 16))
1481                              (lshiftrt:SI
1482                               (match_operand:SI 2 "gpc_reg_operand" "r")
1483                               (const_int 16)))
1484                     (const_int 0)))
1485    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1486         (mult:SI (lshiftrt:SI
1487                   (match_dup 1)
1488                   (const_int 16))
1489                  (lshiftrt:SI
1490                   (match_dup 2)
1491                   (const_int 16))))]
1492   "TARGET_MULHW"
1493   "mulhhwu. %0,%1,%2"
1494   [(set_attr "type" "halfmul")])
1496 (define_insn "*mulhhwu"
1497   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1498         (mult:SI (lshiftrt:SI
1499                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1500                   (const_int 16))
1501                  (lshiftrt:SI
1502                   (match_operand:SI 2 "gpc_reg_operand" "r")
1503                   (const_int 16))))]
1504   "TARGET_MULHW"
1505   "mulhhwu %0,%1,%2"
1506   [(set_attr "type" "halfmul")])
1508 (define_insn "*mullhwc"
1509   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1510         (compare:CC (mult:SI (sign_extend:SI
1511                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1512                              (sign_extend:SI
1513                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1514                     (const_int 0)))
1515    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1516         (mult:SI (sign_extend:SI
1517                   (match_dup 1))
1518                  (sign_extend:SI
1519                   (match_dup 2))))]
1520   "TARGET_MULHW"
1521   "mullhw. %0,%1,%2"
1522   [(set_attr "type" "halfmul")])
1524 (define_insn "*mullhw"
1525   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526         (mult:SI (sign_extend:SI
1527                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1528                  (sign_extend:SI
1529                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1530   "TARGET_MULHW"
1531   "mullhw %0,%1,%2"
1532   [(set_attr "type" "halfmul")])
1534 (define_insn "*mullhwuc"
1535   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1536         (compare:CC (mult:SI (zero_extend:SI
1537                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1538                              (zero_extend:SI
1539                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1540                     (const_int 0)))
1541    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1542         (mult:SI (zero_extend:SI
1543                   (match_dup 1))
1544                  (zero_extend:SI
1545                   (match_dup 2))))]
1546   "TARGET_MULHW"
1547   "mullhwu. %0,%1,%2"
1548   [(set_attr "type" "halfmul")])
1550 (define_insn "*mullhwu"
1551   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1552         (mult:SI (zero_extend:SI
1553                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1554                  (zero_extend:SI
1555                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1556   "TARGET_MULHW"
1557   "mullhwu %0,%1,%2"
1558   [(set_attr "type" "halfmul")])
1560 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1561 (define_insn "dlmzb"
1562   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1563         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1564                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1565                    UNSPEC_DLMZB_CR))
1566    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1567         (unspec:SI [(match_dup 1)
1568                     (match_dup 2)]
1569                    UNSPEC_DLMZB))]
1570   "TARGET_DLMZB"
1571   "dlmzb. %0,%1,%2")
1573 (define_expand "strlensi"
1574   [(set (match_operand:SI 0 "gpc_reg_operand")
1575         (unspec:SI [(match_operand:BLK 1 "general_operand")
1576                     (match_operand:QI 2 "const_int_operand")
1577                     (match_operand 3 "const_int_operand")]
1578                    UNSPEC_DLMZB_STRLEN))
1579    (clobber (match_scratch:CC 4))]
1580   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1582   rtx result = operands[0];
1583   rtx src = operands[1];
1584   rtx search_char = operands[2];
1585   rtx align = operands[3];
1586   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1587   rtx loop_label, end_label, mem, cr0, cond;
1588   if (search_char != const0_rtx
1589       || GET_CODE (align) != CONST_INT
1590       || INTVAL (align) < 8)
1591         FAIL;
1592   word1 = gen_reg_rtx (SImode);
1593   word2 = gen_reg_rtx (SImode);
1594   scratch_dlmzb = gen_reg_rtx (SImode);
1595   scratch_string = gen_reg_rtx (Pmode);
1596   loop_label = gen_label_rtx ();
1597   end_label = gen_label_rtx ();
1598   addr = force_reg (Pmode, XEXP (src, 0));
1599   emit_move_insn (scratch_string, addr);
1600   emit_label (loop_label);
1601   mem = change_address (src, SImode, scratch_string);
1602   emit_move_insn (word1, mem);
1603   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1604   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1605   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1606   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1607   emit_jump_insn (gen_rtx_SET (pc_rtx,
1608                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1609                                                      cond,
1610                                                      gen_rtx_LABEL_REF
1611                                                        (VOIDmode,
1612                                                         end_label),
1613                                                      pc_rtx)));
1614   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1615   emit_jump_insn (gen_rtx_SET (pc_rtx,
1616                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1617   emit_barrier ();
1618   emit_label (end_label);
1619   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1620   emit_insn (gen_subsi3 (result, scratch_string, addr));
1621   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1622   DONE;
1625 ;; Fixed-point arithmetic insns.
1627 (define_expand "add<mode>3"
1628   [(set (match_operand:SDI 0 "gpc_reg_operand")
1629         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1630                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1631   ""
1633   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1634     {
1635       rtx lo0 = gen_lowpart (SImode, operands[0]);
1636       rtx lo1 = gen_lowpart (SImode, operands[1]);
1637       rtx lo2 = gen_lowpart (SImode, operands[2]);
1638       rtx hi0 = gen_highpart (SImode, operands[0]);
1639       rtx hi1 = gen_highpart (SImode, operands[1]);
1640       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1642       if (!reg_or_short_operand (lo2, SImode))
1643         lo2 = force_reg (SImode, lo2);
1644       if (!adde_operand (hi2, SImode))
1645         hi2 = force_reg (SImode, hi2);
1647       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1648       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1649       DONE;
1650     }
1652   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1653     {
1654       rtx tmp = ((!can_create_pseudo_p ()
1655                   || rtx_equal_p (operands[0], operands[1]))
1656                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1658       /* Adding a constant to r0 is not a valid insn, so use a different
1659          strategy in that case.  */
1660       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1661         {
1662           if (operands[0] == operands[1])
1663             FAIL;
1664           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1665           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1666           DONE;
1667         }
1669       HOST_WIDE_INT val = INTVAL (operands[2]);
1670       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1671       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1673       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1674         FAIL;
1676       /* The ordering here is important for the prolog expander.
1677          When space is allocated from the stack, adding 'low' first may
1678          produce a temporary deallocation (which would be bad).  */
1679       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1680       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1681       DONE;
1682     }
1685 (define_insn "*add<mode>3"
1686   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1687         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1688                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1689   ""
1690   "@
1691    add %0,%1,%2
1692    addi %0,%1,%2
1693    addis %0,%1,%v2"
1694   [(set_attr "type" "add")])
1696 (define_insn "addsi3_high"
1697   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1698         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1699                  (high:SI (match_operand 2 "" ""))))]
1700   "TARGET_MACHO && !TARGET_64BIT"
1701   "addis %0,%1,ha16(%2)"
1702   [(set_attr "type" "add")])
1704 (define_insn_and_split "*add<mode>3_dot"
1705   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1706         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1707                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1708                     (const_int 0)))
1709    (clobber (match_scratch:GPR 0 "=r,r"))]
1710   "<MODE>mode == Pmode"
1711   "@
1712    add. %0,%1,%2
1713    #"
1714   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1715   [(set (match_dup 0)
1716         (plus:GPR (match_dup 1)
1717                  (match_dup 2)))
1718    (set (match_dup 3)
1719         (compare:CC (match_dup 0)
1720                     (const_int 0)))]
1721   ""
1722   [(set_attr "type" "add")
1723    (set_attr "dot" "yes")
1724    (set_attr "length" "4,8")])
1726 (define_insn_and_split "*add<mode>3_dot2"
1727   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1728         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1729                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1730                     (const_int 0)))
1731    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1732         (plus:GPR (match_dup 1)
1733                   (match_dup 2)))]
1734   "<MODE>mode == Pmode"
1735   "@
1736    add. %0,%1,%2
1737    #"
1738   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1739   [(set (match_dup 0)
1740         (plus:GPR (match_dup 1)
1741                   (match_dup 2)))
1742    (set (match_dup 3)
1743         (compare:CC (match_dup 0)
1744                     (const_int 0)))]
1745   ""
1746   [(set_attr "type" "add")
1747    (set_attr "dot" "yes")
1748    (set_attr "length" "4,8")])
1750 (define_insn_and_split "*add<mode>3_imm_dot"
1751   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1752         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1753                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1754                     (const_int 0)))
1755    (clobber (match_scratch:GPR 0 "=r,r"))
1756    (clobber (reg:GPR CA_REGNO))]
1757   "<MODE>mode == Pmode"
1758   "@
1759    addic. %0,%1,%2
1760    #"
1761   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1762   [(set (match_dup 0)
1763         (plus:GPR (match_dup 1)
1764                   (match_dup 2)))
1765    (set (match_dup 3)
1766         (compare:CC (match_dup 0)
1767                     (const_int 0)))]
1768   ""
1769   [(set_attr "type" "add")
1770    (set_attr "dot" "yes")
1771    (set_attr "length" "4,8")])
1773 (define_insn_and_split "*add<mode>3_imm_dot2"
1774   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1775         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1776                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1777                     (const_int 0)))
1778    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1779         (plus:GPR (match_dup 1)
1780                   (match_dup 2)))
1781    (clobber (reg:GPR CA_REGNO))]
1782   "<MODE>mode == Pmode"
1783   "@
1784    addic. %0,%1,%2
1785    #"
1786   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1787   [(set (match_dup 0)
1788         (plus:GPR (match_dup 1)
1789                   (match_dup 2)))
1790    (set (match_dup 3)
1791         (compare:CC (match_dup 0)
1792                     (const_int 0)))]
1793   ""
1794   [(set_attr "type" "add")
1795    (set_attr "dot" "yes")
1796    (set_attr "length" "4,8")])
1798 ;; Split an add that we can't do in one insn into two insns, each of which
1799 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1800 ;; add should be last in case the result gets used in an address.
1802 (define_split
1803   [(set (match_operand:GPR 0 "gpc_reg_operand")
1804         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1805                   (match_operand:GPR 2 "non_add_cint_operand")))]
1806   ""
1807   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1808    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1810   HOST_WIDE_INT val = INTVAL (operands[2]);
1811   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1812   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1814   operands[4] = GEN_INT (low);
1815   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1816     operands[3] = GEN_INT (rest);
1817   else if (can_create_pseudo_p ())
1818     {
1819       operands[3] = gen_reg_rtx (DImode);
1820       emit_move_insn (operands[3], operands[2]);
1821       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1822       DONE;
1823     }
1824   else
1825     FAIL;
1829 (define_insn "add<mode>3_carry"
1830   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1831         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1832                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1833    (set (reg:P CA_REGNO)
1834         (ltu:P (plus:P (match_dup 1)
1835                        (match_dup 2))
1836                (match_dup 1)))]
1837   ""
1838   "add%I2c %0,%1,%2"
1839   [(set_attr "type" "add")])
1841 (define_insn "*add<mode>3_imm_carry_pos"
1842   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1843         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1844                 (match_operand:P 2 "short_cint_operand" "n")))
1845    (set (reg:P CA_REGNO)
1846         (geu:P (match_dup 1)
1847                (match_operand:P 3 "const_int_operand" "n")))]
1848   "INTVAL (operands[2]) > 0
1849    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1850   "addic %0,%1,%2"
1851   [(set_attr "type" "add")])
1853 (define_insn "*add<mode>3_imm_carry_0"
1854   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1855         (match_operand:P 1 "gpc_reg_operand" "r"))
1856    (set (reg:P CA_REGNO)
1857         (const_int 0))]
1858   ""
1859   "addic %0,%1,0"
1860   [(set_attr "type" "add")])
1862 (define_insn "*add<mode>3_imm_carry_m1"
1863   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1864         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1865                 (const_int -1)))
1866    (set (reg:P CA_REGNO)
1867         (ne:P (match_dup 1)
1868               (const_int 0)))]
1869   ""
1870   "addic %0,%1,-1"
1871   [(set_attr "type" "add")])
1873 (define_insn "*add<mode>3_imm_carry_neg"
1874   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1875         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1876                 (match_operand:P 2 "short_cint_operand" "n")))
1877    (set (reg:P CA_REGNO)
1878         (gtu:P (match_dup 1)
1879                (match_operand:P 3 "const_int_operand" "n")))]
1880   "INTVAL (operands[2]) < 0
1881    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1882   "addic %0,%1,%2"
1883   [(set_attr "type" "add")])
1886 (define_expand "add<mode>3_carry_in"
1887   [(parallel [
1888      (set (match_operand:GPR 0 "gpc_reg_operand")
1889           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1890                               (match_operand:GPR 2 "adde_operand"))
1891                     (reg:GPR CA_REGNO)))
1892      (clobber (reg:GPR CA_REGNO))])]
1893   ""
1895   if (operands[2] == const0_rtx)
1896     {
1897       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1898       DONE;
1899     }
1900   if (operands[2] == constm1_rtx)
1901     {
1902       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1903       DONE;
1904     }
1907 (define_insn "*add<mode>3_carry_in_internal"
1908   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1909         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1910                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1911                   (reg:GPR CA_REGNO)))
1912    (clobber (reg:GPR CA_REGNO))]
1913   ""
1914   "adde %0,%1,%2"
1915   [(set_attr "type" "add")])
1917 (define_insn "*add<mode>3_carry_in_internal2"
1918   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1919         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1920                             (reg:GPR CA_REGNO))
1921                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1922    (clobber (reg:GPR CA_REGNO))]
1923   ""
1924   "adde %0,%1,%2"
1925   [(set_attr "type" "add")])
1927 (define_insn "add<mode>3_carry_in_0"
1928   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1929         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1930                   (reg:GPR CA_REGNO)))
1931    (clobber (reg:GPR CA_REGNO))]
1932   ""
1933   "addze %0,%1"
1934   [(set_attr "type" "add")])
1936 (define_insn "add<mode>3_carry_in_m1"
1937   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1938         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1939                             (reg:GPR CA_REGNO))
1940                   (const_int -1)))
1941    (clobber (reg:GPR CA_REGNO))]
1942   ""
1943   "addme %0,%1"
1944   [(set_attr "type" "add")])
1947 (define_expand "one_cmpl<mode>2"
1948   [(set (match_operand:SDI 0 "gpc_reg_operand")
1949         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1950   ""
1952   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1953     {
1954       rs6000_split_logical (operands, NOT, false, false, false);
1955       DONE;
1956     }
1959 (define_insn "*one_cmpl<mode>2"
1960   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1961         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1962   ""
1963   "not %0,%1")
1965 (define_insn_and_split "*one_cmpl<mode>2_dot"
1966   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1967         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1968                     (const_int 0)))
1969    (clobber (match_scratch:GPR 0 "=r,r"))]
1970   "<MODE>mode == Pmode"
1971   "@
1972    not. %0,%1
1973    #"
1974   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1975   [(set (match_dup 0)
1976         (not:GPR (match_dup 1)))
1977    (set (match_dup 2)
1978         (compare:CC (match_dup 0)
1979                     (const_int 0)))]
1980   ""
1981   [(set_attr "type" "logical")
1982    (set_attr "dot" "yes")
1983    (set_attr "length" "4,8")])
1985 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1986   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1987         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1988                     (const_int 0)))
1989    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1990         (not:GPR (match_dup 1)))]
1991   "<MODE>mode == Pmode"
1992   "@
1993    not. %0,%1
1994    #"
1995   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1996   [(set (match_dup 0)
1997         (not:GPR (match_dup 1)))
1998    (set (match_dup 2)
1999         (compare:CC (match_dup 0)
2000                     (const_int 0)))]
2001   ""
2002   [(set_attr "type" "logical")
2003    (set_attr "dot" "yes")
2004    (set_attr "length" "4,8")])
2007 (define_expand "sub<mode>3"
2008   [(set (match_operand:SDI 0 "gpc_reg_operand")
2009         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2010                    (match_operand:SDI 2 "gpc_reg_operand")))]
2011   ""
2013   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2014     {
2015       rtx lo0 = gen_lowpart (SImode, operands[0]);
2016       rtx lo1 = gen_lowpart (SImode, operands[1]);
2017       rtx lo2 = gen_lowpart (SImode, operands[2]);
2018       rtx hi0 = gen_highpart (SImode, operands[0]);
2019       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2020       rtx hi2 = gen_highpart (SImode, operands[2]);
2022       if (!reg_or_short_operand (lo1, SImode))
2023         lo1 = force_reg (SImode, lo1);
2024       if (!adde_operand (hi1, SImode))
2025         hi1 = force_reg (SImode, hi1);
2027       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2028       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2029       DONE;
2030     }
2032   if (short_cint_operand (operands[1], <MODE>mode))
2033     {
2034       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2035       DONE;
2036     }
2039 (define_insn "*subf<mode>3"
2040   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2041         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2042                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2043   ""
2044   "subf %0,%1,%2"
2045   [(set_attr "type" "add")])
2047 (define_insn_and_split "*subf<mode>3_dot"
2048   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2049         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2050                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2051                     (const_int 0)))
2052    (clobber (match_scratch:GPR 0 "=r,r"))]
2053   "<MODE>mode == Pmode"
2054   "@
2055    subf. %0,%1,%2
2056    #"
2057   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2058   [(set (match_dup 0)
2059         (minus:GPR (match_dup 2)
2060                    (match_dup 1)))
2061    (set (match_dup 3)
2062         (compare:CC (match_dup 0)
2063                     (const_int 0)))]
2064   ""
2065   [(set_attr "type" "add")
2066    (set_attr "dot" "yes")
2067    (set_attr "length" "4,8")])
2069 (define_insn_and_split "*subf<mode>3_dot2"
2070   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2071         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2072                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2073                     (const_int 0)))
2074    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2075         (minus:GPR (match_dup 2)
2076                    (match_dup 1)))]
2077   "<MODE>mode == Pmode"
2078   "@
2079    subf. %0,%1,%2
2080    #"
2081   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2082   [(set (match_dup 0)
2083         (minus:GPR (match_dup 2)
2084                    (match_dup 1)))
2085    (set (match_dup 3)
2086         (compare:CC (match_dup 0)
2087                     (const_int 0)))]
2088   ""
2089   [(set_attr "type" "add")
2090    (set_attr "dot" "yes")
2091    (set_attr "length" "4,8")])
2093 (define_insn "subf<mode>3_imm"
2094   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2095         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2096                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2097    (clobber (reg:GPR CA_REGNO))]
2098   ""
2099   "subfic %0,%1,%2"
2100   [(set_attr "type" "add")])
2102 (define_insn_and_split "subf<mode>3_carry_dot2"
2103   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2104         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2105                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2106                     (const_int 0)))
2107    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2108         (minus:P (match_dup 2)
2109                    (match_dup 1)))
2110    (set (reg:P CA_REGNO)
2111         (leu:P (match_dup 1)
2112                (match_dup 2)))]
2113   "<MODE>mode == Pmode"
2114   "@
2115    subfc. %0,%1,%2
2116    #"
2117   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2118   [(parallel [(set (match_dup 0)
2119                    (minus:P (match_dup 2)
2120                             (match_dup 1)))
2121               (set (reg:P CA_REGNO)
2122                    (leu:P (match_dup 1)
2123                           (match_dup 2)))])
2124    (set (match_dup 3)
2125         (compare:CC (match_dup 0)
2126                     (const_int 0)))]
2127   ""
2128   [(set_attr "type" "add")
2129    (set_attr "dot" "yes")
2130    (set_attr "length" "4,8")])
2132 (define_insn "subf<mode>3_carry"
2133   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2134         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2135                  (match_operand:P 1 "gpc_reg_operand" "r")))
2136    (set (reg:P CA_REGNO)
2137         (leu:P (match_dup 1)
2138                (match_dup 2)))]
2139   ""
2140   "subf%I2c %0,%1,%2"
2141   [(set_attr "type" "add")])
2143 (define_insn "*subf<mode>3_imm_carry_0"
2144   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2145         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2146    (set (reg:P CA_REGNO)
2147         (eq:P (match_dup 1)
2148               (const_int 0)))]
2149   ""
2150   "subfic %0,%1,0"
2151   [(set_attr "type" "add")])
2153 (define_insn "*subf<mode>3_imm_carry_m1"
2154   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2155         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2156    (set (reg:P CA_REGNO)
2157         (const_int 1))]
2158   ""
2159   "subfic %0,%1,-1"
2160   [(set_attr "type" "add")])
2163 (define_expand "subf<mode>3_carry_in"
2164   [(parallel [
2165      (set (match_operand:GPR 0 "gpc_reg_operand")
2166           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2167                               (reg:GPR CA_REGNO))
2168                     (match_operand:GPR 2 "adde_operand")))
2169      (clobber (reg:GPR CA_REGNO))])]
2170   ""
2172   if (operands[2] == const0_rtx)
2173     {
2174       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2175       DONE;
2176     }
2177   if (operands[2] == constm1_rtx)
2178     {
2179       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2180       DONE;
2181     }
2184 (define_insn "*subf<mode>3_carry_in_internal"
2185   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2186         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2187                             (reg:GPR CA_REGNO))
2188                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2189    (clobber (reg:GPR CA_REGNO))]
2190   ""
2191   "subfe %0,%1,%2"
2192   [(set_attr "type" "add")])
2194 (define_insn "subf<mode>3_carry_in_0"
2195   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2196         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2197                   (reg:GPR CA_REGNO)))
2198    (clobber (reg:GPR CA_REGNO))]
2199   ""
2200   "subfze %0,%1"
2201   [(set_attr "type" "add")])
2203 (define_insn "subf<mode>3_carry_in_m1"
2204   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2205         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2206                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2207                   (const_int -2)))
2208    (clobber (reg:GPR CA_REGNO))]
2209   ""
2210   "subfme %0,%1"
2211   [(set_attr "type" "add")])
2213 (define_insn "subf<mode>3_carry_in_xx"
2214   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2215         (plus:GPR (reg:GPR CA_REGNO)
2216                   (const_int -1)))
2217    (clobber (reg:GPR CA_REGNO))]
2218   ""
2219   "subfe %0,%0,%0"
2220   [(set_attr "type" "add")])
2223 (define_insn "neg<mode>2"
2224   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2226   ""
2227   "neg %0,%1"
2228   [(set_attr "type" "add")])
2230 (define_insn_and_split "*neg<mode>2_dot"
2231   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2232         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2233                     (const_int 0)))
2234    (clobber (match_scratch:GPR 0 "=r,r"))]
2235   "<MODE>mode == Pmode"
2236   "@
2237    neg. %0,%1
2238    #"
2239   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2240   [(set (match_dup 0)
2241         (neg:GPR (match_dup 1)))
2242    (set (match_dup 2)
2243         (compare:CC (match_dup 0)
2244                     (const_int 0)))]
2245   ""
2246   [(set_attr "type" "add")
2247    (set_attr "dot" "yes")
2248    (set_attr "length" "4,8")])
2250 (define_insn_and_split "*neg<mode>2_dot2"
2251   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2252         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2253                     (const_int 0)))
2254    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2255         (neg:GPR (match_dup 1)))]
2256   "<MODE>mode == Pmode"
2257   "@
2258    neg. %0,%1
2259    #"
2260   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2261   [(set (match_dup 0)
2262         (neg:GPR (match_dup 1)))
2263    (set (match_dup 2)
2264         (compare:CC (match_dup 0)
2265                     (const_int 0)))]
2266   ""
2267   [(set_attr "type" "add")
2268    (set_attr "dot" "yes")
2269    (set_attr "length" "4,8")])
2272 (define_insn "clz<mode>2"
2273   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2274         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2275   ""
2276   "cntlz<wd> %0,%1"
2277   [(set_attr "type" "cntlz")])
2279 (define_expand "ctz<mode>2"
2280    [(set (match_operand:GPR 0 "gpc_reg_operand")
2281          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2282   ""
2284   if (TARGET_CTZ)
2285     {
2286       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2287       DONE;
2288     }
2290   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2291   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2292   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2294   if (TARGET_POPCNTD)
2295     {
2296       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2297       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2298       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2299       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2300     }
2301   else
2302     {
2303       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2304       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2305       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2306       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2307     }
2309   DONE;
2312 (define_insn "ctz<mode>2_hw"
2313   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2314         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2315   "TARGET_CTZ"
2316   "cnttz<wd> %0,%1"
2317   [(set_attr "type" "cntlz")])
2319 (define_expand "ffs<mode>2"
2320   [(set (match_operand:GPR 0 "gpc_reg_operand")
2321         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2322   ""
2324   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2325   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2326   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2327   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2328   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2329   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2330   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2331   DONE;
2335 (define_expand "popcount<mode>2"
2336   [(set (match_operand:GPR 0 "gpc_reg_operand")
2337         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2338   "TARGET_POPCNTB || TARGET_POPCNTD"
2340   rs6000_emit_popcount (operands[0], operands[1]);
2341   DONE;
2344 (define_insn "popcntb<mode>2"
2345   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2346         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2347                     UNSPEC_POPCNTB))]
2348   "TARGET_POPCNTB"
2349   "popcntb %0,%1"
2350   [(set_attr "type" "popcnt")])
2352 (define_insn "popcntd<mode>2"
2353   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2354         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2355   "TARGET_POPCNTD"
2356   "popcnt<wd> %0,%1"
2357   [(set_attr "type" "popcnt")])
2360 (define_expand "parity<mode>2"
2361   [(set (match_operand:GPR 0 "gpc_reg_operand")
2362         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2363   "TARGET_POPCNTB"
2365   rs6000_emit_parity (operands[0], operands[1]);
2366   DONE;
2369 (define_insn "parity<mode>2_cmpb"
2370   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2371         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2372   "TARGET_CMPB && TARGET_POPCNTB"
2373   "prty<wd> %0,%1"
2374   [(set_attr "type" "popcnt")])
2376 (define_insn "cmpb<mode>3"
2377   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2378         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2379                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2380   "TARGET_CMPB"
2381   "cmpb %0,%1,%2"
2382   [(set_attr "type" "cmp")])
2384 ;; Since the hardware zeros the upper part of the register, save generating the
2385 ;; AND immediate if we are converting to unsigned
2386 (define_insn "*bswap<mode>2_extenddi"
2387   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2388         (zero_extend:DI
2389          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2390   "TARGET_POWERPC64"
2391   "l<wd>brx %0,%y1"
2392   [(set_attr "length" "4")
2393    (set_attr "type" "load")])
2395 (define_insn "*bswaphi2_extendsi"
2396   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2397         (zero_extend:SI
2398          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2399   ""
2400   "lhbrx %0,%y1"
2401   [(set_attr "length" "4")
2402    (set_attr "type" "load")])
2404 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2405 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2406 ;; load with byte swap, which can be slower than doing it in the registers.  It
2407 ;; also prevents certain failures with the RELOAD register allocator.
2409 (define_expand "bswap<mode>2"
2410   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2411    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2412   ""
2414   rtx dest = operands[0];
2415   rtx src = operands[1];
2417   if (!REG_P (dest) && !REG_P (src))
2418     src = force_reg (<MODE>mode, src);
2420   if (MEM_P (src))
2421     emit_insn (gen_bswap<mode>2_load (dest, src));
2422   else if (MEM_P (dest))
2423     emit_insn (gen_bswap<mode>2_store (dest, src));
2424   else
2425     emit_insn (gen_bswap<mode>2_reg (dest, src));
2426   DONE;
2429 (define_insn "bswap<mode>2_load"
2430   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2431         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2432   ""
2433   "l<wd>brx %0,%y1"
2434   [(set_attr "type" "load")])
2436 (define_insn "bswap<mode>2_store"
2437   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2438         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2439   ""
2440   "st<wd>brx %1,%y0"
2441   [(set_attr "type" "store")])
2443 (define_insn_and_split "bswaphi2_reg"
2444   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2445         (bswap:HI
2446          (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2447    (clobber (match_scratch:SI 2 "=&r,X"))]
2448   ""
2449   "@
2450    #
2451    xxbrh %x0,%x1"
2452   "reload_completed && int_reg_operand (operands[0], HImode)"
2453   [(set (match_dup 3)
2454         (and:SI (lshiftrt:SI (match_dup 4)
2455                              (const_int 8))
2456                 (const_int 255)))
2457    (set (match_dup 2)
2458         (and:SI (ashift:SI (match_dup 4)
2459                            (const_int 8))
2460                 (const_int 65280)))             ;; 0xff00
2461    (set (match_dup 3)
2462         (ior:SI (match_dup 3)
2463                 (match_dup 2)))]
2465   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2466   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2468   [(set_attr "length" "12,4")
2469    (set_attr "type" "*,vecperm")])
2471 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2472 ;; zero_extract insns do not change for -mlittle.
2473 (define_insn_and_split "bswapsi2_reg"
2474   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2475         (bswap:SI
2476          (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2477   ""
2478   "@
2479    #
2480    xxbrw %x0,%x1"
2481   "reload_completed && int_reg_operand (operands[0], SImode)"
2482   [(set (match_dup 0)                                   ; DABC
2483         (rotate:SI (match_dup 1)
2484                    (const_int 24)))
2485    (set (match_dup 0)                                   ; DCBC
2486         (ior:SI (and:SI (ashift:SI (match_dup 1)
2487                                    (const_int 8))
2488                         (const_int 16711680))
2489                 (and:SI (match_dup 0)
2490                         (const_int -16711681))))
2491    (set (match_dup 0)                                   ; DCBA
2492         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2493                                      (const_int 24))
2494                         (const_int 255))
2495                 (and:SI (match_dup 0)
2496                         (const_int -256))))]
2497   ""
2498   [(set_attr "length" "12,4")
2499    (set_attr "type" "*,vecperm")])
2501 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2502 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2503 ;; complex code.
2505 (define_expand "bswapdi2"
2506   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2507                    (bswap:DI
2508                     (match_operand:DI 1 "reg_or_mem_operand")))
2509               (clobber (match_scratch:DI 2))
2510               (clobber (match_scratch:DI 3))])]
2511   ""
2513   rtx dest = operands[0];
2514   rtx src = operands[1];
2516   if (!REG_P (dest) && !REG_P (src))
2517     operands[1] = src = force_reg (DImode, src);
2519   if (TARGET_POWERPC64 && TARGET_LDBRX)
2520     {
2521       if (MEM_P (src))
2522         emit_insn (gen_bswapdi2_load (dest, src));
2523       else if (MEM_P (dest))
2524         emit_insn (gen_bswapdi2_store (dest, src));
2525       else if (TARGET_P9_VECTOR)
2526         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2527       else
2528         emit_insn (gen_bswapdi2_reg (dest, src));
2529       DONE;
2530     }
2532   if (!TARGET_POWERPC64)
2533     {
2534       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2535          that uses 64-bit registers needs the same scratch registers as 64-bit
2536          mode.  */
2537       emit_insn (gen_bswapdi2_32bit (dest, src));
2538       DONE;
2539     }
2542 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2543 (define_insn "bswapdi2_load"
2544   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2545         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2546   "TARGET_POWERPC64 && TARGET_LDBRX"
2547   "ldbrx %0,%y1"
2548   [(set_attr "type" "load")])
2550 (define_insn "bswapdi2_store"
2551   [(set (match_operand:DI 0 "memory_operand" "=Z")
2552         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2553   "TARGET_POWERPC64 && TARGET_LDBRX"
2554   "stdbrx %1,%y0"
2555   [(set_attr "type" "store")])
2557 (define_insn "bswapdi2_xxbrd"
2558   [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2559         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2560   "TARGET_P9_VECTOR"
2561   "xxbrd %x0,%x1"
2562   [(set_attr "type" "vecperm")])
2564 (define_insn "bswapdi2_reg"
2565   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2566         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2567    (clobber (match_scratch:DI 2 "=&r"))
2568    (clobber (match_scratch:DI 3 "=&r"))]
2569   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2570   "#"
2571   [(set_attr "length" "36")])
2573 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2574 (define_insn "*bswapdi2_64bit"
2575   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2576         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2577    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2578    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2579   "TARGET_POWERPC64 && !TARGET_LDBRX
2580    && (REG_P (operands[0]) || REG_P (operands[1]))
2581    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2582    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2583   "#"
2584   [(set_attr "length" "16,12,36")])
2586 (define_split
2587   [(set (match_operand:DI 0 "gpc_reg_operand")
2588         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2589    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2590    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2591   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2592   [(const_int 0)]
2594   rtx dest   = operands[0];
2595   rtx src    = operands[1];
2596   rtx op2    = operands[2];
2597   rtx op3    = operands[3];
2598   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2599                                     BYTES_BIG_ENDIAN ? 4 : 0);
2600   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2601                                      BYTES_BIG_ENDIAN ? 4 : 0);
2602   rtx addr1;
2603   rtx addr2;
2604   rtx word1;
2605   rtx word2;
2607   addr1 = XEXP (src, 0);
2608   if (GET_CODE (addr1) == PLUS)
2609     {
2610       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2611       if (TARGET_AVOID_XFORM)
2612         {
2613           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2614           addr2 = op2;
2615         }
2616       else
2617         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2618     }
2619   else if (TARGET_AVOID_XFORM)
2620     {
2621       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2622       addr2 = op2;
2623     }
2624   else
2625     {
2626       emit_move_insn (op2, GEN_INT (4));
2627       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2628     }
2630   word1 = change_address (src, SImode, addr1);
2631   word2 = change_address (src, SImode, addr2);
2633   if (BYTES_BIG_ENDIAN)
2634     {
2635       emit_insn (gen_bswapsi2 (op3_32, word2));
2636       emit_insn (gen_bswapsi2 (dest_32, word1));
2637     }
2638   else
2639     {
2640       emit_insn (gen_bswapsi2 (op3_32, word1));
2641       emit_insn (gen_bswapsi2 (dest_32, word2));
2642     }
2644   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2645   emit_insn (gen_iordi3 (dest, dest, op3));
2646   DONE;
2649 (define_split
2650   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2651         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2652    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2653    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2654   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2655   [(const_int 0)]
2657   rtx dest   = operands[0];
2658   rtx src    = operands[1];
2659   rtx op2    = operands[2];
2660   rtx op3    = operands[3];
2661   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2662                                     BYTES_BIG_ENDIAN ? 4 : 0);
2663   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2664                                     BYTES_BIG_ENDIAN ? 4 : 0);
2665   rtx addr1;
2666   rtx addr2;
2667   rtx word1;
2668   rtx word2;
2670   addr1 = XEXP (dest, 0);
2671   if (GET_CODE (addr1) == PLUS)
2672     {
2673       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2674       if (TARGET_AVOID_XFORM)
2675         {
2676           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2677           addr2 = op2;
2678         }
2679       else
2680         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2681     }
2682   else if (TARGET_AVOID_XFORM)
2683     {
2684       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2685       addr2 = op2;
2686     }
2687   else
2688     {
2689       emit_move_insn (op2, GEN_INT (4));
2690       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2691     }
2693   word1 = change_address (dest, SImode, addr1);
2694   word2 = change_address (dest, SImode, addr2);
2696   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2698   if (BYTES_BIG_ENDIAN)
2699     {
2700       emit_insn (gen_bswapsi2 (word1, src_si));
2701       emit_insn (gen_bswapsi2 (word2, op3_si));
2702     }
2703   else
2704     {
2705       emit_insn (gen_bswapsi2 (word2, src_si));
2706       emit_insn (gen_bswapsi2 (word1, op3_si));
2707     }
2708   DONE;
2711 (define_split
2712   [(set (match_operand:DI 0 "gpc_reg_operand")
2713         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2714    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2715    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2716   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2717   [(const_int 0)]
2719   rtx dest    = operands[0];
2720   rtx src     = operands[1];
2721   rtx op2     = operands[2];
2722   rtx op3     = operands[3];
2723   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2724   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2725   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2726   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2727   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2729   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2730   emit_insn (gen_bswapsi2 (dest_si, src_si));
2731   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2732   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2733   emit_insn (gen_iordi3 (dest, dest, op3));
2734   DONE;
2737 (define_insn "bswapdi2_32bit"
2738   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2739         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2740    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2741   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2742   "#"
2743   [(set_attr "length" "16,12,36")])
2745 (define_split
2746   [(set (match_operand:DI 0 "gpc_reg_operand")
2747         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2748    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2749   "!TARGET_POWERPC64 && reload_completed"
2750   [(const_int 0)]
2752   rtx dest  = operands[0];
2753   rtx src   = operands[1];
2754   rtx op2   = operands[2];
2755   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2756   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2757   rtx addr1;
2758   rtx addr2;
2759   rtx word1;
2760   rtx word2;
2762   addr1 = XEXP (src, 0);
2763   if (GET_CODE (addr1) == PLUS)
2764     {
2765       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2766       if (TARGET_AVOID_XFORM
2767           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2768         {
2769           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2770           addr2 = op2;
2771         }
2772       else
2773         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2774     }
2775   else if (TARGET_AVOID_XFORM
2776            || REGNO (addr1) == REGNO (dest2))
2777     {
2778       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2779       addr2 = op2;
2780     }
2781   else
2782     {
2783       emit_move_insn (op2, GEN_INT (4));
2784       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2785     }
2787   word1 = change_address (src, SImode, addr1);
2788   word2 = change_address (src, SImode, addr2);
2790   emit_insn (gen_bswapsi2 (dest2, word1));
2791   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2792      thus allowing us to omit an early clobber on the output.  */
2793   emit_insn (gen_bswapsi2 (dest1, word2));
2794   DONE;
2797 (define_split
2798   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2799         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2800    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2801   "!TARGET_POWERPC64 && reload_completed"
2802   [(const_int 0)]
2804   rtx dest = operands[0];
2805   rtx src  = operands[1];
2806   rtx op2  = operands[2];
2807   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2808   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2809   rtx addr1;
2810   rtx addr2;
2811   rtx word1;
2812   rtx word2;
2814   addr1 = XEXP (dest, 0);
2815   if (GET_CODE (addr1) == PLUS)
2816     {
2817       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2818       if (TARGET_AVOID_XFORM)
2819         {
2820           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2821           addr2 = op2;
2822         }
2823       else
2824         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2825     }
2826   else if (TARGET_AVOID_XFORM)
2827     {
2828       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2829       addr2 = op2;
2830     }
2831   else
2832     {
2833       emit_move_insn (op2, GEN_INT (4));
2834       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2835     }
2837   word1 = change_address (dest, SImode, addr1);
2838   word2 = change_address (dest, SImode, addr2);
2840   emit_insn (gen_bswapsi2 (word2, src1));
2841   emit_insn (gen_bswapsi2 (word1, src2));
2842   DONE;
2845 (define_split
2846   [(set (match_operand:DI 0 "gpc_reg_operand")
2847         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2848    (clobber (match_operand:SI 2 ""))]
2849   "!TARGET_POWERPC64 && reload_completed"
2850   [(const_int 0)]
2852   rtx dest  = operands[0];
2853   rtx src   = operands[1];
2854   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2855   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2856   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2857   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2859   emit_insn (gen_bswapsi2 (dest1, src2));
2860   emit_insn (gen_bswapsi2 (dest2, src1));
2861   DONE;
2865 (define_insn "mul<mode>3"
2866   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2867         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2868                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2869   ""
2870   "@
2871    mull<wd> %0,%1,%2
2872    mulli %0,%1,%2"
2873    [(set_attr "type" "mul")
2874     (set (attr "size")
2875       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2876                 (const_string "8")
2877              (match_operand:GPR 2 "short_cint_operand")
2878                 (const_string "16")]
2879         (const_string "<bits>")))])
2881 (define_insn_and_split "*mul<mode>3_dot"
2882   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2883         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2884                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2885                     (const_int 0)))
2886    (clobber (match_scratch:GPR 0 "=r,r"))]
2887   "<MODE>mode == Pmode"
2888   "@
2889    mull<wd>. %0,%1,%2
2890    #"
2891   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2892   [(set (match_dup 0)
2893         (mult:GPR (match_dup 1)
2894                   (match_dup 2)))
2895    (set (match_dup 3)
2896         (compare:CC (match_dup 0)
2897                     (const_int 0)))]
2898   ""
2899   [(set_attr "type" "mul")
2900    (set_attr "size" "<bits>")
2901    (set_attr "dot" "yes")
2902    (set_attr "length" "4,8")])
2904 (define_insn_and_split "*mul<mode>3_dot2"
2905   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2906         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2907                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2908                     (const_int 0)))
2909    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2910         (mult:GPR (match_dup 1)
2911                   (match_dup 2)))]
2912   "<MODE>mode == Pmode"
2913   "@
2914    mull<wd>. %0,%1,%2
2915    #"
2916   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2917   [(set (match_dup 0)
2918         (mult:GPR (match_dup 1)
2919                   (match_dup 2)))
2920    (set (match_dup 3)
2921         (compare:CC (match_dup 0)
2922                     (const_int 0)))]
2923   ""
2924   [(set_attr "type" "mul")
2925    (set_attr "size" "<bits>")
2926    (set_attr "dot" "yes")
2927    (set_attr "length" "4,8")])
2930 (define_expand "<su>mul<mode>3_highpart"
2931   [(set (match_operand:GPR 0 "gpc_reg_operand")
2932         (subreg:GPR
2933           (mult:<DMODE> (any_extend:<DMODE>
2934                           (match_operand:GPR 1 "gpc_reg_operand"))
2935                         (any_extend:<DMODE>
2936                           (match_operand:GPR 2 "gpc_reg_operand")))
2937          0))]
2938   ""
2940   if (<MODE>mode == SImode && TARGET_POWERPC64)
2941     {
2942       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2943                                              operands[2]));
2944       DONE;
2945     }
2947   if (!WORDS_BIG_ENDIAN)
2948     {
2949       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2950                                                  operands[2]));
2951       DONE;
2952     }
2955 (define_insn "*<su>mul<mode>3_highpart"
2956   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2957         (subreg:GPR
2958           (mult:<DMODE> (any_extend:<DMODE>
2959                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2960                         (any_extend:<DMODE>
2961                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2962          0))]
2963   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2964   "mulh<wd><u> %0,%1,%2"
2965   [(set_attr "type" "mul")
2966    (set_attr "size" "<bits>")])
2968 (define_insn "<su>mulsi3_highpart_le"
2969   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2970         (subreg:SI
2971           (mult:DI (any_extend:DI
2972                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2973                    (any_extend:DI
2974                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2975          4))]
2976   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2977   "mulhw<u> %0,%1,%2"
2978   [(set_attr "type" "mul")])
2980 (define_insn "<su>muldi3_highpart_le"
2981   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2982         (subreg:DI
2983           (mult:TI (any_extend:TI
2984                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2985                    (any_extend:TI
2986                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2987          8))]
2988   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2989   "mulhd<u> %0,%1,%2"
2990   [(set_attr "type" "mul")
2991    (set_attr "size" "64")])
2993 (define_insn "<su>mulsi3_highpart_64"
2994   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2995         (truncate:SI
2996           (lshiftrt:DI
2997             (mult:DI (any_extend:DI
2998                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2999                      (any_extend:DI
3000                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3001             (const_int 32))))]
3002   "TARGET_POWERPC64"
3003   "mulhw<u> %0,%1,%2"
3004   [(set_attr "type" "mul")])
3006 (define_expand "<u>mul<mode><dmode>3"
3007   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3008         (mult:<DMODE> (any_extend:<DMODE>
3009                         (match_operand:GPR 1 "gpc_reg_operand"))
3010                       (any_extend:<DMODE>
3011                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3012   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3014   rtx l = gen_reg_rtx (<MODE>mode);
3015   rtx h = gen_reg_rtx (<MODE>mode);
3016   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3017   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3018   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3019   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3020   DONE;
3023 (define_insn "*maddld4"
3024   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3025         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3026                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3027                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3028   "TARGET_MADDLD"
3029   "maddld %0,%1,%2,%3"
3030   [(set_attr "type" "mul")])
3032 (define_insn "udiv<mode>3"
3033   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3034         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3035                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3036   ""
3037   "div<wd>u %0,%1,%2"
3038   [(set_attr "type" "div")
3039    (set_attr "size" "<bits>")])
3042 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3043 ;; modulus.  If it isn't a power of two, force operands into register and do
3044 ;; a normal divide.
3045 (define_expand "div<mode>3"
3046   [(set (match_operand:GPR 0 "gpc_reg_operand")
3047         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3048                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3049   ""
3051   if (CONST_INT_P (operands[2])
3052       && INTVAL (operands[2]) > 0
3053       && exact_log2 (INTVAL (operands[2])) >= 0)
3054     {
3055       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3056       DONE;
3057     }
3059   operands[2] = force_reg (<MODE>mode, operands[2]);
3062 (define_insn "*div<mode>3"
3063   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3064         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3065                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3066   ""
3067   "div<wd> %0,%1,%2"
3068   [(set_attr "type" "div")
3069    (set_attr "size" "<bits>")])
3071 (define_insn "div<mode>3_sra"
3072   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3073         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3074                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3075    (clobber (reg:GPR CA_REGNO))]
3076   ""
3077   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3078   [(set_attr "type" "two")
3079    (set_attr "length" "8")])
3081 (define_insn_and_split "*div<mode>3_sra_dot"
3082   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3083         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3084                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3085                     (const_int 0)))
3086    (clobber (match_scratch:GPR 0 "=r,r"))
3087    (clobber (reg:GPR CA_REGNO))]
3088   "<MODE>mode == Pmode"
3089   "@
3090    sra<wd>i %0,%1,%p2\;addze. %0,%0
3091    #"
3092   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3093   [(parallel [(set (match_dup 0)
3094                    (div:GPR (match_dup 1)
3095                             (match_dup 2)))
3096               (clobber (reg:GPR CA_REGNO))])
3097    (set (match_dup 3)
3098         (compare:CC (match_dup 0)
3099                     (const_int 0)))]
3100   ""
3101   [(set_attr "type" "two")
3102    (set_attr "length" "8,12")
3103    (set_attr "cell_micro" "not")])
3105 (define_insn_and_split "*div<mode>3_sra_dot2"
3106   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3107         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3108                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3109                     (const_int 0)))
3110    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3111         (div:GPR (match_dup 1)
3112                  (match_dup 2)))
3113    (clobber (reg:GPR CA_REGNO))]
3114   "<MODE>mode == Pmode"
3115   "@
3116    sra<wd>i %0,%1,%p2\;addze. %0,%0
3117    #"
3118   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3119   [(parallel [(set (match_dup 0)
3120                    (div:GPR (match_dup 1)
3121                             (match_dup 2)))
3122               (clobber (reg:GPR CA_REGNO))])
3123    (set (match_dup 3)
3124         (compare:CC (match_dup 0)
3125                     (const_int 0)))]
3126   ""
3127   [(set_attr "type" "two")
3128    (set_attr "length" "8,12")
3129    (set_attr "cell_micro" "not")])
3131 (define_expand "mod<mode>3"
3132   [(set (match_operand:GPR 0 "gpc_reg_operand")
3133         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3134                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3135   ""
3137   int i;
3138   rtx temp1;
3139   rtx temp2;
3141   if (GET_CODE (operands[2]) != CONST_INT
3142       || INTVAL (operands[2]) <= 0
3143       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3144     {
3145       if (!TARGET_MODULO)
3146         FAIL;
3148       operands[2] = force_reg (<MODE>mode, operands[2]);
3149     }
3150   else
3151     {
3152       temp1 = gen_reg_rtx (<MODE>mode);
3153       temp2 = gen_reg_rtx (<MODE>mode);
3155       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3156       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3157       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3158       DONE;
3159     }
3162 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3163 ;; mod, prefer putting the result of mod into a different register
3164 (define_insn "*mod<mode>3"
3165   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3166         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3167                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3168   "TARGET_MODULO"
3169   "mods<wd> %0,%1,%2"
3170   [(set_attr "type" "div")
3171    (set_attr "size" "<bits>")])
3174 (define_insn "umod<mode>3"
3175   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3176         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3177                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3178   "TARGET_MODULO"
3179   "modu<wd> %0,%1,%2"
3180   [(set_attr "type" "div")
3181    (set_attr "size" "<bits>")])
3183 ;; On machines with modulo support, do a combined div/mod the old fashioned
3184 ;; method, since the multiply/subtract is faster than doing the mod instruction
3185 ;; after a divide.
3187 (define_peephole2
3188   [(set (match_operand:GPR 0 "gpc_reg_operand")
3189         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3190                  (match_operand:GPR 2 "gpc_reg_operand")))
3191    (set (match_operand:GPR 3 "gpc_reg_operand")
3192         (mod:GPR (match_dup 1)
3193                  (match_dup 2)))]
3194   "TARGET_MODULO
3195    && ! reg_mentioned_p (operands[0], operands[1])
3196    && ! reg_mentioned_p (operands[0], operands[2])
3197    && ! reg_mentioned_p (operands[3], operands[1])
3198    && ! reg_mentioned_p (operands[3], operands[2])"
3199   [(set (match_dup 0)
3200         (div:GPR (match_dup 1)
3201                  (match_dup 2)))
3202    (set (match_dup 3)
3203         (mult:GPR (match_dup 0)
3204                   (match_dup 2)))
3205    (set (match_dup 3)
3206         (minus:GPR (match_dup 1)
3207                    (match_dup 3)))])
3209 (define_peephole2
3210   [(set (match_operand:GPR 0 "gpc_reg_operand")
3211         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3212                   (match_operand:GPR 2 "gpc_reg_operand")))
3213    (set (match_operand:GPR 3 "gpc_reg_operand")
3214         (umod:GPR (match_dup 1)
3215                   (match_dup 2)))]
3216   "TARGET_MODULO
3217    && ! reg_mentioned_p (operands[0], operands[1])
3218    && ! reg_mentioned_p (operands[0], operands[2])
3219    && ! reg_mentioned_p (operands[3], operands[1])
3220    && ! reg_mentioned_p (operands[3], operands[2])"
3221   [(set (match_dup 0)
3222         (udiv:GPR (match_dup 1)
3223                   (match_dup 2)))
3224    (set (match_dup 3)
3225         (mult:GPR (match_dup 0)
3226                   (match_dup 2)))
3227    (set (match_dup 3)
3228         (minus:GPR (match_dup 1)
3229                    (match_dup 3)))])
3232 ;; Logical instructions
3233 ;; The logical instructions are mostly combined by using match_operator,
3234 ;; but the plain AND insns are somewhat different because there is no
3235 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3236 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3238 (define_expand "and<mode>3"
3239   [(set (match_operand:SDI 0 "gpc_reg_operand")
3240         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3241                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3242   ""
3244   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3245     {
3246       rs6000_split_logical (operands, AND, false, false, false);
3247       DONE;
3248     }
3250   if (CONST_INT_P (operands[2]))
3251     {
3252       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3253         {
3254           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3255           DONE;
3256         }
3258       if (logical_const_operand (operands[2], <MODE>mode))
3259         {
3260           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3261           DONE;
3262         }
3264       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3265         {
3266           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3267           DONE;
3268         }
3270       operands[2] = force_reg (<MODE>mode, operands[2]);
3271     }
3275 (define_insn "and<mode>3_imm"
3276   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3277         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3278                  (match_operand:GPR 2 "logical_const_operand" "n")))
3279    (clobber (match_scratch:CC 3 "=x"))]
3280   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3281   "andi%e2. %0,%1,%u2"
3282   [(set_attr "type" "logical")
3283    (set_attr "dot" "yes")])
3285 (define_insn_and_split "*and<mode>3_imm_dot"
3286   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3287         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3288                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3289                     (const_int 0)))
3290    (clobber (match_scratch:GPR 0 "=r,r"))
3291    (clobber (match_scratch:CC 4 "=X,x"))]
3292   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3293    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3294   "@
3295    andi%e2. %0,%1,%u2
3296    #"
3297   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3298   [(parallel [(set (match_dup 0)
3299                    (and:GPR (match_dup 1)
3300                             (match_dup 2)))
3301               (clobber (match_dup 4))])
3302    (set (match_dup 3)
3303         (compare:CC (match_dup 0)
3304                     (const_int 0)))]
3305   ""
3306   [(set_attr "type" "logical")
3307    (set_attr "dot" "yes")
3308    (set_attr "length" "4,8")])
3310 (define_insn_and_split "*and<mode>3_imm_dot2"
3311   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3312         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3313                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3314                     (const_int 0)))
3315    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3316         (and:GPR (match_dup 1)
3317                  (match_dup 2)))
3318    (clobber (match_scratch:CC 4 "=X,x"))]
3319   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3320    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3321   "@
3322    andi%e2. %0,%1,%u2
3323    #"
3324   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3325   [(parallel [(set (match_dup 0)
3326                    (and:GPR (match_dup 1)
3327                             (match_dup 2)))
3328               (clobber (match_dup 4))])
3329    (set (match_dup 3)
3330         (compare:CC (match_dup 0)
3331                     (const_int 0)))]
3332   ""
3333   [(set_attr "type" "logical")
3334    (set_attr "dot" "yes")
3335    (set_attr "length" "4,8")])
3337 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3338   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3339         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3340                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3341                     (const_int 0)))
3342    (clobber (match_scratch:GPR 0 "=r,r"))]
3343   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3344    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3345   "@
3346    andi%e2. %0,%1,%u2
3347    #"
3348   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3349   [(set (match_dup 0)
3350         (and:GPR (match_dup 1)
3351                  (match_dup 2)))
3352    (set (match_dup 3)
3353         (compare:CC (match_dup 0)
3354                     (const_int 0)))]
3355   ""
3356   [(set_attr "type" "logical")
3357    (set_attr "dot" "yes")
3358    (set_attr "length" "4,8")])
3360 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3361   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3362         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3363                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3364                     (const_int 0)))
3365    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3366         (and:GPR (match_dup 1)
3367                  (match_dup 2)))]
3368   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3369    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3370   "@
3371    andi%e2. %0,%1,%u2
3372    #"
3373   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3374   [(set (match_dup 0)
3375         (and:GPR (match_dup 1)
3376                  (match_dup 2)))
3377    (set (match_dup 3)
3378         (compare:CC (match_dup 0)
3379                     (const_int 0)))]
3380   ""
3381   [(set_attr "type" "logical")
3382    (set_attr "dot" "yes")
3383    (set_attr "length" "4,8")])
3385 (define_insn "*and<mode>3_imm_dot_shifted"
3386   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3387         (compare:CC
3388           (and:GPR
3389             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3390                           (match_operand:SI 4 "const_int_operand" "n"))
3391             (match_operand:GPR 2 "const_int_operand" "n"))
3392           (const_int 0)))
3393    (clobber (match_scratch:GPR 0 "=r"))]
3394   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3395                                    << INTVAL (operands[4])),
3396                           DImode)
3397    && (<MODE>mode == Pmode
3398        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3400   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3401   return "andi%e2. %0,%1,%u2";
3403   [(set_attr "type" "logical")
3404    (set_attr "dot" "yes")])
3407 (define_insn "and<mode>3_mask"
3408   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3409         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3410                  (match_operand:GPR 2 "const_int_operand" "n")))]
3411   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3413   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3415   [(set_attr "type" "shift")])
3417 (define_insn_and_split "*and<mode>3_mask_dot"
3418   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3419         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3420                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3421                     (const_int 0)))
3422    (clobber (match_scratch:GPR 0 "=r,r"))]
3423   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3424    && !logical_const_operand (operands[2], <MODE>mode)
3425    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3427   if (which_alternative == 0)
3428     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3429   else
3430     return "#";
3432   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3433   [(set (match_dup 0)
3434         (and:GPR (match_dup 1)
3435                  (match_dup 2)))
3436    (set (match_dup 3)
3437         (compare:CC (match_dup 0)
3438                     (const_int 0)))]
3439   ""
3440   [(set_attr "type" "shift")
3441    (set_attr "dot" "yes")
3442    (set_attr "length" "4,8")])
3444 (define_insn_and_split "*and<mode>3_mask_dot2"
3445   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3446         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3447                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3448                     (const_int 0)))
3449    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3450         (and:GPR (match_dup 1)
3451                  (match_dup 2)))]
3452   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3453    && !logical_const_operand (operands[2], <MODE>mode)
3454    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3456   if (which_alternative == 0)
3457     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3458   else
3459     return "#";
3461   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3462   [(set (match_dup 0)
3463         (and:GPR (match_dup 1)
3464                  (match_dup 2)))
3465    (set (match_dup 3)
3466         (compare:CC (match_dup 0)
3467                     (const_int 0)))]
3468   ""
3469   [(set_attr "type" "shift")
3470    (set_attr "dot" "yes")
3471    (set_attr "length" "4,8")])
3474 (define_insn_and_split "*and<mode>3_2insn"
3475   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3476         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3477                  (match_operand:GPR 2 "const_int_operand" "n")))]
3478   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3479    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3480         || logical_const_operand (operands[2], <MODE>mode))"
3481   "#"
3482   "&& 1"
3483   [(pc)]
3485   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3486   DONE;
3488   [(set_attr "type" "shift")
3489    (set_attr "length" "8")])
3491 (define_insn_and_split "*and<mode>3_2insn_dot"
3492   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3493         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3494                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3495                     (const_int 0)))
3496    (clobber (match_scratch:GPR 0 "=r,r"))]
3497   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3498    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3499    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3500         || logical_const_operand (operands[2], <MODE>mode))"
3501   "#"
3502   "&& reload_completed"
3503   [(pc)]
3505   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3506   DONE;
3508   [(set_attr "type" "shift")
3509    (set_attr "dot" "yes")
3510    (set_attr "length" "8,12")])
3512 (define_insn_and_split "*and<mode>3_2insn_dot2"
3513   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3514         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3515                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3516                     (const_int 0)))
3517    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3518         (and:GPR (match_dup 1)
3519                  (match_dup 2)))]
3520   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3521    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3522    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3523         || logical_const_operand (operands[2], <MODE>mode))"
3524   "#"
3525   "&& reload_completed"
3526   [(pc)]
3528   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3529   DONE;
3531   [(set_attr "type" "shift")
3532    (set_attr "dot" "yes")
3533    (set_attr "length" "8,12")])
3536 (define_expand "<code><mode>3"
3537   [(set (match_operand:SDI 0 "gpc_reg_operand")
3538         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3539                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3540   ""
3542   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3543     {
3544       rs6000_split_logical (operands, <CODE>, false, false, false);
3545       DONE;
3546     }
3548   if (non_logical_cint_operand (operands[2], <MODE>mode))
3549     {
3550       rtx tmp = ((!can_create_pseudo_p ()
3551                   || rtx_equal_p (operands[0], operands[1]))
3552                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3554       HOST_WIDE_INT value = INTVAL (operands[2]);
3555       HOST_WIDE_INT lo = value & 0xffff;
3556       HOST_WIDE_INT hi = value - lo;
3558       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3559       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3560       DONE;
3561     }
3563   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3564     operands[2] = force_reg (<MODE>mode, operands[2]);
3567 (define_split
3568   [(set (match_operand:GPR 0 "gpc_reg_operand")
3569         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3570                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3571   ""
3572   [(set (match_dup 3)
3573         (iorxor:GPR (match_dup 1)
3574                     (match_dup 4)))
3575    (set (match_dup 0)
3576         (iorxor:GPR (match_dup 3)
3577                     (match_dup 5)))]
3579   operands[3] = ((!can_create_pseudo_p ()
3580                   || rtx_equal_p (operands[0], operands[1]))
3581                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3583   HOST_WIDE_INT value = INTVAL (operands[2]);
3584   HOST_WIDE_INT lo = value & 0xffff;
3585   HOST_WIDE_INT hi = value - lo;
3587   operands[4] = GEN_INT (hi);
3588   operands[5] = GEN_INT (lo);
3591 (define_insn "*bool<mode>3_imm"
3592   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3593         (match_operator:GPR 3 "boolean_or_operator"
3594          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3595           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3596   ""
3597   "%q3i%e2 %0,%1,%u2"
3598   [(set_attr "type" "logical")])
3600 (define_insn "*bool<mode>3"
3601   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3602         (match_operator:GPR 3 "boolean_operator"
3603          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3604           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3605   ""
3606   "%q3 %0,%1,%2"
3607   [(set_attr "type" "logical")])
3609 (define_insn_and_split "*bool<mode>3_dot"
3610   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3611         (compare:CC (match_operator:GPR 3 "boolean_operator"
3612          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3613           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3614          (const_int 0)))
3615    (clobber (match_scratch:GPR 0 "=r,r"))]
3616   "<MODE>mode == Pmode"
3617   "@
3618    %q3. %0,%1,%2
3619    #"
3620   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3621   [(set (match_dup 0)
3622         (match_dup 3))
3623    (set (match_dup 4)
3624         (compare:CC (match_dup 0)
3625                     (const_int 0)))]
3626   ""
3627   [(set_attr "type" "logical")
3628    (set_attr "dot" "yes")
3629    (set_attr "length" "4,8")])
3631 (define_insn_and_split "*bool<mode>3_dot2"
3632   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3633         (compare:CC (match_operator:GPR 3 "boolean_operator"
3634          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3635           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3636          (const_int 0)))
3637    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3638         (match_dup 3))]
3639   "<MODE>mode == Pmode"
3640   "@
3641    %q3. %0,%1,%2
3642    #"
3643   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3644   [(set (match_dup 0)
3645         (match_dup 3))
3646    (set (match_dup 4)
3647         (compare:CC (match_dup 0)
3648                     (const_int 0)))]
3649   ""
3650   [(set_attr "type" "logical")
3651    (set_attr "dot" "yes")
3652    (set_attr "length" "4,8")])
3655 (define_insn "*boolc<mode>3"
3656   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3657         (match_operator:GPR 3 "boolean_operator"
3658          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3659           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3660   ""
3661   "%q3 %0,%1,%2"
3662   [(set_attr "type" "logical")])
3664 (define_insn_and_split "*boolc<mode>3_dot"
3665   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3666         (compare:CC (match_operator:GPR 3 "boolean_operator"
3667          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3668           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3669          (const_int 0)))
3670    (clobber (match_scratch:GPR 0 "=r,r"))]
3671   "<MODE>mode == Pmode"
3672   "@
3673    %q3. %0,%1,%2
3674    #"
3675   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3676   [(set (match_dup 0)
3677         (match_dup 3))
3678    (set (match_dup 4)
3679         (compare:CC (match_dup 0)
3680                     (const_int 0)))]
3681   ""
3682   [(set_attr "type" "logical")
3683    (set_attr "dot" "yes")
3684    (set_attr "length" "4,8")])
3686 (define_insn_and_split "*boolc<mode>3_dot2"
3687   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3688         (compare:CC (match_operator:GPR 3 "boolean_operator"
3689          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3690           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3691          (const_int 0)))
3692    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3693         (match_dup 3))]
3694   "<MODE>mode == Pmode"
3695   "@
3696    %q3. %0,%1,%2
3697    #"
3698   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3699   [(set (match_dup 0)
3700         (match_dup 3))
3701    (set (match_dup 4)
3702         (compare:CC (match_dup 0)
3703                     (const_int 0)))]
3704   ""
3705   [(set_attr "type" "logical")
3706    (set_attr "dot" "yes")
3707    (set_attr "length" "4,8")])
3710 (define_insn "*boolcc<mode>3"
3711   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3712         (match_operator:GPR 3 "boolean_operator"
3713          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3714           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3715   ""
3716   "%q3 %0,%1,%2"
3717   [(set_attr "type" "logical")])
3719 (define_insn_and_split "*boolcc<mode>3_dot"
3720   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3721         (compare:CC (match_operator:GPR 3 "boolean_operator"
3722          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3723           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3724          (const_int 0)))
3725    (clobber (match_scratch:GPR 0 "=r,r"))]
3726   "<MODE>mode == Pmode"
3727   "@
3728    %q3. %0,%1,%2
3729    #"
3730   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3731   [(set (match_dup 0)
3732         (match_dup 3))
3733    (set (match_dup 4)
3734         (compare:CC (match_dup 0)
3735                     (const_int 0)))]
3736   ""
3737   [(set_attr "type" "logical")
3738    (set_attr "dot" "yes")
3739    (set_attr "length" "4,8")])
3741 (define_insn_and_split "*boolcc<mode>3_dot2"
3742   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3743         (compare:CC (match_operator:GPR 3 "boolean_operator"
3744          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3745           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3746          (const_int 0)))
3747    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3748         (match_dup 3))]
3749   "<MODE>mode == Pmode"
3750   "@
3751    %q3. %0,%1,%2
3752    #"
3753   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3754   [(set (match_dup 0)
3755         (match_dup 3))
3756    (set (match_dup 4)
3757         (compare:CC (match_dup 0)
3758                     (const_int 0)))]
3759   ""
3760   [(set_attr "type" "logical")
3761    (set_attr "dot" "yes")
3762    (set_attr "length" "4,8")])
3765 ;; TODO: Should have dots of this as well.
3766 (define_insn "*eqv<mode>3"
3767   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3768         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3769                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3770   ""
3771   "eqv %0,%1,%2"
3772   [(set_attr "type" "logical")])
3774 ;; Rotate-and-mask and insert.
3776 (define_insn "*rotl<mode>3_mask"
3777   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3778         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3779                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3780                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3781                  (match_operand:GPR 3 "const_int_operand" "n")))]
3782   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3784   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3786   [(set_attr "type" "shift")
3787    (set_attr "maybe_var_shift" "yes")])
3789 (define_insn_and_split "*rotl<mode>3_mask_dot"
3790   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3791         (compare:CC
3792           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3793                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3794                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3795                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3796           (const_int 0)))
3797    (clobber (match_scratch:GPR 0 "=r,r"))]
3798   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3799    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3801   if (which_alternative == 0)
3802     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3803   else
3804     return "#";
3806   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3807   [(set (match_dup 0)
3808         (and:GPR (match_dup 4)
3809                  (match_dup 3)))
3810    (set (match_dup 5)
3811         (compare:CC (match_dup 0)
3812                     (const_int 0)))]
3813   ""
3814   [(set_attr "type" "shift")
3815    (set_attr "maybe_var_shift" "yes")
3816    (set_attr "dot" "yes")
3817    (set_attr "length" "4,8")])
3819 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3820   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3821         (compare:CC
3822           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3823                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3824                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3825                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3826           (const_int 0)))
3827    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3828         (and:GPR (match_dup 4)
3829                  (match_dup 3)))]
3830   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3831    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3833   if (which_alternative == 0)
3834     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3835   else
3836     return "#";
3838   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3839   [(set (match_dup 0)
3840         (and:GPR (match_dup 4)
3841                  (match_dup 3)))
3842    (set (match_dup 5)
3843         (compare:CC (match_dup 0)
3844                     (const_int 0)))]
3845   ""
3846   [(set_attr "type" "shift")
3847    (set_attr "maybe_var_shift" "yes")
3848    (set_attr "dot" "yes")
3849    (set_attr "length" "4,8")])
3851 ; Special case for less-than-0.  We can do it with just one machine
3852 ; instruction, but the generic optimizers do not realise it is cheap.
3853 (define_insn "*lt0_<mode>di"
3854   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3855         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3856                 (const_int 0)))]
3857   "TARGET_POWERPC64"
3858   "srdi %0,%1,63"
3859   [(set_attr "type" "shift")])
3861 (define_insn "*lt0_<mode>si"
3862   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3863         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3864                 (const_int 0)))]
3865   ""
3866   "rlwinm %0,%1,1,31,31"
3867   [(set_attr "type" "shift")])
3871 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3872 ; both are an AND so are the same precedence).
3873 (define_insn "*rotl<mode>3_insert"
3874   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3875         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3876                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3877                             (match_operand:SI 2 "const_int_operand" "n")])
3878                           (match_operand:GPR 3 "const_int_operand" "n"))
3879                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3880                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3881   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3882    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3884   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3886   [(set_attr "type" "insert")])
3887 ; FIXME: this needs an attr "size", so that the scheduler can see the
3888 ; difference between rlwimi and rldimi.  We also might want dot forms,
3889 ; but not for rlwimi on POWER4 and similar processors.
3891 (define_insn "*rotl<mode>3_insert_2"
3892   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3893         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3894                           (match_operand:GPR 6 "const_int_operand" "n"))
3895                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3896                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3897                             (match_operand:SI 2 "const_int_operand" "n")])
3898                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3899   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3900    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3902   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3904   [(set_attr "type" "insert")])
3906 ; There are also some forms without one of the ANDs.
3907 (define_insn "*rotl<mode>3_insert_3"
3908   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3909         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3910                           (match_operand:GPR 4 "const_int_operand" "n"))
3911                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3912                              (match_operand:SI 2 "const_int_operand" "n"))))]
3913   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3915   if (<MODE>mode == SImode)
3916     return "rlwimi %0,%1,%h2,0,31-%h2";
3917   else
3918     return "rldimi %0,%1,%H2,0";
3920   [(set_attr "type" "insert")])
3922 (define_insn "*rotl<mode>3_insert_4"
3923   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3924         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3925                           (match_operand:GPR 4 "const_int_operand" "n"))
3926                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3927                                (match_operand:SI 2 "const_int_operand" "n"))))]
3928   "<MODE>mode == SImode &&
3929    GET_MODE_PRECISION (<MODE>mode)
3930    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3932   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3933                          - INTVAL (operands[2]));
3934   if (<MODE>mode == SImode)
3935     return "rlwimi %0,%1,%h2,32-%h2,31";
3936   else
3937     return "rldimi %0,%1,%H2,64-%H2";
3939   [(set_attr "type" "insert")])
3941 (define_insn "*rotlsi3_insert_5"
3942   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3943         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3944                         (match_operand:SI 2 "const_int_operand" "n,n"))
3945                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3946                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3947   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3948    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3949    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3950   "@
3951    rlwimi %0,%3,0,%4
3952    rlwimi %0,%1,0,%2"
3953   [(set_attr "type" "insert")])
3955 (define_insn "*rotldi3_insert_6"
3956   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3957         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3958                         (match_operand:DI 2 "const_int_operand" "n"))
3959                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3960                         (match_operand:DI 4 "const_int_operand" "n"))))]
3961   "exact_log2 (-UINTVAL (operands[2])) > 0
3962    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3964   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3965   return "rldimi %0,%3,0,%5";
3967   [(set_attr "type" "insert")
3968    (set_attr "size" "64")])
3970 (define_insn "*rotldi3_insert_7"
3971   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3972         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3973                         (match_operand:DI 4 "const_int_operand" "n"))
3974                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3975                         (match_operand:DI 2 "const_int_operand" "n"))))]
3976   "exact_log2 (-UINTVAL (operands[2])) > 0
3977    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3979   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3980   return "rldimi %0,%3,0,%5";
3982   [(set_attr "type" "insert")
3983    (set_attr "size" "64")])
3986 ; This handles the important case of multiple-precision shifts.  There is
3987 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3988 (define_split
3989   [(set (match_operand:GPR 0 "gpc_reg_operand")
3990         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3991                              (match_operand:SI 3 "const_int_operand"))
3992                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3993                                (match_operand:SI 4 "const_int_operand"))))]
3994   "can_create_pseudo_p ()
3995    && INTVAL (operands[3]) + INTVAL (operands[4])
3996       >= GET_MODE_PRECISION (<MODE>mode)"
3997   [(set (match_dup 5)
3998         (lshiftrt:GPR (match_dup 2)
3999                       (match_dup 4)))
4000    (set (match_dup 0)
4001         (ior:GPR (and:GPR (match_dup 5)
4002                           (match_dup 6))
4003                  (ashift:GPR (match_dup 1)
4004                              (match_dup 3))))]
4006   unsigned HOST_WIDE_INT mask = 1;
4007   mask = (mask << INTVAL (operands[3])) - 1;
4008   operands[5] = gen_reg_rtx (<MODE>mode);
4009   operands[6] = GEN_INT (mask);
4012 (define_split
4013   [(set (match_operand:GPR 0 "gpc_reg_operand")
4014         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4015                                (match_operand:SI 4 "const_int_operand"))
4016                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4017                              (match_operand:SI 3 "const_int_operand"))))]
4018   "can_create_pseudo_p ()
4019    && INTVAL (operands[3]) + INTVAL (operands[4])
4020       >= GET_MODE_PRECISION (<MODE>mode)"
4021   [(set (match_dup 5)
4022         (lshiftrt:GPR (match_dup 2)
4023                       (match_dup 4)))
4024    (set (match_dup 0)
4025         (ior:GPR (and:GPR (match_dup 5)
4026                           (match_dup 6))
4027                  (ashift:GPR (match_dup 1)
4028                              (match_dup 3))))]
4030   unsigned HOST_WIDE_INT mask = 1;
4031   mask = (mask << INTVAL (operands[3])) - 1;
4032   operands[5] = gen_reg_rtx (<MODE>mode);
4033   operands[6] = GEN_INT (mask);
4037 ; Another important case is setting some bits to 1; we can do that with
4038 ; an insert instruction, in many cases.
4039 (define_insn_and_split "*ior<mode>_mask"
4040   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4041         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4042                  (match_operand:GPR 2 "const_int_operand" "n")))
4043    (clobber (match_scratch:GPR 3 "=r"))]
4044   "!logical_const_operand (operands[2], <MODE>mode)
4045    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4046   "#"
4047   "&& 1"
4048   [(set (match_dup 3)
4049         (const_int -1))
4050    (set (match_dup 0)
4051         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4052                                       (match_dup 4))
4053                           (match_dup 2))
4054                  (and:GPR (match_dup 1)
4055                           (match_dup 5))))]
4057   int nb, ne;
4058   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4059   if (GET_CODE (operands[3]) == SCRATCH)
4060     operands[3] = gen_reg_rtx (<MODE>mode);
4061   operands[4] = GEN_INT (ne);
4062   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4064   [(set_attr "type" "two")
4065    (set_attr "length" "8")])
4068 ;; Now the simple shifts.
4070 (define_insn "rotl<mode>3"
4071   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4072         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4073                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4074   ""
4075   "rotl<wd>%I2 %0,%1,%<hH>2"
4076   [(set_attr "type" "shift")
4077    (set_attr "maybe_var_shift" "yes")])
4079 (define_insn "*rotlsi3_64"
4080   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4081         (zero_extend:DI
4082             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4083                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4084   "TARGET_POWERPC64"
4085   "rotlw%I2 %0,%1,%h2"
4086   [(set_attr "type" "shift")
4087    (set_attr "maybe_var_shift" "yes")])
4089 (define_insn_and_split "*rotl<mode>3_dot"
4090   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4091         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4092                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4093                     (const_int 0)))
4094    (clobber (match_scratch:GPR 0 "=r,r"))]
4095   "<MODE>mode == Pmode"
4096   "@
4097    rotl<wd>%I2. %0,%1,%<hH>2
4098    #"
4099   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4100   [(set (match_dup 0)
4101         (rotate:GPR (match_dup 1)
4102                     (match_dup 2)))
4103    (set (match_dup 3)
4104         (compare:CC (match_dup 0)
4105                     (const_int 0)))]
4106   ""
4107   [(set_attr "type" "shift")
4108    (set_attr "maybe_var_shift" "yes")
4109    (set_attr "dot" "yes")
4110    (set_attr "length" "4,8")])
4112 (define_insn_and_split "*rotl<mode>3_dot2"
4113   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4114         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4115                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4116                     (const_int 0)))
4117    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4118         (rotate:GPR (match_dup 1)
4119                     (match_dup 2)))]
4120   "<MODE>mode == Pmode"
4121   "@
4122    rotl<wd>%I2. %0,%1,%<hH>2
4123    #"
4124   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4125   [(set (match_dup 0)
4126         (rotate:GPR (match_dup 1)
4127                     (match_dup 2)))
4128    (set (match_dup 3)
4129         (compare:CC (match_dup 0)
4130                     (const_int 0)))]
4131   ""
4132   [(set_attr "type" "shift")
4133    (set_attr "maybe_var_shift" "yes")
4134    (set_attr "dot" "yes")
4135    (set_attr "length" "4,8")])
4138 (define_insn "ashl<mode>3"
4139   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4140         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4141                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4142   ""
4143   "sl<wd>%I2 %0,%1,%<hH>2"
4144   [(set_attr "type" "shift")
4145    (set_attr "maybe_var_shift" "yes")])
4147 (define_insn "*ashlsi3_64"
4148   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4149         (zero_extend:DI
4150             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4151                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4152   "TARGET_POWERPC64"
4153   "slw%I2 %0,%1,%h2"
4154   [(set_attr "type" "shift")
4155    (set_attr "maybe_var_shift" "yes")])
4157 (define_insn_and_split "*ashl<mode>3_dot"
4158   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4159         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4160                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4161                     (const_int 0)))
4162    (clobber (match_scratch:GPR 0 "=r,r"))]
4163   "<MODE>mode == Pmode"
4164   "@
4165    sl<wd>%I2. %0,%1,%<hH>2
4166    #"
4167   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4168   [(set (match_dup 0)
4169         (ashift:GPR (match_dup 1)
4170                     (match_dup 2)))
4171    (set (match_dup 3)
4172         (compare:CC (match_dup 0)
4173                     (const_int 0)))]
4174   ""
4175   [(set_attr "type" "shift")
4176    (set_attr "maybe_var_shift" "yes")
4177    (set_attr "dot" "yes")
4178    (set_attr "length" "4,8")])
4180 (define_insn_and_split "*ashl<mode>3_dot2"
4181   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4182         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4183                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4184                     (const_int 0)))
4185    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4186         (ashift:GPR (match_dup 1)
4187                     (match_dup 2)))]
4188   "<MODE>mode == Pmode"
4189   "@
4190    sl<wd>%I2. %0,%1,%<hH>2
4191    #"
4192   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4193   [(set (match_dup 0)
4194         (ashift:GPR (match_dup 1)
4195                     (match_dup 2)))
4196    (set (match_dup 3)
4197         (compare:CC (match_dup 0)
4198                     (const_int 0)))]
4199   ""
4200   [(set_attr "type" "shift")
4201    (set_attr "maybe_var_shift" "yes")
4202    (set_attr "dot" "yes")
4203    (set_attr "length" "4,8")])
4205 ;; Pretend we have a memory form of extswsli until register allocation is done
4206 ;; so that we use LWZ to load the value from memory, instead of LWA.
4207 (define_insn_and_split "ashdi3_extswsli"
4208   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4209         (ashift:DI
4210          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4211          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4212   "TARGET_EXTSWSLI"
4213   "@
4214    extswsli %0,%1,%2
4215    #"
4216   "&& reload_completed && MEM_P (operands[1])"
4217   [(set (match_dup 3)
4218         (match_dup 1))
4219    (set (match_dup 0)
4220         (ashift:DI (sign_extend:DI (match_dup 3))
4221                    (match_dup 2)))]
4223   operands[3] = gen_lowpart (SImode, operands[0]);
4225   [(set_attr "type" "shift")
4226    (set_attr "maybe_var_shift" "no")])
4229 (define_insn_and_split "ashdi3_extswsli_dot"
4230   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4231         (compare:CC
4232          (ashift:DI
4233           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4234           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4235          (const_int 0)))
4236    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4237   "TARGET_EXTSWSLI"
4238   "@
4239    extswsli. %0,%1,%2
4240    #
4241    #
4242    #"
4243   "&& reload_completed
4244    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4245        || memory_operand (operands[1], SImode))"
4246   [(pc)]
4248   rtx dest = operands[0];
4249   rtx src = operands[1];
4250   rtx shift = operands[2];
4251   rtx cr = operands[3];
4252   rtx src2;
4254   if (!MEM_P (src))
4255     src2 = src;
4256   else
4257     {
4258       src2 = gen_lowpart (SImode, dest);
4259       emit_move_insn (src2, src);
4260     }
4262   if (REGNO (cr) == CR0_REGNO)
4263     {
4264       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4265       DONE;
4266     }
4268   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4269   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4270   DONE;
4272   [(set_attr "type" "shift")
4273    (set_attr "maybe_var_shift" "no")
4274    (set_attr "dot" "yes")
4275    (set_attr "length" "4,8,8,12")])
4277 (define_insn_and_split "ashdi3_extswsli_dot2"
4278   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4279         (compare:CC
4280          (ashift:DI
4281           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4282           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4283          (const_int 0)))
4284    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4285         (ashift:DI (sign_extend:DI (match_dup 1))
4286                    (match_dup 2)))]
4287   "TARGET_EXTSWSLI"
4288   "@
4289    extswsli. %0,%1,%2
4290    #
4291    #
4292    #"
4293   "&& reload_completed
4294    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4295        || memory_operand (operands[1], SImode))"
4296   [(pc)]
4298   rtx dest = operands[0];
4299   rtx src = operands[1];
4300   rtx shift = operands[2];
4301   rtx cr = operands[3];
4302   rtx src2;
4304   if (!MEM_P (src))
4305     src2 = src;
4306   else
4307     {
4308       src2 = gen_lowpart (SImode, dest);
4309       emit_move_insn (src2, src);
4310     }
4312   if (REGNO (cr) == CR0_REGNO)
4313     {
4314       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4315       DONE;
4316     }
4318   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4319   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4320   DONE;
4322   [(set_attr "type" "shift")
4323    (set_attr "maybe_var_shift" "no")
4324    (set_attr "dot" "yes")
4325    (set_attr "length" "4,8,8,12")])
4327 (define_insn "lshr<mode>3"
4328   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4329         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4330                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4331   ""
4332   "sr<wd>%I2 %0,%1,%<hH>2"
4333   [(set_attr "type" "shift")
4334    (set_attr "maybe_var_shift" "yes")])
4336 (define_insn "*lshrsi3_64"
4337   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4338         (zero_extend:DI
4339             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4340                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4341   "TARGET_POWERPC64"
4342   "srw%I2 %0,%1,%h2"
4343   [(set_attr "type" "shift")
4344    (set_attr "maybe_var_shift" "yes")])
4346 (define_insn_and_split "*lshr<mode>3_dot"
4347   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4348         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4349                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4350                     (const_int 0)))
4351    (clobber (match_scratch:GPR 0 "=r,r"))]
4352   "<MODE>mode == Pmode"
4353   "@
4354    sr<wd>%I2. %0,%1,%<hH>2
4355    #"
4356   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4357   [(set (match_dup 0)
4358         (lshiftrt:GPR (match_dup 1)
4359                       (match_dup 2)))
4360    (set (match_dup 3)
4361         (compare:CC (match_dup 0)
4362                     (const_int 0)))]
4363   ""
4364   [(set_attr "type" "shift")
4365    (set_attr "maybe_var_shift" "yes")
4366    (set_attr "dot" "yes")
4367    (set_attr "length" "4,8")])
4369 (define_insn_and_split "*lshr<mode>3_dot2"
4370   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4371         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4372                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4373                     (const_int 0)))
4374    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4375         (lshiftrt:GPR (match_dup 1)
4376                       (match_dup 2)))]
4377   "<MODE>mode == Pmode"
4378   "@
4379    sr<wd>%I2. %0,%1,%<hH>2
4380    #"
4381   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4382   [(set (match_dup 0)
4383         (lshiftrt:GPR (match_dup 1)
4384                       (match_dup 2)))
4385    (set (match_dup 3)
4386         (compare:CC (match_dup 0)
4387                     (const_int 0)))]
4388   ""
4389   [(set_attr "type" "shift")
4390    (set_attr "maybe_var_shift" "yes")
4391    (set_attr "dot" "yes")
4392    (set_attr "length" "4,8")])
4395 (define_insn "ashr<mode>3"
4396   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4397         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4398                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4399    (clobber (reg:GPR CA_REGNO))]
4400   ""
4401   "sra<wd>%I2 %0,%1,%<hH>2"
4402   [(set_attr "type" "shift")
4403    (set_attr "maybe_var_shift" "yes")])
4405 (define_insn "*ashrsi3_64"
4406   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4407         (sign_extend:DI
4408             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4409                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4410    (clobber (reg:SI CA_REGNO))]
4411   "TARGET_POWERPC64"
4412   "sraw%I2 %0,%1,%h2"
4413   [(set_attr "type" "shift")
4414    (set_attr "maybe_var_shift" "yes")])
4416 (define_insn_and_split "*ashr<mode>3_dot"
4417   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4418         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4419                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4420                     (const_int 0)))
4421    (clobber (match_scratch:GPR 0 "=r,r"))
4422    (clobber (reg:GPR CA_REGNO))]
4423   "<MODE>mode == Pmode"
4424   "@
4425    sra<wd>%I2. %0,%1,%<hH>2
4426    #"
4427   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4428   [(parallel [(set (match_dup 0)
4429                    (ashiftrt:GPR (match_dup 1)
4430                                  (match_dup 2)))
4431               (clobber (reg:GPR CA_REGNO))])
4432    (set (match_dup 3)
4433         (compare:CC (match_dup 0)
4434                     (const_int 0)))]
4435   ""
4436   [(set_attr "type" "shift")
4437    (set_attr "maybe_var_shift" "yes")
4438    (set_attr "dot" "yes")
4439    (set_attr "length" "4,8")])
4441 (define_insn_and_split "*ashr<mode>3_dot2"
4442   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4443         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4444                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4445                     (const_int 0)))
4446    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4447         (ashiftrt:GPR (match_dup 1)
4448                       (match_dup 2)))
4449    (clobber (reg:GPR CA_REGNO))]
4450   "<MODE>mode == Pmode"
4451   "@
4452    sra<wd>%I2. %0,%1,%<hH>2
4453    #"
4454   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4455   [(parallel [(set (match_dup 0)
4456                    (ashiftrt:GPR (match_dup 1)
4457                                  (match_dup 2)))
4458               (clobber (reg:GPR CA_REGNO))])
4459    (set (match_dup 3)
4460         (compare:CC (match_dup 0)
4461                     (const_int 0)))]
4462   ""
4463   [(set_attr "type" "shift")
4464    (set_attr "maybe_var_shift" "yes")
4465    (set_attr "dot" "yes")
4466    (set_attr "length" "4,8")])
4468 ;; Builtins to replace a division to generate FRE reciprocal estimate
4469 ;; instructions and the necessary fixup instructions
4470 (define_expand "recip<mode>3"
4471   [(match_operand:RECIPF 0 "gpc_reg_operand")
4472    (match_operand:RECIPF 1 "gpc_reg_operand")
4473    (match_operand:RECIPF 2 "gpc_reg_operand")]
4474   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4476    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4477    DONE;
4480 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4481 ;; hardware division.  This is only done before register allocation and with
4482 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4483 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4484 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4485 (define_split
4486   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4487         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4488                     (match_operand 2 "gpc_reg_operand")))]
4489   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4490    && can_create_pseudo_p () && flag_finite_math_only
4491    && !flag_trapping_math && flag_reciprocal_math"
4492   [(const_int 0)]
4494   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4495   DONE;
4498 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4499 ;; appropriate fixup.
4500 (define_expand "rsqrt<mode>2"
4501   [(match_operand:RECIPF 0 "gpc_reg_operand")
4502    (match_operand:RECIPF 1 "gpc_reg_operand")]
4503   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4505   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4506   DONE;
4509 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4510 ;; modes here, and also add in conditional vsx/power8-vector support to access
4511 ;; values in the traditional Altivec registers if the appropriate
4512 ;; -mupper-regs-{df,sf} option is enabled.
4514 (define_expand "abs<mode>2"
4515   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4516         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4517   "TARGET_HARD_FLOAT"
4518   "")
4520 (define_insn "*abs<mode>2_fpr"
4521   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4522         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4523   "TARGET_HARD_FLOAT"
4524   "@
4525    fabs %0,%1
4526    xsabsdp %x0,%x1"
4527   [(set_attr "type" "fpsimple")])
4529 (define_insn "*nabs<mode>2_fpr"
4530   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4531         (neg:SFDF
4532          (abs:SFDF
4533           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4534   "TARGET_HARD_FLOAT"
4535   "@
4536    fnabs %0,%1
4537    xsnabsdp %x0,%x1"
4538   [(set_attr "type" "fpsimple")])
4540 (define_expand "neg<mode>2"
4541   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4542         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4543   "TARGET_HARD_FLOAT"
4544   "")
4546 (define_insn "*neg<mode>2_fpr"
4547   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4548         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4549   "TARGET_HARD_FLOAT"
4550   "@
4551    fneg %0,%1
4552    xsnegdp %x0,%x1"
4553   [(set_attr "type" "fpsimple")])
4555 (define_expand "add<mode>3"
4556   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4557         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4558                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4559   "TARGET_HARD_FLOAT"
4560   "")
4562 (define_insn "*add<mode>3_fpr"
4563   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4564         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4565                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4566   "TARGET_HARD_FLOAT"
4567   "@
4568    fadd<Ftrad> %0,%1,%2
4569    xsadd<Fvsx> %x0,%x1,%x2"
4570   [(set_attr "type" "fp")])
4572 (define_expand "sub<mode>3"
4573   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4574         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4575                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4576   "TARGET_HARD_FLOAT"
4577   "")
4579 (define_insn "*sub<mode>3_fpr"
4580   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4581         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4582                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4583   "TARGET_HARD_FLOAT"
4584   "@
4585    fsub<Ftrad> %0,%1,%2
4586    xssub<Fvsx> %x0,%x1,%x2"
4587   [(set_attr "type" "fp")])
4589 (define_expand "mul<mode>3"
4590   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4591         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4592                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4593   "TARGET_HARD_FLOAT"
4594   "")
4596 (define_insn "*mul<mode>3_fpr"
4597   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4598         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4599                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4600   "TARGET_HARD_FLOAT"
4601   "@
4602    fmul<Ftrad> %0,%1,%2
4603    xsmul<Fvsx> %x0,%x1,%x2"
4604   [(set_attr "type" "dmul")])
4606 (define_expand "div<mode>3"
4607   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4608         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4609                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4610   "TARGET_HARD_FLOAT"
4612   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4613       && can_create_pseudo_p () && flag_finite_math_only
4614       && !flag_trapping_math && flag_reciprocal_math)
4615     {
4616       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4617       DONE;
4618     }
4621 (define_insn "*div<mode>3_fpr"
4622   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4623         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4624                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4625   "TARGET_HARD_FLOAT"
4626   "@
4627    fdiv<Ftrad> %0,%1,%2
4628    xsdiv<Fvsx> %x0,%x1,%x2"
4629   [(set_attr "type" "<Fs>div")])
4631 (define_insn "*sqrt<mode>2_internal"
4632   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4633         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4634   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4635   "@
4636    fsqrt<Ftrad> %0,%1
4637    xssqrt<Fvsx> %x0,%x1"
4638   [(set_attr "type" "<Fs>sqrt")])
4640 (define_expand "sqrt<mode>2"
4641   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4642         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4643   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4645   if (<MODE>mode == SFmode
4646       && TARGET_RECIP_PRECISION
4647       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4648       && !optimize_function_for_size_p (cfun)
4649       && flag_finite_math_only && !flag_trapping_math
4650       && flag_unsafe_math_optimizations)
4651     {
4652       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4653       DONE;
4654     }
4657 ;; Floating point reciprocal approximation
4658 (define_insn "fre<Fs>"
4659   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4660         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4661                      UNSPEC_FRES))]
4662   "TARGET_<FFRE>"
4663   "@
4664    fre<Ftrad> %0,%1
4665    xsre<Fvsx> %x0,%x1"
4666   [(set_attr "type" "fp")])
4668 (define_insn "*rsqrt<mode>2"
4669   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4670         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4671                      UNSPEC_RSQRT))]
4672   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4673   "@
4674    frsqrte<Ftrad> %0,%1
4675    xsrsqrte<Fvsx> %x0,%x1"
4676   [(set_attr "type" "fp")])
4678 ;; Floating point comparisons
4679 (define_insn "*cmp<mode>_fpr"
4680   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4681         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4682                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4683   "TARGET_HARD_FLOAT"
4684   "@
4685    fcmpu %0,%1,%2
4686    xscmpudp %0,%x1,%x2"
4687   [(set_attr "type" "fpcompare")])
4689 ;; Floating point conversions
4690 (define_expand "extendsfdf2"
4691   [(set (match_operand:DF 0 "gpc_reg_operand")
4692         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4693   "TARGET_HARD_FLOAT"
4695   if (HONOR_SNANS (SFmode))
4696     operands[1] = force_reg (SFmode, operands[1]);
4699 (define_insn_and_split "*extendsfdf2_fpr"
4700   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4701         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4702   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4703   "@
4704    #
4705    fmr %0,%1
4706    lfs%U1%X1 %0,%1
4707    #
4708    xscpsgndp %x0,%x1,%x1
4709    lxsspx %x0,%y1
4710    lxssp %0,%1"
4711   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4712   [(const_int 0)]
4714   emit_note (NOTE_INSN_DELETED);
4715   DONE;
4717   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4719 (define_insn "*extendsfdf2_snan"
4720   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4721         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4722   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4723   "@
4724    frsp %0,%1
4725    xsrsp %x0,%x1"
4726   [(set_attr "type" "fp")])
4728 (define_expand "truncdfsf2"
4729   [(set (match_operand:SF 0 "gpc_reg_operand")
4730         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4731   "TARGET_HARD_FLOAT"
4732   "")
4734 (define_insn "*truncdfsf2_fpr"
4735   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4736         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4737   "TARGET_HARD_FLOAT"
4738   "@
4739    frsp %0,%1
4740    xsrsp %x0,%x1"
4741   [(set_attr "type" "fp")])
4743 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4744 ;; builtins.c and optabs.c that are not correct for IBM long double
4745 ;; when little-endian.
4746 (define_expand "signbit<mode>2"
4747   [(set (match_dup 2)
4748         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4749    (set (match_dup 3)
4750         (subreg:DI (match_dup 2) 0))
4751    (set (match_dup 4)
4752         (match_dup 5))
4753    (set (match_operand:SI 0 "gpc_reg_operand")
4754         (match_dup 6))]
4755   "TARGET_HARD_FLOAT
4756    && (!FLOAT128_IEEE_P (<MODE>mode)
4757        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4759   if (FLOAT128_IEEE_P (<MODE>mode))
4760     {
4761       rtx dest = operands[0];
4762       rtx src = operands[1];
4763       rtx tmp = gen_reg_rtx (DImode);
4764       rtx dest_di = gen_lowpart (DImode, dest);
4766       if (<MODE>mode == KFmode)
4767         emit_insn (gen_signbitkf2_dm (tmp, src));
4768       else if (<MODE>mode == TFmode)
4769         emit_insn (gen_signbittf2_dm (tmp, src));
4770       else
4771         gcc_unreachable ();
4773       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4774       DONE;
4775     }
4776   operands[2] = gen_reg_rtx (DFmode);
4777   operands[3] = gen_reg_rtx (DImode);
4778   if (TARGET_POWERPC64)
4779     {
4780       operands[4] = gen_reg_rtx (DImode);
4781       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4782       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4783                                     WORDS_BIG_ENDIAN ? 4 : 0);
4784     }
4785   else
4786     {
4787       operands[4] = gen_reg_rtx (SImode);
4788       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4789                                     WORDS_BIG_ENDIAN ? 0 : 4);
4790       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4791     }
4794 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4795 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4796 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4797 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4799 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4800 ;; split allows the post reload phases to eliminate the move, and do the shift
4801 ;; directly with the register that contains the signbit.
4802 (define_insn_and_split "signbit<mode>2_dm"
4803   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4804         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4805                    UNSPEC_SIGNBIT))]
4806   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4807   "@
4808    mfvsrd %0,%x1
4809    #"
4810   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4811   [(set (match_dup 0)
4812         (match_dup 2))]
4814   operands[2] = gen_highpart (DImode, operands[1]);
4816  [(set_attr "type" "mftgpr,*")])
4818 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4819 ;; register and then doing a direct move if the value comes from memory.  On
4820 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4821 (define_insn_and_split "*signbit<mode>2_dm_mem"
4822   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4823         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4824                    UNSPEC_SIGNBIT))]
4825   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4826   "#"
4827   "&& 1"
4828   [(set (match_dup 0)
4829         (match_dup 2))]
4831   rtx dest = operands[0];
4832   rtx src = operands[1];
4833   rtx addr = XEXP (src, 0);
4835   if (WORDS_BIG_ENDIAN)
4836     operands[2] = adjust_address (src, DImode, 0);
4838   else if (REG_P (addr) || SUBREG_P (addr))
4839     operands[2] = adjust_address (src, DImode, 8);
4841   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4842            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4843     operands[2] = adjust_address (src, DImode, 8);
4845   else
4846     {
4847       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4848       emit_insn (gen_rtx_SET (tmp, addr));
4849       operands[2] = change_address (src, DImode,
4850                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4851     }
4854 (define_expand "copysign<mode>3"
4855   [(set (match_dup 3)
4856         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4857    (set (match_dup 4)
4858         (neg:SFDF (abs:SFDF (match_dup 1))))
4859    (set (match_operand:SFDF 0 "gpc_reg_operand")
4860         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4861                                (match_dup 5))
4862                          (match_dup 3)
4863                          (match_dup 4)))]
4864   "TARGET_HARD_FLOAT
4865    && ((TARGET_PPC_GFXOPT
4866         && !HONOR_NANS (<MODE>mode)
4867         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4868        || TARGET_CMPB
4869        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4871   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4872     {
4873       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4874                                              operands[2]));
4875       DONE;
4876     }
4878    operands[3] = gen_reg_rtx (<MODE>mode);
4879    operands[4] = gen_reg_rtx (<MODE>mode);
4880    operands[5] = CONST0_RTX (<MODE>mode);
4881   })
4883 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4884 ;; compiler from optimizing -0.0
4885 (define_insn "copysign<mode>3_fcpsgn"
4886   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4887         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4888                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4889                      UNSPEC_COPYSIGN))]
4890   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4891   "@
4892    fcpsgn %0,%2,%1
4893    xscpsgndp %x0,%x2,%x1"
4894   [(set_attr "type" "fpsimple")])
4896 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4897 ;; fsel instruction and some auxiliary computations.  Then we just have a
4898 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4899 ;; combine.
4900 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4901 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4902 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4903 ;; define_splits to make them if made by combine.  On VSX machines we have the
4904 ;; min/max instructions.
4906 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4907 ;; to allow either DF/SF to use only traditional registers.
4909 (define_expand "s<minmax><mode>3"
4910   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4911         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4912                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4913   "TARGET_MINMAX"
4915   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4916   DONE;
4919 (define_insn "*s<minmax><mode>3_vsx"
4920   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4921         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4922                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4923   "TARGET_VSX && TARGET_HARD_FLOAT"
4925   return (TARGET_P9_MINMAX
4926           ? "xs<minmax>cdp %x0,%x1,%x2"
4927           : "xs<minmax>dp %x0,%x1,%x2");
4929   [(set_attr "type" "fp")])
4931 ;; The conditional move instructions allow us to perform max and min operations
4932 ;; even when we don't have the appropriate max/min instruction using the FSEL
4933 ;; instruction.
4935 (define_insn_and_split "*s<minmax><mode>3_fpr"
4936   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4937         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4938                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4939   "!TARGET_VSX && TARGET_MINMAX"
4940   "#"
4941   "&& 1"
4942   [(const_int 0)]
4944   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4945   DONE;
4948 (define_expand "mov<mode>cc"
4949    [(set (match_operand:GPR 0 "gpc_reg_operand")
4950          (if_then_else:GPR (match_operand 1 "comparison_operator")
4951                            (match_operand:GPR 2 "gpc_reg_operand")
4952                            (match_operand:GPR 3 "gpc_reg_operand")))]
4953   "TARGET_ISEL"
4955   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4956     DONE;
4957   else
4958     FAIL;
4961 ;; We use the BASE_REGS for the isel input operands because, if rA is
4962 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4963 ;; because we may switch the operands and rB may end up being rA.
4965 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4966 ;; leave out the mode in operand 4 and use one pattern, but reload can
4967 ;; change the mode underneath our feet and then gets confused trying
4968 ;; to reload the value.
4969 (define_insn "isel_signed_<mode>"
4970   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4971         (if_then_else:GPR
4972          (match_operator 1 "scc_comparison_operator"
4973                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4974                           (const_int 0)])
4975          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4976          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4977   "TARGET_ISEL"
4978   "isel %0,%2,%3,%j1"
4979   [(set_attr "type" "isel")])
4981 (define_insn "isel_unsigned_<mode>"
4982   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4983         (if_then_else:GPR
4984          (match_operator 1 "scc_comparison_operator"
4985                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4986                           (const_int 0)])
4987          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4988          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4989   "TARGET_ISEL"
4990   "isel %0,%2,%3,%j1"
4991   [(set_attr "type" "isel")])
4993 ;; These patterns can be useful for combine; they let combine know that
4994 ;; isel can handle reversed comparisons so long as the operands are
4995 ;; registers.
4997 (define_insn "*isel_reversed_signed_<mode>"
4998   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4999         (if_then_else:GPR
5000          (match_operator 1 "scc_rev_comparison_operator"
5001                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5002                           (const_int 0)])
5003          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5004          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5005   "TARGET_ISEL"
5007   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5008   return "isel %0,%3,%2,%j1";
5010   [(set_attr "type" "isel")])
5012 (define_insn "*isel_reversed_unsigned_<mode>"
5013   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5014         (if_then_else:GPR
5015          (match_operator 1 "scc_rev_comparison_operator"
5016                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5017                           (const_int 0)])
5018          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5019          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5020   "TARGET_ISEL"
5022   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5023   return "isel %0,%3,%2,%j1";
5025   [(set_attr "type" "isel")])
5027 ;; Floating point conditional move
5028 (define_expand "mov<mode>cc"
5029    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5030          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5031                             (match_operand:SFDF 2 "gpc_reg_operand")
5032                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5033   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5035   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5036     DONE;
5037   else
5038     FAIL;
5041 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5042   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5043         (if_then_else:SFDF
5044          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5045              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5046          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5047          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5048   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5049   "fsel %0,%1,%2,%3"
5050   [(set_attr "type" "fp")])
5052 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5053   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5054         (if_then_else:SFDF
5055          (match_operator:CCFP 1 "fpmask_comparison_operator"
5056                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5057                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5058          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5059          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5060    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5061   "TARGET_P9_MINMAX"
5062   "#"
5063   ""
5064   [(set (match_dup 6)
5065         (if_then_else:V2DI (match_dup 1)
5066                            (match_dup 7)
5067                            (match_dup 8)))
5068    (set (match_dup 0)
5069         (if_then_else:SFDF (ne (match_dup 6)
5070                                (match_dup 8))
5071                            (match_dup 4)
5072                            (match_dup 5)))]
5074   if (GET_CODE (operands[6]) == SCRATCH)
5075     operands[6] = gen_reg_rtx (V2DImode);
5077   operands[7] = CONSTM1_RTX (V2DImode);
5078   operands[8] = CONST0_RTX (V2DImode);
5080  [(set_attr "length" "8")
5081   (set_attr "type" "vecperm")])
5083 ;; Handle inverting the fpmask comparisons.
5084 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5085   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5086         (if_then_else:SFDF
5087          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5088                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5089                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5090          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5091          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5092    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5093   "TARGET_P9_MINMAX"
5094   "#"
5095   "&& 1"
5096   [(set (match_dup 6)
5097         (if_then_else:V2DI (match_dup 9)
5098                            (match_dup 7)
5099                            (match_dup 8)))
5100    (set (match_dup 0)
5101         (if_then_else:SFDF (ne (match_dup 6)
5102                                (match_dup 8))
5103                            (match_dup 5)
5104                            (match_dup 4)))]
5106   rtx op1 = operands[1];
5107   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5109   if (GET_CODE (operands[6]) == SCRATCH)
5110     operands[6] = gen_reg_rtx (V2DImode);
5112   operands[7] = CONSTM1_RTX (V2DImode);
5113   operands[8] = CONST0_RTX (V2DImode);
5115   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5117  [(set_attr "length" "8")
5118   (set_attr "type" "vecperm")])
5120 (define_insn "*fpmask<mode>"
5121   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5122         (if_then_else:V2DI
5123          (match_operator:CCFP 1 "fpmask_comparison_operator"
5124                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5125                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5126          (match_operand:V2DI 4 "all_ones_constant" "")
5127          (match_operand:V2DI 5 "zero_constant" "")))]
5128   "TARGET_P9_MINMAX"
5129   "xscmp%V1dp %x0,%x2,%x3"
5130   [(set_attr "type" "fpcompare")])
5132 (define_insn "*xxsel<mode>"
5133   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5134         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5135                                (match_operand:V2DI 2 "zero_constant" ""))
5136                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5137                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5138   "TARGET_P9_MINMAX"
5139   "xxsel %x0,%x4,%x3,%x1"
5140   [(set_attr "type" "vecmove")])
5143 ;; Conversions to and from floating-point.
5145 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5146 ; don't want to support putting SImode in FPR registers.
5147 (define_insn "lfiwax"
5148   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5149         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5150                    UNSPEC_LFIWAX))]
5151   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5152   "@
5153    lfiwax %0,%y1
5154    lxsiwax %x0,%y1
5155    mtvsrwa %x0,%1
5156    vextsw2d %0,%1"
5157   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5159 ; This split must be run before register allocation because it allocates the
5160 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5161 ; it earlier to allow for the combiner to merge insns together where it might
5162 ; not be needed and also in case the insns are deleted as dead code.
5164 (define_insn_and_split "floatsi<mode>2_lfiwax"
5165   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5166         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5167    (clobber (match_scratch:DI 2 "=wi"))]
5168   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5169    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5170   "#"
5171   ""
5172   [(pc)]
5174   rtx dest = operands[0];
5175   rtx src = operands[1];
5176   rtx tmp;
5178   if (!MEM_P (src) && TARGET_POWERPC64
5179       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5180     tmp = convert_to_mode (DImode, src, false);
5181   else
5182     {
5183       tmp = operands[2];
5184       if (GET_CODE (tmp) == SCRATCH)
5185         tmp = gen_reg_rtx (DImode);
5186       if (MEM_P (src))
5187         {
5188           src = rs6000_address_for_fpconvert (src);
5189           emit_insn (gen_lfiwax (tmp, src));
5190         }
5191       else
5192         {
5193           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5194           emit_move_insn (stack, src);
5195           emit_insn (gen_lfiwax (tmp, stack));
5196         }
5197     }
5198   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5199   DONE;
5201   [(set_attr "length" "12")
5202    (set_attr "type" "fpload")])
5204 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5205   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5206         (float:SFDF
5207          (sign_extend:DI
5208           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5209    (clobber (match_scratch:DI 2 "=wi"))]
5210   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5211   "#"
5212   ""
5213   [(pc)]
5215   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5216   if (GET_CODE (operands[2]) == SCRATCH)
5217     operands[2] = gen_reg_rtx (DImode);
5218   if (TARGET_P8_VECTOR)
5219     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5220   else
5221     emit_insn (gen_lfiwax (operands[2], operands[1]));
5222   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5223   DONE;
5225   [(set_attr "length" "8")
5226    (set_attr "type" "fpload")])
5228 (define_insn "lfiwzx"
5229   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5230         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5231                    UNSPEC_LFIWZX))]
5232   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5233   "@
5234    lfiwzx %0,%y1
5235    lxsiwzx %x0,%y1
5236    mtvsrwz %x0,%1
5237    xxextractuw %x0,%x1,4"
5238   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5240 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5241   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5242         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5243    (clobber (match_scratch:DI 2 "=wi"))]
5244   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5245   "#"
5246   ""
5247   [(pc)]
5249   rtx dest = operands[0];
5250   rtx src = operands[1];
5251   rtx tmp;
5253   if (!MEM_P (src) && TARGET_POWERPC64
5254       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5255     tmp = convert_to_mode (DImode, src, true);
5256   else
5257     {
5258       tmp = operands[2];
5259       if (GET_CODE (tmp) == SCRATCH)
5260         tmp = gen_reg_rtx (DImode);
5261       if (MEM_P (src))
5262         {
5263           src = rs6000_address_for_fpconvert (src);
5264           emit_insn (gen_lfiwzx (tmp, src));
5265         }
5266       else
5267         {
5268           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5269           emit_move_insn (stack, src);
5270           emit_insn (gen_lfiwzx (tmp, stack));
5271         }
5272     }
5273   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5274   DONE;
5276   [(set_attr "length" "12")
5277    (set_attr "type" "fpload")])
5279 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5280   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5281         (unsigned_float:SFDF
5282          (zero_extend:DI
5283           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5284    (clobber (match_scratch:DI 2 "=wi"))]
5285   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5286   "#"
5287   ""
5288   [(pc)]
5290   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5291   if (GET_CODE (operands[2]) == SCRATCH)
5292     operands[2] = gen_reg_rtx (DImode);
5293   if (TARGET_P8_VECTOR)
5294     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5295   else
5296     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5297   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5298   DONE;
5300   [(set_attr "length" "8")
5301    (set_attr "type" "fpload")])
5303 ; For each of these conversions, there is a define_expand, a define_insn
5304 ; with a '#' template, and a define_split (with C code).  The idea is
5305 ; to allow constant folding with the template of the define_insn,
5306 ; then to have the insns split later (between sched1 and final).
5308 (define_expand "floatsidf2"
5309   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5310                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5311               (use (match_dup 2))
5312               (use (match_dup 3))
5313               (clobber (match_dup 4))
5314               (clobber (match_dup 5))
5315               (clobber (match_dup 6))])]
5316   "TARGET_HARD_FLOAT"
5318   if (TARGET_LFIWAX && TARGET_FCFID)
5319     {
5320       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5321       DONE;
5322     }
5323   else if (TARGET_FCFID)
5324     {
5325       rtx dreg = operands[1];
5326       if (!REG_P (dreg))
5327         dreg = force_reg (SImode, dreg);
5328       dreg = convert_to_mode (DImode, dreg, false);
5329       emit_insn (gen_floatdidf2 (operands[0], dreg));
5330       DONE;
5331     }
5333   if (!REG_P (operands[1]))
5334     operands[1] = force_reg (SImode, operands[1]);
5335   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5336   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5337   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5338   operands[5] = gen_reg_rtx (DFmode);
5339   operands[6] = gen_reg_rtx (SImode);
5342 (define_insn_and_split "*floatsidf2_internal"
5343   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5344         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5345    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5346    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5347    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5348    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5349    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5350   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5351   "#"
5352   ""
5353   [(pc)]
5355   rtx lowword, highword;
5356   gcc_assert (MEM_P (operands[4]));
5357   highword = adjust_address (operands[4], SImode, 0);
5358   lowword = adjust_address (operands[4], SImode, 4);
5359   if (! WORDS_BIG_ENDIAN)
5360     std::swap (lowword, highword);
5362   emit_insn (gen_xorsi3 (operands[6], operands[1],
5363                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5364   emit_move_insn (lowword, operands[6]);
5365   emit_move_insn (highword, operands[2]);
5366   emit_move_insn (operands[5], operands[4]);
5367   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5368   DONE;
5370   [(set_attr "length" "24")
5371    (set_attr "type" "fp")])
5373 ;; If we don't have a direct conversion to single precision, don't enable this
5374 ;; conversion for 32-bit without fast math, because we don't have the insn to
5375 ;; generate the fixup swizzle to avoid double rounding problems.
5376 (define_expand "floatunssisf2"
5377   [(set (match_operand:SF 0 "gpc_reg_operand")
5378         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5379   "TARGET_HARD_FLOAT
5380    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5381        || (TARGET_FCFID
5382            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5384   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5385     {
5386       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5387       DONE;
5388     }
5389   else
5390     {
5391       rtx dreg = operands[1];
5392       if (!REG_P (dreg))
5393         dreg = force_reg (SImode, dreg);
5394       dreg = convert_to_mode (DImode, dreg, true);
5395       emit_insn (gen_floatdisf2 (operands[0], dreg));
5396       DONE;
5397     }
5400 (define_expand "floatunssidf2"
5401   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5402                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5403               (use (match_dup 2))
5404               (use (match_dup 3))
5405               (clobber (match_dup 4))
5406               (clobber (match_dup 5))])]
5407   "TARGET_HARD_FLOAT"
5409   if (TARGET_LFIWZX && TARGET_FCFID)
5410     {
5411       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5412       DONE;
5413     }
5414   else if (TARGET_FCFID)
5415     {
5416       rtx dreg = operands[1];
5417       if (!REG_P (dreg))
5418         dreg = force_reg (SImode, dreg);
5419       dreg = convert_to_mode (DImode, dreg, true);
5420       emit_insn (gen_floatdidf2 (operands[0], dreg));
5421       DONE;
5422     }
5424   if (!REG_P (operands[1]))
5425     operands[1] = force_reg (SImode, operands[1]);
5426   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5427   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5428   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5429   operands[5] = gen_reg_rtx (DFmode);
5432 (define_insn_and_split "*floatunssidf2_internal"
5433   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5434         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5435    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5436    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5437    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5438    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5439   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5440    && !(TARGET_FCFID && TARGET_POWERPC64)"
5441   "#"
5442   ""
5443   [(pc)]
5445   rtx lowword, highword;
5446   gcc_assert (MEM_P (operands[4]));
5447   highword = adjust_address (operands[4], SImode, 0);
5448   lowword = adjust_address (operands[4], SImode, 4);
5449   if (! WORDS_BIG_ENDIAN)
5450     std::swap (lowword, highword);
5452   emit_move_insn (lowword, operands[1]);
5453   emit_move_insn (highword, operands[2]);
5454   emit_move_insn (operands[5], operands[4]);
5455   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5456   DONE;
5458   [(set_attr "length" "20")
5459    (set_attr "type" "fp")])
5461 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5462 ;; vector registers.  These insns favor doing the sign/zero extension in
5463 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5464 ;; extension and then a direct move.
5466 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5467   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5468                    (float:FP_ISA3
5469                     (match_operand:QHI 1 "input_operand")))
5470               (clobber (match_scratch:DI 2))
5471               (clobber (match_scratch:DI 3))
5472               (clobber (match_scratch:<QHI:MODE> 4))])]
5473   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5475   if (MEM_P (operands[1]))
5476     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5479 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5480   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5481         (float:FP_ISA3
5482          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5483    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5484    (clobber (match_scratch:DI 3 "=X,r,X"))
5485    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5486   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5487   "#"
5488   "&& reload_completed"
5489   [(const_int 0)]
5491   rtx result = operands[0];
5492   rtx input = operands[1];
5493   rtx di = operands[2];
5495   if (!MEM_P (input))
5496     {
5497       rtx tmp = operands[3];
5498       if (altivec_register_operand (input, <QHI:MODE>mode))
5499         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5500       else if (GET_CODE (tmp) == SCRATCH)
5501         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5502       else
5503         {
5504           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5505           emit_move_insn (di, tmp);
5506         }
5507     }
5508   else
5509     {
5510       rtx tmp = operands[4];
5511       emit_move_insn (tmp, input);
5512       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5513     }
5515   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5516   DONE;
5519 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5520   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5521                    (unsigned_float:FP_ISA3
5522                     (match_operand:QHI 1 "input_operand")))
5523               (clobber (match_scratch:DI 2))
5524               (clobber (match_scratch:DI 3))])]
5525   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5527   if (MEM_P (operands[1]))
5528     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5531 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5532   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5533         (unsigned_float:FP_ISA3
5534          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5535    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5536    (clobber (match_scratch:DI 3 "=X,r,X"))]
5537   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5538   "#"
5539   "&& reload_completed"
5540   [(const_int 0)]
5542   rtx result = operands[0];
5543   rtx input = operands[1];
5544   rtx di = operands[2];
5546   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5547     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5548   else
5549     {
5550       rtx tmp = operands[3];
5551       if (GET_CODE (tmp) == SCRATCH)
5552         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5553       else
5554         {
5555           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5556           emit_move_insn (di, tmp);
5557         }
5558     }
5560   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5561   DONE;
5564 (define_expand "fix_trunc<mode>si2"
5565   [(set (match_operand:SI 0 "gpc_reg_operand")
5566         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5567   "TARGET_HARD_FLOAT"
5569   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5570     {
5571       rtx src = force_reg (<MODE>mode, operands[1]);
5573       if (TARGET_STFIWX)
5574         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5575       else
5576         {
5577           rtx tmp = gen_reg_rtx (DImode);
5578           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5579           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5580                                                       tmp, stack));
5581         }
5582       DONE;
5583     }
5586 ; Like the convert to float patterns, this insn must be split before
5587 ; register allocation so that it can allocate the memory slot if it
5588 ; needed
5589 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5590   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5591         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5592    (clobber (match_scratch:DI 2 "=d"))]
5593   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5594    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5595   "#"
5596   ""
5597   [(pc)]
5599   rtx dest = operands[0];
5600   rtx src = operands[1];
5601   rtx tmp = operands[2];
5603   if (GET_CODE (tmp) == SCRATCH)
5604     tmp = gen_reg_rtx (DImode);
5606   emit_insn (gen_fctiwz_<mode> (tmp, src));
5607   if (MEM_P (dest))
5608     {
5609       dest = rs6000_address_for_fpconvert (dest);
5610       emit_insn (gen_stfiwx (dest, tmp));
5611       DONE;
5612     }
5613   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5614     {
5615       dest = gen_lowpart (DImode, dest);
5616       emit_move_insn (dest, tmp);
5617       DONE;
5618     }
5619   else
5620     {
5621       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5622       emit_insn (gen_stfiwx (stack, tmp));
5623       emit_move_insn (dest, stack);
5624       DONE;
5625     }
5627   [(set_attr "length" "12")
5628    (set_attr "type" "fp")])
5630 (define_insn_and_split "fix_trunc<mode>si2_internal"
5631   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5632         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5633    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5634    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5635   "TARGET_HARD_FLOAT
5636    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5637   "#"
5638   ""
5639   [(pc)]
5641   rtx lowword;
5642   gcc_assert (MEM_P (operands[3]));
5643   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5645   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5646   emit_move_insn (operands[3], operands[2]);
5647   emit_move_insn (operands[0], lowword);
5648   DONE;
5650   [(set_attr "length" "16")
5651    (set_attr "type" "fp")])
5653 (define_expand "fix_trunc<mode>di2"
5654   [(set (match_operand:DI 0 "gpc_reg_operand")
5655         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5656   "TARGET_HARD_FLOAT && TARGET_FCFID"
5657   "")
5659 (define_insn "*fix_trunc<mode>di2_fctidz"
5660   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5661         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5662   "TARGET_HARD_FLOAT && TARGET_FCFID"
5663   "@
5664    fctidz %0,%1
5665    xscvdpsxds %x0,%x1"
5666   [(set_attr "type" "fp")])
5668 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5669 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5670 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5671 ;; values can go in VSX registers.  Keeping the direct move part through
5672 ;; register allocation prevents the register allocator from doing a direct move
5673 ;; of the SImode value to a GPR, and then a store/load.
5674 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5675   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5676         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5677    (clobber (match_scratch:SI 2 "=X,X,wi"))]
5678   "TARGET_DIRECT_MOVE"
5679   "@
5680    fctiw<u>z %0,%1
5681    xscvdp<su>xws %x0,%x1
5682    #"
5683   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5684   [(set (match_dup 2)
5685         (any_fix:SI (match_dup 1)))
5686    (set (match_dup 3)
5687         (match_dup 2))]
5689   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5691   [(set_attr "length" "4,4,8")
5692    (set_attr "type" "fp")])
5694 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5695   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5696         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5697   "TARGET_DIRECT_MOVE"
5698   "@
5699    fctiw<u>z %0,%1
5700    xscvdp<su>xws %x0,%x1"
5701   [(set_attr "type" "fp")])
5703 ;; Keep the convert and store together through register allocation to prevent
5704 ;; the register allocator from getting clever and doing a direct move to a GPR
5705 ;; and then store for reg+offset stores.
5706 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5707   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5708         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5709    (clobber (match_scratch:SI 2 "=wa"))]
5710     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5711   "#"
5712   "&& reload_completed"
5713   [(set (match_dup 2)
5714         (any_fix:SI (match_dup 1)))
5715    (set (match_dup 0)
5716         (match_dup 3))]
5718   operands[3] = (<QHSI:MODE>mode == SImode
5719                  ? operands[2]
5720                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5723 (define_expand "fixuns_trunc<mode>si2"
5724   [(set (match_operand:SI 0 "gpc_reg_operand")
5725         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5726   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5728   if (!TARGET_P8_VECTOR)
5729     {
5730       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5731       DONE;
5732     }
5735 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5736   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5737         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5738    (clobber (match_scratch:DI 2 "=d"))]
5739   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5740    && TARGET_STFIWX && can_create_pseudo_p ()
5741    && !TARGET_P8_VECTOR"
5742   "#"
5743   ""
5744   [(pc)]
5746   rtx dest = operands[0];
5747   rtx src = operands[1];
5748   rtx tmp = operands[2];
5750   if (GET_CODE (tmp) == SCRATCH)
5751     tmp = gen_reg_rtx (DImode);
5753   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5754   if (MEM_P (dest))
5755     {
5756       dest = rs6000_address_for_fpconvert (dest);
5757       emit_insn (gen_stfiwx (dest, tmp));
5758       DONE;
5759     }
5760   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5761     {
5762       dest = gen_lowpart (DImode, dest);
5763       emit_move_insn (dest, tmp);
5764       DONE;
5765     }
5766   else
5767     {
5768       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5769       emit_insn (gen_stfiwx (stack, tmp));
5770       emit_move_insn (dest, stack);
5771       DONE;
5772     }
5774   [(set_attr "length" "12")
5775    (set_attr "type" "fp")])
5777 (define_insn "fixuns_trunc<mode>di2"
5778   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5779         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5780   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5781   "@
5782    fctiduz %0,%1
5783    xscvdpuxds %x0,%x1"
5784   [(set_attr "type" "fp")])
5786 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5787 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5788 ;; because the first makes it clear that operand 0 is not live
5789 ;; before the instruction.
5790 (define_insn "fctiwz_<mode>"
5791   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5792         (unspec:DI [(fix:SI
5793                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5794                    UNSPEC_FCTIWZ))]
5795   "TARGET_HARD_FLOAT"
5796   "@
5797    fctiwz %0,%1
5798    xscvdpsxws %x0,%x1"
5799   [(set_attr "type" "fp")])
5801 (define_insn "fctiwuz_<mode>"
5802   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5803         (unspec:DI [(unsigned_fix:SI
5804                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5805                    UNSPEC_FCTIWUZ))]
5806   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5807   "@
5808    fctiwuz %0,%1
5809    xscvdpuxws %x0,%x1"
5810   [(set_attr "type" "fp")])
5812 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5813 ;; since the friz instruction does not truncate the value if the floating
5814 ;; point value is < LONG_MIN or > LONG_MAX.
5815 (define_insn "*friz"
5816   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5817         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5818   "TARGET_HARD_FLOAT && TARGET_FPRND
5819    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5820   "@
5821    friz %0,%1
5822    xsrdpiz %x0,%x1"
5823   [(set_attr "type" "fp")])
5825 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5826 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5827 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5828 ;; extend it, store it back on the stack from the GPR, load it back into the
5829 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5830 ;; disable using store and load to sign/zero extend the value.
5831 (define_insn_and_split "*round32<mode>2_fprs"
5832   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5833         (float:SFDF
5834          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5835    (clobber (match_scratch:DI 2 "=d"))
5836    (clobber (match_scratch:DI 3 "=d"))]
5837   "TARGET_HARD_FLOAT
5838    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5839    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5840   "#"
5841   ""
5842   [(pc)]
5844   rtx dest = operands[0];
5845   rtx src = operands[1];
5846   rtx tmp1 = operands[2];
5847   rtx tmp2 = operands[3];
5848   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5850   if (GET_CODE (tmp1) == SCRATCH)
5851     tmp1 = gen_reg_rtx (DImode);
5852   if (GET_CODE (tmp2) == SCRATCH)
5853     tmp2 = gen_reg_rtx (DImode);
5855   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5856   emit_insn (gen_stfiwx (stack, tmp1));
5857   emit_insn (gen_lfiwax (tmp2, stack));
5858   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5859   DONE;
5861   [(set_attr "type" "fpload")
5862    (set_attr "length" "16")])
5864 (define_insn_and_split "*roundu32<mode>2_fprs"
5865   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5866         (unsigned_float:SFDF
5867          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5868    (clobber (match_scratch:DI 2 "=d"))
5869    (clobber (match_scratch:DI 3 "=d"))]
5870   "TARGET_HARD_FLOAT
5871    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5872    && can_create_pseudo_p ()"
5873   "#"
5874   ""
5875   [(pc)]
5877   rtx dest = operands[0];
5878   rtx src = operands[1];
5879   rtx tmp1 = operands[2];
5880   rtx tmp2 = operands[3];
5881   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5883   if (GET_CODE (tmp1) == SCRATCH)
5884     tmp1 = gen_reg_rtx (DImode);
5885   if (GET_CODE (tmp2) == SCRATCH)
5886     tmp2 = gen_reg_rtx (DImode);
5888   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5889   emit_insn (gen_stfiwx (stack, tmp1));
5890   emit_insn (gen_lfiwzx (tmp2, stack));
5891   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5892   DONE;
5894   [(set_attr "type" "fpload")
5895    (set_attr "length" "16")])
5897 ;; No VSX equivalent to fctid
5898 (define_insn "lrint<mode>di2"
5899   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5900         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5901                    UNSPEC_FCTID))]
5902   "TARGET_HARD_FLOAT && TARGET_FPRND"
5903   "fctid %0,%1"
5904   [(set_attr "type" "fp")])
5906 (define_insn "btrunc<mode>2"
5907   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5908         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5909                      UNSPEC_FRIZ))]
5910   "TARGET_HARD_FLOAT && TARGET_FPRND"
5911   "@
5912    friz %0,%1
5913    xsrdpiz %x0,%x1"
5914   [(set_attr "type" "fp")])
5916 (define_insn "ceil<mode>2"
5917   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5918         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5919                      UNSPEC_FRIP))]
5920   "TARGET_HARD_FLOAT && TARGET_FPRND"
5921   "@
5922    frip %0,%1
5923    xsrdpip %x0,%x1"
5924   [(set_attr "type" "fp")])
5926 (define_insn "floor<mode>2"
5927   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5928         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5929                      UNSPEC_FRIM))]
5930   "TARGET_HARD_FLOAT && TARGET_FPRND"
5931   "@
5932    frim %0,%1
5933    xsrdpim %x0,%x1"
5934   [(set_attr "type" "fp")])
5936 ;; No VSX equivalent to frin
5937 (define_insn "round<mode>2"
5938   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5939         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5940                      UNSPEC_FRIN))]
5941   "TARGET_HARD_FLOAT && TARGET_FPRND"
5942   "frin %0,%1"
5943   [(set_attr "type" "fp")])
5945 (define_insn "*xsrdpi<mode>2"
5946   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5947         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5948                      UNSPEC_XSRDPI))]
5949   "TARGET_HARD_FLOAT && TARGET_VSX"
5950   "xsrdpi %x0,%x1"
5951   [(set_attr "type" "fp")])
5953 (define_expand "lround<mode>di2"
5954   [(set (match_dup 2)
5955         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
5956                      UNSPEC_XSRDPI))
5957    (set (match_operand:DI 0 "gpc_reg_operand")
5958         (unspec:DI [(match_dup 2)]
5959                    UNSPEC_FCTID))]
5960   "TARGET_HARD_FLOAT && TARGET_VSX"
5962   operands[2] = gen_reg_rtx (<MODE>mode);
5965 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5966 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5967 ; is only generated for Power8 or later.
5968 (define_insn "stfiwx"
5969   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5970         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5971                    UNSPEC_STFIWX))]
5972   "TARGET_PPC_GFXOPT"
5973   "@
5974    stfiwx %1,%y0
5975    stxsiwx %x1,%y0"
5976   [(set_attr "type" "fpstore")])
5978 ;; If we don't have a direct conversion to single precision, don't enable this
5979 ;; conversion for 32-bit without fast math, because we don't have the insn to
5980 ;; generate the fixup swizzle to avoid double rounding problems.
5981 (define_expand "floatsisf2"
5982   [(set (match_operand:SF 0 "gpc_reg_operand")
5983         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5984   "TARGET_HARD_FLOAT
5985    && ((TARGET_FCFIDS && TARGET_LFIWAX)
5986        || (TARGET_FCFID
5987            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5989   if (TARGET_FCFIDS && TARGET_LFIWAX)
5990     {
5991       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5992       DONE;
5993     }
5994   else if (TARGET_FCFID && TARGET_LFIWAX)
5995     {
5996       rtx dfreg = gen_reg_rtx (DFmode);
5997       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5998       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5999       DONE;
6000     }
6001   else
6002     {
6003       rtx dreg = operands[1];
6004       if (!REG_P (dreg))
6005         dreg = force_reg (SImode, dreg);
6006       dreg = convert_to_mode (DImode, dreg, false);
6007       emit_insn (gen_floatdisf2 (operands[0], dreg));
6008       DONE;
6009     }
6012 (define_insn "floatdidf2"
6013   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6014         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6015   "TARGET_FCFID && TARGET_HARD_FLOAT"
6016   "@
6017    fcfid %0,%1
6018    xscvsxddp %x0,%x1"
6019   [(set_attr "type" "fp")])
6021 ; Allow the combiner to merge source memory operands to the conversion so that
6022 ; the optimizer/register allocator doesn't try to load the value too early in a
6023 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6024 ; hit.  We will split after reload to avoid the trip through the GPRs
6026 (define_insn_and_split "*floatdidf2_mem"
6027   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6028         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6029    (clobber (match_scratch:DI 2 "=d,wi"))]
6030   "TARGET_HARD_FLOAT && TARGET_FCFID"
6031   "#"
6032   "&& reload_completed"
6033   [(set (match_dup 2) (match_dup 1))
6034    (set (match_dup 0) (float:DF (match_dup 2)))]
6035   ""
6036   [(set_attr "length" "8")
6037    (set_attr "type" "fpload")])
6039 (define_expand "floatunsdidf2"
6040   [(set (match_operand:DF 0 "gpc_reg_operand")
6041         (unsigned_float:DF
6042          (match_operand:DI 1 "gpc_reg_operand")))]
6043   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6044   "")
6046 (define_insn "*floatunsdidf2_fcfidu"
6047   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6048         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6049   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6050   "@
6051    fcfidu %0,%1
6052    xscvuxddp %x0,%x1"
6053   [(set_attr "type" "fp")
6054    (set_attr "length" "4")])
6056 (define_insn_and_split "*floatunsdidf2_mem"
6057   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6058         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6059    (clobber (match_scratch:DI 2 "=d,wi"))]
6060   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6061   "#"
6062   "&& reload_completed"
6063   [(set (match_dup 2) (match_dup 1))
6064    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6065   ""
6066   [(set_attr "length" "8")
6067    (set_attr "type" "fpload")])
6069 (define_expand "floatdisf2"
6070   [(set (match_operand:SF 0 "gpc_reg_operand")
6071         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6072   "TARGET_FCFID && TARGET_HARD_FLOAT
6073    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6075   if (!TARGET_FCFIDS)
6076     {
6077       rtx val = operands[1];
6078       if (!flag_unsafe_math_optimizations)
6079         {
6080           rtx label = gen_label_rtx ();
6081           val = gen_reg_rtx (DImode);
6082           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6083           emit_label (label);
6084         }
6085       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6086       DONE;
6087     }
6090 (define_insn "floatdisf2_fcfids"
6091   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6092         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6093   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6094   "@
6095    fcfids %0,%1
6096    xscvsxdsp %x0,%x1"
6097   [(set_attr "type" "fp")])
6099 (define_insn_and_split "*floatdisf2_mem"
6100   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6101         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6102    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6103   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6104   "#"
6105   "&& reload_completed"
6106   [(pc)]
6108   emit_move_insn (operands[2], operands[1]);
6109   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6110   DONE;
6112   [(set_attr "length" "8")])
6114 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6115 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6116 ;; from double rounding.
6117 ;; Instead of creating a new cpu type for two FP operations, just use fp
6118 (define_insn_and_split "floatdisf2_internal1"
6119   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6120         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6121    (clobber (match_scratch:DF 2 "=d"))]
6122   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6123   "#"
6124   "&& reload_completed"
6125   [(set (match_dup 2)
6126         (float:DF (match_dup 1)))
6127    (set (match_dup 0)
6128         (float_truncate:SF (match_dup 2)))]
6129   ""
6130   [(set_attr "length" "8")
6131    (set_attr "type" "fp")])
6133 ;; Twiddles bits to avoid double rounding.
6134 ;; Bits that might be truncated when converting to DFmode are replaced
6135 ;; by a bit that won't be lost at that stage, but is below the SFmode
6136 ;; rounding position.
6137 (define_expand "floatdisf2_internal2"
6138   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6139                                               (const_int 53)))
6140               (clobber (reg:DI CA_REGNO))])
6141    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6142                                         (const_int 2047)))
6143    (set (match_dup 3) (plus:DI (match_dup 3)
6144                                (const_int 1)))
6145    (set (match_dup 0) (plus:DI (match_dup 0)
6146                                (const_int 2047)))
6147    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6148                                      (const_int 2)))
6149    (set (match_dup 0) (ior:DI (match_dup 0)
6150                               (match_dup 1)))
6151    (set (match_dup 0) (and:DI (match_dup 0)
6152                               (const_int -2048)))
6153    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6154                            (label_ref (match_operand:DI 2 ""))
6155                            (pc)))
6156    (set (match_dup 0) (match_dup 1))]
6157   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6159   operands[3] = gen_reg_rtx (DImode);
6160   operands[4] = gen_reg_rtx (CCUNSmode);
6163 (define_expand "floatunsdisf2"
6164   [(set (match_operand:SF 0 "gpc_reg_operand")
6165         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6166   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6167   "")
6169 (define_insn "floatunsdisf2_fcfidus"
6170   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6171         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6172   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6173   "@
6174    fcfidus %0,%1
6175    xscvuxdsp %x0,%x1"
6176   [(set_attr "type" "fp")])
6178 (define_insn_and_split "*floatunsdisf2_mem"
6179   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6180         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6181    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6182   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6183   "#"
6184   "&& reload_completed"
6185   [(pc)]
6187   emit_move_insn (operands[2], operands[1]);
6188   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6189   DONE;
6191   [(set_attr "length" "8")
6192    (set_attr "type" "fpload")])
6194 ;; Define the TImode operations that can be done in a small number
6195 ;; of instructions.  The & constraints are to prevent the register
6196 ;; allocator from allocating registers that overlap with the inputs
6197 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6198 ;; also allow for the output being the same as one of the inputs.
6200 (define_expand "addti3"
6201   [(set (match_operand:TI 0 "gpc_reg_operand")
6202         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6203                  (match_operand:TI 2 "reg_or_short_operand")))]
6204   "TARGET_64BIT"
6206   rtx lo0 = gen_lowpart (DImode, operands[0]);
6207   rtx lo1 = gen_lowpart (DImode, operands[1]);
6208   rtx lo2 = gen_lowpart (DImode, operands[2]);
6209   rtx hi0 = gen_highpart (DImode, operands[0]);
6210   rtx hi1 = gen_highpart (DImode, operands[1]);
6211   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6213   if (!reg_or_short_operand (lo2, DImode))
6214     lo2 = force_reg (DImode, lo2);
6215   if (!adde_operand (hi2, DImode))
6216     hi2 = force_reg (DImode, hi2);
6218   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6219   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6220   DONE;
6223 (define_expand "subti3"
6224   [(set (match_operand:TI 0 "gpc_reg_operand")
6225         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6226                   (match_operand:TI 2 "gpc_reg_operand")))]
6227   "TARGET_64BIT"
6229   rtx lo0 = gen_lowpart (DImode, operands[0]);
6230   rtx lo1 = gen_lowpart (DImode, operands[1]);
6231   rtx lo2 = gen_lowpart (DImode, operands[2]);
6232   rtx hi0 = gen_highpart (DImode, operands[0]);
6233   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6234   rtx hi2 = gen_highpart (DImode, operands[2]);
6236   if (!reg_or_short_operand (lo1, DImode))
6237     lo1 = force_reg (DImode, lo1);
6238   if (!adde_operand (hi1, DImode))
6239     hi1 = force_reg (DImode, hi1);
6241   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6242   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6243   DONE;
6246 ;; 128-bit logical operations expanders
6248 (define_expand "and<mode>3"
6249   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6250         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6251                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6252   ""
6253   "")
6255 (define_expand "ior<mode>3"
6256   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6257         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6258                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6259   ""
6260   "")
6262 (define_expand "xor<mode>3"
6263   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6264         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6265                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6266   ""
6267   "")
6269 (define_expand "one_cmpl<mode>2"
6270   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6271         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6272   ""
6273   "")
6275 (define_expand "nor<mode>3"
6276   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6277         (and:BOOL_128
6278          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6279          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6280   ""
6281   "")
6283 (define_expand "andc<mode>3"
6284   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6285         (and:BOOL_128
6286          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6287          (match_operand:BOOL_128 1 "vlogical_operand")))]
6288   ""
6289   "")
6291 ;; Power8 vector logical instructions.
6292 (define_expand "eqv<mode>3"
6293   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6294         (not:BOOL_128
6295          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6296                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6297   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6298   "")
6300 ;; Rewrite nand into canonical form
6301 (define_expand "nand<mode>3"
6302   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6303         (ior:BOOL_128
6304          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6305          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6306   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6307   "")
6309 ;; The canonical form is to have the negated element first, so we need to
6310 ;; reverse arguments.
6311 (define_expand "orc<mode>3"
6312   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6313         (ior:BOOL_128
6314          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6315          (match_operand:BOOL_128 1 "vlogical_operand")))]
6316   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6317   "")
6319 ;; 128-bit logical operations insns and split operations
6320 (define_insn_and_split "*and<mode>3_internal"
6321   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6322         (and:BOOL_128
6323          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6324          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6325   ""
6327   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6328     return "xxland %x0,%x1,%x2";
6330   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6331     return "vand %0,%1,%2";
6333   return "#";
6335   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6336   [(const_int 0)]
6338   rs6000_split_logical (operands, AND, false, false, false);
6339   DONE;
6341   [(set (attr "type")
6342       (if_then_else
6343         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6344         (const_string "veclogical")
6345         (const_string "integer")))
6346    (set (attr "length")
6347       (if_then_else
6348         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6349         (const_string "4")
6350         (if_then_else
6351          (match_test "TARGET_POWERPC64")
6352          (const_string "8")
6353          (const_string "16"))))])
6355 ;; 128-bit IOR/XOR
6356 (define_insn_and_split "*bool<mode>3_internal"
6357   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6358         (match_operator:BOOL_128 3 "boolean_or_operator"
6359          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6360           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6361   ""
6363   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6364     return "xxl%q3 %x0,%x1,%x2";
6366   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6367     return "v%q3 %0,%1,%2";
6369   return "#";
6371   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6372   [(const_int 0)]
6374   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6375   DONE;
6377   [(set (attr "type")
6378       (if_then_else
6379         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6380         (const_string "veclogical")
6381         (const_string "integer")))
6382    (set (attr "length")
6383       (if_then_else
6384         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6385         (const_string "4")
6386         (if_then_else
6387          (match_test "TARGET_POWERPC64")
6388          (const_string "8")
6389          (const_string "16"))))])
6391 ;; 128-bit ANDC/ORC
6392 (define_insn_and_split "*boolc<mode>3_internal1"
6393   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6394         (match_operator:BOOL_128 3 "boolean_operator"
6395          [(not:BOOL_128
6396            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6397           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6398   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6400   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6401     return "xxl%q3 %x0,%x1,%x2";
6403   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6404     return "v%q3 %0,%1,%2";
6406   return "#";
6408   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6409    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6410   [(const_int 0)]
6412   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6413   DONE;
6415   [(set (attr "type")
6416       (if_then_else
6417         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6418         (const_string "veclogical")
6419         (const_string "integer")))
6420    (set (attr "length")
6421       (if_then_else
6422         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6423         (const_string "4")
6424         (if_then_else
6425          (match_test "TARGET_POWERPC64")
6426          (const_string "8")
6427          (const_string "16"))))])
6429 (define_insn_and_split "*boolc<mode>3_internal2"
6430   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6431         (match_operator:TI2 3 "boolean_operator"
6432          [(not:TI2
6433            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6434           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6435   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6436   "#"
6437   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6438   [(const_int 0)]
6440   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6441   DONE;
6443   [(set_attr "type" "integer")
6444    (set (attr "length")
6445         (if_then_else
6446          (match_test "TARGET_POWERPC64")
6447          (const_string "8")
6448          (const_string "16")))])
6450 ;; 128-bit NAND/NOR
6451 (define_insn_and_split "*boolcc<mode>3_internal1"
6452   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6453         (match_operator:BOOL_128 3 "boolean_operator"
6454          [(not:BOOL_128
6455            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6456           (not:BOOL_128
6457            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6458   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6460   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6461     return "xxl%q3 %x0,%x1,%x2";
6463   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6464     return "v%q3 %0,%1,%2";
6466   return "#";
6468   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6469    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6470   [(const_int 0)]
6472   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6473   DONE;
6475   [(set (attr "type")
6476       (if_then_else
6477         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6478         (const_string "veclogical")
6479         (const_string "integer")))
6480    (set (attr "length")
6481       (if_then_else
6482         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6483         (const_string "4")
6484         (if_then_else
6485          (match_test "TARGET_POWERPC64")
6486          (const_string "8")
6487          (const_string "16"))))])
6489 (define_insn_and_split "*boolcc<mode>3_internal2"
6490   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6491         (match_operator:TI2 3 "boolean_operator"
6492          [(not:TI2
6493            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6494           (not:TI2
6495            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6496   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6497   "#"
6498   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6499   [(const_int 0)]
6501   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6502   DONE;
6504   [(set_attr "type" "integer")
6505    (set (attr "length")
6506         (if_then_else
6507          (match_test "TARGET_POWERPC64")
6508          (const_string "8")
6509          (const_string "16")))])
6512 ;; 128-bit EQV
6513 (define_insn_and_split "*eqv<mode>3_internal1"
6514   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6515         (not:BOOL_128
6516          (xor:BOOL_128
6517           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6518           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6519   "TARGET_P8_VECTOR"
6521   if (vsx_register_operand (operands[0], <MODE>mode))
6522     return "xxleqv %x0,%x1,%x2";
6524   return "#";
6526   "TARGET_P8_VECTOR && reload_completed
6527    && int_reg_operand (operands[0], <MODE>mode)"
6528   [(const_int 0)]
6530   rs6000_split_logical (operands, XOR, true, false, false);
6531   DONE;
6533   [(set (attr "type")
6534       (if_then_else
6535         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6536         (const_string "veclogical")
6537         (const_string "integer")))
6538    (set (attr "length")
6539       (if_then_else
6540         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6541         (const_string "4")
6542         (if_then_else
6543          (match_test "TARGET_POWERPC64")
6544          (const_string "8")
6545          (const_string "16"))))])
6547 (define_insn_and_split "*eqv<mode>3_internal2"
6548   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6549         (not:TI2
6550          (xor:TI2
6551           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6552           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6553   "!TARGET_P8_VECTOR"
6554   "#"
6555   "reload_completed && !TARGET_P8_VECTOR"
6556   [(const_int 0)]
6558   rs6000_split_logical (operands, XOR, true, false, false);
6559   DONE;
6561   [(set_attr "type" "integer")
6562    (set (attr "length")
6563         (if_then_else
6564          (match_test "TARGET_POWERPC64")
6565          (const_string "8")
6566          (const_string "16")))])
6568 ;; 128-bit one's complement
6569 (define_insn_and_split "*one_cmpl<mode>3_internal"
6570   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6571         (not:BOOL_128
6572           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6573   ""
6575   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6576     return "xxlnor %x0,%x1,%x1";
6578   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6579     return "vnor %0,%1,%1";
6581   return "#";
6583   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6584   [(const_int 0)]
6586   rs6000_split_logical (operands, NOT, false, false, false);
6587   DONE;
6589   [(set (attr "type")
6590       (if_then_else
6591         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6592         (const_string "veclogical")
6593         (const_string "integer")))
6594    (set (attr "length")
6595       (if_then_else
6596         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6597         (const_string "4")
6598         (if_then_else
6599          (match_test "TARGET_POWERPC64")
6600          (const_string "8")
6601          (const_string "16"))))])
6604 ;; Now define ways of moving data around.
6606 ;; Set up a register with a value from the GOT table
6608 (define_expand "movsi_got"
6609   [(set (match_operand:SI 0 "gpc_reg_operand")
6610         (unspec:SI [(match_operand:SI 1 "got_operand")
6611                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6612   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6614   if (GET_CODE (operands[1]) == CONST)
6615     {
6616       rtx offset = const0_rtx;
6617       HOST_WIDE_INT value;
6619       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6620       value = INTVAL (offset);
6621       if (value != 0)
6622         {
6623           rtx tmp = (!can_create_pseudo_p ()
6624                      ? operands[0]
6625                      : gen_reg_rtx (Pmode));
6626           emit_insn (gen_movsi_got (tmp, operands[1]));
6627           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6628           DONE;
6629         }
6630     }
6632   operands[2] = rs6000_got_register (operands[1]);
6635 (define_insn "*movsi_got_internal"
6636   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6637         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6638                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6639                    UNSPEC_MOVSI_GOT))]
6640   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6641   "lwz %0,%a1@got(%2)"
6642   [(set_attr "type" "load")])
6644 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6645 ;; didn't get allocated to a hard register.
6646 (define_split
6647   [(set (match_operand:SI 0 "gpc_reg_operand")
6648         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6649                     (match_operand:SI 2 "memory_operand")]
6650                    UNSPEC_MOVSI_GOT))]
6651   "DEFAULT_ABI == ABI_V4
6652     && flag_pic == 1
6653     && reload_completed"
6654   [(set (match_dup 0) (match_dup 2))
6655    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6656                                  UNSPEC_MOVSI_GOT))]
6657   "")
6659 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6660 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6661 ;; and this is even supposed to be faster, but it is simpler not to get
6662 ;; integers in the TOC.
6663 (define_insn "movsi_low"
6664   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6665         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6666                            (match_operand 2 "" ""))))]
6667   "TARGET_MACHO && ! TARGET_64BIT"
6668   "lwz %0,lo16(%2)(%1)"
6669   [(set_attr "type" "load")
6670    (set_attr "length" "4")])
6672 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6673 ;;              STW          STFIWX       STXSIWX      LI           LIS
6674 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6675 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6676 ;;              MF%1         MT%0         MT%0         NOP
6677 (define_insn "*movsi_internal1"
6678   [(set (match_operand:SI 0 "nonimmediate_operand"
6679                 "=r,         r,           r,           ?*wI,        ?*wH,
6680                  m,          ?Z,          ?Z,          r,           r,
6681                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6682                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6683                  r,          *c*l,        *h,          *h")
6685         (match_operand:SI 1 "input_operand"
6686                 "r,          U,           m,           Z,           Z,
6687                  r,          wI,          wH,          I,           L,
6688                  n,          wIwH,        O,           wM,          wB,
6689                  O,          wM,          wS,          r,           wIwH,
6690                  *h,         r,           r,           0"))]
6692   "gpc_reg_operand (operands[0], SImode)
6693    || gpc_reg_operand (operands[1], SImode)"
6694   "@
6695    mr %0,%1
6696    la %0,%a1
6697    lwz%U1%X1 %0,%1
6698    lfiwzx %0,%y1
6699    lxsiwzx %x0,%y1
6700    stw%U0%X0 %1,%0
6701    stfiwx %1,%y0
6702    stxsiwx %x1,%y0
6703    li %0,%1
6704    lis %0,%v1
6705    #
6706    xxlor %x0,%x1,%x1
6707    xxspltib %x0,0
6708    xxspltib %x0,255
6709    vspltisw %0,%1
6710    xxlxor %x0,%x0,%x0
6711    xxlorc %x0,%x0,%x0
6712    #
6713    mtvsrwz %x0,%1
6714    mfvsrwz %0,%x1
6715    mf%1 %0
6716    mt%0 %1
6717    mt%0 %1
6718    nop"
6719   [(set_attr "type"
6720                 "*,          *,           load,        fpload,      fpload,
6721                  store,      fpstore,     fpstore,     *,           *,
6722                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6723                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6724                  *,           *,           *,           *")
6726    (set_attr "length"
6727                 "4,          4,           4,           4,           4,
6728                  4,          4,           4,           4,           4,
6729                  8,          4,           4,           4,           4,
6730                  4,          4,           8,           4,           4,
6731                  4,          4,           4,           4")])
6733 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6734 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6736 ;; Because SF values are actually stored as DF values within the vector
6737 ;; registers, we need to convert the value to the vector SF format when
6738 ;; we need to use the bits in a union or similar cases.  We only need
6739 ;; to do this transformation when the value is a vector register.  Loads,
6740 ;; stores, and transfers within GPRs are assumed to be safe.
6742 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6743 ;; no alternatives, because the call is created as part of secondary_reload,
6744 ;; and operand #2's register class is used to allocate the temporary register.
6745 ;; This function is called before reload, and it creates the temporary as
6746 ;; needed.
6748 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6749 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6750 ;;              MTVSRWZ
6752 (define_insn_and_split "movsi_from_sf"
6753   [(set (match_operand:SI 0 "nonimmediate_operand"
6754                 "=r,         r,           ?*wI,        ?*wH,     m,
6755                  m,          wY,          Z,           r,        ?*wIwH,
6756                  wIwH")
6758         (unspec:SI [(match_operand:SF 1 "input_operand"
6759                 "r,          m,           Z,           Z,        r,
6760                  f,          wb,          wu,          wIwH,     wIwH,
6761                  r")]
6762                     UNSPEC_SI_FROM_SF))
6764    (clobber (match_scratch:V4SF 2
6765                 "=X,         X,           X,           X,        X,
6766                  X,          X,           X,           wIwH,     X,
6767                  X"))]
6769   "TARGET_NO_SF_SUBREG
6770    && (register_operand (operands[0], SImode)
6771        || register_operand (operands[1], SFmode))"
6772   "@
6773    mr %0,%1
6774    lwz%U1%X1 %0,%1
6775    lfiwzx %0,%y1
6776    lxsiwzx %x0,%y1
6777    stw%U0%X0 %1,%0
6778    stfs%U0%X0 %1,%0
6779    stxssp %1,%0
6780    stxsspx %x1,%y0
6781    #
6782    xscvdpspn %x0,%x1
6783    mtvsrwz %x0,%1"
6784   "&& reload_completed
6785    && int_reg_operand (operands[0], SImode)
6786    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6787   [(const_int 0)]
6789   rtx op0 = operands[0];
6790   rtx op1 = operands[1];
6791   rtx op2 = operands[2];
6792   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6793   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6795   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6796   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6797   DONE;
6799   [(set_attr "type"
6800                 "*,          load,        fpload,      fpload,   store,
6801                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6802                  mffgpr")
6804    (set_attr "length"
6805                 "4,          4,           4,           4,        4,
6806                  4,          4,           4,           8,        4,
6807                  4")])
6809 ;; movsi_from_sf with zero extension
6811 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6812 ;;              VSX->VSX     MTVSRWZ
6814 (define_insn_and_split "*movdi_from_sf_zero_ext"
6815   [(set (match_operand:DI 0 "gpc_reg_operand"
6816                 "=r,         r,           ?*wI,        ?*wH,     r,
6817                  ?wK,        wIwH")
6819         (zero_extend:DI
6820          (unspec:SI [(match_operand:SF 1 "input_operand"
6821                 "r,          m,           Z,           Z,        wIwH,
6822                  wIwH,       r")]
6823                     UNSPEC_SI_FROM_SF)))
6825    (clobber (match_scratch:V4SF 2
6826                 "=X,         X,           X,           X,        wa,
6827                  wIwH,       X"))]
6829   "TARGET_DIRECT_MOVE_64BIT
6830    && (register_operand (operands[0], DImode)
6831        || register_operand (operands[1], SImode))"
6832   "@
6833    rldicl %0,%1,0,32
6834    lwz%U1%X1 %0,%1
6835    lfiwzx %0,%y1
6836    lxsiwzx %x0,%y1
6837    #
6838    #
6839    mtvsrwz %x0,%1"
6840   "&& reload_completed
6841    && register_operand (operands[0], DImode)
6842    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6843   [(const_int 0)]
6845   rtx op0 = operands[0];
6846   rtx op1 = operands[1];
6847   rtx op2 = operands[2];
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, op2_si));
6852   DONE;
6854   [(set_attr "type"
6855                 "*,          load,        fpload,      fpload,   two,
6856                  two,        mffgpr")
6858    (set_attr "length"
6859                 "4,          4,           4,           4,        8,
6860                  8,          4")])
6862 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6863 ;; moving it to SImode.  We can do a SFmode store without having to do the
6864 ;; conversion explicitly.  If we are doing a register->register conversion, use
6865 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6866 ;; input will not fit in a SFmode, and the later assumes the value has already
6867 ;; been rounded.
6868 (define_insn "*movsi_from_df"
6869   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
6870         (unspec:SI [(float_truncate:SF
6871                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6872                     UNSPEC_SI_FROM_SF))]
6874   "TARGET_NO_SF_SUBREG"
6875   "@
6876    xscvdpsp %x0,%x1
6877    stfs%U0%X0 %1,%0
6878    stxssp %1,%0
6879    stxsspx %x1,%y0"
6880   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
6882 ;; Split a load of a large constant into the appropriate two-insn
6883 ;; sequence.
6885 (define_split
6886   [(set (match_operand:SI 0 "gpc_reg_operand")
6887         (match_operand:SI 1 "const_int_operand"))]
6888   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6889    && (INTVAL (operands[1]) & 0xffff) != 0"
6890   [(set (match_dup 0)
6891         (match_dup 2))
6892    (set (match_dup 0)
6893         (ior:SI (match_dup 0)
6894                 (match_dup 3)))]
6896   if (rs6000_emit_set_const (operands[0], operands[1]))
6897     DONE;
6898   else
6899     FAIL;
6902 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6903 (define_split
6904   [(set (match_operand:DI 0 "altivec_register_operand")
6905         (match_operand:DI 1 "xxspltib_constant_split"))]
6906   "TARGET_P9_VECTOR && reload_completed"
6907   [(const_int 0)]
6909   rtx op0 = operands[0];
6910   rtx op1 = operands[1];
6911   int r = REGNO (op0);
6912   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6914   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6915   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6916   DONE;
6919 (define_insn "*mov<mode>_internal2"
6920   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6921         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6922                     (const_int 0)))
6923    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6924   ""
6925   "@
6926    cmp<wd>i %2,%0,0
6927    mr. %0,%1
6928    #"
6929   [(set_attr "type" "cmp,logical,cmp")
6930    (set_attr "dot" "yes")
6931    (set_attr "length" "4,4,8")])
6933 (define_split
6934   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6935         (compare:CC (match_operand:P 1 "gpc_reg_operand")
6936                     (const_int 0)))
6937    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6938   "reload_completed"
6939   [(set (match_dup 0) (match_dup 1))
6940    (set (match_dup 2)
6941         (compare:CC (match_dup 0)
6942                     (const_int 0)))]
6943   "")
6945 (define_expand "mov<mode>"
6946   [(set (match_operand:INT 0 "general_operand")
6947         (match_operand:INT 1 "any_operand"))]
6948   ""
6950   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
6951   DONE;
6954 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
6955 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
6956 ;;              MTVSRWZ     MF%1       MT%1       NOP
6957 (define_insn "*mov<mode>_internal"
6958   [(set (match_operand:QHI 0 "nonimmediate_operand"
6959                 "=r,        r,         ?*wJwK,    m,         Z,         r,
6960                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
6961                  ?*wJwK,    r,         *c*l,      *h")
6963         (match_operand:QHI 1 "input_operand"
6964                 "r,         m,         Z,         r,         wJwK,      i,
6965                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
6966                  r,         *h,        r,         0"))]
6968   "gpc_reg_operand (operands[0], <MODE>mode)
6969    || gpc_reg_operand (operands[1], <MODE>mode)"
6970   "@
6971    mr %0,%1
6972    l<wd>z%U1%X1 %0,%1
6973    lxsi<wd>zx %x0,%y1
6974    st<wd>%U0%X0 %1,%0
6975    stxsi<wd>x %x1,%y0
6976    li %0,%1
6977    xxlor %x0,%x1,%x1
6978    xxspltib %x0,0
6979    xxspltib %x0,255
6980    vspltis<wd> %0,%1
6981    #
6982    mfvsrwz %0,%x1
6983    mtvsrwz %x0,%1
6984    mf%1 %0
6985    mt%0 %1
6986    nop"
6987   [(set_attr "type"
6988                 "*,         load,      fpload,    store,     fpstore,   *,
6989                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
6990                  mffgpr,    mfjmpr,    mtjmpr,    *")
6992    (set_attr "length"
6993                 "4,         4,         4,         4,         4,         4,
6994                  4,         4,         4,         4,         8,         4,
6995                  4,         4,         4,         4")])
6998 ;; Here is how to move condition codes around.  When we store CC data in
6999 ;; an integer register or memory, we store just the high-order 4 bits.
7000 ;; This lets us not shift in the most common case of CR0.
7001 (define_expand "movcc"
7002   [(set (match_operand:CC 0 "nonimmediate_operand")
7003         (match_operand:CC 1 "nonimmediate_operand"))]
7004   ""
7005   "")
7007 (define_insn "*movcc_internal1"
7008   [(set (match_operand:CC 0 "nonimmediate_operand"
7009                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7010         (match_operand:CC 1 "general_operand"
7011                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7012   "register_operand (operands[0], CCmode)
7013    || register_operand (operands[1], CCmode)"
7014   "@
7015    mcrf %0,%1
7016    mtcrf 128,%1
7017    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7018    crxor %0,%0,%0
7019    mfcr %0%Q1
7020    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7021    mr %0,%1
7022    li %0,%1
7023    mf%1 %0
7024    mt%0 %1
7025    lwz%U1%X1 %0,%1
7026    stw%U0%X0 %1,%0"
7027   [(set (attr "type")
7028      (cond [(eq_attr "alternative" "0,3")
7029                 (const_string "cr_logical")
7030             (eq_attr "alternative" "1,2")
7031                 (const_string "mtcr")
7032             (eq_attr "alternative" "6,7")
7033                 (const_string "integer")
7034             (eq_attr "alternative" "8")
7035                 (const_string "mfjmpr")
7036             (eq_attr "alternative" "9")
7037                 (const_string "mtjmpr")
7038             (eq_attr "alternative" "10")
7039                 (const_string "load")
7040             (eq_attr "alternative" "11")
7041                 (const_string "store")
7042             (match_test "TARGET_MFCRF")
7043                 (const_string "mfcrf")
7044            ]
7045         (const_string "mfcr")))
7046    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7048 ;; For floating-point, we normally deal with the floating-point registers
7049 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7050 ;; can produce floating-point values in fixed-point registers.  Unless the
7051 ;; value is a simple constant or already in memory, we deal with this by
7052 ;; allocating memory and copying the value explicitly via that memory location.
7054 ;; Move 32-bit binary/decimal floating point
7055 (define_expand "mov<mode>"
7056   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7057         (match_operand:FMOVE32 1 "any_operand"))]
7058   "<fmove_ok>"
7060   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7061   DONE;
7064 (define_split
7065   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7066         (match_operand:FMOVE32 1 "const_double_operand"))]
7067   "reload_completed
7068    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7069        || (GET_CODE (operands[0]) == SUBREG
7070            && GET_CODE (SUBREG_REG (operands[0])) == REG
7071            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7072   [(set (match_dup 2) (match_dup 3))]
7074   long l;
7076   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7078   if (! TARGET_POWERPC64)
7079     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7080   else
7081     operands[2] = gen_lowpart (SImode, operands[0]);
7083   operands[3] = gen_int_mode (l, SImode);
7086 ;; Originally, we tried to keep movsf and movsd common, but the differences
7087 ;; addressing was making it rather difficult to hide with mode attributes.  In
7088 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7089 ;; before the VSX stores meant that the register allocator would tend to do a
7090 ;; direct move to the GPR (which involves conversion from scalar to
7091 ;; vector/memory formats) to save values in the traditional Altivec registers,
7092 ;; while SDmode had problems on power6 if the GPR store was not first due to
7093 ;; the power6 not having an integer store operation.
7095 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7096 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7097 ;;      MR           MT<x>      MF<x>       NOP
7099 (define_insn "movsf_hardfloat"
7100   [(set (match_operand:SF 0 "nonimmediate_operand"
7101          "=!r,       f,         wb,         wu,        m,         wY,
7102           Z,         m,         ww,         !r,        f,         ww,
7103           !r,        *c*l,      !r,         *h")
7104         (match_operand:SF 1 "input_operand"
7105          "m,         m,         wY,         Z,         f,         wb,
7106           wu,        r,         j,          j,         f,         ww,
7107           r,         r,         *h,         0"))]
7108   "(register_operand (operands[0], SFmode)
7109    || register_operand (operands[1], SFmode))
7110    && TARGET_HARD_FLOAT
7111    && (TARGET_ALLOW_SF_SUBREG
7112        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7113   "@
7114    lwz%U1%X1 %0,%1
7115    lfs%U1%X1 %0,%1
7116    lxssp %0,%1
7117    lxsspx %x0,%y1
7118    stfs%U0%X0 %1,%0
7119    stxssp %1,%0
7120    stxsspx %x1,%y0
7121    stw%U0%X0 %1,%0
7122    xxlxor %x0,%x0,%x0
7123    li %0,0
7124    fmr %0,%1
7125    xscpsgndp %x0,%x1,%x1
7126    mr %0,%1
7127    mt%0 %1
7128    mf%1 %0
7129    nop"
7130   [(set_attr "type"
7131         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7132          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7133          *,          mtjmpr,    mfjmpr,     *")])
7135 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7136 ;;      FMR          MR         MT%0       MF%1       NOP
7137 (define_insn "movsd_hardfloat"
7138   [(set (match_operand:SD 0 "nonimmediate_operand"
7139          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7140           f,         !r,        *c*l,      !r,        *h")
7141         (match_operand:SD 1 "input_operand"
7142          "m,         Z,         r,         wx,        r,         wh,
7143           f,         r,         r,         *h,        0"))]
7144   "(register_operand (operands[0], SDmode)
7145    || register_operand (operands[1], SDmode))
7146    && TARGET_HARD_FLOAT"
7147   "@
7148    lwz%U1%X1 %0,%1
7149    lfiwzx %0,%y1
7150    stw%U0%X0 %1,%0
7151    stfiwx %1,%y0
7152    mtvsrwz %x0,%1
7153    mfvsrwz %0,%x1
7154    fmr %0,%1
7155    mr %0,%1
7156    mt%0 %1
7157    mf%1 %0
7158    nop"
7159   [(set_attr "type"
7160         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7161          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7163 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7164 ;;      LIS          G-const.   F/n-const  NOP
7165 (define_insn "*mov<mode>_softfloat"
7166   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7167         "=r,         cl,        r,         r,         m,         r,
7168           r,         r,         r,         *h")
7170         (match_operand:FMOVE32 1 "input_operand"
7171          "r,         r,         h,         m,         r,         I,
7172           L,         G,         Fn,        0"))]
7174   "(gpc_reg_operand (operands[0], <MODE>mode)
7175    || gpc_reg_operand (operands[1], <MODE>mode))
7176    && TARGET_SOFT_FLOAT"
7177   "@
7178    mr %0,%1
7179    mt%0 %1
7180    mf%1 %0
7181    lwz%U1%X1 %0,%1
7182    stw%U0%X0 %1,%0
7183    li %0,%1
7184    lis %0,%v1
7185    #
7186    #
7187    nop"
7188   [(set_attr "type"
7189         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7190          *,          *,         *,         *")
7192    (set_attr "length"
7193         "4,          4,         4,         4,         4,         4,
7194          4,          4,         8,         4")])
7196 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7197 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7199 ;; Because SF values are actually stored as DF values within the vector
7200 ;; registers, we need to convert the value to the vector SF format when
7201 ;; we need to use the bits in a union or similar cases.  We only need
7202 ;; to do this transformation when the value is a vector register.  Loads,
7203 ;; stores, and transfers within GPRs are assumed to be safe.
7205 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7206 ;; no alternatives, because the call is created as part of secondary_reload,
7207 ;; and operand #2's register class is used to allocate the temporary register.
7208 ;; This function is called before reload, and it creates the temporary as
7209 ;; needed.
7211 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7212 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7213 (define_insn_and_split "movsf_from_si"
7214   [(set (match_operand:SF 0 "nonimmediate_operand"
7215             "=!r,       f,         wb,        wu,        m,         Z,
7216              Z,         wy,        ?r,        !r")
7218         (unspec:SF [(match_operand:SI 1 "input_operand" 
7219             "m,         m,         wY,        Z,         r,         f,
7220              wu,        r,         wy,        r")]
7221                    UNSPEC_SF_FROM_SI))
7223    (clobber (match_scratch:DI 2
7224             "=X,        X,         X,         X,         X,         X,
7225              X,         r,         X,         X"))]
7227   "TARGET_NO_SF_SUBREG
7228    && (register_operand (operands[0], SFmode)
7229        || register_operand (operands[1], SImode))"
7230   "@
7231    lwz%U1%X1 %0,%1
7232    lfs%U1%X1 %0,%1
7233    lxssp %0,%1
7234    lxsspx %x0,%y1
7235    stw%U0%X0 %1,%0
7236    stfiwx %1,%y0
7237    stxsiwx %x1,%y0
7238    #
7239    mfvsrwz %0,%x1
7240    mr %0,%1"
7242   "&& reload_completed
7243    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7244    && int_reg_operand_not_pseudo (operands[1], SImode)"
7245   [(const_int 0)]
7247   rtx op0 = operands[0];
7248   rtx op1 = operands[1];
7249   rtx op2 = operands[2];
7250   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7252   /* Move SF value to upper 32-bits for xscvspdpn.  */
7253   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7254   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7255   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7256   DONE;
7258   [(set_attr "length"
7259             "4,          4,         4,         4,         4,         4,
7260              4,          12,        4,         4")
7261    (set_attr "type"
7262             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7263              fpstore,    vecfloat,  mffgpr,    *")])
7266 ;; Move 64-bit binary/decimal floating point
7267 (define_expand "mov<mode>"
7268   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7269         (match_operand:FMOVE64 1 "any_operand"))]
7270   ""
7272   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7273   DONE;
7276 (define_split
7277   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7278         (match_operand:FMOVE64 1 "const_int_operand"))]
7279   "! TARGET_POWERPC64 && reload_completed
7280    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7281        || (GET_CODE (operands[0]) == SUBREG
7282            && GET_CODE (SUBREG_REG (operands[0])) == REG
7283            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7284   [(set (match_dup 2) (match_dup 4))
7285    (set (match_dup 3) (match_dup 1))]
7287   int endian = (WORDS_BIG_ENDIAN == 0);
7288   HOST_WIDE_INT value = INTVAL (operands[1]);
7290   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7291   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7292   operands[4] = GEN_INT (value >> 32);
7293   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7296 (define_split
7297   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7298         (match_operand:FMOVE64 1 "const_double_operand"))]
7299   "! TARGET_POWERPC64 && reload_completed
7300    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7301        || (GET_CODE (operands[0]) == SUBREG
7302            && GET_CODE (SUBREG_REG (operands[0])) == REG
7303            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7304   [(set (match_dup 2) (match_dup 4))
7305    (set (match_dup 3) (match_dup 5))]
7307   int endian = (WORDS_BIG_ENDIAN == 0);
7308   long l[2];
7310   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7312   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7313   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7314   operands[4] = gen_int_mode (l[endian], SImode);
7315   operands[5] = gen_int_mode (l[1 - endian], SImode);
7318 (define_split
7319   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7320         (match_operand:FMOVE64 1 "const_double_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 3))]
7328   int endian = (WORDS_BIG_ENDIAN == 0);
7329   long l[2];
7330   HOST_WIDE_INT val;
7332   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7334   operands[2] = gen_lowpart (DImode, operands[0]);
7335   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7336   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7337          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7339   operands[3] = gen_int_mode (val, DImode);
7342 ;; Don't have reload use general registers to load a constant.  It is
7343 ;; less efficient than loading the constant into an FP register, since
7344 ;; it will probably be used there.
7346 ;; The move constraints are ordered to prefer floating point registers before
7347 ;; general purpose registers to avoid doing a store and a load to get the value
7348 ;; into a floating point register when it is needed for a floating point
7349 ;; operation.  Prefer traditional floating point registers over VSX registers,
7350 ;; since the D-form version of the memory instructions does not need a GPR for
7351 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7352 ;; registers.
7354 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7355 ;; except for 0.0 which can be created on VSX with an xor instruction.
7357 ;;           STFD         LFD         FMR         LXSD        STXSD
7358 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7359 ;;           LWZ          STW         MR
7362 (define_insn "*mov<mode>_hardfloat32"
7363   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7364             "=m,          d,          d,          <f64_p9>,   wY,
7365               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7366               Y,          r,          !r")
7368         (match_operand:FMOVE64 1 "input_operand"
7369              "d,          m,          d,          wY,         <f64_p9>,
7370               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7371               r,          Y,          r"))]
7373   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7374    && (gpc_reg_operand (operands[0], <MODE>mode)
7375        || gpc_reg_operand (operands[1], <MODE>mode))"
7376   "@
7377    stfd%U0%X0 %1,%0
7378    lfd%U1%X1 %0,%1
7379    fmr %0,%1
7380    lxsd %0,%1
7381    stxsd %1,%0
7382    lxsd%U1x %x0,%y1
7383    stxsd%U0x %x1,%y0
7384    xxlor %x0,%x1,%x1
7385    xxlxor %x0,%x0,%x0
7386    #
7387    #
7388    #
7389    #"
7390   [(set_attr "type"
7391             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7392              fpload,      fpstore,    veclogical, veclogical, two,
7393              store,       load,       two")
7395    (set_attr "size" "64")
7396    (set_attr "length"
7397             "4,           4,          4,          4,          4,
7398              4,           4,          4,          4,          8,
7399              8,           8,          8")])
7401 ;;           STW      LWZ     MR      G-const H-const F-const
7403 (define_insn "*mov<mode>_softfloat32"
7404   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7405            "=Y,       r,      r,      r,      r,      r")
7407         (match_operand:FMOVE64 1 "input_operand"
7408             "r,       Y,      r,      G,      H,      F"))]
7410   "!TARGET_POWERPC64
7411    && (gpc_reg_operand (operands[0], <MODE>mode)
7412        || gpc_reg_operand (operands[1], <MODE>mode))"
7413   "#"
7414   [(set_attr "type"
7415             "store,   load,   two,    *,      *,      *")
7417    (set_attr "length"
7418              "8,      8,      8,      8,      12,     16")])
7420 ; ld/std require word-aligned displacements -> 'Y' constraint.
7421 ; List Y->r and r->Y before r->r for reload.
7423 ;;           STFD         LFD         FMR         LXSD        STXSD
7424 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7425 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7426 ;;           NOP          MFTGPR      MFFGPR      MFVSRD      MTVSRD
7428 (define_insn "*mov<mode>_hardfloat64"
7429   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7430            "=m,           d,          d,          <f64_p9>,   wY,
7431              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7432              Y,           r,          !r,         *c*l,       !r,
7433             *h,           r,          wg,         r,          <f64_dm>")
7435         (match_operand:FMOVE64 1 "input_operand"
7436             "d,           m,          d,          wY,         <f64_p9>,
7437              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7438              r,           Y,          r,          r,          h,
7439              0,           wg,         r,          <f64_dm>,   r"))]
7441   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7442    && (gpc_reg_operand (operands[0], <MODE>mode)
7443        || gpc_reg_operand (operands[1], <MODE>mode))"
7444   "@
7445    stfd%U0%X0 %1,%0
7446    lfd%U1%X1 %0,%1
7447    fmr %0,%1
7448    lxsd %0,%1
7449    stxsd %1,%0
7450    lxsd%U1x %x0,%y1
7451    stxsd%U0x %x1,%y0
7452    xxlor %x0,%x1,%x1
7453    xxlxor %x0,%x0,%x0
7454    li %0,0
7455    std%U0%X0 %1,%0
7456    ld%U1%X1 %0,%1
7457    mr %0,%1
7458    mt%0 %1
7459    mf%1 %0
7460    nop
7461    mftgpr %0,%1
7462    mffgpr %0,%1
7463    mfvsrd %0,%x1
7464    mtvsrd %x0,%1"
7465   [(set_attr "type"
7466             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7467              fpload,      fpstore,    veclogical, veclogical, integer,
7468              store,       load,       *,          mtjmpr,     mfjmpr,
7469              *,           mftgpr,     mffgpr,     mftgpr,    mffgpr")
7471    (set_attr "size" "64")
7472    (set_attr "length" "4")])
7474 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7475 ;;           H-const  F-const  Special
7477 (define_insn "*mov<mode>_softfloat64"
7478   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7479            "=Y,       r,      r,      cl,     r,      r,
7480              r,       r,      *h")
7482         (match_operand:FMOVE64 1 "input_operand"
7483             "r,       Y,      r,      r,      h,      G,
7484              H,       F,      0"))]
7486   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7487    && (gpc_reg_operand (operands[0], <MODE>mode)
7488        || gpc_reg_operand (operands[1], <MODE>mode))"
7489   "@
7490    std%U0%X0 %1,%0
7491    ld%U1%X1 %0,%1
7492    mr %0,%1
7493    mt%0 %1
7494    mf%1 %0
7495    #
7496    #
7497    #
7498    nop"
7499   [(set_attr "type"
7500             "store,   load,   *,      mtjmpr, mfjmpr, *,
7501              *,       *,      *")
7503    (set_attr "length"
7504             "4,       4,      4,      4,      4,      8,
7505              12,      16,     4")])
7507 (define_expand "mov<mode>"
7508   [(set (match_operand:FMOVE128 0 "general_operand")
7509         (match_operand:FMOVE128 1 "any_operand"))]
7510   ""
7512   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7513   DONE;
7516 ;; It's important to list Y->r and r->Y before r->r because otherwise
7517 ;; reload, given m->r, will try to pick r->r and reload it, which
7518 ;; doesn't make progress.
7520 ;; We can't split little endian direct moves of TDmode, because the words are
7521 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7522 ;; problematical.  Don't allow direct move for this case.
7524 (define_insn_and_split "*mov<mode>_64bit_dm"
7525   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7526         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7527   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7528    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7529    && (gpc_reg_operand (operands[0], <MODE>mode)
7530        || gpc_reg_operand (operands[1], <MODE>mode))"
7531   "#"
7532   "&& reload_completed"
7533   [(pc)]
7534 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7535   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7537 (define_insn_and_split "*movtd_64bit_nodm"
7538   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7539         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7540   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7541    && (gpc_reg_operand (operands[0], TDmode)
7542        || gpc_reg_operand (operands[1], TDmode))"
7543   "#"
7544   "&& reload_completed"
7545   [(pc)]
7546 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7547   [(set_attr "length" "8,8,8,12,12,8")])
7549 (define_insn_and_split "*mov<mode>_32bit"
7550   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7551         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7552   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7553    && (FLOAT128_2REG_P (<MODE>mode)
7554        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7555        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7556    && (gpc_reg_operand (operands[0], <MODE>mode)
7557        || gpc_reg_operand (operands[1], <MODE>mode))"
7558   "#"
7559   "&& reload_completed"
7560   [(pc)]
7561 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7562   [(set_attr "length" "8,8,8,8,20,20,16")])
7564 (define_insn_and_split "*mov<mode>_softfloat"
7565   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7566         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7567   "TARGET_SOFT_FLOAT
7568    && (gpc_reg_operand (operands[0], <MODE>mode)
7569        || gpc_reg_operand (operands[1], <MODE>mode))"
7570   "#"
7571   "&& reload_completed"
7572   [(pc)]
7573 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7574   [(set_attr "length" "20,20,16")])
7576 (define_expand "extenddf<mode>2"
7577   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7578         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7579   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7581   if (FLOAT128_IEEE_P (<MODE>mode))
7582     rs6000_expand_float128_convert (operands[0], operands[1], false);
7583   else if (TARGET_VSX)
7584     {
7585       if (<MODE>mode == TFmode)
7586         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7587       else if (<MODE>mode == IFmode)
7588         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7589       else
7590         gcc_unreachable ();
7591     }
7592    else
7593     {
7594       rtx zero = gen_reg_rtx (DFmode);
7595       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7597       if (<MODE>mode == TFmode)
7598         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7599       else if (<MODE>mode == IFmode)
7600         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7601       else
7602         gcc_unreachable ();
7603     }
7604   DONE;
7607 ;; Allow memory operands for the source to be created by the combiner.
7608 (define_insn_and_split "extenddf<mode>2_fprs"
7609   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7610         (float_extend:IBM128
7611          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7612    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7613   "!TARGET_VSX && TARGET_HARD_FLOAT
7614    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7615   "#"
7616   "&& reload_completed"
7617   [(set (match_dup 3) (match_dup 1))
7618    (set (match_dup 4) (match_dup 2))]
7620   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7621   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7623   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7624   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7627 (define_insn_and_split "extenddf<mode>2_vsx"
7628   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7629         (float_extend:IBM128
7630          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7631   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7632   "#"
7633   "&& reload_completed"
7634   [(set (match_dup 2) (match_dup 1))
7635    (set (match_dup 3) (match_dup 4))]
7637   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7638   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7640   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7641   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7642   operands[4] = CONST0_RTX (DFmode);
7645 (define_expand "extendsf<mode>2"
7646   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7647         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7648   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7650   if (FLOAT128_IEEE_P (<MODE>mode))
7651     rs6000_expand_float128_convert (operands[0], operands[1], false);
7652   else
7653     {
7654       rtx tmp = gen_reg_rtx (DFmode);
7655       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7656       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7657     }
7658   DONE;
7661 (define_expand "trunc<mode>df2"
7662   [(set (match_operand:DF 0 "gpc_reg_operand")
7663         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7664   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7666   if (FLOAT128_IEEE_P (<MODE>mode))
7667     {
7668       rs6000_expand_float128_convert (operands[0], operands[1], false);
7669       DONE;
7670     }
7673 (define_insn_and_split "trunc<mode>df2_internal1"
7674   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7675         (float_truncate:DF
7676          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7677   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7678    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7679   "@
7680    #
7681    fmr %0,%1"
7682   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7683   [(const_int 0)]
7685   emit_note (NOTE_INSN_DELETED);
7686   DONE;
7688   [(set_attr "type" "fpsimple")])
7690 (define_insn "trunc<mode>df2_internal2"
7691   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7692         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7693   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7694    && TARGET_LONG_DOUBLE_128"
7695   "fadd %0,%1,%L1"
7696   [(set_attr "type" "fp")])
7698 (define_expand "trunc<mode>sf2"
7699   [(set (match_operand:SF 0 "gpc_reg_operand")
7700         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7701   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7703   if (FLOAT128_IEEE_P (<MODE>mode))
7704     rs6000_expand_float128_convert (operands[0], operands[1], false);
7705   else if (<MODE>mode == TFmode)
7706     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7707   else if (<MODE>mode == IFmode)
7708     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7709   else
7710     gcc_unreachable ();
7711   DONE;
7714 (define_insn_and_split "trunc<mode>sf2_fprs"
7715   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7716         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7717    (clobber (match_scratch:DF 2 "=d"))]
7718   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7719   "#"
7720   "&& reload_completed"
7721   [(set (match_dup 2)
7722         (float_truncate:DF (match_dup 1)))
7723    (set (match_dup 0)
7724         (float_truncate:SF (match_dup 2)))]
7725   "")
7727 (define_expand "floatsi<mode>2"
7728   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7729                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7730               (clobber (match_scratch:DI 2))])]
7731   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7733   rtx op0 = operands[0];
7734   rtx op1 = operands[1];
7736   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7737     ;
7738   else if (FLOAT128_IEEE_P (<MODE>mode))
7739     {
7740       rs6000_expand_float128_convert (op0, op1, false);
7741       DONE;
7742     }
7743   else
7744     {
7745       rtx tmp = gen_reg_rtx (DFmode);
7746       expand_float (tmp, op1, false);
7747       if (<MODE>mode == TFmode)
7748         emit_insn (gen_extenddftf2 (op0, tmp));
7749       else if (<MODE>mode == IFmode)
7750         emit_insn (gen_extenddfif2 (op0, tmp));
7751       else
7752         gcc_unreachable ();
7753       DONE;
7754     }
7757 ; fadd, but rounding towards zero.
7758 ; This is probably not the optimal code sequence.
7759 (define_insn "fix_trunc_helper<mode>"
7760   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7761         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7762                    UNSPEC_FIX_TRUNC_TF))
7763    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7764   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7765   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7766   [(set_attr "type" "fp")
7767    (set_attr "length" "20")])
7769 (define_expand "fix_trunc<mode>si2"
7770   [(set (match_operand:SI 0 "gpc_reg_operand")
7771         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7772   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7774   rtx op0 = operands[0];
7775   rtx op1 = operands[1];
7777   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7778     ;
7779   else
7780     {
7781       if (FLOAT128_IEEE_P (<MODE>mode))
7782         rs6000_expand_float128_convert (op0, op1, false);
7783       else if (<MODE>mode == TFmode)
7784         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7785       else if (<MODE>mode == IFmode)
7786         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7787       else
7788         gcc_unreachable ();
7789       DONE;
7790     }
7793 (define_expand "fix_trunc<mode>si2_fprs"
7794   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7795                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7796               (clobber (match_dup 2))
7797               (clobber (match_dup 3))
7798               (clobber (match_dup 4))
7799               (clobber (match_dup 5))])]
7800   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7802   operands[2] = gen_reg_rtx (DFmode);
7803   operands[3] = gen_reg_rtx (DFmode);
7804   operands[4] = gen_reg_rtx (DImode);
7805   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7808 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7809   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7810         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7811    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7812    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7813    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7814    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7815   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7816   "#"
7817   ""
7818   [(pc)]
7820   rtx lowword;
7821   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7822                                          operands[3]));
7824   gcc_assert (MEM_P (operands[5]));
7825   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7827   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7828   emit_move_insn (operands[5], operands[4]);
7829   emit_move_insn (operands[0], lowword);
7830   DONE;
7833 (define_expand "fix_trunc<mode>di2"
7834   [(set (match_operand:DI 0 "gpc_reg_operand")
7835         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7836   "TARGET_FLOAT128_TYPE"
7838   if (!TARGET_FLOAT128_HW)
7839     {
7840       rs6000_expand_float128_convert (operands[0], operands[1], false);
7841       DONE;
7842     }
7845 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7846   [(set (match_operand:SDI 0 "gpc_reg_operand")
7847         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7848   "TARGET_FLOAT128_TYPE"
7850   rs6000_expand_float128_convert (operands[0], operands[1], true);
7851   DONE;
7854 (define_expand "floatdi<mode>2"
7855   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7856         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7857   "TARGET_FLOAT128_TYPE"
7859   if (!TARGET_FLOAT128_HW)
7860     {
7861       rs6000_expand_float128_convert (operands[0], operands[1], false);
7862       DONE;
7863     }
7866 (define_expand "floatunsdi<IEEE128:mode>2"
7867   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7868         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7869   "TARGET_FLOAT128_TYPE"
7871   if (!TARGET_FLOAT128_HW)
7872     {
7873       rs6000_expand_float128_convert (operands[0], operands[1], true);
7874       DONE;
7875     }
7878 (define_expand "floatuns<IEEE128:mode>2"
7879   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7880         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
7881   "TARGET_FLOAT128_TYPE"
7883   rtx op0 = operands[0];
7884   rtx op1 = operands[1];
7886   if (TARGET_FLOAT128_HW)
7887     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7888   else
7889     rs6000_expand_float128_convert (op0, op1, true);
7890   DONE;
7893 (define_expand "neg<mode>2"
7894   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7895         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7896   "FLOAT128_IEEE_P (<MODE>mode)
7897    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7899   if (FLOAT128_IEEE_P (<MODE>mode))
7900     {
7901       if (TARGET_FLOAT128_HW)
7902         {
7903           if (<MODE>mode == TFmode)
7904             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7905           else if (<MODE>mode == KFmode)
7906             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7907           else
7908             gcc_unreachable ();
7909         }
7910       else if (TARGET_FLOAT128_TYPE)
7911         {
7912           if (<MODE>mode == TFmode)
7913             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7914           else if (<MODE>mode == KFmode)
7915             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7916           else
7917             gcc_unreachable ();
7918         }
7919       else
7920         {
7921           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7922           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7923                                                 <MODE>mode,
7924                                                 operands[1], <MODE>mode);
7926           if (target && !rtx_equal_p (target, operands[0]))
7927             emit_move_insn (operands[0], target);
7928         }
7929       DONE;
7930     }
7933 (define_insn "neg<mode>2_internal"
7934   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7935         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7936   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7938   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7939     return "fneg %L0,%L1\;fneg %0,%1";
7940   else
7941     return "fneg %0,%1\;fneg %L0,%L1";
7943   [(set_attr "type" "fpsimple")
7944    (set_attr "length" "8")])
7946 (define_expand "abs<mode>2"
7947   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7948         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7949   "FLOAT128_IEEE_P (<MODE>mode)
7950    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7952   rtx label;
7954   if (FLOAT128_IEEE_P (<MODE>mode))
7955     {
7956       if (TARGET_FLOAT128_HW)
7957         {
7958           if (<MODE>mode == TFmode)
7959             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7960           else if (<MODE>mode == KFmode)
7961             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7962           else
7963             FAIL;
7964           DONE;
7965         }
7966       else if (TARGET_FLOAT128_TYPE)
7967         {
7968           if (<MODE>mode == TFmode)
7969             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7970           else if (<MODE>mode == KFmode)
7971             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7972           else
7973             FAIL;
7974           DONE;
7975         }
7976       else
7977         FAIL;
7978     }
7980   label = gen_label_rtx ();
7981   if (<MODE>mode == TFmode)
7982     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7983   else if (<MODE>mode == IFmode)
7984     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7985   else
7986     FAIL;
7987   emit_label (label);
7988   DONE;
7991 (define_expand "abs<mode>2_internal"
7992   [(set (match_operand:IBM128 0 "gpc_reg_operand")
7993         (match_operand:IBM128 1 "gpc_reg_operand"))
7994    (set (match_dup 3) (match_dup 5))
7995    (set (match_dup 5) (abs:DF (match_dup 5)))
7996    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7997    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7998                            (label_ref (match_operand 2 ""))
7999                            (pc)))
8000    (set (match_dup 6) (neg:DF (match_dup 6)))]
8001   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8003   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8004   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8005   operands[3] = gen_reg_rtx (DFmode);
8006   operands[4] = gen_reg_rtx (CCFPmode);
8007   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8008   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8012 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8013 ;; register
8015 (define_expand "ieee_128bit_negative_zero"
8016   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8017   "TARGET_FLOAT128_TYPE"
8019   rtvec v = rtvec_alloc (16);
8020   int i, high;
8022   for (i = 0; i < 16; i++)
8023     RTVEC_ELT (v, i) = const0_rtx;
8025   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8026   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8028   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8029   DONE;
8032 ;; IEEE 128-bit negate
8034 ;; We have 2 insns here for negate and absolute value.  The first uses
8035 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8036 ;; insns, and second insn after the first split pass loads up the bit to
8037 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8038 ;; neg/abs to create the constant just once.
8040 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8041   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8042         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8043    (clobber (match_scratch:V16QI 2 "=v"))]
8044   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8045   "#"
8046   "&& 1"
8047   [(parallel [(set (match_dup 0)
8048                    (neg:IEEE128 (match_dup 1)))
8049               (use (match_dup 2))])]
8051   if (GET_CODE (operands[2]) == SCRATCH)
8052     operands[2] = gen_reg_rtx (V16QImode);
8054   operands[3] = gen_reg_rtx (V16QImode);
8055   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8057   [(set_attr "length" "8")
8058    (set_attr "type" "vecsimple")])
8060 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8061   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8062         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8063    (use (match_operand:V16QI 2 "register_operand" "v"))]
8064   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8065   "xxlxor %x0,%x1,%x2"
8066   [(set_attr "type" "veclogical")])
8068 ;; IEEE 128-bit absolute value
8069 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8070   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8071         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8072    (clobber (match_scratch:V16QI 2 "=v"))]
8073   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8074   "#"
8075   "&& 1"
8076   [(parallel [(set (match_dup 0)
8077                    (abs:IEEE128 (match_dup 1)))
8078               (use (match_dup 2))])]
8080   if (GET_CODE (operands[2]) == SCRATCH)
8081     operands[2] = gen_reg_rtx (V16QImode);
8083   operands[3] = gen_reg_rtx (V16QImode);
8084   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8086   [(set_attr "length" "8")
8087    (set_attr "type" "vecsimple")])
8089 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8090   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8091         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8092    (use (match_operand:V16QI 2 "register_operand" "v"))]
8093   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8094   "xxlandc %x0,%x1,%x2"
8095   [(set_attr "type" "veclogical")])
8097 ;; IEEE 128-bit negative absolute value
8098 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8099   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8100         (neg:IEEE128
8101          (abs:IEEE128
8102           (match_operand:IEEE128 1 "register_operand" "wa"))))
8103    (clobber (match_scratch:V16QI 2 "=v"))]
8104   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8105    && FLOAT128_IEEE_P (<MODE>mode)"
8106   "#"
8107   "&& 1"
8108   [(parallel [(set (match_dup 0)
8109                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8110               (use (match_dup 2))])]
8112   if (GET_CODE (operands[2]) == SCRATCH)
8113     operands[2] = gen_reg_rtx (V16QImode);
8115   operands[3] = gen_reg_rtx (V16QImode);
8116   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8118   [(set_attr "length" "8")
8119    (set_attr "type" "vecsimple")])
8121 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8122   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8123         (neg:IEEE128
8124          (abs:IEEE128
8125           (match_operand:IEEE128 1 "register_operand" "wa"))))
8126    (use (match_operand:V16QI 2 "register_operand" "v"))]
8127   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8128   "xxlor %x0,%x1,%x2"
8129   [(set_attr "type" "veclogical")])
8131 ;; Float128 conversion functions.  These expand to library function calls.
8132 ;; We use expand to convert from IBM double double to IEEE 128-bit
8133 ;; and trunc for the opposite.
8134 (define_expand "extendiftf2"
8135   [(set (match_operand:TF 0 "gpc_reg_operand")
8136         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8137   "TARGET_FLOAT128_TYPE"
8139   rs6000_expand_float128_convert (operands[0], operands[1], false);
8140   DONE;
8143 (define_expand "extendifkf2"
8144   [(set (match_operand:KF 0 "gpc_reg_operand")
8145         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8146   "TARGET_FLOAT128_TYPE"
8148   rs6000_expand_float128_convert (operands[0], operands[1], false);
8149   DONE;
8152 (define_expand "extendtfkf2"
8153   [(set (match_operand:KF 0 "gpc_reg_operand")
8154         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8155   "TARGET_FLOAT128_TYPE"
8157   rs6000_expand_float128_convert (operands[0], operands[1], false);
8158   DONE;
8161 (define_expand "trunciftf2"
8162   [(set (match_operand:IF 0 "gpc_reg_operand")
8163         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8164   "TARGET_FLOAT128_TYPE"
8166   rs6000_expand_float128_convert (operands[0], operands[1], false);
8167   DONE;
8170 (define_expand "truncifkf2"
8171   [(set (match_operand:IF 0 "gpc_reg_operand")
8172         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand")))]
8173   "TARGET_FLOAT128_TYPE"
8175   rs6000_expand_float128_convert (operands[0], operands[1], false);
8176   DONE;
8179 (define_expand "trunckftf2"
8180   [(set (match_operand:TF 0 "gpc_reg_operand")
8181         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8182   "TARGET_FLOAT128_TYPE"
8184   rs6000_expand_float128_convert (operands[0], operands[1], false);
8185   DONE;
8188 (define_expand "trunctfif2"
8189   [(set (match_operand:IF 0 "gpc_reg_operand")
8190         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8191   "TARGET_FLOAT128_TYPE"
8193   rs6000_expand_float128_convert (operands[0], operands[1], false);
8194   DONE;
8197 (define_insn_and_split "*extend<mode>tf2_internal"
8198   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8199         (float_extend:TF
8200          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8201    "TARGET_FLOAT128_TYPE
8202     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8203   "#"
8204   "&& reload_completed"
8205   [(set (match_dup 0) (match_dup 2))]
8207   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8210 (define_insn_and_split "*extendtf<mode>2_internal"
8211   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8212         (float_extend:IFKF
8213          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8214    "TARGET_FLOAT128_TYPE
8215     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8216   "#"
8217   "&& reload_completed"
8218   [(set (match_dup 0) (match_dup 2))]
8220   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8224 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8225 ;; must have 3 arguments, and scratch register constraint must be a single
8226 ;; constraint.
8228 ;; Reload patterns to support gpr load/store with misaligned mem.
8229 ;; and multiple gpr load/store at offset >= 0xfffc
8230 (define_expand "reload_<mode>_store"
8231   [(parallel [(match_operand 0 "memory_operand" "=m")
8232               (match_operand 1 "gpc_reg_operand" "r")
8233               (match_operand:GPR 2 "register_operand" "=&b")])]
8234   ""
8236   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8237   DONE;
8240 (define_expand "reload_<mode>_load"
8241   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8242               (match_operand 1 "memory_operand" "m")
8243               (match_operand:GPR 2 "register_operand" "=b")])]
8244   ""
8246   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8247   DONE;
8251 ;; Reload patterns for various types using the vector registers.  We may need
8252 ;; an additional base register to convert the reg+offset addressing to reg+reg
8253 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8254 ;; index register for gpr registers.
8255 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8256   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8257               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8258               (match_operand:P 2 "register_operand" "=b")])]
8259   "<P:tptrsize>"
8261   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8262   DONE;
8265 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8266   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8267               (match_operand:RELOAD 1 "memory_operand" "m")
8268               (match_operand:P 2 "register_operand" "=b")])]
8269   "<P:tptrsize>"
8271   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8272   DONE;
8276 ;; Reload sometimes tries to move the address to a GPR, and can generate
8277 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8278 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8280 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8281   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8282         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8283                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8284                (const_int -16)))]
8285   "TARGET_ALTIVEC && reload_completed"
8286   "#"
8287   "&& reload_completed"
8288   [(set (match_dup 0)
8289         (plus:P (match_dup 1)
8290                 (match_dup 2)))
8291    (set (match_dup 0)
8292         (and:P (match_dup 0)
8293                (const_int -16)))])
8295 ;; Power8 merge instructions to allow direct move to/from floating point
8296 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8297 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8298 ;; value, since it is allocated in reload and not all of the flow information
8299 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8300 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8301 ;; schedule other instructions between the two instructions.
8303 (define_insn "p8_fmrgow_<mode>"
8304   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8305         (unspec:FMOVE64X [
8306                 (match_operand:DF 1 "register_operand" "d")
8307                 (match_operand:DF 2 "register_operand" "d")]
8308                          UNSPEC_P8V_FMRGOW))]
8309   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8310   "fmrgow %0,%1,%2"
8311   [(set_attr "type" "fpsimple")])
8313 (define_insn "p8_mtvsrwz"
8314   [(set (match_operand:DF 0 "register_operand" "=d")
8315         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8316                    UNSPEC_P8V_MTVSRWZ))]
8317   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8318   "mtvsrwz %x0,%1"
8319   [(set_attr "type" "mftgpr")])
8321 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8322   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8323         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8324                          UNSPEC_P8V_RELOAD_FROM_GPR))
8325    (clobber (match_operand:IF 2 "register_operand" "=d"))]
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   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8334   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8335   rtx gpr_hi_reg = gen_highpart (SImode, src);
8336   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8338   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8339   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8340   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8341   DONE;
8343   [(set_attr "length" "12")
8344    (set_attr "type" "three")])
8346 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8347 (define_insn "p8_mtvsrd_df"
8348   [(set (match_operand:DF 0 "register_operand" "=wa")
8349         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8350                    UNSPEC_P8V_MTVSRD))]
8351   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8352   "mtvsrd %x0,%1"
8353   [(set_attr "type" "mftgpr")])
8355 (define_insn "p8_xxpermdi_<mode>"
8356   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8357         (unspec:FMOVE128_GPR [
8358                 (match_operand:DF 1 "register_operand" "wa")
8359                 (match_operand:DF 2 "register_operand" "wa")]
8360                 UNSPEC_P8V_XXPERMDI))]
8361   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8362   "xxpermdi %x0,%x1,%x2,0"
8363   [(set_attr "type" "vecperm")])
8365 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8366   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8367         (unspec:FMOVE128_GPR
8368          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8369          UNSPEC_P8V_RELOAD_FROM_GPR))
8370    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8371   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8372   "#"
8373   "&& reload_completed"
8374   [(const_int 0)]
8376   rtx dest = operands[0];
8377   rtx src = operands[1];
8378   /* You might think that we could use op0 as one temp and a DF clobber
8379      as op2, but you'd be wrong.  Secondary reload move patterns don't
8380      check for overlap of the clobber and the destination.  */
8381   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8382   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8383   rtx gpr_hi_reg = gen_highpart (DImode, src);
8384   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8386   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8387   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8388   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8389   DONE;
8391   [(set_attr "length" "12")
8392    (set_attr "type" "three")])
8394 (define_split
8395   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8396         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8397   "reload_completed
8398    && (int_reg_operand (operands[0], <MODE>mode)
8399        || int_reg_operand (operands[1], <MODE>mode))
8400    && (!TARGET_DIRECT_MOVE_128
8401        || (!vsx_register_operand (operands[0], <MODE>mode)
8402            && !vsx_register_operand (operands[1], <MODE>mode)))"
8403   [(pc)]
8404 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8406 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8407 ;; type is stored internally as double precision in the VSX registers, we have
8408 ;; to convert it from the vector format.
8409 (define_insn "p8_mtvsrd_sf"
8410   [(set (match_operand:SF 0 "register_operand" "=wa")
8411         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8412                    UNSPEC_P8V_MTVSRD))]
8413   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8414   "mtvsrd %x0,%1"
8415   [(set_attr "type" "mftgpr")])
8417 (define_insn_and_split "reload_vsx_from_gprsf"
8418   [(set (match_operand:SF 0 "register_operand" "=wa")
8419         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8420                    UNSPEC_P8V_RELOAD_FROM_GPR))
8421    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8422   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8423   "#"
8424   "&& reload_completed"
8425   [(const_int 0)]
8427   rtx op0 = operands[0];
8428   rtx op1 = operands[1];
8429   rtx op2 = operands[2];
8430   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8432   /* Move SF value to upper 32-bits for xscvspdpn.  */
8433   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8434   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8435   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8436   DONE;
8438   [(set_attr "length" "8")
8439    (set_attr "type" "two")])
8441 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8442 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8443 ;; and then doing a move of that.
8444 (define_insn "p8_mfvsrd_3_<mode>"
8445   [(set (match_operand:DF 0 "register_operand" "=r")
8446         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8447                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8448   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8449   "mfvsrd %0,%x1"
8450   [(set_attr "type" "mftgpr")])
8452 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8453   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8454         (unspec:FMOVE128_GPR
8455          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8456          UNSPEC_P8V_RELOAD_FROM_VSX))
8457    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8458   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8459   "#"
8460   "&& reload_completed"
8461   [(const_int 0)]
8463   rtx dest = operands[0];
8464   rtx src = operands[1];
8465   rtx tmp = operands[2];
8466   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8467   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8469   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8470   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8471   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8472   DONE;
8474   [(set_attr "length" "12")
8475    (set_attr "type" "three")])
8477 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8478 ;; type is stored internally as double precision, we have to convert it to the
8479 ;; vector format.
8481 (define_insn_and_split "reload_gpr_from_vsxsf"
8482   [(set (match_operand:SF 0 "register_operand" "=r")
8483         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8484                    UNSPEC_P8V_RELOAD_FROM_VSX))
8485    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8486   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8487   "#"
8488   "&& reload_completed"
8489   [(const_int 0)]
8491   rtx op0 = operands[0];
8492   rtx op1 = operands[1];
8493   rtx op2 = operands[2];
8494   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8495   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8497   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8498   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8499   DONE;
8501   [(set_attr "length" "8")
8502    (set_attr "type" "two")])
8505 ;; Next come the multi-word integer load and store and the load and store
8506 ;; multiple insns.
8508 ;; List r->r after r->Y, otherwise reload will try to reload a
8509 ;; non-offsettable address by using r->r which won't make progress.
8510 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8511 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8513 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8514 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8515 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8516 ;;        AVX const  
8518 (define_insn "*movdi_internal32"
8519   [(set (match_operand:DI 0 "nonimmediate_operand"
8520          "=Y,        r,         r,         m,         ^d,         ^d,
8521           r,         wY,        Z,         ^wb,       $wv,        ^wi,
8522           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8523           *wv")
8525         (match_operand:DI 1 "input_operand"
8526          "r,         Y,         r,         ^d,        m,          ^d,
8527           IJKnGHF,   ^wb,       $wv,       wY,        Z,          ^wi,
8528           Oj,        wM,        OjwM,      Oj,        wM,         wS,
8529           wB"))]
8531   "! TARGET_POWERPC64
8532    && (gpc_reg_operand (operands[0], DImode)
8533        || gpc_reg_operand (operands[1], DImode))"
8534   "@
8535    #
8536    #
8537    #
8538    stfd%U0%X0 %1,%0
8539    lfd%U1%X1 %0,%1
8540    fmr %0,%1
8541    #
8542    stxsd %1,%0
8543    stxsdx %x1,%y0
8544    lxsd %0,%1
8545    lxsdx %x0,%y1
8546    xxlor %x0,%x1,%x1
8547    xxspltib %x0,0
8548    xxspltib %x0,255
8549    vspltisw %0,%1
8550    xxlxor %x0,%x0,%x0
8551    xxlorc %x0,%x0,%x0
8552    #
8553    #"
8554   [(set_attr "type"
8555                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8556                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8557                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8558                 vecsimple")
8559    (set_attr "size" "64")])
8561 (define_split
8562   [(set (match_operand:DI 0 "gpc_reg_operand")
8563         (match_operand:DI 1 "const_int_operand"))]
8564   "! TARGET_POWERPC64 && reload_completed
8565    && gpr_or_gpr_p (operands[0], operands[1])
8566    && !direct_move_p (operands[0], operands[1])"
8567   [(set (match_dup 2) (match_dup 4))
8568    (set (match_dup 3) (match_dup 1))]
8570   HOST_WIDE_INT value = INTVAL (operands[1]);
8571   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8572                                        DImode);
8573   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8574                                        DImode);
8575   operands[4] = GEN_INT (value >> 32);
8576   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8579 (define_split
8580   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8581         (match_operand:DIFD 1 "input_operand"))]
8582   "reload_completed && !TARGET_POWERPC64
8583    && gpr_or_gpr_p (operands[0], operands[1])
8584    && !direct_move_p (operands[0], operands[1])"
8585   [(pc)]
8586 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8588 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8589 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8590 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8591 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8592 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8593 (define_insn "*movdi_internal64"
8594   [(set (match_operand:DI 0 "nonimmediate_operand"
8595                "=YZ,       r,         r,         r,         r,          r,
8596                 m,         ^d,        ^d,        wY,        Z,          $wb,
8597                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8598                 *wi,       *wv,       *wv,       r,         *h,         *h,
8599                 ?*r,       ?*wg,      ?*r,       ?*wj")
8601         (match_operand:DI 1 "input_operand"
8602                "r,         YZ,        r,         I,         L,          nF,
8603                 ^d,        m,         ^d,        ^wb,       $wv,        wY,
8604                 Z,         ^wi,       Oj,        wM,        OjwM,       Oj,
8605                 wM,        wS,        wB,        *h,        r,          0,
8606                 wg,        r,         wj,        r"))]
8608   "TARGET_POWERPC64
8609    && (gpc_reg_operand (operands[0], DImode)
8610        || gpc_reg_operand (operands[1], DImode))"
8611   "@
8612    std%U0%X0 %1,%0
8613    ld%U1%X1 %0,%1
8614    mr %0,%1
8615    li %0,%1
8616    lis %0,%v1
8617    #
8618    stfd%U0%X0 %1,%0
8619    lfd%U1%X1 %0,%1
8620    fmr %0,%1
8621    stxsd %1,%0
8622    stxsdx %x1,%y0
8623    lxsd %0,%1
8624    lxsdx %x0,%y1
8625    xxlor %x0,%x1,%x1
8626    xxspltib %x0,0
8627    xxspltib %x0,255
8628    #
8629    xxlxor %x0,%x0,%x0
8630    xxlorc %x0,%x0,%x0
8631    #
8632    #
8633    mf%1 %0
8634    mt%0 %1
8635    nop
8636    mftgpr %0,%1
8637    mffgpr %0,%1
8638    mfvsrd %0,%x1
8639    mtvsrd %x0,%1"
8640   [(set_attr "type"
8641                "store,      load,       *,         *,         *,         *,
8642                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8643                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8644                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8645                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8647    (set_attr "size" "64")
8648    (set_attr "length"
8649                "4,         4,         4,         4,         4,          20,
8650                 4,         4,         4,         4,         4,          4,
8651                 4,         4,         4,         4,         4,          8,
8652                 8,         4,         4,         4,         4,          4,
8653                 4,         4,         4,         4")])
8655 ; Some DImode loads are best done as a load of -1 followed by a mask
8656 ; instruction.
8657 (define_split
8658   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8659         (match_operand:DI 1 "const_int_operand"))]
8660   "TARGET_POWERPC64
8661    && num_insns_constant (operands[1], DImode) > 1
8662    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8663    && rs6000_is_valid_and_mask (operands[1], DImode)"
8664   [(set (match_dup 0)
8665         (const_int -1))
8666    (set (match_dup 0)
8667         (and:DI (match_dup 0)
8668                 (match_dup 1)))]
8669   "")
8671 ;; Split a load of a large constant into the appropriate five-instruction
8672 ;; sequence.  Handle anything in a constant number of insns.
8673 ;; When non-easy constants can go in the TOC, this should use
8674 ;; easy_fp_constant predicate.
8675 (define_split
8676   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8677         (match_operand:DI 1 "const_int_operand"))]
8678   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8679   [(set (match_dup 0) (match_dup 2))
8680    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8682   if (rs6000_emit_set_const (operands[0], operands[1]))
8683     DONE;
8684   else
8685     FAIL;
8688 (define_split
8689   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8690         (match_operand:DI 1 "const_scalar_int_operand"))]
8691   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8692   [(set (match_dup 0) (match_dup 2))
8693    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8695   if (rs6000_emit_set_const (operands[0], operands[1]))
8696     DONE;
8697   else
8698     FAIL;
8701 (define_split
8702   [(set (match_operand:DI 0 "altivec_register_operand")
8703         (match_operand:DI 1 "s5bit_cint_operand"))]
8704   "TARGET_VSX && reload_completed"
8705   [(const_int 0)]
8707   rtx op0 = operands[0];
8708   rtx op1 = operands[1];
8709   int r = REGNO (op0);
8710   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8712   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8713   if (op1 != const0_rtx && op1 != constm1_rtx)
8714     {
8715       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8716       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8717     }
8718   DONE;
8721 ;; Split integer constants that can be loaded with XXSPLTIB and a
8722 ;; sign extend operation.
8723 (define_split
8724   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8725         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8726   "TARGET_P9_VECTOR && reload_completed"
8727   [(const_int 0)]
8729   rtx op0 = operands[0];
8730   rtx op1 = operands[1];
8731   int r = REGNO (op0);
8732   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8734   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8735   if (<MODE>mode == DImode)
8736     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8737   else if (<MODE>mode == SImode)
8738     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8739   else if (<MODE>mode == HImode)
8740     {
8741       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8742       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8743     }
8744   DONE;
8748 ;; TImode/PTImode is similar, except that we usually want to compute the
8749 ;; address into a register and use lsi/stsi (the exception is during reload).
8751 (define_insn "*mov<mode>_string"
8752   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8753         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8754   "! TARGET_POWERPC64
8755    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8756    && (gpc_reg_operand (operands[0], <MODE>mode)
8757        || gpc_reg_operand (operands[1], <MODE>mode))"
8758   "#"
8759   [(set_attr "type" "store,store,load,load,*,*")
8760    (set_attr "update" "yes")
8761    (set_attr "indexed" "yes")
8762    (set_attr "cell_micro" "conditional")])
8764 (define_insn "*mov<mode>_ppc64"
8765   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8766         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8767   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8768    && (gpc_reg_operand (operands[0], <MODE>mode)
8769        || gpc_reg_operand (operands[1], <MODE>mode)))"
8771   return rs6000_output_move_128bit (operands);
8773   [(set_attr "type" "store,store,load,load,*,*")
8774    (set_attr "length" "8")])
8776 (define_split
8777   [(set (match_operand:TI2 0 "int_reg_operand")
8778         (match_operand:TI2 1 "const_scalar_int_operand"))]
8779   "TARGET_POWERPC64
8780    && (VECTOR_MEM_NONE_P (<MODE>mode)
8781        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8782   [(set (match_dup 2) (match_dup 4))
8783    (set (match_dup 3) (match_dup 5))]
8785   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8786                                        <MODE>mode);
8787   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8788                                        <MODE>mode);
8789   if (CONST_WIDE_INT_P (operands[1]))
8790     {
8791       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8792       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8793     }
8794   else if (CONST_INT_P (operands[1]))
8795     {
8796       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8797       operands[5] = operands[1];
8798     }
8799   else
8800     FAIL;
8803 (define_split
8804   [(set (match_operand:TI2 0 "nonimmediate_operand")
8805         (match_operand:TI2 1 "input_operand"))]
8806   "reload_completed
8807    && gpr_or_gpr_p (operands[0], operands[1])
8808    && !direct_move_p (operands[0], operands[1])
8809    && !quad_load_store_p (operands[0], operands[1])"
8810   [(pc)]
8811 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8813 (define_expand "setmemsi"
8814   [(parallel [(set (match_operand:BLK 0 "")
8815                    (match_operand 2 "const_int_operand"))
8816               (use (match_operand:SI 1 ""))
8817               (use (match_operand:SI 3 ""))])]
8818   ""
8820   /* If value to set is not zero, use the library routine.  */
8821   if (operands[2] != const0_rtx)
8822     FAIL;
8824   if (expand_block_clear (operands))
8825     DONE;
8826   else
8827     FAIL;
8830 ;; String compare N insn.
8831 ;; Argument 0 is the target (result)
8832 ;; Argument 1 is the destination
8833 ;; Argument 2 is the source
8834 ;; Argument 3 is the length
8835 ;; Argument 4 is the alignment
8837 (define_expand "cmpstrnsi"
8838   [(parallel [(set (match_operand:SI 0)
8839                (compare:SI (match_operand:BLK 1)
8840                            (match_operand:BLK 2)))
8841               (use (match_operand:SI 3))
8842               (use (match_operand:SI 4))])]
8843   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8845   if (optimize_insn_for_size_p ())
8846     FAIL;
8848   if (expand_strn_compare (operands, 0))
8849     DONE;
8850   else  
8851     FAIL;
8854 ;; String compare insn.
8855 ;; Argument 0 is the target (result)
8856 ;; Argument 1 is the destination
8857 ;; Argument 2 is the source
8858 ;; Argument 3 is the alignment
8860 (define_expand "cmpstrsi"
8861   [(parallel [(set (match_operand:SI 0)
8862                (compare:SI (match_operand:BLK 1)
8863                            (match_operand:BLK 2)))
8864               (use (match_operand:SI 3))])]
8865   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8867   if (optimize_insn_for_size_p ())
8868     FAIL;
8870   if (expand_strn_compare (operands, 1))
8871     DONE;
8872   else  
8873     FAIL;
8876 ;; Block compare insn.
8877 ;; Argument 0 is the target (result)
8878 ;; Argument 1 is the destination
8879 ;; Argument 2 is the source
8880 ;; Argument 3 is the length
8881 ;; Argument 4 is the alignment
8883 (define_expand "cmpmemsi"
8884   [(parallel [(set (match_operand:SI 0)
8885                (compare:SI (match_operand:BLK 1)
8886                            (match_operand:BLK 2)))
8887               (use (match_operand:SI 3))
8888               (use (match_operand:SI 4))])]
8889   "TARGET_POPCNTD"
8891   if (expand_block_compare (operands))
8892     DONE;
8893   else
8894     FAIL;
8897 ;; String/block move insn.
8898 ;; Argument 0 is the destination
8899 ;; Argument 1 is the source
8900 ;; Argument 2 is the length
8901 ;; Argument 3 is the alignment
8903 (define_expand "movmemsi"
8904   [(parallel [(set (match_operand:BLK 0 "")
8905                    (match_operand:BLK 1 ""))
8906               (use (match_operand:SI 2 ""))
8907               (use (match_operand:SI 3 ""))])]
8908   ""
8910   if (expand_block_move (operands))
8911     DONE;
8912   else
8913     FAIL;
8916 ;; Define insns that do load or store with update.  Some of these we can
8917 ;; get by using pre-decrement or pre-increment, but the hardware can also
8918 ;; do cases where the increment is not the size of the object.
8920 ;; In all these cases, we use operands 0 and 1 for the register being
8921 ;; incremented because those are the operands that local-alloc will
8922 ;; tie and these are the pair most likely to be tieable (and the ones
8923 ;; that will benefit the most).
8925 (define_insn "*movdi_update1"
8926   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8927         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8928                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8929    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8930         (plus:DI (match_dup 1) (match_dup 2)))]
8931   "TARGET_POWERPC64 && TARGET_UPDATE
8932    && (!avoiding_indexed_address_p (DImode)
8933        || !gpc_reg_operand (operands[2], DImode))"
8934   "@
8935    ldux %3,%0,%2
8936    ldu %3,%2(%0)"
8937   [(set_attr "type" "load")
8938    (set_attr "update" "yes")
8939    (set_attr "indexed" "yes,no")])
8941 (define_insn "movdi_<mode>_update"
8942   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8943                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8944         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8945    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8946         (plus:P (match_dup 1) (match_dup 2)))]
8947   "TARGET_POWERPC64 && TARGET_UPDATE
8948    && (!avoiding_indexed_address_p (Pmode)
8949        || !gpc_reg_operand (operands[2], Pmode)
8950        || (REG_P (operands[0])
8951            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8952   "@
8953    stdux %3,%0,%2
8954    stdu %3,%2(%0)"
8955   [(set_attr "type" "store")
8956    (set_attr "update" "yes")
8957    (set_attr "indexed" "yes,no")])
8959 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8960 ;; needed for stack allocation, even if the user passes -mno-update.
8961 (define_insn "movdi_<mode>_update_stack"
8962   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8963                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8964         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8965    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8966         (plus:P (match_dup 1) (match_dup 2)))]
8967   "TARGET_POWERPC64"
8968   "@
8969    stdux %3,%0,%2
8970    stdu %3,%2(%0)"
8971   [(set_attr "type" "store")
8972    (set_attr "update" "yes")
8973    (set_attr "indexed" "yes,no")])
8975 (define_insn "*movsi_update1"
8976   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8977         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8978                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8979    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8980         (plus:SI (match_dup 1) (match_dup 2)))]
8981   "TARGET_UPDATE
8982    && (!avoiding_indexed_address_p (SImode)
8983        || !gpc_reg_operand (operands[2], SImode))"
8984   "@
8985    lwzux %3,%0,%2
8986    lwzu %3,%2(%0)"
8987   [(set_attr "type" "load")
8988    (set_attr "update" "yes")
8989    (set_attr "indexed" "yes,no")])
8991 (define_insn "*movsi_update2"
8992   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8993         (sign_extend:DI
8994          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8995                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8996    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8997         (plus:DI (match_dup 1) (match_dup 2)))]
8998   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
8999   "lwaux %3,%0,%2"
9000   [(set_attr "type" "load")
9001    (set_attr "sign_extend" "yes")
9002    (set_attr "update" "yes")
9003    (set_attr "indexed" "yes")])
9005 (define_insn "movsi_update"
9006   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9007                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9008         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9009    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9010         (plus:SI (match_dup 1) (match_dup 2)))]
9011   "TARGET_UPDATE
9012    && (!avoiding_indexed_address_p (SImode)
9013        || !gpc_reg_operand (operands[2], SImode)
9014        || (REG_P (operands[0])
9015            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9016   "@
9017    stwux %3,%0,%2
9018    stwu %3,%2(%0)"
9019   [(set_attr "type" "store")
9020    (set_attr "update" "yes")
9021    (set_attr "indexed" "yes,no")])
9023 ;; This is an unconditional pattern; needed for stack allocation, even
9024 ;; if the user passes -mno-update.
9025 (define_insn "movsi_update_stack"
9026   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9027                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9028         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9029    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9030         (plus:SI (match_dup 1) (match_dup 2)))]
9031   ""
9032   "@
9033    stwux %3,%0,%2
9034    stwu %3,%2(%0)"
9035   [(set_attr "type" "store")
9036    (set_attr "update" "yes")
9037    (set_attr "indexed" "yes,no")])
9039 (define_insn "*movhi_update1"
9040   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9041         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9042                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9043    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9044         (plus:SI (match_dup 1) (match_dup 2)))]
9045   "TARGET_UPDATE
9046    && (!avoiding_indexed_address_p (SImode)
9047        || !gpc_reg_operand (operands[2], SImode))"
9048   "@
9049    lhzux %3,%0,%2
9050    lhzu %3,%2(%0)"
9051   [(set_attr "type" "load")
9052    (set_attr "update" "yes")
9053    (set_attr "indexed" "yes,no")])
9055 (define_insn "*movhi_update2"
9056   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9057         (zero_extend:SI
9058          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9059                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9060    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9061         (plus:SI (match_dup 1) (match_dup 2)))]
9062   "TARGET_UPDATE
9063    && (!avoiding_indexed_address_p (SImode)
9064        || !gpc_reg_operand (operands[2], SImode))"
9065   "@
9066    lhzux %3,%0,%2
9067    lhzu %3,%2(%0)"
9068   [(set_attr "type" "load")
9069    (set_attr "update" "yes")
9070    (set_attr "indexed" "yes,no")])
9072 (define_insn "*movhi_update3"
9073   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9074         (sign_extend:SI
9075          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9076                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9077    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9078         (plus:SI (match_dup 1) (match_dup 2)))]
9079   "TARGET_UPDATE
9080    && !(avoiding_indexed_address_p (SImode)
9081         && gpc_reg_operand (operands[2], SImode))"
9082   "@
9083    lhaux %3,%0,%2
9084    lhau %3,%2(%0)"
9085   [(set_attr "type" "load")
9086    (set_attr "sign_extend" "yes")
9087    (set_attr "update" "yes")
9088    (set_attr "indexed" "yes,no")])
9090 (define_insn "*movhi_update4"
9091   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9092                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9093         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9094    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9095         (plus:SI (match_dup 1) (match_dup 2)))]
9096   "TARGET_UPDATE
9097    && (!avoiding_indexed_address_p (SImode)
9098        || !gpc_reg_operand (operands[2], SImode))"
9099   "@
9100    sthux %3,%0,%2
9101    sthu %3,%2(%0)"
9102   [(set_attr "type" "store")
9103    (set_attr "update" "yes")
9104    (set_attr "indexed" "yes,no")])
9106 (define_insn "*movqi_update1"
9107   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9108         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9109                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9110    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9111         (plus:SI (match_dup 1) (match_dup 2)))]
9112   "TARGET_UPDATE
9113    && (!avoiding_indexed_address_p (SImode)
9114        || !gpc_reg_operand (operands[2], SImode))"
9115   "@
9116    lbzux %3,%0,%2
9117    lbzu %3,%2(%0)"
9118   [(set_attr "type" "load")
9119    (set_attr "update" "yes")
9120    (set_attr "indexed" "yes,no")])
9122 (define_insn "*movqi_update2"
9123   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9124         (zero_extend:SI
9125          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9126                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9127    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9128         (plus:SI (match_dup 1) (match_dup 2)))]
9129   "TARGET_UPDATE
9130    && (!avoiding_indexed_address_p (SImode)
9131        || !gpc_reg_operand (operands[2], SImode))"
9132   "@
9133    lbzux %3,%0,%2
9134    lbzu %3,%2(%0)"
9135   [(set_attr "type" "load")
9136    (set_attr "update" "yes")
9137    (set_attr "indexed" "yes,no")])
9139 (define_insn "*movqi_update3"
9140   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9141                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9142         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9143    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9144         (plus:SI (match_dup 1) (match_dup 2)))]
9145   "TARGET_UPDATE
9146    && (!avoiding_indexed_address_p (SImode)
9147        || !gpc_reg_operand (operands[2], SImode))"
9148   "@
9149    stbux %3,%0,%2
9150    stbu %3,%2(%0)"
9151   [(set_attr "type" "store")
9152    (set_attr "update" "yes")
9153    (set_attr "indexed" "yes,no")])
9155 (define_insn "*movsf_update1"
9156   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9157         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9158                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9159    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9160         (plus:SI (match_dup 1) (match_dup 2)))]
9161   "TARGET_HARD_FLOAT && TARGET_UPDATE
9162    && (!avoiding_indexed_address_p (SImode)
9163        || !gpc_reg_operand (operands[2], SImode))"
9164   "@
9165    lfsux %3,%0,%2
9166    lfsu %3,%2(%0)"
9167   [(set_attr "type" "fpload")
9168    (set_attr "update" "yes")
9169    (set_attr "indexed" "yes,no")])
9171 (define_insn "*movsf_update2"
9172   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9173                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9174         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9175    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9176         (plus:SI (match_dup 1) (match_dup 2)))]
9177   "TARGET_HARD_FLOAT && TARGET_UPDATE
9178    && (!avoiding_indexed_address_p (SImode)
9179        || !gpc_reg_operand (operands[2], SImode))"
9180   "@
9181    stfsux %3,%0,%2
9182    stfsu %3,%2(%0)"
9183   [(set_attr "type" "fpstore")
9184    (set_attr "update" "yes")
9185    (set_attr "indexed" "yes,no")])
9187 (define_insn "*movsf_update3"
9188   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9189         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9190                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9191    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9192         (plus:SI (match_dup 1) (match_dup 2)))]
9193   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9194    && (!avoiding_indexed_address_p (SImode)
9195        || !gpc_reg_operand (operands[2], SImode))"
9196   "@
9197    lwzux %3,%0,%2
9198    lwzu %3,%2(%0)"
9199   [(set_attr "type" "load")
9200    (set_attr "update" "yes")
9201    (set_attr "indexed" "yes,no")])
9203 (define_insn "*movsf_update4"
9204   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9205                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9206         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9207    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9208         (plus:SI (match_dup 1) (match_dup 2)))]
9209   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9210    && (!avoiding_indexed_address_p (SImode)
9211        || !gpc_reg_operand (operands[2], SImode))"
9212   "@
9213    stwux %3,%0,%2
9214    stwu %3,%2(%0)"
9215   [(set_attr "type" "store")
9216    (set_attr "update" "yes")
9217    (set_attr "indexed" "yes,no")])
9219 (define_insn "*movdf_update1"
9220   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9221         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9222                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9223    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9224         (plus:SI (match_dup 1) (match_dup 2)))]
9225   "TARGET_HARD_FLOAT && TARGET_UPDATE
9226    && (!avoiding_indexed_address_p (SImode)
9227        || !gpc_reg_operand (operands[2], SImode))"
9228   "@
9229    lfdux %3,%0,%2
9230    lfdu %3,%2(%0)"
9231   [(set_attr "type" "fpload")
9232    (set_attr "update" "yes")
9233    (set_attr "indexed" "yes,no")
9234    (set_attr "size" "64")])
9236 (define_insn "*movdf_update2"
9237   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9238                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9239         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9240    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9241         (plus:SI (match_dup 1) (match_dup 2)))]
9242   "TARGET_HARD_FLOAT && TARGET_UPDATE
9243    && (!avoiding_indexed_address_p (SImode)
9244        || !gpc_reg_operand (operands[2], SImode))"
9245   "@
9246    stfdux %3,%0,%2
9247    stfdu %3,%2(%0)"
9248   [(set_attr "type" "fpstore")
9249    (set_attr "update" "yes")
9250    (set_attr "indexed" "yes,no")])
9253 ;; After inserting conditional returns we can sometimes have
9254 ;; unnecessary register moves.  Unfortunately we cannot have a
9255 ;; modeless peephole here, because some single SImode sets have early
9256 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9257 ;; sequences, using get_attr_length here will smash the operands
9258 ;; array.  Neither is there an early_cobbler_p predicate.
9259 ;; Also this optimization interferes with scalars going into
9260 ;; altivec registers (the code does reloading through the FPRs).
9261 (define_peephole2
9262   [(set (match_operand:DF 0 "gpc_reg_operand")
9263         (match_operand:DF 1 "any_operand"))
9264    (set (match_operand:DF 2 "gpc_reg_operand")
9265         (match_dup 0))]
9266   "!TARGET_VSX
9267    && peep2_reg_dead_p (2, operands[0])"
9268   [(set (match_dup 2) (match_dup 1))])
9270 (define_peephole2
9271   [(set (match_operand:SF 0 "gpc_reg_operand")
9272         (match_operand:SF 1 "any_operand"))
9273    (set (match_operand:SF 2 "gpc_reg_operand")
9274         (match_dup 0))]
9275   "!TARGET_P8_VECTOR
9276    && peep2_reg_dead_p (2, operands[0])"
9277   [(set (match_dup 2) (match_dup 1))])
9280 ;; TLS support.
9282 ;; Mode attributes for different ABIs.
9283 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9284 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9285 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9286 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9288 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9289   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9290         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9291               (match_operand 4 "" "g")))
9292    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9293                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9294                    UNSPEC_TLSGD)
9295    (clobber (reg:SI LR_REGNO))]
9296   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9298   if (TARGET_CMODEL != CMODEL_SMALL)
9299     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9300            "bl %z3\;nop";
9301   else
9302     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9304   "&& TARGET_TLS_MARKERS"
9305   [(set (match_dup 0)
9306         (unspec:TLSmode [(match_dup 1)
9307                          (match_dup 2)]
9308                         UNSPEC_TLSGD))
9309    (parallel [(set (match_dup 0)
9310                    (call (mem:TLSmode (match_dup 3))
9311                          (match_dup 4)))
9312               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9313               (clobber (reg:SI LR_REGNO))])]
9314   ""
9315   [(set_attr "type" "two")
9316    (set (attr "length")
9317      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9318                    (const_int 16)
9319                    (const_int 12)))])
9321 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9322   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9323         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9324               (match_operand 4 "" "g")))
9325    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9326                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9327                    UNSPEC_TLSGD)
9328    (clobber (reg:SI LR_REGNO))]
9329   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9331   if (flag_pic)
9332     {
9333       if (TARGET_SECURE_PLT && flag_pic == 2)
9334         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9335       else
9336         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9337     }
9338   else
9339     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9341   "&& TARGET_TLS_MARKERS"
9342   [(set (match_dup 0)
9343         (unspec:TLSmode [(match_dup 1)
9344                          (match_dup 2)]
9345                         UNSPEC_TLSGD))
9346    (parallel [(set (match_dup 0)
9347                    (call (mem:TLSmode (match_dup 3))
9348                          (match_dup 4)))
9349               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9350               (clobber (reg:SI LR_REGNO))])]
9351   ""
9352   [(set_attr "type" "two")
9353    (set_attr "length" "8")])
9355 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9356   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9357         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9358                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9359                         UNSPEC_TLSGD))]
9360   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9361   "addi %0,%1,%2@got@tlsgd"
9362   "&& TARGET_CMODEL != CMODEL_SMALL"
9363   [(set (match_dup 3)
9364         (high:TLSmode
9365             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9366    (set (match_dup 0)
9367         (lo_sum:TLSmode (match_dup 3)
9368             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9370   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9372   [(set (attr "length")
9373      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9374                    (const_int 8)
9375                    (const_int 4)))])
9377 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9378   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9379      (high:TLSmode
9380        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9381                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9382                        UNSPEC_TLSGD)))]
9383   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9384   "addis %0,%1,%2@got@tlsgd@ha"
9385   [(set_attr "length" "4")])
9387 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9388   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9389      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9390        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9391                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9392                        UNSPEC_TLSGD)))]
9393   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9394   "addi %0,%1,%2@got@tlsgd@l"
9395   [(set_attr "length" "4")])
9397 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9398   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9399         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9400               (match_operand 2 "" "g")))
9401    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9402                    UNSPEC_TLSGD)
9403    (clobber (reg:SI LR_REGNO))]
9404   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9405    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9406   "bl %z1(%3@tlsgd)\;nop"
9407   [(set_attr "type" "branch")
9408    (set_attr "length" "8")])
9410 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9411   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9412         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9413               (match_operand 2 "" "g")))
9414    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9415                    UNSPEC_TLSGD)
9416    (clobber (reg:SI LR_REGNO))]
9417   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9419   if (flag_pic)
9420     {
9421       if (TARGET_SECURE_PLT && flag_pic == 2)
9422         return "bl %z1+32768(%3@tlsgd)@plt";
9423       return "bl %z1(%3@tlsgd)@plt";
9424     }
9425   return "bl %z1(%3@tlsgd)";
9427   [(set_attr "type" "branch")
9428    (set_attr "length" "4")])
9430 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9431   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9432         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9433               (match_operand 3 "" "g")))
9434    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9435                    UNSPEC_TLSLD)
9436    (clobber (reg:SI LR_REGNO))]
9437   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9439   if (TARGET_CMODEL != CMODEL_SMALL)
9440     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9441            "bl %z2\;nop";
9442   else
9443     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9445   "&& TARGET_TLS_MARKERS"
9446   [(set (match_dup 0)
9447         (unspec:TLSmode [(match_dup 1)]
9448                         UNSPEC_TLSLD))
9449    (parallel [(set (match_dup 0)
9450                    (call (mem:TLSmode (match_dup 2))
9451                          (match_dup 3)))
9452               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9453               (clobber (reg:SI LR_REGNO))])]
9454   ""
9455   [(set_attr "type" "two")
9456    (set (attr "length")
9457      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9458                    (const_int 16)
9459                    (const_int 12)))])
9461 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9462   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9463         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9464               (match_operand 3 "" "g")))
9465    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9466                    UNSPEC_TLSLD)
9467    (clobber (reg:SI LR_REGNO))]
9468   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9470   if (flag_pic)
9471     {
9472       if (TARGET_SECURE_PLT && flag_pic == 2)
9473         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9474       else
9475         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9476     }
9477   else
9478     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9480   "&& TARGET_TLS_MARKERS"
9481   [(set (match_dup 0)
9482         (unspec:TLSmode [(match_dup 1)]
9483                         UNSPEC_TLSLD))
9484    (parallel [(set (match_dup 0)
9485                    (call (mem:TLSmode (match_dup 2))
9486                          (match_dup 3)))
9487               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9488               (clobber (reg:SI LR_REGNO))])]
9489   ""
9490   [(set_attr "length" "8")])
9492 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9493   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9494         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9495                         UNSPEC_TLSLD))]
9496   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9497   "addi %0,%1,%&@got@tlsld"
9498   "&& TARGET_CMODEL != CMODEL_SMALL"
9499   [(set (match_dup 2)
9500         (high:TLSmode
9501             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9502    (set (match_dup 0)
9503         (lo_sum:TLSmode (match_dup 2)
9504             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9506   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9508   [(set (attr "length")
9509      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9510                    (const_int 8)
9511                    (const_int 4)))])
9513 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9514   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9515      (high:TLSmode
9516        (unspec:TLSmode [(const_int 0)
9517                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9518                        UNSPEC_TLSLD)))]
9519   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9520   "addis %0,%1,%&@got@tlsld@ha"
9521   [(set_attr "length" "4")])
9523 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9524   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9525      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9526        (unspec:TLSmode [(const_int 0)
9527                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9528                        UNSPEC_TLSLD)))]
9529   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9530   "addi %0,%1,%&@got@tlsld@l"
9531   [(set_attr "length" "4")])
9533 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9534   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9535         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9536               (match_operand 2 "" "g")))
9537    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9538    (clobber (reg:SI LR_REGNO))]
9539   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9540    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9541   "bl %z1(%&@tlsld)\;nop"
9542   [(set_attr "type" "branch")
9543    (set_attr "length" "8")])
9545 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9546   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9547         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9548               (match_operand 2 "" "g")))
9549    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9550    (clobber (reg:SI LR_REGNO))]
9551   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9553   if (flag_pic)
9554     {
9555       if (TARGET_SECURE_PLT && flag_pic == 2)
9556         return "bl %z1+32768(%&@tlsld)@plt";
9557       return "bl %z1(%&@tlsld)@plt";
9558     }
9559   return "bl %z1(%&@tlsld)";
9561   [(set_attr "type" "branch")
9562    (set_attr "length" "4")])
9564 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9565   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9566         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9567                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9568                         UNSPEC_TLSDTPREL))]
9569   "HAVE_AS_TLS"
9570   "addi %0,%1,%2@dtprel")
9572 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9573   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9574         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9575                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9576                         UNSPEC_TLSDTPRELHA))]
9577   "HAVE_AS_TLS"
9578   "addis %0,%1,%2@dtprel@ha")
9580 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9581   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9582         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9583                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9584                         UNSPEC_TLSDTPRELLO))]
9585   "HAVE_AS_TLS"
9586   "addi %0,%1,%2@dtprel@l")
9588 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9589   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9590         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9591                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9592                         UNSPEC_TLSGOTDTPREL))]
9593   "HAVE_AS_TLS"
9594   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9595   "&& TARGET_CMODEL != CMODEL_SMALL"
9596   [(set (match_dup 3)
9597         (high:TLSmode
9598             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9599    (set (match_dup 0)
9600         (lo_sum:TLSmode (match_dup 3)
9601             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9603   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9605   [(set (attr "length")
9606      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9607                    (const_int 8)
9608                    (const_int 4)))])
9610 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9611   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9612      (high:TLSmode
9613        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9614                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9615                        UNSPEC_TLSGOTDTPREL)))]
9616   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9617   "addis %0,%1,%2@got@dtprel@ha"
9618   [(set_attr "length" "4")])
9620 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9621   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9622      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9623          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9624                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9625                          UNSPEC_TLSGOTDTPREL)))]
9626   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9627   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9628   [(set_attr "length" "4")])
9630 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9631   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9632         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9633                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9634                         UNSPEC_TLSTPREL))]
9635   "HAVE_AS_TLS"
9636   "addi %0,%1,%2@tprel")
9638 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9639   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9640         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9641                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9642                         UNSPEC_TLSTPRELHA))]
9643   "HAVE_AS_TLS"
9644   "addis %0,%1,%2@tprel@ha")
9646 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9647   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9648         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9649                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9650                         UNSPEC_TLSTPRELLO))]
9651   "HAVE_AS_TLS"
9652   "addi %0,%1,%2@tprel@l")
9654 ;; "b" output constraint here and on tls_tls input to support linker tls
9655 ;; optimization.  The linker may edit the instructions emitted by a
9656 ;; tls_got_tprel/tls_tls pair to addis,addi.
9657 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9658   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9659         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9660                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9661                         UNSPEC_TLSGOTTPREL))]
9662   "HAVE_AS_TLS"
9663   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9664   "&& TARGET_CMODEL != CMODEL_SMALL"
9665   [(set (match_dup 3)
9666         (high:TLSmode
9667             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9668    (set (match_dup 0)
9669         (lo_sum:TLSmode (match_dup 3)
9670             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9672   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9674   [(set (attr "length")
9675      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9676                    (const_int 8)
9677                    (const_int 4)))])
9679 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9680   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9681      (high:TLSmode
9682        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9683                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9684                        UNSPEC_TLSGOTTPREL)))]
9685   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9686   "addis %0,%1,%2@got@tprel@ha"
9687   [(set_attr "length" "4")])
9689 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9690   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9691      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9692          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9693                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9694                          UNSPEC_TLSGOTTPREL)))]
9695   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9696   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9697   [(set_attr "length" "4")])
9699 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9700   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9701         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9702                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9703                         UNSPEC_TLSTLS))]
9704   "TARGET_ELF && HAVE_AS_TLS"
9705   "add %0,%1,%2@tls")
9707 (define_expand "tls_get_tpointer"
9708   [(set (match_operand:SI 0 "gpc_reg_operand")
9709         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9710   "TARGET_XCOFF && HAVE_AS_TLS"
9712   emit_insn (gen_tls_get_tpointer_internal ());
9713   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9714   DONE;
9717 (define_insn "tls_get_tpointer_internal"
9718   [(set (reg:SI 3)
9719         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9720    (clobber (reg:SI LR_REGNO))]
9721   "TARGET_XCOFF && HAVE_AS_TLS"
9722   "bla __get_tpointer")
9724 (define_expand "tls_get_addr<mode>"
9725   [(set (match_operand:P 0 "gpc_reg_operand")
9726         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9727                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9728   "TARGET_XCOFF && HAVE_AS_TLS"
9730   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9731   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9732   emit_insn (gen_tls_get_addr_internal<mode> ());
9733   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9734   DONE;
9737 (define_insn "tls_get_addr_internal<mode>"
9738   [(set (reg:P 3)
9739         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9740    (clobber (reg:P 0))
9741    (clobber (reg:P 4))
9742    (clobber (reg:P 5))
9743    (clobber (reg:P 11))
9744    (clobber (reg:CC CR0_REGNO))
9745    (clobber (reg:P LR_REGNO))]
9746   "TARGET_XCOFF && HAVE_AS_TLS"
9747   "bla __tls_get_addr")
9749 ;; Next come insns related to the calling sequence.
9751 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9752 ;; We move the back-chain and decrement the stack pointer.
9754 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9755 ;; constant alloca, using that predicate will force the generic code to put
9756 ;; the constant size into a register before calling the expander.
9758 ;; As a result the expander would not have the constant size information
9759 ;; in those cases and would have to generate less efficient code.
9761 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9762 ;; the constant size.  The value is forced into a register if necessary.
9764 (define_expand "allocate_stack"
9765   [(set (match_operand 0 "gpc_reg_operand")
9766         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9767    (set (reg 1)
9768         (minus (reg 1) (match_dup 1)))]
9769   ""
9771   rtx chain = gen_reg_rtx (Pmode);
9772   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9773   rtx neg_op0;
9774   rtx insn, par, set, mem;
9776   /* By allowing reg_or_cint_operand as the predicate we can get
9777      better code for stack-clash-protection because we do not lose
9778      size information.  But the rest of the code expects the operand
9779      to be reg_or_short_operand.  If it isn't, then force it into
9780      a register.  */
9781   rtx orig_op1 = operands[1];
9782   if (!reg_or_short_operand (operands[1], Pmode))
9783     operands[1] = force_reg (Pmode, operands[1]);
9785   emit_move_insn (chain, stack_bot);
9787   /* Check stack bounds if necessary.  */
9788   if (crtl->limit_stack)
9789     {
9790       rtx available;
9791       available = expand_binop (Pmode, sub_optab,
9792                                 stack_pointer_rtx, stack_limit_rtx,
9793                                 NULL_RTX, 1, OPTAB_WIDEN);
9794       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9795     }
9797   /* Allocate and probe if requested.
9798      This may look similar to the loop we use for prologue allocations,
9799      but it is critically different.  For the former we know the loop
9800      will iterate, but do not know that generally here.  The former
9801      uses that knowledge to rotate the loop.  Combining them would be
9802      possible with some performance cost.  */
9803   if (flag_stack_clash_protection)
9804     {
9805       rtx rounded_size, last_addr, residual;
9806       HOST_WIDE_INT probe_interval;
9807       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9808                                                 &residual, &probe_interval,
9809                                                 orig_op1);
9810       
9811       /* We do occasionally get in here with constant sizes, we might
9812          as well do a reasonable job when we obviously can.  */
9813       if (rounded_size != const0_rtx)
9814         {
9815           rtx loop_lab, end_loop;
9816           bool rotated = CONST_INT_P (rounded_size);
9817           rtx update = GEN_INT (-probe_interval);
9818           if (probe_interval > 32768)
9819             update = force_reg (Pmode, update);
9821           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9822                                                         last_addr, rotated);
9824           if (Pmode == SImode)
9825             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9826                                                stack_pointer_rtx,
9827                                                update, chain));
9828           else
9829             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9830                                                   stack_pointer_rtx,
9831                                                   update, chain));
9832           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9833                                                       last_addr, rotated);
9834         }
9836       /* Now handle residuals.  We just have to set operands[1] correctly
9837          and let the rest of the expander run.  */
9838       operands[1] = residual;
9839     }
9841   if (!(CONST_INT_P (operands[1])
9842         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9843     {
9844       operands[1] = force_reg (Pmode, operands[1]);
9845       neg_op0 = gen_reg_rtx (Pmode);
9846       if (TARGET_32BIT)
9847         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9848       else
9849         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9850     }
9851   else
9852     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9854   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9855                                        : gen_movdi_di_update_stack))
9856                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9857                          chain));
9858   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9859      it now and set the alias set/attributes. The above gen_*_update
9860      calls will generate a PARALLEL with the MEM set being the first
9861      operation. */
9862   par = PATTERN (insn);
9863   gcc_assert (GET_CODE (par) == PARALLEL);
9864   set = XVECEXP (par, 0, 0);
9865   gcc_assert (GET_CODE (set) == SET);
9866   mem = SET_DEST (set);
9867   gcc_assert (MEM_P (mem));
9868   MEM_NOTRAP_P (mem) = 1;
9869   set_mem_alias_set (mem, get_frame_alias_set ());
9871   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9872   DONE;
9875 ;; These patterns say how to save and restore the stack pointer.  We need not
9876 ;; save the stack pointer at function level since we are careful to
9877 ;; preserve the backchain.  At block level, we have to restore the backchain
9878 ;; when we restore the stack pointer.
9880 ;; For nonlocal gotos, we must save both the stack pointer and its
9881 ;; backchain and restore both.  Note that in the nonlocal case, the
9882 ;; save area is a memory location.
9884 (define_expand "save_stack_function"
9885   [(match_operand 0 "any_operand")
9886    (match_operand 1 "any_operand")]
9887   ""
9888   "DONE;")
9890 (define_expand "restore_stack_function"
9891   [(match_operand 0 "any_operand")
9892    (match_operand 1 "any_operand")]
9893   ""
9894   "DONE;")
9896 ;; Adjust stack pointer (op0) to a new value (op1).
9897 ;; First copy old stack backchain to new location, and ensure that the
9898 ;; scheduler won't reorder the sp assignment before the backchain write.
9899 (define_expand "restore_stack_block"
9900   [(set (match_dup 2) (match_dup 3))
9901    (set (match_dup 4) (match_dup 2))
9902    (match_dup 5)
9903    (set (match_operand 0 "register_operand")
9904         (match_operand 1 "register_operand"))]
9905   ""
9907   rtvec p;
9909   operands[1] = force_reg (Pmode, operands[1]);
9910   operands[2] = gen_reg_rtx (Pmode);
9911   operands[3] = gen_frame_mem (Pmode, operands[0]);
9912   operands[4] = gen_frame_mem (Pmode, operands[1]);
9913   p = rtvec_alloc (1);
9914   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9915                                   const0_rtx);
9916   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9919 (define_expand "save_stack_nonlocal"
9920   [(set (match_dup 3) (match_dup 4))
9921    (set (match_operand 0 "memory_operand") (match_dup 3))
9922    (set (match_dup 2) (match_operand 1 "register_operand"))]
9923   ""
9925   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9927   /* Copy the backchain to the first word, sp to the second.  */
9928   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9929   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9930   operands[3] = gen_reg_rtx (Pmode);
9931   operands[4] = gen_frame_mem (Pmode, operands[1]);
9934 (define_expand "restore_stack_nonlocal"
9935   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9936    (set (match_dup 3) (match_dup 4))
9937    (set (match_dup 5) (match_dup 2))
9938    (match_dup 6)
9939    (set (match_operand 0 "register_operand") (match_dup 3))]
9940   ""
9942   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9943   rtvec p;
9945   /* Restore the backchain from the first word, sp from the second.  */
9946   operands[2] = gen_reg_rtx (Pmode);
9947   operands[3] = gen_reg_rtx (Pmode);
9948   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9949   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9950   operands[5] = gen_frame_mem (Pmode, operands[3]);
9951   p = rtvec_alloc (1);
9952   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9953                                   const0_rtx);
9954   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9957 ;; TOC register handling.
9959 ;; Code to initialize the TOC register...
9961 (define_insn "load_toc_aix_si"
9962   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9963                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9964               (use (reg:SI 2))])]
9965   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9967   char buf[30];
9968   extern int need_toc_init;
9969   need_toc_init = 1;
9970   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9971   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9972   operands[2] = gen_rtx_REG (Pmode, 2);
9973   return "lwz %0,%1(%2)";
9975   [(set_attr "type" "load")
9976    (set_attr "update" "no")
9977    (set_attr "indexed" "no")])
9979 (define_insn "load_toc_aix_di"
9980   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9981                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9982               (use (reg:DI 2))])]
9983   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9985   char buf[30];
9986   extern int need_toc_init;
9987   need_toc_init = 1;
9988   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9989                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9990   if (TARGET_ELF)
9991     strcat (buf, "@toc");
9992   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9993   operands[2] = gen_rtx_REG (Pmode, 2);
9994   return "ld %0,%1(%2)";
9996   [(set_attr "type" "load")
9997    (set_attr "update" "no")
9998    (set_attr "indexed" "no")])
10000 (define_insn "load_toc_v4_pic_si"
10001   [(set (reg:SI LR_REGNO)
10002         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10003   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10004   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10005   [(set_attr "type" "branch")
10006    (set_attr "length" "4")])
10008 (define_expand "load_toc_v4_PIC_1"
10009   [(parallel [(set (reg:SI LR_REGNO)
10010                    (match_operand:SI 0 "immediate_operand" "s"))
10011               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10012   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10013    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10014   "")
10016 (define_insn "load_toc_v4_PIC_1_normal"
10017   [(set (reg:SI LR_REGNO)
10018         (match_operand:SI 0 "immediate_operand" "s"))
10019    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10020   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10021    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10022   "bcl 20,31,%0\n%0:"
10023   [(set_attr "type" "branch")
10024    (set_attr "length" "4")
10025    (set_attr "cannot_copy" "yes")])
10027 (define_insn "load_toc_v4_PIC_1_476"
10028   [(set (reg:SI LR_REGNO)
10029         (match_operand:SI 0 "immediate_operand" "s"))
10030    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10031   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10032    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10034   char name[32];
10035   static char templ[32];
10037   get_ppc476_thunk_name (name);
10038   sprintf (templ, "bl %s\n%%0:", name);
10039   return templ;
10041   [(set_attr "type" "branch")
10042    (set_attr "length" "4")
10043    (set_attr "cannot_copy" "yes")])
10045 (define_expand "load_toc_v4_PIC_1b"
10046   [(parallel [(set (reg:SI LR_REGNO)
10047                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10048                                (label_ref (match_operand 1 ""))]
10049                            UNSPEC_TOCPTR))
10050               (match_dup 1)])]
10051   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10052   "")
10054 (define_insn "load_toc_v4_PIC_1b_normal"
10055   [(set (reg:SI LR_REGNO)
10056         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10057                     (label_ref (match_operand 1 "" ""))]
10058                 UNSPEC_TOCPTR))
10059    (match_dup 1)]
10060   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10061   "bcl 20,31,$+8\;.long %0-$"
10062   [(set_attr "type" "branch")
10063    (set_attr "length" "8")])
10065 (define_insn "load_toc_v4_PIC_1b_476"
10066   [(set (reg:SI LR_REGNO)
10067         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10068                     (label_ref (match_operand 1 "" ""))]
10069                 UNSPEC_TOCPTR))
10070    (match_dup 1)]
10071   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10073   char name[32];
10074   static char templ[32];
10076   get_ppc476_thunk_name (name);
10077   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10078   return templ;
10080   [(set_attr "type" "branch")
10081    (set_attr "length" "16")])
10083 (define_insn "load_toc_v4_PIC_2"
10084   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10085         (mem:SI (plus:SI
10086                   (match_operand:SI 1 "gpc_reg_operand" "b")
10087                   (const
10088                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10089                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10090   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10091   "lwz %0,%2-%3(%1)"
10092   [(set_attr "type" "load")])
10094 (define_insn "load_toc_v4_PIC_3b"
10095   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10096         (plus:SI
10097           (match_operand:SI 1 "gpc_reg_operand" "b")
10098           (high:SI
10099             (const
10100               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10101                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10102   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10103   "addis %0,%1,%2-%3@ha")
10105 (define_insn "load_toc_v4_PIC_3c"
10106   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10107         (lo_sum:SI
10108           (match_operand:SI 1 "gpc_reg_operand" "b")
10109           (const
10110             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10111                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10112   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10113   "addi %0,%1,%2-%3@l")
10115 ;; If the TOC is shared over a translation unit, as happens with all
10116 ;; the kinds of PIC that we support, we need to restore the TOC
10117 ;; pointer only when jumping over units of translation.
10118 ;; On Darwin, we need to reload the picbase.
10120 (define_expand "builtin_setjmp_receiver"
10121   [(use (label_ref (match_operand 0 "")))]
10122   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10123    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10124    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10126 #if TARGET_MACHO
10127   if (DEFAULT_ABI == ABI_DARWIN)
10128     {
10129       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10130       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10131       rtx tmplabrtx;
10132       char tmplab[20];
10134       crtl->uses_pic_offset_table = 1;
10135       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10136                                   CODE_LABEL_NUMBER (operands[0]));
10137       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10139       emit_insn (gen_load_macho_picbase (tmplabrtx));
10140       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10141       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10142     }
10143   else
10144 #endif
10145     rs6000_emit_load_toc_table (FALSE);
10146   DONE;
10149 ;; Largetoc support
10150 (define_insn "*largetoc_high"
10151   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10152         (high:DI
10153           (unspec [(match_operand:DI 1 "" "")
10154                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10155                   UNSPEC_TOCREL)))]
10156    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10157    "addis %0,%2,%1@toc@ha")
10159 (define_insn "*largetoc_high_aix<mode>"
10160   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10161         (high:P
10162           (unspec [(match_operand:P 1 "" "")
10163                    (match_operand:P 2 "gpc_reg_operand" "b")]
10164                   UNSPEC_TOCREL)))]
10165    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10166    "addis %0,%1@u(%2)")
10168 (define_insn "*largetoc_high_plus"
10169   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10170         (high:DI
10171           (plus:DI
10172             (unspec [(match_operand:DI 1 "" "")
10173                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10174                     UNSPEC_TOCREL)
10175             (match_operand:DI 3 "add_cint_operand" "n"))))]
10176    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10177    "addis %0,%2,%1+%3@toc@ha")
10179 (define_insn "*largetoc_high_plus_aix<mode>"
10180   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10181         (high:P
10182           (plus:P
10183             (unspec [(match_operand:P 1 "" "")
10184                      (match_operand:P 2 "gpc_reg_operand" "b")]
10185                     UNSPEC_TOCREL)
10186             (match_operand:P 3 "add_cint_operand" "n"))))]
10187    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10188    "addis %0,%1+%3@u(%2)")
10190 (define_insn "*largetoc_low"
10191   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10192         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10193                    (match_operand:DI 2 "" "")))]
10194    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10195    "addi %0,%1,%2@l")
10197 (define_insn "*largetoc_low_aix<mode>"
10198   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10199         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10200                    (match_operand:P 2 "" "")))]
10201    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10202    "la %0,%2@l(%1)")
10204 (define_insn_and_split "*tocref<mode>"
10205   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10206         (match_operand:P 1 "small_toc_ref" "R"))]
10207    "TARGET_TOC"
10208    "la %0,%a1"
10209    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10210   [(set (match_dup 0) (high:P (match_dup 1)))
10211    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10213 ;; Elf specific ways of loading addresses for non-PIC code.
10214 ;; The output of this could be r0, but we make a very strong
10215 ;; preference for a base register because it will usually
10216 ;; be needed there.
10217 (define_insn "elf_high"
10218   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10219         (high:SI (match_operand 1 "" "")))]
10220   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10221   "lis %0,%1@ha")
10223 (define_insn "elf_low"
10224   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10225         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10226                    (match_operand 2 "" "")))]
10227    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10228    "la %0,%2@l(%1)")
10230 ;; Call and call_value insns
10231 (define_expand "call"
10232   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10233                     (match_operand 1 ""))
10234               (use (match_operand 2 ""))
10235               (clobber (reg:SI LR_REGNO))])]
10236   ""
10238 #if TARGET_MACHO
10239   if (MACHOPIC_INDIRECT)
10240     operands[0] = machopic_indirect_call_target (operands[0]);
10241 #endif
10243   gcc_assert (GET_CODE (operands[0]) == MEM);
10244   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10246   operands[0] = XEXP (operands[0], 0);
10248   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10249     {
10250       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10251       DONE;
10252     }
10254   if (GET_CODE (operands[0]) != SYMBOL_REF
10255       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10256     {
10257       if (INTVAL (operands[2]) & CALL_LONG)
10258         operands[0] = rs6000_longcall_ref (operands[0]);
10260       switch (DEFAULT_ABI)
10261         {
10262         case ABI_V4:
10263         case ABI_DARWIN:
10264           operands[0] = force_reg (Pmode, operands[0]);
10265           break;
10267         default:
10268           gcc_unreachable ();
10269         }
10270     }
10273 (define_expand "call_value"
10274   [(parallel [(set (match_operand 0 "")
10275                    (call (mem:SI (match_operand 1 "address_operand"))
10276                          (match_operand 2 "")))
10277               (use (match_operand 3 ""))
10278               (clobber (reg:SI LR_REGNO))])]
10279   ""
10281 #if TARGET_MACHO
10282   if (MACHOPIC_INDIRECT)
10283     operands[1] = machopic_indirect_call_target (operands[1]);
10284 #endif
10286   gcc_assert (GET_CODE (operands[1]) == MEM);
10287   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10289   operands[1] = XEXP (operands[1], 0);
10291   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10292     {
10293       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10294       DONE;
10295     }
10297   if (GET_CODE (operands[1]) != SYMBOL_REF
10298       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10299     {
10300       if (INTVAL (operands[3]) & CALL_LONG)
10301         operands[1] = rs6000_longcall_ref (operands[1]);
10303       switch (DEFAULT_ABI)
10304         {
10305         case ABI_V4:
10306         case ABI_DARWIN:
10307           operands[1] = force_reg (Pmode, operands[1]);
10308           break;
10310         default:
10311           gcc_unreachable ();
10312         }
10313     }
10316 ;; Call to function in current module.  No TOC pointer reload needed.
10317 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10318 ;; either the function was not prototyped, or it was prototyped as a
10319 ;; variable argument function.  It is > 0 if FP registers were passed
10320 ;; and < 0 if they were not.
10322 (define_insn "*call_local32"
10323   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10324          (match_operand 1 "" "g,g"))
10325    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10326    (clobber (reg:SI LR_REGNO))]
10327   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10329   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10330     output_asm_insn ("crxor 6,6,6", operands);
10332   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10333     output_asm_insn ("creqv 6,6,6", operands);
10335   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10337   [(set_attr "type" "branch")
10338    (set_attr "length" "4,8")])
10340 (define_insn "*call_local64"
10341   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10342          (match_operand 1 "" "g,g"))
10343    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10344    (clobber (reg:SI LR_REGNO))]
10345   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10347   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10348     output_asm_insn ("crxor 6,6,6", operands);
10350   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10351     output_asm_insn ("creqv 6,6,6", operands);
10353   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10355   [(set_attr "type" "branch")
10356    (set_attr "length" "4,8")])
10358 (define_insn "*call_value_local32"
10359   [(set (match_operand 0 "" "")
10360         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10361               (match_operand 2 "" "g,g")))
10362    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10363    (clobber (reg:SI LR_REGNO))]
10364   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10366   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10367     output_asm_insn ("crxor 6,6,6", operands);
10369   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10370     output_asm_insn ("creqv 6,6,6", operands);
10372   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10374   [(set_attr "type" "branch")
10375    (set_attr "length" "4,8")])
10378 (define_insn "*call_value_local64"
10379   [(set (match_operand 0 "" "")
10380         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10381               (match_operand 2 "" "g,g")))
10382    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10383    (clobber (reg:SI LR_REGNO))]
10384   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10386   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10387     output_asm_insn ("crxor 6,6,6", operands);
10389   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10390     output_asm_insn ("creqv 6,6,6", operands);
10392   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10394   [(set_attr "type" "branch")
10395    (set_attr "length" "4,8")])
10398 ;; A function pointer under System V is just a normal pointer
10399 ;; operands[0] is the function pointer
10400 ;; operands[1] is the stack size to clean up
10401 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10402 ;; which indicates how to set cr1
10404 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10405   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10406          (match_operand 1 "" "g,g,g,g"))
10407    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10408    (clobber (reg:SI LR_REGNO))]
10409   "DEFAULT_ABI == ABI_V4
10410    || DEFAULT_ABI == ABI_DARWIN"
10412   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10413     output_asm_insn ("crxor 6,6,6", operands);
10415   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10416     output_asm_insn ("creqv 6,6,6", operands);
10418   if (rs6000_speculate_indirect_jumps
10419       || which_alternative == 1 || which_alternative == 3)
10420     return "b%T0l";
10421   else
10422     return "crset 2\;beq%T0l-";
10424   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10425    (set (attr "length")
10426         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10427                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10428                         (const_int 0)))
10429                   (const_string "8")
10430                (and (eq (symbol_ref "which_alternative") (const_int 2))
10431                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10432                         (const_int 0)))
10433                   (const_string "8")
10434                (and (eq (symbol_ref "which_alternative") (const_int 2))
10435                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10436                         (const_int 0)))
10437                   (const_string "12")
10438                (eq (symbol_ref "which_alternative") (const_int 3))
10439                   (const_string "8")]
10440               (const_string "4")))])
10442 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10443   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10444          (match_operand 1 "" "g,g"))
10445    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10446    (clobber (reg:SI LR_REGNO))]
10447   "(DEFAULT_ABI == ABI_DARWIN
10448    || (DEFAULT_ABI == ABI_V4
10449        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10451   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10452     output_asm_insn ("crxor 6,6,6", operands);
10454   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10455     output_asm_insn ("creqv 6,6,6", operands);
10457 #if TARGET_MACHO
10458   return output_call(insn, operands, 0, 2);
10459 #else
10460   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10461     {
10462       gcc_assert (!TARGET_SECURE_PLT);
10463       return "bl %z0@plt";
10464     }
10465   else
10466     return "bl %z0";
10467 #endif
10469   "DEFAULT_ABI == ABI_V4
10470    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10471    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10472   [(parallel [(call (mem:SI (match_dup 0))
10473                     (match_dup 1))
10474               (use (match_dup 2))
10475               (use (match_dup 3))
10476               (clobber (reg:SI LR_REGNO))])]
10478   operands[3] = pic_offset_table_rtx;
10480   [(set_attr "type" "branch,branch")
10481    (set_attr "length" "4,8")])
10483 (define_insn "*call_nonlocal_sysv_secure<mode>"
10484   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10485          (match_operand 1 "" "g,g"))
10486    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10487    (use (match_operand:SI 3 "register_operand" "r,r"))
10488    (clobber (reg:SI LR_REGNO))]
10489   "(DEFAULT_ABI == ABI_V4
10490     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10491     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10493   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10494     output_asm_insn ("crxor 6,6,6", operands);
10496   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10497     output_asm_insn ("creqv 6,6,6", operands);
10499   if (flag_pic == 2)
10500     /* The magic 32768 offset here and in the other sysv call insns
10501        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10502        See sysv4.h:toc_section.  */
10503     return "bl %z0+32768@plt";
10504   else
10505     return "bl %z0@plt";
10507   [(set_attr "type" "branch,branch")
10508    (set_attr "length" "4,8")])
10510 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10511   [(set (match_operand 0 "" "")
10512         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10513               (match_operand 2 "" "g,g,g,g")))
10514    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10515    (clobber (reg:SI LR_REGNO))]
10516   "DEFAULT_ABI == ABI_V4
10517    || DEFAULT_ABI == ABI_DARWIN"
10519   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10520     output_asm_insn ("crxor 6,6,6", operands);
10522   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10523     output_asm_insn ("creqv 6,6,6", operands);
10525   if (rs6000_speculate_indirect_jumps
10526       || which_alternative == 1 || which_alternative == 3)
10527     return "b%T1l";
10528   else
10529     return "crset 2\;beq%T1l-";
10531   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10532    (set (attr "length")
10533         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10534                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10535                         (const_int 0)))
10536                   (const_string "8")
10537                (and (eq (symbol_ref "which_alternative") (const_int 2))
10538                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10539                         (const_int 0)))
10540                   (const_string "8")
10541                (and (eq (symbol_ref "which_alternative") (const_int 2))
10542                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10543                         (const_int 0)))
10544                   (const_string "12")
10545                (eq (symbol_ref "which_alternative") (const_int 3))
10546                   (const_string "8")]
10547               (const_string "4")))])
10549 (define_insn_and_split "*call_value_nonlocal_sysv<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    (clobber (reg:SI LR_REGNO))]
10555   "(DEFAULT_ABI == ABI_DARWIN
10556    || (DEFAULT_ABI == ABI_V4
10557        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10559   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10560     output_asm_insn ("crxor 6,6,6", operands);
10562   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10563     output_asm_insn ("creqv 6,6,6", operands);
10565 #if TARGET_MACHO
10566   return output_call(insn, operands, 1, 3);
10567 #else
10568   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10569     {
10570       gcc_assert (!TARGET_SECURE_PLT);
10571       return "bl %z1@plt";
10572     }
10573   else
10574     return "bl %z1";
10575 #endif
10577   "DEFAULT_ABI == ABI_V4
10578    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10579    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10580   [(parallel [(set (match_dup 0)
10581                    (call (mem:SI (match_dup 1))
10582                          (match_dup 2)))
10583               (use (match_dup 3))
10584               (use (match_dup 4))
10585               (clobber (reg:SI LR_REGNO))])]
10587   operands[4] = pic_offset_table_rtx;
10589   [(set_attr "type" "branch,branch")
10590    (set_attr "length" "4,8")])
10592 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10593   [(set (match_operand 0 "" "")
10594         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10595               (match_operand 2 "" "g,g")))
10596    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10597    (use (match_operand:SI 4 "register_operand" "r,r"))
10598    (clobber (reg:SI LR_REGNO))]
10599   "(DEFAULT_ABI == ABI_V4
10600     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10601     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10603   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10604     output_asm_insn ("crxor 6,6,6", operands);
10606   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10607     output_asm_insn ("creqv 6,6,6", operands);
10609   if (flag_pic == 2)
10610     return "bl %z1+32768@plt";
10611   else
10612     return "bl %z1@plt";
10614   [(set_attr "type" "branch,branch")
10615    (set_attr "length" "4,8")])
10618 ;; Call to AIX abi function in the same module.
10620 (define_insn "*call_local_aix<mode>"
10621   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10622          (match_operand 1 "" "g"))
10623    (clobber (reg:P LR_REGNO))]
10624   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10625   "bl %z0"
10626   [(set_attr "type" "branch")
10627    (set_attr "length" "4")])
10629 (define_insn "*call_value_local_aix<mode>"
10630   [(set (match_operand 0 "" "")
10631         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10632               (match_operand 2 "" "g")))
10633    (clobber (reg:P LR_REGNO))]
10634   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10635   "bl %z1"
10636   [(set_attr "type" "branch")
10637    (set_attr "length" "4")])
10639 ;; Call to AIX abi function which may be in another module.
10640 ;; Restore the TOC pointer (r2) after the call.
10642 (define_insn "*call_nonlocal_aix<mode>"
10643   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10644          (match_operand 1 "" "g"))
10645    (clobber (reg:P LR_REGNO))]
10646   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10647   "bl %z0\;nop"
10648   [(set_attr "type" "branch")
10649    (set_attr "length" "8")])
10651 (define_insn "*call_value_nonlocal_aix<mode>"
10652   [(set (match_operand 0 "" "")
10653         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10654               (match_operand 2 "" "g")))
10655    (clobber (reg:P LR_REGNO))]
10656   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10657   "bl %z1\;nop"
10658   [(set_attr "type" "branch")
10659    (set_attr "length" "8")])
10661 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10662 ;; Operand0 is the addresss of the function to call
10663 ;; Operand2 is the location in the function descriptor to load r2 from
10664 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10666 (define_insn "*call_indirect_aix<mode>"
10667   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10668          (match_operand 1 "" "g,g"))
10669    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10670    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10671    (clobber (reg:P LR_REGNO))]
10672   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10673   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10674   [(set_attr "type" "jmpreg")
10675    (set_attr "length" "12")])
10677 (define_insn "*call_indirect_aix<mode>_nospec"
10678   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10679          (match_operand 1 "" "g,g"))
10680    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10681    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10682    (clobber (reg:P LR_REGNO))]
10683   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10684   "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10685   [(set_attr "type" "jmpreg")
10686    (set_attr "length" "16")])
10688 (define_insn "*call_value_indirect_aix<mode>"
10689   [(set (match_operand 0 "" "")
10690         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10691               (match_operand 2 "" "g,g")))
10692    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10693    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10694    (clobber (reg:P LR_REGNO))]
10695   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10696   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10697   [(set_attr "type" "jmpreg")
10698    (set_attr "length" "12")])
10700 (define_insn "*call_value_indirect_aix<mode>_nospec"
10701   [(set (match_operand 0 "" "")
10702         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10703               (match_operand 2 "" "g,g")))
10704    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10705    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10706    (clobber (reg:P LR_REGNO))]
10707   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10708   "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10709   [(set_attr "type" "jmpreg")
10710    (set_attr "length" "16")])
10712 ;; Call to indirect functions with the ELFv2 ABI.
10713 ;; Operand0 is the addresss of the function to call
10714 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10716 (define_insn "*call_indirect_elfv2<mode>"
10717   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10718          (match_operand 1 "" "g,g"))
10719    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10720    (clobber (reg:P LR_REGNO))]
10721   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10722   "b%T0l\;<ptrload> 2,%2(1)"
10723   [(set_attr "type" "jmpreg")
10724    (set_attr "length" "8")])
10726 ;; Variant with deliberate misprediction.
10727 (define_insn "*call_indirect_elfv2<mode>_nospec"
10728   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10729          (match_operand 1 "" "g,g"))
10730    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10731    (clobber (reg:P LR_REGNO))]
10732   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10733   "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10734   [(set_attr "type" "jmpreg")
10735    (set_attr "length" "12")])
10737 (define_insn "*call_value_indirect_elfv2<mode>"
10738   [(set (match_operand 0 "" "")
10739         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10740               (match_operand 2 "" "g,g")))
10741    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10742    (clobber (reg:P LR_REGNO))]
10743   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10744   "b%T1l\;<ptrload> 2,%3(1)"
10745   [(set_attr "type" "jmpreg")
10746    (set_attr "length" "8")])
10748 ; Variant with deliberate misprediction.
10749 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10750   [(set (match_operand 0 "" "")
10751         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10752               (match_operand 2 "" "g,g")))
10753    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10754    (clobber (reg:P LR_REGNO))]
10755   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10756   "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10757   [(set_attr "type" "jmpreg")
10758    (set_attr "length" "12")])
10760 ;; Call subroutine returning any type.
10761 (define_expand "untyped_call"
10762   [(parallel [(call (match_operand 0 "")
10763                     (const_int 0))
10764               (match_operand 1 "")
10765               (match_operand 2 "")])]
10766   ""
10768   int i;
10770   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10772   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10773     {
10774       rtx set = XVECEXP (operands[2], 0, i);
10775       emit_move_insn (SET_DEST (set), SET_SRC (set));
10776     }
10778   /* The optimizer does not know that the call sets the function value
10779      registers we stored in the result block.  We avoid problems by
10780      claiming that all hard registers are used and clobbered at this
10781      point.  */
10782   emit_insn (gen_blockage ());
10784   DONE;
10787 ;; sibling call patterns
10788 (define_expand "sibcall"
10789   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10790                     (match_operand 1 ""))
10791               (use (match_operand 2 ""))
10792               (simple_return)])]
10793   ""
10795 #if TARGET_MACHO
10796   if (MACHOPIC_INDIRECT)
10797     operands[0] = machopic_indirect_call_target (operands[0]);
10798 #endif
10800   gcc_assert (GET_CODE (operands[0]) == MEM);
10801   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10803   operands[0] = XEXP (operands[0], 0);
10805   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10806     {
10807       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10808       DONE;
10809     }
10812 (define_expand "sibcall_value"
10813   [(parallel [(set (match_operand 0 "register_operand")
10814                 (call (mem:SI (match_operand 1 "address_operand"))
10815                       (match_operand 2 "")))
10816               (use (match_operand 3 ""))
10817               (simple_return)])]
10818   ""
10820 #if TARGET_MACHO
10821   if (MACHOPIC_INDIRECT)
10822     operands[1] = machopic_indirect_call_target (operands[1]);
10823 #endif
10825   gcc_assert (GET_CODE (operands[1]) == MEM);
10826   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10828   operands[1] = XEXP (operands[1], 0);
10830   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10831     {
10832       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10833       DONE;
10834     }
10837 (define_insn "*sibcall_local32"
10838   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10839          (match_operand 1 "" "g,g"))
10840    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10841    (simple_return)]
10842   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10844   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10845     output_asm_insn ("crxor 6,6,6", operands);
10847   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10848     output_asm_insn ("creqv 6,6,6", operands);
10850   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10852   [(set_attr "type" "branch")
10853    (set_attr "length" "4,8")])
10855 (define_insn "*sibcall_local64"
10856   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10857          (match_operand 1 "" "g,g"))
10858    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10859    (simple_return)]
10860   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10862   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10863     output_asm_insn ("crxor 6,6,6", operands);
10865   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10866     output_asm_insn ("creqv 6,6,6", operands);
10868   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10870   [(set_attr "type" "branch")
10871    (set_attr "length" "4,8")])
10873 (define_insn "*sibcall_value_local32"
10874   [(set (match_operand 0 "" "")
10875         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10876               (match_operand 2 "" "g,g")))
10877    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10878    (simple_return)]
10879   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10881   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10882     output_asm_insn ("crxor 6,6,6", operands);
10884   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10885     output_asm_insn ("creqv 6,6,6", operands);
10887   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10889   [(set_attr "type" "branch")
10890    (set_attr "length" "4,8")])
10892 (define_insn "*sibcall_value_local64"
10893   [(set (match_operand 0 "" "")
10894         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10895               (match_operand 2 "" "g,g")))
10896    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10897    (simple_return)]
10898   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10900   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10901     output_asm_insn ("crxor 6,6,6", operands);
10903   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10904     output_asm_insn ("creqv 6,6,6", operands);
10906   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10908   [(set_attr "type" "branch")
10909    (set_attr "length" "4,8")])
10911 (define_insn "*sibcall_nonlocal_sysv<mode>"
10912   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10913          (match_operand 1 "" ""))
10914    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10915    (simple_return)]
10916   "(DEFAULT_ABI == ABI_DARWIN
10917     || DEFAULT_ABI == ABI_V4)
10918    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10920   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10921     output_asm_insn ("crxor 6,6,6", operands);
10923   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10924     output_asm_insn ("creqv 6,6,6", operands);
10926   if (which_alternative >= 2)
10927     {
10928       if (rs6000_speculate_indirect_jumps)
10929         return "b%T0";
10930       else
10931         /* Can use CR0 since it is volatile across sibcalls.  */
10932         return "crset 2\;beq%T0-\;b $";
10933     }
10934   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10935     {
10936       gcc_assert (!TARGET_SECURE_PLT);
10937       return "b %z0@plt";
10938     }
10939   else
10940     return "b %z0";
10942   [(set_attr "type" "branch")
10943    (set (attr "length")
10944         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10945                   (const_string "8")
10946                (and (eq (symbol_ref "which_alternative") (const_int 2))
10947                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10948                         (const_int 0)))
10949                   (const_string "12")
10950                (and (eq (symbol_ref "which_alternative") (const_int 3))
10951                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10952                         (const_int 0)))
10953                   (const_string "8")
10954                (and (eq (symbol_ref "which_alternative") (const_int 3))
10955                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10956                         (const_int 0)))
10957                   (const_string "16")]
10958               (const_string "4")))])
10960 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10961   [(set (match_operand 0 "" "")
10962         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10963               (match_operand 2 "" "")))
10964    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10965    (simple_return)]
10966   "(DEFAULT_ABI == ABI_DARWIN
10967     || DEFAULT_ABI == ABI_V4)
10968    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10970   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10971     output_asm_insn ("crxor 6,6,6", operands);
10973   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10974     output_asm_insn ("creqv 6,6,6", operands);
10976   if (which_alternative >= 2)
10977     {
10978       if (rs6000_speculate_indirect_jumps)
10979         return "b%T1";
10980       else
10981         /* Can use CR0 since it is volatile across sibcalls.  */
10982         return "crset 2\;beq%T1-\;b $";
10983     }
10984   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10985     {
10986       gcc_assert (!TARGET_SECURE_PLT);
10987       return "b %z1@plt";
10988     }
10989   else
10990     return "b %z1";
10992   [(set_attr "type" "branch")
10993    (set (attr "length")
10994         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10995                   (const_string "8")
10996                (and (eq (symbol_ref "which_alternative") (const_int 2))
10997                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10998                         (const_int 0)))
10999                   (const_string "12")
11000                (and (eq (symbol_ref "which_alternative") (const_int 3))
11001                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
11002                         (const_int 0)))
11003                   (const_string "8")
11004                (and (eq (symbol_ref "which_alternative") (const_int 3))
11005                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11006                         (const_int 0)))
11007                   (const_string "16")]
11008               (const_string "4")))])
11010 ;; AIX ABI sibling call patterns.
11012 (define_insn "*sibcall_aix<mode>"
11013   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11014          (match_operand 1 "" "g,g"))
11015    (simple_return)]
11016   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11017   "@
11018    b %z0
11019    b%T0"
11020   [(set_attr "type" "branch")
11021    (set_attr "length" "4")])
11023 (define_insn "*sibcall_value_aix<mode>"
11024   [(set (match_operand 0 "" "")
11025         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11026               (match_operand 2 "" "g,g")))
11027    (simple_return)]
11028   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11029   "@
11030    b %z1
11031    b%T1"
11032   [(set_attr "type" "branch")
11033    (set_attr "length" "4")])
11035 (define_expand "sibcall_epilogue"
11036   [(use (const_int 0))]
11037   ""
11039   if (!TARGET_SCHED_PROLOG)
11040     emit_insn (gen_blockage ());
11041   rs6000_emit_epilogue (TRUE);
11042   DONE;
11045 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11046 ;; all of memory.  This blocks insns from being moved across this point.
11048 (define_insn "blockage"
11049   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11050   ""
11051   ""
11052   [(set_attr "length" "0")])
11054 (define_expand "probe_stack_address"
11055   [(use (match_operand 0 "address_operand"))]
11056   ""
11058   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11059   MEM_VOLATILE_P (operands[0]) = 1;
11061   if (TARGET_64BIT)
11062     emit_insn (gen_probe_stack_di (operands[0]));
11063   else
11064     emit_insn (gen_probe_stack_si (operands[0]));
11065   DONE;
11068 (define_insn "probe_stack_<mode>"
11069   [(set (match_operand:P 0 "memory_operand" "=m")
11070         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11071   ""
11073   operands[1] = gen_rtx_REG (Pmode, 0);
11074   return "st<wd>%U0%X0 %1,%0";
11076   [(set_attr "type" "store")
11077    (set (attr "update")
11078         (if_then_else (match_operand 0 "update_address_mem")
11079                       (const_string "yes")
11080                       (const_string "no")))
11081    (set (attr "indexed")
11082         (if_then_else (match_operand 0 "indexed_address_mem")
11083                       (const_string "yes")
11084                       (const_string "no")))
11085    (set_attr "length" "4")])
11087 (define_insn "probe_stack_range<P:mode>"
11088   [(set (match_operand:P 0 "register_operand" "=&r")
11089         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11090                             (match_operand:P 2 "register_operand" "r")
11091                             (match_operand:P 3 "register_operand" "r")]
11092                            UNSPECV_PROBE_STACK_RANGE))]
11093   ""
11094   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11095   [(set_attr "type" "three")])
11097 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11098 ;; signed & unsigned, and one type of branch.
11100 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11101 ;; insns, and branches.
11103 (define_expand "cbranch<mode>4"
11104   [(use (match_operator 0 "comparison_operator"
11105          [(match_operand:GPR 1 "gpc_reg_operand")
11106           (match_operand:GPR 2 "reg_or_short_operand")]))
11107    (use (match_operand 3))]
11108   ""
11110   /* Take care of the possibility that operands[2] might be negative but
11111      this might be a logical operation.  That insn doesn't exist.  */
11112   if (GET_CODE (operands[2]) == CONST_INT
11113       && INTVAL (operands[2]) < 0)
11114     {
11115       operands[2] = force_reg (<MODE>mode, operands[2]);
11116       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11117                                     GET_MODE (operands[0]),
11118                                     operands[1], operands[2]);
11119    }
11121   rs6000_emit_cbranch (<MODE>mode, operands);
11122   DONE;
11125 (define_expand "cbranch<mode>4"
11126   [(use (match_operator 0 "comparison_operator"
11127          [(match_operand:FP 1 "gpc_reg_operand")
11128           (match_operand:FP 2 "gpc_reg_operand")]))
11129    (use (match_operand 3))]
11130   ""
11132   rs6000_emit_cbranch (<MODE>mode, operands);
11133   DONE;
11136 (define_expand "cstore<mode>4_signed"
11137   [(use (match_operator 1 "signed_comparison_operator"
11138          [(match_operand:P 2 "gpc_reg_operand")
11139           (match_operand:P 3 "gpc_reg_operand")]))
11140    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11141   ""
11143   enum rtx_code cond_code = GET_CODE (operands[1]);
11145   rtx op0 = operands[0];
11146   rtx op1 = operands[2];
11147   rtx op2 = operands[3];
11149   if (cond_code == GE || cond_code == LT)
11150     {
11151       cond_code = swap_condition (cond_code);
11152       std::swap (op1, op2);
11153     }
11155   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11156   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11157   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11159   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11160   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11161   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11163   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11165   if (cond_code == LE)
11166     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11167   else
11168     {
11169       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11170       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11171       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11172     }
11174   DONE;
11177 (define_expand "cstore<mode>4_unsigned"
11178   [(use (match_operator 1 "unsigned_comparison_operator"
11179          [(match_operand:P 2 "gpc_reg_operand")
11180           (match_operand:P 3 "reg_or_short_operand")]))
11181    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11182   ""
11184   enum rtx_code cond_code = GET_CODE (operands[1]);
11186   rtx op0 = operands[0];
11187   rtx op1 = operands[2];
11188   rtx op2 = operands[3];
11190   if (cond_code == GEU || cond_code == LTU)
11191     {
11192       cond_code = swap_condition (cond_code);
11193       std::swap (op1, op2);
11194     }
11196   if (!gpc_reg_operand (op1, <MODE>mode))
11197     op1 = force_reg (<MODE>mode, op1);
11198   if (!reg_or_short_operand (op2, <MODE>mode))
11199     op2 = force_reg (<MODE>mode, op2);
11201   rtx tmp = gen_reg_rtx (<MODE>mode);
11202   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11204   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11205   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11207   if (cond_code == LEU)
11208     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11209   else
11210     emit_insn (gen_neg<mode>2 (op0, tmp2));
11212   DONE;
11215 (define_expand "cstore_si_as_di"
11216   [(use (match_operator 1 "unsigned_comparison_operator"
11217          [(match_operand:SI 2 "gpc_reg_operand")
11218           (match_operand:SI 3 "reg_or_short_operand")]))
11219    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11220   ""
11222   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11223   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11225   operands[2] = force_reg (SImode, operands[2]);
11226   operands[3] = force_reg (SImode, operands[3]);
11227   rtx op1 = gen_reg_rtx (DImode);
11228   rtx op2 = gen_reg_rtx (DImode);
11229   convert_move (op1, operands[2], uns_flag);
11230   convert_move (op2, operands[3], uns_flag);
11232   if (cond_code == GT || cond_code == LE)
11233     {
11234       cond_code = swap_condition (cond_code);
11235       std::swap (op1, op2);
11236     }
11238   rtx tmp = gen_reg_rtx (DImode);
11239   rtx tmp2 = gen_reg_rtx (DImode);
11240   emit_insn (gen_subdi3 (tmp, op1, op2));
11241   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11243   rtx tmp3;
11244   switch (cond_code)
11245     {
11246     default:
11247       gcc_unreachable ();
11248     case LT:
11249       tmp3 = tmp2;
11250       break;
11251     case GE:
11252       tmp3 = gen_reg_rtx (DImode);
11253       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11254       break;
11255     }
11257   convert_move (operands[0], tmp3, 1);
11259   DONE;
11262 (define_expand "cstore<mode>4_signed_imm"
11263   [(use (match_operator 1 "signed_comparison_operator"
11264          [(match_operand:GPR 2 "gpc_reg_operand")
11265           (match_operand:GPR 3 "immediate_operand")]))
11266    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11267   ""
11269   bool invert = false;
11271   enum rtx_code cond_code = GET_CODE (operands[1]);
11273   rtx op0 = operands[0];
11274   rtx op1 = operands[2];
11275   HOST_WIDE_INT val = INTVAL (operands[3]);
11277   if (cond_code == GE || cond_code == GT)
11278     {
11279       cond_code = reverse_condition (cond_code);
11280       invert = true;
11281     }
11283   if (cond_code == LE)
11284     val++;
11286   rtx tmp = gen_reg_rtx (<MODE>mode);
11287   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11288   rtx x = gen_reg_rtx (<MODE>mode);
11289   if (val < 0)
11290     emit_insn (gen_and<mode>3 (x, op1, tmp));
11291   else
11292     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11294   if (invert)
11295     {
11296       rtx tmp = gen_reg_rtx (<MODE>mode);
11297       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11298       x = tmp;
11299     }
11301   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11302   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11304   DONE;
11307 (define_expand "cstore<mode>4_unsigned_imm"
11308   [(use (match_operator 1 "unsigned_comparison_operator"
11309          [(match_operand:GPR 2 "gpc_reg_operand")
11310           (match_operand:GPR 3 "immediate_operand")]))
11311    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11312   ""
11314   bool invert = false;
11316   enum rtx_code cond_code = GET_CODE (operands[1]);
11318   rtx op0 = operands[0];
11319   rtx op1 = operands[2];
11320   HOST_WIDE_INT val = INTVAL (operands[3]);
11322   if (cond_code == GEU || cond_code == GTU)
11323     {
11324       cond_code = reverse_condition (cond_code);
11325       invert = true;
11326     }
11328   if (cond_code == LEU)
11329     val++;
11331   rtx tmp = gen_reg_rtx (<MODE>mode);
11332   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11333   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11334   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11335   rtx x = gen_reg_rtx (<MODE>mode);
11336   if (val < 0)
11337     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11338   else
11339     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11341   if (invert)
11342     {
11343       rtx tmp = gen_reg_rtx (<MODE>mode);
11344       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11345       x = tmp;
11346     }
11348   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11349   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11351   DONE;
11354 (define_expand "cstore<mode>4"
11355   [(use (match_operator 1 "comparison_operator"
11356          [(match_operand:GPR 2 "gpc_reg_operand")
11357           (match_operand:GPR 3 "reg_or_short_operand")]))
11358    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11359   ""
11361   /* Expanding EQ and NE directly to some machine instructions does not help
11362      but does hurt combine.  So don't.  */
11363   if (GET_CODE (operands[1]) == EQ)
11364     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11365   else if (<MODE>mode == Pmode
11366            && GET_CODE (operands[1]) == NE)
11367     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11368   else if (GET_CODE (operands[1]) == NE)
11369     {
11370       rtx tmp = gen_reg_rtx (<MODE>mode);
11371       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11372       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11373     }
11375   /* If ISEL is fast, expand to it.  */
11376   else if (TARGET_ISEL)
11377     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11379   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11380      etc. combinations magically work out just right.  */
11381   else if (<MODE>mode == Pmode
11382            && unsigned_comparison_operator (operands[1], VOIDmode))
11383     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11384                                            operands[2], operands[3]));
11386   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11387   else if (<MODE>mode == SImode && Pmode == DImode)
11388     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11389                                     operands[2], operands[3]));
11391   /* For signed comparisons against a constant, we can do some simple
11392      bit-twiddling.  */
11393   else if (signed_comparison_operator (operands[1], VOIDmode)
11394            && CONST_INT_P (operands[3]))
11395     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11396                                              operands[2], operands[3]));
11398   /* And similarly for unsigned comparisons.  */
11399   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11400            && CONST_INT_P (operands[3]))
11401     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11402                                                operands[2], operands[3]));
11404   /* We also do not want to use mfcr for signed comparisons.  */
11405   else if (<MODE>mode == Pmode
11406            && signed_comparison_operator (operands[1], VOIDmode))
11407     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11408                                          operands[2], operands[3]));
11410   /* Everything else, use the mfcr brute force.  */
11411   else
11412     rs6000_emit_sCOND (<MODE>mode, operands);
11414   DONE;
11417 (define_expand "cstore<mode>4"
11418   [(use (match_operator 1 "comparison_operator"
11419          [(match_operand:FP 2 "gpc_reg_operand")
11420           (match_operand:FP 3 "gpc_reg_operand")]))
11421    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11422   ""
11424   rs6000_emit_sCOND (<MODE>mode, operands);
11425   DONE;
11429 (define_expand "stack_protect_set"
11430   [(match_operand 0 "memory_operand")
11431    (match_operand 1 "memory_operand")]
11432   ""
11434   if (rs6000_stack_protector_guard == SSP_TLS)
11435     {
11436       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11437       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11438       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11439       operands[1] = gen_rtx_MEM (Pmode, addr);
11440     }
11442   if (TARGET_64BIT)
11443     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11444   else
11445     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11447   DONE;
11450 (define_insn "stack_protect_setsi"
11451   [(set (match_operand:SI 0 "memory_operand" "=m")
11452         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11453    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11454   "TARGET_32BIT"
11455   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11456   [(set_attr "type" "three")
11457    (set_attr "length" "12")])
11459 (define_insn "stack_protect_setdi"
11460   [(set (match_operand:DI 0 "memory_operand" "=Y")
11461         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11462    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11463   "TARGET_64BIT"
11464   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11465   [(set_attr "type" "three")
11466    (set_attr "length" "12")])
11468 (define_expand "stack_protect_test"
11469   [(match_operand 0 "memory_operand")
11470    (match_operand 1 "memory_operand")
11471    (match_operand 2 "")]
11472   ""
11474   rtx guard = operands[1];
11476   if (rs6000_stack_protector_guard == SSP_TLS)
11477     {
11478       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11479       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11480       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11481       guard = gen_rtx_MEM (Pmode, addr);
11482     }
11484   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11485   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11486   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11487   emit_jump_insn (jump);
11489   DONE;
11492 (define_insn "stack_protect_testsi"
11493   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11494         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11495                       (match_operand:SI 2 "memory_operand" "m,m")]
11496                      UNSPEC_SP_TEST))
11497    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11498    (clobber (match_scratch:SI 3 "=&r,&r"))]
11499   "TARGET_32BIT"
11500   "@
11501    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11502    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11503   [(set_attr "length" "16,20")])
11505 (define_insn "stack_protect_testdi"
11506   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11507         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11508                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11509                      UNSPEC_SP_TEST))
11510    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11511    (clobber (match_scratch:DI 3 "=&r,&r"))]
11512   "TARGET_64BIT"
11513   "@
11514    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11515    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11516   [(set_attr "length" "16,20")])
11519 ;; Here are the actual compare insns.
11520 (define_insn "*cmp<mode>_signed"
11521   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11522         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11523                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11524   ""
11525   "cmp<wd>%I2 %0,%1,%2"
11526   [(set_attr "type" "cmp")])
11528 (define_insn "*cmp<mode>_unsigned"
11529   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11530         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11531                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11532   ""
11533   "cmpl<wd>%I2 %0,%1,%2"
11534   [(set_attr "type" "cmp")])
11536 ;; If we are comparing a register for equality with a large constant,
11537 ;; we can do this with an XOR followed by a compare.  But this is profitable
11538 ;; only if the large constant is only used for the comparison (and in this
11539 ;; case we already have a register to reuse as scratch).
11541 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11542 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11544 (define_peephole2
11545   [(set (match_operand:SI 0 "register_operand")
11546         (match_operand:SI 1 "logical_const_operand"))
11547    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11548                        [(match_dup 0)
11549                         (match_operand:SI 2 "logical_const_operand")]))
11550    (set (match_operand:CC 4 "cc_reg_operand")
11551         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11552                     (match_dup 0)))
11553    (set (pc)
11554         (if_then_else (match_operator 6 "equality_operator"
11555                        [(match_dup 4) (const_int 0)])
11556                       (match_operand 7 "")
11557                       (match_operand 8 "")))]
11558   "peep2_reg_dead_p (3, operands[0])
11559    && peep2_reg_dead_p (4, operands[4])
11560    && REGNO (operands[0]) != REGNO (operands[5])"
11561  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11562   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11563   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11566   /* Get the constant we are comparing against, and see what it looks like
11567      when sign-extended from 16 to 32 bits.  Then see what constant we could
11568      XOR with SEXTC to get the sign-extended value.  */
11569   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11570                                               SImode,
11571                                               operands[1], operands[2]);
11572   HOST_WIDE_INT c = INTVAL (cnst);
11573   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11574   HOST_WIDE_INT xorv = c ^ sextc;
11576   operands[9] = GEN_INT (xorv);
11577   operands[10] = GEN_INT (sextc);
11580 ;; The following two insns don't exist as single insns, but if we provide
11581 ;; them, we can swap an add and compare, which will enable us to overlap more
11582 ;; of the required delay between a compare and branch.  We generate code for
11583 ;; them by splitting.
11585 (define_insn ""
11586   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11587         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11588                     (match_operand:SI 2 "short_cint_operand" "i")))
11589    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11590         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11591   ""
11592   "#"
11593   [(set_attr "length" "8")])
11595 (define_insn ""
11596   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11597         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11598                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11599    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11600         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11601   ""
11602   "#"
11603   [(set_attr "length" "8")])
11605 (define_split
11606   [(set (match_operand:CC 3 "cc_reg_operand")
11607         (compare:CC (match_operand:SI 1 "gpc_reg_operand")
11608                     (match_operand:SI 2 "short_cint_operand")))
11609    (set (match_operand:SI 0 "gpc_reg_operand")
11610         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11611   ""
11612   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11613    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11615 (define_split
11616   [(set (match_operand:CCUNS 3 "cc_reg_operand")
11617         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11618                        (match_operand:SI 2 "u_short_cint_operand")))
11619    (set (match_operand:SI 0 "gpc_reg_operand")
11620         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11621   ""
11622   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11623    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11625 ;; Only need to compare second words if first words equal
11626 (define_insn "*cmp<mode>_internal1"
11627   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11628         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11629                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11630   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11631    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11632   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11633   [(set_attr "type" "fpcompare")
11634    (set_attr "length" "12")])
11636 (define_insn_and_split "*cmp<mode>_internal2"
11637   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11638         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11639                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11640     (clobber (match_scratch:DF 3 "=d"))
11641     (clobber (match_scratch:DF 4 "=d"))
11642     (clobber (match_scratch:DF 5 "=d"))
11643     (clobber (match_scratch:DF 6 "=d"))
11644     (clobber (match_scratch:DF 7 "=d"))
11645     (clobber (match_scratch:DF 8 "=d"))
11646     (clobber (match_scratch:DF 9 "=d"))
11647     (clobber (match_scratch:DF 10 "=d"))
11648     (clobber (match_scratch:GPR 11 "=b"))]
11649   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11650    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11651   "#"
11652   "&& reload_completed"
11653   [(set (match_dup 3) (match_dup 14))
11654    (set (match_dup 4) (match_dup 15))
11655    (set (match_dup 9) (abs:DF (match_dup 5)))
11656    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11657    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11658                            (label_ref (match_dup 12))
11659                            (pc)))
11660    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11661    (set (pc) (label_ref (match_dup 13)))
11662    (match_dup 12)
11663    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11664    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11665    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11666    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11667    (match_dup 13)]
11669   REAL_VALUE_TYPE rv;
11670   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11671   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11673   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11674   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11675   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11676   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11677   operands[12] = gen_label_rtx ();
11678   operands[13] = gen_label_rtx ();
11679   real_inf (&rv);
11680   operands[14] = force_const_mem (DFmode,
11681                                   const_double_from_real_value (rv, DFmode));
11682   operands[15] = force_const_mem (DFmode,
11683                                   const_double_from_real_value (dconst0,
11684                                                                 DFmode));
11685   if (TARGET_TOC)
11686     {
11687       rtx tocref;
11688       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11689       operands[14] = gen_const_mem (DFmode, tocref);
11690       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11691       operands[15] = gen_const_mem (DFmode, tocref);
11692       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11693       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11694     }
11697 ;; Now we have the scc insns.  We can do some combinations because of the
11698 ;; way the machine works.
11700 ;; Note that this is probably faster if we can put an insn between the
11701 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11702 ;; cases the insns below which don't use an intermediate CR field will
11703 ;; be used instead.
11704 (define_insn ""
11705   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11706         (match_operator:SI 1 "scc_comparison_operator"
11707                            [(match_operand 2 "cc_reg_operand" "y")
11708                             (const_int 0)]))]
11709   ""
11710   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11711   [(set (attr "type")
11712      (cond [(match_test "TARGET_MFCRF")
11713                 (const_string "mfcrf")
11714            ]
11715         (const_string "mfcr")))
11716    (set_attr "length" "8")])
11718 (define_insn ""
11719   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11720         (match_operator:DI 1 "scc_comparison_operator"
11721                            [(match_operand 2 "cc_reg_operand" "y")
11722                             (const_int 0)]))]
11723   "TARGET_POWERPC64"
11724   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11725   [(set (attr "type")
11726      (cond [(match_test "TARGET_MFCRF")
11727                 (const_string "mfcrf")
11728            ]
11729         (const_string "mfcr")))
11730    (set_attr "length" "8")])
11732 (define_insn ""
11733   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11734         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11735                                        [(match_operand 2 "cc_reg_operand" "y,y")
11736                                         (const_int 0)])
11737                     (const_int 0)))
11738    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11739         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11740   "TARGET_32BIT"
11741   "@
11742    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11743    #"
11744   [(set_attr "type" "shift")
11745    (set_attr "dot" "yes")
11746    (set_attr "length" "8,16")])
11748 (define_split
11749   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11750         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11751                                        [(match_operand 2 "cc_reg_operand")
11752                                         (const_int 0)])
11753                     (const_int 0)))
11754    (set (match_operand:SI 3 "gpc_reg_operand")
11755         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11756   "TARGET_32BIT && reload_completed"
11757   [(set (match_dup 3)
11758         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11759    (set (match_dup 0)
11760         (compare:CC (match_dup 3)
11761                     (const_int 0)))]
11762   "")
11764 (define_insn ""
11765   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11766         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11767                                       [(match_operand 2 "cc_reg_operand" "y")
11768                                        (const_int 0)])
11769                    (match_operand:SI 3 "const_int_operand" "n")))]
11770   ""
11772   int is_bit = ccr_bit (operands[1], 1);
11773   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11774   int count;
11776   if (is_bit >= put_bit)
11777     count = is_bit - put_bit;
11778   else
11779     count = 32 - (put_bit - is_bit);
11781   operands[4] = GEN_INT (count);
11782   operands[5] = GEN_INT (put_bit);
11784   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11786   [(set (attr "type")
11787      (cond [(match_test "TARGET_MFCRF")
11788                 (const_string "mfcrf")
11789            ]
11790         (const_string "mfcr")))
11791    (set_attr "length" "8")])
11793 (define_insn ""
11794   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11795         (compare:CC
11796          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11797                                        [(match_operand 2 "cc_reg_operand" "y,y")
11798                                         (const_int 0)])
11799                     (match_operand:SI 3 "const_int_operand" "n,n"))
11800          (const_int 0)))
11801    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11802         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11803                    (match_dup 3)))]
11804   ""
11806   int is_bit = ccr_bit (operands[1], 1);
11807   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11808   int count;
11810   /* Force split for non-cc0 compare.  */
11811   if (which_alternative == 1)
11812      return "#";
11814   if (is_bit >= put_bit)
11815     count = is_bit - put_bit;
11816   else
11817     count = 32 - (put_bit - is_bit);
11819   operands[5] = GEN_INT (count);
11820   operands[6] = GEN_INT (put_bit);
11822   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11824   [(set_attr "type" "shift")
11825    (set_attr "dot" "yes")
11826    (set_attr "length" "8,16")])
11828 (define_split
11829   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11830         (compare:CC
11831          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11832                                        [(match_operand 2 "cc_reg_operand")
11833                                         (const_int 0)])
11834                     (match_operand:SI 3 "const_int_operand"))
11835          (const_int 0)))
11836    (set (match_operand:SI 4 "gpc_reg_operand")
11837         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11838                    (match_dup 3)))]
11839   "reload_completed"
11840   [(set (match_dup 4)
11841         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11842                    (match_dup 3)))
11843    (set (match_dup 0)
11844         (compare:CC (match_dup 4)
11845                     (const_int 0)))]
11846   "")
11849 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11850 (define_code_attr UNS [(eq "CC")
11851                        (ne "CC")
11852                        (lt "CC") (ltu "CCUNS")
11853                        (gt "CC") (gtu "CCUNS")
11854                        (le "CC") (leu "CCUNS")
11855                        (ge "CC") (geu "CCUNS")])
11856 (define_code_attr UNSu_ [(eq "")
11857                          (ne "")
11858                          (lt "") (ltu "u_")
11859                          (gt "") (gtu "u_")
11860                          (le "") (leu "u_")
11861                          (ge "") (geu "u_")])
11862 (define_code_attr UNSIK [(eq "I")
11863                          (ne "I")
11864                          (lt "I") (ltu "K")
11865                          (gt "I") (gtu "K")
11866                          (le "I") (leu "K")
11867                          (ge "I") (geu "K")])
11869 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11870   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11871         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11872                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11873    (clobber (match_scratch:GPR 3 "=r"))
11874    (clobber (match_scratch:GPR 4 "=r"))
11875    (clobber (match_scratch:<UNS> 5 "=y"))]
11876   "TARGET_ISEL
11877    && !(<CODE> == EQ && operands[2] == const0_rtx)
11878    && !(<CODE> == NE && operands[2] == const0_rtx
11879         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11880   "#"
11881   "&& 1"
11882   [(pc)]
11884   rtx_code code = <CODE>;
11885   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11886     {
11887       HOST_WIDE_INT val = INTVAL (operands[2]);
11888       if (code == LT && val != -0x8000)
11889         {
11890           code = LE;
11891           val--;
11892         }
11893       if (code == GT && val != 0x7fff)
11894         {
11895           code = GE;
11896           val++;
11897         }
11898       if (code == LTU && val != 0)
11899         {
11900           code = LEU;
11901           val--;
11902         }
11903       if (code == GTU && val != 0xffff)
11904         {
11905           code = GEU;
11906           val++;
11907         }
11908       operands[2] = GEN_INT (val);
11909     }
11911   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11912     operands[3] = const0_rtx;
11913   else
11914     {
11915       if (GET_CODE (operands[3]) == SCRATCH)
11916         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11917       emit_move_insn (operands[3], const0_rtx);
11918     }
11920   if (GET_CODE (operands[4]) == SCRATCH)
11921     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11922   emit_move_insn (operands[4], const1_rtx);
11924   if (GET_CODE (operands[5]) == SCRATCH)
11925     operands[5] = gen_reg_rtx (<UNS>mode);
11927   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11928   emit_insn (gen_rtx_SET (operands[5], c1));
11930   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11931   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11932   emit_move_insn (operands[0], x);
11934   DONE;
11936   [(set (attr "cost")
11937         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11938                                    || <CODE> == NE
11939                                    || <CODE> == LE || <CODE> == GE
11940                                    || <CODE> == LEU || <CODE> == GEU")
11941                       (const_string "9")
11942                       (const_string "10")))])
11944 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11945                               (DI "rKJI")])
11947 (define_expand "eq<mode>3"
11948   [(parallel [
11949      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11950           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11951                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11952      (clobber (match_scratch:GPR 3 "=r"))
11953      (clobber (match_scratch:GPR 4 "=r"))])]
11954   ""
11956   if (TARGET_ISEL && operands[2] != const0_rtx)
11957     {
11958       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11959                                            operands[2]));
11960       DONE;
11961     }
11964 (define_insn_and_split "*eq<mode>3"
11965   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11966         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11967                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11968    (clobber (match_scratch:GPR 3 "=r"))
11969    (clobber (match_scratch:GPR 4 "=r"))]
11970   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11971   "#"
11972   "&& 1"
11973   [(set (match_dup 4)
11974         (clz:GPR (match_dup 3)))
11975    (set (match_dup 0)
11976         (lshiftrt:GPR (match_dup 4)
11977                       (match_dup 5)))]
11979   operands[3] = rs6000_emit_eqne (<MODE>mode,
11980                                   operands[1], operands[2], operands[3]);
11982   if (GET_CODE (operands[4]) == SCRATCH)
11983     operands[4] = gen_reg_rtx (<MODE>mode);
11985   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11987   [(set (attr "length")
11988         (if_then_else (match_test "operands[2] == const0_rtx")
11989                       (const_string "8")
11990                       (const_string "12")))])
11992 (define_expand "ne<mode>3"
11993   [(parallel [
11994      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11995           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11996                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11997      (clobber (match_scratch:P 3 "=r"))
11998      (clobber (match_scratch:P 4 "=r"))
11999      (clobber (reg:P CA_REGNO))])]
12000   ""
12002   if (TARGET_ISEL && operands[2] != const0_rtx)
12003     {
12004       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12005                                            operands[2]));
12006       DONE;
12007     }
12010 (define_insn_and_split "*ne<mode>3"
12011   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12012         (ne: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   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12018   "#"
12019   "&& 1"
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 (plus:P (not:P (match_dup 4))
12028                                    (reg:P CA_REGNO))
12029                            (match_dup 3)))
12030               (clobber (reg:P CA_REGNO))])]
12032   operands[3] = rs6000_emit_eqne (<MODE>mode,
12033                                   operands[1], operands[2], operands[3]);
12035   if (GET_CODE (operands[4]) == SCRATCH)
12036     operands[4] = gen_reg_rtx (<MODE>mode);
12038   [(set (attr "length")
12039         (if_then_else (match_test "operands[2] == const0_rtx")
12040                       (const_string "8")
12041                       (const_string "12")))])
12043 (define_insn_and_split "*neg_eq_<mode>"
12044   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12045         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12046                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12047    (clobber (match_scratch:P 3 "=r"))
12048    (clobber (match_scratch:P 4 "=r"))
12049    (clobber (reg:P CA_REGNO))]
12050   ""
12051   "#"
12052   ""
12053   [(parallel [(set (match_dup 4)
12054                    (plus:P (match_dup 3)
12055                            (const_int -1)))
12056               (set (reg:P CA_REGNO)
12057                    (ne:P (match_dup 3)
12058                          (const_int 0)))])
12059    (parallel [(set (match_dup 0)
12060                    (plus:P (reg:P CA_REGNO)
12061                            (const_int -1)))
12062               (clobber (reg:P CA_REGNO))])]
12064   operands[3] = rs6000_emit_eqne (<MODE>mode,
12065                                   operands[1], operands[2], operands[3]);
12067   if (GET_CODE (operands[4]) == SCRATCH)
12068     operands[4] = gen_reg_rtx (<MODE>mode);
12070   [(set (attr "length")
12071         (if_then_else (match_test "operands[2] == const0_rtx")
12072                       (const_string "8")
12073                       (const_string "12")))])
12075 (define_insn_and_split "*neg_ne_<mode>"
12076   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12077         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12078                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12079    (clobber (match_scratch:P 3 "=r"))
12080    (clobber (match_scratch:P 4 "=r"))
12081    (clobber (reg:P CA_REGNO))]
12082   ""
12083   "#"
12084   ""
12085   [(parallel [(set (match_dup 4)
12086                    (neg:P (match_dup 3)))
12087               (set (reg:P CA_REGNO)
12088                    (eq:P (match_dup 3)
12089                          (const_int 0)))])
12090    (parallel [(set (match_dup 0)
12091                    (plus:P (reg:P CA_REGNO)
12092                            (const_int -1)))
12093               (clobber (reg:P CA_REGNO))])]
12095   operands[3] = rs6000_emit_eqne (<MODE>mode,
12096                                   operands[1], operands[2], operands[3]);
12098   if (GET_CODE (operands[4]) == SCRATCH)
12099     operands[4] = gen_reg_rtx (<MODE>mode);
12101   [(set (attr "length")
12102         (if_then_else (match_test "operands[2] == const0_rtx")
12103                       (const_string "8")
12104                       (const_string "12")))])
12106 (define_insn_and_split "*plus_eq_<mode>"
12107   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12108         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12109                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12110                 (match_operand:P 3 "gpc_reg_operand" "r")))
12111    (clobber (match_scratch:P 4 "=r"))
12112    (clobber (match_scratch:P 5 "=r"))
12113    (clobber (reg:P CA_REGNO))]
12114   ""
12115   "#"
12116   ""
12117   [(parallel [(set (match_dup 5)
12118                    (neg:P (match_dup 4)))
12119               (set (reg:P CA_REGNO)
12120                    (eq: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 "*plus_ne_<mode>"
12139   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12140         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12141                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12142                 (match_operand:P 3 "gpc_reg_operand" "r")))
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 (match_dup 3)
12157                            (reg:P CA_REGNO)))
12158               (clobber (reg:P CA_REGNO))])]
12160   operands[4] = rs6000_emit_eqne (<MODE>mode,
12161                                   operands[1], operands[2], operands[4]);
12163   if (GET_CODE (operands[5]) == SCRATCH)
12164     operands[5] = gen_reg_rtx (<MODE>mode);
12166   [(set (attr "length")
12167         (if_then_else (match_test "operands[2] == const0_rtx")
12168                       (const_string "8")
12169                       (const_string "12")))])
12171 (define_insn_and_split "*minus_eq_<mode>"
12172   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12173         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12174                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12175                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12176    (clobber (match_scratch:P 4 "=r"))
12177    (clobber (match_scratch:P 5 "=r"))
12178    (clobber (reg:P CA_REGNO))]
12179   ""
12180   "#"
12181   ""
12182   [(parallel [(set (match_dup 5)
12183                    (plus:P (match_dup 4)
12184                            (const_int -1)))
12185               (set (reg:P CA_REGNO)
12186                    (ne: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 "*minus_ne_<mode>"
12206   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12207         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12208                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12209                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12210    (clobber (match_scratch:P 4 "=r"))
12211    (clobber (match_scratch:P 5 "=r"))
12212    (clobber (reg:P CA_REGNO))]
12213   ""
12214   "#"
12215   ""
12216   [(parallel [(set (match_dup 5)
12217                    (neg:P (match_dup 4)))
12218               (set (reg:P CA_REGNO)
12219                    (eq:P (match_dup 4)
12220                          (const_int 0)))])
12221    (parallel [(set (match_dup 0)
12222                    (plus:P (plus:P (match_dup 3)
12223                                    (reg:P CA_REGNO))
12224                            (const_int -1)))
12225               (clobber (reg:P CA_REGNO))])]
12227   operands[4] = rs6000_emit_eqne (<MODE>mode,
12228                                   operands[1], operands[2], operands[4]);
12230   if (GET_CODE (operands[5]) == SCRATCH)
12231     operands[5] = gen_reg_rtx (<MODE>mode);
12233   [(set (attr "length")
12234         (if_then_else (match_test "operands[2] == const0_rtx")
12235                       (const_string "8")
12236                       (const_string "12")))])
12238 (define_insn_and_split "*eqsi3_ext<mode>"
12239   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12240         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12241                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12242    (clobber (match_scratch:SI 3 "=r"))
12243    (clobber (match_scratch:SI 4 "=r"))]
12244   ""
12245   "#"
12246   ""
12247   [(set (match_dup 4)
12248         (clz:SI (match_dup 3)))
12249    (set (match_dup 0)
12250         (zero_extend:EXTSI
12251           (lshiftrt:SI (match_dup 4)
12252                        (const_int 5))))]
12254   operands[3] = rs6000_emit_eqne (SImode,
12255                                   operands[1], operands[2], operands[3]);
12257   if (GET_CODE (operands[4]) == SCRATCH)
12258     operands[4] = gen_reg_rtx (SImode);
12260   [(set (attr "length")
12261         (if_then_else (match_test "operands[2] == const0_rtx")
12262                       (const_string "8")
12263                       (const_string "12")))])
12265 (define_insn_and_split "*nesi3_ext<mode>"
12266   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12267         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12268                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12269    (clobber (match_scratch:SI 3 "=r"))
12270    (clobber (match_scratch:SI 4 "=r"))
12271    (clobber (match_scratch:EXTSI 5 "=r"))]
12272   "!TARGET_ISEL"
12273   "#"
12274   "&& 1"
12275   [(set (match_dup 4)
12276         (clz:SI (match_dup 3)))
12277    (set (match_dup 5)
12278         (zero_extend:EXTSI
12279           (lshiftrt:SI (match_dup 4)
12280                        (const_int 5))))
12281    (set (match_dup 0)
12282         (xor:EXTSI (match_dup 5)
12283                    (const_int 1)))]
12285   operands[3] = rs6000_emit_eqne (SImode,
12286                                   operands[1], operands[2], operands[3]);
12288   if (GET_CODE (operands[4]) == SCRATCH)
12289     operands[4] = gen_reg_rtx (SImode);
12290   if (GET_CODE (operands[5]) == SCRATCH)
12291     operands[5] = gen_reg_rtx (<MODE>mode);
12293   [(set (attr "length")
12294         (if_then_else (match_test "operands[2] == const0_rtx")
12295                       (const_string "12")
12296                       (const_string "16")))])
12298 ;; Define both directions of branch and return.  If we need a reload
12299 ;; register, we'd rather use CR0 since it is much easier to copy a
12300 ;; register CC value to there.
12302 (define_insn ""
12303   [(set (pc)
12304         (if_then_else (match_operator 1 "branch_comparison_operator"
12305                                       [(match_operand 2 "cc_reg_operand" "y")
12306                                        (const_int 0)])
12307                       (label_ref (match_operand 0))
12308                       (pc)))]
12309   ""
12311   return output_cbranch (operands[1], "%l0", 0, insn);
12313   [(set_attr "type" "branch")])
12315 (define_insn ""
12316   [(set (pc)
12317         (if_then_else (match_operator 0 "branch_comparison_operator"
12318                                       [(match_operand 1 "cc_reg_operand" "y")
12319                                        (const_int 0)])
12320                       (any_return)
12321                       (pc)))]
12322   "<return_pred>"
12324   return output_cbranch (operands[0], NULL, 0, insn);
12326   [(set_attr "type" "jmpreg")
12327    (set_attr "length" "4")])
12329 ;; Logic on condition register values.
12331 ; This pattern matches things like
12332 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12333 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12334 ;                                  (const_int 1)))
12335 ; which are generated by the branch logic.
12336 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12338 (define_insn "cceq_ior_compare"
12339   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12340         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12341                         [(match_operator:SI 2
12342                                       "branch_positive_comparison_operator"
12343                                       [(match_operand 3
12344                                                       "cc_reg_operand" "y,y")
12345                                        (const_int 0)])
12346                          (match_operator:SI 4
12347                                       "branch_positive_comparison_operator"
12348                                       [(match_operand 5
12349                                                       "cc_reg_operand" "0,y")
12350                                        (const_int 0)])])
12351                       (const_int 1)))]
12352   ""
12353   "cr%q1 %E0,%j2,%j4"
12354   [(set_attr "type" "cr_logical")
12355    (set_attr "cr_logical_3op" "no,yes")])
12357 ; Why is the constant -1 here, but 1 in the previous pattern?
12358 ; Because ~1 has all but the low bit set.
12359 (define_insn "cceq_ior_compare_complement"
12360   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12361         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12362                         [(not:SI (match_operator:SI 2
12363                                       "branch_positive_comparison_operator"
12364                                       [(match_operand 3
12365                                                       "cc_reg_operand" "y,y")
12366                                        (const_int 0)]))
12367                          (match_operator:SI 4
12368                                 "branch_positive_comparison_operator"
12369                                 [(match_operand 5
12370                                                 "cc_reg_operand" "0,y")
12371                                  (const_int 0)])])
12372                       (const_int -1)))]
12373   ""
12374   "cr%q1 %E0,%j2,%j4"
12375   [(set_attr "type" "cr_logical")
12376    (set_attr "cr_logical_3op" "no,yes")])
12378 (define_insn "*cceq_rev_compare"
12379   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12380         (compare:CCEQ (match_operator:SI 1
12381                                       "branch_positive_comparison_operator"
12382                                       [(match_operand 2
12383                                                       "cc_reg_operand" "0,y")
12384                                        (const_int 0)])
12385                       (const_int 0)))]
12386   ""
12387   "crnot %E0,%j1"
12388   [(set_attr "type" "cr_logical")
12389    (set_attr "cr_logical_3op" "no,yes")])
12391 ;; If we are comparing the result of two comparisons, this can be done
12392 ;; using creqv or crxor.
12394 (define_insn_and_split ""
12395   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12396         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12397                               [(match_operand 2 "cc_reg_operand" "y")
12398                                (const_int 0)])
12399                       (match_operator 3 "branch_comparison_operator"
12400                               [(match_operand 4 "cc_reg_operand" "y")
12401                                (const_int 0)])))]
12402   ""
12403   "#"
12404   ""
12405   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12406                                     (match_dup 5)))]
12408   int positive_1, positive_2;
12410   positive_1 = branch_positive_comparison_operator (operands[1],
12411                                                     GET_MODE (operands[1]));
12412   positive_2 = branch_positive_comparison_operator (operands[3],
12413                                                     GET_MODE (operands[3]));
12415   if (! positive_1)
12416     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12417                                                             GET_CODE (operands[1])),
12418                                   SImode,
12419                                   operands[2], const0_rtx);
12420   else if (GET_MODE (operands[1]) != SImode)
12421     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12422                                   operands[2], const0_rtx);
12424   if (! positive_2)
12425     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12426                                                             GET_CODE (operands[3])),
12427                                   SImode,
12428                                   operands[4], const0_rtx);
12429   else if (GET_MODE (operands[3]) != SImode)
12430     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12431                                   operands[4], const0_rtx);
12433   if (positive_1 == positive_2)
12434     {
12435       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12436       operands[5] = constm1_rtx;
12437     }
12438   else
12439     {
12440       operands[5] = const1_rtx;
12441     }
12444 ;; Unconditional branch and return.
12446 (define_insn "jump"
12447   [(set (pc)
12448         (label_ref (match_operand 0)))]
12449   ""
12450   "b %l0"
12451   [(set_attr "type" "branch")])
12453 (define_insn "<return_str>return"
12454   [(any_return)]
12455   "<return_pred>"
12456   "blr"
12457   [(set_attr "type" "jmpreg")])
12459 (define_expand "indirect_jump"
12460   [(set (pc) (match_operand 0 "register_operand"))]
12461  ""
12463   if (!rs6000_speculate_indirect_jumps) {
12464     rtx ccreg = gen_reg_rtx (CCmode);
12465     if (Pmode == DImode)
12466       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12467     else
12468       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12469     DONE;
12470   }
12473 (define_insn "*indirect_jump<mode>"
12474   [(set (pc)
12475         (match_operand:P 0 "register_operand" "c,*l"))]
12476   "rs6000_speculate_indirect_jumps"
12477   "b%T0"
12478   [(set_attr "type" "jmpreg")])
12480 (define_insn "indirect_jump<mode>_nospec"
12481   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12482    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12483   "!rs6000_speculate_indirect_jumps"
12484   "crset %E1\;beq%T0- %1\;b $"
12485   [(set_attr "type" "jmpreg")
12486    (set_attr "length" "12")])
12488 ;; Table jump for switch statements:
12489 (define_expand "tablejump"
12490   [(use (match_operand 0))
12491    (use (label_ref (match_operand 1)))]
12492   ""
12494   if (rs6000_speculate_indirect_jumps)
12495     {
12496       if (TARGET_32BIT)
12497         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12498       else
12499         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12500     }
12501   else
12502     {
12503       rtx ccreg = gen_reg_rtx (CCmode);
12504       rtx jump;
12505       if (TARGET_32BIT)
12506         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12507       else
12508         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12509       emit_jump_insn (jump);
12510     }
12511   DONE;
12514 (define_expand "tablejumpsi"
12515   [(set (match_dup 3)
12516         (plus:SI (match_operand:SI 0)
12517                  (match_dup 2)))
12518    (parallel [(set (pc)
12519                    (match_dup 3))
12520               (use (label_ref (match_operand 1)))])]
12521   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12523   operands[0] = force_reg (SImode, operands[0]);
12524   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12525   operands[3] = gen_reg_rtx (SImode);
12528 (define_expand "tablejumpsi_nospec"
12529   [(set (match_dup 4)
12530         (plus:SI (match_operand:SI 0)
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_32BIT && !rs6000_speculate_indirect_jumps"
12538   operands[0] = force_reg (SImode, operands[0]);
12539   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12540   operands[4] = gen_reg_rtx (SImode);
12543 (define_expand "tablejumpdi"
12544   [(set (match_dup 4)
12545         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12546    (set (match_dup 3)
12547         (plus:DI (match_dup 4)
12548                  (match_dup 2)))
12549    (parallel [(set (pc)
12550                    (match_dup 3))
12551               (use (label_ref (match_operand 1)))])]
12552   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12554   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12555   operands[3] = gen_reg_rtx (DImode);
12556   operands[4] = gen_reg_rtx (DImode);
12559 (define_expand "tablejumpdi_nospec"
12560   [(set (match_dup 5)
12561         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12562    (set (match_dup 4)
12563         (plus:DI (match_dup 5)
12564                  (match_dup 3)))
12565    (parallel [(set (pc)
12566                    (match_dup 4))
12567               (use (label_ref (match_operand 1)))
12568               (clobber (match_operand 2))])]
12569   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12571   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12572   operands[4] = gen_reg_rtx (DImode);
12573   operands[5] = gen_reg_rtx (DImode);
12576 (define_insn "*tablejump<mode>_internal1"
12577   [(set (pc)
12578         (match_operand:P 0 "register_operand" "c,*l"))
12579    (use (label_ref (match_operand 1)))]
12580   "rs6000_speculate_indirect_jumps"
12581   "b%T0"
12582   [(set_attr "type" "jmpreg")])
12584 (define_insn "*tablejump<mode>_internal1_nospec"
12585   [(set (pc)
12586         (match_operand:P 0 "register_operand" "c,*l"))
12587    (use (label_ref (match_operand 1)))
12588    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12589   "!rs6000_speculate_indirect_jumps"
12590   "crset %E2\;beq%T0- %2\;b $"
12591   [(set_attr "type" "jmpreg")
12592    (set_attr "length" "12")])
12594 (define_insn "nop"
12595   [(unspec [(const_int 0)] UNSPEC_NOP)]
12596   ""
12597   "nop")
12599 (define_insn "group_ending_nop"
12600   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12601   ""
12603   if (rs6000_tune == PROCESSOR_POWER6)
12604     return "ori 1,1,0";
12605   return "ori 2,2,0";
12608 (define_insn "rs6000_speculation_barrier"
12609   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12610   ""
12611   "ori 31,31,0")
12613 ;; Define the subtract-one-and-jump insns, starting with the template
12614 ;; so loop.c knows what to generate.
12616 (define_expand "doloop_end"
12617   [(use (match_operand 0))      ; loop pseudo
12618    (use (match_operand 1))]     ; label
12619   ""
12621   if (TARGET_64BIT)
12622     {
12623       if (GET_MODE (operands[0]) != DImode)
12624         FAIL;
12625       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12626     }
12627   else
12628     {
12629       if (GET_MODE (operands[0]) != SImode)
12630         FAIL;
12631       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12632     }
12633   DONE;
12636 (define_expand "ctr<mode>"
12637   [(parallel [(set (pc)
12638                    (if_then_else (ne (match_operand:P 0 "register_operand")
12639                                      (const_int 1))
12640                                  (label_ref (match_operand 1))
12641                                  (pc)))
12642               (set (match_dup 0)
12643                    (plus:P (match_dup 0)
12644                             (const_int -1)))
12645               (clobber (match_scratch:CC 2))
12646               (clobber (match_scratch:P 3))])]
12647   ""
12648   "")
12650 ;; We need to be able to do this for any operand, including MEM, or we
12651 ;; will cause reload to blow up since we don't allow output reloads on
12652 ;; JUMP_INSNs.
12653 ;; For the length attribute to be calculated correctly, the
12654 ;; label MUST be operand 0.
12655 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12656 ;; the ctr<mode> insns.
12658 (define_code_iterator eqne [eq ne])
12659 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12660 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12662 (define_insn "<bd>_<mode>"
12663   [(set (pc)
12664         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12665                           (const_int 1))
12666                       (label_ref (match_operand 0))
12667                       (pc)))
12668    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12669         (plus:P (match_dup 1)
12670                 (const_int -1)))
12671    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12672    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12673   ""
12675   if (which_alternative != 0)
12676     return "#";
12677   else if (get_attr_length (insn) == 4)
12678     return "<bd> %l0";
12679   else
12680     return "<bd_neg> $+8\;b %l0";
12682   [(set_attr "type" "branch")
12683    (set_attr "length" "*,16,20,20")])
12685 ;; Now the splitter if we could not allocate the CTR register
12686 (define_split
12687   [(set (pc)
12688         (if_then_else (match_operator 2 "comparison_operator"
12689                                       [(match_operand:P 1 "gpc_reg_operand")
12690                                        (const_int 1)])
12691                       (match_operand 5)
12692                       (match_operand 6)))
12693    (set (match_operand:P 0 "nonimmediate_operand")
12694         (plus:P (match_dup 1)
12695                 (const_int -1)))
12696    (clobber (match_scratch:CC 3))
12697    (clobber (match_scratch:P 4))]
12698   "reload_completed"
12699   [(set (pc)
12700         (if_then_else (match_dup 7)
12701                       (match_dup 5)
12702                       (match_dup 6)))]
12704   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12705                                 const0_rtx);
12706   emit_insn (gen_rtx_SET (operands[3],
12707                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12708   if (gpc_reg_operand (operands[0], <MODE>mode))
12709     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12710   else
12711     {
12712       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12713       emit_move_insn (operands[0], operands[4]);
12714     } 
12715     /* No DONE so branch comes from the pattern.  */
12718 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12719 ;; Note that in the case of long branches we have to decompose this into
12720 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12721 ;; and the CR bit, which means there is no way to conveniently invert the
12722 ;; comparison as is done with plain bdnz/bdz.
12724 (define_insn "<bd>tf_<mode>"
12725   [(set (pc)
12726         (if_then_else
12727           (and
12728              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12729                    (const_int 1))
12730              (match_operator 3 "branch_comparison_operator"
12731                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12732                        (const_int 0)]))
12733           (label_ref (match_operand 0))
12734           (pc)))
12735    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12736         (plus:P (match_dup 1)
12737                 (const_int -1)))
12738    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12739    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12740    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12741   ""
12743   if (which_alternative != 0)
12744     return "#";
12745   else if (get_attr_length (insn) == 4)
12746     {
12747       if (branch_positive_comparison_operator (operands[3],
12748                                                GET_MODE (operands[3])))
12749         return "<bd>t %j3,%l0";
12750       else
12751         return "<bd>f %j3,%l0";
12752     }
12753   else
12754     {
12755       static char seq[96];
12756       char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12757       sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12758       return seq;
12759     }
12761   [(set_attr "type" "branch")
12762    (set_attr "length" "*,16,20,20")])
12764 ;; Now the splitter if we could not allocate the CTR register
12765 (define_split
12766   [(set (pc)
12767         (if_then_else
12768           (and
12769              (match_operator 1 "comparison_operator"
12770                              [(match_operand:P 0 "gpc_reg_operand")
12771                               (const_int 1)])
12772              (match_operator 3 "branch_comparison_operator"
12773                       [(match_operand 2 "cc_reg_operand")
12774                        (const_int 0)]))
12775           (match_operand 4)
12776           (match_operand 5)))
12777    (set (match_operand:P 6 "int_reg_operand")
12778         (plus:P (match_dup 0)
12779                 (const_int -1)))
12780    (clobber (match_scratch:P 7))
12781    (clobber (match_scratch:CC 8))
12782    (clobber (match_scratch:CCEQ 9))]
12783   "reload_completed"
12784 [(pc)]
12786   rtx ctr = operands[0];
12787   rtx ctrcmp = operands[1];
12788   rtx ccin = operands[2];
12789   rtx cccmp = operands[3];
12790   rtx dst1 = operands[4];
12791   rtx dst2 = operands[5];
12792   rtx ctrout = operands[6];
12793   rtx ctrtmp = operands[7];
12794   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12795   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12796   if (!ispos)
12797     cmpcode = reverse_condition (cmpcode);
12798   /* Generate crand/crandc here.  */
12799   emit_insn (gen_rtx_SET (operands[8],
12800                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12801   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12803   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12804   if (ispos)
12805      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12806                                       operands[8], cccmp, ccin));
12807   else
12808      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12809                                                  operands[8], cccmp, ccin));
12810   if (gpc_reg_operand (operands[0], <MODE>mode))
12811      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12812   else
12813     {
12814       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12815       emit_move_insn (ctrout, ctrtmp);
12816     }
12817   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12818   emit_jump_insn (gen_rtx_SET (pc_rtx,
12819                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12820                                                      dst1, dst2)));
12821   DONE;
12825 (define_insn "trap"
12826   [(trap_if (const_int 1) (const_int 0))]
12827   ""
12828   "trap"
12829   [(set_attr "type" "trap")])
12831 (define_expand "ctrap<mode>4"
12832   [(trap_if (match_operator 0 "ordered_comparison_operator"
12833                             [(match_operand:GPR 1 "register_operand")
12834                              (match_operand:GPR 2 "reg_or_short_operand")])
12835             (match_operand 3 "zero_constant" ""))]
12836   ""
12837   "")
12839 (define_insn ""
12840   [(trap_if (match_operator 0 "ordered_comparison_operator"
12841                             [(match_operand:GPR 1 "register_operand" "r")
12842                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12843             (const_int 0))]
12844   ""
12845   "t<wd>%V0%I2 %1,%2"
12846   [(set_attr "type" "trap")])
12848 ;; Insns related to generating the function prologue and epilogue.
12850 (define_expand "prologue"
12851   [(use (const_int 0))]
12852   ""
12854   rs6000_emit_prologue ();
12855   if (!TARGET_SCHED_PROLOG)
12856     emit_insn (gen_blockage ());
12857   DONE;
12860 (define_insn "*movesi_from_cr_one"
12861   [(match_parallel 0 "mfcr_operation"
12862                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12863                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12864                                      (match_operand 3 "immediate_operand" "n")]
12865                           UNSPEC_MOVESI_FROM_CR))])]
12866   "TARGET_MFCRF"
12868   int mask = 0;
12869   int i;
12870   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12871   {
12872     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12873     operands[4] = GEN_INT (mask);
12874     output_asm_insn ("mfcr %1,%4", operands);
12875   }
12876   return "";
12878   [(set_attr "type" "mfcrf")])
12880 ;; Don't include the volatile CRs since their values are not used wrt CR save
12881 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12882 ;; prologue past an insn (early exit test) that defines a register used in the
12883 ;; prologue.
12884 (define_insn "prologue_movesi_from_cr"
12885   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12886         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12887                     (reg:CC CR4_REGNO)]
12888                    UNSPEC_MOVESI_FROM_CR))]
12889   ""
12890   "mfcr %0"
12891   [(set_attr "type" "mfcr")])
12893 (define_insn "*crsave"
12894   [(match_parallel 0 "crsave_operation"
12895                    [(set (match_operand:SI 1 "memory_operand" "=m")
12896                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12897   ""
12898   "stw %2,%1"
12899   [(set_attr "type" "store")])
12901 (define_insn "*stmw"
12902   [(match_parallel 0 "stmw_operation"
12903                    [(set (match_operand:SI 1 "memory_operand" "=m")
12904                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12905   "TARGET_MULTIPLE"
12906   "stmw %2,%1"
12907   [(set_attr "type" "store")
12908    (set_attr "update" "yes")
12909    (set_attr "indexed" "yes")])
12911 ; The following comment applies to:
12912 ;     save_gpregs_*
12913 ;     save_fpregs_*
12914 ;     restore_gpregs*
12915 ;     return_and_restore_gpregs*
12916 ;     return_and_restore_fpregs*
12917 ;     return_and_restore_fpregs_aix*
12919 ; The out-of-line save / restore functions expects one input argument.
12920 ; Since those are not standard call_insn's, we must avoid using
12921 ; MATCH_OPERAND for that argument. That way the register rename
12922 ; optimization will not try to rename this register.
12923 ; Each pattern is repeated for each possible register number used in 
12924 ; various ABIs (r11, r1, and for some functions r12)
12926 (define_insn "*save_gpregs_<mode>_r11"
12927   [(match_parallel 0 "any_parallel_operand"
12928                    [(clobber (reg:P LR_REGNO))
12929                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12930                     (use (reg:P 11))
12931                     (set (match_operand:P 2 "memory_operand" "=m")
12932                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12933   ""
12934   "bl %1"
12935   [(set_attr "type" "branch")
12936    (set_attr "length" "4")])
12938 (define_insn "*save_gpregs_<mode>_r12"
12939   [(match_parallel 0 "any_parallel_operand"
12940                    [(clobber (reg:P LR_REGNO))
12941                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12942                     (use (reg:P 12))
12943                     (set (match_operand:P 2 "memory_operand" "=m")
12944                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12945   ""
12946   "bl %1"
12947   [(set_attr "type" "branch")
12948    (set_attr "length" "4")])
12950 (define_insn "*save_gpregs_<mode>_r1"
12951   [(match_parallel 0 "any_parallel_operand"
12952                    [(clobber (reg:P LR_REGNO))
12953                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12954                     (use (reg:P 1))
12955                     (set (match_operand:P 2 "memory_operand" "=m")
12956                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12957   ""
12958   "bl %1"
12959   [(set_attr "type" "branch")
12960    (set_attr "length" "4")])
12962 (define_insn "*save_fpregs_<mode>_r11"
12963   [(match_parallel 0 "any_parallel_operand"
12964                    [(clobber (reg:P LR_REGNO))
12965                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12966                     (use (reg:P 11))
12967                     (set (match_operand:DF 2 "memory_operand" "=m")
12968                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12969   ""
12970   "bl %1"
12971   [(set_attr "type" "branch")
12972    (set_attr "length" "4")])
12974 (define_insn "*save_fpregs_<mode>_r12"
12975   [(match_parallel 0 "any_parallel_operand"
12976                    [(clobber (reg:P LR_REGNO))
12977                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12978                     (use (reg:P 12))
12979                     (set (match_operand:DF 2 "memory_operand" "=m")
12980                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12981   ""
12982   "bl %1"
12983   [(set_attr "type" "branch")
12984    (set_attr "length" "4")])
12986 (define_insn "*save_fpregs_<mode>_r1"
12987   [(match_parallel 0 "any_parallel_operand"
12988                    [(clobber (reg:P LR_REGNO))
12989                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12990                     (use (reg:P 1))
12991                     (set (match_operand:DF 2 "memory_operand" "=m")
12992                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12993   ""
12994   "bl %1"
12995   [(set_attr "type" "branch")
12996    (set_attr "length" "4")])
12998 ; This is to explain that changes to the stack pointer should
12999 ; not be moved over loads from or stores to stack memory.
13000 (define_insn "stack_tie"
13001   [(match_parallel 0 "tie_operand"
13002                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13003   ""
13004   ""
13005   [(set_attr "length" "0")])
13007 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13008 ; stay behind all restores from the stack, it cannot be reordered to before
13009 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13010 (define_insn "stack_restore_tie"
13011   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13012         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13013                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13014    (set (mem:BLK (scratch)) (const_int 0))]
13015   "TARGET_32BIT"
13016   "@
13017    mr %0,%1
13018    add%I2 %0,%1,%2"
13019   [(set_attr "type" "*,add")])
13021 (define_expand "epilogue"
13022   [(use (const_int 0))]
13023   ""
13025   if (!TARGET_SCHED_PROLOG)
13026     emit_insn (gen_blockage ());
13027   rs6000_emit_epilogue (FALSE);
13028   DONE;
13031 ; On some processors, doing the mtcrf one CC register at a time is
13032 ; faster (like on the 604e).  On others, doing them all at once is
13033 ; faster; for instance, on the 601 and 750.
13035 (define_expand "movsi_to_cr_one"
13036   [(set (match_operand:CC 0 "cc_reg_operand")
13037         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13038                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13039   ""
13040   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13042 (define_insn "*movsi_to_cr"
13043   [(match_parallel 0 "mtcrf_operation"
13044                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13045                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13046                                      (match_operand 3 "immediate_operand" "n")]
13047                                     UNSPEC_MOVESI_TO_CR))])]
13048  ""
13050   int mask = 0;
13051   int i;
13052   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13053     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13054   operands[4] = GEN_INT (mask);
13055   return "mtcrf %4,%2";
13057   [(set_attr "type" "mtcr")])
13059 (define_insn "*mtcrfsi"
13060   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13061         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13062                     (match_operand 2 "immediate_operand" "n")]
13063                    UNSPEC_MOVESI_TO_CR))]
13064   "GET_CODE (operands[0]) == REG
13065    && CR_REGNO_P (REGNO (operands[0]))
13066    && GET_CODE (operands[2]) == CONST_INT
13067    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13068   "mtcrf %R0,%1"
13069   [(set_attr "type" "mtcr")])
13071 ; The load-multiple instructions have similar properties.
13072 ; Note that "load_multiple" is a name known to the machine-independent
13073 ; code that actually corresponds to the PowerPC load-string.
13075 (define_insn "*lmw"
13076   [(match_parallel 0 "lmw_operation"
13077                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13078                          (match_operand:SI 2 "memory_operand" "m"))])]
13079   "TARGET_MULTIPLE"
13080   "lmw %1,%2"
13081   [(set_attr "type" "load")
13082    (set_attr "update" "yes")
13083    (set_attr "indexed" "yes")
13084    (set_attr "cell_micro" "always")])
13086 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13087 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13089 ; The following comment applies to:
13090 ;     save_gpregs_*
13091 ;     save_fpregs_*
13092 ;     restore_gpregs*
13093 ;     return_and_restore_gpregs*
13094 ;     return_and_restore_fpregs*
13095 ;     return_and_restore_fpregs_aix*
13097 ; The out-of-line save / restore functions expects one input argument.
13098 ; Since those are not standard call_insn's, we must avoid using
13099 ; MATCH_OPERAND for that argument. That way the register rename
13100 ; optimization will not try to rename this register.
13101 ; Each pattern is repeated for each possible register number used in 
13102 ; various ABIs (r11, r1, and for some functions r12)
13104 (define_insn "*restore_gpregs_<mode>_r11"
13105  [(match_parallel 0 "any_parallel_operand"
13106                   [(clobber (reg:P LR_REGNO))
13107                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13108                    (use (reg:P 11))
13109                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13110                         (match_operand:P 3 "memory_operand" "m"))])]
13111  ""
13112  "bl %1"
13113  [(set_attr "type" "branch")
13114   (set_attr "length" "4")])
13116 (define_insn "*restore_gpregs_<mode>_r12"
13117  [(match_parallel 0 "any_parallel_operand"
13118                   [(clobber (reg:P LR_REGNO))
13119                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13120                    (use (reg:P 12))
13121                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13122                         (match_operand:P 3 "memory_operand" "m"))])]
13123  ""
13124  "bl %1"
13125  [(set_attr "type" "branch")
13126   (set_attr "length" "4")])
13128 (define_insn "*restore_gpregs_<mode>_r1"
13129  [(match_parallel 0 "any_parallel_operand"
13130                   [(clobber (reg:P LR_REGNO))
13131                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13132                    (use (reg:P 1))
13133                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13134                         (match_operand:P 3 "memory_operand" "m"))])]
13135  ""
13136  "bl %1"
13137  [(set_attr "type" "branch")
13138   (set_attr "length" "4")])
13140 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13141  [(match_parallel 0 "any_parallel_operand"
13142                   [(return)
13143                    (clobber (reg:P LR_REGNO))
13144                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13145                    (use (reg:P 11))
13146                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13147                         (match_operand:P 3 "memory_operand" "m"))])]
13148  ""
13149  "b %1"
13150  [(set_attr "type" "branch")
13151   (set_attr "length" "4")])
13153 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13154  [(match_parallel 0 "any_parallel_operand"
13155                   [(return)
13156                    (clobber (reg:P LR_REGNO))
13157                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13158                    (use (reg:P 12))
13159                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13160                         (match_operand:P 3 "memory_operand" "m"))])]
13161  ""
13162  "b %1"
13163  [(set_attr "type" "branch")
13164   (set_attr "length" "4")])
13166 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13167  [(match_parallel 0 "any_parallel_operand"
13168                   [(return)
13169                    (clobber (reg:P LR_REGNO))
13170                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13171                    (use (reg:P 1))
13172                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13173                         (match_operand:P 3 "memory_operand" "m"))])]
13174  ""
13175  "b %1"
13176  [(set_attr "type" "branch")
13177   (set_attr "length" "4")])
13179 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13180  [(match_parallel 0 "any_parallel_operand"
13181                   [(return)
13182                    (clobber (reg:P LR_REGNO))
13183                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13184                    (use (reg:P 11))
13185                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13186                         (match_operand:DF 3 "memory_operand" "m"))])]
13187  ""
13188  "b %1"
13189  [(set_attr "type" "branch")
13190   (set_attr "length" "4")])
13192 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13193  [(match_parallel 0 "any_parallel_operand"
13194                   [(return)
13195                    (clobber (reg:P LR_REGNO))
13196                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13197                    (use (reg:P 12))
13198                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13199                         (match_operand:DF 3 "memory_operand" "m"))])]
13200  ""
13201  "b %1"
13202  [(set_attr "type" "branch")
13203   (set_attr "length" "4")])
13205 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13206  [(match_parallel 0 "any_parallel_operand"
13207                   [(return)
13208                    (clobber (reg:P LR_REGNO))
13209                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13210                    (use (reg:P 1))
13211                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13212                         (match_operand:DF 3 "memory_operand" "m"))])]
13213  ""
13214  "b %1"
13215  [(set_attr "type" "branch")
13216   (set_attr "length" "4")])
13218 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13219  [(match_parallel 0 "any_parallel_operand"
13220                   [(return)
13221                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13222                    (use (reg:P 11))
13223                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13224                         (match_operand:DF 3 "memory_operand" "m"))])]
13225  ""
13226  "b %1"
13227  [(set_attr "type" "branch")
13228   (set_attr "length" "4")])
13230 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13231  [(match_parallel 0 "any_parallel_operand"
13232                   [(return)
13233                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13234                    (use (reg:P 1))
13235                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13236                         (match_operand:DF 3 "memory_operand" "m"))])]
13237  ""
13238  "b %1"
13239  [(set_attr "type" "branch")
13240   (set_attr "length" "4")])
13242 ; This is used in compiling the unwind routines.
13243 (define_expand "eh_return"
13244   [(use (match_operand 0 "general_operand"))]
13245   ""
13247   if (TARGET_32BIT)
13248     emit_insn (gen_eh_set_lr_si (operands[0]));
13249   else
13250     emit_insn (gen_eh_set_lr_di (operands[0]));
13251   DONE;
13254 ; We can't expand this before we know where the link register is stored.
13255 (define_insn "eh_set_lr_<mode>"
13256   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13257                     UNSPECV_EH_RR)
13258    (clobber (match_scratch:P 1 "=&b"))]
13259   ""
13260   "#")
13262 (define_split
13263   [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13264    (clobber (match_scratch 1))]
13265   "reload_completed"
13266   [(const_int 0)]
13268   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13269   DONE;
13272 (define_insn "prefetch"
13273   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13274              (match_operand:SI 1 "const_int_operand" "n")
13275              (match_operand:SI 2 "const_int_operand" "n"))]
13276   ""
13280   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13281      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13282      The AIX assembler does not support the three operand form of dcbt
13283      and dcbtst on Power 7 (-mpwr7).  */
13284   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13286   if (REG_P (operands[0]))
13287     {
13288       if (INTVAL (operands[1]) == 0)
13289         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13290       else
13291         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13292     }
13293   else
13294     {
13295       if (INTVAL (operands[1]) == 0)
13296         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13297       else
13298         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13299     }
13301   [(set_attr "type" "load")])
13303 ;; Handle -fsplit-stack.
13305 (define_expand "split_stack_prologue"
13306   [(const_int 0)]
13307   ""
13309   rs6000_expand_split_stack_prologue ();
13310   DONE;
13313 (define_expand "load_split_stack_limit"
13314   [(set (match_operand 0)
13315         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13316   ""
13318   emit_insn (gen_rtx_SET (operands[0],
13319                           gen_rtx_UNSPEC (Pmode,
13320                                           gen_rtvec (1, const0_rtx),
13321                                           UNSPEC_STACK_CHECK)));
13322   DONE;
13325 (define_insn "load_split_stack_limit_di"
13326   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13327         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13328   "TARGET_64BIT"
13329   "ld %0,-0x7040(13)"
13330   [(set_attr "type" "load")
13331    (set_attr "update" "no")
13332    (set_attr "indexed" "no")])
13334 (define_insn "load_split_stack_limit_si"
13335   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13336         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13337   "!TARGET_64BIT"
13338   "lwz %0,-0x7020(2)"
13339   [(set_attr "type" "load")
13340    (set_attr "update" "no")
13341    (set_attr "indexed" "no")])
13343 ;; A return instruction which the middle-end doesn't see.
13344 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13345 ;; after the call to __morestack.
13346 (define_insn "split_stack_return"
13347   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13348   ""
13349   "blr"
13350   [(set_attr "type" "jmpreg")])
13352 ;; If there are operand 0 bytes available on the stack, jump to
13353 ;; operand 1.
13354 (define_expand "split_stack_space_check"
13355   [(set (match_dup 2)
13356         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13357    (set (match_dup 3)
13358         (minus (reg STACK_POINTER_REGNUM)
13359                (match_operand 0)))
13360    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13361    (set (pc) (if_then_else
13362               (geu (match_dup 4) (const_int 0))
13363               (label_ref (match_operand 1))
13364               (pc)))]
13365   ""
13367   rs6000_split_stack_space_check (operands[0], operands[1]);
13368   DONE;
13371 (define_insn "bpermd_<mode>"
13372   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13373         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13374                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13375   "TARGET_POPCNTD"
13376   "bpermd %0,%1,%2"
13377   [(set_attr "type" "popcnt")])
13380 ;; Builtin fma support.  Handle 
13381 ;; Note that the conditions for expansion are in the FMA_F iterator.
13383 (define_expand "fma<mode>4"
13384   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13385         (fma:FMA_F
13386           (match_operand:FMA_F 1 "gpc_reg_operand")
13387           (match_operand:FMA_F 2 "gpc_reg_operand")
13388           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13389   ""
13390   "")
13392 (define_insn "*fma<mode>4_fpr"
13393   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13394         (fma:SFDF
13395           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13396           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13397           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13398   "TARGET_HARD_FLOAT"
13399   "@
13400    fmadd<Ftrad> %0,%1,%2,%3
13401    xsmadda<Fvsx> %x0,%x1,%x2
13402    xsmaddm<Fvsx> %x0,%x1,%x3"
13403   [(set_attr "type" "fp")])
13405 ; Altivec only has fma and nfms.
13406 (define_expand "fms<mode>4"
13407   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13408         (fma:FMA_F
13409           (match_operand:FMA_F 1 "gpc_reg_operand")
13410           (match_operand:FMA_F 2 "gpc_reg_operand")
13411           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13412   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13413   "")
13415 (define_insn "*fms<mode>4_fpr"
13416   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13417         (fma:SFDF
13418          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13419          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13420          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13421   "TARGET_HARD_FLOAT"
13422   "@
13423    fmsub<Ftrad> %0,%1,%2,%3
13424    xsmsuba<Fvsx> %x0,%x1,%x2
13425    xsmsubm<Fvsx> %x0,%x1,%x3"
13426   [(set_attr "type" "fp")])
13428 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13429 (define_expand "fnma<mode>4"
13430   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13431         (neg:FMA_F
13432           (fma:FMA_F
13433             (match_operand:FMA_F 1 "gpc_reg_operand")
13434             (match_operand:FMA_F 2 "gpc_reg_operand")
13435             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13436   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13437   "")
13439 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13440 (define_expand "fnms<mode>4"
13441   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13442         (neg:FMA_F
13443           (fma:FMA_F
13444             (match_operand:FMA_F 1 "gpc_reg_operand")
13445             (match_operand:FMA_F 2 "gpc_reg_operand")
13446             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13447   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13448   "")
13450 ; Not an official optab name, but used from builtins.
13451 (define_expand "nfma<mode>4"
13452   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13453         (neg:FMA_F
13454           (fma:FMA_F
13455             (match_operand:FMA_F 1 "gpc_reg_operand")
13456             (match_operand:FMA_F 2 "gpc_reg_operand")
13457             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13458   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13459   "")
13461 (define_insn "*nfma<mode>4_fpr"
13462   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13463         (neg:SFDF
13464          (fma:SFDF
13465           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13466           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13467           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13468   "TARGET_HARD_FLOAT"
13469   "@
13470    fnmadd<Ftrad> %0,%1,%2,%3
13471    xsnmadda<Fvsx> %x0,%x1,%x2
13472    xsnmaddm<Fvsx> %x0,%x1,%x3"
13473   [(set_attr "type" "fp")])
13475 ; Not an official optab name, but used from builtins.
13476 (define_expand "nfms<mode>4"
13477   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13478         (neg:FMA_F
13479           (fma:FMA_F
13480             (match_operand:FMA_F 1 "gpc_reg_operand")
13481             (match_operand:FMA_F 2 "gpc_reg_operand")
13482             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13483   ""
13484   "")
13486 (define_insn "*nfmssf4_fpr"
13487   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13488         (neg:SFDF
13489          (fma:SFDF
13490           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13491           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13492           (neg:SFDF
13493            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13494   "TARGET_HARD_FLOAT"
13495   "@
13496    fnmsub<Ftrad> %0,%1,%2,%3
13497    xsnmsuba<Fvsx> %x0,%x1,%x2
13498    xsnmsubm<Fvsx> %x0,%x1,%x3"
13499   [(set_attr "type" "fp")])
13502 (define_expand "rs6000_get_timebase"
13503   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13504   ""
13506   if (TARGET_POWERPC64)
13507     emit_insn (gen_rs6000_mftb_di (operands[0]));
13508   else
13509     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13510   DONE;
13513 (define_insn "rs6000_get_timebase_ppc32"
13514   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13515         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13516    (clobber (match_scratch:SI 1 "=r"))
13517    (clobber (match_scratch:CC 2 "=y"))]
13518   "!TARGET_POWERPC64"
13520   if (WORDS_BIG_ENDIAN)
13521     if (TARGET_MFCRF)
13522       {
13523         return "mfspr %0,269\;"
13524                "mfspr %L0,268\;"
13525                "mfspr %1,269\;"
13526                "cmpw %2,%0,%1\;"
13527                "bne- %2,$-16";
13528       }
13529     else
13530       {
13531         return "mftbu %0\;"
13532                "mftb %L0\;"
13533                "mftbu %1\;"
13534                "cmpw %2,%0,%1\;"
13535                "bne- %2,$-16";
13536       }
13537   else
13538     if (TARGET_MFCRF)
13539       {
13540         return "mfspr %L0,269\;"
13541                "mfspr %0,268\;"
13542                "mfspr %1,269\;"
13543                "cmpw %2,%L0,%1\;"
13544                "bne- %2,$-16";
13545       }
13546     else
13547       {
13548         return "mftbu %L0\;"
13549                "mftb %0\;"
13550                "mftbu %1\;"
13551                "cmpw %2,%L0,%1\;"
13552                "bne- %2,$-16";
13553       }
13555   [(set_attr "length" "20")])
13557 (define_insn "rs6000_mftb_<mode>"
13558   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13559         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13560   ""
13562   if (TARGET_MFCRF)
13563     return "mfspr %0,268";
13564   else
13565     return "mftb %0";
13569 (define_insn "rs6000_mffs"
13570   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13571         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13572   "TARGET_HARD_FLOAT"
13573   "mffs %0")
13575 (define_insn "rs6000_mtfsf"
13576   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13577                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13578                     UNSPECV_MTFSF)]
13579   "TARGET_HARD_FLOAT"
13580   "mtfsf %0,%1")
13583 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13584 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13585 ;; register that is being loaded.  The fused ops must be physically adjacent.
13587 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13588 ;; before register allocation, and is meant to reduce the lifetime for the
13589 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13590 ;; to use the register that is being load.  The peephole2 then gathers any
13591 ;; other fused possibilities that it can find after register allocation.  If
13592 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13594 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13595 ;; before register allocation, so that we can avoid allocating a temporary base
13596 ;; register that won't be used, and that we try to load into base registers,
13597 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13598 ;; (addis followed by load) even on power8.
13600 (define_split
13601   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13602         (match_operand:INT1 1 "toc_fusion_mem_raw"))]
13603   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13604   [(parallel [(set (match_dup 0) (match_dup 2))
13605               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13606               (use (match_dup 3))
13607               (clobber (scratch:DI))])]
13609   operands[2] = fusion_wrap_memory_address (operands[1]);
13610   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13613 (define_insn "*toc_fusionload_<mode>"
13614   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13615         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13616    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13617    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13618    (clobber (match_scratch:DI 3 "=X,&b"))]
13619   "TARGET_TOC_FUSION_INT"
13621   if (base_reg_operand (operands[0], <MODE>mode))
13622     return emit_fusion_gpr_load (operands[0], operands[1]);
13624   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13626   [(set_attr "type" "load")
13627    (set_attr "length" "8")])
13629 (define_insn "*toc_fusionload_di"
13630   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13631         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13632    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13633    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13634    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13635   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13636    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13638   if (base_reg_operand (operands[0], DImode))
13639     return emit_fusion_gpr_load (operands[0], operands[1]);
13641   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13643   [(set_attr "type" "load")
13644    (set_attr "length" "8")])
13647 ;; Find cases where the addis that feeds into a load instruction is either used
13648 ;; once or is the same as the target register, and replace it with the fusion
13649 ;; insn
13651 (define_peephole2
13652   [(set (match_operand:P 0 "base_reg_operand")
13653         (match_operand:P 1 "fusion_gpr_addis"))
13654    (set (match_operand:INT1 2 "base_reg_operand")
13655         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13656   "TARGET_P8_FUSION
13657    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13658                          operands[3])"
13659   [(const_int 0)]
13661   expand_fusion_gpr_load (operands);
13662   DONE;
13665 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13666 ;; reload)
13668 (define_insn "fusion_gpr_load_<mode>"
13669   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13670         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13671                      UNSPEC_FUSION_GPR))]
13672   "TARGET_P8_FUSION"
13674   return emit_fusion_gpr_load (operands[0], operands[1]);
13676   [(set_attr "type" "load")
13677    (set_attr "length" "8")])
13680 ;; ISA 3.0 (power9) fusion support
13681 ;; Merge addis with floating load/store to FPRs (or GPRs).
13682 (define_peephole2
13683   [(set (match_operand:P 0 "base_reg_operand")
13684         (match_operand:P 1 "fusion_gpr_addis"))
13685    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13686         (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13687   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13688    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13689   [(const_int 0)]
13691   expand_fusion_p9_load (operands);
13692   DONE;
13695 (define_peephole2
13696   [(set (match_operand:P 0 "base_reg_operand")
13697         (match_operand:P 1 "fusion_gpr_addis"))
13698    (set (match_operand:SFDF 2 "offsettable_mem_operand")
13699         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13700   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13701    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13702    && !rtx_equal_p (operands[0], operands[3])"
13703   [(const_int 0)]
13705   expand_fusion_p9_store (operands);
13706   DONE;
13709 (define_peephole2
13710   [(set (match_operand:SDI 0 "int_reg_operand")
13711         (match_operand:SDI 1 "upper16_cint_operand"))
13712    (set (match_dup 0)
13713         (ior:SDI (match_dup 0)
13714                  (match_operand:SDI 2 "u_short_cint_operand")))]
13715   "TARGET_P9_FUSION"
13716   [(set (match_dup 0)
13717         (unspec:SDI [(match_dup 1)
13718                      (match_dup 2)] UNSPEC_FUSION_P9))])
13720 (define_peephole2
13721   [(set (match_operand:SDI 0 "int_reg_operand")
13722         (match_operand:SDI 1 "upper16_cint_operand"))
13723    (set (match_operand:SDI 2 "int_reg_operand")
13724         (ior:SDI (match_dup 0)
13725                  (match_operand:SDI 3 "u_short_cint_operand")))]
13726   "TARGET_P9_FUSION
13727    && !rtx_equal_p (operands[0], operands[2])
13728    && peep2_reg_dead_p (2, operands[0])"
13729   [(set (match_dup 2)
13730         (unspec:SDI [(match_dup 1)
13731                      (match_dup 3)] UNSPEC_FUSION_P9))])
13733 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13734 ;; reload).  Because we want to eventually have secondary_reload generate
13735 ;; these, they have to have a single alternative that gives the register
13736 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13737 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13738   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13739         (unspec:GPR_FUSION
13740          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13741          UNSPEC_FUSION_P9))
13742    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13743   "TARGET_P9_FUSION"
13745   /* This insn is a secondary reload insn, which cannot have alternatives.
13746      If we are not loading up register 0, use the power8 fusion instead.  */
13747   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13748     return emit_fusion_gpr_load (operands[0], operands[1]);
13750   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13752   [(set_attr "type" "load")
13753    (set_attr "length" "8")])
13755 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13756   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13757         (unspec:GPR_FUSION
13758          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13759          UNSPEC_FUSION_P9))
13760    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13761   "TARGET_P9_FUSION"
13763   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13765   [(set_attr "type" "store")
13766    (set_attr "length" "8")])
13768 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13769   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13770         (unspec:FPR_FUSION
13771          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13772          UNSPEC_FUSION_P9))
13773    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13774   "TARGET_P9_FUSION"
13776   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13778   [(set_attr "type" "fpload")
13779    (set_attr "length" "8")])
13781 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13782   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13783         (unspec:FPR_FUSION
13784          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13785          UNSPEC_FUSION_P9))
13786    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13787   "TARGET_P9_FUSION"
13789   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13791   [(set_attr "type" "fpstore")
13792    (set_attr "length" "8")])
13794 (define_insn "*fusion_p9_<mode>_constant"
13795   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13796         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13797                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13798                     UNSPEC_FUSION_P9))] 
13799   "TARGET_P9_FUSION"
13801   emit_fusion_addis (operands[0], operands[1]);
13802   return "ori %0,%0,%2";
13804   [(set_attr "type" "two")
13805    (set_attr "length" "8")])
13808 ;; Optimize cases where we want to do a D-form load (register+offset) on
13809 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13810 ;; has generated:
13811 ;;      LFD 0,32(3)
13812 ;;      XXLOR 32,0,0
13814 ;; and we change this to:
13815 ;;      LI 0,32
13816 ;;      LXSDX 32,3,9
13818 (define_peephole2
13819   [(match_scratch:P 0 "b")
13820    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13821         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13822    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13823         (match_dup 1))]
13824   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13825   [(set (match_dup 0)
13826         (match_dup 4))
13827    (set (match_dup 3)
13828         (match_dup 5))]
13830   rtx tmp_reg = operands[0];
13831   rtx mem = operands[2];
13832   rtx addr = XEXP (mem, 0);
13833   rtx add_op0, add_op1, new_addr;
13835   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13836   add_op0 = XEXP (addr, 0);
13837   add_op1 = XEXP (addr, 1);
13838   gcc_assert (REG_P (add_op0));
13839   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13841   operands[4] = add_op1;
13842   operands[5] = change_address (mem, <MODE>mode, new_addr);
13845 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13846 ;; Altivec register, and the register allocator has generated:
13847 ;;      XXLOR 0,32,32
13848 ;;      STFD 0,32(3)
13850 ;; and we change this to:
13851 ;;      LI 0,32
13852 ;;      STXSDX 32,3,9
13854 (define_peephole2
13855   [(match_scratch:P 0 "b")
13856    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13857         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13858    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13859         (match_dup 1))]
13860   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13861   [(set (match_dup 0)
13862         (match_dup 4))
13863    (set (match_dup 5)
13864         (match_dup 2))]
13866   rtx tmp_reg = operands[0];
13867   rtx mem = operands[3];
13868   rtx addr = XEXP (mem, 0);
13869   rtx add_op0, add_op1, new_addr;
13871   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13872   add_op0 = XEXP (addr, 0);
13873   add_op1 = XEXP (addr, 1);
13874   gcc_assert (REG_P (add_op0));
13875   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13877   operands[4] = add_op1;
13878   operands[5] = change_address (mem, <MODE>mode, new_addr);
13880    
13882 ;; Miscellaneous ISA 2.06 (power7) instructions
13883 (define_insn "addg6s"
13884   [(set (match_operand:SI 0 "register_operand" "=r")
13885         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13886                     (match_operand:SI 2 "register_operand" "r")]
13887                    UNSPEC_ADDG6S))]
13888   "TARGET_POPCNTD"
13889   "addg6s %0,%1,%2"
13890   [(set_attr "type" "integer")
13891    (set_attr "length" "4")])
13893 (define_insn "cdtbcd"
13894   [(set (match_operand:SI 0 "register_operand" "=r")
13895         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13896                    UNSPEC_CDTBCD))]
13897   "TARGET_POPCNTD"
13898   "cdtbcd %0,%1"
13899   [(set_attr "type" "integer")
13900    (set_attr "length" "4")])
13902 (define_insn "cbcdtd"
13903   [(set (match_operand:SI 0 "register_operand" "=r")
13904         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13905                    UNSPEC_CBCDTD))]
13906   "TARGET_POPCNTD"
13907   "cbcdtd %0,%1"
13908   [(set_attr "type" "integer")
13909    (set_attr "length" "4")])
13911 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13912                                         UNSPEC_DIVEU])
13914 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13915                              (UNSPEC_DIVEU      "eu")])
13917 (define_insn "div<div_extend>_<mode>"
13918   [(set (match_operand:GPR 0 "register_operand" "=r")
13919         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13920                      (match_operand:GPR 2 "register_operand" "r")]
13921                     UNSPEC_DIV_EXTEND))]
13922   "TARGET_POPCNTD"
13923   "div<wd><div_extend> %0,%1,%2"
13924   [(set_attr "type" "div")
13925    (set_attr "size" "<bits>")])
13928 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13930 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13931 (define_mode_attr FP128_64 [(TF "DF")
13932                             (IF "DF")
13933                             (TD "DI")
13934                             (KF "DI")])
13936 (define_expand "unpack<mode>"
13937   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13938         (unspec:<FP128_64>
13939          [(match_operand:FMOVE128 1 "register_operand")
13940           (match_operand:QI 2 "const_0_to_1_operand")]
13941          UNSPEC_UNPACK_128BIT))]
13942   "FLOAT128_2REG_P (<MODE>mode)"
13943   "")
13945 (define_insn_and_split "unpack<mode>_dm"
13946   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13947         (unspec:<FP128_64>
13948          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13949           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13950          UNSPEC_UNPACK_128BIT))]
13951   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13952   "#"
13953   "&& reload_completed"
13954   [(set (match_dup 0) (match_dup 3))]
13956   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13958   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13959     {
13960       emit_note (NOTE_INSN_DELETED);
13961       DONE;
13962     }
13964   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13966   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13967    (set_attr "length" "4")])
13969 (define_insn_and_split "unpack<mode>_nodm"
13970   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13971         (unspec:<FP128_64>
13972          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13973           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13974          UNSPEC_UNPACK_128BIT))]
13975   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13976   "#"
13977   "&& reload_completed"
13978   [(set (match_dup 0) (match_dup 3))]
13980   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13982   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13983     {
13984       emit_note (NOTE_INSN_DELETED);
13985       DONE;
13986     }
13988   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13990   [(set_attr "type" "fp,fpstore")
13991    (set_attr "length" "4")])
13993 (define_insn_and_split "pack<mode>"
13994   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13995         (unspec:FMOVE128
13996          [(match_operand:<FP128_64> 1 "register_operand" "d")
13997           (match_operand:<FP128_64> 2 "register_operand" "d")]
13998          UNSPEC_PACK_128BIT))]
13999   "FLOAT128_2REG_P (<MODE>mode)"
14000   "#"
14001   "&& reload_completed"
14002   [(set (match_dup 3) (match_dup 1))
14003    (set (match_dup 4) (match_dup 2))]
14005   unsigned dest_hi = REGNO (operands[0]);
14006   unsigned dest_lo = dest_hi + 1;
14008   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14009   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14011   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14012   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14014   [(set_attr "type" "fp")
14015    (set_attr "length" "8")])
14017 (define_insn "unpack<mode>"
14018   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14019         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14020                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14021          UNSPEC_UNPACK_128BIT))]
14022   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14024   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14025     return ASM_COMMENT_START " xxpermdi to same register";
14027   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14028   return "xxpermdi %x0,%x1,%x1,%3";
14030   [(set_attr "type" "vecperm")])
14032 (define_insn "pack<mode>"
14033   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14034         (unspec:FMOVE128_VSX
14035          [(match_operand:DI 1 "register_operand" "wa")
14036           (match_operand:DI 2 "register_operand" "wa")]
14037          UNSPEC_PACK_128BIT))]
14038   "TARGET_VSX"
14039   "xxpermdi %x0,%x1,%x2,0"
14040   [(set_attr "type" "vecperm")])
14044 ;; ISA 2.08 IEEE 128-bit floating point support.
14046 (define_insn "add<mode>3"
14047   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14048         (plus:IEEE128
14049          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14050          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14051   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14052   "xsaddqp %0,%1,%2"
14053   [(set_attr "type" "vecfloat")
14054    (set_attr "size" "128")])
14056 (define_insn "sub<mode>3"
14057   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14058         (minus:IEEE128
14059          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14060          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14061   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14062   "xssubqp %0,%1,%2"
14063   [(set_attr "type" "vecfloat")
14064    (set_attr "size" "128")])
14066 (define_insn "mul<mode>3"
14067   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14068         (mult:IEEE128
14069          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14070          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14071   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14072   "xsmulqp %0,%1,%2"
14073   [(set_attr "type" "qmul")
14074    (set_attr "size" "128")])
14076 (define_insn "div<mode>3"
14077   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14078         (div:IEEE128
14079          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14080          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14081   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14082   "xsdivqp %0,%1,%2"
14083   [(set_attr "type" "vecdiv")
14084    (set_attr "size" "128")])
14086 (define_insn "sqrt<mode>2"
14087   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14088         (sqrt:IEEE128
14089          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14090   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14091    "xssqrtqp %0,%1"
14092   [(set_attr "type" "vecdiv")
14093    (set_attr "size" "128")])
14095 (define_expand "copysign<mode>3"
14096   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14097    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14098    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14099   "FLOAT128_IEEE_P (<MODE>mode)"
14101   if (TARGET_FLOAT128_HW)
14102     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14103                                          operands[2]));
14104   else
14105     {
14106       rtx tmp = gen_reg_rtx (<MODE>mode);
14107       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14108                                            operands[2], tmp));
14109     }
14110   DONE;
14113 (define_insn "copysign<mode>3_hard"
14114   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14115         (unspec:IEEE128
14116          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14117           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14118          UNSPEC_COPYSIGN))]
14119   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14120    "xscpsgnqp %0,%2,%1"
14121   [(set_attr "type" "vecmove")
14122    (set_attr "size" "128")])
14124 (define_insn "copysign<mode>3_soft"
14125   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14126         (unspec:IEEE128
14127          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14128           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14129           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14130          UNSPEC_COPYSIGN))]
14131   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14132    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14133   [(set_attr "type" "veccomplex")
14134    (set_attr "length" "8")])
14136 (define_insn "neg<mode>2_hw"
14137   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14138         (neg:IEEE128
14139          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14140   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14141   "xsnegqp %0,%1"
14142   [(set_attr "type" "vecmove")
14143    (set_attr "size" "128")])
14146 (define_insn "abs<mode>2_hw"
14147   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14148         (abs:IEEE128
14149          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14150   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14151   "xsabsqp %0,%1"
14152   [(set_attr "type" "vecmove")
14153    (set_attr "size" "128")])
14156 (define_insn "*nabs<mode>2_hw"
14157   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14158         (neg:IEEE128
14159          (abs:IEEE128
14160           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14161   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14162   "xsnabsqp %0,%1"
14163   [(set_attr "type" "vecmove")
14164    (set_attr "size" "128")])
14166 ;; Initially don't worry about doing fusion
14167 (define_insn "fma<mode>4_hw"
14168   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14169         (fma:IEEE128
14170          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14171          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14172          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14173   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14174   "xsmaddqp %0,%1,%2"
14175   [(set_attr "type" "qmul")
14176    (set_attr "size" "128")])
14178 (define_insn "*fms<mode>4_hw"
14179   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14180         (fma:IEEE128
14181          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14182          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14183          (neg:IEEE128
14184           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14185   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14186   "xsmsubqp %0,%1,%2"
14187   [(set_attr "type" "qmul")
14188    (set_attr "size" "128")])
14190 (define_insn "*nfma<mode>4_hw"
14191   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14192         (neg:IEEE128
14193          (fma:IEEE128
14194           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14195           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14196           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14197   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14198   "xsnmaddqp %0,%1,%2"
14199   [(set_attr "type" "qmul")
14200    (set_attr "size" "128")])
14202 (define_insn "*nfms<mode>4_hw"
14203   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14204         (neg:IEEE128
14205          (fma:IEEE128
14206           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14207           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14208           (neg:IEEE128
14209            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14210   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14211   "xsnmsubqp %0,%1,%2"
14212   [(set_attr "type" "qmul")
14213    (set_attr "size" "128")])
14215 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14216   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14217         (float_extend:IEEE128
14218          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14219   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14220   "xscvdpqp %0,%1"
14221   [(set_attr "type" "vecfloat")
14222    (set_attr "size" "128")])
14224 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14225 ;; point is a simple copy.
14226 (define_insn_and_split "extendkftf2"
14227   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14228         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14229   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14230   "@
14231    #
14232    xxlor %x0,%x1,%x1"
14233   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14234   [(const_int 0)]
14236   emit_note (NOTE_INSN_DELETED);
14237   DONE;
14239   [(set_attr "type" "*,veclogical")
14240    (set_attr "length" "0,4")])
14242 (define_insn_and_split "trunctfkf2"
14243   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14244         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14245   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14246   "@
14247    #
14248    xxlor %x0,%x1,%x1"
14249   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14250   [(const_int 0)]
14252   emit_note (NOTE_INSN_DELETED);
14253   DONE;
14255   [(set_attr "type" "*,veclogical")
14256    (set_attr "length" "0,4")])
14258 (define_insn "trunc<mode>df2_hw"
14259   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14260         (float_truncate:DF
14261          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14262   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14263   "xscvqpdp %0,%1"
14264   [(set_attr "type" "vecfloat")
14265    (set_attr "size" "128")])
14267 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14268 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14269 ;; conversion
14270 (define_insn_and_split "trunc<mode>sf2_hw"
14271   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14272         (float_truncate:SF
14273          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14274    (clobber (match_scratch:DF 2 "=v"))]
14275   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14276   "#"
14277   "&& 1"
14278   [(set (match_dup 2)
14279         (unspec:DF [(match_dup 1)]
14280                    UNSPEC_TRUNC_ROUND_TO_ODD))
14281    (set (match_dup 0)
14282         (float_truncate:SF (match_dup 2)))]
14284   if (GET_CODE (operands[2]) == SCRATCH)
14285     operands[2] = gen_reg_rtx (DFmode);
14287   [(set_attr "type" "vecfloat")
14288    (set_attr "length" "8")])
14290 ;; Conversion between IEEE 128-bit and integer types
14292 ;; The fix function for DImode and SImode was declared earlier as a
14293 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14294 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14295 ;; unless we have the IEEE 128-bit hardware.
14297 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14298 ;; to provide a GPR target that used direct move and a conversion in the GPR
14299 ;; which works around QImode/HImode not being allowed in vector registers in
14300 ;; ISA 2.07 (power8).
14301 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14302   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14303         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14304   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14305   "xscvqp<su><wd>z %0,%1"
14306   [(set_attr "type" "vecfloat")
14307    (set_attr "size" "128")])
14309 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14310   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14311         (any_fix:QHI
14312          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14313   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14314   "xscvqp<su>wz %0,%1"
14315   [(set_attr "type" "vecfloat")
14316    (set_attr "size" "128")])
14318 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14319 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14320 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14321   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14322         (any_fix:QHSI
14323          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14324    (clobber (match_scratch:QHSI 2 "=v"))]
14325   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14326   "#"
14327   "&& reload_completed"
14328   [(set (match_dup 2)
14329         (any_fix:QHSI (match_dup 1)))
14330    (set (match_dup 0)
14331         (match_dup 2))])
14333 (define_insn "float_<mode>di2_hw"
14334   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14335         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14336   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14337   "xscvsdqp %0,%1"
14338   [(set_attr "type" "vecfloat")
14339    (set_attr "size" "128")])
14341 (define_insn_and_split "float_<mode>si2_hw"
14342   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14343         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14344    (clobber (match_scratch:DI 2 "=v"))]
14345   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14346   "#"
14347   "&& 1"
14348   [(set (match_dup 2)
14349         (sign_extend:DI (match_dup 1)))
14350    (set (match_dup 0)
14351         (float:IEEE128 (match_dup 2)))]
14353   if (GET_CODE (operands[2]) == SCRATCH)
14354     operands[2] = gen_reg_rtx (DImode);
14356   if (MEM_P (operands[1]))
14357     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14360 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14361   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14362         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14363    (clobber (match_scratch:DI 2 "=X,r,X"))]
14364   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14365   "#"
14366   "&& reload_completed"
14367   [(const_int 0)]
14369   rtx dest = operands[0];
14370   rtx src = operands[1];
14371   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14373   if (altivec_register_operand (src, <QHI:MODE>mode))
14374     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14375   else if (int_reg_operand (src, <QHI:MODE>mode))
14376     {
14377       rtx ext_di = operands[2];
14378       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14379       emit_move_insn (dest_di, ext_di);
14380     }
14381   else if (MEM_P (src))
14382     {
14383       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14384       emit_move_insn (dest_qhi, src);
14385       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14386     }
14387   else
14388     gcc_unreachable ();
14390   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14391   DONE;
14393   [(set_attr "length" "8,12,12")
14394    (set_attr "type" "vecfloat")
14395    (set_attr "size" "128")])
14397 (define_insn "floatuns_<mode>di2_hw"
14398   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14399         (unsigned_float:IEEE128
14400          (match_operand:DI 1 "altivec_register_operand" "v")))]
14401   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14402   "xscvudqp %0,%1"
14403   [(set_attr "type" "vecfloat")
14404    (set_attr "size" "128")])
14406 (define_insn_and_split "floatuns_<mode>si2_hw"
14407   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14408         (unsigned_float:IEEE128
14409          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14410    (clobber (match_scratch:DI 2 "=v"))]
14411   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14412   "#"
14413   "&& 1"
14414   [(set (match_dup 2)
14415         (zero_extend:DI (match_dup 1)))
14416    (set (match_dup 0)
14417         (float:IEEE128 (match_dup 2)))]
14419   if (GET_CODE (operands[2]) == SCRATCH)
14420     operands[2] = gen_reg_rtx (DImode);
14422   if (MEM_P (operands[1]))
14423     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14426 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14427   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14428         (unsigned_float:IEEE128
14429          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14430    (clobber (match_scratch:DI 2 "=X,r,X"))]
14431   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14432   "#"
14433   "&& reload_completed"
14434   [(const_int 0)]
14436   rtx dest = operands[0];
14437   rtx src = operands[1];
14438   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14440   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14441     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14442   else if (int_reg_operand (src, <QHI:MODE>mode))
14443     {
14444       rtx ext_di = operands[2];
14445       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14446       emit_move_insn (dest_di, ext_di);
14447     }
14448   else
14449     gcc_unreachable ();
14451   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14452   DONE;
14454   [(set_attr "length" "8,12,8")
14455    (set_attr "type" "vecfloat")
14456    (set_attr "size" "128")])
14458 ;; IEEE 128-bit round to integer built-in functions
14459 (define_insn "floor<mode>2"
14460   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14461         (unspec:IEEE128
14462          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14463          UNSPEC_FRIM))]
14464   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14465   "xsrqpi 1,%0,%1,3"
14466   [(set_attr "type" "vecfloat")
14467    (set_attr "size" "128")])
14469 (define_insn "ceil<mode>2"
14470   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14471         (unspec:IEEE128
14472          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14473          UNSPEC_FRIP))]
14474   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14475   "xsrqpi 1,%0,%1,2"
14476   [(set_attr "type" "vecfloat")
14477    (set_attr "size" "128")])
14479 (define_insn "btrunc<mode>2"
14480   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14481         (unspec:IEEE128
14482          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14483          UNSPEC_FRIZ))]
14484   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14485   "xsrqpi 1,%0,%1,1"
14486   [(set_attr "type" "vecfloat")
14487    (set_attr "size" "128")])
14489 (define_insn "round<mode>2"
14490   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14491         (unspec:IEEE128
14492          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14493          UNSPEC_FRIN))]
14494   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14495   "xsrqpi 0,%0,%1,0"
14496   [(set_attr "type" "vecfloat")
14497    (set_attr "size" "128")])
14499 ;; IEEE 128-bit instructions with round to odd semantics
14500 (define_insn "add<mode>3_odd"
14501   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14502         (unspec:IEEE128
14503          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14504           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14505          UNSPEC_ADD_ROUND_TO_ODD))]
14506   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14507   "xsaddqpo %0,%1,%2"
14508   [(set_attr "type" "vecfloat")
14509    (set_attr "size" "128")])
14511 (define_insn "sub<mode>3_odd"
14512   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14513         (unspec:IEEE128
14514          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14515           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14516          UNSPEC_SUB_ROUND_TO_ODD))]
14517   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14518   "xssubqpo %0,%1,%2"
14519   [(set_attr "type" "vecfloat")
14520    (set_attr "size" "128")])
14522 (define_insn "mul<mode>3_odd"
14523   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14524         (unspec:IEEE128
14525          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14526           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14527          UNSPEC_MUL_ROUND_TO_ODD))]
14528   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14529   "xsmulqpo %0,%1,%2"
14530   [(set_attr "type" "qmul")
14531    (set_attr "size" "128")])
14533 (define_insn "div<mode>3_odd"
14534   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14535         (unspec:IEEE128
14536          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14537           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14538          UNSPEC_DIV_ROUND_TO_ODD))]
14539   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14540   "xsdivqpo %0,%1,%2"
14541   [(set_attr "type" "vecdiv")
14542    (set_attr "size" "128")])
14544 (define_insn "sqrt<mode>2_odd"
14545   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14546         (unspec:IEEE128
14547          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14548          UNSPEC_SQRT_ROUND_TO_ODD))]
14549   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14550    "xssqrtqpo %0,%1"
14551   [(set_attr "type" "vecdiv")
14552    (set_attr "size" "128")])
14554 (define_insn "fma<mode>4_odd"
14555   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14556         (unspec:IEEE128
14557          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14558           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14559           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14560          UNSPEC_FMA_ROUND_TO_ODD))]
14561   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14562   "xsmaddqpo %0,%1,%2"
14563   [(set_attr "type" "qmul")
14564    (set_attr "size" "128")])
14566 (define_insn "*fms<mode>4_odd"
14567   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14568         (unspec:IEEE128
14569          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14570           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14571           (neg:IEEE128
14572            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14573          UNSPEC_FMA_ROUND_TO_ODD))]
14574   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14575   "xsmsubqpo %0,%1,%2"
14576   [(set_attr "type" "qmul")
14577    (set_attr "size" "128")])
14579 (define_insn "*nfma<mode>4_odd"
14580   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14581         (neg:IEEE128
14582          (unspec:IEEE128
14583           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14584            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14585            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14586           UNSPEC_FMA_ROUND_TO_ODD)))]
14587   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14588   "xsnmaddqpo %0,%1,%2"
14589   [(set_attr "type" "qmul")
14590    (set_attr "size" "128")])
14592 (define_insn "*nfms<mode>4_odd"
14593   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14594         (neg:IEEE128
14595          (unspec:IEEE128
14596           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14597            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14598            (neg:IEEE128
14599             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14600           UNSPEC_FMA_ROUND_TO_ODD)))]
14601   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14602   "xsnmsubqpo %0,%1,%2"
14603   [(set_attr "type" "qmul")
14604    (set_attr "size" "128")])
14606 (define_insn "trunc<mode>df2_odd"
14607   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14608         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14609                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14610   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14611   "xscvqpdpo %0,%1"
14612   [(set_attr "type" "vecfloat")
14613    (set_attr "size" "128")])
14615 ;; IEEE 128-bit comparisons
14616 (define_insn "*cmp<mode>_hw"
14617   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14618         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14619                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14620   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14621    "xscmpuqp %0,%1,%2"
14622   [(set_attr "type" "veccmp")
14623    (set_attr "size" "128")])
14627 (include "sync.md")
14628 (include "vector.md")
14629 (include "vsx.md")
14630 (include "altivec.md")
14631 (include "dfp.md")
14632 (include "crypto.md")
14633 (include "htm.md")