rs6000.md (extendtfif2): Add missing 128-bit conversion insn that shows up when...
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob3044e6eb475450baaa7c3eb344500954f8348dc3
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 "extendtfif2"
8162   [(set (match_operand:IF 0 "gpc_reg_operand")
8163         (float_extend: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 "trunciftf2"
8171   [(set (match_operand:TF 0 "gpc_reg_operand")
8172         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8173   "TARGET_FLOAT128_TYPE"
8175   rs6000_expand_float128_convert (operands[0], operands[1], false);
8176   DONE;
8179 (define_expand "truncifkf2"
8180   [(set (match_operand:KF 0 "gpc_reg_operand")
8181         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8182   "TARGET_FLOAT128_TYPE"
8184   rs6000_expand_float128_convert (operands[0], operands[1], false);
8185   DONE;
8188 (define_expand "trunckftf2"
8189   [(set (match_operand:TF 0 "gpc_reg_operand")
8190         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8191   "TARGET_FLOAT128_TYPE"
8193   rs6000_expand_float128_convert (operands[0], operands[1], false);
8194   DONE;
8197 (define_expand "trunctfif2"
8198   [(set (match_operand:IF 0 "gpc_reg_operand")
8199         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8200   "TARGET_FLOAT128_TYPE"
8202   rs6000_expand_float128_convert (operands[0], operands[1], false);
8203   DONE;
8206 (define_insn_and_split "*extend<mode>tf2_internal"
8207   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8208         (float_extend:TF
8209          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8210    "TARGET_FLOAT128_TYPE
8211     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8212   "#"
8213   "&& reload_completed"
8214   [(set (match_dup 0) (match_dup 2))]
8216   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8219 (define_insn_and_split "*extendtf<mode>2_internal"
8220   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8221         (float_extend:IFKF
8222          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8223    "TARGET_FLOAT128_TYPE
8224     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8225   "#"
8226   "&& reload_completed"
8227   [(set (match_dup 0) (match_dup 2))]
8229   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8233 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8234 ;; must have 3 arguments, and scratch register constraint must be a single
8235 ;; constraint.
8237 ;; Reload patterns to support gpr load/store with misaligned mem.
8238 ;; and multiple gpr load/store at offset >= 0xfffc
8239 (define_expand "reload_<mode>_store"
8240   [(parallel [(match_operand 0 "memory_operand" "=m")
8241               (match_operand 1 "gpc_reg_operand" "r")
8242               (match_operand:GPR 2 "register_operand" "=&b")])]
8243   ""
8245   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8246   DONE;
8249 (define_expand "reload_<mode>_load"
8250   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8251               (match_operand 1 "memory_operand" "m")
8252               (match_operand:GPR 2 "register_operand" "=b")])]
8253   ""
8255   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8256   DONE;
8260 ;; Reload patterns for various types using the vector registers.  We may need
8261 ;; an additional base register to convert the reg+offset addressing to reg+reg
8262 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8263 ;; index register for gpr registers.
8264 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8265   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8266               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8267               (match_operand:P 2 "register_operand" "=b")])]
8268   "<P:tptrsize>"
8270   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8271   DONE;
8274 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8275   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8276               (match_operand:RELOAD 1 "memory_operand" "m")
8277               (match_operand:P 2 "register_operand" "=b")])]
8278   "<P:tptrsize>"
8280   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8281   DONE;
8285 ;; Reload sometimes tries to move the address to a GPR, and can generate
8286 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8287 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8289 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8290   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8291         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8292                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8293                (const_int -16)))]
8294   "TARGET_ALTIVEC && reload_completed"
8295   "#"
8296   "&& reload_completed"
8297   [(set (match_dup 0)
8298         (plus:P (match_dup 1)
8299                 (match_dup 2)))
8300    (set (match_dup 0)
8301         (and:P (match_dup 0)
8302                (const_int -16)))])
8304 ;; Power8 merge instructions to allow direct move to/from floating point
8305 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8306 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8307 ;; value, since it is allocated in reload and not all of the flow information
8308 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8309 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8310 ;; schedule other instructions between the two instructions.
8312 (define_insn "p8_fmrgow_<mode>"
8313   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8314         (unspec:FMOVE64X [
8315                 (match_operand:DF 1 "register_operand" "d")
8316                 (match_operand:DF 2 "register_operand" "d")]
8317                          UNSPEC_P8V_FMRGOW))]
8318   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8319   "fmrgow %0,%1,%2"
8320   [(set_attr "type" "fpsimple")])
8322 (define_insn "p8_mtvsrwz"
8323   [(set (match_operand:DF 0 "register_operand" "=d")
8324         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8325                    UNSPEC_P8V_MTVSRWZ))]
8326   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8327   "mtvsrwz %x0,%1"
8328   [(set_attr "type" "mftgpr")])
8330 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8331   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8332         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8333                          UNSPEC_P8V_RELOAD_FROM_GPR))
8334    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8335   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8336   "#"
8337   "&& reload_completed"
8338   [(const_int 0)]
8340   rtx dest = operands[0];
8341   rtx src = operands[1];
8342   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8343   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8344   rtx gpr_hi_reg = gen_highpart (SImode, src);
8345   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8347   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8348   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8349   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8350   DONE;
8352   [(set_attr "length" "12")
8353    (set_attr "type" "three")])
8355 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8356 (define_insn "p8_mtvsrd_df"
8357   [(set (match_operand:DF 0 "register_operand" "=wa")
8358         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8359                    UNSPEC_P8V_MTVSRD))]
8360   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8361   "mtvsrd %x0,%1"
8362   [(set_attr "type" "mftgpr")])
8364 (define_insn "p8_xxpermdi_<mode>"
8365   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8366         (unspec:FMOVE128_GPR [
8367                 (match_operand:DF 1 "register_operand" "wa")
8368                 (match_operand:DF 2 "register_operand" "wa")]
8369                 UNSPEC_P8V_XXPERMDI))]
8370   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8371   "xxpermdi %x0,%x1,%x2,0"
8372   [(set_attr "type" "vecperm")])
8374 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8375   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8376         (unspec:FMOVE128_GPR
8377          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8378          UNSPEC_P8V_RELOAD_FROM_GPR))
8379    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8380   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8381   "#"
8382   "&& reload_completed"
8383   [(const_int 0)]
8385   rtx dest = operands[0];
8386   rtx src = operands[1];
8387   /* You might think that we could use op0 as one temp and a DF clobber
8388      as op2, but you'd be wrong.  Secondary reload move patterns don't
8389      check for overlap of the clobber and the destination.  */
8390   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8391   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8392   rtx gpr_hi_reg = gen_highpart (DImode, src);
8393   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8395   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8396   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8397   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8398   DONE;
8400   [(set_attr "length" "12")
8401    (set_attr "type" "three")])
8403 (define_split
8404   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8405         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8406   "reload_completed
8407    && (int_reg_operand (operands[0], <MODE>mode)
8408        || int_reg_operand (operands[1], <MODE>mode))
8409    && (!TARGET_DIRECT_MOVE_128
8410        || (!vsx_register_operand (operands[0], <MODE>mode)
8411            && !vsx_register_operand (operands[1], <MODE>mode)))"
8412   [(pc)]
8413 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8415 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8416 ;; type is stored internally as double precision in the VSX registers, we have
8417 ;; to convert it from the vector format.
8418 (define_insn "p8_mtvsrd_sf"
8419   [(set (match_operand:SF 0 "register_operand" "=wa")
8420         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8421                    UNSPEC_P8V_MTVSRD))]
8422   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8423   "mtvsrd %x0,%1"
8424   [(set_attr "type" "mftgpr")])
8426 (define_insn_and_split "reload_vsx_from_gprsf"
8427   [(set (match_operand:SF 0 "register_operand" "=wa")
8428         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8429                    UNSPEC_P8V_RELOAD_FROM_GPR))
8430    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8431   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8432   "#"
8433   "&& reload_completed"
8434   [(const_int 0)]
8436   rtx op0 = operands[0];
8437   rtx op1 = operands[1];
8438   rtx op2 = operands[2];
8439   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8441   /* Move SF value to upper 32-bits for xscvspdpn.  */
8442   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8443   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8444   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8445   DONE;
8447   [(set_attr "length" "8")
8448    (set_attr "type" "two")])
8450 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8451 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8452 ;; and then doing a move of that.
8453 (define_insn "p8_mfvsrd_3_<mode>"
8454   [(set (match_operand:DF 0 "register_operand" "=r")
8455         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8456                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8457   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8458   "mfvsrd %0,%x1"
8459   [(set_attr "type" "mftgpr")])
8461 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8462   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8463         (unspec:FMOVE128_GPR
8464          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8465          UNSPEC_P8V_RELOAD_FROM_VSX))
8466    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8467   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8468   "#"
8469   "&& reload_completed"
8470   [(const_int 0)]
8472   rtx dest = operands[0];
8473   rtx src = operands[1];
8474   rtx tmp = operands[2];
8475   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8476   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8478   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8479   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8480   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8481   DONE;
8483   [(set_attr "length" "12")
8484    (set_attr "type" "three")])
8486 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8487 ;; type is stored internally as double precision, we have to convert it to the
8488 ;; vector format.
8490 (define_insn_and_split "reload_gpr_from_vsxsf"
8491   [(set (match_operand:SF 0 "register_operand" "=r")
8492         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8493                    UNSPEC_P8V_RELOAD_FROM_VSX))
8494    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8495   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8496   "#"
8497   "&& reload_completed"
8498   [(const_int 0)]
8500   rtx op0 = operands[0];
8501   rtx op1 = operands[1];
8502   rtx op2 = operands[2];
8503   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8504   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8506   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8507   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8508   DONE;
8510   [(set_attr "length" "8")
8511    (set_attr "type" "two")])
8514 ;; Next come the multi-word integer load and store and the load and store
8515 ;; multiple insns.
8517 ;; List r->r after r->Y, otherwise reload will try to reload a
8518 ;; non-offsettable address by using r->r which won't make progress.
8519 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8520 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8522 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8523 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8524 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8525 ;;        AVX const  
8527 (define_insn "*movdi_internal32"
8528   [(set (match_operand:DI 0 "nonimmediate_operand"
8529          "=Y,        r,         r,         m,         ^d,         ^d,
8530           r,         wY,        Z,         ^wb,       $wv,        ^wi,
8531           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8532           *wv")
8534         (match_operand:DI 1 "input_operand"
8535          "r,         Y,         r,         ^d,        m,          ^d,
8536           IJKnGHF,   ^wb,       $wv,       wY,        Z,          ^wi,
8537           Oj,        wM,        OjwM,      Oj,        wM,         wS,
8538           wB"))]
8540   "! TARGET_POWERPC64
8541    && (gpc_reg_operand (operands[0], DImode)
8542        || gpc_reg_operand (operands[1], DImode))"
8543   "@
8544    #
8545    #
8546    #
8547    stfd%U0%X0 %1,%0
8548    lfd%U1%X1 %0,%1
8549    fmr %0,%1
8550    #
8551    stxsd %1,%0
8552    stxsdx %x1,%y0
8553    lxsd %0,%1
8554    lxsdx %x0,%y1
8555    xxlor %x0,%x1,%x1
8556    xxspltib %x0,0
8557    xxspltib %x0,255
8558    vspltisw %0,%1
8559    xxlxor %x0,%x0,%x0
8560    xxlorc %x0,%x0,%x0
8561    #
8562    #"
8563   [(set_attr "type"
8564                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8565                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8566                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8567                 vecsimple")
8568    (set_attr "size" "64")])
8570 (define_split
8571   [(set (match_operand:DI 0 "gpc_reg_operand")
8572         (match_operand:DI 1 "const_int_operand"))]
8573   "! TARGET_POWERPC64 && reload_completed
8574    && gpr_or_gpr_p (operands[0], operands[1])
8575    && !direct_move_p (operands[0], operands[1])"
8576   [(set (match_dup 2) (match_dup 4))
8577    (set (match_dup 3) (match_dup 1))]
8579   HOST_WIDE_INT value = INTVAL (operands[1]);
8580   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8581                                        DImode);
8582   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8583                                        DImode);
8584   operands[4] = GEN_INT (value >> 32);
8585   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8588 (define_split
8589   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8590         (match_operand:DIFD 1 "input_operand"))]
8591   "reload_completed && !TARGET_POWERPC64
8592    && gpr_or_gpr_p (operands[0], operands[1])
8593    && !direct_move_p (operands[0], operands[1])"
8594   [(pc)]
8595 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8597 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8598 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8599 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8600 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8601 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8602 (define_insn "*movdi_internal64"
8603   [(set (match_operand:DI 0 "nonimmediate_operand"
8604                "=YZ,       r,         r,         r,         r,          r,
8605                 m,         ^d,        ^d,        wY,        Z,          $wb,
8606                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8607                 *wi,       *wv,       *wv,       r,         *h,         *h,
8608                 ?*r,       ?*wg,      ?*r,       ?*wj")
8610         (match_operand:DI 1 "input_operand"
8611                "r,         YZ,        r,         I,         L,          nF,
8612                 ^d,        m,         ^d,        ^wb,       $wv,        wY,
8613                 Z,         ^wi,       Oj,        wM,        OjwM,       Oj,
8614                 wM,        wS,        wB,        *h,        r,          0,
8615                 wg,        r,         wj,        r"))]
8617   "TARGET_POWERPC64
8618    && (gpc_reg_operand (operands[0], DImode)
8619        || gpc_reg_operand (operands[1], DImode))"
8620   "@
8621    std%U0%X0 %1,%0
8622    ld%U1%X1 %0,%1
8623    mr %0,%1
8624    li %0,%1
8625    lis %0,%v1
8626    #
8627    stfd%U0%X0 %1,%0
8628    lfd%U1%X1 %0,%1
8629    fmr %0,%1
8630    stxsd %1,%0
8631    stxsdx %x1,%y0
8632    lxsd %0,%1
8633    lxsdx %x0,%y1
8634    xxlor %x0,%x1,%x1
8635    xxspltib %x0,0
8636    xxspltib %x0,255
8637    #
8638    xxlxor %x0,%x0,%x0
8639    xxlorc %x0,%x0,%x0
8640    #
8641    #
8642    mf%1 %0
8643    mt%0 %1
8644    nop
8645    mftgpr %0,%1
8646    mffgpr %0,%1
8647    mfvsrd %0,%x1
8648    mtvsrd %x0,%1"
8649   [(set_attr "type"
8650                "store,      load,       *,         *,         *,         *,
8651                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8652                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8653                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8654                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8656    (set_attr "size" "64")
8657    (set_attr "length"
8658                "4,         4,         4,         4,         4,          20,
8659                 4,         4,         4,         4,         4,          4,
8660                 4,         4,         4,         4,         4,          8,
8661                 8,         4,         4,         4,         4,          4,
8662                 4,         4,         4,         4")])
8664 ; Some DImode loads are best done as a load of -1 followed by a mask
8665 ; instruction.
8666 (define_split
8667   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8668         (match_operand:DI 1 "const_int_operand"))]
8669   "TARGET_POWERPC64
8670    && num_insns_constant (operands[1], DImode) > 1
8671    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8672    && rs6000_is_valid_and_mask (operands[1], DImode)"
8673   [(set (match_dup 0)
8674         (const_int -1))
8675    (set (match_dup 0)
8676         (and:DI (match_dup 0)
8677                 (match_dup 1)))]
8678   "")
8680 ;; Split a load of a large constant into the appropriate five-instruction
8681 ;; sequence.  Handle anything in a constant number of insns.
8682 ;; When non-easy constants can go in the TOC, this should use
8683 ;; easy_fp_constant predicate.
8684 (define_split
8685   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8686         (match_operand:DI 1 "const_int_operand"))]
8687   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8688   [(set (match_dup 0) (match_dup 2))
8689    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8691   if (rs6000_emit_set_const (operands[0], operands[1]))
8692     DONE;
8693   else
8694     FAIL;
8697 (define_split
8698   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8699         (match_operand:DI 1 "const_scalar_int_operand"))]
8700   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8701   [(set (match_dup 0) (match_dup 2))
8702    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8704   if (rs6000_emit_set_const (operands[0], operands[1]))
8705     DONE;
8706   else
8707     FAIL;
8710 (define_split
8711   [(set (match_operand:DI 0 "altivec_register_operand")
8712         (match_operand:DI 1 "s5bit_cint_operand"))]
8713   "TARGET_VSX && reload_completed"
8714   [(const_int 0)]
8716   rtx op0 = operands[0];
8717   rtx op1 = operands[1];
8718   int r = REGNO (op0);
8719   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8721   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8722   if (op1 != const0_rtx && op1 != constm1_rtx)
8723     {
8724       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8725       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8726     }
8727   DONE;
8730 ;; Split integer constants that can be loaded with XXSPLTIB and a
8731 ;; sign extend operation.
8732 (define_split
8733   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8734         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8735   "TARGET_P9_VECTOR && reload_completed"
8736   [(const_int 0)]
8738   rtx op0 = operands[0];
8739   rtx op1 = operands[1];
8740   int r = REGNO (op0);
8741   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8743   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8744   if (<MODE>mode == DImode)
8745     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8746   else if (<MODE>mode == SImode)
8747     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8748   else if (<MODE>mode == HImode)
8749     {
8750       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8751       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8752     }
8753   DONE;
8757 ;; TImode/PTImode is similar, except that we usually want to compute the
8758 ;; address into a register and use lsi/stsi (the exception is during reload).
8760 (define_insn "*mov<mode>_string"
8761   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8762         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8763   "! TARGET_POWERPC64
8764    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8765    && (gpc_reg_operand (operands[0], <MODE>mode)
8766        || gpc_reg_operand (operands[1], <MODE>mode))"
8767   "#"
8768   [(set_attr "type" "store,store,load,load,*,*")
8769    (set_attr "update" "yes")
8770    (set_attr "indexed" "yes")
8771    (set_attr "cell_micro" "conditional")])
8773 (define_insn "*mov<mode>_ppc64"
8774   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8775         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8776   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8777    && (gpc_reg_operand (operands[0], <MODE>mode)
8778        || gpc_reg_operand (operands[1], <MODE>mode)))"
8780   return rs6000_output_move_128bit (operands);
8782   [(set_attr "type" "store,store,load,load,*,*")
8783    (set_attr "length" "8")])
8785 (define_split
8786   [(set (match_operand:TI2 0 "int_reg_operand")
8787         (match_operand:TI2 1 "const_scalar_int_operand"))]
8788   "TARGET_POWERPC64
8789    && (VECTOR_MEM_NONE_P (<MODE>mode)
8790        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8791   [(set (match_dup 2) (match_dup 4))
8792    (set (match_dup 3) (match_dup 5))]
8794   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8795                                        <MODE>mode);
8796   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8797                                        <MODE>mode);
8798   if (CONST_WIDE_INT_P (operands[1]))
8799     {
8800       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8801       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8802     }
8803   else if (CONST_INT_P (operands[1]))
8804     {
8805       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8806       operands[5] = operands[1];
8807     }
8808   else
8809     FAIL;
8812 (define_split
8813   [(set (match_operand:TI2 0 "nonimmediate_operand")
8814         (match_operand:TI2 1 "input_operand"))]
8815   "reload_completed
8816    && gpr_or_gpr_p (operands[0], operands[1])
8817    && !direct_move_p (operands[0], operands[1])
8818    && !quad_load_store_p (operands[0], operands[1])"
8819   [(pc)]
8820 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8822 (define_expand "setmemsi"
8823   [(parallel [(set (match_operand:BLK 0 "")
8824                    (match_operand 2 "const_int_operand"))
8825               (use (match_operand:SI 1 ""))
8826               (use (match_operand:SI 3 ""))])]
8827   ""
8829   /* If value to set is not zero, use the library routine.  */
8830   if (operands[2] != const0_rtx)
8831     FAIL;
8833   if (expand_block_clear (operands))
8834     DONE;
8835   else
8836     FAIL;
8839 ;; String compare N insn.
8840 ;; Argument 0 is the target (result)
8841 ;; Argument 1 is the destination
8842 ;; Argument 2 is the source
8843 ;; Argument 3 is the length
8844 ;; Argument 4 is the alignment
8846 (define_expand "cmpstrnsi"
8847   [(parallel [(set (match_operand:SI 0)
8848                (compare:SI (match_operand:BLK 1)
8849                            (match_operand:BLK 2)))
8850               (use (match_operand:SI 3))
8851               (use (match_operand:SI 4))])]
8852   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8854   if (optimize_insn_for_size_p ())
8855     FAIL;
8857   if (expand_strn_compare (operands, 0))
8858     DONE;
8859   else  
8860     FAIL;
8863 ;; String compare insn.
8864 ;; Argument 0 is the target (result)
8865 ;; Argument 1 is the destination
8866 ;; Argument 2 is the source
8867 ;; Argument 3 is the alignment
8869 (define_expand "cmpstrsi"
8870   [(parallel [(set (match_operand:SI 0)
8871                (compare:SI (match_operand:BLK 1)
8872                            (match_operand:BLK 2)))
8873               (use (match_operand:SI 3))])]
8874   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8876   if (optimize_insn_for_size_p ())
8877     FAIL;
8879   if (expand_strn_compare (operands, 1))
8880     DONE;
8881   else  
8882     FAIL;
8885 ;; Block compare insn.
8886 ;; Argument 0 is the target (result)
8887 ;; Argument 1 is the destination
8888 ;; Argument 2 is the source
8889 ;; Argument 3 is the length
8890 ;; Argument 4 is the alignment
8892 (define_expand "cmpmemsi"
8893   [(parallel [(set (match_operand:SI 0)
8894                (compare:SI (match_operand:BLK 1)
8895                            (match_operand:BLK 2)))
8896               (use (match_operand:SI 3))
8897               (use (match_operand:SI 4))])]
8898   "TARGET_POPCNTD"
8900   if (expand_block_compare (operands))
8901     DONE;
8902   else
8903     FAIL;
8906 ;; String/block move insn.
8907 ;; Argument 0 is the destination
8908 ;; Argument 1 is the source
8909 ;; Argument 2 is the length
8910 ;; Argument 3 is the alignment
8912 (define_expand "movmemsi"
8913   [(parallel [(set (match_operand:BLK 0 "")
8914                    (match_operand:BLK 1 ""))
8915               (use (match_operand:SI 2 ""))
8916               (use (match_operand:SI 3 ""))])]
8917   ""
8919   if (expand_block_move (operands))
8920     DONE;
8921   else
8922     FAIL;
8925 ;; Define insns that do load or store with update.  Some of these we can
8926 ;; get by using pre-decrement or pre-increment, but the hardware can also
8927 ;; do cases where the increment is not the size of the object.
8929 ;; In all these cases, we use operands 0 and 1 for the register being
8930 ;; incremented because those are the operands that local-alloc will
8931 ;; tie and these are the pair most likely to be tieable (and the ones
8932 ;; that will benefit the most).
8934 (define_insn "*movdi_update1"
8935   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8936         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8937                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8938    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8939         (plus:DI (match_dup 1) (match_dup 2)))]
8940   "TARGET_POWERPC64 && TARGET_UPDATE
8941    && (!avoiding_indexed_address_p (DImode)
8942        || !gpc_reg_operand (operands[2], DImode))"
8943   "@
8944    ldux %3,%0,%2
8945    ldu %3,%2(%0)"
8946   [(set_attr "type" "load")
8947    (set_attr "update" "yes")
8948    (set_attr "indexed" "yes,no")])
8950 (define_insn "movdi_<mode>_update"
8951   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8952                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8953         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8954    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8955         (plus:P (match_dup 1) (match_dup 2)))]
8956   "TARGET_POWERPC64 && TARGET_UPDATE
8957    && (!avoiding_indexed_address_p (Pmode)
8958        || !gpc_reg_operand (operands[2], Pmode)
8959        || (REG_P (operands[0])
8960            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8961   "@
8962    stdux %3,%0,%2
8963    stdu %3,%2(%0)"
8964   [(set_attr "type" "store")
8965    (set_attr "update" "yes")
8966    (set_attr "indexed" "yes,no")])
8968 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8969 ;; needed for stack allocation, even if the user passes -mno-update.
8970 (define_insn "movdi_<mode>_update_stack"
8971   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8972                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8973         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8974    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8975         (plus:P (match_dup 1) (match_dup 2)))]
8976   "TARGET_POWERPC64"
8977   "@
8978    stdux %3,%0,%2
8979    stdu %3,%2(%0)"
8980   [(set_attr "type" "store")
8981    (set_attr "update" "yes")
8982    (set_attr "indexed" "yes,no")])
8984 (define_insn "*movsi_update1"
8985   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8986         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8987                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8988    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8989         (plus:SI (match_dup 1) (match_dup 2)))]
8990   "TARGET_UPDATE
8991    && (!avoiding_indexed_address_p (SImode)
8992        || !gpc_reg_operand (operands[2], SImode))"
8993   "@
8994    lwzux %3,%0,%2
8995    lwzu %3,%2(%0)"
8996   [(set_attr "type" "load")
8997    (set_attr "update" "yes")
8998    (set_attr "indexed" "yes,no")])
9000 (define_insn "*movsi_update2"
9001   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9002         (sign_extend:DI
9003          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9004                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9005    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9006         (plus:DI (match_dup 1) (match_dup 2)))]
9007   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9008   "lwaux %3,%0,%2"
9009   [(set_attr "type" "load")
9010    (set_attr "sign_extend" "yes")
9011    (set_attr "update" "yes")
9012    (set_attr "indexed" "yes")])
9014 (define_insn "movsi_update"
9015   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9016                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9017         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9018    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9019         (plus:SI (match_dup 1) (match_dup 2)))]
9020   "TARGET_UPDATE
9021    && (!avoiding_indexed_address_p (SImode)
9022        || !gpc_reg_operand (operands[2], SImode)
9023        || (REG_P (operands[0])
9024            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9025   "@
9026    stwux %3,%0,%2
9027    stwu %3,%2(%0)"
9028   [(set_attr "type" "store")
9029    (set_attr "update" "yes")
9030    (set_attr "indexed" "yes,no")])
9032 ;; This is an unconditional pattern; needed for stack allocation, even
9033 ;; if the user passes -mno-update.
9034 (define_insn "movsi_update_stack"
9035   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9036                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9037         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9038    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9039         (plus:SI (match_dup 1) (match_dup 2)))]
9040   ""
9041   "@
9042    stwux %3,%0,%2
9043    stwu %3,%2(%0)"
9044   [(set_attr "type" "store")
9045    (set_attr "update" "yes")
9046    (set_attr "indexed" "yes,no")])
9048 (define_insn "*movhi_update1"
9049   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9050         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9051                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9052    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9053         (plus:SI (match_dup 1) (match_dup 2)))]
9054   "TARGET_UPDATE
9055    && (!avoiding_indexed_address_p (SImode)
9056        || !gpc_reg_operand (operands[2], SImode))"
9057   "@
9058    lhzux %3,%0,%2
9059    lhzu %3,%2(%0)"
9060   [(set_attr "type" "load")
9061    (set_attr "update" "yes")
9062    (set_attr "indexed" "yes,no")])
9064 (define_insn "*movhi_update2"
9065   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9066         (zero_extend:SI
9067          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9068                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9069    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9070         (plus:SI (match_dup 1) (match_dup 2)))]
9071   "TARGET_UPDATE
9072    && (!avoiding_indexed_address_p (SImode)
9073        || !gpc_reg_operand (operands[2], SImode))"
9074   "@
9075    lhzux %3,%0,%2
9076    lhzu %3,%2(%0)"
9077   [(set_attr "type" "load")
9078    (set_attr "update" "yes")
9079    (set_attr "indexed" "yes,no")])
9081 (define_insn "*movhi_update3"
9082   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9083         (sign_extend:SI
9084          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9085                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9086    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9087         (plus:SI (match_dup 1) (match_dup 2)))]
9088   "TARGET_UPDATE
9089    && !(avoiding_indexed_address_p (SImode)
9090         && gpc_reg_operand (operands[2], SImode))"
9091   "@
9092    lhaux %3,%0,%2
9093    lhau %3,%2(%0)"
9094   [(set_attr "type" "load")
9095    (set_attr "sign_extend" "yes")
9096    (set_attr "update" "yes")
9097    (set_attr "indexed" "yes,no")])
9099 (define_insn "*movhi_update4"
9100   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9101                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9102         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9103    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9104         (plus:SI (match_dup 1) (match_dup 2)))]
9105   "TARGET_UPDATE
9106    && (!avoiding_indexed_address_p (SImode)
9107        || !gpc_reg_operand (operands[2], SImode))"
9108   "@
9109    sthux %3,%0,%2
9110    sthu %3,%2(%0)"
9111   [(set_attr "type" "store")
9112    (set_attr "update" "yes")
9113    (set_attr "indexed" "yes,no")])
9115 (define_insn "*movqi_update1"
9116   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9117         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9118                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9119    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9120         (plus:SI (match_dup 1) (match_dup 2)))]
9121   "TARGET_UPDATE
9122    && (!avoiding_indexed_address_p (SImode)
9123        || !gpc_reg_operand (operands[2], SImode))"
9124   "@
9125    lbzux %3,%0,%2
9126    lbzu %3,%2(%0)"
9127   [(set_attr "type" "load")
9128    (set_attr "update" "yes")
9129    (set_attr "indexed" "yes,no")])
9131 (define_insn "*movqi_update2"
9132   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9133         (zero_extend:SI
9134          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9135                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9136    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9137         (plus:SI (match_dup 1) (match_dup 2)))]
9138   "TARGET_UPDATE
9139    && (!avoiding_indexed_address_p (SImode)
9140        || !gpc_reg_operand (operands[2], SImode))"
9141   "@
9142    lbzux %3,%0,%2
9143    lbzu %3,%2(%0)"
9144   [(set_attr "type" "load")
9145    (set_attr "update" "yes")
9146    (set_attr "indexed" "yes,no")])
9148 (define_insn "*movqi_update3"
9149   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9150                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9151         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9152    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9153         (plus:SI (match_dup 1) (match_dup 2)))]
9154   "TARGET_UPDATE
9155    && (!avoiding_indexed_address_p (SImode)
9156        || !gpc_reg_operand (operands[2], SImode))"
9157   "@
9158    stbux %3,%0,%2
9159    stbu %3,%2(%0)"
9160   [(set_attr "type" "store")
9161    (set_attr "update" "yes")
9162    (set_attr "indexed" "yes,no")])
9164 (define_insn "*movsf_update1"
9165   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9166         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9167                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9168    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9169         (plus:SI (match_dup 1) (match_dup 2)))]
9170   "TARGET_HARD_FLOAT && TARGET_UPDATE
9171    && (!avoiding_indexed_address_p (SImode)
9172        || !gpc_reg_operand (operands[2], SImode))"
9173   "@
9174    lfsux %3,%0,%2
9175    lfsu %3,%2(%0)"
9176   [(set_attr "type" "fpload")
9177    (set_attr "update" "yes")
9178    (set_attr "indexed" "yes,no")])
9180 (define_insn "*movsf_update2"
9181   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9182                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9183         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9184    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9185         (plus:SI (match_dup 1) (match_dup 2)))]
9186   "TARGET_HARD_FLOAT && TARGET_UPDATE
9187    && (!avoiding_indexed_address_p (SImode)
9188        || !gpc_reg_operand (operands[2], SImode))"
9189   "@
9190    stfsux %3,%0,%2
9191    stfsu %3,%2(%0)"
9192   [(set_attr "type" "fpstore")
9193    (set_attr "update" "yes")
9194    (set_attr "indexed" "yes,no")])
9196 (define_insn "*movsf_update3"
9197   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9198         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9199                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9200    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9201         (plus:SI (match_dup 1) (match_dup 2)))]
9202   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9203    && (!avoiding_indexed_address_p (SImode)
9204        || !gpc_reg_operand (operands[2], SImode))"
9205   "@
9206    lwzux %3,%0,%2
9207    lwzu %3,%2(%0)"
9208   [(set_attr "type" "load")
9209    (set_attr "update" "yes")
9210    (set_attr "indexed" "yes,no")])
9212 (define_insn "*movsf_update4"
9213   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9214                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9215         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9216    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9217         (plus:SI (match_dup 1) (match_dup 2)))]
9218   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9219    && (!avoiding_indexed_address_p (SImode)
9220        || !gpc_reg_operand (operands[2], SImode))"
9221   "@
9222    stwux %3,%0,%2
9223    stwu %3,%2(%0)"
9224   [(set_attr "type" "store")
9225    (set_attr "update" "yes")
9226    (set_attr "indexed" "yes,no")])
9228 (define_insn "*movdf_update1"
9229   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9230         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9231                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9232    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9233         (plus:SI (match_dup 1) (match_dup 2)))]
9234   "TARGET_HARD_FLOAT && TARGET_UPDATE
9235    && (!avoiding_indexed_address_p (SImode)
9236        || !gpc_reg_operand (operands[2], SImode))"
9237   "@
9238    lfdux %3,%0,%2
9239    lfdu %3,%2(%0)"
9240   [(set_attr "type" "fpload")
9241    (set_attr "update" "yes")
9242    (set_attr "indexed" "yes,no")
9243    (set_attr "size" "64")])
9245 (define_insn "*movdf_update2"
9246   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9247                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9248         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9249    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9250         (plus:SI (match_dup 1) (match_dup 2)))]
9251   "TARGET_HARD_FLOAT && TARGET_UPDATE
9252    && (!avoiding_indexed_address_p (SImode)
9253        || !gpc_reg_operand (operands[2], SImode))"
9254   "@
9255    stfdux %3,%0,%2
9256    stfdu %3,%2(%0)"
9257   [(set_attr "type" "fpstore")
9258    (set_attr "update" "yes")
9259    (set_attr "indexed" "yes,no")])
9262 ;; After inserting conditional returns we can sometimes have
9263 ;; unnecessary register moves.  Unfortunately we cannot have a
9264 ;; modeless peephole here, because some single SImode sets have early
9265 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9266 ;; sequences, using get_attr_length here will smash the operands
9267 ;; array.  Neither is there an early_cobbler_p predicate.
9268 ;; Also this optimization interferes with scalars going into
9269 ;; altivec registers (the code does reloading through the FPRs).
9270 (define_peephole2
9271   [(set (match_operand:DF 0 "gpc_reg_operand")
9272         (match_operand:DF 1 "any_operand"))
9273    (set (match_operand:DF 2 "gpc_reg_operand")
9274         (match_dup 0))]
9275   "!TARGET_VSX
9276    && peep2_reg_dead_p (2, operands[0])"
9277   [(set (match_dup 2) (match_dup 1))])
9279 (define_peephole2
9280   [(set (match_operand:SF 0 "gpc_reg_operand")
9281         (match_operand:SF 1 "any_operand"))
9282    (set (match_operand:SF 2 "gpc_reg_operand")
9283         (match_dup 0))]
9284   "!TARGET_P8_VECTOR
9285    && peep2_reg_dead_p (2, operands[0])"
9286   [(set (match_dup 2) (match_dup 1))])
9289 ;; TLS support.
9291 ;; Mode attributes for different ABIs.
9292 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9293 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9294 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9295 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9297 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9298   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9299         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9300               (match_operand 4 "" "g")))
9301    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9302                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9303                    UNSPEC_TLSGD)
9304    (clobber (reg:SI LR_REGNO))]
9305   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9307   if (TARGET_CMODEL != CMODEL_SMALL)
9308     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9309            "bl %z3\;nop";
9310   else
9311     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9313   "&& TARGET_TLS_MARKERS"
9314   [(set (match_dup 0)
9315         (unspec:TLSmode [(match_dup 1)
9316                          (match_dup 2)]
9317                         UNSPEC_TLSGD))
9318    (parallel [(set (match_dup 0)
9319                    (call (mem:TLSmode (match_dup 3))
9320                          (match_dup 4)))
9321               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9322               (clobber (reg:SI LR_REGNO))])]
9323   ""
9324   [(set_attr "type" "two")
9325    (set (attr "length")
9326      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9327                    (const_int 16)
9328                    (const_int 12)))])
9330 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9331   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9332         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9333               (match_operand 4 "" "g")))
9334    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9335                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9336                    UNSPEC_TLSGD)
9337    (clobber (reg:SI LR_REGNO))]
9338   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9340   if (flag_pic)
9341     {
9342       if (TARGET_SECURE_PLT && flag_pic == 2)
9343         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9344       else
9345         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9346     }
9347   else
9348     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9350   "&& TARGET_TLS_MARKERS"
9351   [(set (match_dup 0)
9352         (unspec:TLSmode [(match_dup 1)
9353                          (match_dup 2)]
9354                         UNSPEC_TLSGD))
9355    (parallel [(set (match_dup 0)
9356                    (call (mem:TLSmode (match_dup 3))
9357                          (match_dup 4)))
9358               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9359               (clobber (reg:SI LR_REGNO))])]
9360   ""
9361   [(set_attr "type" "two")
9362    (set_attr "length" "8")])
9364 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9365   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9366         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9367                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9368                         UNSPEC_TLSGD))]
9369   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9370   "addi %0,%1,%2@got@tlsgd"
9371   "&& TARGET_CMODEL != CMODEL_SMALL"
9372   [(set (match_dup 3)
9373         (high:TLSmode
9374             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9375    (set (match_dup 0)
9376         (lo_sum:TLSmode (match_dup 3)
9377             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9379   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9381   [(set (attr "length")
9382      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9383                    (const_int 8)
9384                    (const_int 4)))])
9386 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9387   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9388      (high:TLSmode
9389        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9390                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9391                        UNSPEC_TLSGD)))]
9392   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9393   "addis %0,%1,%2@got@tlsgd@ha"
9394   [(set_attr "length" "4")])
9396 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9397   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9398      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9399        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9400                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9401                        UNSPEC_TLSGD)))]
9402   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9403   "addi %0,%1,%2@got@tlsgd@l"
9404   [(set_attr "length" "4")])
9406 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9407   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9408         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9409               (match_operand 2 "" "g")))
9410    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9411                    UNSPEC_TLSGD)
9412    (clobber (reg:SI LR_REGNO))]
9413   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9414    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9415   "bl %z1(%3@tlsgd)\;nop"
9416   [(set_attr "type" "branch")
9417    (set_attr "length" "8")])
9419 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9420   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9421         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9422               (match_operand 2 "" "g")))
9423    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9424                    UNSPEC_TLSGD)
9425    (clobber (reg:SI LR_REGNO))]
9426   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9428   if (flag_pic)
9429     {
9430       if (TARGET_SECURE_PLT && flag_pic == 2)
9431         return "bl %z1+32768(%3@tlsgd)@plt";
9432       return "bl %z1(%3@tlsgd)@plt";
9433     }
9434   return "bl %z1(%3@tlsgd)";
9436   [(set_attr "type" "branch")
9437    (set_attr "length" "4")])
9439 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9440   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9441         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9442               (match_operand 3 "" "g")))
9443    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9444                    UNSPEC_TLSLD)
9445    (clobber (reg:SI LR_REGNO))]
9446   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9448   if (TARGET_CMODEL != CMODEL_SMALL)
9449     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9450            "bl %z2\;nop";
9451   else
9452     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9454   "&& TARGET_TLS_MARKERS"
9455   [(set (match_dup 0)
9456         (unspec:TLSmode [(match_dup 1)]
9457                         UNSPEC_TLSLD))
9458    (parallel [(set (match_dup 0)
9459                    (call (mem:TLSmode (match_dup 2))
9460                          (match_dup 3)))
9461               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9462               (clobber (reg:SI LR_REGNO))])]
9463   ""
9464   [(set_attr "type" "two")
9465    (set (attr "length")
9466      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9467                    (const_int 16)
9468                    (const_int 12)))])
9470 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9471   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9472         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9473               (match_operand 3 "" "g")))
9474    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9475                    UNSPEC_TLSLD)
9476    (clobber (reg:SI LR_REGNO))]
9477   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9479   if (flag_pic)
9480     {
9481       if (TARGET_SECURE_PLT && flag_pic == 2)
9482         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9483       else
9484         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9485     }
9486   else
9487     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9489   "&& TARGET_TLS_MARKERS"
9490   [(set (match_dup 0)
9491         (unspec:TLSmode [(match_dup 1)]
9492                         UNSPEC_TLSLD))
9493    (parallel [(set (match_dup 0)
9494                    (call (mem:TLSmode (match_dup 2))
9495                          (match_dup 3)))
9496               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9497               (clobber (reg:SI LR_REGNO))])]
9498   ""
9499   [(set_attr "length" "8")])
9501 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9502   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9503         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9504                         UNSPEC_TLSLD))]
9505   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9506   "addi %0,%1,%&@got@tlsld"
9507   "&& TARGET_CMODEL != CMODEL_SMALL"
9508   [(set (match_dup 2)
9509         (high:TLSmode
9510             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9511    (set (match_dup 0)
9512         (lo_sum:TLSmode (match_dup 2)
9513             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9515   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9517   [(set (attr "length")
9518      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9519                    (const_int 8)
9520                    (const_int 4)))])
9522 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9523   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9524      (high:TLSmode
9525        (unspec:TLSmode [(const_int 0)
9526                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9527                        UNSPEC_TLSLD)))]
9528   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9529   "addis %0,%1,%&@got@tlsld@ha"
9530   [(set_attr "length" "4")])
9532 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9533   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9535        (unspec:TLSmode [(const_int 0)
9536                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9537                        UNSPEC_TLSLD)))]
9538   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9539   "addi %0,%1,%&@got@tlsld@l"
9540   [(set_attr "length" "4")])
9542 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9543   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9544         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9545               (match_operand 2 "" "g")))
9546    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9547    (clobber (reg:SI LR_REGNO))]
9548   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9549    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9550   "bl %z1(%&@tlsld)\;nop"
9551   [(set_attr "type" "branch")
9552    (set_attr "length" "8")])
9554 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9555   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9556         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9557               (match_operand 2 "" "g")))
9558    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9559    (clobber (reg:SI LR_REGNO))]
9560   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9562   if (flag_pic)
9563     {
9564       if (TARGET_SECURE_PLT && flag_pic == 2)
9565         return "bl %z1+32768(%&@tlsld)@plt";
9566       return "bl %z1(%&@tlsld)@plt";
9567     }
9568   return "bl %z1(%&@tlsld)";
9570   [(set_attr "type" "branch")
9571    (set_attr "length" "4")])
9573 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9574   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9575         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9576                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9577                         UNSPEC_TLSDTPREL))]
9578   "HAVE_AS_TLS"
9579   "addi %0,%1,%2@dtprel")
9581 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9582   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9583         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9584                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9585                         UNSPEC_TLSDTPRELHA))]
9586   "HAVE_AS_TLS"
9587   "addis %0,%1,%2@dtprel@ha")
9589 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9590   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9591         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9592                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9593                         UNSPEC_TLSDTPRELLO))]
9594   "HAVE_AS_TLS"
9595   "addi %0,%1,%2@dtprel@l")
9597 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9598   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9599         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9600                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9601                         UNSPEC_TLSGOTDTPREL))]
9602   "HAVE_AS_TLS"
9603   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9604   "&& TARGET_CMODEL != CMODEL_SMALL"
9605   [(set (match_dup 3)
9606         (high:TLSmode
9607             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9608    (set (match_dup 0)
9609         (lo_sum:TLSmode (match_dup 3)
9610             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9612   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9614   [(set (attr "length")
9615      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9616                    (const_int 8)
9617                    (const_int 4)))])
9619 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9620   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9621      (high:TLSmode
9622        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9623                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9624                        UNSPEC_TLSGOTDTPREL)))]
9625   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9626   "addis %0,%1,%2@got@dtprel@ha"
9627   [(set_attr "length" "4")])
9629 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9630   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9631      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9632          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9633                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9634                          UNSPEC_TLSGOTDTPREL)))]
9635   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9636   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9637   [(set_attr "length" "4")])
9639 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9640   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9641         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9642                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9643                         UNSPEC_TLSTPREL))]
9644   "HAVE_AS_TLS"
9645   "addi %0,%1,%2@tprel")
9647 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9648   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9649         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9650                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9651                         UNSPEC_TLSTPRELHA))]
9652   "HAVE_AS_TLS"
9653   "addis %0,%1,%2@tprel@ha")
9655 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9656   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9657         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9658                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9659                         UNSPEC_TLSTPRELLO))]
9660   "HAVE_AS_TLS"
9661   "addi %0,%1,%2@tprel@l")
9663 ;; "b" output constraint here and on tls_tls input to support linker tls
9664 ;; optimization.  The linker may edit the instructions emitted by a
9665 ;; tls_got_tprel/tls_tls pair to addis,addi.
9666 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9667   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9668         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9669                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9670                         UNSPEC_TLSGOTTPREL))]
9671   "HAVE_AS_TLS"
9672   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9673   "&& TARGET_CMODEL != CMODEL_SMALL"
9674   [(set (match_dup 3)
9675         (high:TLSmode
9676             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9677    (set (match_dup 0)
9678         (lo_sum:TLSmode (match_dup 3)
9679             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9681   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9683   [(set (attr "length")
9684      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9685                    (const_int 8)
9686                    (const_int 4)))])
9688 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9689   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9690      (high:TLSmode
9691        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9692                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9693                        UNSPEC_TLSGOTTPREL)))]
9694   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9695   "addis %0,%1,%2@got@tprel@ha"
9696   [(set_attr "length" "4")])
9698 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9699   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9700      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9701          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9702                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9703                          UNSPEC_TLSGOTTPREL)))]
9704   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9705   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9706   [(set_attr "length" "4")])
9708 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9709   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9710         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9711                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9712                         UNSPEC_TLSTLS))]
9713   "TARGET_ELF && HAVE_AS_TLS"
9714   "add %0,%1,%2@tls")
9716 (define_expand "tls_get_tpointer"
9717   [(set (match_operand:SI 0 "gpc_reg_operand")
9718         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9719   "TARGET_XCOFF && HAVE_AS_TLS"
9721   emit_insn (gen_tls_get_tpointer_internal ());
9722   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9723   DONE;
9726 (define_insn "tls_get_tpointer_internal"
9727   [(set (reg:SI 3)
9728         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9729    (clobber (reg:SI LR_REGNO))]
9730   "TARGET_XCOFF && HAVE_AS_TLS"
9731   "bla __get_tpointer")
9733 (define_expand "tls_get_addr<mode>"
9734   [(set (match_operand:P 0 "gpc_reg_operand")
9735         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9736                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9737   "TARGET_XCOFF && HAVE_AS_TLS"
9739   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9740   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9741   emit_insn (gen_tls_get_addr_internal<mode> ());
9742   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9743   DONE;
9746 (define_insn "tls_get_addr_internal<mode>"
9747   [(set (reg:P 3)
9748         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9749    (clobber (reg:P 0))
9750    (clobber (reg:P 4))
9751    (clobber (reg:P 5))
9752    (clobber (reg:P 11))
9753    (clobber (reg:CC CR0_REGNO))
9754    (clobber (reg:P LR_REGNO))]
9755   "TARGET_XCOFF && HAVE_AS_TLS"
9756   "bla __tls_get_addr")
9758 ;; Next come insns related to the calling sequence.
9760 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9761 ;; We move the back-chain and decrement the stack pointer.
9763 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9764 ;; constant alloca, using that predicate will force the generic code to put
9765 ;; the constant size into a register before calling the expander.
9767 ;; As a result the expander would not have the constant size information
9768 ;; in those cases and would have to generate less efficient code.
9770 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9771 ;; the constant size.  The value is forced into a register if necessary.
9773 (define_expand "allocate_stack"
9774   [(set (match_operand 0 "gpc_reg_operand")
9775         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9776    (set (reg 1)
9777         (minus (reg 1) (match_dup 1)))]
9778   ""
9780   rtx chain = gen_reg_rtx (Pmode);
9781   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9782   rtx neg_op0;
9783   rtx insn, par, set, mem;
9785   /* By allowing reg_or_cint_operand as the predicate we can get
9786      better code for stack-clash-protection because we do not lose
9787      size information.  But the rest of the code expects the operand
9788      to be reg_or_short_operand.  If it isn't, then force it into
9789      a register.  */
9790   rtx orig_op1 = operands[1];
9791   if (!reg_or_short_operand (operands[1], Pmode))
9792     operands[1] = force_reg (Pmode, operands[1]);
9794   emit_move_insn (chain, stack_bot);
9796   /* Check stack bounds if necessary.  */
9797   if (crtl->limit_stack)
9798     {
9799       rtx available;
9800       available = expand_binop (Pmode, sub_optab,
9801                                 stack_pointer_rtx, stack_limit_rtx,
9802                                 NULL_RTX, 1, OPTAB_WIDEN);
9803       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9804     }
9806   /* Allocate and probe if requested.
9807      This may look similar to the loop we use for prologue allocations,
9808      but it is critically different.  For the former we know the loop
9809      will iterate, but do not know that generally here.  The former
9810      uses that knowledge to rotate the loop.  Combining them would be
9811      possible with some performance cost.  */
9812   if (flag_stack_clash_protection)
9813     {
9814       rtx rounded_size, last_addr, residual;
9815       HOST_WIDE_INT probe_interval;
9816       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9817                                                 &residual, &probe_interval,
9818                                                 orig_op1);
9819       
9820       /* We do occasionally get in here with constant sizes, we might
9821          as well do a reasonable job when we obviously can.  */
9822       if (rounded_size != const0_rtx)
9823         {
9824           rtx loop_lab, end_loop;
9825           bool rotated = CONST_INT_P (rounded_size);
9826           rtx update = GEN_INT (-probe_interval);
9827           if (probe_interval > 32768)
9828             update = force_reg (Pmode, update);
9830           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9831                                                         last_addr, rotated);
9833           if (Pmode == SImode)
9834             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9835                                                stack_pointer_rtx,
9836                                                update, chain));
9837           else
9838             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9839                                                   stack_pointer_rtx,
9840                                                   update, chain));
9841           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9842                                                       last_addr, rotated);
9843         }
9845       /* Now handle residuals.  We just have to set operands[1] correctly
9846          and let the rest of the expander run.  */
9847       operands[1] = residual;
9848     }
9850   if (!(CONST_INT_P (operands[1])
9851         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9852     {
9853       operands[1] = force_reg (Pmode, operands[1]);
9854       neg_op0 = gen_reg_rtx (Pmode);
9855       if (TARGET_32BIT)
9856         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9857       else
9858         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9859     }
9860   else
9861     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9863   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9864                                        : gen_movdi_di_update_stack))
9865                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9866                          chain));
9867   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9868      it now and set the alias set/attributes. The above gen_*_update
9869      calls will generate a PARALLEL with the MEM set being the first
9870      operation. */
9871   par = PATTERN (insn);
9872   gcc_assert (GET_CODE (par) == PARALLEL);
9873   set = XVECEXP (par, 0, 0);
9874   gcc_assert (GET_CODE (set) == SET);
9875   mem = SET_DEST (set);
9876   gcc_assert (MEM_P (mem));
9877   MEM_NOTRAP_P (mem) = 1;
9878   set_mem_alias_set (mem, get_frame_alias_set ());
9880   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9881   DONE;
9884 ;; These patterns say how to save and restore the stack pointer.  We need not
9885 ;; save the stack pointer at function level since we are careful to
9886 ;; preserve the backchain.  At block level, we have to restore the backchain
9887 ;; when we restore the stack pointer.
9889 ;; For nonlocal gotos, we must save both the stack pointer and its
9890 ;; backchain and restore both.  Note that in the nonlocal case, the
9891 ;; save area is a memory location.
9893 (define_expand "save_stack_function"
9894   [(match_operand 0 "any_operand")
9895    (match_operand 1 "any_operand")]
9896   ""
9897   "DONE;")
9899 (define_expand "restore_stack_function"
9900   [(match_operand 0 "any_operand")
9901    (match_operand 1 "any_operand")]
9902   ""
9903   "DONE;")
9905 ;; Adjust stack pointer (op0) to a new value (op1).
9906 ;; First copy old stack backchain to new location, and ensure that the
9907 ;; scheduler won't reorder the sp assignment before the backchain write.
9908 (define_expand "restore_stack_block"
9909   [(set (match_dup 2) (match_dup 3))
9910    (set (match_dup 4) (match_dup 2))
9911    (match_dup 5)
9912    (set (match_operand 0 "register_operand")
9913         (match_operand 1 "register_operand"))]
9914   ""
9916   rtvec p;
9918   operands[1] = force_reg (Pmode, operands[1]);
9919   operands[2] = gen_reg_rtx (Pmode);
9920   operands[3] = gen_frame_mem (Pmode, operands[0]);
9921   operands[4] = gen_frame_mem (Pmode, operands[1]);
9922   p = rtvec_alloc (1);
9923   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9924                                   const0_rtx);
9925   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9928 (define_expand "save_stack_nonlocal"
9929   [(set (match_dup 3) (match_dup 4))
9930    (set (match_operand 0 "memory_operand") (match_dup 3))
9931    (set (match_dup 2) (match_operand 1 "register_operand"))]
9932   ""
9934   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9936   /* Copy the backchain to the first word, sp to the second.  */
9937   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9938   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9939   operands[3] = gen_reg_rtx (Pmode);
9940   operands[4] = gen_frame_mem (Pmode, operands[1]);
9943 (define_expand "restore_stack_nonlocal"
9944   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9945    (set (match_dup 3) (match_dup 4))
9946    (set (match_dup 5) (match_dup 2))
9947    (match_dup 6)
9948    (set (match_operand 0 "register_operand") (match_dup 3))]
9949   ""
9951   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9952   rtvec p;
9954   /* Restore the backchain from the first word, sp from the second.  */
9955   operands[2] = gen_reg_rtx (Pmode);
9956   operands[3] = gen_reg_rtx (Pmode);
9957   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9958   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9959   operands[5] = gen_frame_mem (Pmode, operands[3]);
9960   p = rtvec_alloc (1);
9961   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9962                                   const0_rtx);
9963   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9966 ;; TOC register handling.
9968 ;; Code to initialize the TOC register...
9970 (define_insn "load_toc_aix_si"
9971   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9972                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9973               (use (reg:SI 2))])]
9974   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9976   char buf[30];
9977   extern int need_toc_init;
9978   need_toc_init = 1;
9979   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9980   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9981   operands[2] = gen_rtx_REG (Pmode, 2);
9982   return "lwz %0,%1(%2)";
9984   [(set_attr "type" "load")
9985    (set_attr "update" "no")
9986    (set_attr "indexed" "no")])
9988 (define_insn "load_toc_aix_di"
9989   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9990                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9991               (use (reg:DI 2))])]
9992   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9994   char buf[30];
9995   extern int need_toc_init;
9996   need_toc_init = 1;
9997   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9998                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9999   if (TARGET_ELF)
10000     strcat (buf, "@toc");
10001   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10002   operands[2] = gen_rtx_REG (Pmode, 2);
10003   return "ld %0,%1(%2)";
10005   [(set_attr "type" "load")
10006    (set_attr "update" "no")
10007    (set_attr "indexed" "no")])
10009 (define_insn "load_toc_v4_pic_si"
10010   [(set (reg:SI LR_REGNO)
10011         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10012   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10013   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10014   [(set_attr "type" "branch")
10015    (set_attr "length" "4")])
10017 (define_expand "load_toc_v4_PIC_1"
10018   [(parallel [(set (reg:SI LR_REGNO)
10019                    (match_operand:SI 0 "immediate_operand" "s"))
10020               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10021   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10022    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10023   "")
10025 (define_insn "load_toc_v4_PIC_1_normal"
10026   [(set (reg:SI LR_REGNO)
10027         (match_operand:SI 0 "immediate_operand" "s"))
10028    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10029   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10030    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10031   "bcl 20,31,%0\n%0:"
10032   [(set_attr "type" "branch")
10033    (set_attr "length" "4")
10034    (set_attr "cannot_copy" "yes")])
10036 (define_insn "load_toc_v4_PIC_1_476"
10037   [(set (reg:SI LR_REGNO)
10038         (match_operand:SI 0 "immediate_operand" "s"))
10039    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10040   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10041    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10043   char name[32];
10044   static char templ[32];
10046   get_ppc476_thunk_name (name);
10047   sprintf (templ, "bl %s\n%%0:", name);
10048   return templ;
10050   [(set_attr "type" "branch")
10051    (set_attr "length" "4")
10052    (set_attr "cannot_copy" "yes")])
10054 (define_expand "load_toc_v4_PIC_1b"
10055   [(parallel [(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_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10061   "")
10063 (define_insn "load_toc_v4_PIC_1b_normal"
10064   [(set (reg:SI LR_REGNO)
10065         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10066                     (label_ref (match_operand 1 "" ""))]
10067                 UNSPEC_TOCPTR))
10068    (match_dup 1)]
10069   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10070   "bcl 20,31,$+8\;.long %0-$"
10071   [(set_attr "type" "branch")
10072    (set_attr "length" "8")])
10074 (define_insn "load_toc_v4_PIC_1b_476"
10075   [(set (reg:SI LR_REGNO)
10076         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10077                     (label_ref (match_operand 1 "" ""))]
10078                 UNSPEC_TOCPTR))
10079    (match_dup 1)]
10080   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10082   char name[32];
10083   static char templ[32];
10085   get_ppc476_thunk_name (name);
10086   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10087   return templ;
10089   [(set_attr "type" "branch")
10090    (set_attr "length" "16")])
10092 (define_insn "load_toc_v4_PIC_2"
10093   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10094         (mem:SI (plus:SI
10095                   (match_operand:SI 1 "gpc_reg_operand" "b")
10096                   (const
10097                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10098                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10099   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10100   "lwz %0,%2-%3(%1)"
10101   [(set_attr "type" "load")])
10103 (define_insn "load_toc_v4_PIC_3b"
10104   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10105         (plus:SI
10106           (match_operand:SI 1 "gpc_reg_operand" "b")
10107           (high:SI
10108             (const
10109               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10110                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10111   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10112   "addis %0,%1,%2-%3@ha")
10114 (define_insn "load_toc_v4_PIC_3c"
10115   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10116         (lo_sum:SI
10117           (match_operand:SI 1 "gpc_reg_operand" "b")
10118           (const
10119             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10120                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10121   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10122   "addi %0,%1,%2-%3@l")
10124 ;; If the TOC is shared over a translation unit, as happens with all
10125 ;; the kinds of PIC that we support, we need to restore the TOC
10126 ;; pointer only when jumping over units of translation.
10127 ;; On Darwin, we need to reload the picbase.
10129 (define_expand "builtin_setjmp_receiver"
10130   [(use (label_ref (match_operand 0 "")))]
10131   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10132    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10133    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10135 #if TARGET_MACHO
10136   if (DEFAULT_ABI == ABI_DARWIN)
10137     {
10138       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10139       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10140       rtx tmplabrtx;
10141       char tmplab[20];
10143       crtl->uses_pic_offset_table = 1;
10144       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10145                                   CODE_LABEL_NUMBER (operands[0]));
10146       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10148       emit_insn (gen_load_macho_picbase (tmplabrtx));
10149       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10150       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10151     }
10152   else
10153 #endif
10154     rs6000_emit_load_toc_table (FALSE);
10155   DONE;
10158 ;; Largetoc support
10159 (define_insn "*largetoc_high"
10160   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10161         (high:DI
10162           (unspec [(match_operand:DI 1 "" "")
10163                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10164                   UNSPEC_TOCREL)))]
10165    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10166    "addis %0,%2,%1@toc@ha")
10168 (define_insn "*largetoc_high_aix<mode>"
10169   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10170         (high:P
10171           (unspec [(match_operand:P 1 "" "")
10172                    (match_operand:P 2 "gpc_reg_operand" "b")]
10173                   UNSPEC_TOCREL)))]
10174    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10175    "addis %0,%1@u(%2)")
10177 (define_insn "*largetoc_high_plus"
10178   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10179         (high:DI
10180           (plus:DI
10181             (unspec [(match_operand:DI 1 "" "")
10182                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10183                     UNSPEC_TOCREL)
10184             (match_operand:DI 3 "add_cint_operand" "n"))))]
10185    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10186    "addis %0,%2,%1+%3@toc@ha")
10188 (define_insn "*largetoc_high_plus_aix<mode>"
10189   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10190         (high:P
10191           (plus:P
10192             (unspec [(match_operand:P 1 "" "")
10193                      (match_operand:P 2 "gpc_reg_operand" "b")]
10194                     UNSPEC_TOCREL)
10195             (match_operand:P 3 "add_cint_operand" "n"))))]
10196    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10197    "addis %0,%1+%3@u(%2)")
10199 (define_insn "*largetoc_low"
10200   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10201         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10202                    (match_operand:DI 2 "" "")))]
10203    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10204    "addi %0,%1,%2@l")
10206 (define_insn "*largetoc_low_aix<mode>"
10207   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10208         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10209                    (match_operand:P 2 "" "")))]
10210    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10211    "la %0,%2@l(%1)")
10213 (define_insn_and_split "*tocref<mode>"
10214   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10215         (match_operand:P 1 "small_toc_ref" "R"))]
10216    "TARGET_TOC"
10217    "la %0,%a1"
10218    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10219   [(set (match_dup 0) (high:P (match_dup 1)))
10220    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10222 ;; Elf specific ways of loading addresses for non-PIC code.
10223 ;; The output of this could be r0, but we make a very strong
10224 ;; preference for a base register because it will usually
10225 ;; be needed there.
10226 (define_insn "elf_high"
10227   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10228         (high:SI (match_operand 1 "" "")))]
10229   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10230   "lis %0,%1@ha")
10232 (define_insn "elf_low"
10233   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10234         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10235                    (match_operand 2 "" "")))]
10236    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10237    "la %0,%2@l(%1)")
10239 ;; Call and call_value insns
10240 (define_expand "call"
10241   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10242                     (match_operand 1 ""))
10243               (use (match_operand 2 ""))
10244               (clobber (reg:SI LR_REGNO))])]
10245   ""
10247 #if TARGET_MACHO
10248   if (MACHOPIC_INDIRECT)
10249     operands[0] = machopic_indirect_call_target (operands[0]);
10250 #endif
10252   gcc_assert (GET_CODE (operands[0]) == MEM);
10253   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10255   operands[0] = XEXP (operands[0], 0);
10257   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10258     {
10259       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10260       DONE;
10261     }
10263   if (GET_CODE (operands[0]) != SYMBOL_REF
10264       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10265     {
10266       if (INTVAL (operands[2]) & CALL_LONG)
10267         operands[0] = rs6000_longcall_ref (operands[0]);
10269       switch (DEFAULT_ABI)
10270         {
10271         case ABI_V4:
10272         case ABI_DARWIN:
10273           operands[0] = force_reg (Pmode, operands[0]);
10274           break;
10276         default:
10277           gcc_unreachable ();
10278         }
10279     }
10282 (define_expand "call_value"
10283   [(parallel [(set (match_operand 0 "")
10284                    (call (mem:SI (match_operand 1 "address_operand"))
10285                          (match_operand 2 "")))
10286               (use (match_operand 3 ""))
10287               (clobber (reg:SI LR_REGNO))])]
10288   ""
10290 #if TARGET_MACHO
10291   if (MACHOPIC_INDIRECT)
10292     operands[1] = machopic_indirect_call_target (operands[1]);
10293 #endif
10295   gcc_assert (GET_CODE (operands[1]) == MEM);
10296   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10298   operands[1] = XEXP (operands[1], 0);
10300   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10301     {
10302       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10303       DONE;
10304     }
10306   if (GET_CODE (operands[1]) != SYMBOL_REF
10307       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10308     {
10309       if (INTVAL (operands[3]) & CALL_LONG)
10310         operands[1] = rs6000_longcall_ref (operands[1]);
10312       switch (DEFAULT_ABI)
10313         {
10314         case ABI_V4:
10315         case ABI_DARWIN:
10316           operands[1] = force_reg (Pmode, operands[1]);
10317           break;
10319         default:
10320           gcc_unreachable ();
10321         }
10322     }
10325 ;; Call to function in current module.  No TOC pointer reload needed.
10326 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10327 ;; either the function was not prototyped, or it was prototyped as a
10328 ;; variable argument function.  It is > 0 if FP registers were passed
10329 ;; and < 0 if they were not.
10331 (define_insn "*call_local32"
10332   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10333          (match_operand 1 "" "g,g"))
10334    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10335    (clobber (reg:SI LR_REGNO))]
10336   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10338   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10339     output_asm_insn ("crxor 6,6,6", operands);
10341   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10342     output_asm_insn ("creqv 6,6,6", operands);
10344   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10346   [(set_attr "type" "branch")
10347    (set_attr "length" "4,8")])
10349 (define_insn "*call_local64"
10350   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10351          (match_operand 1 "" "g,g"))
10352    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10353    (clobber (reg:SI LR_REGNO))]
10354   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10356   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10357     output_asm_insn ("crxor 6,6,6", operands);
10359   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10360     output_asm_insn ("creqv 6,6,6", operands);
10362   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10364   [(set_attr "type" "branch")
10365    (set_attr "length" "4,8")])
10367 (define_insn "*call_value_local32"
10368   [(set (match_operand 0 "" "")
10369         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10370               (match_operand 2 "" "g,g")))
10371    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10372    (clobber (reg:SI LR_REGNO))]
10373   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10375   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10376     output_asm_insn ("crxor 6,6,6", operands);
10378   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10379     output_asm_insn ("creqv 6,6,6", operands);
10381   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10383   [(set_attr "type" "branch")
10384    (set_attr "length" "4,8")])
10387 (define_insn "*call_value_local64"
10388   [(set (match_operand 0 "" "")
10389         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10390               (match_operand 2 "" "g,g")))
10391    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10392    (clobber (reg:SI LR_REGNO))]
10393   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10395   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10396     output_asm_insn ("crxor 6,6,6", operands);
10398   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10399     output_asm_insn ("creqv 6,6,6", operands);
10401   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10403   [(set_attr "type" "branch")
10404    (set_attr "length" "4,8")])
10407 ;; A function pointer under System V is just a normal pointer
10408 ;; operands[0] is the function pointer
10409 ;; operands[1] is the stack size to clean up
10410 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10411 ;; which indicates how to set cr1
10413 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10414   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10415          (match_operand 1 "" "g,g,g,g"))
10416    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10417    (clobber (reg:SI LR_REGNO))]
10418   "DEFAULT_ABI == ABI_V4
10419    || DEFAULT_ABI == ABI_DARWIN"
10421   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10422     output_asm_insn ("crxor 6,6,6", operands);
10424   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10425     output_asm_insn ("creqv 6,6,6", operands);
10427   if (rs6000_speculate_indirect_jumps
10428       || which_alternative == 1 || which_alternative == 3)
10429     return "b%T0l";
10430   else
10431     return "crset 2\;beq%T0l-";
10433   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10434    (set (attr "length")
10435         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10436                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10437                         (const_int 0)))
10438                   (const_string "8")
10439                (and (eq (symbol_ref "which_alternative") (const_int 2))
10440                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10441                         (const_int 0)))
10442                   (const_string "8")
10443                (and (eq (symbol_ref "which_alternative") (const_int 2))
10444                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10445                         (const_int 0)))
10446                   (const_string "12")
10447                (eq (symbol_ref "which_alternative") (const_int 3))
10448                   (const_string "8")]
10449               (const_string "4")))])
10451 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10452   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10453          (match_operand 1 "" "g,g"))
10454    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10455    (clobber (reg:SI LR_REGNO))]
10456   "(DEFAULT_ABI == ABI_DARWIN
10457    || (DEFAULT_ABI == ABI_V4
10458        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10460   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10461     output_asm_insn ("crxor 6,6,6", operands);
10463   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10464     output_asm_insn ("creqv 6,6,6", operands);
10466 #if TARGET_MACHO
10467   return output_call(insn, operands, 0, 2);
10468 #else
10469   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10470     {
10471       gcc_assert (!TARGET_SECURE_PLT);
10472       return "bl %z0@plt";
10473     }
10474   else
10475     return "bl %z0";
10476 #endif
10478   "DEFAULT_ABI == ABI_V4
10479    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10480    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10481   [(parallel [(call (mem:SI (match_dup 0))
10482                     (match_dup 1))
10483               (use (match_dup 2))
10484               (use (match_dup 3))
10485               (clobber (reg:SI LR_REGNO))])]
10487   operands[3] = pic_offset_table_rtx;
10489   [(set_attr "type" "branch,branch")
10490    (set_attr "length" "4,8")])
10492 (define_insn "*call_nonlocal_sysv_secure<mode>"
10493   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10494          (match_operand 1 "" "g,g"))
10495    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10496    (use (match_operand:SI 3 "register_operand" "r,r"))
10497    (clobber (reg:SI LR_REGNO))]
10498   "(DEFAULT_ABI == ABI_V4
10499     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10500     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10502   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10503     output_asm_insn ("crxor 6,6,6", operands);
10505   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10506     output_asm_insn ("creqv 6,6,6", operands);
10508   if (flag_pic == 2)
10509     /* The magic 32768 offset here and in the other sysv call insns
10510        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10511        See sysv4.h:toc_section.  */
10512     return "bl %z0+32768@plt";
10513   else
10514     return "bl %z0@plt";
10516   [(set_attr "type" "branch,branch")
10517    (set_attr "length" "4,8")])
10519 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10520   [(set (match_operand 0 "" "")
10521         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10522               (match_operand 2 "" "g,g,g,g")))
10523    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10524    (clobber (reg:SI LR_REGNO))]
10525   "DEFAULT_ABI == ABI_V4
10526    || DEFAULT_ABI == ABI_DARWIN"
10528   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10529     output_asm_insn ("crxor 6,6,6", operands);
10531   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10532     output_asm_insn ("creqv 6,6,6", operands);
10534   if (rs6000_speculate_indirect_jumps
10535       || which_alternative == 1 || which_alternative == 3)
10536     return "b%T1l";
10537   else
10538     return "crset 2\;beq%T1l-";
10540   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10541    (set (attr "length")
10542         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10543                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10544                         (const_int 0)))
10545                   (const_string "8")
10546                (and (eq (symbol_ref "which_alternative") (const_int 2))
10547                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10548                         (const_int 0)))
10549                   (const_string "8")
10550                (and (eq (symbol_ref "which_alternative") (const_int 2))
10551                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10552                         (const_int 0)))
10553                   (const_string "12")
10554                (eq (symbol_ref "which_alternative") (const_int 3))
10555                   (const_string "8")]
10556               (const_string "4")))])
10558 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10559   [(set (match_operand 0 "" "")
10560         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10561               (match_operand 2 "" "g,g")))
10562    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10563    (clobber (reg:SI LR_REGNO))]
10564   "(DEFAULT_ABI == ABI_DARWIN
10565    || (DEFAULT_ABI == ABI_V4
10566        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10568   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10569     output_asm_insn ("crxor 6,6,6", operands);
10571   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10572     output_asm_insn ("creqv 6,6,6", operands);
10574 #if TARGET_MACHO
10575   return output_call(insn, operands, 1, 3);
10576 #else
10577   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10578     {
10579       gcc_assert (!TARGET_SECURE_PLT);
10580       return "bl %z1@plt";
10581     }
10582   else
10583     return "bl %z1";
10584 #endif
10586   "DEFAULT_ABI == ABI_V4
10587    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10588    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10589   [(parallel [(set (match_dup 0)
10590                    (call (mem:SI (match_dup 1))
10591                          (match_dup 2)))
10592               (use (match_dup 3))
10593               (use (match_dup 4))
10594               (clobber (reg:SI LR_REGNO))])]
10596   operands[4] = pic_offset_table_rtx;
10598   [(set_attr "type" "branch,branch")
10599    (set_attr "length" "4,8")])
10601 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10602   [(set (match_operand 0 "" "")
10603         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10604               (match_operand 2 "" "g,g")))
10605    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10606    (use (match_operand:SI 4 "register_operand" "r,r"))
10607    (clobber (reg:SI LR_REGNO))]
10608   "(DEFAULT_ABI == ABI_V4
10609     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10610     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10612   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10613     output_asm_insn ("crxor 6,6,6", operands);
10615   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10616     output_asm_insn ("creqv 6,6,6", operands);
10618   if (flag_pic == 2)
10619     return "bl %z1+32768@plt";
10620   else
10621     return "bl %z1@plt";
10623   [(set_attr "type" "branch,branch")
10624    (set_attr "length" "4,8")])
10627 ;; Call to AIX abi function in the same module.
10629 (define_insn "*call_local_aix<mode>"
10630   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10631          (match_operand 1 "" "g"))
10632    (clobber (reg:P LR_REGNO))]
10633   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10634   "bl %z0"
10635   [(set_attr "type" "branch")
10636    (set_attr "length" "4")])
10638 (define_insn "*call_value_local_aix<mode>"
10639   [(set (match_operand 0 "" "")
10640         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10641               (match_operand 2 "" "g")))
10642    (clobber (reg:P LR_REGNO))]
10643   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10644   "bl %z1"
10645   [(set_attr "type" "branch")
10646    (set_attr "length" "4")])
10648 ;; Call to AIX abi function which may be in another module.
10649 ;; Restore the TOC pointer (r2) after the call.
10651 (define_insn "*call_nonlocal_aix<mode>"
10652   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10653          (match_operand 1 "" "g"))
10654    (clobber (reg:P LR_REGNO))]
10655   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10656   "bl %z0\;nop"
10657   [(set_attr "type" "branch")
10658    (set_attr "length" "8")])
10660 (define_insn "*call_value_nonlocal_aix<mode>"
10661   [(set (match_operand 0 "" "")
10662         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10663               (match_operand 2 "" "g")))
10664    (clobber (reg:P LR_REGNO))]
10665   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10666   "bl %z1\;nop"
10667   [(set_attr "type" "branch")
10668    (set_attr "length" "8")])
10670 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10671 ;; Operand0 is the addresss of the function to call
10672 ;; Operand2 is the location in the function descriptor to load r2 from
10673 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10675 (define_insn "*call_indirect_aix<mode>"
10676   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10677          (match_operand 1 "" "g,g"))
10678    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10679    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10680    (clobber (reg:P LR_REGNO))]
10681   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10682   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10683   [(set_attr "type" "jmpreg")
10684    (set_attr "length" "12")])
10686 (define_insn "*call_indirect_aix<mode>_nospec"
10687   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10688          (match_operand 1 "" "g,g"))
10689    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10690    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10691    (clobber (reg:P LR_REGNO))]
10692   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10693   "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10694   [(set_attr "type" "jmpreg")
10695    (set_attr "length" "16")])
10697 (define_insn "*call_value_indirect_aix<mode>"
10698   [(set (match_operand 0 "" "")
10699         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10700               (match_operand 2 "" "g,g")))
10701    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10702    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10703    (clobber (reg:P LR_REGNO))]
10704   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10705   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10706   [(set_attr "type" "jmpreg")
10707    (set_attr "length" "12")])
10709 (define_insn "*call_value_indirect_aix<mode>_nospec"
10710   [(set (match_operand 0 "" "")
10711         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10712               (match_operand 2 "" "g,g")))
10713    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10714    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10715    (clobber (reg:P LR_REGNO))]
10716   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10717   "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10718   [(set_attr "type" "jmpreg")
10719    (set_attr "length" "16")])
10721 ;; Call to indirect functions with the ELFv2 ABI.
10722 ;; Operand0 is the addresss of the function to call
10723 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10725 (define_insn "*call_indirect_elfv2<mode>"
10726   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10727          (match_operand 1 "" "g,g"))
10728    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10729    (clobber (reg:P LR_REGNO))]
10730   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10731   "b%T0l\;<ptrload> 2,%2(1)"
10732   [(set_attr "type" "jmpreg")
10733    (set_attr "length" "8")])
10735 ;; Variant with deliberate misprediction.
10736 (define_insn "*call_indirect_elfv2<mode>_nospec"
10737   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10738          (match_operand 1 "" "g,g"))
10739    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10740    (clobber (reg:P LR_REGNO))]
10741   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10742   "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10743   [(set_attr "type" "jmpreg")
10744    (set_attr "length" "12")])
10746 (define_insn "*call_value_indirect_elfv2<mode>"
10747   [(set (match_operand 0 "" "")
10748         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10749               (match_operand 2 "" "g,g")))
10750    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10751    (clobber (reg:P LR_REGNO))]
10752   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10753   "b%T1l\;<ptrload> 2,%3(1)"
10754   [(set_attr "type" "jmpreg")
10755    (set_attr "length" "8")])
10757 ; Variant with deliberate misprediction.
10758 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10759   [(set (match_operand 0 "" "")
10760         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10761               (match_operand 2 "" "g,g")))
10762    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10763    (clobber (reg:P LR_REGNO))]
10764   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10765   "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10766   [(set_attr "type" "jmpreg")
10767    (set_attr "length" "12")])
10769 ;; Call subroutine returning any type.
10770 (define_expand "untyped_call"
10771   [(parallel [(call (match_operand 0 "")
10772                     (const_int 0))
10773               (match_operand 1 "")
10774               (match_operand 2 "")])]
10775   ""
10777   int i;
10779   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10781   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10782     {
10783       rtx set = XVECEXP (operands[2], 0, i);
10784       emit_move_insn (SET_DEST (set), SET_SRC (set));
10785     }
10787   /* The optimizer does not know that the call sets the function value
10788      registers we stored in the result block.  We avoid problems by
10789      claiming that all hard registers are used and clobbered at this
10790      point.  */
10791   emit_insn (gen_blockage ());
10793   DONE;
10796 ;; sibling call patterns
10797 (define_expand "sibcall"
10798   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10799                     (match_operand 1 ""))
10800               (use (match_operand 2 ""))
10801               (simple_return)])]
10802   ""
10804 #if TARGET_MACHO
10805   if (MACHOPIC_INDIRECT)
10806     operands[0] = machopic_indirect_call_target (operands[0]);
10807 #endif
10809   gcc_assert (GET_CODE (operands[0]) == MEM);
10810   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10812   operands[0] = XEXP (operands[0], 0);
10814   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10815     {
10816       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10817       DONE;
10818     }
10821 (define_expand "sibcall_value"
10822   [(parallel [(set (match_operand 0 "register_operand")
10823                 (call (mem:SI (match_operand 1 "address_operand"))
10824                       (match_operand 2 "")))
10825               (use (match_operand 3 ""))
10826               (simple_return)])]
10827   ""
10829 #if TARGET_MACHO
10830   if (MACHOPIC_INDIRECT)
10831     operands[1] = machopic_indirect_call_target (operands[1]);
10832 #endif
10834   gcc_assert (GET_CODE (operands[1]) == MEM);
10835   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10837   operands[1] = XEXP (operands[1], 0);
10839   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10840     {
10841       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10842       DONE;
10843     }
10846 (define_insn "*sibcall_local32"
10847   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10848          (match_operand 1 "" "g,g"))
10849    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10850    (simple_return)]
10851   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10853   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10854     output_asm_insn ("crxor 6,6,6", operands);
10856   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10857     output_asm_insn ("creqv 6,6,6", operands);
10859   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10861   [(set_attr "type" "branch")
10862    (set_attr "length" "4,8")])
10864 (define_insn "*sibcall_local64"
10865   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10866          (match_operand 1 "" "g,g"))
10867    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10868    (simple_return)]
10869   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10871   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10872     output_asm_insn ("crxor 6,6,6", operands);
10874   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10875     output_asm_insn ("creqv 6,6,6", operands);
10877   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10879   [(set_attr "type" "branch")
10880    (set_attr "length" "4,8")])
10882 (define_insn "*sibcall_value_local32"
10883   [(set (match_operand 0 "" "")
10884         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10885               (match_operand 2 "" "g,g")))
10886    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10887    (simple_return)]
10888   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10890   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10891     output_asm_insn ("crxor 6,6,6", operands);
10893   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10894     output_asm_insn ("creqv 6,6,6", operands);
10896   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10898   [(set_attr "type" "branch")
10899    (set_attr "length" "4,8")])
10901 (define_insn "*sibcall_value_local64"
10902   [(set (match_operand 0 "" "")
10903         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10904               (match_operand 2 "" "g,g")))
10905    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10906    (simple_return)]
10907   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10909   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10910     output_asm_insn ("crxor 6,6,6", operands);
10912   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10913     output_asm_insn ("creqv 6,6,6", operands);
10915   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10917   [(set_attr "type" "branch")
10918    (set_attr "length" "4,8")])
10920 (define_insn "*sibcall_nonlocal_sysv<mode>"
10921   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10922          (match_operand 1 "" ""))
10923    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10924    (simple_return)]
10925   "(DEFAULT_ABI == ABI_DARWIN
10926     || DEFAULT_ABI == ABI_V4)
10927    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10929   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10930     output_asm_insn ("crxor 6,6,6", operands);
10932   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10933     output_asm_insn ("creqv 6,6,6", operands);
10935   if (which_alternative >= 2)
10936     {
10937       if (rs6000_speculate_indirect_jumps)
10938         return "b%T0";
10939       else
10940         /* Can use CR0 since it is volatile across sibcalls.  */
10941         return "crset 2\;beq%T0-\;b $";
10942     }
10943   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10944     {
10945       gcc_assert (!TARGET_SECURE_PLT);
10946       return "b %z0@plt";
10947     }
10948   else
10949     return "b %z0";
10951   [(set_attr "type" "branch")
10952    (set (attr "length")
10953         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10954                   (const_string "8")
10955                (and (eq (symbol_ref "which_alternative") (const_int 2))
10956                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10957                         (const_int 0)))
10958                   (const_string "12")
10959                (and (eq (symbol_ref "which_alternative") (const_int 3))
10960                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10961                         (const_int 0)))
10962                   (const_string "8")
10963                (and (eq (symbol_ref "which_alternative") (const_int 3))
10964                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10965                         (const_int 0)))
10966                   (const_string "16")]
10967               (const_string "4")))])
10969 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10970   [(set (match_operand 0 "" "")
10971         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10972               (match_operand 2 "" "")))
10973    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10974    (simple_return)]
10975   "(DEFAULT_ABI == ABI_DARWIN
10976     || DEFAULT_ABI == ABI_V4)
10977    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10979   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10980     output_asm_insn ("crxor 6,6,6", operands);
10982   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10983     output_asm_insn ("creqv 6,6,6", operands);
10985   if (which_alternative >= 2)
10986     {
10987       if (rs6000_speculate_indirect_jumps)
10988         return "b%T1";
10989       else
10990         /* Can use CR0 since it is volatile across sibcalls.  */
10991         return "crset 2\;beq%T1-\;b $";
10992     }
10993   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10994     {
10995       gcc_assert (!TARGET_SECURE_PLT);
10996       return "b %z1@plt";
10997     }
10998   else
10999     return "b %z1";
11001   [(set_attr "type" "branch")
11002    (set (attr "length")
11003         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
11004                   (const_string "8")
11005                (and (eq (symbol_ref "which_alternative") (const_int 2))
11006                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11007                         (const_int 0)))
11008                   (const_string "12")
11009                (and (eq (symbol_ref "which_alternative") (const_int 3))
11010                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
11011                         (const_int 0)))
11012                   (const_string "8")
11013                (and (eq (symbol_ref "which_alternative") (const_int 3))
11014                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11015                         (const_int 0)))
11016                   (const_string "16")]
11017               (const_string "4")))])
11019 ;; AIX ABI sibling call patterns.
11021 (define_insn "*sibcall_aix<mode>"
11022   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11023          (match_operand 1 "" "g,g"))
11024    (simple_return)]
11025   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11026   "@
11027    b %z0
11028    b%T0"
11029   [(set_attr "type" "branch")
11030    (set_attr "length" "4")])
11032 (define_insn "*sibcall_value_aix<mode>"
11033   [(set (match_operand 0 "" "")
11034         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11035               (match_operand 2 "" "g,g")))
11036    (simple_return)]
11037   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11038   "@
11039    b %z1
11040    b%T1"
11041   [(set_attr "type" "branch")
11042    (set_attr "length" "4")])
11044 (define_expand "sibcall_epilogue"
11045   [(use (const_int 0))]
11046   ""
11048   if (!TARGET_SCHED_PROLOG)
11049     emit_insn (gen_blockage ());
11050   rs6000_emit_epilogue (TRUE);
11051   DONE;
11054 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11055 ;; all of memory.  This blocks insns from being moved across this point.
11057 (define_insn "blockage"
11058   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11059   ""
11060   ""
11061   [(set_attr "length" "0")])
11063 (define_expand "probe_stack_address"
11064   [(use (match_operand 0 "address_operand"))]
11065   ""
11067   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11068   MEM_VOLATILE_P (operands[0]) = 1;
11070   if (TARGET_64BIT)
11071     emit_insn (gen_probe_stack_di (operands[0]));
11072   else
11073     emit_insn (gen_probe_stack_si (operands[0]));
11074   DONE;
11077 (define_insn "probe_stack_<mode>"
11078   [(set (match_operand:P 0 "memory_operand" "=m")
11079         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11080   ""
11082   operands[1] = gen_rtx_REG (Pmode, 0);
11083   return "st<wd>%U0%X0 %1,%0";
11085   [(set_attr "type" "store")
11086    (set (attr "update")
11087         (if_then_else (match_operand 0 "update_address_mem")
11088                       (const_string "yes")
11089                       (const_string "no")))
11090    (set (attr "indexed")
11091         (if_then_else (match_operand 0 "indexed_address_mem")
11092                       (const_string "yes")
11093                       (const_string "no")))
11094    (set_attr "length" "4")])
11096 (define_insn "probe_stack_range<P:mode>"
11097   [(set (match_operand:P 0 "register_operand" "=&r")
11098         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11099                             (match_operand:P 2 "register_operand" "r")
11100                             (match_operand:P 3 "register_operand" "r")]
11101                            UNSPECV_PROBE_STACK_RANGE))]
11102   ""
11103   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11104   [(set_attr "type" "three")])
11106 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11107 ;; signed & unsigned, and one type of branch.
11109 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11110 ;; insns, and branches.
11112 (define_expand "cbranch<mode>4"
11113   [(use (match_operator 0 "comparison_operator"
11114          [(match_operand:GPR 1 "gpc_reg_operand")
11115           (match_operand:GPR 2 "reg_or_short_operand")]))
11116    (use (match_operand 3))]
11117   ""
11119   /* Take care of the possibility that operands[2] might be negative but
11120      this might be a logical operation.  That insn doesn't exist.  */
11121   if (GET_CODE (operands[2]) == CONST_INT
11122       && INTVAL (operands[2]) < 0)
11123     {
11124       operands[2] = force_reg (<MODE>mode, operands[2]);
11125       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11126                                     GET_MODE (operands[0]),
11127                                     operands[1], operands[2]);
11128    }
11130   rs6000_emit_cbranch (<MODE>mode, operands);
11131   DONE;
11134 (define_expand "cbranch<mode>4"
11135   [(use (match_operator 0 "comparison_operator"
11136          [(match_operand:FP 1 "gpc_reg_operand")
11137           (match_operand:FP 2 "gpc_reg_operand")]))
11138    (use (match_operand 3))]
11139   ""
11141   rs6000_emit_cbranch (<MODE>mode, operands);
11142   DONE;
11145 (define_expand "cstore<mode>4_signed"
11146   [(use (match_operator 1 "signed_comparison_operator"
11147          [(match_operand:P 2 "gpc_reg_operand")
11148           (match_operand:P 3 "gpc_reg_operand")]))
11149    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11150   ""
11152   enum rtx_code cond_code = GET_CODE (operands[1]);
11154   rtx op0 = operands[0];
11155   rtx op1 = operands[2];
11156   rtx op2 = operands[3];
11158   if (cond_code == GE || cond_code == LT)
11159     {
11160       cond_code = swap_condition (cond_code);
11161       std::swap (op1, op2);
11162     }
11164   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11165   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11166   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11168   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11169   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11170   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11172   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11174   if (cond_code == LE)
11175     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11176   else
11177     {
11178       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11179       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11180       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11181     }
11183   DONE;
11186 (define_expand "cstore<mode>4_unsigned"
11187   [(use (match_operator 1 "unsigned_comparison_operator"
11188          [(match_operand:P 2 "gpc_reg_operand")
11189           (match_operand:P 3 "reg_or_short_operand")]))
11190    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11191   ""
11193   enum rtx_code cond_code = GET_CODE (operands[1]);
11195   rtx op0 = operands[0];
11196   rtx op1 = operands[2];
11197   rtx op2 = operands[3];
11199   if (cond_code == GEU || cond_code == LTU)
11200     {
11201       cond_code = swap_condition (cond_code);
11202       std::swap (op1, op2);
11203     }
11205   if (!gpc_reg_operand (op1, <MODE>mode))
11206     op1 = force_reg (<MODE>mode, op1);
11207   if (!reg_or_short_operand (op2, <MODE>mode))
11208     op2 = force_reg (<MODE>mode, op2);
11210   rtx tmp = gen_reg_rtx (<MODE>mode);
11211   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11213   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11214   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11216   if (cond_code == LEU)
11217     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11218   else
11219     emit_insn (gen_neg<mode>2 (op0, tmp2));
11221   DONE;
11224 (define_expand "cstore_si_as_di"
11225   [(use (match_operator 1 "unsigned_comparison_operator"
11226          [(match_operand:SI 2 "gpc_reg_operand")
11227           (match_operand:SI 3 "reg_or_short_operand")]))
11228    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11229   ""
11231   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11232   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11234   operands[2] = force_reg (SImode, operands[2]);
11235   operands[3] = force_reg (SImode, operands[3]);
11236   rtx op1 = gen_reg_rtx (DImode);
11237   rtx op2 = gen_reg_rtx (DImode);
11238   convert_move (op1, operands[2], uns_flag);
11239   convert_move (op2, operands[3], uns_flag);
11241   if (cond_code == GT || cond_code == LE)
11242     {
11243       cond_code = swap_condition (cond_code);
11244       std::swap (op1, op2);
11245     }
11247   rtx tmp = gen_reg_rtx (DImode);
11248   rtx tmp2 = gen_reg_rtx (DImode);
11249   emit_insn (gen_subdi3 (tmp, op1, op2));
11250   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11252   rtx tmp3;
11253   switch (cond_code)
11254     {
11255     default:
11256       gcc_unreachable ();
11257     case LT:
11258       tmp3 = tmp2;
11259       break;
11260     case GE:
11261       tmp3 = gen_reg_rtx (DImode);
11262       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11263       break;
11264     }
11266   convert_move (operands[0], tmp3, 1);
11268   DONE;
11271 (define_expand "cstore<mode>4_signed_imm"
11272   [(use (match_operator 1 "signed_comparison_operator"
11273          [(match_operand:GPR 2 "gpc_reg_operand")
11274           (match_operand:GPR 3 "immediate_operand")]))
11275    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11276   ""
11278   bool invert = false;
11280   enum rtx_code cond_code = GET_CODE (operands[1]);
11282   rtx op0 = operands[0];
11283   rtx op1 = operands[2];
11284   HOST_WIDE_INT val = INTVAL (operands[3]);
11286   if (cond_code == GE || cond_code == GT)
11287     {
11288       cond_code = reverse_condition (cond_code);
11289       invert = true;
11290     }
11292   if (cond_code == LE)
11293     val++;
11295   rtx tmp = gen_reg_rtx (<MODE>mode);
11296   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11297   rtx x = gen_reg_rtx (<MODE>mode);
11298   if (val < 0)
11299     emit_insn (gen_and<mode>3 (x, op1, tmp));
11300   else
11301     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11303   if (invert)
11304     {
11305       rtx tmp = gen_reg_rtx (<MODE>mode);
11306       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11307       x = tmp;
11308     }
11310   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11311   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11313   DONE;
11316 (define_expand "cstore<mode>4_unsigned_imm"
11317   [(use (match_operator 1 "unsigned_comparison_operator"
11318          [(match_operand:GPR 2 "gpc_reg_operand")
11319           (match_operand:GPR 3 "immediate_operand")]))
11320    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11321   ""
11323   bool invert = false;
11325   enum rtx_code cond_code = GET_CODE (operands[1]);
11327   rtx op0 = operands[0];
11328   rtx op1 = operands[2];
11329   HOST_WIDE_INT val = INTVAL (operands[3]);
11331   if (cond_code == GEU || cond_code == GTU)
11332     {
11333       cond_code = reverse_condition (cond_code);
11334       invert = true;
11335     }
11337   if (cond_code == LEU)
11338     val++;
11340   rtx tmp = gen_reg_rtx (<MODE>mode);
11341   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11342   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11343   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11344   rtx x = gen_reg_rtx (<MODE>mode);
11345   if (val < 0)
11346     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11347   else
11348     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11350   if (invert)
11351     {
11352       rtx tmp = gen_reg_rtx (<MODE>mode);
11353       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11354       x = tmp;
11355     }
11357   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11358   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11360   DONE;
11363 (define_expand "cstore<mode>4"
11364   [(use (match_operator 1 "comparison_operator"
11365          [(match_operand:GPR 2 "gpc_reg_operand")
11366           (match_operand:GPR 3 "reg_or_short_operand")]))
11367    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11368   ""
11370   /* Expanding EQ and NE directly to some machine instructions does not help
11371      but does hurt combine.  So don't.  */
11372   if (GET_CODE (operands[1]) == EQ)
11373     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11374   else if (<MODE>mode == Pmode
11375            && GET_CODE (operands[1]) == NE)
11376     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11377   else if (GET_CODE (operands[1]) == NE)
11378     {
11379       rtx tmp = gen_reg_rtx (<MODE>mode);
11380       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11381       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11382     }
11384   /* If ISEL is fast, expand to it.  */
11385   else if (TARGET_ISEL)
11386     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11388   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11389      etc. combinations magically work out just right.  */
11390   else if (<MODE>mode == Pmode
11391            && unsigned_comparison_operator (operands[1], VOIDmode))
11392     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11393                                            operands[2], operands[3]));
11395   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11396   else if (<MODE>mode == SImode && Pmode == DImode)
11397     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11398                                     operands[2], operands[3]));
11400   /* For signed comparisons against a constant, we can do some simple
11401      bit-twiddling.  */
11402   else if (signed_comparison_operator (operands[1], VOIDmode)
11403            && CONST_INT_P (operands[3]))
11404     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11405                                              operands[2], operands[3]));
11407   /* And similarly for unsigned comparisons.  */
11408   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11409            && CONST_INT_P (operands[3]))
11410     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11411                                                operands[2], operands[3]));
11413   /* We also do not want to use mfcr for signed comparisons.  */
11414   else if (<MODE>mode == Pmode
11415            && signed_comparison_operator (operands[1], VOIDmode))
11416     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11417                                          operands[2], operands[3]));
11419   /* Everything else, use the mfcr brute force.  */
11420   else
11421     rs6000_emit_sCOND (<MODE>mode, operands);
11423   DONE;
11426 (define_expand "cstore<mode>4"
11427   [(use (match_operator 1 "comparison_operator"
11428          [(match_operand:FP 2 "gpc_reg_operand")
11429           (match_operand:FP 3 "gpc_reg_operand")]))
11430    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11431   ""
11433   rs6000_emit_sCOND (<MODE>mode, operands);
11434   DONE;
11438 (define_expand "stack_protect_set"
11439   [(match_operand 0 "memory_operand")
11440    (match_operand 1 "memory_operand")]
11441   ""
11443   if (rs6000_stack_protector_guard == SSP_TLS)
11444     {
11445       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11446       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11447       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11448       operands[1] = gen_rtx_MEM (Pmode, addr);
11449     }
11451   if (TARGET_64BIT)
11452     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11453   else
11454     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11456   DONE;
11459 (define_insn "stack_protect_setsi"
11460   [(set (match_operand:SI 0 "memory_operand" "=m")
11461         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11462    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11463   "TARGET_32BIT"
11464   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11465   [(set_attr "type" "three")
11466    (set_attr "length" "12")])
11468 (define_insn "stack_protect_setdi"
11469   [(set (match_operand:DI 0 "memory_operand" "=Y")
11470         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11471    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11472   "TARGET_64BIT"
11473   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11474   [(set_attr "type" "three")
11475    (set_attr "length" "12")])
11477 (define_expand "stack_protect_test"
11478   [(match_operand 0 "memory_operand")
11479    (match_operand 1 "memory_operand")
11480    (match_operand 2 "")]
11481   ""
11483   rtx guard = operands[1];
11485   if (rs6000_stack_protector_guard == SSP_TLS)
11486     {
11487       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11488       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11489       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11490       guard = gen_rtx_MEM (Pmode, addr);
11491     }
11493   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11494   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11495   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11496   emit_jump_insn (jump);
11498   DONE;
11501 (define_insn "stack_protect_testsi"
11502   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11503         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11504                       (match_operand:SI 2 "memory_operand" "m,m")]
11505                      UNSPEC_SP_TEST))
11506    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11507    (clobber (match_scratch:SI 3 "=&r,&r"))]
11508   "TARGET_32BIT"
11509   "@
11510    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11511    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11512   [(set_attr "length" "16,20")])
11514 (define_insn "stack_protect_testdi"
11515   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11516         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11517                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11518                      UNSPEC_SP_TEST))
11519    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11520    (clobber (match_scratch:DI 3 "=&r,&r"))]
11521   "TARGET_64BIT"
11522   "@
11523    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11524    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11525   [(set_attr "length" "16,20")])
11528 ;; Here are the actual compare insns.
11529 (define_insn "*cmp<mode>_signed"
11530   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11531         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11532                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11533   ""
11534   "cmp<wd>%I2 %0,%1,%2"
11535   [(set_attr "type" "cmp")])
11537 (define_insn "*cmp<mode>_unsigned"
11538   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11539         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11540                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11541   ""
11542   "cmpl<wd>%I2 %0,%1,%2"
11543   [(set_attr "type" "cmp")])
11545 ;; If we are comparing a register for equality with a large constant,
11546 ;; we can do this with an XOR followed by a compare.  But this is profitable
11547 ;; only if the large constant is only used for the comparison (and in this
11548 ;; case we already have a register to reuse as scratch).
11550 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11551 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11553 (define_peephole2
11554   [(set (match_operand:SI 0 "register_operand")
11555         (match_operand:SI 1 "logical_const_operand"))
11556    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11557                        [(match_dup 0)
11558                         (match_operand:SI 2 "logical_const_operand")]))
11559    (set (match_operand:CC 4 "cc_reg_operand")
11560         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11561                     (match_dup 0)))
11562    (set (pc)
11563         (if_then_else (match_operator 6 "equality_operator"
11564                        [(match_dup 4) (const_int 0)])
11565                       (match_operand 7 "")
11566                       (match_operand 8 "")))]
11567   "peep2_reg_dead_p (3, operands[0])
11568    && peep2_reg_dead_p (4, operands[4])
11569    && REGNO (operands[0]) != REGNO (operands[5])"
11570  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11571   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11572   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11575   /* Get the constant we are comparing against, and see what it looks like
11576      when sign-extended from 16 to 32 bits.  Then see what constant we could
11577      XOR with SEXTC to get the sign-extended value.  */
11578   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11579                                               SImode,
11580                                               operands[1], operands[2]);
11581   HOST_WIDE_INT c = INTVAL (cnst);
11582   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11583   HOST_WIDE_INT xorv = c ^ sextc;
11585   operands[9] = GEN_INT (xorv);
11586   operands[10] = GEN_INT (sextc);
11589 ;; The following two insns don't exist as single insns, but if we provide
11590 ;; them, we can swap an add and compare, which will enable us to overlap more
11591 ;; of the required delay between a compare and branch.  We generate code for
11592 ;; them by splitting.
11594 (define_insn ""
11595   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11596         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11597                     (match_operand:SI 2 "short_cint_operand" "i")))
11598    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11599         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11600   ""
11601   "#"
11602   [(set_attr "length" "8")])
11604 (define_insn ""
11605   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11606         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11607                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11608    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11609         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11610   ""
11611   "#"
11612   [(set_attr "length" "8")])
11614 (define_split
11615   [(set (match_operand:CC 3 "cc_reg_operand")
11616         (compare:CC (match_operand:SI 1 "gpc_reg_operand")
11617                     (match_operand:SI 2 "short_cint_operand")))
11618    (set (match_operand:SI 0 "gpc_reg_operand")
11619         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11620   ""
11621   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11622    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11624 (define_split
11625   [(set (match_operand:CCUNS 3 "cc_reg_operand")
11626         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11627                        (match_operand:SI 2 "u_short_cint_operand")))
11628    (set (match_operand:SI 0 "gpc_reg_operand")
11629         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11630   ""
11631   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11632    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11634 ;; Only need to compare second words if first words equal
11635 (define_insn "*cmp<mode>_internal1"
11636   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11637         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11638                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11639   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11640    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11641   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11642   [(set_attr "type" "fpcompare")
11643    (set_attr "length" "12")])
11645 (define_insn_and_split "*cmp<mode>_internal2"
11646   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11647         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11648                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11649     (clobber (match_scratch:DF 3 "=d"))
11650     (clobber (match_scratch:DF 4 "=d"))
11651     (clobber (match_scratch:DF 5 "=d"))
11652     (clobber (match_scratch:DF 6 "=d"))
11653     (clobber (match_scratch:DF 7 "=d"))
11654     (clobber (match_scratch:DF 8 "=d"))
11655     (clobber (match_scratch:DF 9 "=d"))
11656     (clobber (match_scratch:DF 10 "=d"))
11657     (clobber (match_scratch:GPR 11 "=b"))]
11658   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11659    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11660   "#"
11661   "&& reload_completed"
11662   [(set (match_dup 3) (match_dup 14))
11663    (set (match_dup 4) (match_dup 15))
11664    (set (match_dup 9) (abs:DF (match_dup 5)))
11665    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11666    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11667                            (label_ref (match_dup 12))
11668                            (pc)))
11669    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11670    (set (pc) (label_ref (match_dup 13)))
11671    (match_dup 12)
11672    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11673    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11674    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11675    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11676    (match_dup 13)]
11678   REAL_VALUE_TYPE rv;
11679   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11680   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11682   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11683   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11684   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11685   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11686   operands[12] = gen_label_rtx ();
11687   operands[13] = gen_label_rtx ();
11688   real_inf (&rv);
11689   operands[14] = force_const_mem (DFmode,
11690                                   const_double_from_real_value (rv, DFmode));
11691   operands[15] = force_const_mem (DFmode,
11692                                   const_double_from_real_value (dconst0,
11693                                                                 DFmode));
11694   if (TARGET_TOC)
11695     {
11696       rtx tocref;
11697       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11698       operands[14] = gen_const_mem (DFmode, tocref);
11699       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11700       operands[15] = gen_const_mem (DFmode, tocref);
11701       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11702       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11703     }
11706 ;; Now we have the scc insns.  We can do some combinations because of the
11707 ;; way the machine works.
11709 ;; Note that this is probably faster if we can put an insn between the
11710 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11711 ;; cases the insns below which don't use an intermediate CR field will
11712 ;; be used instead.
11713 (define_insn ""
11714   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11715         (match_operator:SI 1 "scc_comparison_operator"
11716                            [(match_operand 2 "cc_reg_operand" "y")
11717                             (const_int 0)]))]
11718   ""
11719   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11720   [(set (attr "type")
11721      (cond [(match_test "TARGET_MFCRF")
11722                 (const_string "mfcrf")
11723            ]
11724         (const_string "mfcr")))
11725    (set_attr "length" "8")])
11727 (define_insn ""
11728   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11729         (match_operator:DI 1 "scc_comparison_operator"
11730                            [(match_operand 2 "cc_reg_operand" "y")
11731                             (const_int 0)]))]
11732   "TARGET_POWERPC64"
11733   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11734   [(set (attr "type")
11735      (cond [(match_test "TARGET_MFCRF")
11736                 (const_string "mfcrf")
11737            ]
11738         (const_string "mfcr")))
11739    (set_attr "length" "8")])
11741 (define_insn ""
11742   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11743         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11744                                        [(match_operand 2 "cc_reg_operand" "y,y")
11745                                         (const_int 0)])
11746                     (const_int 0)))
11747    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11748         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11749   "TARGET_32BIT"
11750   "@
11751    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11752    #"
11753   [(set_attr "type" "shift")
11754    (set_attr "dot" "yes")
11755    (set_attr "length" "8,16")])
11757 (define_split
11758   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11759         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11760                                        [(match_operand 2 "cc_reg_operand")
11761                                         (const_int 0)])
11762                     (const_int 0)))
11763    (set (match_operand:SI 3 "gpc_reg_operand")
11764         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11765   "TARGET_32BIT && reload_completed"
11766   [(set (match_dup 3)
11767         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11768    (set (match_dup 0)
11769         (compare:CC (match_dup 3)
11770                     (const_int 0)))]
11771   "")
11773 (define_insn ""
11774   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11775         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11776                                       [(match_operand 2 "cc_reg_operand" "y")
11777                                        (const_int 0)])
11778                    (match_operand:SI 3 "const_int_operand" "n")))]
11779   ""
11781   int is_bit = ccr_bit (operands[1], 1);
11782   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11783   int count;
11785   if (is_bit >= put_bit)
11786     count = is_bit - put_bit;
11787   else
11788     count = 32 - (put_bit - is_bit);
11790   operands[4] = GEN_INT (count);
11791   operands[5] = GEN_INT (put_bit);
11793   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11795   [(set (attr "type")
11796      (cond [(match_test "TARGET_MFCRF")
11797                 (const_string "mfcrf")
11798            ]
11799         (const_string "mfcr")))
11800    (set_attr "length" "8")])
11802 (define_insn ""
11803   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11804         (compare:CC
11805          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11806                                        [(match_operand 2 "cc_reg_operand" "y,y")
11807                                         (const_int 0)])
11808                     (match_operand:SI 3 "const_int_operand" "n,n"))
11809          (const_int 0)))
11810    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11811         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11812                    (match_dup 3)))]
11813   ""
11815   int is_bit = ccr_bit (operands[1], 1);
11816   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11817   int count;
11819   /* Force split for non-cc0 compare.  */
11820   if (which_alternative == 1)
11821      return "#";
11823   if (is_bit >= put_bit)
11824     count = is_bit - put_bit;
11825   else
11826     count = 32 - (put_bit - is_bit);
11828   operands[5] = GEN_INT (count);
11829   operands[6] = GEN_INT (put_bit);
11831   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11833   [(set_attr "type" "shift")
11834    (set_attr "dot" "yes")
11835    (set_attr "length" "8,16")])
11837 (define_split
11838   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11839         (compare:CC
11840          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11841                                        [(match_operand 2 "cc_reg_operand")
11842                                         (const_int 0)])
11843                     (match_operand:SI 3 "const_int_operand"))
11844          (const_int 0)))
11845    (set (match_operand:SI 4 "gpc_reg_operand")
11846         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11847                    (match_dup 3)))]
11848   "reload_completed"
11849   [(set (match_dup 4)
11850         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11851                    (match_dup 3)))
11852    (set (match_dup 0)
11853         (compare:CC (match_dup 4)
11854                     (const_int 0)))]
11855   "")
11858 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11859 (define_code_attr UNS [(eq "CC")
11860                        (ne "CC")
11861                        (lt "CC") (ltu "CCUNS")
11862                        (gt "CC") (gtu "CCUNS")
11863                        (le "CC") (leu "CCUNS")
11864                        (ge "CC") (geu "CCUNS")])
11865 (define_code_attr UNSu_ [(eq "")
11866                          (ne "")
11867                          (lt "") (ltu "u_")
11868                          (gt "") (gtu "u_")
11869                          (le "") (leu "u_")
11870                          (ge "") (geu "u_")])
11871 (define_code_attr UNSIK [(eq "I")
11872                          (ne "I")
11873                          (lt "I") (ltu "K")
11874                          (gt "I") (gtu "K")
11875                          (le "I") (leu "K")
11876                          (ge "I") (geu "K")])
11878 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11879   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11880         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11881                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11882    (clobber (match_scratch:GPR 3 "=r"))
11883    (clobber (match_scratch:GPR 4 "=r"))
11884    (clobber (match_scratch:<UNS> 5 "=y"))]
11885   "TARGET_ISEL
11886    && !(<CODE> == EQ && operands[2] == const0_rtx)
11887    && !(<CODE> == NE && operands[2] == const0_rtx
11888         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11889   "#"
11890   "&& 1"
11891   [(pc)]
11893   rtx_code code = <CODE>;
11894   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11895     {
11896       HOST_WIDE_INT val = INTVAL (operands[2]);
11897       if (code == LT && val != -0x8000)
11898         {
11899           code = LE;
11900           val--;
11901         }
11902       if (code == GT && val != 0x7fff)
11903         {
11904           code = GE;
11905           val++;
11906         }
11907       if (code == LTU && val != 0)
11908         {
11909           code = LEU;
11910           val--;
11911         }
11912       if (code == GTU && val != 0xffff)
11913         {
11914           code = GEU;
11915           val++;
11916         }
11917       operands[2] = GEN_INT (val);
11918     }
11920   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11921     operands[3] = const0_rtx;
11922   else
11923     {
11924       if (GET_CODE (operands[3]) == SCRATCH)
11925         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11926       emit_move_insn (operands[3], const0_rtx);
11927     }
11929   if (GET_CODE (operands[4]) == SCRATCH)
11930     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11931   emit_move_insn (operands[4], const1_rtx);
11933   if (GET_CODE (operands[5]) == SCRATCH)
11934     operands[5] = gen_reg_rtx (<UNS>mode);
11936   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11937   emit_insn (gen_rtx_SET (operands[5], c1));
11939   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11940   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11941   emit_move_insn (operands[0], x);
11943   DONE;
11945   [(set (attr "cost")
11946         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11947                                    || <CODE> == NE
11948                                    || <CODE> == LE || <CODE> == GE
11949                                    || <CODE> == LEU || <CODE> == GEU")
11950                       (const_string "9")
11951                       (const_string "10")))])
11953 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11954                               (DI "rKJI")])
11956 (define_expand "eq<mode>3"
11957   [(parallel [
11958      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11959           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11960                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11961      (clobber (match_scratch:GPR 3 "=r"))
11962      (clobber (match_scratch:GPR 4 "=r"))])]
11963   ""
11965   if (TARGET_ISEL && operands[2] != const0_rtx)
11966     {
11967       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11968                                            operands[2]));
11969       DONE;
11970     }
11973 (define_insn_and_split "*eq<mode>3"
11974   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11975         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11976                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11977    (clobber (match_scratch:GPR 3 "=r"))
11978    (clobber (match_scratch:GPR 4 "=r"))]
11979   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11980   "#"
11981   "&& 1"
11982   [(set (match_dup 4)
11983         (clz:GPR (match_dup 3)))
11984    (set (match_dup 0)
11985         (lshiftrt:GPR (match_dup 4)
11986                       (match_dup 5)))]
11988   operands[3] = rs6000_emit_eqne (<MODE>mode,
11989                                   operands[1], operands[2], operands[3]);
11991   if (GET_CODE (operands[4]) == SCRATCH)
11992     operands[4] = gen_reg_rtx (<MODE>mode);
11994   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11996   [(set (attr "length")
11997         (if_then_else (match_test "operands[2] == const0_rtx")
11998                       (const_string "8")
11999                       (const_string "12")))])
12001 (define_expand "ne<mode>3"
12002   [(parallel [
12003      (set (match_operand:P 0 "gpc_reg_operand" "=r")
12004           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12005                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12006      (clobber (match_scratch:P 3 "=r"))
12007      (clobber (match_scratch:P 4 "=r"))
12008      (clobber (reg:P CA_REGNO))])]
12009   ""
12011   if (TARGET_ISEL && operands[2] != const0_rtx)
12012     {
12013       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12014                                            operands[2]));
12015       DONE;
12016     }
12019 (define_insn_and_split "*ne<mode>3"
12020   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12021         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12022               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12023    (clobber (match_scratch:P 3 "=r"))
12024    (clobber (match_scratch:P 4 "=r"))
12025    (clobber (reg:P CA_REGNO))]
12026   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12027   "#"
12028   "&& 1"
12029   [(parallel [(set (match_dup 4)
12030                    (plus:P (match_dup 3)
12031                            (const_int -1)))
12032               (set (reg:P CA_REGNO)
12033                    (ne:P (match_dup 3)
12034                          (const_int 0)))])
12035    (parallel [(set (match_dup 0)
12036                    (plus:P (plus:P (not:P (match_dup 4))
12037                                    (reg:P CA_REGNO))
12038                            (match_dup 3)))
12039               (clobber (reg:P CA_REGNO))])]
12041   operands[3] = rs6000_emit_eqne (<MODE>mode,
12042                                   operands[1], operands[2], operands[3]);
12044   if (GET_CODE (operands[4]) == SCRATCH)
12045     operands[4] = gen_reg_rtx (<MODE>mode);
12047   [(set (attr "length")
12048         (if_then_else (match_test "operands[2] == const0_rtx")
12049                       (const_string "8")
12050                       (const_string "12")))])
12052 (define_insn_and_split "*neg_eq_<mode>"
12053   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12054         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12055                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12056    (clobber (match_scratch:P 3 "=r"))
12057    (clobber (match_scratch:P 4 "=r"))
12058    (clobber (reg:P CA_REGNO))]
12059   ""
12060   "#"
12061   ""
12062   [(parallel [(set (match_dup 4)
12063                    (plus:P (match_dup 3)
12064                            (const_int -1)))
12065               (set (reg:P CA_REGNO)
12066                    (ne:P (match_dup 3)
12067                          (const_int 0)))])
12068    (parallel [(set (match_dup 0)
12069                    (plus:P (reg:P CA_REGNO)
12070                            (const_int -1)))
12071               (clobber (reg:P CA_REGNO))])]
12073   operands[3] = rs6000_emit_eqne (<MODE>mode,
12074                                   operands[1], operands[2], operands[3]);
12076   if (GET_CODE (operands[4]) == SCRATCH)
12077     operands[4] = gen_reg_rtx (<MODE>mode);
12079   [(set (attr "length")
12080         (if_then_else (match_test "operands[2] == const0_rtx")
12081                       (const_string "8")
12082                       (const_string "12")))])
12084 (define_insn_and_split "*neg_ne_<mode>"
12085   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12086         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12087                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12088    (clobber (match_scratch:P 3 "=r"))
12089    (clobber (match_scratch:P 4 "=r"))
12090    (clobber (reg:P CA_REGNO))]
12091   ""
12092   "#"
12093   ""
12094   [(parallel [(set (match_dup 4)
12095                    (neg:P (match_dup 3)))
12096               (set (reg:P CA_REGNO)
12097                    (eq:P (match_dup 3)
12098                          (const_int 0)))])
12099    (parallel [(set (match_dup 0)
12100                    (plus:P (reg:P CA_REGNO)
12101                            (const_int -1)))
12102               (clobber (reg:P CA_REGNO))])]
12104   operands[3] = rs6000_emit_eqne (<MODE>mode,
12105                                   operands[1], operands[2], operands[3]);
12107   if (GET_CODE (operands[4]) == SCRATCH)
12108     operands[4] = gen_reg_rtx (<MODE>mode);
12110   [(set (attr "length")
12111         (if_then_else (match_test "operands[2] == const0_rtx")
12112                       (const_string "8")
12113                       (const_string "12")))])
12115 (define_insn_and_split "*plus_eq_<mode>"
12116   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12117         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12118                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12119                 (match_operand:P 3 "gpc_reg_operand" "r")))
12120    (clobber (match_scratch:P 4 "=r"))
12121    (clobber (match_scratch:P 5 "=r"))
12122    (clobber (reg:P CA_REGNO))]
12123   ""
12124   "#"
12125   ""
12126   [(parallel [(set (match_dup 5)
12127                    (neg:P (match_dup 4)))
12128               (set (reg:P CA_REGNO)
12129                    (eq:P (match_dup 4)
12130                          (const_int 0)))])
12131    (parallel [(set (match_dup 0)
12132                    (plus:P (match_dup 3)
12133                            (reg:P CA_REGNO)))
12134               (clobber (reg:P CA_REGNO))])]
12136   operands[4] = rs6000_emit_eqne (<MODE>mode,
12137                                   operands[1], operands[2], operands[4]);
12139   if (GET_CODE (operands[5]) == SCRATCH)
12140     operands[5] = gen_reg_rtx (<MODE>mode);
12142   [(set (attr "length")
12143         (if_then_else (match_test "operands[2] == const0_rtx")
12144                       (const_string "8")
12145                       (const_string "12")))])
12147 (define_insn_and_split "*plus_ne_<mode>"
12148   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12149         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12150                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12151                 (match_operand:P 3 "gpc_reg_operand" "r")))
12152    (clobber (match_scratch:P 4 "=r"))
12153    (clobber (match_scratch:P 5 "=r"))
12154    (clobber (reg:P CA_REGNO))]
12155   ""
12156   "#"
12157   ""
12158   [(parallel [(set (match_dup 5)
12159                    (plus:P (match_dup 4)
12160                            (const_int -1)))
12161               (set (reg:P CA_REGNO)
12162                    (ne:P (match_dup 4)
12163                          (const_int 0)))])
12164    (parallel [(set (match_dup 0)
12165                    (plus:P (match_dup 3)
12166                            (reg:P CA_REGNO)))
12167               (clobber (reg:P CA_REGNO))])]
12169   operands[4] = rs6000_emit_eqne (<MODE>mode,
12170                                   operands[1], operands[2], operands[4]);
12172   if (GET_CODE (operands[5]) == SCRATCH)
12173     operands[5] = gen_reg_rtx (<MODE>mode);
12175   [(set (attr "length")
12176         (if_then_else (match_test "operands[2] == const0_rtx")
12177                       (const_string "8")
12178                       (const_string "12")))])
12180 (define_insn_and_split "*minus_eq_<mode>"
12181   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12182         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12183                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12184                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12185    (clobber (match_scratch:P 4 "=r"))
12186    (clobber (match_scratch:P 5 "=r"))
12187    (clobber (reg:P CA_REGNO))]
12188   ""
12189   "#"
12190   ""
12191   [(parallel [(set (match_dup 5)
12192                    (plus:P (match_dup 4)
12193                            (const_int -1)))
12194               (set (reg:P CA_REGNO)
12195                    (ne:P (match_dup 4)
12196                          (const_int 0)))])
12197    (parallel [(set (match_dup 0)
12198                    (plus:P (plus:P (match_dup 3)
12199                                    (reg:P CA_REGNO))
12200                            (const_int -1)))
12201               (clobber (reg:P CA_REGNO))])]
12203   operands[4] = rs6000_emit_eqne (<MODE>mode,
12204                                   operands[1], operands[2], operands[4]);
12206   if (GET_CODE (operands[5]) == SCRATCH)
12207     operands[5] = gen_reg_rtx (<MODE>mode);
12209   [(set (attr "length")
12210         (if_then_else (match_test "operands[2] == const0_rtx")
12211                       (const_string "8")
12212                       (const_string "12")))])
12214 (define_insn_and_split "*minus_ne_<mode>"
12215   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12216         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12217                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12218                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12219    (clobber (match_scratch:P 4 "=r"))
12220    (clobber (match_scratch:P 5 "=r"))
12221    (clobber (reg:P CA_REGNO))]
12222   ""
12223   "#"
12224   ""
12225   [(parallel [(set (match_dup 5)
12226                    (neg:P (match_dup 4)))
12227               (set (reg:P CA_REGNO)
12228                    (eq:P (match_dup 4)
12229                          (const_int 0)))])
12230    (parallel [(set (match_dup 0)
12231                    (plus:P (plus:P (match_dup 3)
12232                                    (reg:P CA_REGNO))
12233                            (const_int -1)))
12234               (clobber (reg:P CA_REGNO))])]
12236   operands[4] = rs6000_emit_eqne (<MODE>mode,
12237                                   operands[1], operands[2], operands[4]);
12239   if (GET_CODE (operands[5]) == SCRATCH)
12240     operands[5] = gen_reg_rtx (<MODE>mode);
12242   [(set (attr "length")
12243         (if_then_else (match_test "operands[2] == const0_rtx")
12244                       (const_string "8")
12245                       (const_string "12")))])
12247 (define_insn_and_split "*eqsi3_ext<mode>"
12248   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12249         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12250                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12251    (clobber (match_scratch:SI 3 "=r"))
12252    (clobber (match_scratch:SI 4 "=r"))]
12253   ""
12254   "#"
12255   ""
12256   [(set (match_dup 4)
12257         (clz:SI (match_dup 3)))
12258    (set (match_dup 0)
12259         (zero_extend:EXTSI
12260           (lshiftrt:SI (match_dup 4)
12261                        (const_int 5))))]
12263   operands[3] = rs6000_emit_eqne (SImode,
12264                                   operands[1], operands[2], operands[3]);
12266   if (GET_CODE (operands[4]) == SCRATCH)
12267     operands[4] = gen_reg_rtx (SImode);
12269   [(set (attr "length")
12270         (if_then_else (match_test "operands[2] == const0_rtx")
12271                       (const_string "8")
12272                       (const_string "12")))])
12274 (define_insn_and_split "*nesi3_ext<mode>"
12275   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12276         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12277                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12278    (clobber (match_scratch:SI 3 "=r"))
12279    (clobber (match_scratch:SI 4 "=r"))
12280    (clobber (match_scratch:EXTSI 5 "=r"))]
12281   "!TARGET_ISEL"
12282   "#"
12283   "&& 1"
12284   [(set (match_dup 4)
12285         (clz:SI (match_dup 3)))
12286    (set (match_dup 5)
12287         (zero_extend:EXTSI
12288           (lshiftrt:SI (match_dup 4)
12289                        (const_int 5))))
12290    (set (match_dup 0)
12291         (xor:EXTSI (match_dup 5)
12292                    (const_int 1)))]
12294   operands[3] = rs6000_emit_eqne (SImode,
12295                                   operands[1], operands[2], operands[3]);
12297   if (GET_CODE (operands[4]) == SCRATCH)
12298     operands[4] = gen_reg_rtx (SImode);
12299   if (GET_CODE (operands[5]) == SCRATCH)
12300     operands[5] = gen_reg_rtx (<MODE>mode);
12302   [(set (attr "length")
12303         (if_then_else (match_test "operands[2] == const0_rtx")
12304                       (const_string "12")
12305                       (const_string "16")))])
12307 ;; Define both directions of branch and return.  If we need a reload
12308 ;; register, we'd rather use CR0 since it is much easier to copy a
12309 ;; register CC value to there.
12311 (define_insn ""
12312   [(set (pc)
12313         (if_then_else (match_operator 1 "branch_comparison_operator"
12314                                       [(match_operand 2 "cc_reg_operand" "y")
12315                                        (const_int 0)])
12316                       (label_ref (match_operand 0))
12317                       (pc)))]
12318   ""
12320   return output_cbranch (operands[1], "%l0", 0, insn);
12322   [(set_attr "type" "branch")])
12324 (define_insn ""
12325   [(set (pc)
12326         (if_then_else (match_operator 0 "branch_comparison_operator"
12327                                       [(match_operand 1 "cc_reg_operand" "y")
12328                                        (const_int 0)])
12329                       (any_return)
12330                       (pc)))]
12331   "<return_pred>"
12333   return output_cbranch (operands[0], NULL, 0, insn);
12335   [(set_attr "type" "jmpreg")
12336    (set_attr "length" "4")])
12338 ;; Logic on condition register values.
12340 ; This pattern matches things like
12341 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12342 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12343 ;                                  (const_int 1)))
12344 ; which are generated by the branch logic.
12345 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12347 (define_insn "cceq_ior_compare"
12348   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12349         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12350                         [(match_operator:SI 2
12351                                       "branch_positive_comparison_operator"
12352                                       [(match_operand 3
12353                                                       "cc_reg_operand" "y,y")
12354                                        (const_int 0)])
12355                          (match_operator:SI 4
12356                                       "branch_positive_comparison_operator"
12357                                       [(match_operand 5
12358                                                       "cc_reg_operand" "0,y")
12359                                        (const_int 0)])])
12360                       (const_int 1)))]
12361   ""
12362   "cr%q1 %E0,%j2,%j4"
12363   [(set_attr "type" "cr_logical")
12364    (set_attr "cr_logical_3op" "no,yes")])
12366 ; Why is the constant -1 here, but 1 in the previous pattern?
12367 ; Because ~1 has all but the low bit set.
12368 (define_insn "cceq_ior_compare_complement"
12369   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12370         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12371                         [(not:SI (match_operator:SI 2
12372                                       "branch_positive_comparison_operator"
12373                                       [(match_operand 3
12374                                                       "cc_reg_operand" "y,y")
12375                                        (const_int 0)]))
12376                          (match_operator:SI 4
12377                                 "branch_positive_comparison_operator"
12378                                 [(match_operand 5
12379                                                 "cc_reg_operand" "0,y")
12380                                  (const_int 0)])])
12381                       (const_int -1)))]
12382   ""
12383   "cr%q1 %E0,%j2,%j4"
12384   [(set_attr "type" "cr_logical")
12385    (set_attr "cr_logical_3op" "no,yes")])
12387 (define_insn "*cceq_rev_compare"
12388   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12389         (compare:CCEQ (match_operator:SI 1
12390                                       "branch_positive_comparison_operator"
12391                                       [(match_operand 2
12392                                                       "cc_reg_operand" "0,y")
12393                                        (const_int 0)])
12394                       (const_int 0)))]
12395   ""
12396   "crnot %E0,%j1"
12397   [(set_attr "type" "cr_logical")
12398    (set_attr "cr_logical_3op" "no,yes")])
12400 ;; If we are comparing the result of two comparisons, this can be done
12401 ;; using creqv or crxor.
12403 (define_insn_and_split ""
12404   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12405         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12406                               [(match_operand 2 "cc_reg_operand" "y")
12407                                (const_int 0)])
12408                       (match_operator 3 "branch_comparison_operator"
12409                               [(match_operand 4 "cc_reg_operand" "y")
12410                                (const_int 0)])))]
12411   ""
12412   "#"
12413   ""
12414   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12415                                     (match_dup 5)))]
12417   int positive_1, positive_2;
12419   positive_1 = branch_positive_comparison_operator (operands[1],
12420                                                     GET_MODE (operands[1]));
12421   positive_2 = branch_positive_comparison_operator (operands[3],
12422                                                     GET_MODE (operands[3]));
12424   if (! positive_1)
12425     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12426                                                             GET_CODE (operands[1])),
12427                                   SImode,
12428                                   operands[2], const0_rtx);
12429   else if (GET_MODE (operands[1]) != SImode)
12430     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12431                                   operands[2], const0_rtx);
12433   if (! positive_2)
12434     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12435                                                             GET_CODE (operands[3])),
12436                                   SImode,
12437                                   operands[4], const0_rtx);
12438   else if (GET_MODE (operands[3]) != SImode)
12439     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12440                                   operands[4], const0_rtx);
12442   if (positive_1 == positive_2)
12443     {
12444       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12445       operands[5] = constm1_rtx;
12446     }
12447   else
12448     {
12449       operands[5] = const1_rtx;
12450     }
12453 ;; Unconditional branch and return.
12455 (define_insn "jump"
12456   [(set (pc)
12457         (label_ref (match_operand 0)))]
12458   ""
12459   "b %l0"
12460   [(set_attr "type" "branch")])
12462 (define_insn "<return_str>return"
12463   [(any_return)]
12464   "<return_pred>"
12465   "blr"
12466   [(set_attr "type" "jmpreg")])
12468 (define_expand "indirect_jump"
12469   [(set (pc) (match_operand 0 "register_operand"))]
12470  ""
12472   if (!rs6000_speculate_indirect_jumps) {
12473     rtx ccreg = gen_reg_rtx (CCmode);
12474     if (Pmode == DImode)
12475       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12476     else
12477       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12478     DONE;
12479   }
12482 (define_insn "*indirect_jump<mode>"
12483   [(set (pc)
12484         (match_operand:P 0 "register_operand" "c,*l"))]
12485   "rs6000_speculate_indirect_jumps"
12486   "b%T0"
12487   [(set_attr "type" "jmpreg")])
12489 (define_insn "indirect_jump<mode>_nospec"
12490   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12491    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12492   "!rs6000_speculate_indirect_jumps"
12493   "crset %E1\;beq%T0- %1\;b $"
12494   [(set_attr "type" "jmpreg")
12495    (set_attr "length" "12")])
12497 ;; Table jump for switch statements:
12498 (define_expand "tablejump"
12499   [(use (match_operand 0))
12500    (use (label_ref (match_operand 1)))]
12501   ""
12503   if (rs6000_speculate_indirect_jumps)
12504     {
12505       if (TARGET_32BIT)
12506         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12507       else
12508         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12509     }
12510   else
12511     {
12512       rtx ccreg = gen_reg_rtx (CCmode);
12513       rtx jump;
12514       if (TARGET_32BIT)
12515         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12516       else
12517         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12518       emit_jump_insn (jump);
12519     }
12520   DONE;
12523 (define_expand "tablejumpsi"
12524   [(set (match_dup 3)
12525         (plus:SI (match_operand:SI 0)
12526                  (match_dup 2)))
12527    (parallel [(set (pc)
12528                    (match_dup 3))
12529               (use (label_ref (match_operand 1)))])]
12530   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12532   operands[0] = force_reg (SImode, operands[0]);
12533   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12534   operands[3] = gen_reg_rtx (SImode);
12537 (define_expand "tablejumpsi_nospec"
12538   [(set (match_dup 4)
12539         (plus:SI (match_operand:SI 0)
12540                  (match_dup 3)))
12541    (parallel [(set (pc)
12542                    (match_dup 4))
12543               (use (label_ref (match_operand 1)))
12544               (clobber (match_operand 2))])]
12545   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12547   operands[0] = force_reg (SImode, operands[0]);
12548   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12549   operands[4] = gen_reg_rtx (SImode);
12552 (define_expand "tablejumpdi"
12553   [(set (match_dup 4)
12554         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12555    (set (match_dup 3)
12556         (plus:DI (match_dup 4)
12557                  (match_dup 2)))
12558    (parallel [(set (pc)
12559                    (match_dup 3))
12560               (use (label_ref (match_operand 1)))])]
12561   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12563   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12564   operands[3] = gen_reg_rtx (DImode);
12565   operands[4] = gen_reg_rtx (DImode);
12568 (define_expand "tablejumpdi_nospec"
12569   [(set (match_dup 5)
12570         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12571    (set (match_dup 4)
12572         (plus:DI (match_dup 5)
12573                  (match_dup 3)))
12574    (parallel [(set (pc)
12575                    (match_dup 4))
12576               (use (label_ref (match_operand 1)))
12577               (clobber (match_operand 2))])]
12578   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12580   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12581   operands[4] = gen_reg_rtx (DImode);
12582   operands[5] = gen_reg_rtx (DImode);
12585 (define_insn "*tablejump<mode>_internal1"
12586   [(set (pc)
12587         (match_operand:P 0 "register_operand" "c,*l"))
12588    (use (label_ref (match_operand 1)))]
12589   "rs6000_speculate_indirect_jumps"
12590   "b%T0"
12591   [(set_attr "type" "jmpreg")])
12593 (define_insn "*tablejump<mode>_internal1_nospec"
12594   [(set (pc)
12595         (match_operand:P 0 "register_operand" "c,*l"))
12596    (use (label_ref (match_operand 1)))
12597    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12598   "!rs6000_speculate_indirect_jumps"
12599   "crset %E2\;beq%T0- %2\;b $"
12600   [(set_attr "type" "jmpreg")
12601    (set_attr "length" "12")])
12603 (define_insn "nop"
12604   [(unspec [(const_int 0)] UNSPEC_NOP)]
12605   ""
12606   "nop")
12608 (define_insn "group_ending_nop"
12609   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12610   ""
12612   if (rs6000_tune == PROCESSOR_POWER6)
12613     return "ori 1,1,0";
12614   return "ori 2,2,0";
12617 (define_insn "rs6000_speculation_barrier"
12618   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12619   ""
12620   "ori 31,31,0")
12622 ;; Define the subtract-one-and-jump insns, starting with the template
12623 ;; so loop.c knows what to generate.
12625 (define_expand "doloop_end"
12626   [(use (match_operand 0))      ; loop pseudo
12627    (use (match_operand 1))]     ; label
12628   ""
12630   if (TARGET_64BIT)
12631     {
12632       if (GET_MODE (operands[0]) != DImode)
12633         FAIL;
12634       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12635     }
12636   else
12637     {
12638       if (GET_MODE (operands[0]) != SImode)
12639         FAIL;
12640       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12641     }
12642   DONE;
12645 (define_expand "ctr<mode>"
12646   [(parallel [(set (pc)
12647                    (if_then_else (ne (match_operand:P 0 "register_operand")
12648                                      (const_int 1))
12649                                  (label_ref (match_operand 1))
12650                                  (pc)))
12651               (set (match_dup 0)
12652                    (plus:P (match_dup 0)
12653                             (const_int -1)))
12654               (clobber (match_scratch:CC 2))
12655               (clobber (match_scratch:P 3))])]
12656   ""
12657   "")
12659 ;; We need to be able to do this for any operand, including MEM, or we
12660 ;; will cause reload to blow up since we don't allow output reloads on
12661 ;; JUMP_INSNs.
12662 ;; For the length attribute to be calculated correctly, the
12663 ;; label MUST be operand 0.
12664 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12665 ;; the ctr<mode> insns.
12667 (define_code_iterator eqne [eq ne])
12668 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12669 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12671 (define_insn "<bd>_<mode>"
12672   [(set (pc)
12673         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12674                           (const_int 1))
12675                       (label_ref (match_operand 0))
12676                       (pc)))
12677    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12678         (plus:P (match_dup 1)
12679                 (const_int -1)))
12680    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12681    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12682   ""
12684   if (which_alternative != 0)
12685     return "#";
12686   else if (get_attr_length (insn) == 4)
12687     return "<bd> %l0";
12688   else
12689     return "<bd_neg> $+8\;b %l0";
12691   [(set_attr "type" "branch")
12692    (set_attr "length" "*,16,20,20")])
12694 ;; Now the splitter if we could not allocate the CTR register
12695 (define_split
12696   [(set (pc)
12697         (if_then_else (match_operator 2 "comparison_operator"
12698                                       [(match_operand:P 1 "gpc_reg_operand")
12699                                        (const_int 1)])
12700                       (match_operand 5)
12701                       (match_operand 6)))
12702    (set (match_operand:P 0 "nonimmediate_operand")
12703         (plus:P (match_dup 1)
12704                 (const_int -1)))
12705    (clobber (match_scratch:CC 3))
12706    (clobber (match_scratch:P 4))]
12707   "reload_completed"
12708   [(set (pc)
12709         (if_then_else (match_dup 7)
12710                       (match_dup 5)
12711                       (match_dup 6)))]
12713   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12714                                 const0_rtx);
12715   emit_insn (gen_rtx_SET (operands[3],
12716                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12717   if (gpc_reg_operand (operands[0], <MODE>mode))
12718     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12719   else
12720     {
12721       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12722       emit_move_insn (operands[0], operands[4]);
12723     } 
12724     /* No DONE so branch comes from the pattern.  */
12727 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12728 ;; Note that in the case of long branches we have to decompose this into
12729 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12730 ;; and the CR bit, which means there is no way to conveniently invert the
12731 ;; comparison as is done with plain bdnz/bdz.
12733 (define_insn "<bd>tf_<mode>"
12734   [(set (pc)
12735         (if_then_else
12736           (and
12737              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12738                    (const_int 1))
12739              (match_operator 3 "branch_comparison_operator"
12740                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12741                        (const_int 0)]))
12742           (label_ref (match_operand 0))
12743           (pc)))
12744    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12745         (plus:P (match_dup 1)
12746                 (const_int -1)))
12747    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12748    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12749    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12750   ""
12752   if (which_alternative != 0)
12753     return "#";
12754   else if (get_attr_length (insn) == 4)
12755     {
12756       if (branch_positive_comparison_operator (operands[3],
12757                                                GET_MODE (operands[3])))
12758         return "<bd>t %j3,%l0";
12759       else
12760         return "<bd>f %j3,%l0";
12761     }
12762   else
12763     {
12764       static char seq[96];
12765       char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12766       sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12767       return seq;
12768     }
12770   [(set_attr "type" "branch")
12771    (set_attr "length" "*,16,20,20")])
12773 ;; Now the splitter if we could not allocate the CTR register
12774 (define_split
12775   [(set (pc)
12776         (if_then_else
12777           (and
12778              (match_operator 1 "comparison_operator"
12779                              [(match_operand:P 0 "gpc_reg_operand")
12780                               (const_int 1)])
12781              (match_operator 3 "branch_comparison_operator"
12782                       [(match_operand 2 "cc_reg_operand")
12783                        (const_int 0)]))
12784           (match_operand 4)
12785           (match_operand 5)))
12786    (set (match_operand:P 6 "int_reg_operand")
12787         (plus:P (match_dup 0)
12788                 (const_int -1)))
12789    (clobber (match_scratch:P 7))
12790    (clobber (match_scratch:CC 8))
12791    (clobber (match_scratch:CCEQ 9))]
12792   "reload_completed"
12793 [(pc)]
12795   rtx ctr = operands[0];
12796   rtx ctrcmp = operands[1];
12797   rtx ccin = operands[2];
12798   rtx cccmp = operands[3];
12799   rtx dst1 = operands[4];
12800   rtx dst2 = operands[5];
12801   rtx ctrout = operands[6];
12802   rtx ctrtmp = operands[7];
12803   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12804   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12805   if (!ispos)
12806     cmpcode = reverse_condition (cmpcode);
12807   /* Generate crand/crandc here.  */
12808   emit_insn (gen_rtx_SET (operands[8],
12809                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12810   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12812   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12813   if (ispos)
12814      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12815                                       operands[8], cccmp, ccin));
12816   else
12817      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12818                                                  operands[8], cccmp, ccin));
12819   if (gpc_reg_operand (operands[0], <MODE>mode))
12820      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12821   else
12822     {
12823       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12824       emit_move_insn (ctrout, ctrtmp);
12825     }
12826   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12827   emit_jump_insn (gen_rtx_SET (pc_rtx,
12828                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12829                                                      dst1, dst2)));
12830   DONE;
12834 (define_insn "trap"
12835   [(trap_if (const_int 1) (const_int 0))]
12836   ""
12837   "trap"
12838   [(set_attr "type" "trap")])
12840 (define_expand "ctrap<mode>4"
12841   [(trap_if (match_operator 0 "ordered_comparison_operator"
12842                             [(match_operand:GPR 1 "register_operand")
12843                              (match_operand:GPR 2 "reg_or_short_operand")])
12844             (match_operand 3 "zero_constant" ""))]
12845   ""
12846   "")
12848 (define_insn ""
12849   [(trap_if (match_operator 0 "ordered_comparison_operator"
12850                             [(match_operand:GPR 1 "register_operand" "r")
12851                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12852             (const_int 0))]
12853   ""
12854   "t<wd>%V0%I2 %1,%2"
12855   [(set_attr "type" "trap")])
12857 ;; Insns related to generating the function prologue and epilogue.
12859 (define_expand "prologue"
12860   [(use (const_int 0))]
12861   ""
12863   rs6000_emit_prologue ();
12864   if (!TARGET_SCHED_PROLOG)
12865     emit_insn (gen_blockage ());
12866   DONE;
12869 (define_insn "*movesi_from_cr_one"
12870   [(match_parallel 0 "mfcr_operation"
12871                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12872                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12873                                      (match_operand 3 "immediate_operand" "n")]
12874                           UNSPEC_MOVESI_FROM_CR))])]
12875   "TARGET_MFCRF"
12877   int mask = 0;
12878   int i;
12879   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12880   {
12881     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12882     operands[4] = GEN_INT (mask);
12883     output_asm_insn ("mfcr %1,%4", operands);
12884   }
12885   return "";
12887   [(set_attr "type" "mfcrf")])
12889 ;; Don't include the volatile CRs since their values are not used wrt CR save
12890 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12891 ;; prologue past an insn (early exit test) that defines a register used in the
12892 ;; prologue.
12893 (define_insn "prologue_movesi_from_cr"
12894   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12895         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12896                     (reg:CC CR4_REGNO)]
12897                    UNSPEC_MOVESI_FROM_CR))]
12898   ""
12899   "mfcr %0"
12900   [(set_attr "type" "mfcr")])
12902 (define_insn "*crsave"
12903   [(match_parallel 0 "crsave_operation"
12904                    [(set (match_operand:SI 1 "memory_operand" "=m")
12905                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12906   ""
12907   "stw %2,%1"
12908   [(set_attr "type" "store")])
12910 (define_insn "*stmw"
12911   [(match_parallel 0 "stmw_operation"
12912                    [(set (match_operand:SI 1 "memory_operand" "=m")
12913                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12914   "TARGET_MULTIPLE"
12915   "stmw %2,%1"
12916   [(set_attr "type" "store")
12917    (set_attr "update" "yes")
12918    (set_attr "indexed" "yes")])
12920 ; The following comment applies to:
12921 ;     save_gpregs_*
12922 ;     save_fpregs_*
12923 ;     restore_gpregs*
12924 ;     return_and_restore_gpregs*
12925 ;     return_and_restore_fpregs*
12926 ;     return_and_restore_fpregs_aix*
12928 ; The out-of-line save / restore functions expects one input argument.
12929 ; Since those are not standard call_insn's, we must avoid using
12930 ; MATCH_OPERAND for that argument. That way the register rename
12931 ; optimization will not try to rename this register.
12932 ; Each pattern is repeated for each possible register number used in 
12933 ; various ABIs (r11, r1, and for some functions r12)
12935 (define_insn "*save_gpregs_<mode>_r11"
12936   [(match_parallel 0 "any_parallel_operand"
12937                    [(clobber (reg:P LR_REGNO))
12938                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12939                     (use (reg:P 11))
12940                     (set (match_operand:P 2 "memory_operand" "=m")
12941                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12942   ""
12943   "bl %1"
12944   [(set_attr "type" "branch")
12945    (set_attr "length" "4")])
12947 (define_insn "*save_gpregs_<mode>_r12"
12948   [(match_parallel 0 "any_parallel_operand"
12949                    [(clobber (reg:P LR_REGNO))
12950                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12951                     (use (reg:P 12))
12952                     (set (match_operand:P 2 "memory_operand" "=m")
12953                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12954   ""
12955   "bl %1"
12956   [(set_attr "type" "branch")
12957    (set_attr "length" "4")])
12959 (define_insn "*save_gpregs_<mode>_r1"
12960   [(match_parallel 0 "any_parallel_operand"
12961                    [(clobber (reg:P LR_REGNO))
12962                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12963                     (use (reg:P 1))
12964                     (set (match_operand:P 2 "memory_operand" "=m")
12965                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12966   ""
12967   "bl %1"
12968   [(set_attr "type" "branch")
12969    (set_attr "length" "4")])
12971 (define_insn "*save_fpregs_<mode>_r11"
12972   [(match_parallel 0 "any_parallel_operand"
12973                    [(clobber (reg:P LR_REGNO))
12974                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12975                     (use (reg:P 11))
12976                     (set (match_operand:DF 2 "memory_operand" "=m")
12977                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12978   ""
12979   "bl %1"
12980   [(set_attr "type" "branch")
12981    (set_attr "length" "4")])
12983 (define_insn "*save_fpregs_<mode>_r12"
12984   [(match_parallel 0 "any_parallel_operand"
12985                    [(clobber (reg:P LR_REGNO))
12986                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12987                     (use (reg:P 12))
12988                     (set (match_operand:DF 2 "memory_operand" "=m")
12989                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12990   ""
12991   "bl %1"
12992   [(set_attr "type" "branch")
12993    (set_attr "length" "4")])
12995 (define_insn "*save_fpregs_<mode>_r1"
12996   [(match_parallel 0 "any_parallel_operand"
12997                    [(clobber (reg:P LR_REGNO))
12998                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12999                     (use (reg:P 1))
13000                     (set (match_operand:DF 2 "memory_operand" "=m")
13001                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13002   ""
13003   "bl %1"
13004   [(set_attr "type" "branch")
13005    (set_attr "length" "4")])
13007 ; This is to explain that changes to the stack pointer should
13008 ; not be moved over loads from or stores to stack memory.
13009 (define_insn "stack_tie"
13010   [(match_parallel 0 "tie_operand"
13011                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13012   ""
13013   ""
13014   [(set_attr "length" "0")])
13016 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13017 ; stay behind all restores from the stack, it cannot be reordered to before
13018 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13019 (define_insn "stack_restore_tie"
13020   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13021         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13022                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13023    (set (mem:BLK (scratch)) (const_int 0))]
13024   "TARGET_32BIT"
13025   "@
13026    mr %0,%1
13027    add%I2 %0,%1,%2"
13028   [(set_attr "type" "*,add")])
13030 (define_expand "epilogue"
13031   [(use (const_int 0))]
13032   ""
13034   if (!TARGET_SCHED_PROLOG)
13035     emit_insn (gen_blockage ());
13036   rs6000_emit_epilogue (FALSE);
13037   DONE;
13040 ; On some processors, doing the mtcrf one CC register at a time is
13041 ; faster (like on the 604e).  On others, doing them all at once is
13042 ; faster; for instance, on the 601 and 750.
13044 (define_expand "movsi_to_cr_one"
13045   [(set (match_operand:CC 0 "cc_reg_operand")
13046         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13047                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13048   ""
13049   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13051 (define_insn "*movsi_to_cr"
13052   [(match_parallel 0 "mtcrf_operation"
13053                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13054                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13055                                      (match_operand 3 "immediate_operand" "n")]
13056                                     UNSPEC_MOVESI_TO_CR))])]
13057  ""
13059   int mask = 0;
13060   int i;
13061   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13062     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13063   operands[4] = GEN_INT (mask);
13064   return "mtcrf %4,%2";
13066   [(set_attr "type" "mtcr")])
13068 (define_insn "*mtcrfsi"
13069   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13070         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13071                     (match_operand 2 "immediate_operand" "n")]
13072                    UNSPEC_MOVESI_TO_CR))]
13073   "GET_CODE (operands[0]) == REG
13074    && CR_REGNO_P (REGNO (operands[0]))
13075    && GET_CODE (operands[2]) == CONST_INT
13076    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13077   "mtcrf %R0,%1"
13078   [(set_attr "type" "mtcr")])
13080 ; The load-multiple instructions have similar properties.
13081 ; Note that "load_multiple" is a name known to the machine-independent
13082 ; code that actually corresponds to the PowerPC load-string.
13084 (define_insn "*lmw"
13085   [(match_parallel 0 "lmw_operation"
13086                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13087                          (match_operand:SI 2 "memory_operand" "m"))])]
13088   "TARGET_MULTIPLE"
13089   "lmw %1,%2"
13090   [(set_attr "type" "load")
13091    (set_attr "update" "yes")
13092    (set_attr "indexed" "yes")
13093    (set_attr "cell_micro" "always")])
13095 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13096 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13098 ; The following comment applies to:
13099 ;     save_gpregs_*
13100 ;     save_fpregs_*
13101 ;     restore_gpregs*
13102 ;     return_and_restore_gpregs*
13103 ;     return_and_restore_fpregs*
13104 ;     return_and_restore_fpregs_aix*
13106 ; The out-of-line save / restore functions expects one input argument.
13107 ; Since those are not standard call_insn's, we must avoid using
13108 ; MATCH_OPERAND for that argument. That way the register rename
13109 ; optimization will not try to rename this register.
13110 ; Each pattern is repeated for each possible register number used in 
13111 ; various ABIs (r11, r1, and for some functions r12)
13113 (define_insn "*restore_gpregs_<mode>_r11"
13114  [(match_parallel 0 "any_parallel_operand"
13115                   [(clobber (reg:P LR_REGNO))
13116                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13117                    (use (reg:P 11))
13118                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13119                         (match_operand:P 3 "memory_operand" "m"))])]
13120  ""
13121  "bl %1"
13122  [(set_attr "type" "branch")
13123   (set_attr "length" "4")])
13125 (define_insn "*restore_gpregs_<mode>_r12"
13126  [(match_parallel 0 "any_parallel_operand"
13127                   [(clobber (reg:P LR_REGNO))
13128                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13129                    (use (reg:P 12))
13130                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13131                         (match_operand:P 3 "memory_operand" "m"))])]
13132  ""
13133  "bl %1"
13134  [(set_attr "type" "branch")
13135   (set_attr "length" "4")])
13137 (define_insn "*restore_gpregs_<mode>_r1"
13138  [(match_parallel 0 "any_parallel_operand"
13139                   [(clobber (reg:P LR_REGNO))
13140                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13141                    (use (reg:P 1))
13142                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13143                         (match_operand:P 3 "memory_operand" "m"))])]
13144  ""
13145  "bl %1"
13146  [(set_attr "type" "branch")
13147   (set_attr "length" "4")])
13149 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13150  [(match_parallel 0 "any_parallel_operand"
13151                   [(return)
13152                    (clobber (reg:P LR_REGNO))
13153                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13154                    (use (reg:P 11))
13155                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13156                         (match_operand:P 3 "memory_operand" "m"))])]
13157  ""
13158  "b %1"
13159  [(set_attr "type" "branch")
13160   (set_attr "length" "4")])
13162 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13163  [(match_parallel 0 "any_parallel_operand"
13164                   [(return)
13165                    (clobber (reg:P LR_REGNO))
13166                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13167                    (use (reg:P 12))
13168                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13169                         (match_operand:P 3 "memory_operand" "m"))])]
13170  ""
13171  "b %1"
13172  [(set_attr "type" "branch")
13173   (set_attr "length" "4")])
13175 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13176  [(match_parallel 0 "any_parallel_operand"
13177                   [(return)
13178                    (clobber (reg:P LR_REGNO))
13179                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13180                    (use (reg:P 1))
13181                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13182                         (match_operand:P 3 "memory_operand" "m"))])]
13183  ""
13184  "b %1"
13185  [(set_attr "type" "branch")
13186   (set_attr "length" "4")])
13188 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13189  [(match_parallel 0 "any_parallel_operand"
13190                   [(return)
13191                    (clobber (reg:P LR_REGNO))
13192                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13193                    (use (reg:P 11))
13194                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13195                         (match_operand:DF 3 "memory_operand" "m"))])]
13196  ""
13197  "b %1"
13198  [(set_attr "type" "branch")
13199   (set_attr "length" "4")])
13201 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13202  [(match_parallel 0 "any_parallel_operand"
13203                   [(return)
13204                    (clobber (reg:P LR_REGNO))
13205                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13206                    (use (reg:P 12))
13207                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13208                         (match_operand:DF 3 "memory_operand" "m"))])]
13209  ""
13210  "b %1"
13211  [(set_attr "type" "branch")
13212   (set_attr "length" "4")])
13214 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13215  [(match_parallel 0 "any_parallel_operand"
13216                   [(return)
13217                    (clobber (reg:P LR_REGNO))
13218                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13219                    (use (reg:P 1))
13220                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13221                         (match_operand:DF 3 "memory_operand" "m"))])]
13222  ""
13223  "b %1"
13224  [(set_attr "type" "branch")
13225   (set_attr "length" "4")])
13227 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13228  [(match_parallel 0 "any_parallel_operand"
13229                   [(return)
13230                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13231                    (use (reg:P 11))
13232                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13233                         (match_operand:DF 3 "memory_operand" "m"))])]
13234  ""
13235  "b %1"
13236  [(set_attr "type" "branch")
13237   (set_attr "length" "4")])
13239 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13240  [(match_parallel 0 "any_parallel_operand"
13241                   [(return)
13242                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13243                    (use (reg:P 1))
13244                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13245                         (match_operand:DF 3 "memory_operand" "m"))])]
13246  ""
13247  "b %1"
13248  [(set_attr "type" "branch")
13249   (set_attr "length" "4")])
13251 ; This is used in compiling the unwind routines.
13252 (define_expand "eh_return"
13253   [(use (match_operand 0 "general_operand"))]
13254   ""
13256   if (TARGET_32BIT)
13257     emit_insn (gen_eh_set_lr_si (operands[0]));
13258   else
13259     emit_insn (gen_eh_set_lr_di (operands[0]));
13260   DONE;
13263 ; We can't expand this before we know where the link register is stored.
13264 (define_insn "eh_set_lr_<mode>"
13265   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13266                     UNSPECV_EH_RR)
13267    (clobber (match_scratch:P 1 "=&b"))]
13268   ""
13269   "#")
13271 (define_split
13272   [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13273    (clobber (match_scratch 1))]
13274   "reload_completed"
13275   [(const_int 0)]
13277   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13278   DONE;
13281 (define_insn "prefetch"
13282   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13283              (match_operand:SI 1 "const_int_operand" "n")
13284              (match_operand:SI 2 "const_int_operand" "n"))]
13285   ""
13289   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13290      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13291      The AIX assembler does not support the three operand form of dcbt
13292      and dcbtst on Power 7 (-mpwr7).  */
13293   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13295   if (REG_P (operands[0]))
13296     {
13297       if (INTVAL (operands[1]) == 0)
13298         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13299       else
13300         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13301     }
13302   else
13303     {
13304       if (INTVAL (operands[1]) == 0)
13305         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13306       else
13307         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13308     }
13310   [(set_attr "type" "load")])
13312 ;; Handle -fsplit-stack.
13314 (define_expand "split_stack_prologue"
13315   [(const_int 0)]
13316   ""
13318   rs6000_expand_split_stack_prologue ();
13319   DONE;
13322 (define_expand "load_split_stack_limit"
13323   [(set (match_operand 0)
13324         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13325   ""
13327   emit_insn (gen_rtx_SET (operands[0],
13328                           gen_rtx_UNSPEC (Pmode,
13329                                           gen_rtvec (1, const0_rtx),
13330                                           UNSPEC_STACK_CHECK)));
13331   DONE;
13334 (define_insn "load_split_stack_limit_di"
13335   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13336         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13337   "TARGET_64BIT"
13338   "ld %0,-0x7040(13)"
13339   [(set_attr "type" "load")
13340    (set_attr "update" "no")
13341    (set_attr "indexed" "no")])
13343 (define_insn "load_split_stack_limit_si"
13344   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13345         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13346   "!TARGET_64BIT"
13347   "lwz %0,-0x7020(2)"
13348   [(set_attr "type" "load")
13349    (set_attr "update" "no")
13350    (set_attr "indexed" "no")])
13352 ;; A return instruction which the middle-end doesn't see.
13353 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13354 ;; after the call to __morestack.
13355 (define_insn "split_stack_return"
13356   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13357   ""
13358   "blr"
13359   [(set_attr "type" "jmpreg")])
13361 ;; If there are operand 0 bytes available on the stack, jump to
13362 ;; operand 1.
13363 (define_expand "split_stack_space_check"
13364   [(set (match_dup 2)
13365         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13366    (set (match_dup 3)
13367         (minus (reg STACK_POINTER_REGNUM)
13368                (match_operand 0)))
13369    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13370    (set (pc) (if_then_else
13371               (geu (match_dup 4) (const_int 0))
13372               (label_ref (match_operand 1))
13373               (pc)))]
13374   ""
13376   rs6000_split_stack_space_check (operands[0], operands[1]);
13377   DONE;
13380 (define_insn "bpermd_<mode>"
13381   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13382         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13383                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13384   "TARGET_POPCNTD"
13385   "bpermd %0,%1,%2"
13386   [(set_attr "type" "popcnt")])
13389 ;; Builtin fma support.  Handle 
13390 ;; Note that the conditions for expansion are in the FMA_F iterator.
13392 (define_expand "fma<mode>4"
13393   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13394         (fma:FMA_F
13395           (match_operand:FMA_F 1 "gpc_reg_operand")
13396           (match_operand:FMA_F 2 "gpc_reg_operand")
13397           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13398   ""
13399   "")
13401 (define_insn "*fma<mode>4_fpr"
13402   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13403         (fma:SFDF
13404           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13405           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13406           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13407   "TARGET_HARD_FLOAT"
13408   "@
13409    fmadd<Ftrad> %0,%1,%2,%3
13410    xsmadda<Fvsx> %x0,%x1,%x2
13411    xsmaddm<Fvsx> %x0,%x1,%x3"
13412   [(set_attr "type" "fp")])
13414 ; Altivec only has fma and nfms.
13415 (define_expand "fms<mode>4"
13416   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13417         (fma:FMA_F
13418           (match_operand:FMA_F 1 "gpc_reg_operand")
13419           (match_operand:FMA_F 2 "gpc_reg_operand")
13420           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13421   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13422   "")
13424 (define_insn "*fms<mode>4_fpr"
13425   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13426         (fma:SFDF
13427          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13428          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13429          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13430   "TARGET_HARD_FLOAT"
13431   "@
13432    fmsub<Ftrad> %0,%1,%2,%3
13433    xsmsuba<Fvsx> %x0,%x1,%x2
13434    xsmsubm<Fvsx> %x0,%x1,%x3"
13435   [(set_attr "type" "fp")])
13437 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13438 (define_expand "fnma<mode>4"
13439   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13440         (neg:FMA_F
13441           (fma:FMA_F
13442             (match_operand:FMA_F 1 "gpc_reg_operand")
13443             (match_operand:FMA_F 2 "gpc_reg_operand")
13444             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13445   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13446   "")
13448 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13449 (define_expand "fnms<mode>4"
13450   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13451         (neg:FMA_F
13452           (fma:FMA_F
13453             (match_operand:FMA_F 1 "gpc_reg_operand")
13454             (match_operand:FMA_F 2 "gpc_reg_operand")
13455             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13456   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13457   "")
13459 ; Not an official optab name, but used from builtins.
13460 (define_expand "nfma<mode>4"
13461   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13462         (neg:FMA_F
13463           (fma:FMA_F
13464             (match_operand:FMA_F 1 "gpc_reg_operand")
13465             (match_operand:FMA_F 2 "gpc_reg_operand")
13466             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13467   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13468   "")
13470 (define_insn "*nfma<mode>4_fpr"
13471   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13472         (neg:SFDF
13473          (fma:SFDF
13474           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13475           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13476           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13477   "TARGET_HARD_FLOAT"
13478   "@
13479    fnmadd<Ftrad> %0,%1,%2,%3
13480    xsnmadda<Fvsx> %x0,%x1,%x2
13481    xsnmaddm<Fvsx> %x0,%x1,%x3"
13482   [(set_attr "type" "fp")])
13484 ; Not an official optab name, but used from builtins.
13485 (define_expand "nfms<mode>4"
13486   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13487         (neg:FMA_F
13488           (fma:FMA_F
13489             (match_operand:FMA_F 1 "gpc_reg_operand")
13490             (match_operand:FMA_F 2 "gpc_reg_operand")
13491             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13492   ""
13493   "")
13495 (define_insn "*nfmssf4_fpr"
13496   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13497         (neg:SFDF
13498          (fma:SFDF
13499           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13500           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13501           (neg:SFDF
13502            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13503   "TARGET_HARD_FLOAT"
13504   "@
13505    fnmsub<Ftrad> %0,%1,%2,%3
13506    xsnmsuba<Fvsx> %x0,%x1,%x2
13507    xsnmsubm<Fvsx> %x0,%x1,%x3"
13508   [(set_attr "type" "fp")])
13511 (define_expand "rs6000_get_timebase"
13512   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13513   ""
13515   if (TARGET_POWERPC64)
13516     emit_insn (gen_rs6000_mftb_di (operands[0]));
13517   else
13518     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13519   DONE;
13522 (define_insn "rs6000_get_timebase_ppc32"
13523   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13524         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13525    (clobber (match_scratch:SI 1 "=r"))
13526    (clobber (match_scratch:CC 2 "=y"))]
13527   "!TARGET_POWERPC64"
13529   if (WORDS_BIG_ENDIAN)
13530     if (TARGET_MFCRF)
13531       {
13532         return "mfspr %0,269\;"
13533                "mfspr %L0,268\;"
13534                "mfspr %1,269\;"
13535                "cmpw %2,%0,%1\;"
13536                "bne- %2,$-16";
13537       }
13538     else
13539       {
13540         return "mftbu %0\;"
13541                "mftb %L0\;"
13542                "mftbu %1\;"
13543                "cmpw %2,%0,%1\;"
13544                "bne- %2,$-16";
13545       }
13546   else
13547     if (TARGET_MFCRF)
13548       {
13549         return "mfspr %L0,269\;"
13550                "mfspr %0,268\;"
13551                "mfspr %1,269\;"
13552                "cmpw %2,%L0,%1\;"
13553                "bne- %2,$-16";
13554       }
13555     else
13556       {
13557         return "mftbu %L0\;"
13558                "mftb %0\;"
13559                "mftbu %1\;"
13560                "cmpw %2,%L0,%1\;"
13561                "bne- %2,$-16";
13562       }
13564   [(set_attr "length" "20")])
13566 (define_insn "rs6000_mftb_<mode>"
13567   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13568         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13569   ""
13571   if (TARGET_MFCRF)
13572     return "mfspr %0,268";
13573   else
13574     return "mftb %0";
13578 (define_insn "rs6000_mffs"
13579   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13580         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13581   "TARGET_HARD_FLOAT"
13582   "mffs %0")
13584 (define_insn "rs6000_mtfsf"
13585   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13586                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13587                     UNSPECV_MTFSF)]
13588   "TARGET_HARD_FLOAT"
13589   "mtfsf %0,%1")
13592 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13593 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13594 ;; register that is being loaded.  The fused ops must be physically adjacent.
13596 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13597 ;; before register allocation, and is meant to reduce the lifetime for the
13598 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13599 ;; to use the register that is being load.  The peephole2 then gathers any
13600 ;; other fused possibilities that it can find after register allocation.  If
13601 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13603 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13604 ;; before register allocation, so that we can avoid allocating a temporary base
13605 ;; register that won't be used, and that we try to load into base registers,
13606 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13607 ;; (addis followed by load) even on power8.
13609 (define_split
13610   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13611         (match_operand:INT1 1 "toc_fusion_mem_raw"))]
13612   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13613   [(parallel [(set (match_dup 0) (match_dup 2))
13614               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13615               (use (match_dup 3))
13616               (clobber (scratch:DI))])]
13618   operands[2] = fusion_wrap_memory_address (operands[1]);
13619   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13622 (define_insn "*toc_fusionload_<mode>"
13623   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13624         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13625    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13626    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13627    (clobber (match_scratch:DI 3 "=X,&b"))]
13628   "TARGET_TOC_FUSION_INT"
13630   if (base_reg_operand (operands[0], <MODE>mode))
13631     return emit_fusion_gpr_load (operands[0], operands[1]);
13633   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13635   [(set_attr "type" "load")
13636    (set_attr "length" "8")])
13638 (define_insn "*toc_fusionload_di"
13639   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13640         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13641    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13642    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13643    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13644   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13645    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13647   if (base_reg_operand (operands[0], DImode))
13648     return emit_fusion_gpr_load (operands[0], operands[1]);
13650   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13652   [(set_attr "type" "load")
13653    (set_attr "length" "8")])
13656 ;; Find cases where the addis that feeds into a load instruction is either used
13657 ;; once or is the same as the target register, and replace it with the fusion
13658 ;; insn
13660 (define_peephole2
13661   [(set (match_operand:P 0 "base_reg_operand")
13662         (match_operand:P 1 "fusion_gpr_addis"))
13663    (set (match_operand:INT1 2 "base_reg_operand")
13664         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13665   "TARGET_P8_FUSION
13666    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13667                          operands[3])"
13668   [(const_int 0)]
13670   expand_fusion_gpr_load (operands);
13671   DONE;
13674 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13675 ;; reload)
13677 (define_insn "fusion_gpr_load_<mode>"
13678   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13679         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13680                      UNSPEC_FUSION_GPR))]
13681   "TARGET_P8_FUSION"
13683   return emit_fusion_gpr_load (operands[0], operands[1]);
13685   [(set_attr "type" "load")
13686    (set_attr "length" "8")])
13689 ;; ISA 3.0 (power9) fusion support
13690 ;; Merge addis with floating load/store to FPRs (or GPRs).
13691 (define_peephole2
13692   [(set (match_operand:P 0 "base_reg_operand")
13693         (match_operand:P 1 "fusion_gpr_addis"))
13694    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13695         (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13696   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13697    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13698   [(const_int 0)]
13700   expand_fusion_p9_load (operands);
13701   DONE;
13704 (define_peephole2
13705   [(set (match_operand:P 0 "base_reg_operand")
13706         (match_operand:P 1 "fusion_gpr_addis"))
13707    (set (match_operand:SFDF 2 "offsettable_mem_operand")
13708         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13709   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13710    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13711    && !rtx_equal_p (operands[0], operands[3])"
13712   [(const_int 0)]
13714   expand_fusion_p9_store (operands);
13715   DONE;
13718 (define_peephole2
13719   [(set (match_operand:SDI 0 "int_reg_operand")
13720         (match_operand:SDI 1 "upper16_cint_operand"))
13721    (set (match_dup 0)
13722         (ior:SDI (match_dup 0)
13723                  (match_operand:SDI 2 "u_short_cint_operand")))]
13724   "TARGET_P9_FUSION"
13725   [(set (match_dup 0)
13726         (unspec:SDI [(match_dup 1)
13727                      (match_dup 2)] UNSPEC_FUSION_P9))])
13729 (define_peephole2
13730   [(set (match_operand:SDI 0 "int_reg_operand")
13731         (match_operand:SDI 1 "upper16_cint_operand"))
13732    (set (match_operand:SDI 2 "int_reg_operand")
13733         (ior:SDI (match_dup 0)
13734                  (match_operand:SDI 3 "u_short_cint_operand")))]
13735   "TARGET_P9_FUSION
13736    && !rtx_equal_p (operands[0], operands[2])
13737    && peep2_reg_dead_p (2, operands[0])"
13738   [(set (match_dup 2)
13739         (unspec:SDI [(match_dup 1)
13740                      (match_dup 3)] UNSPEC_FUSION_P9))])
13742 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13743 ;; reload).  Because we want to eventually have secondary_reload generate
13744 ;; these, they have to have a single alternative that gives the register
13745 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13746 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13747   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13748         (unspec:GPR_FUSION
13749          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13750          UNSPEC_FUSION_P9))
13751    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13752   "TARGET_P9_FUSION"
13754   /* This insn is a secondary reload insn, which cannot have alternatives.
13755      If we are not loading up register 0, use the power8 fusion instead.  */
13756   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13757     return emit_fusion_gpr_load (operands[0], operands[1]);
13759   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13761   [(set_attr "type" "load")
13762    (set_attr "length" "8")])
13764 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13765   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13766         (unspec:GPR_FUSION
13767          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13768          UNSPEC_FUSION_P9))
13769    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13770   "TARGET_P9_FUSION"
13772   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13774   [(set_attr "type" "store")
13775    (set_attr "length" "8")])
13777 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13778   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13779         (unspec:FPR_FUSION
13780          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13781          UNSPEC_FUSION_P9))
13782    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13783   "TARGET_P9_FUSION"
13785   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13787   [(set_attr "type" "fpload")
13788    (set_attr "length" "8")])
13790 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13791   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13792         (unspec:FPR_FUSION
13793          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13794          UNSPEC_FUSION_P9))
13795    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13796   "TARGET_P9_FUSION"
13798   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13800   [(set_attr "type" "fpstore")
13801    (set_attr "length" "8")])
13803 (define_insn "*fusion_p9_<mode>_constant"
13804   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13805         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13806                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13807                     UNSPEC_FUSION_P9))] 
13808   "TARGET_P9_FUSION"
13810   emit_fusion_addis (operands[0], operands[1]);
13811   return "ori %0,%0,%2";
13813   [(set_attr "type" "two")
13814    (set_attr "length" "8")])
13817 ;; Optimize cases where we want to do a D-form load (register+offset) on
13818 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13819 ;; has generated:
13820 ;;      LFD 0,32(3)
13821 ;;      XXLOR 32,0,0
13823 ;; and we change this to:
13824 ;;      LI 0,32
13825 ;;      LXSDX 32,3,9
13827 (define_peephole2
13828   [(match_scratch:P 0 "b")
13829    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13830         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13831    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13832         (match_dup 1))]
13833   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13834   [(set (match_dup 0)
13835         (match_dup 4))
13836    (set (match_dup 3)
13837         (match_dup 5))]
13839   rtx tmp_reg = operands[0];
13840   rtx mem = operands[2];
13841   rtx addr = XEXP (mem, 0);
13842   rtx add_op0, add_op1, new_addr;
13844   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13845   add_op0 = XEXP (addr, 0);
13846   add_op1 = XEXP (addr, 1);
13847   gcc_assert (REG_P (add_op0));
13848   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13850   operands[4] = add_op1;
13851   operands[5] = change_address (mem, <MODE>mode, new_addr);
13854 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13855 ;; Altivec register, and the register allocator has generated:
13856 ;;      XXLOR 0,32,32
13857 ;;      STFD 0,32(3)
13859 ;; and we change this to:
13860 ;;      LI 0,32
13861 ;;      STXSDX 32,3,9
13863 (define_peephole2
13864   [(match_scratch:P 0 "b")
13865    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13866         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13867    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13868         (match_dup 1))]
13869   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13870   [(set (match_dup 0)
13871         (match_dup 4))
13872    (set (match_dup 5)
13873         (match_dup 2))]
13875   rtx tmp_reg = operands[0];
13876   rtx mem = operands[3];
13877   rtx addr = XEXP (mem, 0);
13878   rtx add_op0, add_op1, new_addr;
13880   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13881   add_op0 = XEXP (addr, 0);
13882   add_op1 = XEXP (addr, 1);
13883   gcc_assert (REG_P (add_op0));
13884   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13886   operands[4] = add_op1;
13887   operands[5] = change_address (mem, <MODE>mode, new_addr);
13889    
13891 ;; Miscellaneous ISA 2.06 (power7) instructions
13892 (define_insn "addg6s"
13893   [(set (match_operand:SI 0 "register_operand" "=r")
13894         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13895                     (match_operand:SI 2 "register_operand" "r")]
13896                    UNSPEC_ADDG6S))]
13897   "TARGET_POPCNTD"
13898   "addg6s %0,%1,%2"
13899   [(set_attr "type" "integer")
13900    (set_attr "length" "4")])
13902 (define_insn "cdtbcd"
13903   [(set (match_operand:SI 0 "register_operand" "=r")
13904         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13905                    UNSPEC_CDTBCD))]
13906   "TARGET_POPCNTD"
13907   "cdtbcd %0,%1"
13908   [(set_attr "type" "integer")
13909    (set_attr "length" "4")])
13911 (define_insn "cbcdtd"
13912   [(set (match_operand:SI 0 "register_operand" "=r")
13913         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13914                    UNSPEC_CBCDTD))]
13915   "TARGET_POPCNTD"
13916   "cbcdtd %0,%1"
13917   [(set_attr "type" "integer")
13918    (set_attr "length" "4")])
13920 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13921                                         UNSPEC_DIVEU])
13923 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13924                              (UNSPEC_DIVEU      "eu")])
13926 (define_insn "div<div_extend>_<mode>"
13927   [(set (match_operand:GPR 0 "register_operand" "=r")
13928         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13929                      (match_operand:GPR 2 "register_operand" "r")]
13930                     UNSPEC_DIV_EXTEND))]
13931   "TARGET_POPCNTD"
13932   "div<wd><div_extend> %0,%1,%2"
13933   [(set_attr "type" "div")
13934    (set_attr "size" "<bits>")])
13937 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13939 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13940 (define_mode_attr FP128_64 [(TF "DF")
13941                             (IF "DF")
13942                             (TD "DI")
13943                             (KF "DI")])
13945 (define_expand "unpack<mode>"
13946   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13947         (unspec:<FP128_64>
13948          [(match_operand:FMOVE128 1 "register_operand")
13949           (match_operand:QI 2 "const_0_to_1_operand")]
13950          UNSPEC_UNPACK_128BIT))]
13951   "FLOAT128_2REG_P (<MODE>mode)"
13952   "")
13954 (define_insn_and_split "unpack<mode>_dm"
13955   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13956         (unspec:<FP128_64>
13957          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13958           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13959          UNSPEC_UNPACK_128BIT))]
13960   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13961   "#"
13962   "&& reload_completed"
13963   [(set (match_dup 0) (match_dup 3))]
13965   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13967   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13968     {
13969       emit_note (NOTE_INSN_DELETED);
13970       DONE;
13971     }
13973   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13975   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13976    (set_attr "length" "4")])
13978 (define_insn_and_split "unpack<mode>_nodm"
13979   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13980         (unspec:<FP128_64>
13981          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13982           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13983          UNSPEC_UNPACK_128BIT))]
13984   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13985   "#"
13986   "&& reload_completed"
13987   [(set (match_dup 0) (match_dup 3))]
13989   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13991   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13992     {
13993       emit_note (NOTE_INSN_DELETED);
13994       DONE;
13995     }
13997   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13999   [(set_attr "type" "fp,fpstore")
14000    (set_attr "length" "4")])
14002 (define_insn_and_split "pack<mode>"
14003   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14004         (unspec:FMOVE128
14005          [(match_operand:<FP128_64> 1 "register_operand" "d")
14006           (match_operand:<FP128_64> 2 "register_operand" "d")]
14007          UNSPEC_PACK_128BIT))]
14008   "FLOAT128_2REG_P (<MODE>mode)"
14009   "#"
14010   "&& reload_completed"
14011   [(set (match_dup 3) (match_dup 1))
14012    (set (match_dup 4) (match_dup 2))]
14014   unsigned dest_hi = REGNO (operands[0]);
14015   unsigned dest_lo = dest_hi + 1;
14017   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14018   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14020   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14021   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14023   [(set_attr "type" "fp")
14024    (set_attr "length" "8")])
14026 (define_insn "unpack<mode>"
14027   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14028         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14029                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14030          UNSPEC_UNPACK_128BIT))]
14031   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14033   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14034     return ASM_COMMENT_START " xxpermdi to same register";
14036   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14037   return "xxpermdi %x0,%x1,%x1,%3";
14039   [(set_attr "type" "vecperm")])
14041 (define_insn "pack<mode>"
14042   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14043         (unspec:FMOVE128_VSX
14044          [(match_operand:DI 1 "register_operand" "wa")
14045           (match_operand:DI 2 "register_operand" "wa")]
14046          UNSPEC_PACK_128BIT))]
14047   "TARGET_VSX"
14048   "xxpermdi %x0,%x1,%x2,0"
14049   [(set_attr "type" "vecperm")])
14053 ;; ISA 2.08 IEEE 128-bit floating point support.
14055 (define_insn "add<mode>3"
14056   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14057         (plus:IEEE128
14058          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14059          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14060   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14061   "xsaddqp %0,%1,%2"
14062   [(set_attr "type" "vecfloat")
14063    (set_attr "size" "128")])
14065 (define_insn "sub<mode>3"
14066   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14067         (minus:IEEE128
14068          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14069          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14070   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14071   "xssubqp %0,%1,%2"
14072   [(set_attr "type" "vecfloat")
14073    (set_attr "size" "128")])
14075 (define_insn "mul<mode>3"
14076   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14077         (mult:IEEE128
14078          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14079          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14080   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14081   "xsmulqp %0,%1,%2"
14082   [(set_attr "type" "qmul")
14083    (set_attr "size" "128")])
14085 (define_insn "div<mode>3"
14086   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14087         (div:IEEE128
14088          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14089          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14090   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14091   "xsdivqp %0,%1,%2"
14092   [(set_attr "type" "vecdiv")
14093    (set_attr "size" "128")])
14095 (define_insn "sqrt<mode>2"
14096   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14097         (sqrt:IEEE128
14098          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14099   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14100    "xssqrtqp %0,%1"
14101   [(set_attr "type" "vecdiv")
14102    (set_attr "size" "128")])
14104 (define_expand "copysign<mode>3"
14105   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14106    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14107    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14108   "FLOAT128_IEEE_P (<MODE>mode)"
14110   if (TARGET_FLOAT128_HW)
14111     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14112                                          operands[2]));
14113   else
14114     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14115                                          operands[2]));
14116   DONE;
14119 (define_insn "copysign<mode>3_hard"
14120   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14121         (unspec:IEEE128
14122          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14123           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14124          UNSPEC_COPYSIGN))]
14125   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14126    "xscpsgnqp %0,%2,%1"
14127   [(set_attr "type" "vecmove")
14128    (set_attr "size" "128")])
14130 (define_insn "copysign<mode>3_soft"
14131   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14132         (unspec:IEEE128
14133          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14134           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14135          UNSPEC_COPYSIGN))
14136    (clobber (match_scratch:IEEE128 3 "=&v"))]
14137   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14138    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14139   [(set_attr "type" "veccomplex")
14140    (set_attr "length" "8")])
14142 (define_insn "neg<mode>2_hw"
14143   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14144         (neg:IEEE128
14145          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14146   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14147   "xsnegqp %0,%1"
14148   [(set_attr "type" "vecmove")
14149    (set_attr "size" "128")])
14152 (define_insn "abs<mode>2_hw"
14153   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14154         (abs:IEEE128
14155          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14156   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14157   "xsabsqp %0,%1"
14158   [(set_attr "type" "vecmove")
14159    (set_attr "size" "128")])
14162 (define_insn "*nabs<mode>2_hw"
14163   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14164         (neg:IEEE128
14165          (abs:IEEE128
14166           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14167   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14168   "xsnabsqp %0,%1"
14169   [(set_attr "type" "vecmove")
14170    (set_attr "size" "128")])
14172 ;; Initially don't worry about doing fusion
14173 (define_insn "fma<mode>4_hw"
14174   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14175         (fma:IEEE128
14176          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14177          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14178          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14179   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14180   "xsmaddqp %0,%1,%2"
14181   [(set_attr "type" "qmul")
14182    (set_attr "size" "128")])
14184 (define_insn "*fms<mode>4_hw"
14185   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14186         (fma:IEEE128
14187          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14188          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14189          (neg:IEEE128
14190           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14191   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14192   "xsmsubqp %0,%1,%2"
14193   [(set_attr "type" "qmul")
14194    (set_attr "size" "128")])
14196 (define_insn "*nfma<mode>4_hw"
14197   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14198         (neg:IEEE128
14199          (fma:IEEE128
14200           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14201           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14202           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14203   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14204   "xsnmaddqp %0,%1,%2"
14205   [(set_attr "type" "qmul")
14206    (set_attr "size" "128")])
14208 (define_insn "*nfms<mode>4_hw"
14209   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14210         (neg:IEEE128
14211          (fma:IEEE128
14212           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14213           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14214           (neg:IEEE128
14215            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14216   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14217   "xsnmsubqp %0,%1,%2"
14218   [(set_attr "type" "qmul")
14219    (set_attr "size" "128")])
14221 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14222   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14223         (float_extend:IEEE128
14224          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14225   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14226   "xscvdpqp %0,%1"
14227   [(set_attr "type" "vecfloat")
14228    (set_attr "size" "128")])
14230 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14231 ;; point is a simple copy.
14232 (define_insn_and_split "extendkftf2"
14233   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14234         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14235   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14236   "@
14237    #
14238    xxlor %x0,%x1,%x1"
14239   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14240   [(const_int 0)]
14242   emit_note (NOTE_INSN_DELETED);
14243   DONE;
14245   [(set_attr "type" "*,veclogical")
14246    (set_attr "length" "0,4")])
14248 (define_insn_and_split "trunctfkf2"
14249   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14250         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14251   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14252   "@
14253    #
14254    xxlor %x0,%x1,%x1"
14255   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14256   [(const_int 0)]
14258   emit_note (NOTE_INSN_DELETED);
14259   DONE;
14261   [(set_attr "type" "*,veclogical")
14262    (set_attr "length" "0,4")])
14264 (define_insn "trunc<mode>df2_hw"
14265   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14266         (float_truncate:DF
14267          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14268   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14269   "xscvqpdp %0,%1"
14270   [(set_attr "type" "vecfloat")
14271    (set_attr "size" "128")])
14273 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14274 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14275 ;; conversion
14276 (define_insn_and_split "trunc<mode>sf2_hw"
14277   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14278         (float_truncate:SF
14279          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14280    (clobber (match_scratch:DF 2 "=v"))]
14281   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14282   "#"
14283   "&& 1"
14284   [(set (match_dup 2)
14285         (unspec:DF [(match_dup 1)]
14286                    UNSPEC_TRUNC_ROUND_TO_ODD))
14287    (set (match_dup 0)
14288         (float_truncate:SF (match_dup 2)))]
14290   if (GET_CODE (operands[2]) == SCRATCH)
14291     operands[2] = gen_reg_rtx (DFmode);
14293   [(set_attr "type" "vecfloat")
14294    (set_attr "length" "8")])
14296 ;; Conversion between IEEE 128-bit and integer types
14298 ;; The fix function for DImode and SImode was declared earlier as a
14299 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14300 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14301 ;; unless we have the IEEE 128-bit hardware.
14303 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14304 ;; to provide a GPR target that used direct move and a conversion in the GPR
14305 ;; which works around QImode/HImode not being allowed in vector registers in
14306 ;; ISA 2.07 (power8).
14307 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14308   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14309         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14310   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14311   "xscvqp<su><wd>z %0,%1"
14312   [(set_attr "type" "vecfloat")
14313    (set_attr "size" "128")])
14315 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14316   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14317         (any_fix:QHI
14318          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14319   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14320   "xscvqp<su>wz %0,%1"
14321   [(set_attr "type" "vecfloat")
14322    (set_attr "size" "128")])
14324 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14325 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14326 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14327   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14328         (any_fix:QHSI
14329          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14330    (clobber (match_scratch:QHSI 2 "=v"))]
14331   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14332   "#"
14333   "&& reload_completed"
14334   [(set (match_dup 2)
14335         (any_fix:QHSI (match_dup 1)))
14336    (set (match_dup 0)
14337         (match_dup 2))])
14339 (define_insn "float_<mode>di2_hw"
14340   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14341         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14342   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14343   "xscvsdqp %0,%1"
14344   [(set_attr "type" "vecfloat")
14345    (set_attr "size" "128")])
14347 (define_insn_and_split "float_<mode>si2_hw"
14348   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14349         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14350    (clobber (match_scratch:DI 2 "=v"))]
14351   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14352   "#"
14353   "&& 1"
14354   [(set (match_dup 2)
14355         (sign_extend:DI (match_dup 1)))
14356    (set (match_dup 0)
14357         (float:IEEE128 (match_dup 2)))]
14359   if (GET_CODE (operands[2]) == SCRATCH)
14360     operands[2] = gen_reg_rtx (DImode);
14362   if (MEM_P (operands[1]))
14363     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14366 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14367   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14368         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14369    (clobber (match_scratch:DI 2 "=X,r,X"))]
14370   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14371   "#"
14372   "&& reload_completed"
14373   [(const_int 0)]
14375   rtx dest = operands[0];
14376   rtx src = operands[1];
14377   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14379   if (altivec_register_operand (src, <QHI:MODE>mode))
14380     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14381   else if (int_reg_operand (src, <QHI:MODE>mode))
14382     {
14383       rtx ext_di = operands[2];
14384       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14385       emit_move_insn (dest_di, ext_di);
14386     }
14387   else if (MEM_P (src))
14388     {
14389       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14390       emit_move_insn (dest_qhi, src);
14391       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14392     }
14393   else
14394     gcc_unreachable ();
14396   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14397   DONE;
14399   [(set_attr "length" "8,12,12")
14400    (set_attr "type" "vecfloat")
14401    (set_attr "size" "128")])
14403 (define_insn "floatuns_<mode>di2_hw"
14404   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14405         (unsigned_float:IEEE128
14406          (match_operand:DI 1 "altivec_register_operand" "v")))]
14407   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14408   "xscvudqp %0,%1"
14409   [(set_attr "type" "vecfloat")
14410    (set_attr "size" "128")])
14412 (define_insn_and_split "floatuns_<mode>si2_hw"
14413   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14414         (unsigned_float:IEEE128
14415          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14416    (clobber (match_scratch:DI 2 "=v"))]
14417   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14418   "#"
14419   "&& 1"
14420   [(set (match_dup 2)
14421         (zero_extend:DI (match_dup 1)))
14422    (set (match_dup 0)
14423         (float:IEEE128 (match_dup 2)))]
14425   if (GET_CODE (operands[2]) == SCRATCH)
14426     operands[2] = gen_reg_rtx (DImode);
14428   if (MEM_P (operands[1]))
14429     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14432 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14433   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14434         (unsigned_float:IEEE128
14435          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14436    (clobber (match_scratch:DI 2 "=X,r,X"))]
14437   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14438   "#"
14439   "&& reload_completed"
14440   [(const_int 0)]
14442   rtx dest = operands[0];
14443   rtx src = operands[1];
14444   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14446   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14447     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14448   else if (int_reg_operand (src, <QHI:MODE>mode))
14449     {
14450       rtx ext_di = operands[2];
14451       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14452       emit_move_insn (dest_di, ext_di);
14453     }
14454   else
14455     gcc_unreachable ();
14457   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14458   DONE;
14460   [(set_attr "length" "8,12,8")
14461    (set_attr "type" "vecfloat")
14462    (set_attr "size" "128")])
14464 ;; IEEE 128-bit round to integer built-in functions
14465 (define_insn "floor<mode>2"
14466   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14467         (unspec:IEEE128
14468          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14469          UNSPEC_FRIM))]
14470   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14471   "xsrqpi 1,%0,%1,3"
14472   [(set_attr "type" "vecfloat")
14473    (set_attr "size" "128")])
14475 (define_insn "ceil<mode>2"
14476   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14477         (unspec:IEEE128
14478          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14479          UNSPEC_FRIP))]
14480   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14481   "xsrqpi 1,%0,%1,2"
14482   [(set_attr "type" "vecfloat")
14483    (set_attr "size" "128")])
14485 (define_insn "btrunc<mode>2"
14486   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14487         (unspec:IEEE128
14488          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14489          UNSPEC_FRIZ))]
14490   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14491   "xsrqpi 1,%0,%1,1"
14492   [(set_attr "type" "vecfloat")
14493    (set_attr "size" "128")])
14495 (define_insn "round<mode>2"
14496   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14497         (unspec:IEEE128
14498          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14499          UNSPEC_FRIN))]
14500   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14501   "xsrqpi 0,%0,%1,0"
14502   [(set_attr "type" "vecfloat")
14503    (set_attr "size" "128")])
14505 ;; IEEE 128-bit instructions with round to odd semantics
14506 (define_insn "add<mode>3_odd"
14507   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14508         (unspec:IEEE128
14509          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14510           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14511          UNSPEC_ADD_ROUND_TO_ODD))]
14512   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14513   "xsaddqpo %0,%1,%2"
14514   [(set_attr "type" "vecfloat")
14515    (set_attr "size" "128")])
14517 (define_insn "sub<mode>3_odd"
14518   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14519         (unspec:IEEE128
14520          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14521           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14522          UNSPEC_SUB_ROUND_TO_ODD))]
14523   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14524   "xssubqpo %0,%1,%2"
14525   [(set_attr "type" "vecfloat")
14526    (set_attr "size" "128")])
14528 (define_insn "mul<mode>3_odd"
14529   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14530         (unspec:IEEE128
14531          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14532           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14533          UNSPEC_MUL_ROUND_TO_ODD))]
14534   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14535   "xsmulqpo %0,%1,%2"
14536   [(set_attr "type" "qmul")
14537    (set_attr "size" "128")])
14539 (define_insn "div<mode>3_odd"
14540   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14541         (unspec:IEEE128
14542          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14543           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14544          UNSPEC_DIV_ROUND_TO_ODD))]
14545   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14546   "xsdivqpo %0,%1,%2"
14547   [(set_attr "type" "vecdiv")
14548    (set_attr "size" "128")])
14550 (define_insn "sqrt<mode>2_odd"
14551   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14552         (unspec:IEEE128
14553          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14554          UNSPEC_SQRT_ROUND_TO_ODD))]
14555   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14556    "xssqrtqpo %0,%1"
14557   [(set_attr "type" "vecdiv")
14558    (set_attr "size" "128")])
14560 (define_insn "fma<mode>4_odd"
14561   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14562         (unspec:IEEE128
14563          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14564           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14565           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14566          UNSPEC_FMA_ROUND_TO_ODD))]
14567   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14568   "xsmaddqpo %0,%1,%2"
14569   [(set_attr "type" "qmul")
14570    (set_attr "size" "128")])
14572 (define_insn "*fms<mode>4_odd"
14573   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14574         (unspec:IEEE128
14575          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14576           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14577           (neg:IEEE128
14578            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14579          UNSPEC_FMA_ROUND_TO_ODD))]
14580   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14581   "xsmsubqpo %0,%1,%2"
14582   [(set_attr "type" "qmul")
14583    (set_attr "size" "128")])
14585 (define_insn "*nfma<mode>4_odd"
14586   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14587         (neg:IEEE128
14588          (unspec:IEEE128
14589           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14590            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14591            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14592           UNSPEC_FMA_ROUND_TO_ODD)))]
14593   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14594   "xsnmaddqpo %0,%1,%2"
14595   [(set_attr "type" "qmul")
14596    (set_attr "size" "128")])
14598 (define_insn "*nfms<mode>4_odd"
14599   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14600         (neg:IEEE128
14601          (unspec:IEEE128
14602           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14603            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14604            (neg:IEEE128
14605             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14606           UNSPEC_FMA_ROUND_TO_ODD)))]
14607   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14608   "xsnmsubqpo %0,%1,%2"
14609   [(set_attr "type" "qmul")
14610    (set_attr "size" "128")])
14612 (define_insn "trunc<mode>df2_odd"
14613   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14614         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14615                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14616   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14617   "xscvqpdpo %0,%1"
14618   [(set_attr "type" "vecfloat")
14619    (set_attr "size" "128")])
14621 ;; IEEE 128-bit comparisons
14622 (define_insn "*cmp<mode>_hw"
14623   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14624         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14625                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14626   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14627    "xscmpuqp %0,%1,%2"
14628   [(set_attr "type" "veccmp")
14629    (set_attr "size" "128")])
14633 (include "sync.md")
14634 (include "vector.md")
14635 (include "vsx.md")
14636 (include "altivec.md")
14637 (include "dfp.md")
14638 (include "crypto.md")
14639 (include "htm.md")