[rs6000] Use gen_int_mode in ieee_128bit_negative_zero
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob2c310d7cf58f9d51c24be702fb465620c9a74b9f
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2017 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_DIVEO
134    UNSPEC_DIVEU
135    UNSPEC_DIVEUO
136    UNSPEC_UNPACK_128BIT
137    UNSPEC_PACK_128BIT
138    UNSPEC_LSQ
139    UNSPEC_FUSION_GPR
140    UNSPEC_STACK_CHECK
141    UNSPEC_FUSION_P9
142    UNSPEC_FUSION_ADDIS
143    UNSPEC_ADD_ROUND_TO_ODD
144    UNSPEC_SUB_ROUND_TO_ODD
145    UNSPEC_MUL_ROUND_TO_ODD
146    UNSPEC_DIV_ROUND_TO_ODD
147    UNSPEC_FMA_ROUND_TO_ODD
148    UNSPEC_SQRT_ROUND_TO_ODD
149    UNSPEC_TRUNC_ROUND_TO_ODD
150    UNSPEC_SIGNBIT
151    UNSPEC_SF_FROM_SI
152    UNSPEC_SI_FROM_SF
153   ])
156 ;; UNSPEC_VOLATILE usage
159 (define_c_enum "unspecv"
160   [UNSPECV_BLOCK
161    UNSPECV_LL                   ; load-locked
162    UNSPECV_SC                   ; store-conditional
163    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
164    UNSPECV_EH_RR                ; eh_reg_restore
165    UNSPECV_ISYNC                ; isync instruction
166    UNSPECV_MFTB                 ; move from time base
167    UNSPECV_NLGR                 ; non-local goto receiver
168    UNSPECV_MFFS                 ; Move from FPSCR
169    UNSPECV_MTFSF                ; Move to FPSCR Fields
170    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
171   ])
174 ;; Define an insn type attribute.  This is used in function unit delay
175 ;; computations.
176 (define_attr "type"
177   "integer,two,three,
178    add,logical,shift,insert,
179    mul,halfmul,div,
180    exts,cntlz,popcnt,isel,
181    load,store,fpload,fpstore,vecload,vecstore,
182    cmp,
183    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
184    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
185    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
186    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188    veclogical,veccmpfx,vecexts,vecmove,
189    htm,htmsimple,dfp"
190   (const_string "integer"))
192 ;; What data size does this instruction work on?
193 ;; This is used for insert, mul and others as necessary.
194 (define_attr "size" "8,16,32,64,128" (const_string "32"))
196 ;; What is the insn_cost for this insn?  The target hook can still override
197 ;; this.  For optimizing for size the "length" attribute is used instead.
198 (define_attr "cost" "" (const_int 0))
200 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
201 ;; This is used for add, logical, shift, exts, mul.
202 (define_attr "dot" "no,yes" (const_string "no"))
204 ;; Does this instruction sign-extend its result?
205 ;; This is used for load insns.
206 (define_attr "sign_extend" "no,yes" (const_string "no"))
208 ;; Does this instruction use indexed (that is, reg+reg) addressing?
209 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
210 ;; it is automatically set based on that.  If a load or store instruction
211 ;; has fewer than two operands it needs to set this attribute manually
212 ;; or the compiler will crash.
213 (define_attr "indexed" "no,yes"
214   (if_then_else (ior (match_operand 0 "indexed_address_mem")
215                      (match_operand 1 "indexed_address_mem"))
216                 (const_string "yes")
217                 (const_string "no")))
219 ;; Does this instruction use update addressing?
220 ;; This is used for load and store insns.  See the comments for "indexed".
221 (define_attr "update" "no,yes"
222   (if_then_else (ior (match_operand 0 "update_address_mem")
223                      (match_operand 1 "update_address_mem"))
224                 (const_string "yes")
225                 (const_string "no")))
227 ;; Is this instruction using operands[2] as shift amount, and can that be a
228 ;; register?
229 ;; This is used for shift insns.
230 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
232 ;; Is this instruction using a shift amount from a register?
233 ;; This is used for shift insns.
234 (define_attr "var_shift" "no,yes"
235   (if_then_else (and (eq_attr "type" "shift")
236                      (eq_attr "maybe_var_shift" "yes"))
237                 (if_then_else (match_operand 2 "gpc_reg_operand")
238                               (const_string "yes")
239                               (const_string "no"))
240                 (const_string "no")))
242 ;; Is copying of this instruction disallowed?
243 (define_attr "cannot_copy" "no,yes" (const_string "no"))
245 ;; Define floating point instruction sub-types for use with Xfpu.md
246 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
248 ;; Length (in bytes).
249 ; '(pc)' in the following doesn't include the instruction itself; it is
250 ; calculated as if the instruction had zero size.
251 (define_attr "length" ""
252   (if_then_else (eq_attr "type" "branch")
253                 (if_then_else (and (ge (minus (match_dup 0) (pc))
254                                        (const_int -32768))
255                                    (lt (minus (match_dup 0) (pc))
256                                        (const_int 32764)))
257                               (const_int 4)
258                               (const_int 8))
259                 (const_int 4)))
261 ;; Processor type -- this attribute must exactly match the processor_type
262 ;; enumeration in rs6000-opts.h.
263 (define_attr "cpu"
264   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
265    ppc750,ppc7400,ppc7450,
266    ppc403,ppc405,ppc440,ppc476,
267    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
268    power4,power5,power6,power7,power8,power9,
269    rs64a,mpccore,cell,ppca2,titan"
270   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
273 ;; If this instruction is microcoded on the CELL processor
274 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
275 (define_attr "cell_micro" "not,conditional,always"
276   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
277                           (eq_attr "dot" "yes"))
278                      (and (eq_attr "type" "load")
279                           (eq_attr "sign_extend" "yes"))
280                      (and (eq_attr "type" "shift")
281                           (eq_attr "var_shift" "yes")))
282                 (const_string "always")
283                 (const_string "not")))
285 (automata_option "ndfa")
287 (include "rs64.md")
288 (include "mpc.md")
289 (include "40x.md")
290 (include "440.md")
291 (include "476.md")
292 (include "601.md")
293 (include "603.md")
294 (include "6xx.md")
295 (include "7xx.md")
296 (include "7450.md")
297 (include "8540.md")
298 (include "e300c2c3.md")
299 (include "e500mc.md")
300 (include "e500mc64.md")
301 (include "e5500.md")
302 (include "e6500.md")
303 (include "power4.md")
304 (include "power5.md")
305 (include "power6.md")
306 (include "power7.md")
307 (include "power8.md")
308 (include "power9.md")
309 (include "cell.md")
310 (include "xfpu.md")
311 (include "a2.md")
312 (include "titan.md")
314 (include "predicates.md")
315 (include "constraints.md")
317 (include "darwin.md")
320 ;; Mode iterators
322 ; This mode iterator allows :GPR to be used to indicate the allowable size
323 ; of whole values in GPRs.
324 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
326 ; And again, for patterns that need two (potentially) different integer modes.
327 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
329 ; Any supported integer mode.
330 (define_mode_iterator INT [QI HI SI DI TI PTI])
332 ; Any supported integer mode that fits in one register.
333 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
335 ; Integer modes supported in VSX registers with ISA 3.0 instructions
336 (define_mode_iterator INT_ISA3 [QI HI SI DI])
338 ; Everything we can extend QImode to.
339 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
341 ; Everything we can extend HImode to.
342 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
344 ; Everything we can extend SImode to.
345 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
347 ; QImode or HImode for small integer moves and small atomic ops
348 (define_mode_iterator QHI [QI HI])
350 ; QImode, HImode, SImode for fused ops only for GPR loads
351 (define_mode_iterator QHSI [QI HI SI])
353 ; HImode or SImode for sign extended fusion ops
354 (define_mode_iterator HSI [HI SI])
356 ; SImode or DImode, even if DImode doesn't fit in GPRs.
357 (define_mode_iterator SDI [SI DI])
359 ; Types that can be fused with an ADDIS instruction to load or store a GPR
360 ; register that has reg+offset addressing.
361 (define_mode_iterator GPR_FUSION [QI
362                                   HI
363                                   SI
364                                   (DI   "TARGET_POWERPC64")
365                                   SF
366                                   (DF   "TARGET_POWERPC64")])
368 ; Types that can be fused with an ADDIS instruction to load or store a FPR
369 ; register that has reg+offset addressing.
370 (define_mode_iterator FPR_FUSION [DI SF DF])
372 ; The size of a pointer.  Also, the size of the value that a record-condition
373 ; (one with a '.') will compare; and the size used for arithmetic carries.
374 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
376 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
377 ; PTImode is GPR only)
378 (define_mode_iterator TI2 [TI PTI])
380 ; Any hardware-supported floating-point mode
381 (define_mode_iterator FP [
382   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
383   (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
384   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
385   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
386   (KF "TARGET_FLOAT128_TYPE")
387   (DD "TARGET_DFP")
388   (TD "TARGET_DFP")])
390 ; Any fma capable floating-point mode.
391 (define_mode_iterator FMA_F [
392   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
393   (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
394        || VECTOR_UNIT_VSX_P (DFmode)")
395   (V2SF "TARGET_PAIRED_FLOAT")
396   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
397   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
398   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
399   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
400   ])
402 ; Floating point move iterators to combine binary and decimal moves
403 (define_mode_iterator FMOVE32 [SF SD])
404 (define_mode_iterator FMOVE64 [DF DD])
405 (define_mode_iterator FMOVE64X [DI DF DD])
406 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
407                                 (IF "FLOAT128_IBM_P (IFmode)")
408                                 (TD "TARGET_HARD_FLOAT")])
410 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
411                                     (IF "FLOAT128_2REG_P (IFmode)")
412                                     (TD "TARGET_HARD_FLOAT")])
414 ; Iterators for 128 bit types for direct move
415 (define_mode_iterator FMOVE128_GPR [TI
416                                     V16QI
417                                     V8HI
418                                     V4SI
419                                     V4SF
420                                     V2DI
421                                     V2DF
422                                     V1TI
423                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
424                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
426 ; Iterator for 128-bit VSX types for pack/unpack
427 (define_mode_iterator FMOVE128_VSX [V1TI KF])
429 ; Whether a floating point move is ok, don't allow SD without hardware FP
430 (define_mode_attr fmove_ok [(SF "")
431                             (DF "")
432                             (SD "TARGET_HARD_FLOAT")
433                             (DD "")])
435 ; Convert REAL_VALUE to the appropriate bits
436 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
437                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
438                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
439                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
441 ; Whether 0.0 has an all-zero bit pattern
442 (define_mode_attr zero_fp [(SF "j")
443                            (DF "j")
444                            (TF "j")
445                            (IF "j")
446                            (KF "j")
447                            (SD "wn")
448                            (DD "wn")
449                            (TD "wn")])
451 ; Definitions for 64-bit VSX
452 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
454 ; Definitions for 64-bit direct move
455 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
457 ; Definitions for 64-bit use of altivec registers
458 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
460 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
461 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
463 ; These modes do not fit in integer registers in 32-bit mode.
464 (define_mode_iterator DIFD [DI DF DD])
466 ; Iterator for reciprocal estimate instructions
467 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
469 ; Iterator for just SF/DF
470 (define_mode_iterator SFDF [SF DF])
472 ; Like SFDF, but a different name to match conditional move where the
473 ; comparison operands may be a different mode than the input operands.
474 (define_mode_iterator SFDF2 [SF DF])
476 ; Iterator for 128-bit floating point that uses the IBM double-double format
477 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
478                               (TF "FLOAT128_IBM_P (TFmode)")])
480 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
481 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
482                                (TF "FLOAT128_IEEE_P (TFmode)")])
484 ; Iterator for 128-bit floating point
485 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
486                                 (IF "TARGET_FLOAT128_TYPE")
487                                 (TF "TARGET_LONG_DOUBLE_128")])
489 ; Iterator for signbit on 64-bit machines with direct move
490 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
491                                (TF "FLOAT128_VECTOR_P (TFmode)")])
493 ; Iterator for ISA 3.0 supported floating point types
494 (define_mode_iterator FP_ISA3 [SF DF])
496 ; SF/DF suffix for traditional floating instructions
497 (define_mode_attr Ftrad         [(SF "s") (DF "")])
499 ; SF/DF suffix for VSX instructions
500 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
502 ; SF/DF constraint for arithmetic on traditional floating point registers
503 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
505 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
506 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
507 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
508 ; format.
509 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
511 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
512 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
513 ; instructions added in ISA 2.07 (power8)
514 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
516 ; SF/DF constraint for arithmetic on altivec registers
517 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
519 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
520 (define_mode_attr Fs            [(SF "s")  (DF "d")])
522 ; FRE/FRES support
523 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
524 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
526 ; Conditional returns.
527 (define_code_iterator any_return [return simple_return])
528 (define_code_attr return_pred [(return "direct_return ()")
529                                (simple_return "1")])
530 (define_code_attr return_str [(return "") (simple_return "simple_")])
532 ; Logical operators.
533 (define_code_iterator iorxor            [ior xor])
534 (define_code_iterator and_ior_xor       [and ior xor])
536 ; Signed/unsigned variants of ops.
537 (define_code_iterator any_extend        [sign_extend zero_extend])
538 (define_code_iterator any_fix           [fix unsigned_fix])
539 (define_code_iterator any_float         [float unsigned_float])
541 (define_code_attr u  [(sign_extend      "")
542                       (zero_extend      "u")
543                       (fix              "")
544                       (unsigned_fix     "u")])
546 (define_code_attr su [(sign_extend      "s")
547                       (zero_extend      "u")
548                       (fix              "s")
549                       (unsigned_fix     "s")
550                       (float            "s")
551                       (unsigned_float   "u")])
553 (define_code_attr az [(sign_extend      "a")
554                       (zero_extend      "z")
555                       (fix              "a")
556                       (unsigned_fix     "z")
557                       (float            "a")
558                       (unsigned_float   "z")])
560 (define_code_attr uns [(fix             "")
561                        (unsigned_fix    "uns")
562                        (float           "")
563                        (unsigned_float  "uns")])
565 ; Various instructions that come in SI and DI forms.
566 ; A generic w/d attribute, for things like cmpw/cmpd.
567 (define_mode_attr wd [(QI    "b")
568                       (HI    "h")
569                       (SI    "w")
570                       (DI    "d")
571                       (V16QI "b")
572                       (V8HI  "h")
573                       (V4SI  "w")
574                       (V2DI  "d")
575                       (V1TI  "q")
576                       (TI    "q")])
578 ;; How many bits in this mode?
579 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
581 ; DImode bits
582 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
584 ;; Bitmask for shift instructions
585 (define_mode_attr hH [(SI "h") (DI "H")])
587 ;; A mode twice the size of the given mode
588 (define_mode_attr dmode [(SI "di") (DI "ti")])
589 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
591 ;; Suffix for reload patterns
592 (define_mode_attr ptrsize [(SI "32bit")
593                            (DI "64bit")])
595 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
596                             (DI "TARGET_64BIT")])
598 (define_mode_attr mptrsize [(SI "si")
599                             (DI "di")])
601 (define_mode_attr ptrload [(SI "lwz")
602                            (DI "ld")])
604 (define_mode_attr ptrm [(SI "m")
605                         (DI "Y")])
607 (define_mode_attr rreg [(SF   "f")
608                         (DF   "ws")
609                         (TF   "f")
610                         (TD   "f")
611                         (V4SF "wf")
612                         (V2DF "wd")])
614 (define_mode_attr rreg2 [(SF   "f")
615                          (DF   "d")])
617 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
618                                  (DF "TARGET_FCFID")])
620 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
621                                 (DF "TARGET_DOUBLE_FLOAT")])
623 ;; Mode iterator for logical operations on 128-bit types
624 (define_mode_iterator BOOL_128          [TI
625                                          PTI
626                                          (V16QI "TARGET_ALTIVEC")
627                                          (V8HI  "TARGET_ALTIVEC")
628                                          (V4SI  "TARGET_ALTIVEC")
629                                          (V4SF  "TARGET_ALTIVEC")
630                                          (V2DI  "TARGET_ALTIVEC")
631                                          (V2DF  "TARGET_ALTIVEC")
632                                          (V1TI  "TARGET_ALTIVEC")])
634 ;; For the GPRs we use 3 constraints for register outputs, two that are the
635 ;; same as the output register, and a third where the output register is an
636 ;; early clobber, so we don't have to deal with register overlaps.  For the
637 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
638 ;; either.
640 ;; Mode attribute for boolean operation register constraints for output
641 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
642                                          (PTI   "&r,r,r")
643                                          (V16QI "wa,v,&?r,?r,?r")
644                                          (V8HI  "wa,v,&?r,?r,?r")
645                                          (V4SI  "wa,v,&?r,?r,?r")
646                                          (V4SF  "wa,v,&?r,?r,?r")
647                                          (V2DI  "wa,v,&?r,?r,?r")
648                                          (V2DF  "wa,v,&?r,?r,?r")
649                                          (V1TI  "wa,v,&?r,?r,?r")])
651 ;; Mode attribute for boolean operation register constraints for operand1
652 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
653                                          (PTI   "r,0,r")
654                                          (V16QI "wa,v,r,0,r")
655                                          (V8HI  "wa,v,r,0,r")
656                                          (V4SI  "wa,v,r,0,r")
657                                          (V4SF  "wa,v,r,0,r")
658                                          (V2DI  "wa,v,r,0,r")
659                                          (V2DF  "wa,v,r,0,r")
660                                          (V1TI  "wa,v,r,0,r")])
662 ;; Mode attribute for boolean operation register constraints for operand2
663 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
664                                          (PTI   "r,r,0")
665                                          (V16QI "wa,v,r,r,0")
666                                          (V8HI  "wa,v,r,r,0")
667                                          (V4SI  "wa,v,r,r,0")
668                                          (V4SF  "wa,v,r,r,0")
669                                          (V2DI  "wa,v,r,r,0")
670                                          (V2DF  "wa,v,r,r,0")
671                                          (V1TI  "wa,v,r,r,0")])
673 ;; Mode attribute for boolean operation register constraints for operand1
674 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
675 ;; is used for operand1 or operand2
676 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
677                                          (PTI   "r,0,0")
678                                          (V16QI "wa,v,r,0,0")
679                                          (V8HI  "wa,v,r,0,0")
680                                          (V4SI  "wa,v,r,0,0")
681                                          (V4SF  "wa,v,r,0,0")
682                                          (V2DI  "wa,v,r,0,0")
683                                          (V2DF  "wa,v,r,0,0")
684                                          (V1TI  "wa,v,r,0,0")])
686 ;; Reload iterator for creating the function to allocate a base register to
687 ;; supplement addressing modes.
688 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
689                               SF SD SI DF DD DI TI PTI KF IF TF])
691 ;; Iterate over smin, smax
692 (define_code_iterator fp_minmax [smin smax])
694 (define_code_attr     minmax    [(smin "min")
695                                  (smax "max")])
697 (define_code_attr     SMINMAX   [(smin "SMIN")
698                                  (smax "SMAX")])
700 ;; Iterator to optimize the following cases:
701 ;;      D-form load to FPR register & move to Altivec register
702 ;;      Move Altivec register to FPR register and store
703 (define_mode_iterator ALTIVEC_DFORM [DF
704                                      (SF "TARGET_P8_VECTOR")
705                                      (DI "TARGET_POWERPC64")])
708 ;; Start with fixed-point load and store insns.  Here we put only the more
709 ;; complex forms.  Basic data transfer is done later.
711 (define_insn "zero_extendqi<mode>2"
712   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
713         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
714   ""
715   "@
716    lbz%U1%X1 %0,%1
717    rlwinm %0,%1,0,0xff
718    lxsibzx %x0,%y1
719    vextractub %0,%1,7"
720   [(set_attr "type" "load,shift,fpload,vecperm")])
722 (define_insn_and_split "*zero_extendqi<mode>2_dot"
723   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
724         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
725                     (const_int 0)))
726    (clobber (match_scratch:EXTQI 0 "=r,r"))]
727   ""
728   "@
729    andi. %0,%1,0xff
730    #"
731   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
732   [(set (match_dup 0)
733         (zero_extend:EXTQI (match_dup 1)))
734    (set (match_dup 2)
735         (compare:CC (match_dup 0)
736                     (const_int 0)))]
737   ""
738   [(set_attr "type" "logical")
739    (set_attr "dot" "yes")
740    (set_attr "length" "4,8")])
742 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
743   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
744         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
745                     (const_int 0)))
746    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
747         (zero_extend:EXTQI (match_dup 1)))]
748   ""
749   "@
750    andi. %0,%1,0xff
751    #"
752   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
753   [(set (match_dup 0)
754         (zero_extend:EXTQI (match_dup 1)))
755    (set (match_dup 2)
756         (compare:CC (match_dup 0)
757                     (const_int 0)))]
758   ""
759   [(set_attr "type" "logical")
760    (set_attr "dot" "yes")
761    (set_attr "length" "4,8")])
764 (define_insn "zero_extendhi<mode>2"
765   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
766         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
767   ""
768   "@
769    lhz%U1%X1 %0,%1
770    rlwinm %0,%1,0,0xffff
771    lxsihzx %x0,%y1
772    vextractuh %0,%1,6"
773   [(set_attr "type" "load,shift,fpload,vecperm")])
775 (define_insn_and_split "*zero_extendhi<mode>2_dot"
776   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
777         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
778                     (const_int 0)))
779    (clobber (match_scratch:EXTHI 0 "=r,r"))]
780   ""
781   "@
782    andi. %0,%1,0xffff
783    #"
784   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
785   [(set (match_dup 0)
786         (zero_extend:EXTHI (match_dup 1)))
787    (set (match_dup 2)
788         (compare:CC (match_dup 0)
789                     (const_int 0)))]
790   ""
791   [(set_attr "type" "logical")
792    (set_attr "dot" "yes")
793    (set_attr "length" "4,8")])
795 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
796   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
797         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
798                     (const_int 0)))
799    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
800         (zero_extend:EXTHI (match_dup 1)))]
801   ""
802   "@
803    andi. %0,%1,0xffff
804    #"
805   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
806   [(set (match_dup 0)
807         (zero_extend:EXTHI (match_dup 1)))
808    (set (match_dup 2)
809         (compare:CC (match_dup 0)
810                     (const_int 0)))]
811   ""
812   [(set_attr "type" "logical")
813    (set_attr "dot" "yes")
814    (set_attr "length" "4,8")])
817 (define_insn "zero_extendsi<mode>2"
818   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
819         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
820   ""
821   "@
822    lwz%U1%X1 %0,%1
823    rldicl %0,%1,0,32
824    lfiwzx %0,%y1
825    lxsiwzx %x0,%y1
826    mtvsrwz %x0,%1
827    mfvsrwz %0,%x1
828    xxextractuw %x0,%x1,4"
829   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
831 (define_insn_and_split "*zero_extendsi<mode>2_dot"
832   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
833         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
834                     (const_int 0)))
835    (clobber (match_scratch:EXTSI 0 "=r,r"))]
836   ""
837   "@
838    rldicl. %0,%1,0,32
839    #"
840   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
841   [(set (match_dup 0)
842         (zero_extend:DI (match_dup 1)))
843    (set (match_dup 2)
844         (compare:CC (match_dup 0)
845                     (const_int 0)))]
846   ""
847   [(set_attr "type" "shift")
848    (set_attr "dot" "yes")
849    (set_attr "length" "4,8")])
851 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
852   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
853         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
854                     (const_int 0)))
855    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
856         (zero_extend:EXTSI (match_dup 1)))]
857   ""
858   "@
859    rldicl. %0,%1,0,32
860    #"
861   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
862   [(set (match_dup 0)
863         (zero_extend:EXTSI (match_dup 1)))
864    (set (match_dup 2)
865         (compare:CC (match_dup 0)
866                     (const_int 0)))]
867   ""
868   [(set_attr "type" "shift")
869    (set_attr "dot" "yes")
870    (set_attr "length" "4,8")])
873 (define_insn "extendqi<mode>2"
874   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
875         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
876   ""
877   "@
878    extsb %0,%1
879    vextsb2d %0,%1"
880   [(set_attr "type" "exts,vecperm")])
882 (define_insn_and_split "*extendqi<mode>2_dot"
883   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
884         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
885                     (const_int 0)))
886    (clobber (match_scratch:EXTQI 0 "=r,r"))]
887   ""
888   "@
889    extsb. %0,%1
890    #"
891   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
892   [(set (match_dup 0)
893         (sign_extend:EXTQI (match_dup 1)))
894    (set (match_dup 2)
895         (compare:CC (match_dup 0)
896                     (const_int 0)))]
897   ""
898   [(set_attr "type" "exts")
899    (set_attr "dot" "yes")
900    (set_attr "length" "4,8")])
902 (define_insn_and_split "*extendqi<mode>2_dot2"
903   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
904         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
905                     (const_int 0)))
906    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
907         (sign_extend:EXTQI (match_dup 1)))]
908   ""
909   "@
910    extsb. %0,%1
911    #"
912   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
913   [(set (match_dup 0)
914         (sign_extend:EXTQI (match_dup 1)))
915    (set (match_dup 2)
916         (compare:CC (match_dup 0)
917                     (const_int 0)))]
918   ""
919   [(set_attr "type" "exts")
920    (set_attr "dot" "yes")
921    (set_attr "length" "4,8")])
924 (define_expand "extendhi<mode>2"
925   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
926         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
927   ""
928   "")
930 (define_insn "*extendhi<mode>2"
931   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
932         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
933   ""
934   "@
935    lha%U1%X1 %0,%1
936    extsh %0,%1
937    #
938    vextsh2d %0,%1"
939   [(set_attr "type" "load,exts,fpload,vecperm")
940    (set_attr "sign_extend" "yes")
941    (set_attr "length" "4,4,8,4")])
943 (define_split
944   [(set (match_operand:EXTHI 0 "altivec_register_operand")
945         (sign_extend:EXTHI
946          (match_operand:HI 1 "indexed_or_indirect_operand")))]
947   "TARGET_P9_VECTOR && reload_completed"
948   [(set (match_dup 2)
949         (match_dup 1))
950    (set (match_dup 0)
951         (sign_extend:EXTHI (match_dup 2)))]
953   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
956 (define_insn_and_split "*extendhi<mode>2_dot"
957   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
958         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
959                     (const_int 0)))
960    (clobber (match_scratch:EXTHI 0 "=r,r"))]
961   ""
962   "@
963    extsh. %0,%1
964    #"
965   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
966   [(set (match_dup 0)
967         (sign_extend:EXTHI (match_dup 1)))
968    (set (match_dup 2)
969         (compare:CC (match_dup 0)
970                     (const_int 0)))]
971   ""
972   [(set_attr "type" "exts")
973    (set_attr "dot" "yes")
974    (set_attr "length" "4,8")])
976 (define_insn_and_split "*extendhi<mode>2_dot2"
977   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
978         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
979                     (const_int 0)))
980    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
981         (sign_extend:EXTHI (match_dup 1)))]
982   ""
983   "@
984    extsh. %0,%1
985    #"
986   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
987   [(set (match_dup 0)
988         (sign_extend:EXTHI (match_dup 1)))
989    (set (match_dup 2)
990         (compare:CC (match_dup 0)
991                     (const_int 0)))]
992   ""
993   [(set_attr "type" "exts")
994    (set_attr "dot" "yes")
995    (set_attr "length" "4,8")])
998 (define_insn "extendsi<mode>2"
999   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1000                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
1002         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1003                      "Y,  r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
1004   ""
1005   "@
1006    lwa%U1%X1 %0,%1
1007    extsw %0,%1
1008    lfiwax %0,%y1
1009    lxsiwax %x0,%y1
1010    mtvsrwa %x0,%1
1011    vextsw2d %0,%1
1012    #
1013    #"
1014   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1015    (set_attr "sign_extend" "yes")
1016    (set_attr "length" "4,4,4,4,4,4,8,8")])
1018 (define_split
1019   [(set (match_operand:EXTSI 0 "int_reg_operand")
1020         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1021   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1022   [(set (match_dup 2)
1023         (match_dup 1))
1024    (set (match_dup 0)
1025         (sign_extend:DI (match_dup 2)))]
1027   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1030 (define_split
1031   [(set (match_operand:DI 0 "altivec_register_operand")
1032         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1033   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1034   [(const_int 0)]
1036   rtx dest = operands[0];
1037   rtx src = operands[1];
1038   int dest_regno = REGNO (dest);
1039   int src_regno = REGNO (src);
1040   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1041   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1043   if (VECTOR_ELT_ORDER_BIG)
1044     {
1045       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1046       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1047     }
1048   else
1049     {
1050       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1051       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1052     }
1053   DONE;
1056 (define_insn_and_split "*extendsi<mode>2_dot"
1057   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1058         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1059                     (const_int 0)))
1060    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1061   ""
1062   "@
1063    extsw. %0,%1
1064    #"
1065   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1066   [(set (match_dup 0)
1067         (sign_extend:EXTSI (match_dup 1)))
1068    (set (match_dup 2)
1069         (compare:CC (match_dup 0)
1070                     (const_int 0)))]
1071   ""
1072   [(set_attr "type" "exts")
1073    (set_attr "dot" "yes")
1074    (set_attr "length" "4,8")])
1076 (define_insn_and_split "*extendsi<mode>2_dot2"
1077   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1078         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1079                     (const_int 0)))
1080    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1081         (sign_extend:EXTSI (match_dup 1)))]
1082   ""
1083   "@
1084    extsw. %0,%1
1085    #"
1086   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1087   [(set (match_dup 0)
1088         (sign_extend:EXTSI (match_dup 1)))
1089    (set (match_dup 2)
1090         (compare:CC (match_dup 0)
1091                     (const_int 0)))]
1092   ""
1093   [(set_attr "type" "exts")
1094    (set_attr "dot" "yes")
1095    (set_attr "length" "4,8")])
1097 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1099 (define_insn "*macchwc"
1100   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1101         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1102                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1103                                        (const_int 16))
1104                                       (sign_extend:SI
1105                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1106                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1107                     (const_int 0)))
1108    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1109         (plus:SI (mult:SI (ashiftrt:SI
1110                            (match_dup 2)
1111                            (const_int 16))
1112                           (sign_extend:SI
1113                            (match_dup 1)))
1114                  (match_dup 4)))]
1115   "TARGET_MULHW"
1116   "macchw. %0,%1,%2"
1117   [(set_attr "type" "halfmul")])
1119 (define_insn "*macchw"
1120   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1121         (plus:SI (mult:SI (ashiftrt:SI
1122                            (match_operand:SI 2 "gpc_reg_operand" "r")
1123                            (const_int 16))
1124                           (sign_extend:SI
1125                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1126                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1127   "TARGET_MULHW"
1128   "macchw %0,%1,%2"
1129   [(set_attr "type" "halfmul")])
1131 (define_insn "*macchwuc"
1132   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1133         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1134                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1135                                        (const_int 16))
1136                                       (zero_extend:SI
1137                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1138                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1139                     (const_int 0)))
1140    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1141         (plus:SI (mult:SI (lshiftrt:SI
1142                            (match_dup 2)
1143                            (const_int 16))
1144                           (zero_extend:SI
1145                            (match_dup 1)))
1146                  (match_dup 4)))]
1147   "TARGET_MULHW"
1148   "macchwu. %0,%1,%2"
1149   [(set_attr "type" "halfmul")])
1151 (define_insn "*macchwu"
1152   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1153         (plus:SI (mult:SI (lshiftrt:SI
1154                            (match_operand:SI 2 "gpc_reg_operand" "r")
1155                            (const_int 16))
1156                           (zero_extend:SI
1157                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1158                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1159   "TARGET_MULHW"
1160   "macchwu %0,%1,%2"
1161   [(set_attr "type" "halfmul")])
1163 (define_insn "*machhwc"
1164   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1165         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1166                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1167                                        (const_int 16))
1168                                       (ashiftrt:SI
1169                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1170                                        (const_int 16)))
1171                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1172                     (const_int 0)))
1173    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1174         (plus:SI (mult:SI (ashiftrt:SI
1175                            (match_dup 1)
1176                            (const_int 16))
1177                           (ashiftrt:SI
1178                            (match_dup 2)
1179                            (const_int 16)))
1180                  (match_dup 4)))]
1181   "TARGET_MULHW"
1182   "machhw. %0,%1,%2"
1183   [(set_attr "type" "halfmul")])
1185 (define_insn "*machhw"
1186   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1187         (plus:SI (mult:SI (ashiftrt:SI
1188                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1189                            (const_int 16))
1190                           (ashiftrt:SI
1191                            (match_operand:SI 2 "gpc_reg_operand" "r")
1192                            (const_int 16)))
1193                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1194   "TARGET_MULHW"
1195   "machhw %0,%1,%2"
1196   [(set_attr "type" "halfmul")])
1198 (define_insn "*machhwuc"
1199   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1200         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1201                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1202                                        (const_int 16))
1203                                       (lshiftrt:SI
1204                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1205                                        (const_int 16)))
1206                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1207                     (const_int 0)))
1208    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1209         (plus:SI (mult:SI (lshiftrt:SI
1210                            (match_dup 1)
1211                            (const_int 16))
1212                           (lshiftrt:SI
1213                            (match_dup 2)
1214                            (const_int 16)))
1215                  (match_dup 4)))]
1216   "TARGET_MULHW"
1217   "machhwu. %0,%1,%2"
1218   [(set_attr "type" "halfmul")])
1220 (define_insn "*machhwu"
1221   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1222         (plus:SI (mult:SI (lshiftrt:SI
1223                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1224                            (const_int 16))
1225                           (lshiftrt:SI
1226                            (match_operand:SI 2 "gpc_reg_operand" "r")
1227                            (const_int 16)))
1228                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1229   "TARGET_MULHW"
1230   "machhwu %0,%1,%2"
1231   [(set_attr "type" "halfmul")])
1233 (define_insn "*maclhwc"
1234   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1235         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1236                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1237                                       (sign_extend:SI
1238                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1239                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1240                     (const_int 0)))
1241    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1242         (plus:SI (mult:SI (sign_extend:SI
1243                            (match_dup 1))
1244                           (sign_extend:SI
1245                            (match_dup 2)))
1246                  (match_dup 4)))]
1247   "TARGET_MULHW"
1248   "maclhw. %0,%1,%2"
1249   [(set_attr "type" "halfmul")])
1251 (define_insn "*maclhw"
1252   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1253         (plus:SI (mult:SI (sign_extend:SI
1254                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1255                           (sign_extend:SI
1256                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1257                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1258   "TARGET_MULHW"
1259   "maclhw %0,%1,%2"
1260   [(set_attr "type" "halfmul")])
1262 (define_insn "*maclhwuc"
1263   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1264         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1265                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1266                                       (zero_extend:SI
1267                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1268                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1269                     (const_int 0)))
1270    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1271         (plus:SI (mult:SI (zero_extend:SI
1272                            (match_dup 1))
1273                           (zero_extend:SI
1274                            (match_dup 2)))
1275                  (match_dup 4)))]
1276   "TARGET_MULHW"
1277   "maclhwu. %0,%1,%2"
1278   [(set_attr "type" "halfmul")])
1280 (define_insn "*maclhwu"
1281   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1282         (plus:SI (mult:SI (zero_extend:SI
1283                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1284                           (zero_extend:SI
1285                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1286                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1287   "TARGET_MULHW"
1288   "maclhwu %0,%1,%2"
1289   [(set_attr "type" "halfmul")])
1291 (define_insn "*nmacchwc"
1292   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1293         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1294                               (mult:SI (ashiftrt:SI
1295                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1296                                         (const_int 16))
1297                                        (sign_extend:SI
1298                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1299                     (const_int 0)))
1300    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1301         (minus:SI (match_dup 4)
1302                   (mult:SI (ashiftrt:SI
1303                             (match_dup 2)
1304                             (const_int 16))
1305                            (sign_extend:SI
1306                             (match_dup 1)))))]
1307   "TARGET_MULHW"
1308   "nmacchw. %0,%1,%2"
1309   [(set_attr "type" "halfmul")])
1311 (define_insn "*nmacchw"
1312   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1313         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1314                   (mult:SI (ashiftrt:SI
1315                             (match_operand:SI 2 "gpc_reg_operand" "r")
1316                             (const_int 16))
1317                            (sign_extend:SI
1318                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1319   "TARGET_MULHW"
1320   "nmacchw %0,%1,%2"
1321   [(set_attr "type" "halfmul")])
1323 (define_insn "*nmachhwc"
1324   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1325         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1326                               (mult:SI (ashiftrt:SI
1327                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1328                                         (const_int 16))
1329                                        (ashiftrt:SI
1330                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1331                                         (const_int 16))))
1332                     (const_int 0)))
1333    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1334         (minus:SI (match_dup 4)
1335                   (mult:SI (ashiftrt:SI
1336                             (match_dup 1)
1337                             (const_int 16))
1338                            (ashiftrt:SI
1339                             (match_dup 2)
1340                             (const_int 16)))))]
1341   "TARGET_MULHW"
1342   "nmachhw. %0,%1,%2"
1343   [(set_attr "type" "halfmul")])
1345 (define_insn "*nmachhw"
1346   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1348                   (mult:SI (ashiftrt:SI
1349                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1350                             (const_int 16))
1351                            (ashiftrt:SI
1352                             (match_operand:SI 2 "gpc_reg_operand" "r")
1353                             (const_int 16)))))]
1354   "TARGET_MULHW"
1355   "nmachhw %0,%1,%2"
1356   [(set_attr "type" "halfmul")])
1358 (define_insn "*nmaclhwc"
1359   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1360         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1361                               (mult:SI (sign_extend:SI
1362                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1363                                        (sign_extend:SI
1364                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1365                     (const_int 0)))
1366    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1367         (minus:SI (match_dup 4)
1368                   (mult:SI (sign_extend:SI
1369                             (match_dup 1))
1370                            (sign_extend:SI
1371                             (match_dup 2)))))]
1372   "TARGET_MULHW"
1373   "nmaclhw. %0,%1,%2"
1374   [(set_attr "type" "halfmul")])
1376 (define_insn "*nmaclhw"
1377   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1378         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1379                   (mult:SI (sign_extend:SI
1380                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1381                            (sign_extend:SI
1382                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1383   "TARGET_MULHW"
1384   "nmaclhw %0,%1,%2"
1385   [(set_attr "type" "halfmul")])
1387 (define_insn "*mulchwc"
1388   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1389         (compare:CC (mult:SI (ashiftrt:SI
1390                               (match_operand:SI 2 "gpc_reg_operand" "r")
1391                               (const_int 16))
1392                              (sign_extend:SI
1393                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1394                     (const_int 0)))
1395    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1396         (mult:SI (ashiftrt:SI
1397                   (match_dup 2)
1398                   (const_int 16))
1399                  (sign_extend:SI
1400                   (match_dup 1))))]
1401   "TARGET_MULHW"
1402   "mulchw. %0,%1,%2"
1403   [(set_attr "type" "halfmul")])
1405 (define_insn "*mulchw"
1406   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1407         (mult:SI (ashiftrt:SI
1408                   (match_operand:SI 2 "gpc_reg_operand" "r")
1409                   (const_int 16))
1410                  (sign_extend:SI
1411                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1412   "TARGET_MULHW"
1413   "mulchw %0,%1,%2"
1414   [(set_attr "type" "halfmul")])
1416 (define_insn "*mulchwuc"
1417   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1418         (compare:CC (mult:SI (lshiftrt:SI
1419                               (match_operand:SI 2 "gpc_reg_operand" "r")
1420                               (const_int 16))
1421                              (zero_extend:SI
1422                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1423                     (const_int 0)))
1424    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1425         (mult:SI (lshiftrt:SI
1426                   (match_dup 2)
1427                   (const_int 16))
1428                  (zero_extend:SI
1429                   (match_dup 1))))]
1430   "TARGET_MULHW"
1431   "mulchwu. %0,%1,%2"
1432   [(set_attr "type" "halfmul")])
1434 (define_insn "*mulchwu"
1435   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1436         (mult:SI (lshiftrt:SI
1437                   (match_operand:SI 2 "gpc_reg_operand" "r")
1438                   (const_int 16))
1439                  (zero_extend:SI
1440                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1441   "TARGET_MULHW"
1442   "mulchwu %0,%1,%2"
1443   [(set_attr "type" "halfmul")])
1445 (define_insn "*mulhhwc"
1446   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1447         (compare:CC (mult:SI (ashiftrt:SI
1448                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1449                               (const_int 16))
1450                              (ashiftrt:SI
1451                               (match_operand:SI 2 "gpc_reg_operand" "r")
1452                               (const_int 16)))
1453                     (const_int 0)))
1454    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1455         (mult:SI (ashiftrt:SI
1456                   (match_dup 1)
1457                   (const_int 16))
1458                  (ashiftrt:SI
1459                   (match_dup 2)
1460                   (const_int 16))))]
1461   "TARGET_MULHW"
1462   "mulhhw. %0,%1,%2"
1463   [(set_attr "type" "halfmul")])
1465 (define_insn "*mulhhw"
1466   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1467         (mult:SI (ashiftrt:SI
1468                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1469                   (const_int 16))
1470                  (ashiftrt:SI
1471                   (match_operand:SI 2 "gpc_reg_operand" "r")
1472                   (const_int 16))))]
1473   "TARGET_MULHW"
1474   "mulhhw %0,%1,%2"
1475   [(set_attr "type" "halfmul")])
1477 (define_insn "*mulhhwuc"
1478   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1479         (compare:CC (mult:SI (lshiftrt:SI
1480                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1481                               (const_int 16))
1482                              (lshiftrt:SI
1483                               (match_operand:SI 2 "gpc_reg_operand" "r")
1484                               (const_int 16)))
1485                     (const_int 0)))
1486    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1487         (mult:SI (lshiftrt:SI
1488                   (match_dup 1)
1489                   (const_int 16))
1490                  (lshiftrt:SI
1491                   (match_dup 2)
1492                   (const_int 16))))]
1493   "TARGET_MULHW"
1494   "mulhhwu. %0,%1,%2"
1495   [(set_attr "type" "halfmul")])
1497 (define_insn "*mulhhwu"
1498   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1499         (mult:SI (lshiftrt:SI
1500                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1501                   (const_int 16))
1502                  (lshiftrt:SI
1503                   (match_operand:SI 2 "gpc_reg_operand" "r")
1504                   (const_int 16))))]
1505   "TARGET_MULHW"
1506   "mulhhwu %0,%1,%2"
1507   [(set_attr "type" "halfmul")])
1509 (define_insn "*mullhwc"
1510   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1511         (compare:CC (mult:SI (sign_extend:SI
1512                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1513                              (sign_extend:SI
1514                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1515                     (const_int 0)))
1516    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517         (mult:SI (sign_extend:SI
1518                   (match_dup 1))
1519                  (sign_extend:SI
1520                   (match_dup 2))))]
1521   "TARGET_MULHW"
1522   "mullhw. %0,%1,%2"
1523   [(set_attr "type" "halfmul")])
1525 (define_insn "*mullhw"
1526   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1527         (mult:SI (sign_extend:SI
1528                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1529                  (sign_extend:SI
1530                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1531   "TARGET_MULHW"
1532   "mullhw %0,%1,%2"
1533   [(set_attr "type" "halfmul")])
1535 (define_insn "*mullhwuc"
1536   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1537         (compare:CC (mult:SI (zero_extend:SI
1538                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1539                              (zero_extend:SI
1540                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1541                     (const_int 0)))
1542    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1543         (mult:SI (zero_extend:SI
1544                   (match_dup 1))
1545                  (zero_extend:SI
1546                   (match_dup 2))))]
1547   "TARGET_MULHW"
1548   "mullhwu. %0,%1,%2"
1549   [(set_attr "type" "halfmul")])
1551 (define_insn "*mullhwu"
1552   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1553         (mult:SI (zero_extend:SI
1554                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1555                  (zero_extend:SI
1556                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1557   "TARGET_MULHW"
1558   "mullhwu %0,%1,%2"
1559   [(set_attr "type" "halfmul")])
1561 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1562 (define_insn "dlmzb"
1563   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1564         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1565                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1566                    UNSPEC_DLMZB_CR))
1567    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1568         (unspec:SI [(match_dup 1)
1569                     (match_dup 2)]
1570                    UNSPEC_DLMZB))]
1571   "TARGET_DLMZB"
1572   "dlmzb. %0,%1,%2")
1574 (define_expand "strlensi"
1575   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1576         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1577                     (match_operand:QI 2 "const_int_operand" "")
1578                     (match_operand 3 "const_int_operand" "")]
1579                    UNSPEC_DLMZB_STRLEN))
1580    (clobber (match_scratch:CC 4 "=x"))]
1581   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1583   rtx result = operands[0];
1584   rtx src = operands[1];
1585   rtx search_char = operands[2];
1586   rtx align = operands[3];
1587   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1588   rtx loop_label, end_label, mem, cr0, cond;
1589   if (search_char != const0_rtx
1590       || GET_CODE (align) != CONST_INT
1591       || INTVAL (align) < 8)
1592         FAIL;
1593   word1 = gen_reg_rtx (SImode);
1594   word2 = gen_reg_rtx (SImode);
1595   scratch_dlmzb = gen_reg_rtx (SImode);
1596   scratch_string = gen_reg_rtx (Pmode);
1597   loop_label = gen_label_rtx ();
1598   end_label = gen_label_rtx ();
1599   addr = force_reg (Pmode, XEXP (src, 0));
1600   emit_move_insn (scratch_string, addr);
1601   emit_label (loop_label);
1602   mem = change_address (src, SImode, scratch_string);
1603   emit_move_insn (word1, mem);
1604   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1605   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1606   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1607   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1608   emit_jump_insn (gen_rtx_SET (pc_rtx,
1609                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1610                                                      cond,
1611                                                      gen_rtx_LABEL_REF
1612                                                        (VOIDmode,
1613                                                         end_label),
1614                                                      pc_rtx)));
1615   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1616   emit_jump_insn (gen_rtx_SET (pc_rtx,
1617                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1618   emit_barrier ();
1619   emit_label (end_label);
1620   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1621   emit_insn (gen_subsi3 (result, scratch_string, addr));
1622   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1623   DONE;
1626 ;; Fixed-point arithmetic insns.
1628 (define_expand "add<mode>3"
1629   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1630         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1631                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1632   ""
1634   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1635     {
1636       rtx lo0 = gen_lowpart (SImode, operands[0]);
1637       rtx lo1 = gen_lowpart (SImode, operands[1]);
1638       rtx lo2 = gen_lowpart (SImode, operands[2]);
1639       rtx hi0 = gen_highpart (SImode, operands[0]);
1640       rtx hi1 = gen_highpart (SImode, operands[1]);
1641       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1643       if (!reg_or_short_operand (lo2, SImode))
1644         lo2 = force_reg (SImode, lo2);
1645       if (!adde_operand (hi2, SImode))
1646         hi2 = force_reg (SImode, hi2);
1648       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1649       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1650       DONE;
1651     }
1653   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1654     {
1655       rtx tmp = ((!can_create_pseudo_p ()
1656                   || rtx_equal_p (operands[0], operands[1]))
1657                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1659       /* Adding a constant to r0 is not a valid insn, so use a different
1660          strategy in that case.  */
1661       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1662         {
1663           if (operands[0] == operands[1])
1664             FAIL;
1665           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1666           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1667           DONE;
1668         }
1670       HOST_WIDE_INT val = INTVAL (operands[2]);
1671       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1672       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1674       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1675         FAIL;
1677       /* The ordering here is important for the prolog expander.
1678          When space is allocated from the stack, adding 'low' first may
1679          produce a temporary deallocation (which would be bad).  */
1680       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1681       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1682       DONE;
1683     }
1686 (define_insn "*add<mode>3"
1687   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1688         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1689                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1690   ""
1691   "@
1692    add %0,%1,%2
1693    addi %0,%1,%2
1694    addis %0,%1,%v2"
1695   [(set_attr "type" "add")])
1697 (define_insn "addsi3_high"
1698   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1699         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1700                  (high:SI (match_operand 2 "" ""))))]
1701   "TARGET_MACHO && !TARGET_64BIT"
1702   "addis %0,%1,ha16(%2)"
1703   [(set_attr "type" "add")])
1705 (define_insn_and_split "*add<mode>3_dot"
1706   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1707         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1708                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1709                     (const_int 0)))
1710    (clobber (match_scratch:GPR 0 "=r,r"))]
1711   "<MODE>mode == Pmode"
1712   "@
1713    add. %0,%1,%2
1714    #"
1715   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1716   [(set (match_dup 0)
1717         (plus:GPR (match_dup 1)
1718                  (match_dup 2)))
1719    (set (match_dup 3)
1720         (compare:CC (match_dup 0)
1721                     (const_int 0)))]
1722   ""
1723   [(set_attr "type" "add")
1724    (set_attr "dot" "yes")
1725    (set_attr "length" "4,8")])
1727 (define_insn_and_split "*add<mode>3_dot2"
1728   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1729         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1730                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1731                     (const_int 0)))
1732    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1733         (plus:GPR (match_dup 1)
1734                   (match_dup 2)))]
1735   "<MODE>mode == Pmode"
1736   "@
1737    add. %0,%1,%2
1738    #"
1739   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1740   [(set (match_dup 0)
1741         (plus:GPR (match_dup 1)
1742                   (match_dup 2)))
1743    (set (match_dup 3)
1744         (compare:CC (match_dup 0)
1745                     (const_int 0)))]
1746   ""
1747   [(set_attr "type" "add")
1748    (set_attr "dot" "yes")
1749    (set_attr "length" "4,8")])
1751 (define_insn_and_split "*add<mode>3_imm_dot"
1752   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1753         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1754                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1755                     (const_int 0)))
1756    (clobber (match_scratch:GPR 0 "=r,r"))
1757    (clobber (reg:GPR CA_REGNO))]
1758   "<MODE>mode == Pmode"
1759   "@
1760    addic. %0,%1,%2
1761    #"
1762   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1763   [(set (match_dup 0)
1764         (plus:GPR (match_dup 1)
1765                   (match_dup 2)))
1766    (set (match_dup 3)
1767         (compare:CC (match_dup 0)
1768                     (const_int 0)))]
1769   ""
1770   [(set_attr "type" "add")
1771    (set_attr "dot" "yes")
1772    (set_attr "length" "4,8")])
1774 (define_insn_and_split "*add<mode>3_imm_dot2"
1775   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1776         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1777                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1778                     (const_int 0)))
1779    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1780         (plus:GPR (match_dup 1)
1781                   (match_dup 2)))
1782    (clobber (reg:GPR CA_REGNO))]
1783   "<MODE>mode == Pmode"
1784   "@
1785    addic. %0,%1,%2
1786    #"
1787   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1788   [(set (match_dup 0)
1789         (plus:GPR (match_dup 1)
1790                   (match_dup 2)))
1791    (set (match_dup 3)
1792         (compare:CC (match_dup 0)
1793                     (const_int 0)))]
1794   ""
1795   [(set_attr "type" "add")
1796    (set_attr "dot" "yes")
1797    (set_attr "length" "4,8")])
1799 ;; Split an add that we can't do in one insn into two insns, each of which
1800 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1801 ;; add should be last in case the result gets used in an address.
1803 (define_split
1804   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1805         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1806                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1807   ""
1808   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1809    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1811   HOST_WIDE_INT val = INTVAL (operands[2]);
1812   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1813   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1815   operands[4] = GEN_INT (low);
1816   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1817     operands[3] = GEN_INT (rest);
1818   else if (can_create_pseudo_p ())
1819     {
1820       operands[3] = gen_reg_rtx (DImode);
1821       emit_move_insn (operands[3], operands[2]);
1822       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1823       DONE;
1824     }
1825   else
1826     FAIL;
1830 (define_insn "add<mode>3_carry"
1831   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1832         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1833                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1834    (set (reg:P CA_REGNO)
1835         (ltu:P (plus:P (match_dup 1)
1836                        (match_dup 2))
1837                (match_dup 1)))]
1838   ""
1839   "add%I2c %0,%1,%2"
1840   [(set_attr "type" "add")])
1842 (define_insn "*add<mode>3_imm_carry_pos"
1843   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1844         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1845                 (match_operand:P 2 "short_cint_operand" "n")))
1846    (set (reg:P CA_REGNO)
1847         (geu:P (match_dup 1)
1848                (match_operand:P 3 "const_int_operand" "n")))]
1849   "INTVAL (operands[2]) > 0
1850    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1851   "addic %0,%1,%2"
1852   [(set_attr "type" "add")])
1854 (define_insn "*add<mode>3_imm_carry_0"
1855   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1856         (match_operand:P 1 "gpc_reg_operand" "r"))
1857    (set (reg:P CA_REGNO)
1858         (const_int 0))]
1859   ""
1860   "addic %0,%1,0"
1861   [(set_attr "type" "add")])
1863 (define_insn "*add<mode>3_imm_carry_m1"
1864   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1865         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1866                 (const_int -1)))
1867    (set (reg:P CA_REGNO)
1868         (ne:P (match_dup 1)
1869               (const_int 0)))]
1870   ""
1871   "addic %0,%1,-1"
1872   [(set_attr "type" "add")])
1874 (define_insn "*add<mode>3_imm_carry_neg"
1875   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1876         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1877                 (match_operand:P 2 "short_cint_operand" "n")))
1878    (set (reg:P CA_REGNO)
1879         (gtu:P (match_dup 1)
1880                (match_operand:P 3 "const_int_operand" "n")))]
1881   "INTVAL (operands[2]) < 0
1882    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1883   "addic %0,%1,%2"
1884   [(set_attr "type" "add")])
1887 (define_expand "add<mode>3_carry_in"
1888   [(parallel [
1889      (set (match_operand:GPR 0 "gpc_reg_operand")
1890           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1891                               (match_operand:GPR 2 "adde_operand"))
1892                     (reg:GPR CA_REGNO)))
1893      (clobber (reg:GPR CA_REGNO))])]
1894   ""
1896   if (operands[2] == const0_rtx)
1897     {
1898       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1899       DONE;
1900     }
1901   if (operands[2] == constm1_rtx)
1902     {
1903       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1904       DONE;
1905     }
1908 (define_insn "*add<mode>3_carry_in_internal"
1909   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1910         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1911                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1912                   (reg:GPR CA_REGNO)))
1913    (clobber (reg:GPR CA_REGNO))]
1914   ""
1915   "adde %0,%1,%2"
1916   [(set_attr "type" "add")])
1918 (define_insn "*add<mode>3_carry_in_internal2"
1919   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1920         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1921                             (reg:GPR CA_REGNO))
1922                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1923    (clobber (reg:GPR CA_REGNO))]
1924   ""
1925   "adde %0,%1,%2"
1926   [(set_attr "type" "add")])
1928 (define_insn "add<mode>3_carry_in_0"
1929   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1930         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1931                   (reg:GPR CA_REGNO)))
1932    (clobber (reg:GPR CA_REGNO))]
1933   ""
1934   "addze %0,%1"
1935   [(set_attr "type" "add")])
1937 (define_insn "add<mode>3_carry_in_m1"
1938   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1939         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1940                             (reg:GPR CA_REGNO))
1941                   (const_int -1)))
1942    (clobber (reg:GPR CA_REGNO))]
1943   ""
1944   "addme %0,%1"
1945   [(set_attr "type" "add")])
1948 (define_expand "one_cmpl<mode>2"
1949   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1950         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1951   ""
1953   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1954     {
1955       rs6000_split_logical (operands, NOT, false, false, false);
1956       DONE;
1957     }
1960 (define_insn "*one_cmpl<mode>2"
1961   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1962         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1963   ""
1964   "not %0,%1")
1966 (define_insn_and_split "*one_cmpl<mode>2_dot"
1967   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1968         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1969                     (const_int 0)))
1970    (clobber (match_scratch:GPR 0 "=r,r"))]
1971   "<MODE>mode == Pmode"
1972   "@
1973    not. %0,%1
1974    #"
1975   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1976   [(set (match_dup 0)
1977         (not:GPR (match_dup 1)))
1978    (set (match_dup 2)
1979         (compare:CC (match_dup 0)
1980                     (const_int 0)))]
1981   ""
1982   [(set_attr "type" "logical")
1983    (set_attr "dot" "yes")
1984    (set_attr "length" "4,8")])
1986 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1987   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1988         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1989                     (const_int 0)))
1990    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1991         (not:GPR (match_dup 1)))]
1992   "<MODE>mode == Pmode"
1993   "@
1994    not. %0,%1
1995    #"
1996   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1997   [(set (match_dup 0)
1998         (not:GPR (match_dup 1)))
1999    (set (match_dup 2)
2000         (compare:CC (match_dup 0)
2001                     (const_int 0)))]
2002   ""
2003   [(set_attr "type" "logical")
2004    (set_attr "dot" "yes")
2005    (set_attr "length" "4,8")])
2008 (define_expand "sub<mode>3"
2009   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2010         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
2011                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
2012   ""
2014   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2015     {
2016       rtx lo0 = gen_lowpart (SImode, operands[0]);
2017       rtx lo1 = gen_lowpart (SImode, operands[1]);
2018       rtx lo2 = gen_lowpart (SImode, operands[2]);
2019       rtx hi0 = gen_highpart (SImode, operands[0]);
2020       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2021       rtx hi2 = gen_highpart (SImode, operands[2]);
2023       if (!reg_or_short_operand (lo1, SImode))
2024         lo1 = force_reg (SImode, lo1);
2025       if (!adde_operand (hi1, SImode))
2026         hi1 = force_reg (SImode, hi1);
2028       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2029       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2030       DONE;
2031     }
2033   if (short_cint_operand (operands[1], <MODE>mode))
2034     {
2035       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2036       DONE;
2037     }
2040 (define_insn "*subf<mode>3"
2041   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2042         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2043                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2044   ""
2045   "subf %0,%1,%2"
2046   [(set_attr "type" "add")])
2048 (define_insn_and_split "*subf<mode>3_dot"
2049   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2050         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2051                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2052                     (const_int 0)))
2053    (clobber (match_scratch:GPR 0 "=r,r"))]
2054   "<MODE>mode == Pmode"
2055   "@
2056    subf. %0,%1,%2
2057    #"
2058   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2059   [(set (match_dup 0)
2060         (minus:GPR (match_dup 2)
2061                    (match_dup 1)))
2062    (set (match_dup 3)
2063         (compare:CC (match_dup 0)
2064                     (const_int 0)))]
2065   ""
2066   [(set_attr "type" "add")
2067    (set_attr "dot" "yes")
2068    (set_attr "length" "4,8")])
2070 (define_insn_and_split "*subf<mode>3_dot2"
2071   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2072         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2073                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2074                     (const_int 0)))
2075    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2076         (minus:GPR (match_dup 2)
2077                    (match_dup 1)))]
2078   "<MODE>mode == Pmode"
2079   "@
2080    subf. %0,%1,%2
2081    #"
2082   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2083   [(set (match_dup 0)
2084         (minus:GPR (match_dup 2)
2085                    (match_dup 1)))
2086    (set (match_dup 3)
2087         (compare:CC (match_dup 0)
2088                     (const_int 0)))]
2089   ""
2090   [(set_attr "type" "add")
2091    (set_attr "dot" "yes")
2092    (set_attr "length" "4,8")])
2094 (define_insn "subf<mode>3_imm"
2095   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2096         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2097                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2098    (clobber (reg:GPR CA_REGNO))]
2099   ""
2100   "subfic %0,%1,%2"
2101   [(set_attr "type" "add")])
2103 (define_insn_and_split "subf<mode>3_carry_dot2"
2104   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2105         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2106                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2107                     (const_int 0)))
2108    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2109         (minus:P (match_dup 2)
2110                    (match_dup 1)))
2111    (set (reg:P CA_REGNO)
2112         (leu:P (match_dup 1)
2113                (match_dup 2)))]
2114   "<MODE>mode == Pmode"
2115   "@
2116    subfc. %0,%1,%2
2117    #"
2118   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2119   [(parallel [(set (match_dup 0)
2120                    (minus:P (match_dup 2)
2121                             (match_dup 1)))
2122               (set (reg:P CA_REGNO)
2123                    (leu:P (match_dup 1)
2124                           (match_dup 2)))])
2125    (set (match_dup 3)
2126         (compare:CC (match_dup 0)
2127                     (const_int 0)))]
2128   ""
2129   [(set_attr "type" "add")
2130    (set_attr "dot" "yes")
2131    (set_attr "length" "4,8")])
2133 (define_insn "subf<mode>3_carry"
2134   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2135         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2136                  (match_operand:P 1 "gpc_reg_operand" "r")))
2137    (set (reg:P CA_REGNO)
2138         (leu:P (match_dup 1)
2139                (match_dup 2)))]
2140   ""
2141   "subf%I2c %0,%1,%2"
2142   [(set_attr "type" "add")])
2144 (define_insn "*subf<mode>3_imm_carry_0"
2145   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2146         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2147    (set (reg:P CA_REGNO)
2148         (eq:P (match_dup 1)
2149               (const_int 0)))]
2150   ""
2151   "subfic %0,%1,0"
2152   [(set_attr "type" "add")])
2154 (define_insn "*subf<mode>3_imm_carry_m1"
2155   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2156         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2157    (set (reg:P CA_REGNO)
2158         (const_int 1))]
2159   ""
2160   "subfic %0,%1,-1"
2161   [(set_attr "type" "add")])
2164 (define_expand "subf<mode>3_carry_in"
2165   [(parallel [
2166      (set (match_operand:GPR 0 "gpc_reg_operand")
2167           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2168                               (reg:GPR CA_REGNO))
2169                     (match_operand:GPR 2 "adde_operand")))
2170      (clobber (reg:GPR CA_REGNO))])]
2171   ""
2173   if (operands[2] == const0_rtx)
2174     {
2175       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2176       DONE;
2177     }
2178   if (operands[2] == constm1_rtx)
2179     {
2180       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2181       DONE;
2182     }
2185 (define_insn "*subf<mode>3_carry_in_internal"
2186   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2187         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2188                             (reg:GPR CA_REGNO))
2189                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2190    (clobber (reg:GPR CA_REGNO))]
2191   ""
2192   "subfe %0,%1,%2"
2193   [(set_attr "type" "add")])
2195 (define_insn "subf<mode>3_carry_in_0"
2196   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2197         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2198                   (reg:GPR CA_REGNO)))
2199    (clobber (reg:GPR CA_REGNO))]
2200   ""
2201   "subfze %0,%1"
2202   [(set_attr "type" "add")])
2204 (define_insn "subf<mode>3_carry_in_m1"
2205   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2206         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2207                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2208                   (const_int -2)))
2209    (clobber (reg:GPR CA_REGNO))]
2210   ""
2211   "subfme %0,%1"
2212   [(set_attr "type" "add")])
2214 (define_insn "subf<mode>3_carry_in_xx"
2215   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2216         (plus:GPR (reg:GPR CA_REGNO)
2217                   (const_int -1)))
2218    (clobber (reg:GPR CA_REGNO))]
2219   ""
2220   "subfe %0,%0,%0"
2221   [(set_attr "type" "add")])
2224 (define_insn "neg<mode>2"
2225   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2226         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2227   ""
2228   "neg %0,%1"
2229   [(set_attr "type" "add")])
2231 (define_insn_and_split "*neg<mode>2_dot"
2232   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2233         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2234                     (const_int 0)))
2235    (clobber (match_scratch:GPR 0 "=r,r"))]
2236   "<MODE>mode == Pmode"
2237   "@
2238    neg. %0,%1
2239    #"
2240   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2241   [(set (match_dup 0)
2242         (neg:GPR (match_dup 1)))
2243    (set (match_dup 2)
2244         (compare:CC (match_dup 0)
2245                     (const_int 0)))]
2246   ""
2247   [(set_attr "type" "add")
2248    (set_attr "dot" "yes")
2249    (set_attr "length" "4,8")])
2251 (define_insn_and_split "*neg<mode>2_dot2"
2252   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2253         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2254                     (const_int 0)))
2255    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2256         (neg:GPR (match_dup 1)))]
2257   "<MODE>mode == Pmode"
2258   "@
2259    neg. %0,%1
2260    #"
2261   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2262   [(set (match_dup 0)
2263         (neg:GPR (match_dup 1)))
2264    (set (match_dup 2)
2265         (compare:CC (match_dup 0)
2266                     (const_int 0)))]
2267   ""
2268   [(set_attr "type" "add")
2269    (set_attr "dot" "yes")
2270    (set_attr "length" "4,8")])
2273 (define_insn "clz<mode>2"
2274   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2275         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2276   ""
2277   "cntlz<wd> %0,%1"
2278   [(set_attr "type" "cntlz")])
2280 (define_expand "ctz<mode>2"
2281    [(set (match_operand:GPR 0 "gpc_reg_operand")
2282          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2283   ""
2285   if (TARGET_CTZ)
2286     {
2287       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2288       DONE;
2289     }
2291   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2292   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2293   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2295   if (TARGET_POPCNTD)
2296     {
2297       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2298       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2299       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2300       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2301     }
2302   else
2303     {
2304       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2305       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2306       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2307       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2308     }
2310   DONE;
2313 (define_insn "ctz<mode>2_hw"
2314   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2315         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2316   "TARGET_CTZ"
2317   "cnttz<wd> %0,%1"
2318   [(set_attr "type" "cntlz")])
2320 (define_expand "ffs<mode>2"
2321   [(set (match_operand:GPR 0 "gpc_reg_operand")
2322         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2323   ""
2325   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2326   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2327   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2328   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2329   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2330   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2331   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2332   DONE;
2336 (define_expand "popcount<mode>2"
2337   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2338         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2339   "TARGET_POPCNTB || TARGET_POPCNTD"
2341   rs6000_emit_popcount (operands[0], operands[1]);
2342   DONE;
2345 (define_insn "popcntb<mode>2"
2346   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2347         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2348                     UNSPEC_POPCNTB))]
2349   "TARGET_POPCNTB"
2350   "popcntb %0,%1"
2351   [(set_attr "type" "popcnt")])
2353 (define_insn "popcntd<mode>2"
2354   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2355         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2356   "TARGET_POPCNTD"
2357   "popcnt<wd> %0,%1"
2358   [(set_attr "type" "popcnt")])
2361 (define_expand "parity<mode>2"
2362   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2363         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2364   "TARGET_POPCNTB"
2366   rs6000_emit_parity (operands[0], operands[1]);
2367   DONE;
2370 (define_insn "parity<mode>2_cmpb"
2371   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2372         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2373   "TARGET_CMPB && TARGET_POPCNTB"
2374   "prty<wd> %0,%1"
2375   [(set_attr "type" "popcnt")])
2377 (define_insn "cmpb<mode>3"
2378   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2379         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2380                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2381   "TARGET_CMPB"
2382   "cmpb %0,%1,%2"
2383   [(set_attr "type" "cmp")])
2385 ;; Since the hardware zeros the upper part of the register, save generating the
2386 ;; AND immediate if we are converting to unsigned
2387 (define_insn "*bswap<mode>2_extenddi"
2388   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2389         (zero_extend:DI
2390          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2391   "TARGET_POWERPC64"
2392   "l<wd>brx %0,%y1"
2393   [(set_attr "length" "4")
2394    (set_attr "type" "load")])
2396 (define_insn "*bswaphi2_extendsi"
2397   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2398         (zero_extend:SI
2399          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2400   ""
2401   "lhbrx %0,%y1"
2402   [(set_attr "length" "4")
2403    (set_attr "type" "load")])
2405 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2406 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2407 ;; load with byte swap, which can be slower than doing it in the registers.  It
2408 ;; also prevents certain failures with the RELOAD register allocator.
2410 (define_expand "bswap<mode>2"
2411   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2412    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2413   ""
2415   rtx dest = operands[0];
2416   rtx src = operands[1];
2418   if (!REG_P (dest) && !REG_P (src))
2419     src = force_reg (<MODE>mode, src);
2421   if (MEM_P (src))
2422     emit_insn (gen_bswap<mode>2_load (dest, src));
2423   else if (MEM_P (dest))
2424     emit_insn (gen_bswap<mode>2_store (dest, src));
2425   else
2426     emit_insn (gen_bswap<mode>2_reg (dest, src));
2427   DONE;
2430 (define_insn "bswap<mode>2_load"
2431   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2432         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2433   ""
2434   "l<wd>brx %0,%y1"
2435   [(set_attr "type" "load")])
2437 (define_insn "bswap<mode>2_store"
2438   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2439         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2440   ""
2441   "st<wd>brx %1,%y0"
2442   [(set_attr "type" "store")])
2444 (define_insn_and_split "bswaphi2_reg"
2445   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2446         (bswap:HI
2447          (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2448    (clobber (match_scratch:SI 2 "=&r,X"))]
2449   ""
2450   "@
2451    #
2452    xxbrh %x0,%x1"
2453   "reload_completed && int_reg_operand (operands[0], HImode)"
2454   [(set (match_dup 3)
2455         (and:SI (lshiftrt:SI (match_dup 4)
2456                              (const_int 8))
2457                 (const_int 255)))
2458    (set (match_dup 2)
2459         (and:SI (ashift:SI (match_dup 4)
2460                            (const_int 8))
2461                 (const_int 65280)))             ;; 0xff00
2462    (set (match_dup 3)
2463         (ior:SI (match_dup 3)
2464                 (match_dup 2)))]
2466   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2467   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2469   [(set_attr "length" "12,4")
2470    (set_attr "type" "*,vecperm")])
2472 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2473 ;; zero_extract insns do not change for -mlittle.
2474 (define_insn_and_split "bswapsi2_reg"
2475   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2476         (bswap:SI
2477          (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2478   ""
2479   "@
2480    #
2481    xxbrw %x0,%x1"
2482   "reload_completed && int_reg_operand (operands[0], SImode)"
2483   [(set (match_dup 0)                                   ; DABC
2484         (rotate:SI (match_dup 1)
2485                    (const_int 24)))
2486    (set (match_dup 0)                                   ; DCBC
2487         (ior:SI (and:SI (ashift:SI (match_dup 1)
2488                                    (const_int 8))
2489                         (const_int 16711680))
2490                 (and:SI (match_dup 0)
2491                         (const_int -16711681))))
2492    (set (match_dup 0)                                   ; DCBA
2493         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2494                                      (const_int 24))
2495                         (const_int 255))
2496                 (and:SI (match_dup 0)
2497                         (const_int -256))))]
2498   ""
2499   [(set_attr "length" "12,4")
2500    (set_attr "type" "*,vecperm")])
2502 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2503 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2504 ;; complex code.
2506 (define_expand "bswapdi2"
2507   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2508                    (bswap:DI
2509                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2510               (clobber (match_scratch:DI 2 ""))
2511               (clobber (match_scratch:DI 3 ""))])]
2512   ""
2514   rtx dest = operands[0];
2515   rtx src = operands[1];
2517   if (!REG_P (dest) && !REG_P (src))
2518     operands[1] = src = force_reg (DImode, src);
2520   if (TARGET_POWERPC64 && TARGET_LDBRX)
2521     {
2522       if (MEM_P (src))
2523         emit_insn (gen_bswapdi2_load (dest, src));
2524       else if (MEM_P (dest))
2525         emit_insn (gen_bswapdi2_store (dest, src));
2526       else if (TARGET_P9_VECTOR)
2527         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2528       else
2529         emit_insn (gen_bswapdi2_reg (dest, src));
2530       DONE;
2531     }
2533   if (!TARGET_POWERPC64)
2534     {
2535       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2536          that uses 64-bit registers needs the same scratch registers as 64-bit
2537          mode.  */
2538       emit_insn (gen_bswapdi2_32bit (dest, src));
2539       DONE;
2540     }
2543 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2544 (define_insn "bswapdi2_load"
2545   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2546         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2547   "TARGET_POWERPC64 && TARGET_LDBRX"
2548   "ldbrx %0,%y1"
2549   [(set_attr "type" "load")])
2551 (define_insn "bswapdi2_store"
2552   [(set (match_operand:DI 0 "memory_operand" "=Z")
2553         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2554   "TARGET_POWERPC64 && TARGET_LDBRX"
2555   "stdbrx %1,%y0"
2556   [(set_attr "type" "store")])
2558 (define_insn "bswapdi2_xxbrd"
2559   [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2560         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2561   "TARGET_P9_VECTOR"
2562   "xxbrd %x0,%x1"
2563   [(set_attr "type" "vecperm")])
2565 (define_insn "bswapdi2_reg"
2566   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2567         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2568    (clobber (match_scratch:DI 2 "=&r"))
2569    (clobber (match_scratch:DI 3 "=&r"))]
2570   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2571   "#"
2572   [(set_attr "length" "36")])
2574 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2575 (define_insn "*bswapdi2_64bit"
2576   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2577         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2578    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2579    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2580   "TARGET_POWERPC64 && !TARGET_LDBRX
2581    && (REG_P (operands[0]) || REG_P (operands[1]))
2582    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2583    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2584   "#"
2585   [(set_attr "length" "16,12,36")])
2587 (define_split
2588   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2589         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2590    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2591    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2592   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2593   [(const_int 0)]
2594   "
2596   rtx dest   = operands[0];
2597   rtx src    = operands[1];
2598   rtx op2    = operands[2];
2599   rtx op3    = operands[3];
2600   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2601                                     BYTES_BIG_ENDIAN ? 4 : 0);
2602   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2603                                      BYTES_BIG_ENDIAN ? 4 : 0);
2604   rtx addr1;
2605   rtx addr2;
2606   rtx word1;
2607   rtx word2;
2609   addr1 = XEXP (src, 0);
2610   if (GET_CODE (addr1) == PLUS)
2611     {
2612       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2613       if (TARGET_AVOID_XFORM)
2614         {
2615           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2616           addr2 = op2;
2617         }
2618       else
2619         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2620     }
2621   else if (TARGET_AVOID_XFORM)
2622     {
2623       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2624       addr2 = op2;
2625     }
2626   else
2627     {
2628       emit_move_insn (op2, GEN_INT (4));
2629       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2630     }
2632   word1 = change_address (src, SImode, addr1);
2633   word2 = change_address (src, SImode, addr2);
2635   if (BYTES_BIG_ENDIAN)
2636     {
2637       emit_insn (gen_bswapsi2 (op3_32, word2));
2638       emit_insn (gen_bswapsi2 (dest_32, word1));
2639     }
2640   else
2641     {
2642       emit_insn (gen_bswapsi2 (op3_32, word1));
2643       emit_insn (gen_bswapsi2 (dest_32, word2));
2644     }
2646   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2647   emit_insn (gen_iordi3 (dest, dest, op3));
2648   DONE;
2651 (define_split
2652   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2653         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2654    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2655    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2656   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2657   [(const_int 0)]
2658   "
2660   rtx dest   = operands[0];
2661   rtx src    = operands[1];
2662   rtx op2    = operands[2];
2663   rtx op3    = operands[3];
2664   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2665                                     BYTES_BIG_ENDIAN ? 4 : 0);
2666   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2667                                     BYTES_BIG_ENDIAN ? 4 : 0);
2668   rtx addr1;
2669   rtx addr2;
2670   rtx word1;
2671   rtx word2;
2673   addr1 = XEXP (dest, 0);
2674   if (GET_CODE (addr1) == PLUS)
2675     {
2676       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2677       if (TARGET_AVOID_XFORM)
2678         {
2679           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2680           addr2 = op2;
2681         }
2682       else
2683         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2684     }
2685   else if (TARGET_AVOID_XFORM)
2686     {
2687       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2688       addr2 = op2;
2689     }
2690   else
2691     {
2692       emit_move_insn (op2, GEN_INT (4));
2693       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2694     }
2696   word1 = change_address (dest, SImode, addr1);
2697   word2 = change_address (dest, SImode, addr2);
2699   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2701   if (BYTES_BIG_ENDIAN)
2702     {
2703       emit_insn (gen_bswapsi2 (word1, src_si));
2704       emit_insn (gen_bswapsi2 (word2, op3_si));
2705     }
2706   else
2707     {
2708       emit_insn (gen_bswapsi2 (word2, src_si));
2709       emit_insn (gen_bswapsi2 (word1, op3_si));
2710     }
2711   DONE;
2714 (define_split
2715   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2716         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2717    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2718    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2719   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2720   [(const_int 0)]
2721   "
2723   rtx dest    = operands[0];
2724   rtx src     = operands[1];
2725   rtx op2     = operands[2];
2726   rtx op3     = operands[3];
2727   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2728   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2729   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2730   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2731   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2733   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2734   emit_insn (gen_bswapsi2 (dest_si, src_si));
2735   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2736   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2737   emit_insn (gen_iordi3 (dest, dest, op3));
2738   DONE;
2741 (define_insn "bswapdi2_32bit"
2742   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2743         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2744    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2745   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2746   "#"
2747   [(set_attr "length" "16,12,36")])
2749 (define_split
2750   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2751         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2752    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2753   "!TARGET_POWERPC64 && reload_completed"
2754   [(const_int 0)]
2755   "
2757   rtx dest  = operands[0];
2758   rtx src   = operands[1];
2759   rtx op2   = operands[2];
2760   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2761   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2762   rtx addr1;
2763   rtx addr2;
2764   rtx word1;
2765   rtx word2;
2767   addr1 = XEXP (src, 0);
2768   if (GET_CODE (addr1) == PLUS)
2769     {
2770       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2771       if (TARGET_AVOID_XFORM
2772           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2773         {
2774           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2775           addr2 = op2;
2776         }
2777       else
2778         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2779     }
2780   else if (TARGET_AVOID_XFORM
2781            || REGNO (addr1) == REGNO (dest2))
2782     {
2783       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2784       addr2 = op2;
2785     }
2786   else
2787     {
2788       emit_move_insn (op2, GEN_INT (4));
2789       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2790     }
2792   word1 = change_address (src, SImode, addr1);
2793   word2 = change_address (src, SImode, addr2);
2795   emit_insn (gen_bswapsi2 (dest2, word1));
2796   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2797      thus allowing us to omit an early clobber on the output.  */
2798   emit_insn (gen_bswapsi2 (dest1, word2));
2799   DONE;
2802 (define_split
2803   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2804         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2805    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2806   "!TARGET_POWERPC64 && reload_completed"
2807   [(const_int 0)]
2808   "
2810   rtx dest = operands[0];
2811   rtx src  = operands[1];
2812   rtx op2  = operands[2];
2813   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2814   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2815   rtx addr1;
2816   rtx addr2;
2817   rtx word1;
2818   rtx word2;
2820   addr1 = XEXP (dest, 0);
2821   if (GET_CODE (addr1) == PLUS)
2822     {
2823       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2824       if (TARGET_AVOID_XFORM)
2825         {
2826           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2827           addr2 = op2;
2828         }
2829       else
2830         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2831     }
2832   else if (TARGET_AVOID_XFORM)
2833     {
2834       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2835       addr2 = op2;
2836     }
2837   else
2838     {
2839       emit_move_insn (op2, GEN_INT (4));
2840       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2841     }
2843   word1 = change_address (dest, SImode, addr1);
2844   word2 = change_address (dest, SImode, addr2);
2846   emit_insn (gen_bswapsi2 (word2, src1));
2847   emit_insn (gen_bswapsi2 (word1, src2));
2848   DONE;
2851 (define_split
2852   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2853         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2854    (clobber (match_operand:SI 2 "" ""))]
2855   "!TARGET_POWERPC64 && reload_completed"
2856   [(const_int 0)]
2857   "
2859   rtx dest  = operands[0];
2860   rtx src   = operands[1];
2861   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2862   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2863   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2864   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2866   emit_insn (gen_bswapsi2 (dest1, src2));
2867   emit_insn (gen_bswapsi2 (dest2, src1));
2868   DONE;
2872 (define_insn "mul<mode>3"
2873   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2874         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2875                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2876   ""
2877   "@
2878    mull<wd> %0,%1,%2
2879    mulli %0,%1,%2"
2880    [(set_attr "type" "mul")
2881     (set (attr "size")
2882       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2883                 (const_string "8")
2884              (match_operand:GPR 2 "short_cint_operand" "")
2885                 (const_string "16")]
2886         (const_string "<bits>")))])
2888 (define_insn_and_split "*mul<mode>3_dot"
2889   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2890         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2891                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2892                     (const_int 0)))
2893    (clobber (match_scratch:GPR 0 "=r,r"))]
2894   "<MODE>mode == Pmode"
2895   "@
2896    mull<wd>. %0,%1,%2
2897    #"
2898   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2899   [(set (match_dup 0)
2900         (mult:GPR (match_dup 1)
2901                   (match_dup 2)))
2902    (set (match_dup 3)
2903         (compare:CC (match_dup 0)
2904                     (const_int 0)))]
2905   ""
2906   [(set_attr "type" "mul")
2907    (set_attr "size" "<bits>")
2908    (set_attr "dot" "yes")
2909    (set_attr "length" "4,8")])
2911 (define_insn_and_split "*mul<mode>3_dot2"
2912   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2913         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2914                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2915                     (const_int 0)))
2916    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2917         (mult:GPR (match_dup 1)
2918                   (match_dup 2)))]
2919   "<MODE>mode == Pmode"
2920   "@
2921    mull<wd>. %0,%1,%2
2922    #"
2923   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2924   [(set (match_dup 0)
2925         (mult:GPR (match_dup 1)
2926                   (match_dup 2)))
2927    (set (match_dup 3)
2928         (compare:CC (match_dup 0)
2929                     (const_int 0)))]
2930   ""
2931   [(set_attr "type" "mul")
2932    (set_attr "size" "<bits>")
2933    (set_attr "dot" "yes")
2934    (set_attr "length" "4,8")])
2937 (define_expand "<su>mul<mode>3_highpart"
2938   [(set (match_operand:GPR 0 "gpc_reg_operand")
2939         (subreg:GPR
2940           (mult:<DMODE> (any_extend:<DMODE>
2941                           (match_operand:GPR 1 "gpc_reg_operand"))
2942                         (any_extend:<DMODE>
2943                           (match_operand:GPR 2 "gpc_reg_operand")))
2944          0))]
2945   ""
2947   if (<MODE>mode == SImode && TARGET_POWERPC64)
2948     {
2949       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2950                                              operands[2]));
2951       DONE;
2952     }
2954   if (!WORDS_BIG_ENDIAN)
2955     {
2956       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2957                                                  operands[2]));
2958       DONE;
2959     }
2962 (define_insn "*<su>mul<mode>3_highpart"
2963   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2964         (subreg:GPR
2965           (mult:<DMODE> (any_extend:<DMODE>
2966                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2967                         (any_extend:<DMODE>
2968                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2969          0))]
2970   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2971   "mulh<wd><u> %0,%1,%2"
2972   [(set_attr "type" "mul")
2973    (set_attr "size" "<bits>")])
2975 (define_insn "<su>mulsi3_highpart_le"
2976   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2977         (subreg:SI
2978           (mult:DI (any_extend:DI
2979                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2980                    (any_extend:DI
2981                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2982          4))]
2983   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2984   "mulhw<u> %0,%1,%2"
2985   [(set_attr "type" "mul")])
2987 (define_insn "<su>muldi3_highpart_le"
2988   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2989         (subreg:DI
2990           (mult:TI (any_extend:TI
2991                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2992                    (any_extend:TI
2993                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2994          8))]
2995   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2996   "mulhd<u> %0,%1,%2"
2997   [(set_attr "type" "mul")
2998    (set_attr "size" "64")])
3000 (define_insn "<su>mulsi3_highpart_64"
3001   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3002         (truncate:SI
3003           (lshiftrt:DI
3004             (mult:DI (any_extend:DI
3005                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3006                      (any_extend:DI
3007                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3008             (const_int 32))))]
3009   "TARGET_POWERPC64"
3010   "mulhw<u> %0,%1,%2"
3011   [(set_attr "type" "mul")])
3013 (define_expand "<u>mul<mode><dmode>3"
3014   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3015         (mult:<DMODE> (any_extend:<DMODE>
3016                         (match_operand:GPR 1 "gpc_reg_operand"))
3017                       (any_extend:<DMODE>
3018                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3019   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3021   rtx l = gen_reg_rtx (<MODE>mode);
3022   rtx h = gen_reg_rtx (<MODE>mode);
3023   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3024   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3025   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3026   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3027   DONE;
3030 (define_insn "*maddld4"
3031   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3032         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3033                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3034                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3035   "TARGET_MADDLD"
3036   "maddld %0,%1,%2,%3"
3037   [(set_attr "type" "mul")])
3039 (define_insn "udiv<mode>3"
3040   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3041         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3042                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3043   ""
3044   "div<wd>u %0,%1,%2"
3045   [(set_attr "type" "div")
3046    (set_attr "size" "<bits>")])
3049 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3050 ;; modulus.  If it isn't a power of two, force operands into register and do
3051 ;; a normal divide.
3052 (define_expand "div<mode>3"
3053   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3054         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3055                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3056   ""
3058   if (CONST_INT_P (operands[2])
3059       && INTVAL (operands[2]) > 0
3060       && exact_log2 (INTVAL (operands[2])) >= 0)
3061     {
3062       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3063       DONE;
3064     }
3066   operands[2] = force_reg (<MODE>mode, operands[2]);
3069 (define_insn "*div<mode>3"
3070   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3071         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3072                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3073   ""
3074   "div<wd> %0,%1,%2"
3075   [(set_attr "type" "div")
3076    (set_attr "size" "<bits>")])
3078 (define_insn "div<mode>3_sra"
3079   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3080         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3081                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3082    (clobber (reg:GPR CA_REGNO))]
3083   ""
3084   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3085   [(set_attr "type" "two")
3086    (set_attr "length" "8")])
3088 (define_insn_and_split "*div<mode>3_sra_dot"
3089   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3090         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3091                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3092                     (const_int 0)))
3093    (clobber (match_scratch:GPR 0 "=r,r"))
3094    (clobber (reg:GPR CA_REGNO))]
3095   "<MODE>mode == Pmode"
3096   "@
3097    sra<wd>i %0,%1,%p2\;addze. %0,%0
3098    #"
3099   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3100   [(parallel [(set (match_dup 0)
3101                    (div:GPR (match_dup 1)
3102                             (match_dup 2)))
3103               (clobber (reg:GPR CA_REGNO))])
3104    (set (match_dup 3)
3105         (compare:CC (match_dup 0)
3106                     (const_int 0)))]
3107   ""
3108   [(set_attr "type" "two")
3109    (set_attr "length" "8,12")
3110    (set_attr "cell_micro" "not")])
3112 (define_insn_and_split "*div<mode>3_sra_dot2"
3113   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3114         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3115                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3116                     (const_int 0)))
3117    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3118         (div:GPR (match_dup 1)
3119                  (match_dup 2)))
3120    (clobber (reg:GPR CA_REGNO))]
3121   "<MODE>mode == Pmode"
3122   "@
3123    sra<wd>i %0,%1,%p2\;addze. %0,%0
3124    #"
3125   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3126   [(parallel [(set (match_dup 0)
3127                    (div:GPR (match_dup 1)
3128                             (match_dup 2)))
3129               (clobber (reg:GPR CA_REGNO))])
3130    (set (match_dup 3)
3131         (compare:CC (match_dup 0)
3132                     (const_int 0)))]
3133   ""
3134   [(set_attr "type" "two")
3135    (set_attr "length" "8,12")
3136    (set_attr "cell_micro" "not")])
3138 (define_expand "mod<mode>3"
3139   [(set (match_operand:GPR 0 "gpc_reg_operand")
3140         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3141                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3142   ""
3144   int i;
3145   rtx temp1;
3146   rtx temp2;
3148   if (GET_CODE (operands[2]) != CONST_INT
3149       || INTVAL (operands[2]) <= 0
3150       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3151     {
3152       if (!TARGET_MODULO)
3153         FAIL;
3155       operands[2] = force_reg (<MODE>mode, operands[2]);
3156     }
3157   else
3158     {
3159       temp1 = gen_reg_rtx (<MODE>mode);
3160       temp2 = gen_reg_rtx (<MODE>mode);
3162       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3163       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3164       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3165       DONE;
3166     }
3169 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3170 ;; mod, prefer putting the result of mod into a different register
3171 (define_insn "*mod<mode>3"
3172   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3173         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3174                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3175   "TARGET_MODULO"
3176   "mods<wd> %0,%1,%2"
3177   [(set_attr "type" "div")
3178    (set_attr "size" "<bits>")])
3181 (define_insn "umod<mode>3"
3182   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3183         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3184                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3185   "TARGET_MODULO"
3186   "modu<wd> %0,%1,%2"
3187   [(set_attr "type" "div")
3188    (set_attr "size" "<bits>")])
3190 ;; On machines with modulo support, do a combined div/mod the old fashioned
3191 ;; method, since the multiply/subtract is faster than doing the mod instruction
3192 ;; after a divide.
3194 (define_peephole2
3195   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3196         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3197                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3198    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3199         (mod:GPR (match_dup 1)
3200                  (match_dup 2)))]
3201   "TARGET_MODULO
3202    && ! reg_mentioned_p (operands[0], operands[1])
3203    && ! reg_mentioned_p (operands[0], operands[2])
3204    && ! reg_mentioned_p (operands[3], operands[1])
3205    && ! reg_mentioned_p (operands[3], operands[2])"
3206   [(set (match_dup 0)
3207         (div:GPR (match_dup 1)
3208                  (match_dup 2)))
3209    (set (match_dup 3)
3210         (mult:GPR (match_dup 0)
3211                   (match_dup 2)))
3212    (set (match_dup 3)
3213         (minus:GPR (match_dup 1)
3214                    (match_dup 3)))])
3216 (define_peephole2
3217   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3218         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3219                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3220    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3221         (umod:GPR (match_dup 1)
3222                   (match_dup 2)))]
3223   "TARGET_MODULO
3224    && ! reg_mentioned_p (operands[0], operands[1])
3225    && ! reg_mentioned_p (operands[0], operands[2])
3226    && ! reg_mentioned_p (operands[3], operands[1])
3227    && ! reg_mentioned_p (operands[3], operands[2])"
3228   [(set (match_dup 0)
3229         (udiv:GPR (match_dup 1)
3230                   (match_dup 2)))
3231    (set (match_dup 3)
3232         (mult:GPR (match_dup 0)
3233                   (match_dup 2)))
3234    (set (match_dup 3)
3235         (minus:GPR (match_dup 1)
3236                    (match_dup 3)))])
3239 ;; Logical instructions
3240 ;; The logical instructions are mostly combined by using match_operator,
3241 ;; but the plain AND insns are somewhat different because there is no
3242 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3243 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3245 (define_expand "and<mode>3"
3246   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3247         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3248                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3249   ""
3251   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3252     {
3253       rs6000_split_logical (operands, AND, false, false, false);
3254       DONE;
3255     }
3257   if (CONST_INT_P (operands[2]))
3258     {
3259       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3260         {
3261           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3262           DONE;
3263         }
3265       if (logical_const_operand (operands[2], <MODE>mode))
3266         {
3267           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3268           DONE;
3269         }
3271       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3272         {
3273           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3274           DONE;
3275         }
3277       operands[2] = force_reg (<MODE>mode, operands[2]);
3278     }
3282 (define_insn "and<mode>3_imm"
3283   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3284         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3285                  (match_operand:GPR 2 "logical_const_operand" "n")))
3286    (clobber (match_scratch:CC 3 "=x"))]
3287   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3288   "andi%e2. %0,%1,%u2"
3289   [(set_attr "type" "logical")
3290    (set_attr "dot" "yes")])
3292 (define_insn_and_split "*and<mode>3_imm_dot"
3293   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3294         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3295                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3296                     (const_int 0)))
3297    (clobber (match_scratch:GPR 0 "=r,r"))
3298    (clobber (match_scratch:CC 4 "=X,x"))]
3299   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3300    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3301   "@
3302    andi%e2. %0,%1,%u2
3303    #"
3304   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3305   [(parallel [(set (match_dup 0)
3306                    (and:GPR (match_dup 1)
3307                             (match_dup 2)))
3308               (clobber (match_dup 4))])
3309    (set (match_dup 3)
3310         (compare:CC (match_dup 0)
3311                     (const_int 0)))]
3312   ""
3313   [(set_attr "type" "logical")
3314    (set_attr "dot" "yes")
3315    (set_attr "length" "4,8")])
3317 (define_insn_and_split "*and<mode>3_imm_dot2"
3318   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3319         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3320                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3321                     (const_int 0)))
3322    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3323         (and:GPR (match_dup 1)
3324                  (match_dup 2)))
3325    (clobber (match_scratch:CC 4 "=X,x"))]
3326   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3327    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3328   "@
3329    andi%e2. %0,%1,%u2
3330    #"
3331   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3332   [(parallel [(set (match_dup 0)
3333                    (and:GPR (match_dup 1)
3334                             (match_dup 2)))
3335               (clobber (match_dup 4))])
3336    (set (match_dup 3)
3337         (compare:CC (match_dup 0)
3338                     (const_int 0)))]
3339   ""
3340   [(set_attr "type" "logical")
3341    (set_attr "dot" "yes")
3342    (set_attr "length" "4,8")])
3344 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3345   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3346         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3347                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3348                     (const_int 0)))
3349    (clobber (match_scratch:GPR 0 "=r,r"))]
3350   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3351    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3352   "@
3353    andi%e2. %0,%1,%u2
3354    #"
3355   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3356   [(set (match_dup 0)
3357         (and:GPR (match_dup 1)
3358                  (match_dup 2)))
3359    (set (match_dup 3)
3360         (compare:CC (match_dup 0)
3361                     (const_int 0)))]
3362   ""
3363   [(set_attr "type" "logical")
3364    (set_attr "dot" "yes")
3365    (set_attr "length" "4,8")])
3367 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3368   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3369         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3370                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3371                     (const_int 0)))
3372    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3373         (and:GPR (match_dup 1)
3374                  (match_dup 2)))]
3375   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3376    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3377   "@
3378    andi%e2. %0,%1,%u2
3379    #"
3380   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3381   [(set (match_dup 0)
3382         (and:GPR (match_dup 1)
3383                  (match_dup 2)))
3384    (set (match_dup 3)
3385         (compare:CC (match_dup 0)
3386                     (const_int 0)))]
3387   ""
3388   [(set_attr "type" "logical")
3389    (set_attr "dot" "yes")
3390    (set_attr "length" "4,8")])
3392 (define_insn "*and<mode>3_imm_dot_shifted"
3393   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3394         (compare:CC
3395           (and:GPR
3396             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3397                           (match_operand:SI 4 "const_int_operand" "n"))
3398             (match_operand:GPR 2 "const_int_operand" "n"))
3399           (const_int 0)))
3400    (clobber (match_scratch:GPR 0 "=r"))]
3401   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3402                                    << INTVAL (operands[4])),
3403                           DImode)
3404    && (<MODE>mode == Pmode
3405        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3407   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3408   return "andi%e2. %0,%1,%u2";
3410   [(set_attr "type" "logical")
3411    (set_attr "dot" "yes")])
3414 (define_insn "and<mode>3_mask"
3415   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3416         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3417                  (match_operand:GPR 2 "const_int_operand" "n")))]
3418   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3420   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3422   [(set_attr "type" "shift")])
3424 (define_insn_and_split "*and<mode>3_mask_dot"
3425   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3426         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3427                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3428                     (const_int 0)))
3429    (clobber (match_scratch:GPR 0 "=r,r"))]
3430   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3431    && !logical_const_operand (operands[2], <MODE>mode)
3432    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3434   if (which_alternative == 0)
3435     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3436   else
3437     return "#";
3439   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3440   [(set (match_dup 0)
3441         (and:GPR (match_dup 1)
3442                  (match_dup 2)))
3443    (set (match_dup 3)
3444         (compare:CC (match_dup 0)
3445                     (const_int 0)))]
3446   ""
3447   [(set_attr "type" "shift")
3448    (set_attr "dot" "yes")
3449    (set_attr "length" "4,8")])
3451 (define_insn_and_split "*and<mode>3_mask_dot2"
3452   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3453         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3454                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3455                     (const_int 0)))
3456    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3457         (and:GPR (match_dup 1)
3458                  (match_dup 2)))]
3459   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3460    && !logical_const_operand (operands[2], <MODE>mode)
3461    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3463   if (which_alternative == 0)
3464     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3465   else
3466     return "#";
3468   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3469   [(set (match_dup 0)
3470         (and:GPR (match_dup 1)
3471                  (match_dup 2)))
3472    (set (match_dup 3)
3473         (compare:CC (match_dup 0)
3474                     (const_int 0)))]
3475   ""
3476   [(set_attr "type" "shift")
3477    (set_attr "dot" "yes")
3478    (set_attr "length" "4,8")])
3481 (define_insn_and_split "*and<mode>3_2insn"
3482   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3483         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3484                  (match_operand:GPR 2 "const_int_operand" "n")))]
3485   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3486    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3487         || logical_const_operand (operands[2], <MODE>mode))"
3488   "#"
3489   "&& 1"
3490   [(pc)]
3492   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3493   DONE;
3495   [(set_attr "type" "shift")
3496    (set_attr "length" "8")])
3498 (define_insn_and_split "*and<mode>3_2insn_dot"
3499   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3500         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3501                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3502                     (const_int 0)))
3503    (clobber (match_scratch:GPR 0 "=r,r"))]
3504   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3505    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3506    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3507         || logical_const_operand (operands[2], <MODE>mode))"
3508   "#"
3509   "&& reload_completed"
3510   [(pc)]
3512   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3513   DONE;
3515   [(set_attr "type" "shift")
3516    (set_attr "dot" "yes")
3517    (set_attr "length" "8,12")])
3519 (define_insn_and_split "*and<mode>3_2insn_dot2"
3520   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3521         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3522                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3523                     (const_int 0)))
3524    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3525         (and:GPR (match_dup 1)
3526                  (match_dup 2)))]
3527   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3528    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3529    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3530         || logical_const_operand (operands[2], <MODE>mode))"
3531   "#"
3532   "&& reload_completed"
3533   [(pc)]
3535   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3536   DONE;
3538   [(set_attr "type" "shift")
3539    (set_attr "dot" "yes")
3540    (set_attr "length" "8,12")])
3543 (define_expand "<code><mode>3"
3544   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3545         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3546                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3547   ""
3549   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3550     {
3551       rs6000_split_logical (operands, <CODE>, false, false, false);
3552       DONE;
3553     }
3555   if (non_logical_cint_operand (operands[2], <MODE>mode))
3556     {
3557       rtx tmp = ((!can_create_pseudo_p ()
3558                   || rtx_equal_p (operands[0], operands[1]))
3559                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3561       HOST_WIDE_INT value = INTVAL (operands[2]);
3562       HOST_WIDE_INT lo = value & 0xffff;
3563       HOST_WIDE_INT hi = value - lo;
3565       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3566       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3567       DONE;
3568     }
3570   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3571     operands[2] = force_reg (<MODE>mode, operands[2]);
3574 (define_split
3575   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3576         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3577                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3578   ""
3579   [(set (match_dup 3)
3580         (iorxor:GPR (match_dup 1)
3581                     (match_dup 4)))
3582    (set (match_dup 0)
3583         (iorxor:GPR (match_dup 3)
3584                     (match_dup 5)))]
3586   operands[3] = ((!can_create_pseudo_p ()
3587                   || rtx_equal_p (operands[0], operands[1]))
3588                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3590   HOST_WIDE_INT value = INTVAL (operands[2]);
3591   HOST_WIDE_INT lo = value & 0xffff;
3592   HOST_WIDE_INT hi = value - lo;
3594   operands[4] = GEN_INT (hi);
3595   operands[5] = GEN_INT (lo);
3598 (define_insn "*bool<mode>3_imm"
3599   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3600         (match_operator:GPR 3 "boolean_or_operator"
3601          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3602           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3603   ""
3604   "%q3i%e2 %0,%1,%u2"
3605   [(set_attr "type" "logical")])
3607 (define_insn "*bool<mode>3"
3608   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3609         (match_operator:GPR 3 "boolean_operator"
3610          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3611           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3612   ""
3613   "%q3 %0,%1,%2"
3614   [(set_attr "type" "logical")])
3616 (define_insn_and_split "*bool<mode>3_dot"
3617   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3618         (compare:CC (match_operator:GPR 3 "boolean_operator"
3619          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3620           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3621          (const_int 0)))
3622    (clobber (match_scratch:GPR 0 "=r,r"))]
3623   "<MODE>mode == Pmode"
3624   "@
3625    %q3. %0,%1,%2
3626    #"
3627   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3628   [(set (match_dup 0)
3629         (match_dup 3))
3630    (set (match_dup 4)
3631         (compare:CC (match_dup 0)
3632                     (const_int 0)))]
3633   ""
3634   [(set_attr "type" "logical")
3635    (set_attr "dot" "yes")
3636    (set_attr "length" "4,8")])
3638 (define_insn_and_split "*bool<mode>3_dot2"
3639   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3640         (compare:CC (match_operator:GPR 3 "boolean_operator"
3641          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3642           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3643          (const_int 0)))
3644    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3645         (match_dup 3))]
3646   "<MODE>mode == Pmode"
3647   "@
3648    %q3. %0,%1,%2
3649    #"
3650   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3651   [(set (match_dup 0)
3652         (match_dup 3))
3653    (set (match_dup 4)
3654         (compare:CC (match_dup 0)
3655                     (const_int 0)))]
3656   ""
3657   [(set_attr "type" "logical")
3658    (set_attr "dot" "yes")
3659    (set_attr "length" "4,8")])
3662 (define_insn "*boolc<mode>3"
3663   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3664         (match_operator:GPR 3 "boolean_operator"
3665          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3666           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3667   ""
3668   "%q3 %0,%1,%2"
3669   [(set_attr "type" "logical")])
3671 (define_insn_and_split "*boolc<mode>3_dot"
3672   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3673         (compare:CC (match_operator:GPR 3 "boolean_operator"
3674          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3675           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3676          (const_int 0)))
3677    (clobber (match_scratch:GPR 0 "=r,r"))]
3678   "<MODE>mode == Pmode"
3679   "@
3680    %q3. %0,%1,%2
3681    #"
3682   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3683   [(set (match_dup 0)
3684         (match_dup 3))
3685    (set (match_dup 4)
3686         (compare:CC (match_dup 0)
3687                     (const_int 0)))]
3688   ""
3689   [(set_attr "type" "logical")
3690    (set_attr "dot" "yes")
3691    (set_attr "length" "4,8")])
3693 (define_insn_and_split "*boolc<mode>3_dot2"
3694   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3695         (compare:CC (match_operator:GPR 3 "boolean_operator"
3696          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3697           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3698          (const_int 0)))
3699    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3700         (match_dup 3))]
3701   "<MODE>mode == Pmode"
3702   "@
3703    %q3. %0,%1,%2
3704    #"
3705   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3706   [(set (match_dup 0)
3707         (match_dup 3))
3708    (set (match_dup 4)
3709         (compare:CC (match_dup 0)
3710                     (const_int 0)))]
3711   ""
3712   [(set_attr "type" "logical")
3713    (set_attr "dot" "yes")
3714    (set_attr "length" "4,8")])
3717 (define_insn "*boolcc<mode>3"
3718   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3719         (match_operator:GPR 3 "boolean_operator"
3720          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3721           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3722   ""
3723   "%q3 %0,%1,%2"
3724   [(set_attr "type" "logical")])
3726 (define_insn_and_split "*boolcc<mode>3_dot"
3727   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3728         (compare:CC (match_operator:GPR 3 "boolean_operator"
3729          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3730           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3731          (const_int 0)))
3732    (clobber (match_scratch:GPR 0 "=r,r"))]
3733   "<MODE>mode == Pmode"
3734   "@
3735    %q3. %0,%1,%2
3736    #"
3737   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3738   [(set (match_dup 0)
3739         (match_dup 3))
3740    (set (match_dup 4)
3741         (compare:CC (match_dup 0)
3742                     (const_int 0)))]
3743   ""
3744   [(set_attr "type" "logical")
3745    (set_attr "dot" "yes")
3746    (set_attr "length" "4,8")])
3748 (define_insn_and_split "*boolcc<mode>3_dot2"
3749   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3750         (compare:CC (match_operator:GPR 3 "boolean_operator"
3751          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3752           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3753          (const_int 0)))
3754    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3755         (match_dup 3))]
3756   "<MODE>mode == Pmode"
3757   "@
3758    %q3. %0,%1,%2
3759    #"
3760   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3761   [(set (match_dup 0)
3762         (match_dup 3))
3763    (set (match_dup 4)
3764         (compare:CC (match_dup 0)
3765                     (const_int 0)))]
3766   ""
3767   [(set_attr "type" "logical")
3768    (set_attr "dot" "yes")
3769    (set_attr "length" "4,8")])
3772 ;; TODO: Should have dots of this as well.
3773 (define_insn "*eqv<mode>3"
3774   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3775         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3776                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3777   ""
3778   "eqv %0,%1,%2"
3779   [(set_attr "type" "logical")])
3781 ;; Rotate-and-mask and insert.
3783 (define_insn "*rotl<mode>3_mask"
3784   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3785         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3786                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3787                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3788                  (match_operand:GPR 3 "const_int_operand" "n")))]
3789   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3791   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3793   [(set_attr "type" "shift")
3794    (set_attr "maybe_var_shift" "yes")])
3796 (define_insn_and_split "*rotl<mode>3_mask_dot"
3797   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3798         (compare:CC
3799           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3800                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3801                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3802                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3803           (const_int 0)))
3804    (clobber (match_scratch:GPR 0 "=r,r"))]
3805   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3806    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3808   if (which_alternative == 0)
3809     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3810   else
3811     return "#";
3813   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3814   [(set (match_dup 0)
3815         (and:GPR (match_dup 4)
3816                  (match_dup 3)))
3817    (set (match_dup 5)
3818         (compare:CC (match_dup 0)
3819                     (const_int 0)))]
3820   ""
3821   [(set_attr "type" "shift")
3822    (set_attr "maybe_var_shift" "yes")
3823    (set_attr "dot" "yes")
3824    (set_attr "length" "4,8")])
3826 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3827   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3828         (compare:CC
3829           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3830                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3831                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3832                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3833           (const_int 0)))
3834    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3835         (and:GPR (match_dup 4)
3836                  (match_dup 3)))]
3837   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3838    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3840   if (which_alternative == 0)
3841     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3842   else
3843     return "#";
3845   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3846   [(set (match_dup 0)
3847         (and:GPR (match_dup 4)
3848                  (match_dup 3)))
3849    (set (match_dup 5)
3850         (compare:CC (match_dup 0)
3851                     (const_int 0)))]
3852   ""
3853   [(set_attr "type" "shift")
3854    (set_attr "maybe_var_shift" "yes")
3855    (set_attr "dot" "yes")
3856    (set_attr "length" "4,8")])
3858 ; Special case for less-than-0.  We can do it with just one machine
3859 ; instruction, but the generic optimizers do not realise it is cheap.
3860 (define_insn "*lt0_<mode>di"
3861   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3862         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3863                 (const_int 0)))]
3864   "TARGET_POWERPC64"
3865   "srdi %0,%1,63"
3866   [(set_attr "type" "shift")])
3868 (define_insn "*lt0_<mode>si"
3869   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3870         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3871                 (const_int 0)))]
3872   ""
3873   "rlwinm %0,%1,1,31,31"
3874   [(set_attr "type" "shift")])
3878 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3879 ; both are an AND so are the same precedence).
3880 (define_insn "*rotl<mode>3_insert"
3881   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3882         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3883                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3884                             (match_operand:SI 2 "const_int_operand" "n")])
3885                           (match_operand:GPR 3 "const_int_operand" "n"))
3886                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3887                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3888   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3889    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3891   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3893   [(set_attr "type" "insert")])
3894 ; FIXME: this needs an attr "size", so that the scheduler can see the
3895 ; difference between rlwimi and rldimi.  We also might want dot forms,
3896 ; but not for rlwimi on POWER4 and similar processors.
3898 (define_insn "*rotl<mode>3_insert_2"
3899   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3900         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3901                           (match_operand:GPR 6 "const_int_operand" "n"))
3902                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3903                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3904                             (match_operand:SI 2 "const_int_operand" "n")])
3905                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3906   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3907    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3909   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3911   [(set_attr "type" "insert")])
3913 ; There are also some forms without one of the ANDs.
3914 (define_insn "*rotl<mode>3_insert_3"
3915   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3916         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3917                           (match_operand:GPR 4 "const_int_operand" "n"))
3918                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3919                              (match_operand:SI 2 "const_int_operand" "n"))))]
3920   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3922   if (<MODE>mode == SImode)
3923     return "rlwimi %0,%1,%h2,0,31-%h2";
3924   else
3925     return "rldimi %0,%1,%H2,0";
3927   [(set_attr "type" "insert")])
3929 (define_insn "*rotl<mode>3_insert_4"
3930   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3931         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3932                           (match_operand:GPR 4 "const_int_operand" "n"))
3933                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3934                                (match_operand:SI 2 "const_int_operand" "n"))))]
3935   "<MODE>mode == SImode &&
3936    GET_MODE_PRECISION (<MODE>mode)
3937    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3939   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3940                          - INTVAL (operands[2]));
3941   if (<MODE>mode == SImode)
3942     return "rlwimi %0,%1,%h2,32-%h2,31";
3943   else
3944     return "rldimi %0,%1,%H2,64-%H2";
3946   [(set_attr "type" "insert")])
3948 (define_insn "*rotlsi3_insert_5"
3949   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3950         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3951                         (match_operand:SI 2 "const_int_operand" "n,n"))
3952                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3953                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3954   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3955    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3956    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3957   "@
3958    rlwimi %0,%3,0,%4
3959    rlwimi %0,%1,0,%2"
3960   [(set_attr "type" "insert")])
3962 (define_insn "*rotldi3_insert_6"
3963   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3964         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3965                         (match_operand:DI 2 "const_int_operand" "n"))
3966                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3967                         (match_operand:DI 4 "const_int_operand" "n"))))]
3968   "exact_log2 (-UINTVAL (operands[2])) > 0
3969    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3971   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3972   return "rldimi %0,%3,0,%5";
3974   [(set_attr "type" "insert")
3975    (set_attr "size" "64")])
3977 (define_insn "*rotldi3_insert_7"
3978   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3979         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3980                         (match_operand:DI 4 "const_int_operand" "n"))
3981                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3982                         (match_operand:DI 2 "const_int_operand" "n"))))]
3983   "exact_log2 (-UINTVAL (operands[2])) > 0
3984    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3986   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3987   return "rldimi %0,%3,0,%5";
3989   [(set_attr "type" "insert")
3990    (set_attr "size" "64")])
3993 ; This handles the important case of multiple-precision shifts.  There is
3994 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3995 (define_split
3996   [(set (match_operand:GPR 0 "gpc_reg_operand")
3997         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3998                              (match_operand:SI 3 "const_int_operand"))
3999                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4000                                (match_operand:SI 4 "const_int_operand"))))]
4001   "can_create_pseudo_p ()
4002    && INTVAL (operands[3]) + INTVAL (operands[4])
4003       >= GET_MODE_PRECISION (<MODE>mode)"
4004   [(set (match_dup 5)
4005         (lshiftrt:GPR (match_dup 2)
4006                       (match_dup 4)))
4007    (set (match_dup 0)
4008         (ior:GPR (and:GPR (match_dup 5)
4009                           (match_dup 6))
4010                  (ashift:GPR (match_dup 1)
4011                              (match_dup 3))))]
4013   unsigned HOST_WIDE_INT mask = 1;
4014   mask = (mask << INTVAL (operands[3])) - 1;
4015   operands[5] = gen_reg_rtx (<MODE>mode);
4016   operands[6] = GEN_INT (mask);
4019 (define_split
4020   [(set (match_operand:GPR 0 "gpc_reg_operand")
4021         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4022                                (match_operand:SI 4 "const_int_operand"))
4023                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4024                              (match_operand:SI 3 "const_int_operand"))))]
4025   "can_create_pseudo_p ()
4026    && INTVAL (operands[3]) + INTVAL (operands[4])
4027       >= GET_MODE_PRECISION (<MODE>mode)"
4028   [(set (match_dup 5)
4029         (lshiftrt:GPR (match_dup 2)
4030                       (match_dup 4)))
4031    (set (match_dup 0)
4032         (ior:GPR (and:GPR (match_dup 5)
4033                           (match_dup 6))
4034                  (ashift:GPR (match_dup 1)
4035                              (match_dup 3))))]
4037   unsigned HOST_WIDE_INT mask = 1;
4038   mask = (mask << INTVAL (operands[3])) - 1;
4039   operands[5] = gen_reg_rtx (<MODE>mode);
4040   operands[6] = GEN_INT (mask);
4044 ; Another important case is setting some bits to 1; we can do that with
4045 ; an insert instruction, in many cases.
4046 (define_insn_and_split "*ior<mode>_mask"
4047   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4048         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4049                  (match_operand:GPR 2 "const_int_operand" "n")))
4050    (clobber (match_scratch:GPR 3 "=r"))]
4051   "!logical_const_operand (operands[2], <MODE>mode)
4052    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4053   "#"
4054   "&& 1"
4055   [(set (match_dup 3)
4056         (const_int -1))
4057    (set (match_dup 0)
4058         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4059                                       (match_dup 4))
4060                           (match_dup 2))
4061                  (and:GPR (match_dup 1)
4062                           (match_dup 5))))]
4064   int nb, ne;
4065   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4066   if (GET_CODE (operands[3]) == SCRATCH)
4067     operands[3] = gen_reg_rtx (<MODE>mode);
4068   operands[4] = GEN_INT (ne);
4069   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4071   [(set_attr "type" "two")
4072    (set_attr "length" "8")])
4075 ;; Now the simple shifts.
4077 (define_insn "rotl<mode>3"
4078   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4079         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4080                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4081   ""
4082   "rotl<wd>%I2 %0,%1,%<hH>2"
4083   [(set_attr "type" "shift")
4084    (set_attr "maybe_var_shift" "yes")])
4086 (define_insn "*rotlsi3_64"
4087   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4088         (zero_extend:DI
4089             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4090                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4091   "TARGET_POWERPC64"
4092   "rotlw%I2 %0,%1,%h2"
4093   [(set_attr "type" "shift")
4094    (set_attr "maybe_var_shift" "yes")])
4096 (define_insn_and_split "*rotl<mode>3_dot"
4097   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4098         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4099                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4100                     (const_int 0)))
4101    (clobber (match_scratch:GPR 0 "=r,r"))]
4102   "<MODE>mode == Pmode"
4103   "@
4104    rotl<wd>%I2. %0,%1,%<hH>2
4105    #"
4106   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4107   [(set (match_dup 0)
4108         (rotate:GPR (match_dup 1)
4109                     (match_dup 2)))
4110    (set (match_dup 3)
4111         (compare:CC (match_dup 0)
4112                     (const_int 0)))]
4113   ""
4114   [(set_attr "type" "shift")
4115    (set_attr "maybe_var_shift" "yes")
4116    (set_attr "dot" "yes")
4117    (set_attr "length" "4,8")])
4119 (define_insn_and_split "*rotl<mode>3_dot2"
4120   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4121         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4122                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4123                     (const_int 0)))
4124    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4125         (rotate:GPR (match_dup 1)
4126                     (match_dup 2)))]
4127   "<MODE>mode == Pmode"
4128   "@
4129    rotl<wd>%I2. %0,%1,%<hH>2
4130    #"
4131   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4132   [(set (match_dup 0)
4133         (rotate:GPR (match_dup 1)
4134                     (match_dup 2)))
4135    (set (match_dup 3)
4136         (compare:CC (match_dup 0)
4137                     (const_int 0)))]
4138   ""
4139   [(set_attr "type" "shift")
4140    (set_attr "maybe_var_shift" "yes")
4141    (set_attr "dot" "yes")
4142    (set_attr "length" "4,8")])
4145 (define_insn "ashl<mode>3"
4146   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4147         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4148                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4149   ""
4150   "sl<wd>%I2 %0,%1,%<hH>2"
4151   [(set_attr "type" "shift")
4152    (set_attr "maybe_var_shift" "yes")])
4154 (define_insn "*ashlsi3_64"
4155   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4156         (zero_extend:DI
4157             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4158                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4159   "TARGET_POWERPC64"
4160   "slw%I2 %0,%1,%h2"
4161   [(set_attr "type" "shift")
4162    (set_attr "maybe_var_shift" "yes")])
4164 (define_insn_and_split "*ashl<mode>3_dot"
4165   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4166         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4167                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4168                     (const_int 0)))
4169    (clobber (match_scratch:GPR 0 "=r,r"))]
4170   "<MODE>mode == Pmode"
4171   "@
4172    sl<wd>%I2. %0,%1,%<hH>2
4173    #"
4174   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4175   [(set (match_dup 0)
4176         (ashift:GPR (match_dup 1)
4177                     (match_dup 2)))
4178    (set (match_dup 3)
4179         (compare:CC (match_dup 0)
4180                     (const_int 0)))]
4181   ""
4182   [(set_attr "type" "shift")
4183    (set_attr "maybe_var_shift" "yes")
4184    (set_attr "dot" "yes")
4185    (set_attr "length" "4,8")])
4187 (define_insn_and_split "*ashl<mode>3_dot2"
4188   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4189         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4190                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4191                     (const_int 0)))
4192    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4193         (ashift:GPR (match_dup 1)
4194                     (match_dup 2)))]
4195   "<MODE>mode == Pmode"
4196   "@
4197    sl<wd>%I2. %0,%1,%<hH>2
4198    #"
4199   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4200   [(set (match_dup 0)
4201         (ashift:GPR (match_dup 1)
4202                     (match_dup 2)))
4203    (set (match_dup 3)
4204         (compare:CC (match_dup 0)
4205                     (const_int 0)))]
4206   ""
4207   [(set_attr "type" "shift")
4208    (set_attr "maybe_var_shift" "yes")
4209    (set_attr "dot" "yes")
4210    (set_attr "length" "4,8")])
4212 ;; Pretend we have a memory form of extswsli until register allocation is done
4213 ;; so that we use LWZ to load the value from memory, instead of LWA.
4214 (define_insn_and_split "ashdi3_extswsli"
4215   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4216         (ashift:DI
4217          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4218          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4219   "TARGET_EXTSWSLI"
4220   "@
4221    extswsli %0,%1,%2
4222    #"
4223   "&& reload_completed && MEM_P (operands[1])"
4224   [(set (match_dup 3)
4225         (match_dup 1))
4226    (set (match_dup 0)
4227         (ashift:DI (sign_extend:DI (match_dup 3))
4228                    (match_dup 2)))]
4230   operands[3] = gen_lowpart (SImode, operands[0]);
4232   [(set_attr "type" "shift")
4233    (set_attr "maybe_var_shift" "no")])
4236 (define_insn_and_split "ashdi3_extswsli_dot"
4237   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4238         (compare:CC
4239          (ashift:DI
4240           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4241           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4242          (const_int 0)))
4243    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4244   "TARGET_EXTSWSLI"
4245   "@
4246    extswsli. %0,%1,%2
4247    #
4248    #
4249    #"
4250   "&& reload_completed
4251    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4252        || memory_operand (operands[1], SImode))"
4253   [(pc)]
4255   rtx dest = operands[0];
4256   rtx src = operands[1];
4257   rtx shift = operands[2];
4258   rtx cr = operands[3];
4259   rtx src2;
4261   if (!MEM_P (src))
4262     src2 = src;
4263   else
4264     {
4265       src2 = gen_lowpart (SImode, dest);
4266       emit_move_insn (src2, src);
4267     }
4269   if (REGNO (cr) == CR0_REGNO)
4270     {
4271       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4272       DONE;
4273     }
4275   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4276   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4277   DONE;
4279   [(set_attr "type" "shift")
4280    (set_attr "maybe_var_shift" "no")
4281    (set_attr "dot" "yes")
4282    (set_attr "length" "4,8,8,12")])
4284 (define_insn_and_split "ashdi3_extswsli_dot2"
4285   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4286         (compare:CC
4287          (ashift:DI
4288           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4289           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4290          (const_int 0)))
4291    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4292         (ashift:DI (sign_extend:DI (match_dup 1))
4293                    (match_dup 2)))]
4294   "TARGET_EXTSWSLI"
4295   "@
4296    extswsli. %0,%1,%2
4297    #
4298    #
4299    #"
4300   "&& reload_completed
4301    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4302        || memory_operand (operands[1], SImode))"
4303   [(pc)]
4305   rtx dest = operands[0];
4306   rtx src = operands[1];
4307   rtx shift = operands[2];
4308   rtx cr = operands[3];
4309   rtx src2;
4311   if (!MEM_P (src))
4312     src2 = src;
4313   else
4314     {
4315       src2 = gen_lowpart (SImode, dest);
4316       emit_move_insn (src2, src);
4317     }
4319   if (REGNO (cr) == CR0_REGNO)
4320     {
4321       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4322       DONE;
4323     }
4325   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4326   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4327   DONE;
4329   [(set_attr "type" "shift")
4330    (set_attr "maybe_var_shift" "no")
4331    (set_attr "dot" "yes")
4332    (set_attr "length" "4,8,8,12")])
4334 (define_insn "lshr<mode>3"
4335   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4336         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4337                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4338   ""
4339   "sr<wd>%I2 %0,%1,%<hH>2"
4340   [(set_attr "type" "shift")
4341    (set_attr "maybe_var_shift" "yes")])
4343 (define_insn "*lshrsi3_64"
4344   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4345         (zero_extend:DI
4346             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4347                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4348   "TARGET_POWERPC64"
4349   "srw%I2 %0,%1,%h2"
4350   [(set_attr "type" "shift")
4351    (set_attr "maybe_var_shift" "yes")])
4353 (define_insn_and_split "*lshr<mode>3_dot"
4354   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4355         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4356                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4357                     (const_int 0)))
4358    (clobber (match_scratch:GPR 0 "=r,r"))]
4359   "<MODE>mode == Pmode"
4360   "@
4361    sr<wd>%I2. %0,%1,%<hH>2
4362    #"
4363   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4364   [(set (match_dup 0)
4365         (lshiftrt:GPR (match_dup 1)
4366                       (match_dup 2)))
4367    (set (match_dup 3)
4368         (compare:CC (match_dup 0)
4369                     (const_int 0)))]
4370   ""
4371   [(set_attr "type" "shift")
4372    (set_attr "maybe_var_shift" "yes")
4373    (set_attr "dot" "yes")
4374    (set_attr "length" "4,8")])
4376 (define_insn_and_split "*lshr<mode>3_dot2"
4377   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4378         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4379                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4380                     (const_int 0)))
4381    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4382         (lshiftrt:GPR (match_dup 1)
4383                       (match_dup 2)))]
4384   "<MODE>mode == Pmode"
4385   "@
4386    sr<wd>%I2. %0,%1,%<hH>2
4387    #"
4388   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4389   [(set (match_dup 0)
4390         (lshiftrt:GPR (match_dup 1)
4391                       (match_dup 2)))
4392    (set (match_dup 3)
4393         (compare:CC (match_dup 0)
4394                     (const_int 0)))]
4395   ""
4396   [(set_attr "type" "shift")
4397    (set_attr "maybe_var_shift" "yes")
4398    (set_attr "dot" "yes")
4399    (set_attr "length" "4,8")])
4402 (define_insn "ashr<mode>3"
4403   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4404         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4405                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4406    (clobber (reg:GPR CA_REGNO))]
4407   ""
4408   "sra<wd>%I2 %0,%1,%<hH>2"
4409   [(set_attr "type" "shift")
4410    (set_attr "maybe_var_shift" "yes")])
4412 (define_insn "*ashrsi3_64"
4413   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4414         (sign_extend:DI
4415             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4416                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4417    (clobber (reg:SI CA_REGNO))]
4418   "TARGET_POWERPC64"
4419   "sraw%I2 %0,%1,%h2"
4420   [(set_attr "type" "shift")
4421    (set_attr "maybe_var_shift" "yes")])
4423 (define_insn_and_split "*ashr<mode>3_dot"
4424   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4425         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4426                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4427                     (const_int 0)))
4428    (clobber (match_scratch:GPR 0 "=r,r"))
4429    (clobber (reg:GPR CA_REGNO))]
4430   "<MODE>mode == Pmode"
4431   "@
4432    sra<wd>%I2. %0,%1,%<hH>2
4433    #"
4434   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4435   [(parallel [(set (match_dup 0)
4436                    (ashiftrt:GPR (match_dup 1)
4437                                  (match_dup 2)))
4438               (clobber (reg:GPR CA_REGNO))])
4439    (set (match_dup 3)
4440         (compare:CC (match_dup 0)
4441                     (const_int 0)))]
4442   ""
4443   [(set_attr "type" "shift")
4444    (set_attr "maybe_var_shift" "yes")
4445    (set_attr "dot" "yes")
4446    (set_attr "length" "4,8")])
4448 (define_insn_and_split "*ashr<mode>3_dot2"
4449   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4450         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4451                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4452                     (const_int 0)))
4453    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4454         (ashiftrt:GPR (match_dup 1)
4455                       (match_dup 2)))
4456    (clobber (reg:GPR CA_REGNO))]
4457   "<MODE>mode == Pmode"
4458   "@
4459    sra<wd>%I2. %0,%1,%<hH>2
4460    #"
4461   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4462   [(parallel [(set (match_dup 0)
4463                    (ashiftrt:GPR (match_dup 1)
4464                                  (match_dup 2)))
4465               (clobber (reg:GPR CA_REGNO))])
4466    (set (match_dup 3)
4467         (compare:CC (match_dup 0)
4468                     (const_int 0)))]
4469   ""
4470   [(set_attr "type" "shift")
4471    (set_attr "maybe_var_shift" "yes")
4472    (set_attr "dot" "yes")
4473    (set_attr "length" "4,8")])
4475 ;; Builtins to replace a division to generate FRE reciprocal estimate
4476 ;; instructions and the necessary fixup instructions
4477 (define_expand "recip<mode>3"
4478   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4479    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4480    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4481   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4483    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4484    DONE;
4487 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4488 ;; hardware division.  This is only done before register allocation and with
4489 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4490 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4491 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4492 (define_split
4493   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4494         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4495                     (match_operand 2 "gpc_reg_operand" "")))]
4496   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4497    && can_create_pseudo_p () && flag_finite_math_only
4498    && !flag_trapping_math && flag_reciprocal_math"
4499   [(const_int 0)]
4501   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4502   DONE;
4505 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4506 ;; appropriate fixup.
4507 (define_expand "rsqrt<mode>2"
4508   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4509    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4510   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4512   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4513   DONE;
4516 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4517 ;; modes here, and also add in conditional vsx/power8-vector support to access
4518 ;; values in the traditional Altivec registers if the appropriate
4519 ;; -mupper-regs-{df,sf} option is enabled.
4521 (define_expand "abs<mode>2"
4522   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4523         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4524   "TARGET_<MODE>_INSN"
4525   "")
4527 (define_insn "*abs<mode>2_fpr"
4528   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4529         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4530   "TARGET_<MODE>_FPR"
4531   "@
4532    fabs %0,%1
4533    xsabsdp %x0,%x1"
4534   [(set_attr "type" "fpsimple")
4535    (set_attr "fp_type" "fp_addsub_<Fs>")])
4537 (define_insn "*nabs<mode>2_fpr"
4538   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4539         (neg:SFDF
4540          (abs:SFDF
4541           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4542   "TARGET_<MODE>_FPR"
4543   "@
4544    fnabs %0,%1
4545    xsnabsdp %x0,%x1"
4546   [(set_attr "type" "fpsimple")
4547    (set_attr "fp_type" "fp_addsub_<Fs>")])
4549 (define_expand "neg<mode>2"
4550   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4551         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4552   "TARGET_<MODE>_INSN"
4553   "")
4555 (define_insn "*neg<mode>2_fpr"
4556   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4557         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4558   "TARGET_<MODE>_FPR"
4559   "@
4560    fneg %0,%1
4561    xsnegdp %x0,%x1"
4562   [(set_attr "type" "fpsimple")
4563    (set_attr "fp_type" "fp_addsub_<Fs>")])
4565 (define_expand "add<mode>3"
4566   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4567         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4568                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4569   "TARGET_<MODE>_INSN"
4570   "")
4572 (define_insn "*add<mode>3_fpr"
4573   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4574         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4575                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4576   "TARGET_<MODE>_FPR"
4577   "@
4578    fadd<Ftrad> %0,%1,%2
4579    xsadd<Fvsx> %x0,%x1,%x2"
4580   [(set_attr "type" "fp")
4581    (set_attr "fp_type" "fp_addsub_<Fs>")])
4583 (define_expand "sub<mode>3"
4584   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4585         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4586                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4587   "TARGET_<MODE>_INSN"
4588   "")
4590 (define_insn "*sub<mode>3_fpr"
4591   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4592         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4593                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4594   "TARGET_<MODE>_FPR"
4595   "@
4596    fsub<Ftrad> %0,%1,%2
4597    xssub<Fvsx> %x0,%x1,%x2"
4598   [(set_attr "type" "fp")
4599    (set_attr "fp_type" "fp_addsub_<Fs>")])
4601 (define_expand "mul<mode>3"
4602   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4603         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4604                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4605   "TARGET_<MODE>_INSN"
4606   "")
4608 (define_insn "*mul<mode>3_fpr"
4609   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4610         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4611                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4612   "TARGET_<MODE>_FPR"
4613   "@
4614    fmul<Ftrad> %0,%1,%2
4615    xsmul<Fvsx> %x0,%x1,%x2"
4616   [(set_attr "type" "dmul")
4617    (set_attr "fp_type" "fp_mul_<Fs>")])
4619 (define_expand "div<mode>3"
4620   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4621         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4622                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4623   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4625   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4626       && can_create_pseudo_p () && flag_finite_math_only
4627       && !flag_trapping_math && flag_reciprocal_math)
4628     {
4629       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4630       DONE;
4631     }
4634 (define_insn "*div<mode>3_fpr"
4635   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4636         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4637                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4638   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4639   "@
4640    fdiv<Ftrad> %0,%1,%2
4641    xsdiv<Fvsx> %x0,%x1,%x2"
4642   [(set_attr "type" "<Fs>div")
4643    (set_attr "fp_type" "fp_div_<Fs>")])
4645 (define_insn "*sqrt<mode>2_internal"
4646   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4647         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4648   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4649    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4650   "@
4651    fsqrt<Ftrad> %0,%1
4652    xssqrt<Fvsx> %x0,%x1"
4653   [(set_attr "type" "<Fs>sqrt")
4654    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4656 (define_expand "sqrt<mode>2"
4657   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4658         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4659   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4660    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4662   if (<MODE>mode == SFmode
4663       && TARGET_RECIP_PRECISION
4664       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4665       && !optimize_function_for_size_p (cfun)
4666       && flag_finite_math_only && !flag_trapping_math
4667       && flag_unsafe_math_optimizations)
4668     {
4669       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4670       DONE;
4671     }
4674 ;; Floating point reciprocal approximation
4675 (define_insn "fre<Fs>"
4676   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4677         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4678                      UNSPEC_FRES))]
4679   "TARGET_<FFRE>"
4680   "@
4681    fre<Ftrad> %0,%1
4682    xsre<Fvsx> %x0,%x1"
4683   [(set_attr "type" "fp")])
4685 (define_insn "*rsqrt<mode>2"
4686   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4687         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4688                      UNSPEC_RSQRT))]
4689   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4690   "@
4691    frsqrte<Ftrad> %0,%1
4692    xsrsqrte<Fvsx> %x0,%x1"
4693   [(set_attr "type" "fp")])
4695 ;; Floating point comparisons
4696 (define_insn "*cmp<mode>_fpr"
4697   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4698         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4699                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4700   "TARGET_<MODE>_FPR"
4701   "@
4702    fcmpu %0,%1,%2
4703    xscmpudp %0,%x1,%x2"
4704   [(set_attr "type" "fpcompare")])
4706 ;; Floating point conversions
4707 (define_expand "extendsfdf2"
4708   [(set (match_operand:DF 0 "gpc_reg_operand")
4709         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4710   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4712   if (HONOR_SNANS (SFmode))
4713     operands[1] = force_reg (SFmode, operands[1]);
4716 (define_insn_and_split "*extendsfdf2_fpr"
4717   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4718         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4719   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4720   "@
4721    #
4722    fmr %0,%1
4723    lfs%U1%X1 %0,%1
4724    #
4725    xscpsgndp %x0,%x1,%x1
4726    lxsspx %x0,%y1
4727    lxssp %0,%1"
4728   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4729   [(const_int 0)]
4731   emit_note (NOTE_INSN_DELETED);
4732   DONE;
4734   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4736 (define_insn "*extendsfdf2_snan"
4737   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4738         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4739   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4740   "@
4741    frsp %0,%1
4742    xsrsp %x0,%x1"
4743   [(set_attr "type" "fp")])
4745 (define_expand "truncdfsf2"
4746   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4747         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4748   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4749   "")
4751 (define_insn "*truncdfsf2_fpr"
4752   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4753         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4754   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4755   "@
4756    frsp %0,%1
4757    xsrsp %x0,%x1"
4758   [(set_attr "type" "fp")])
4760 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4761 ;; builtins.c and optabs.c that are not correct for IBM long double
4762 ;; when little-endian.
4763 (define_expand "signbit<mode>2"
4764   [(set (match_dup 2)
4765         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4766    (set (match_dup 3)
4767         (subreg:DI (match_dup 2) 0))
4768    (set (match_dup 4)
4769         (match_dup 5))
4770    (set (match_operand:SI 0 "gpc_reg_operand" "")
4771         (match_dup 6))]
4772   "TARGET_HARD_FLOAT
4773    && (!FLOAT128_IEEE_P (<MODE>mode)
4774        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4776   if (FLOAT128_IEEE_P (<MODE>mode))
4777     {
4778       if (<MODE>mode == KFmode)
4779         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4780       else if (<MODE>mode == TFmode)
4781         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4782       else
4783         gcc_unreachable ();
4784       DONE;
4785     }
4786   operands[2] = gen_reg_rtx (DFmode);
4787   operands[3] = gen_reg_rtx (DImode);
4788   if (TARGET_POWERPC64)
4789     {
4790       operands[4] = gen_reg_rtx (DImode);
4791       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4792       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4793                                     WORDS_BIG_ENDIAN ? 4 : 0);
4794     }
4795   else
4796     {
4797       operands[4] = gen_reg_rtx (SImode);
4798       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4799                                     WORDS_BIG_ENDIAN ? 0 : 4);
4800       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4801     }
4804 (define_expand "copysign<mode>3"
4805   [(set (match_dup 3)
4806         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4807    (set (match_dup 4)
4808         (neg:SFDF (abs:SFDF (match_dup 1))))
4809    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4810         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4811                                (match_dup 5))
4812                          (match_dup 3)
4813                          (match_dup 4)))]
4814   "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4815    && ((TARGET_PPC_GFXOPT
4816         && !HONOR_NANS (<MODE>mode)
4817         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4818        || TARGET_CMPB
4819        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4821   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4822     {
4823       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4824                                              operands[2]));
4825       DONE;
4826     }
4828    operands[3] = gen_reg_rtx (<MODE>mode);
4829    operands[4] = gen_reg_rtx (<MODE>mode);
4830    operands[5] = CONST0_RTX (<MODE>mode);
4831   })
4833 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4834 ;; and load.
4835 (define_insn_and_split "signbit<mode>2_dm"
4836   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4837         (unspec:SI
4838          [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4839          UNSPEC_SIGNBIT))]
4840   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4841   "#"
4842   "&& reload_completed"
4843   [(const_int 0)]
4845   rs6000_split_signbit (operands[0], operands[1]);
4846   DONE;
4848  [(set_attr "length" "8,8,4")
4849   (set_attr "type" "mftgpr,load,integer")])
4851 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4852   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4853         (any_extend:DI
4854          (unspec:SI
4855           [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4856           UNSPEC_SIGNBIT)))]
4857   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4858   "#"
4859   "&& reload_completed"
4860   [(const_int 0)]
4862   rs6000_split_signbit (operands[0], operands[1]);
4863   DONE;
4865  [(set_attr "length" "8,8,4")
4866   (set_attr "type" "mftgpr,load,integer")])
4868 ;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
4869 ;; floating point types, which makes normal SUBREG's problematical.  Instead
4870 ;; use a special pattern to avoid using a normal movdi.
4871 (define_insn "signbit<mode>2_dm2"
4872   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4873         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4874                     (const_int 0)]
4875                    UNSPEC_SIGNBIT))]
4876   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4877   "mfvsrd %0,%x1"
4878  [(set_attr "type" "mftgpr")])
4881 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4882 ;; compiler from optimizing -0.0
4883 (define_insn "copysign<mode>3_fcpsgn"
4884   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4885         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4886                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4887                      UNSPEC_COPYSIGN))]
4888   "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4889   "@
4890    fcpsgn %0,%2,%1
4891    xscpsgndp %x0,%x2,%x1"
4892   [(set_attr "type" "fpsimple")])
4894 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4895 ;; fsel instruction and some auxiliary computations.  Then we just have a
4896 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4897 ;; combine.
4898 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4899 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4900 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4901 ;; define_splits to make them if made by combine.  On VSX machines we have the
4902 ;; min/max instructions.
4904 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4905 ;; to allow either DF/SF to use only traditional registers.
4907 (define_expand "s<minmax><mode>3"
4908   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4909         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4910                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4911   "TARGET_MINMAX_<MODE>"
4913   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4914   DONE;
4917 (define_insn "*s<minmax><mode>3_vsx"
4918   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4919         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4920                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4921   "TARGET_VSX && TARGET_<MODE>_FPR"
4923   return (TARGET_P9_MINMAX
4924           ? "xs<minmax>cdp %x0,%x1,%x2"
4925           : "xs<minmax>dp %x0,%x1,%x2");
4927   [(set_attr "type" "fp")])
4929 ;; The conditional move instructions allow us to perform max and min operations
4930 ;; even when we don't have the appropriate max/min instruction using the FSEL
4931 ;; instruction.
4933 (define_insn_and_split "*s<minmax><mode>3_fpr"
4934   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4935         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4936                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4937   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4938   "#"
4939   "&& 1"
4940   [(const_int 0)]
4942   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4943   DONE;
4946 (define_expand "mov<mode>cc"
4947    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4948          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4949                            (match_operand:GPR 2 "gpc_reg_operand" "")
4950                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4951   "TARGET_ISEL"
4952   "
4954   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4955     DONE;
4956   else
4957     FAIL;
4960 ;; We use the BASE_REGS for the isel input operands because, if rA is
4961 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4962 ;; because we may switch the operands and rB may end up being rA.
4964 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4965 ;; leave out the mode in operand 4 and use one pattern, but reload can
4966 ;; change the mode underneath our feet and then gets confused trying
4967 ;; to reload the value.
4968 (define_insn "isel_signed_<mode>"
4969   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4970         (if_then_else:GPR
4971          (match_operator 1 "scc_comparison_operator"
4972                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4973                           (const_int 0)])
4974          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4975          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4976   "TARGET_ISEL"
4977   "isel %0,%2,%3,%j1"
4978   [(set_attr "type" "isel")])
4980 (define_insn "isel_unsigned_<mode>"
4981   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4982         (if_then_else:GPR
4983          (match_operator 1 "scc_comparison_operator"
4984                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4985                           (const_int 0)])
4986          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4987          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4988   "TARGET_ISEL"
4989   "isel %0,%2,%3,%j1"
4990   [(set_attr "type" "isel")])
4992 ;; These patterns can be useful for combine; they let combine know that
4993 ;; isel can handle reversed comparisons so long as the operands are
4994 ;; registers.
4996 (define_insn "*isel_reversed_signed_<mode>"
4997   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4998         (if_then_else:GPR
4999          (match_operator 1 "scc_rev_comparison_operator"
5000                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
5001                           (const_int 0)])
5002          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5003          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5004   "TARGET_ISEL"
5006   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5007   return "isel %0,%3,%2,%j1";
5009   [(set_attr "type" "isel")])
5011 (define_insn "*isel_reversed_unsigned_<mode>"
5012   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5013         (if_then_else:GPR
5014          (match_operator 1 "scc_rev_comparison_operator"
5015                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5016                           (const_int 0)])
5017          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5018          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5019   "TARGET_ISEL"
5021   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5022   return "isel %0,%3,%2,%j1";
5024   [(set_attr "type" "isel")])
5026 ;; Floating point conditional move
5027 (define_expand "mov<mode>cc"
5028    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5029          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
5030                             (match_operand:SFDF 2 "gpc_reg_operand" "")
5031                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
5032   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5033   "
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_<MODE>_FPR && 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_DOUBLE_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_DOUBLE_FLOAT && TARGET_LFIWAX
5169    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5170   "#"
5171   ""
5172   [(pc)]
5173   "
5175   rtx dest = operands[0];
5176   rtx src = operands[1];
5177   rtx tmp;
5179   if (!MEM_P (src) && TARGET_POWERPC64
5180       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5181     tmp = convert_to_mode (DImode, src, false);
5182   else
5183     {
5184       tmp = operands[2];
5185       if (GET_CODE (tmp) == SCRATCH)
5186         tmp = gen_reg_rtx (DImode);
5187       if (MEM_P (src))
5188         {
5189           src = rs6000_address_for_fpconvert (src);
5190           emit_insn (gen_lfiwax (tmp, src));
5191         }
5192       else
5193         {
5194           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5195           emit_move_insn (stack, src);
5196           emit_insn (gen_lfiwax (tmp, stack));
5197         }
5198     }
5199   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5200   DONE;
5202   [(set_attr "length" "12")
5203    (set_attr "type" "fpload")])
5205 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5206   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5207         (float:SFDF
5208          (sign_extend:DI
5209           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5210    (clobber (match_scratch:DI 2 "=wi"))]
5211   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5212   "#"
5213   ""
5214   [(pc)]
5215   "
5217   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5218   if (GET_CODE (operands[2]) == SCRATCH)
5219     operands[2] = gen_reg_rtx (DImode);
5220   if (TARGET_P8_VECTOR)
5221     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5222   else
5223     emit_insn (gen_lfiwax (operands[2], operands[1]));
5224   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5225   DONE;
5227   [(set_attr "length" "8")
5228    (set_attr "type" "fpload")])
5230 (define_insn "lfiwzx"
5231   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5232         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5233                    UNSPEC_LFIWZX))]
5234   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5235   "@
5236    lfiwzx %0,%y1
5237    lxsiwzx %x0,%y1
5238    mtvsrwz %x0,%1
5239    xxextractuw %x0,%x1,4"
5240   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5242 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5243   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5244         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5245    (clobber (match_scratch:DI 2 "=wi"))]
5246   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5247   "#"
5248   ""
5249   [(pc)]
5250   "
5252   rtx dest = operands[0];
5253   rtx src = operands[1];
5254   rtx tmp;
5256   if (!MEM_P (src) && TARGET_POWERPC64
5257       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5258     tmp = convert_to_mode (DImode, src, true);
5259   else
5260     {
5261       tmp = operands[2];
5262       if (GET_CODE (tmp) == SCRATCH)
5263         tmp = gen_reg_rtx (DImode);
5264       if (MEM_P (src))
5265         {
5266           src = rs6000_address_for_fpconvert (src);
5267           emit_insn (gen_lfiwzx (tmp, src));
5268         }
5269       else
5270         {
5271           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5272           emit_move_insn (stack, src);
5273           emit_insn (gen_lfiwzx (tmp, stack));
5274         }
5275     }
5276   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5277   DONE;
5279   [(set_attr "length" "12")
5280    (set_attr "type" "fpload")])
5282 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5283   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5284         (unsigned_float:SFDF
5285          (zero_extend:DI
5286           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5287    (clobber (match_scratch:DI 2 "=wi"))]
5288   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5289   "#"
5290   ""
5291   [(pc)]
5292   "
5294   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5295   if (GET_CODE (operands[2]) == SCRATCH)
5296     operands[2] = gen_reg_rtx (DImode);
5297   if (TARGET_P8_VECTOR)
5298     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5299   else
5300     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5301   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5302   DONE;
5304   [(set_attr "length" "8")
5305    (set_attr "type" "fpload")])
5307 ; For each of these conversions, there is a define_expand, a define_insn
5308 ; with a '#' template, and a define_split (with C code).  The idea is
5309 ; to allow constant folding with the template of the define_insn,
5310 ; then to have the insns split later (between sched1 and final).
5312 (define_expand "floatsidf2"
5313   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5314                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5315               (use (match_dup 2))
5316               (use (match_dup 3))
5317               (clobber (match_dup 4))
5318               (clobber (match_dup 5))
5319               (clobber (match_dup 6))])]
5320   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5321   "
5323   if (TARGET_LFIWAX && TARGET_FCFID)
5324     {
5325       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5326       DONE;
5327     }
5328   else if (TARGET_FCFID)
5329     {
5330       rtx dreg = operands[1];
5331       if (!REG_P (dreg))
5332         dreg = force_reg (SImode, dreg);
5333       dreg = convert_to_mode (DImode, dreg, false);
5334       emit_insn (gen_floatdidf2 (operands[0], dreg));
5335       DONE;
5336     }
5338   if (!REG_P (operands[1]))
5339     operands[1] = force_reg (SImode, operands[1]);
5340   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5341   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5342   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5343   operands[5] = gen_reg_rtx (DFmode);
5344   operands[6] = gen_reg_rtx (SImode);
5347 (define_insn_and_split "*floatsidf2_internal"
5348   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5349         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5350    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5351    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5352    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5353    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5354    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5355   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5356   "#"
5357   ""
5358   [(pc)]
5359   "
5361   rtx lowword, highword;
5362   gcc_assert (MEM_P (operands[4]));
5363   highword = adjust_address (operands[4], SImode, 0);
5364   lowword = adjust_address (operands[4], SImode, 4);
5365   if (! WORDS_BIG_ENDIAN)
5366     std::swap (lowword, highword);
5368   emit_insn (gen_xorsi3 (operands[6], operands[1],
5369                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5370   emit_move_insn (lowword, operands[6]);
5371   emit_move_insn (highword, operands[2]);
5372   emit_move_insn (operands[5], operands[4]);
5373   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5374   DONE;
5376   [(set_attr "length" "24")
5377    (set_attr "type" "fp")])
5379 ;; If we don't have a direct conversion to single precision, don't enable this
5380 ;; conversion for 32-bit without fast math, because we don't have the insn to
5381 ;; generate the fixup swizzle to avoid double rounding problems.
5382 (define_expand "floatunssisf2"
5383   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5384         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5385   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5386    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5387        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5388            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5389   "
5391   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5392     {
5393       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5394       DONE;
5395     }
5396   else
5397     {
5398       rtx dreg = operands[1];
5399       if (!REG_P (dreg))
5400         dreg = force_reg (SImode, dreg);
5401       dreg = convert_to_mode (DImode, dreg, true);
5402       emit_insn (gen_floatdisf2 (operands[0], dreg));
5403       DONE;
5404     }
5407 (define_expand "floatunssidf2"
5408   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5409                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5410               (use (match_dup 2))
5411               (use (match_dup 3))
5412               (clobber (match_dup 4))
5413               (clobber (match_dup 5))])]
5414   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5415   "
5417   if (TARGET_LFIWZX && TARGET_FCFID)
5418     {
5419       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5420       DONE;
5421     }
5422   else if (TARGET_FCFID)
5423     {
5424       rtx dreg = operands[1];
5425       if (!REG_P (dreg))
5426         dreg = force_reg (SImode, dreg);
5427       dreg = convert_to_mode (DImode, dreg, true);
5428       emit_insn (gen_floatdidf2 (operands[0], dreg));
5429       DONE;
5430     }
5432   if (!REG_P (operands[1]))
5433     operands[1] = force_reg (SImode, operands[1]);
5434   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5435   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5436   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5437   operands[5] = gen_reg_rtx (DFmode);
5440 (define_insn_and_split "*floatunssidf2_internal"
5441   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5442         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5443    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5444    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5445    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5446    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5447   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5448    && !(TARGET_FCFID && TARGET_POWERPC64)"
5449   "#"
5450   ""
5451   [(pc)]
5452   "
5454   rtx lowword, highword;
5455   gcc_assert (MEM_P (operands[4]));
5456   highword = adjust_address (operands[4], SImode, 0);
5457   lowword = adjust_address (operands[4], SImode, 4);
5458   if (! WORDS_BIG_ENDIAN)
5459     std::swap (lowword, highword);
5461   emit_move_insn (lowword, operands[1]);
5462   emit_move_insn (highword, operands[2]);
5463   emit_move_insn (operands[5], operands[4]);
5464   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5465   DONE;
5467   [(set_attr "length" "20")
5468    (set_attr "type" "fp")])
5470 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5471 ;; vector registers.  These insns favor doing the sign/zero extension in
5472 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5473 ;; extension and then a direct move.
5475 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5476   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5477                    (float:FP_ISA3
5478                     (match_operand:QHI 1 "input_operand")))
5479               (clobber (match_scratch:DI 2))
5480               (clobber (match_scratch:DI 3))
5481               (clobber (match_scratch:<QHI:MODE> 4))])]
5482   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5484   if (MEM_P (operands[1]))
5485     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5488 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5489   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5490         (float:FP_ISA3
5491          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5492    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5493    (clobber (match_scratch:DI 3 "=X,r,X"))
5494    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5495   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5496   "#"
5497   "&& reload_completed"
5498   [(const_int 0)]
5500   rtx result = operands[0];
5501   rtx input = operands[1];
5502   rtx di = operands[2];
5504   if (!MEM_P (input))
5505     {
5506       rtx tmp = operands[3];
5507       if (altivec_register_operand (input, <QHI:MODE>mode))
5508         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5509       else if (GET_CODE (tmp) == SCRATCH)
5510         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5511       else
5512         {
5513           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5514           emit_move_insn (di, tmp);
5515         }
5516     }
5517   else
5518     {
5519       rtx tmp = operands[4];
5520       emit_move_insn (tmp, input);
5521       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5522     }
5524   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5525   DONE;
5528 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5529   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5530                    (unsigned_float:FP_ISA3
5531                     (match_operand:QHI 1 "input_operand" "")))
5532               (clobber (match_scratch:DI 2 ""))
5533               (clobber (match_scratch:DI 3 ""))])]
5534   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5536   if (MEM_P (operands[1]))
5537     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5540 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5541   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5542         (unsigned_float:FP_ISA3
5543          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5544    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5545    (clobber (match_scratch:DI 3 "=X,r,X"))]
5546   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5547   "#"
5548   "&& reload_completed"
5549   [(const_int 0)]
5551   rtx result = operands[0];
5552   rtx input = operands[1];
5553   rtx di = operands[2];
5555   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5556     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5557   else
5558     {
5559       rtx tmp = operands[3];
5560       if (GET_CODE (tmp) == SCRATCH)
5561         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5562       else
5563         {
5564           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5565           emit_move_insn (di, tmp);
5566         }
5567     }
5569   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5570   DONE;
5573 (define_expand "fix_trunc<mode>si2"
5574   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5575         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5576   "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5577   "
5579   if (!TARGET_P8_VECTOR)
5580     {
5581       rtx src = force_reg (<MODE>mode, operands[1]);
5583       if (TARGET_STFIWX)
5584         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5585       else
5586         {
5587           rtx tmp = gen_reg_rtx (DImode);
5588           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5589           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5590                                                       tmp, stack));
5591         }
5592       DONE;
5593     }
5596 ; Like the convert to float patterns, this insn must be split before
5597 ; register allocation so that it can allocate the memory slot if it
5598 ; needed
5599 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5600   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5601         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5602    (clobber (match_scratch:DI 2 "=d"))]
5603   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5604    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5605    && TARGET_STFIWX && can_create_pseudo_p ()
5606    && !TARGET_P8_VECTOR"
5607   "#"
5608   ""
5609   [(pc)]
5611   rtx dest = operands[0];
5612   rtx src = operands[1];
5613   rtx tmp = operands[2];
5615   if (GET_CODE (tmp) == SCRATCH)
5616     tmp = gen_reg_rtx (DImode);
5618   emit_insn (gen_fctiwz_<mode> (tmp, src));
5619   if (MEM_P (dest))
5620     {
5621       dest = rs6000_address_for_fpconvert (dest);
5622       emit_insn (gen_stfiwx (dest, tmp));
5623       DONE;
5624     }
5625   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5626     {
5627       dest = gen_lowpart (DImode, dest);
5628       emit_move_insn (dest, tmp);
5629       DONE;
5630     }
5631   else
5632     {
5633       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5634       emit_insn (gen_stfiwx (stack, tmp));
5635       emit_move_insn (dest, stack);
5636       DONE;
5637     }
5639   [(set_attr "length" "12")
5640    (set_attr "type" "fp")])
5642 (define_insn_and_split "fix_trunc<mode>si2_internal"
5643   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5644         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5645    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5646    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5647   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5648   "#"
5649   ""
5650   [(pc)]
5651   "
5653   rtx lowword;
5654   gcc_assert (MEM_P (operands[3]));
5655   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5657   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5658   emit_move_insn (operands[3], operands[2]);
5659   emit_move_insn (operands[0], lowword);
5660   DONE;
5662   [(set_attr "length" "16")
5663    (set_attr "type" "fp")])
5665 (define_expand "fix_trunc<mode>di2"
5666   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5667         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5668   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5669   "")
5671 (define_insn "*fix_trunc<mode>di2_fctidz"
5672   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5673         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5674   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5675   "@
5676    fctidz %0,%1
5677    xscvdpsxds %x0,%x1"
5678   [(set_attr "type" "fp")])
5680 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5681   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5682                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5683               (clobber (match_scratch:DI 2))])]
5684   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5686   if (MEM_P (operands[0]))
5687     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5690 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5691   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5692         (fix:QHI
5693          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5694    (clobber (match_scratch:DI 2 "=X,wi"))]
5695   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5696   "#"
5697   "&& reload_completed"
5698   [(const_int 0)]
5700   rtx dest = operands[0];
5701   rtx src = operands[1];
5703   if (vsx_register_operand (dest, <QHI:MODE>mode))
5704     {
5705       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5706       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5707     }
5708   else
5709     {
5710       rtx tmp = operands[2];
5711       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5713       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5714       emit_move_insn (dest, tmp2);
5715     }
5716   DONE;
5719 (define_expand "fixuns_trunc<mode>si2"
5720   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5721         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5722   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5723   "
5725   if (!TARGET_P8_VECTOR)
5726     {
5727       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5728       DONE;
5729     }
5732 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5733   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5734         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5735    (clobber (match_scratch:DI 2 "=d"))]
5736   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5737    && TARGET_STFIWX && can_create_pseudo_p ()
5738    && !TARGET_P8_VECTOR"
5739   "#"
5740   ""
5741   [(pc)]
5743   rtx dest = operands[0];
5744   rtx src = operands[1];
5745   rtx tmp = operands[2];
5747   if (GET_CODE (tmp) == SCRATCH)
5748     tmp = gen_reg_rtx (DImode);
5750   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5751   if (MEM_P (dest))
5752     {
5753       dest = rs6000_address_for_fpconvert (dest);
5754       emit_insn (gen_stfiwx (dest, tmp));
5755       DONE;
5756     }
5757   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5758     {
5759       dest = gen_lowpart (DImode, dest);
5760       emit_move_insn (dest, tmp);
5761       DONE;
5762     }
5763   else
5764     {
5765       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5766       emit_insn (gen_stfiwx (stack, tmp));
5767       emit_move_insn (dest, stack);
5768       DONE;
5769     }
5771   [(set_attr "length" "12")
5772    (set_attr "type" "fp")])
5774 (define_insn "fixuns_trunc<mode>di2"
5775   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5776         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5777   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5778   "@
5779    fctiduz %0,%1
5780    xscvdpuxds %x0,%x1"
5781   [(set_attr "type" "fp")])
5783 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5784   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5785                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5786               (clobber (match_scratch:DI 2))])]
5787   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5789   if (MEM_P (operands[0]))
5790     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5793 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5794   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5795         (unsigned_fix:QHI
5796          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5797    (clobber (match_scratch:DI 2 "=X,wi"))]
5798   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5799   "#"
5800   "&& reload_completed"
5801   [(const_int 0)]
5803   rtx dest = operands[0];
5804   rtx src = operands[1];
5806   if (vsx_register_operand (dest, <QHI:MODE>mode))
5807     {
5808       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5809       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5810     }
5811   else
5812     {
5813       rtx tmp = operands[2];
5814       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5816       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5817       emit_move_insn (dest, tmp2);
5818     }
5819   DONE;
5822 ;; If -mvsx-small-integer, we can represent the FIX operation directly.  On
5823 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5824 ;; to another location, since SImode is not allowed in vector registers.
5825 (define_insn "*fctiw<u>z_<mode>_smallint"
5826   [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5827         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5828   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5829   "@
5830    fctiw<u>z %0,%1
5831    xscvdp<su>xws %x0,%x1"
5832   [(set_attr "type" "fp")])
5834 ;; Combiner pattern to prevent moving the result of converting a floating point
5835 ;; value to 32-bit integer to GPR in order to save it.
5836 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5837   [(set (match_operand:SI 0 "memory_operand" "=Z")
5838         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5839    (clobber (match_scratch:SI 2 "=wa"))]
5840   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5841   "#"
5842   "&& reload_completed"
5843   [(set (match_dup 2)
5844         (any_fix:SI (match_dup 1)))
5845    (set (match_dup 0)
5846         (match_dup 2))])
5848 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5849 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5850 ;; because the first makes it clear that operand 0 is not live
5851 ;; before the instruction.
5852 (define_insn "fctiwz_<mode>"
5853   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5854         (unspec:DI [(fix:SI
5855                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5856                    UNSPEC_FCTIWZ))]
5857   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5858   "@
5859    fctiwz %0,%1
5860    xscvdpsxws %x0,%x1"
5861   [(set_attr "type" "fp")])
5863 (define_insn "fctiwuz_<mode>"
5864   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5865         (unspec:DI [(unsigned_fix:SI
5866                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5867                    UNSPEC_FCTIWUZ))]
5868   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5869   "@
5870    fctiwuz %0,%1
5871    xscvdpuxws %x0,%x1"
5872   [(set_attr "type" "fp")])
5874 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5875 ;; since the friz instruction does not truncate the value if the floating
5876 ;; point value is < LONG_MIN or > LONG_MAX.
5877 (define_insn "*friz"
5878   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5879         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5880   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5881    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5882   "@
5883    friz %0,%1
5884    xsrdpiz %x0,%x1"
5885   [(set_attr "type" "fp")])
5887 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5888 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5889 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5890 ;; extend it, store it back on the stack from the GPR, load it back into the
5891 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5892 ;; disable using store and load to sign/zero extend the value.
5893 (define_insn_and_split "*round32<mode>2_fprs"
5894   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5895         (float:SFDF
5896          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5897    (clobber (match_scratch:DI 2 "=d"))
5898    (clobber (match_scratch:DI 3 "=d"))]
5899   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5900    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5901    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5902   "#"
5903   ""
5904   [(pc)]
5906   rtx dest = operands[0];
5907   rtx src = operands[1];
5908   rtx tmp1 = operands[2];
5909   rtx tmp2 = operands[3];
5910   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5912   if (GET_CODE (tmp1) == SCRATCH)
5913     tmp1 = gen_reg_rtx (DImode);
5914   if (GET_CODE (tmp2) == SCRATCH)
5915     tmp2 = gen_reg_rtx (DImode);
5917   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5918   emit_insn (gen_stfiwx (stack, tmp1));
5919   emit_insn (gen_lfiwax (tmp2, stack));
5920   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5921   DONE;
5923   [(set_attr "type" "fpload")
5924    (set_attr "length" "16")])
5926 (define_insn_and_split "*roundu32<mode>2_fprs"
5927   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5928         (unsigned_float:SFDF
5929          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5930    (clobber (match_scratch:DI 2 "=d"))
5931    (clobber (match_scratch:DI 3 "=d"))]
5932   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5933    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5934    && can_create_pseudo_p ()"
5935   "#"
5936   ""
5937   [(pc)]
5939   rtx dest = operands[0];
5940   rtx src = operands[1];
5941   rtx tmp1 = operands[2];
5942   rtx tmp2 = operands[3];
5943   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5945   if (GET_CODE (tmp1) == SCRATCH)
5946     tmp1 = gen_reg_rtx (DImode);
5947   if (GET_CODE (tmp2) == SCRATCH)
5948     tmp2 = gen_reg_rtx (DImode);
5950   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5951   emit_insn (gen_stfiwx (stack, tmp1));
5952   emit_insn (gen_lfiwzx (tmp2, stack));
5953   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5954   DONE;
5956   [(set_attr "type" "fpload")
5957    (set_attr "length" "16")])
5959 (define_insn "lrintsfsi2"
5960   [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
5961         (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
5962                    UNSPEC_FCTIW))]
5963   "TARGET_SF_FPR && TARGET_FPRND"
5964   "fctiw %0,%1"
5965   [(set_attr "type" "fp")])
5967 ;; No VSX equivalent to fctid
5968 (define_insn "lrint<mode>di2"
5969   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5970         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5971                    UNSPEC_FCTID))]
5972   "TARGET_<MODE>_FPR && TARGET_FPRND"
5973   "fctid %0,%1"
5974   [(set_attr "type" "fp")])
5976 (define_insn "btrunc<mode>2"
5977   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5978         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5979                      UNSPEC_FRIZ))]
5980   "TARGET_<MODE>_FPR && TARGET_FPRND"
5981   "@
5982    friz %0,%1
5983    xsrdpiz %x0,%x1"
5984   [(set_attr "type" "fp")
5985    (set_attr "fp_type" "fp_addsub_<Fs>")])
5987 (define_insn "ceil<mode>2"
5988   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5989         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5990                      UNSPEC_FRIP))]
5991   "TARGET_<MODE>_FPR && TARGET_FPRND"
5992   "@
5993    frip %0,%1
5994    xsrdpip %x0,%x1"
5995   [(set_attr "type" "fp")
5996    (set_attr "fp_type" "fp_addsub_<Fs>")])
5998 (define_insn "floor<mode>2"
5999   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6000         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6001                      UNSPEC_FRIM))]
6002   "TARGET_<MODE>_FPR && TARGET_FPRND"
6003   "@
6004    frim %0,%1
6005    xsrdpim %x0,%x1"
6006   [(set_attr "type" "fp")
6007    (set_attr "fp_type" "fp_addsub_<Fs>")])
6009 ;; No VSX equivalent to frin
6010 (define_insn "round<mode>2"
6011   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6012         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6013                      UNSPEC_FRIN))]
6014   "TARGET_<MODE>_FPR && TARGET_FPRND"
6015   "frin %0,%1"
6016   [(set_attr "type" "fp")
6017    (set_attr "fp_type" "fp_addsub_<Fs>")])
6019 (define_insn "*xsrdpi<mode>2"
6020   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6021         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6022                      UNSPEC_XSRDPI))]
6023   "TARGET_<MODE>_FPR && TARGET_VSX"
6024   "xsrdpi %x0,%x1"
6025   [(set_attr "type" "fp")
6026    (set_attr "fp_type" "fp_addsub_<Fs>")])
6028 (define_expand "lround<mode>di2"
6029   [(set (match_dup 2)
6030         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6031                      UNSPEC_XSRDPI))
6032    (set (match_operand:DI 0 "gpc_reg_operand" "")
6033         (unspec:DI [(match_dup 2)]
6034                    UNSPEC_FCTID))]
6035   "TARGET_<MODE>_FPR && TARGET_VSX"
6037   operands[2] = gen_reg_rtx (<MODE>mode);
6040 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6041 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6042 ; is only generated for Power8 or later.
6043 (define_insn "stfiwx"
6044   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6045         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6046                    UNSPEC_STFIWX))]
6047   "TARGET_PPC_GFXOPT"
6048   "@
6049    stfiwx %1,%y0
6050    stxsiwx %x1,%y0"
6051   [(set_attr "type" "fpstore")])
6053 ;; If we don't have a direct conversion to single precision, don't enable this
6054 ;; conversion for 32-bit without fast math, because we don't have the insn to
6055 ;; generate the fixup swizzle to avoid double rounding problems.
6056 (define_expand "floatsisf2"
6057   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6058         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6059   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6060    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6061        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6062            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6063   "
6065   if (TARGET_FCFIDS && TARGET_LFIWAX)
6066     {
6067       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6068       DONE;
6069     }
6070   else if (TARGET_FCFID && TARGET_LFIWAX)
6071     {
6072       rtx dfreg = gen_reg_rtx (DFmode);
6073       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6074       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6075       DONE;
6076     }
6077   else
6078     {
6079       rtx dreg = operands[1];
6080       if (!REG_P (dreg))
6081         dreg = force_reg (SImode, dreg);
6082       dreg = convert_to_mode (DImode, dreg, false);
6083       emit_insn (gen_floatdisf2 (operands[0], dreg));
6084       DONE;
6085     }
6088 (define_insn "floatdidf2"
6089   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6090         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6091   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6092   "@
6093    fcfid %0,%1
6094    xscvsxddp %x0,%x1"
6095   [(set_attr "type" "fp")])
6097 ; Allow the combiner to merge source memory operands to the conversion so that
6098 ; the optimizer/register allocator doesn't try to load the value too early in a
6099 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6100 ; hit.  We will split after reload to avoid the trip through the GPRs
6102 (define_insn_and_split "*floatdidf2_mem"
6103   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6104         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6105    (clobber (match_scratch:DI 2 "=d,wi"))]
6106   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6107   "#"
6108   "&& reload_completed"
6109   [(set (match_dup 2) (match_dup 1))
6110    (set (match_dup 0) (float:DF (match_dup 2)))]
6111   ""
6112   [(set_attr "length" "8")
6113    (set_attr "type" "fpload")])
6115 (define_expand "floatunsdidf2"
6116   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6117         (unsigned_float:DF
6118          (match_operand:DI 1 "gpc_reg_operand" "")))]
6119   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6120   "")
6122 (define_insn "*floatunsdidf2_fcfidu"
6123   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6124         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6125   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6126   "@
6127    fcfidu %0,%1
6128    xscvuxddp %x0,%x1"
6129   [(set_attr "type" "fp")
6130    (set_attr "length" "4")])
6132 (define_insn_and_split "*floatunsdidf2_mem"
6133   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6134         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6135    (clobber (match_scratch:DI 2 "=d,wi"))]
6136   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6137   "#"
6138   "&& reload_completed"
6139   [(set (match_dup 2) (match_dup 1))
6140    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6141   ""
6142   [(set_attr "length" "8")
6143    (set_attr "type" "fpload")])
6145 (define_expand "floatdisf2"
6146   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6147         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6148   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6149    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6150   "
6152   if (!TARGET_FCFIDS)
6153     {
6154       rtx val = operands[1];
6155       if (!flag_unsafe_math_optimizations)
6156         {
6157           rtx label = gen_label_rtx ();
6158           val = gen_reg_rtx (DImode);
6159           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6160           emit_label (label);
6161         }
6162       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6163       DONE;
6164     }
6167 (define_insn "floatdisf2_fcfids"
6168   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6169         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6170   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6171    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6172   "@
6173    fcfids %0,%1
6174    xscvsxdsp %x0,%x1"
6175   [(set_attr "type" "fp")])
6177 (define_insn_and_split "*floatdisf2_mem"
6178   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6179         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6180    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6181   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6182    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6183   "#"
6184   "&& reload_completed"
6185   [(pc)]
6186   "
6188   emit_move_insn (operands[2], operands[1]);
6189   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6190   DONE;
6192   [(set_attr "length" "8")])
6194 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6195 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6196 ;; from double rounding.
6197 ;; Instead of creating a new cpu type for two FP operations, just use fp
6198 (define_insn_and_split "floatdisf2_internal1"
6199   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6200         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6201    (clobber (match_scratch:DF 2 "=d"))]
6202   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6203   "#"
6204   "&& reload_completed"
6205   [(set (match_dup 2)
6206         (float:DF (match_dup 1)))
6207    (set (match_dup 0)
6208         (float_truncate:SF (match_dup 2)))]
6209   ""
6210   [(set_attr "length" "8")
6211    (set_attr "type" "fp")])
6213 ;; Twiddles bits to avoid double rounding.
6214 ;; Bits that might be truncated when converting to DFmode are replaced
6215 ;; by a bit that won't be lost at that stage, but is below the SFmode
6216 ;; rounding position.
6217 (define_expand "floatdisf2_internal2"
6218   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6219                                               (const_int 53)))
6220               (clobber (reg:DI CA_REGNO))])
6221    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6222                                            (const_int 2047)))
6223    (set (match_dup 3) (plus:DI (match_dup 3)
6224                                (const_int 1)))
6225    (set (match_dup 0) (plus:DI (match_dup 0)
6226                                (const_int 2047)))
6227    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6228                                      (const_int 2)))
6229    (set (match_dup 0) (ior:DI (match_dup 0)
6230                               (match_dup 1)))
6231    (set (match_dup 0) (and:DI (match_dup 0)
6232                               (const_int -2048)))
6233    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6234                            (label_ref (match_operand:DI 2 "" ""))
6235                            (pc)))
6236    (set (match_dup 0) (match_dup 1))]
6237   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6238    && !TARGET_FCFIDS"
6239   "
6241   operands[3] = gen_reg_rtx (DImode);
6242   operands[4] = gen_reg_rtx (CCUNSmode);
6245 (define_expand "floatunsdisf2"
6246   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6247         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6248   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6249    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6250   "")
6252 (define_insn "floatunsdisf2_fcfidus"
6253   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6254         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6255   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6256    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6257   "@
6258    fcfidus %0,%1
6259    xscvuxdsp %x0,%x1"
6260   [(set_attr "type" "fp")])
6262 (define_insn_and_split "*floatunsdisf2_mem"
6263   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6264         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6265    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6266   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6267    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6268   "#"
6269   "&& reload_completed"
6270   [(pc)]
6271   "
6273   emit_move_insn (operands[2], operands[1]);
6274   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6275   DONE;
6277   [(set_attr "length" "8")
6278    (set_attr "type" "fpload")])
6280 ;; Define the TImode operations that can be done in a small number
6281 ;; of instructions.  The & constraints are to prevent the register
6282 ;; allocator from allocating registers that overlap with the inputs
6283 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6284 ;; also allow for the output being the same as one of the inputs.
6286 (define_expand "addti3"
6287   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6288         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6289                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6290   "TARGET_64BIT"
6292   rtx lo0 = gen_lowpart (DImode, operands[0]);
6293   rtx lo1 = gen_lowpart (DImode, operands[1]);
6294   rtx lo2 = gen_lowpart (DImode, operands[2]);
6295   rtx hi0 = gen_highpart (DImode, operands[0]);
6296   rtx hi1 = gen_highpart (DImode, operands[1]);
6297   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6299   if (!reg_or_short_operand (lo2, DImode))
6300     lo2 = force_reg (DImode, lo2);
6301   if (!adde_operand (hi2, DImode))
6302     hi2 = force_reg (DImode, hi2);
6304   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6305   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6306   DONE;
6309 (define_expand "subti3"
6310   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6311         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6312                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6313   "TARGET_64BIT"
6315   rtx lo0 = gen_lowpart (DImode, operands[0]);
6316   rtx lo1 = gen_lowpart (DImode, operands[1]);
6317   rtx lo2 = gen_lowpart (DImode, operands[2]);
6318   rtx hi0 = gen_highpart (DImode, operands[0]);
6319   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6320   rtx hi2 = gen_highpart (DImode, operands[2]);
6322   if (!reg_or_short_operand (lo1, DImode))
6323     lo1 = force_reg (DImode, lo1);
6324   if (!adde_operand (hi1, DImode))
6325     hi1 = force_reg (DImode, hi1);
6327   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6328   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6329   DONE;
6332 ;; 128-bit logical operations expanders
6334 (define_expand "and<mode>3"
6335   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6336         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6337                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6338   ""
6339   "")
6341 (define_expand "ior<mode>3"
6342   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6343         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6344                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6345   ""
6346   "")
6348 (define_expand "xor<mode>3"
6349   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6350         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6351                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6352   ""
6353   "")
6355 (define_expand "one_cmpl<mode>2"
6356   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6357         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6358   ""
6359   "")
6361 (define_expand "nor<mode>3"
6362   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6363         (and:BOOL_128
6364          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6365          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6366   ""
6367   "")
6369 (define_expand "andc<mode>3"
6370   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6371         (and:BOOL_128
6372          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6373          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6374   ""
6375   "")
6377 ;; Power8 vector logical instructions.
6378 (define_expand "eqv<mode>3"
6379   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6380         (not:BOOL_128
6381          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6382                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6383   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6384   "")
6386 ;; Rewrite nand into canonical form
6387 (define_expand "nand<mode>3"
6388   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6389         (ior:BOOL_128
6390          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6391          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6392   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6393   "")
6395 ;; The canonical form is to have the negated element first, so we need to
6396 ;; reverse arguments.
6397 (define_expand "orc<mode>3"
6398   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6399         (ior:BOOL_128
6400          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6401          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6402   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6403   "")
6405 ;; 128-bit logical operations insns and split operations
6406 (define_insn_and_split "*and<mode>3_internal"
6407   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6408         (and:BOOL_128
6409          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6410          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6411   ""
6413   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6414     return "xxland %x0,%x1,%x2";
6416   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6417     return "vand %0,%1,%2";
6419   return "#";
6421   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6422   [(const_int 0)]
6424   rs6000_split_logical (operands, AND, false, false, false);
6425   DONE;
6427   [(set (attr "type")
6428       (if_then_else
6429         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6430         (const_string "veclogical")
6431         (const_string "integer")))
6432    (set (attr "length")
6433       (if_then_else
6434         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6435         (const_string "4")
6436         (if_then_else
6437          (match_test "TARGET_POWERPC64")
6438          (const_string "8")
6439          (const_string "16"))))])
6441 ;; 128-bit IOR/XOR
6442 (define_insn_and_split "*bool<mode>3_internal"
6443   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6444         (match_operator:BOOL_128 3 "boolean_or_operator"
6445          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6446           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6447   ""
6449   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6450     return "xxl%q3 %x0,%x1,%x2";
6452   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6453     return "v%q3 %0,%1,%2";
6455   return "#";
6457   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6458   [(const_int 0)]
6460   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6461   DONE;
6463   [(set (attr "type")
6464       (if_then_else
6465         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6466         (const_string "veclogical")
6467         (const_string "integer")))
6468    (set (attr "length")
6469       (if_then_else
6470         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6471         (const_string "4")
6472         (if_then_else
6473          (match_test "TARGET_POWERPC64")
6474          (const_string "8")
6475          (const_string "16"))))])
6477 ;; 128-bit ANDC/ORC
6478 (define_insn_and_split "*boolc<mode>3_internal1"
6479   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6480         (match_operator:BOOL_128 3 "boolean_operator"
6481          [(not:BOOL_128
6482            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6483           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6484   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6486   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6487     return "xxl%q3 %x0,%x1,%x2";
6489   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6490     return "v%q3 %0,%1,%2";
6492   return "#";
6494   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6495    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6496   [(const_int 0)]
6498   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6499   DONE;
6501   [(set (attr "type")
6502       (if_then_else
6503         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6504         (const_string "veclogical")
6505         (const_string "integer")))
6506    (set (attr "length")
6507       (if_then_else
6508         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6509         (const_string "4")
6510         (if_then_else
6511          (match_test "TARGET_POWERPC64")
6512          (const_string "8")
6513          (const_string "16"))))])
6515 (define_insn_and_split "*boolc<mode>3_internal2"
6516   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6517         (match_operator:TI2 3 "boolean_operator"
6518          [(not:TI2
6519            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6520           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6521   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6522   "#"
6523   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6524   [(const_int 0)]
6526   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6527   DONE;
6529   [(set_attr "type" "integer")
6530    (set (attr "length")
6531         (if_then_else
6532          (match_test "TARGET_POWERPC64")
6533          (const_string "8")
6534          (const_string "16")))])
6536 ;; 128-bit NAND/NOR
6537 (define_insn_and_split "*boolcc<mode>3_internal1"
6538   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6539         (match_operator:BOOL_128 3 "boolean_operator"
6540          [(not:BOOL_128
6541            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6542           (not:BOOL_128
6543            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6544   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6546   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6547     return "xxl%q3 %x0,%x1,%x2";
6549   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6550     return "v%q3 %0,%1,%2";
6552   return "#";
6554   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6555    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6556   [(const_int 0)]
6558   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6559   DONE;
6561   [(set (attr "type")
6562       (if_then_else
6563         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6564         (const_string "veclogical")
6565         (const_string "integer")))
6566    (set (attr "length")
6567       (if_then_else
6568         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6569         (const_string "4")
6570         (if_then_else
6571          (match_test "TARGET_POWERPC64")
6572          (const_string "8")
6573          (const_string "16"))))])
6575 (define_insn_and_split "*boolcc<mode>3_internal2"
6576   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6577         (match_operator:TI2 3 "boolean_operator"
6578          [(not:TI2
6579            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6580           (not:TI2
6581            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6582   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6583   "#"
6584   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6585   [(const_int 0)]
6587   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6588   DONE;
6590   [(set_attr "type" "integer")
6591    (set (attr "length")
6592         (if_then_else
6593          (match_test "TARGET_POWERPC64")
6594          (const_string "8")
6595          (const_string "16")))])
6598 ;; 128-bit EQV
6599 (define_insn_and_split "*eqv<mode>3_internal1"
6600   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6601         (not:BOOL_128
6602          (xor:BOOL_128
6603           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6604           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6605   "TARGET_P8_VECTOR"
6607   if (vsx_register_operand (operands[0], <MODE>mode))
6608     return "xxleqv %x0,%x1,%x2";
6610   return "#";
6612   "TARGET_P8_VECTOR && reload_completed
6613    && int_reg_operand (operands[0], <MODE>mode)"
6614   [(const_int 0)]
6616   rs6000_split_logical (operands, XOR, true, false, false);
6617   DONE;
6619   [(set (attr "type")
6620       (if_then_else
6621         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6622         (const_string "veclogical")
6623         (const_string "integer")))
6624    (set (attr "length")
6625       (if_then_else
6626         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6627         (const_string "4")
6628         (if_then_else
6629          (match_test "TARGET_POWERPC64")
6630          (const_string "8")
6631          (const_string "16"))))])
6633 (define_insn_and_split "*eqv<mode>3_internal2"
6634   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6635         (not:TI2
6636          (xor:TI2
6637           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6638           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6639   "!TARGET_P8_VECTOR"
6640   "#"
6641   "reload_completed && !TARGET_P8_VECTOR"
6642   [(const_int 0)]
6644   rs6000_split_logical (operands, XOR, true, false, false);
6645   DONE;
6647   [(set_attr "type" "integer")
6648    (set (attr "length")
6649         (if_then_else
6650          (match_test "TARGET_POWERPC64")
6651          (const_string "8")
6652          (const_string "16")))])
6654 ;; 128-bit one's complement
6655 (define_insn_and_split "*one_cmpl<mode>3_internal"
6656   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6657         (not:BOOL_128
6658           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6659   ""
6661   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6662     return "xxlnor %x0,%x1,%x1";
6664   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6665     return "vnor %0,%1,%1";
6667   return "#";
6669   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6670   [(const_int 0)]
6672   rs6000_split_logical (operands, NOT, false, false, false);
6673   DONE;
6675   [(set (attr "type")
6676       (if_then_else
6677         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6678         (const_string "veclogical")
6679         (const_string "integer")))
6680    (set (attr "length")
6681       (if_then_else
6682         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6683         (const_string "4")
6684         (if_then_else
6685          (match_test "TARGET_POWERPC64")
6686          (const_string "8")
6687          (const_string "16"))))])
6690 ;; Now define ways of moving data around.
6692 ;; Set up a register with a value from the GOT table
6694 (define_expand "movsi_got"
6695   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6696         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6697                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6698   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6699   "
6701   if (GET_CODE (operands[1]) == CONST)
6702     {
6703       rtx offset = const0_rtx;
6704       HOST_WIDE_INT value;
6706       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6707       value = INTVAL (offset);
6708       if (value != 0)
6709         {
6710           rtx tmp = (!can_create_pseudo_p ()
6711                      ? operands[0]
6712                      : gen_reg_rtx (Pmode));
6713           emit_insn (gen_movsi_got (tmp, operands[1]));
6714           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6715           DONE;
6716         }
6717     }
6719   operands[2] = rs6000_got_register (operands[1]);
6722 (define_insn "*movsi_got_internal"
6723   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6724         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6725                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6726                    UNSPEC_MOVSI_GOT))]
6727   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6728   "lwz %0,%a1@got(%2)"
6729   [(set_attr "type" "load")])
6731 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6732 ;; didn't get allocated to a hard register.
6733 (define_split
6734   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6735         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6736                     (match_operand:SI 2 "memory_operand" "")]
6737                    UNSPEC_MOVSI_GOT))]
6738   "DEFAULT_ABI == ABI_V4
6739     && flag_pic == 1
6740     && reload_completed"
6741   [(set (match_dup 0) (match_dup 2))
6742    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6743                                  UNSPEC_MOVSI_GOT))]
6744   "")
6746 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6747 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6748 ;; and this is even supposed to be faster, but it is simpler not to get
6749 ;; integers in the TOC.
6750 (define_insn "movsi_low"
6751   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6752         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6753                            (match_operand 2 "" ""))))]
6754   "TARGET_MACHO && ! TARGET_64BIT"
6755   "lwz %0,lo16(%2)(%1)"
6756   [(set_attr "type" "load")
6757    (set_attr "length" "4")])
6759 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6760 ;;              STW          STFIWX       STXSIWX      LI           LIS
6761 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6762 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6763 ;;              MF%1         MT%0         MT%0         NOP
6764 (define_insn "*movsi_internal1"
6765   [(set (match_operand:SI 0 "nonimmediate_operand"
6766                 "=r,         r,           r,           ?*wI,        ?*wH,
6767                  m,          ?Z,          ?Z,          r,           r,
6768                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6769                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6770                  r,          *c*l,        *h,          *h")
6772         (match_operand:SI 1 "input_operand"
6773                 "r,          U,           m,           Z,           Z,
6774                  r,          wI,          wH,          I,           L,
6775                  n,          wIwH,        O,           wM,          wB,
6776                  O,          wM,          wS,          r,           wIwH,
6777                  *h,         r,           r,           0"))]
6779   "!TARGET_SINGLE_FPU &&
6780    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6781   "@
6782    mr %0,%1
6783    la %0,%a1
6784    lwz%U1%X1 %0,%1
6785    lfiwzx %0,%y1
6786    lxsiwzx %x0,%y1
6787    stw%U0%X0 %1,%0
6788    stfiwx %1,%y0
6789    stxsiwx %x1,%y0
6790    li %0,%1
6791    lis %0,%v1
6792    #
6793    xxlor %x0,%x1,%x1
6794    xxspltib %x0,0
6795    xxspltib %x0,255
6796    vspltisw %0,%1
6797    xxlxor %x0,%x0,%x0
6798    xxlorc %x0,%x0,%x0
6799    #
6800    mtvsrwz %x0,%1
6801    mfvsrwz %0,%x1
6802    mf%1 %0
6803    mt%0 %1
6804    mt%0 %1
6805    nop"
6806   [(set_attr "type"
6807                 "*,          *,           load,        fpload,      fpload,
6808                  store,      fpstore,     fpstore,     *,           *,
6809                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6810                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6811                  *,           *,           *,           *")
6813    (set_attr "length"
6814                 "4,          4,           4,           4,           4,
6815                  4,          4,           4,           4,           4,
6816                  8,          4,           4,           4,           4,
6817                  4,          4,           8,           4,           4,
6818                  4,          4,           4,           4")])
6820 (define_insn "*movsi_internal1_single"
6821   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6822         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6823   "TARGET_SINGLE_FPU &&
6824    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6825   "@
6826    mr %0,%1
6827    la %0,%a1
6828    lwz%U1%X1 %0,%1
6829    stw%U0%X0 %1,%0
6830    li %0,%1
6831    lis %0,%v1
6832    #
6833    mf%1 %0
6834    mt%0 %1
6835    mt%0 %1
6836    nop
6837    stfs%U0%X0 %1,%0
6838    lfs%U1%X1 %0,%1"
6839   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6840    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6842 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6843 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6845 ;; Because SF values are actually stored as DF values within the vector
6846 ;; registers, we need to convert the value to the vector SF format when
6847 ;; we need to use the bits in a union or similar cases.  We only need
6848 ;; to do this transformation when the value is a vector register.  Loads,
6849 ;; stores, and transfers within GPRs are assumed to be safe.
6851 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6852 ;; no alternatives, because the call is created as part of secondary_reload,
6853 ;; and operand #2's register class is used to allocate the temporary register.
6854 ;; This function is called before reload, and it creates the temporary as
6855 ;; needed.
6857 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6858 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6859 ;;              MTVSRWZ
6861 (define_insn_and_split "movsi_from_sf"
6862   [(set (match_operand:SI 0 "nonimmediate_operand"
6863                 "=r,         r,           ?*wI,        ?*wH,     m,
6864                  m,          wY,          Z,           r,        ?*wIwH,
6865                  wIwH")
6867         (unspec:SI [(match_operand:SF 1 "input_operand"
6868                 "r,          m,           Z,           Z,        r,
6869                  f,          wb,          wu,          wIwH,     wIwH,
6870                  r")]
6871                     UNSPEC_SI_FROM_SF))
6873    (clobber (match_scratch:V4SF 2
6874                 "=X,         X,           X,           X,        X,
6875                  X,          X,           X,           wIwH,     X,
6876                  X"))]
6878   "TARGET_NO_SF_SUBREG
6879    && (register_operand (operands[0], SImode)
6880        || register_operand (operands[1], SFmode))"
6881   "@
6882    mr %0,%1
6883    lwz%U1%X1 %0,%1
6884    lfiwzx %0,%y1
6885    lxsiwzx %x0,%y1
6886    stw%U0%X0 %1,%0
6887    stfs%U0%X0 %1,%0
6888    stxssp %1,%0
6889    stxsspx %x1,%y0
6890    #
6891    xscvdpspn %x0,%x1
6892    mtvsrwz %x0,%1"
6893   "&& reload_completed
6894    && int_reg_operand (operands[0], SImode)
6895    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6896   [(const_int 0)]
6898   rtx op0 = operands[0];
6899   rtx op1 = operands[1];
6900   rtx op2 = operands[2];
6901   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6902   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6904   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6905   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6906   DONE;
6908   [(set_attr "type"
6909                 "*,          load,        fpload,      fpload,   store,
6910                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6911                  mffgpr")
6913    (set_attr "length"
6914                 "4,          4,           4,           4,        4,
6915                  4,          4,           4,           8,        4,
6916                  4")])
6918 ;; movsi_from_sf with zero extension
6920 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6921 ;;              VSX->VSX     MTVSRWZ
6923 (define_insn_and_split "*movdi_from_sf_zero_ext"
6924   [(set (match_operand:DI 0 "gpc_reg_operand"
6925                 "=r,         r,           ?*wI,        ?*wH,     r,
6926                  ?wK,        wIwH")
6928         (zero_extend:DI
6929          (unspec:SI [(match_operand:SF 1 "input_operand"
6930                 "r,          m,           Z,           Z,        wIwH,
6931                  wIwH,       r")]
6932                     UNSPEC_SI_FROM_SF)))
6934    (clobber (match_scratch:V4SF 2
6935                 "=X,         X,           X,           X,        wa,
6936                  wIwH,       X"))]
6938   "TARGET_DIRECT_MOVE_64BIT
6939    && (register_operand (operands[0], DImode)
6940        || register_operand (operands[1], SImode))"
6941   "@
6942    rldicl %0,%1,0,32
6943    lwz%U1%X1 %0,%1
6944    lfiwzx %0,%y1
6945    lxsiwzx %x0,%y1
6946    #
6947    #
6948    mtvsrwz %x0,%1"
6949   "&& reload_completed
6950    && register_operand (operands[0], DImode)
6951    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6952   [(const_int 0)]
6954   rtx op0 = operands[0];
6955   rtx op1 = operands[1];
6956   rtx op2 = operands[2];
6957   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6959   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6960   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6961   DONE;
6963   [(set_attr "type"
6964                 "*,          load,        fpload,      fpload,   two,
6965                  two,        mffgpr")
6967    (set_attr "length"
6968                 "4,          4,           4,           4,        8,
6969                  8,          4")])
6971 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6972 ;; moving it to SImode.  We can do a SFmode store without having to do the
6973 ;; conversion explicitly.  If we are doing a register->register conversion, use
6974 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6975 ;; input will not fit in a SFmode, and the later assumes the value has already
6976 ;; been rounded.
6977 (define_insn "*movsi_from_df"
6978   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
6979         (unspec:SI [(float_truncate:SF
6980                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6981                     UNSPEC_SI_FROM_SF))]
6983   "TARGET_NO_SF_SUBREG"
6984   "@
6985    xscvdpsp %x0,%x1
6986    stfs%U0%X0 %1,%0
6987    stxssp %1,%0
6988    stxsspx %x1,%y0"
6989   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
6991 ;; Split a load of a large constant into the appropriate two-insn
6992 ;; sequence.
6994 (define_split
6995   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6996         (match_operand:SI 1 "const_int_operand" ""))]
6997   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6998    && (INTVAL (operands[1]) & 0xffff) != 0"
6999   [(set (match_dup 0)
7000         (match_dup 2))
7001    (set (match_dup 0)
7002         (ior:SI (match_dup 0)
7003                 (match_dup 3)))]
7004   "
7006   if (rs6000_emit_set_const (operands[0], operands[1]))
7007     DONE;
7008   else
7009     FAIL;
7012 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7013 (define_split
7014   [(set (match_operand:DI 0 "altivec_register_operand")
7015         (match_operand:DI 1 "xxspltib_constant_split"))]
7016   "TARGET_P9_VECTOR && reload_completed"
7017   [(const_int 0)]
7019   rtx op0 = operands[0];
7020   rtx op1 = operands[1];
7021   int r = REGNO (op0);
7022   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7024   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7025   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7026   DONE;
7029 (define_insn "*mov<mode>_internal2"
7030   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7031         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7032                     (const_int 0)))
7033    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7034   ""
7035   "@
7036    cmp<wd>i %2,%0,0
7037    mr. %0,%1
7038    #"
7039   [(set_attr "type" "cmp,logical,cmp")
7040    (set_attr "dot" "yes")
7041    (set_attr "length" "4,4,8")])
7043 (define_split
7044   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7045         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7046                     (const_int 0)))
7047    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7048   "reload_completed"
7049   [(set (match_dup 0) (match_dup 1))
7050    (set (match_dup 2)
7051         (compare:CC (match_dup 0)
7052                     (const_int 0)))]
7053   "")
7055 (define_expand "mov<mode>"
7056   [(set (match_operand:INT 0 "general_operand" "")
7057         (match_operand:INT 1 "any_operand" ""))]
7058   ""
7059   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7061 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7062 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7063 ;;              MTVSRWZ     MF%1       MT%1       NOP
7064 (define_insn "*mov<mode>_internal"
7065   [(set (match_operand:QHI 0 "nonimmediate_operand"
7066                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7067                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7068                  ?*wJwK,    r,         *c*l,      *h")
7070         (match_operand:QHI 1 "input_operand"
7071                 "r,         m,         Z,         r,         wJwK,      i,
7072                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7073                  r,         *h,        r,         0"))]
7075   "gpc_reg_operand (operands[0], <MODE>mode)
7076    || gpc_reg_operand (operands[1], <MODE>mode)"
7077   "@
7078    mr %0,%1
7079    l<wd>z%U1%X1 %0,%1
7080    lxsi<wd>zx %x0,%y1
7081    st<wd>%U0%X0 %1,%0
7082    stxsi<wd>x %x1,%y0
7083    li %0,%1
7084    xxlor %x0,%x1,%x1
7085    xxspltib %x0,0
7086    xxspltib %x0,255
7087    vspltis<wd> %0,%1
7088    #
7089    mfvsrwz %0,%x1
7090    mtvsrwz %x0,%1
7091    mf%1 %0
7092    mt%0 %1
7093    nop"
7094   [(set_attr "type"
7095                 "*,         load,      fpload,    store,     fpstore,   *,
7096                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7097                  mffgpr,    mfjmpr,    mtjmpr,    *")
7099    (set_attr "length"
7100                 "4,         4,         4,         4,         4,         4,
7101                  4,         4,         4,         4,         8,         4,
7102                  4,         4,         4,         4")])
7105 ;; Here is how to move condition codes around.  When we store CC data in
7106 ;; an integer register or memory, we store just the high-order 4 bits.
7107 ;; This lets us not shift in the most common case of CR0.
7108 (define_expand "movcc"
7109   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7110         (match_operand:CC 1 "nonimmediate_operand" ""))]
7111   ""
7112   "")
7114 (define_insn "*movcc_internal1"
7115   [(set (match_operand:CC 0 "nonimmediate_operand"
7116                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7117         (match_operand:CC 1 "general_operand"
7118                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7119   "register_operand (operands[0], CCmode)
7120    || register_operand (operands[1], CCmode)"
7121   "@
7122    mcrf %0,%1
7123    mtcrf 128,%1
7124    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7125    crxor %0,%0,%0
7126    mfcr %0%Q1
7127    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7128    mr %0,%1
7129    li %0,%1
7130    mf%1 %0
7131    mt%0 %1
7132    lwz%U1%X1 %0,%1
7133    stw%U0%X0 %1,%0"
7134   [(set (attr "type")
7135      (cond [(eq_attr "alternative" "0,3")
7136                 (const_string "cr_logical")
7137             (eq_attr "alternative" "1,2")
7138                 (const_string "mtcr")
7139             (eq_attr "alternative" "6,7")
7140                 (const_string "integer")
7141             (eq_attr "alternative" "8")
7142                 (const_string "mfjmpr")
7143             (eq_attr "alternative" "9")
7144                 (const_string "mtjmpr")
7145             (eq_attr "alternative" "10")
7146                 (const_string "load")
7147             (eq_attr "alternative" "11")
7148                 (const_string "store")
7149             (match_test "TARGET_MFCRF")
7150                 (const_string "mfcrf")
7151            ]
7152         (const_string "mfcr")))
7153    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7155 ;; For floating-point, we normally deal with the floating-point registers
7156 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7157 ;; can produce floating-point values in fixed-point registers.  Unless the
7158 ;; value is a simple constant or already in memory, we deal with this by
7159 ;; allocating memory and copying the value explicitly via that memory location.
7161 ;; Move 32-bit binary/decimal floating point
7162 (define_expand "mov<mode>"
7163   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7164         (match_operand:FMOVE32 1 "any_operand" ""))]
7165   "<fmove_ok>"
7166   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7168 (define_split
7169   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7170         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7171   "reload_completed
7172    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7173        || (GET_CODE (operands[0]) == SUBREG
7174            && GET_CODE (SUBREG_REG (operands[0])) == REG
7175            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7176   [(set (match_dup 2) (match_dup 3))]
7177   "
7179   long l;
7181   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7183   if (! TARGET_POWERPC64)
7184     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7185   else
7186     operands[2] = gen_lowpart (SImode, operands[0]);
7188   operands[3] = gen_int_mode (l, SImode);
7191 ;; Originally, we tried to keep movsf and movsd common, but the differences
7192 ;; addressing was making it rather difficult to hide with mode attributes.  In
7193 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7194 ;; before the VSX stores meant that the register allocator would tend to do a
7195 ;; direct move to the GPR (which involves conversion from scalar to
7196 ;; vector/memory formats) to save values in the traditional Altivec registers,
7197 ;; while SDmode had problems on power6 if the GPR store was not first due to
7198 ;; the power6 not having an integer store operation.
7200 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7201 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7202 ;;      MR           MT<x>      MF<x>       NOP
7204 (define_insn "movsf_hardfloat"
7205   [(set (match_operand:SF 0 "nonimmediate_operand"
7206          "=!r,       f,         wb,         wu,        m,         wY,
7207           Z,         m,         ww,         !r,        f,         ww,
7208           !r,        *c*l,      !r,         *h")
7209         (match_operand:SF 1 "input_operand"
7210          "m,         m,         wY,         Z,         f,         wb,
7211           wu,        r,         j,          j,         f,         ww,
7212           r,         r,         *h,         0"))]
7213   "(register_operand (operands[0], SFmode)
7214    || register_operand (operands[1], SFmode))
7215    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7216    && (TARGET_ALLOW_SF_SUBREG
7217        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7218   "@
7219    lwz%U1%X1 %0,%1
7220    lfs%U1%X1 %0,%1
7221    lxssp %0,%1
7222    lxsspx %x0,%y1
7223    stfs%U0%X0 %1,%0
7224    stxssp %1,%0
7225    stxsspx %x1,%y0
7226    stw%U0%X0 %1,%0
7227    xxlxor %x0,%x0,%x0
7228    li %0,0
7229    fmr %0,%1
7230    xscpsgndp %x0,%x1,%x1
7231    mr %0,%1
7232    mt%0 %1
7233    mf%1 %0
7234    nop"
7235   [(set_attr "type"
7236         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7237          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7238          *,          mtjmpr,    mfjmpr,     *")])
7240 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7241 ;;      FMR          MR         MT%0       MF%1       NOP
7242 (define_insn "movsd_hardfloat"
7243   [(set (match_operand:SD 0 "nonimmediate_operand"
7244          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7245           f,         !r,        *c*l,      !r,        *h")
7246         (match_operand:SD 1 "input_operand"
7247          "m,         Z,         r,         wx,        r,         wh,
7248           f,         r,         r,         *h,        0"))]
7249   "(register_operand (operands[0], SDmode)
7250    || register_operand (operands[1], SDmode))
7251    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7252   "@
7253    lwz%U1%X1 %0,%1
7254    lfiwzx %0,%y1
7255    stw%U0%X0 %1,%0
7256    stfiwx %1,%y0
7257    mtvsrwz %x0,%1
7258    mfvsrwz %0,%x1
7259    fmr %0,%1
7260    mr %0,%1
7261    mt%0 %1
7262    mf%1 %0
7263    nop"
7264   [(set_attr "type"
7265         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7266          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7268 (define_insn "*mov<mode>_softfloat"
7269   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7270         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7271   "(gpc_reg_operand (operands[0], <MODE>mode)
7272    || gpc_reg_operand (operands[1], <MODE>mode))
7273    && TARGET_SOFT_FLOAT"
7274   "@
7275    mr %0,%1
7276    mt%0 %1
7277    mf%1 %0
7278    lwz%U1%X1 %0,%1
7279    stw%U0%X0 %1,%0
7280    li %0,%1
7281    lis %0,%v1
7282    #
7283    #
7284    nop"
7285   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7286    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7288 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7289 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7291 ;; Because SF values are actually stored as DF values within the vector
7292 ;; registers, we need to convert the value to the vector SF format when
7293 ;; we need to use the bits in a union or similar cases.  We only need
7294 ;; to do this transformation when the value is a vector register.  Loads,
7295 ;; stores, and transfers within GPRs are assumed to be safe.
7297 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7298 ;; no alternatives, because the call is created as part of secondary_reload,
7299 ;; and operand #2's register class is used to allocate the temporary register.
7300 ;; This function is called before reload, and it creates the temporary as
7301 ;; needed.
7303 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7304 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7305 (define_insn_and_split "movsf_from_si"
7306   [(set (match_operand:SF 0 "nonimmediate_operand"
7307             "=!r,       f,         wb,        wu,        m,         Z,
7308              Z,         wy,        ?r,        !r")
7310         (unspec:SF [(match_operand:SI 1 "input_operand" 
7311             "m,         m,         wY,        Z,         r,         f,
7312              wu,        r,         wy,        r")]
7313                    UNSPEC_SF_FROM_SI))
7315    (clobber (match_scratch:DI 2
7316             "=X,        X,         X,         X,         X,         X,
7317              X,         r,         X,         X"))]
7319   "TARGET_NO_SF_SUBREG
7320    && (register_operand (operands[0], SFmode)
7321        || register_operand (operands[1], SImode))"
7322   "@
7323    lwz%U1%X1 %0,%1
7324    lfs%U1%X1 %0,%1
7325    lxssp %0,%1
7326    lxsspx %x0,%y1
7327    stw%U0%X0 %1,%0
7328    stfiwx %1,%y0
7329    stxsiwx %x1,%y0
7330    #
7331    mfvsrwz %0,%x1
7332    mr %0,%1"
7334   "&& reload_completed
7335    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7336    && int_reg_operand_not_pseudo (operands[1], SImode)"
7337   [(const_int 0)]
7339   rtx op0 = operands[0];
7340   rtx op1 = operands[1];
7341   rtx op2 = operands[2];
7342   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7344   /* Move SF value to upper 32-bits for xscvspdpn.  */
7345   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7346   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7347   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7348   DONE;
7350   [(set_attr "length"
7351             "4,          4,         4,         4,         4,         4,
7352              4,          12,        4,         4")
7353    (set_attr "type"
7354             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7355              fpstore,    vecfloat,  mffgpr,    *")])
7358 ;; Move 64-bit binary/decimal floating point
7359 (define_expand "mov<mode>"
7360   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7361         (match_operand:FMOVE64 1 "any_operand" ""))]
7362   ""
7363   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7365 (define_split
7366   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7367         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7368   "! TARGET_POWERPC64 && reload_completed
7369    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7370        || (GET_CODE (operands[0]) == SUBREG
7371            && GET_CODE (SUBREG_REG (operands[0])) == REG
7372            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7373   [(set (match_dup 2) (match_dup 4))
7374    (set (match_dup 3) (match_dup 1))]
7375   "
7377   int endian = (WORDS_BIG_ENDIAN == 0);
7378   HOST_WIDE_INT value = INTVAL (operands[1]);
7380   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7381   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7382   operands[4] = GEN_INT (value >> 32);
7383   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7386 (define_split
7387   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7388         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7389   "! TARGET_POWERPC64 && reload_completed
7390    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7391        || (GET_CODE (operands[0]) == SUBREG
7392            && GET_CODE (SUBREG_REG (operands[0])) == REG
7393            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7394   [(set (match_dup 2) (match_dup 4))
7395    (set (match_dup 3) (match_dup 5))]
7396   "
7398   int endian = (WORDS_BIG_ENDIAN == 0);
7399   long l[2];
7401   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7403   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7404   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7405   operands[4] = gen_int_mode (l[endian], SImode);
7406   operands[5] = gen_int_mode (l[1 - endian], SImode);
7409 (define_split
7410   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7411         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7412   "TARGET_POWERPC64 && reload_completed
7413    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7414        || (GET_CODE (operands[0]) == SUBREG
7415            && GET_CODE (SUBREG_REG (operands[0])) == REG
7416            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7417   [(set (match_dup 2) (match_dup 3))]
7418   "
7420   int endian = (WORDS_BIG_ENDIAN == 0);
7421   long l[2];
7422   HOST_WIDE_INT val;
7424   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7426   operands[2] = gen_lowpart (DImode, operands[0]);
7427   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7428   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7429          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7431   operands[3] = gen_int_mode (val, DImode);
7434 ;; Don't have reload use general registers to load a constant.  It is
7435 ;; less efficient than loading the constant into an FP register, since
7436 ;; it will probably be used there.
7438 ;; The move constraints are ordered to prefer floating point registers before
7439 ;; general purpose registers to avoid doing a store and a load to get the value
7440 ;; into a floating point register when it is needed for a floating point
7441 ;; operation.  Prefer traditional floating point registers over VSX registers,
7442 ;; since the D-form version of the memory instructions does not need a GPR for
7443 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7444 ;; registers.
7446 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7447 ;; except for 0.0 which can be created on VSX with an xor instruction.
7449 (define_insn "*mov<mode>_hardfloat32"
7450   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7451         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7452   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 
7453    && (gpc_reg_operand (operands[0], <MODE>mode)
7454        || gpc_reg_operand (operands[1], <MODE>mode))"
7455   "@
7456    stfd%U0%X0 %1,%0
7457    lfd%U1%X1 %0,%1
7458    fmr %0,%1
7459    lxsd %0,%1
7460    stxsd %1,%0
7461    lxsd%U1x %x0,%y1
7462    stxsd%U0x %x1,%y0
7463    xxlor %x0,%x1,%x1
7464    xxlxor %x0,%x0,%x0
7465    #
7466    #
7467    #
7468    #"
7469   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7470    (set_attr "size" "64")
7471    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7473 (define_insn "*mov<mode>_softfloat32"
7474   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7475         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7476   "! TARGET_POWERPC64 
7477    && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7478    && (gpc_reg_operand (operands[0], <MODE>mode)
7479        || gpc_reg_operand (operands[1], <MODE>mode))"
7480   "#"
7481   [(set_attr "type" "store,load,two,*,*,*")
7482    (set_attr "length" "8,8,8,8,12,16")])
7484 ; ld/std require word-aligned displacements -> 'Y' constraint.
7485 ; List Y->r and r->Y before r->r for reload.
7486 (define_insn "*mov<mode>_hardfloat64"
7487   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
7488         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
7489   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7490    && (gpc_reg_operand (operands[0], <MODE>mode)
7491        || gpc_reg_operand (operands[1], <MODE>mode))"
7492   "@
7493    stfd%U0%X0 %1,%0
7494    lfd%U1%X1 %0,%1
7495    fmr %0,%1
7496    lxsd %0,%1
7497    stxsd %1,%0
7498    lxsd%U1x %x0,%y1
7499    stxsd%U0x %x1,%y0
7500    xxlor %x0,%x1,%x1
7501    xxlxor %x0,%x0,%x0
7502    li %0,0
7503    std%U0%X0 %1,%0
7504    ld%U1%X1 %0,%1
7505    mr %0,%1
7506    mt%0 %1
7507    mf%1 %0
7508    nop
7509    mftgpr %0,%1
7510    mffgpr %0,%1
7511    mfvsrd %0,%x1
7512    mtvsrd %x0,%1"
7513   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7514    (set_attr "size" "64")
7515    (set_attr "length" "4")])
7517 (define_insn "*mov<mode>_softfloat64"
7518   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7519         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7520   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7521    && (gpc_reg_operand (operands[0], <MODE>mode)
7522        || gpc_reg_operand (operands[1], <MODE>mode))"
7523   "@
7524    std%U0%X0 %1,%0
7525    ld%U1%X1 %0,%1
7526    mr %0,%1
7527    mt%0 %1
7528    mf%1 %0
7529    #
7530    #
7531    #
7532    nop"
7533   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7534    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7536 (define_expand "mov<mode>"
7537   [(set (match_operand:FMOVE128 0 "general_operand" "")
7538         (match_operand:FMOVE128 1 "any_operand" ""))]
7539   ""
7540   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7542 ;; It's important to list Y->r and r->Y before r->r because otherwise
7543 ;; reload, given m->r, will try to pick r->r and reload it, which
7544 ;; doesn't make progress.
7546 ;; We can't split little endian direct moves of TDmode, because the words are
7547 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7548 ;; problematical.  Don't allow direct move for this case.
7550 (define_insn_and_split "*mov<mode>_64bit_dm"
7551   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7552         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7553   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7554    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7555    && (gpc_reg_operand (operands[0], <MODE>mode)
7556        || gpc_reg_operand (operands[1], <MODE>mode))"
7557   "#"
7558   "&& reload_completed"
7559   [(pc)]
7560 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7561   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7563 (define_insn_and_split "*movtd_64bit_nodm"
7564   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7565         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7566   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7567    && (gpc_reg_operand (operands[0], TDmode)
7568        || gpc_reg_operand (operands[1], TDmode))"
7569   "#"
7570   "&& reload_completed"
7571   [(pc)]
7572 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7573   [(set_attr "length" "8,8,8,12,12,8")])
7575 (define_insn_and_split "*mov<mode>_32bit"
7576   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7577         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7578   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7579    && (FLOAT128_2REG_P (<MODE>mode)
7580        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7581        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7582    && (gpc_reg_operand (operands[0], <MODE>mode)
7583        || gpc_reg_operand (operands[1], <MODE>mode))"
7584   "#"
7585   "&& reload_completed"
7586   [(pc)]
7587 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7588   [(set_attr "length" "8,8,8,8,20,20,16")])
7590 (define_insn_and_split "*mov<mode>_softfloat"
7591   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7592         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7593   "TARGET_SOFT_FLOAT
7594    && (gpc_reg_operand (operands[0], <MODE>mode)
7595        || gpc_reg_operand (operands[1], <MODE>mode))"
7596   "#"
7597   "&& reload_completed"
7598   [(pc)]
7599 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7600   [(set_attr "length" "20,20,16")])
7602 (define_expand "extenddf<mode>2"
7603   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7604         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7605   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7607   if (FLOAT128_IEEE_P (<MODE>mode))
7608     rs6000_expand_float128_convert (operands[0], operands[1], false);
7609   else if (TARGET_VSX)
7610     {
7611       if (<MODE>mode == TFmode)
7612         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7613       else if (<MODE>mode == IFmode)
7614         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7615       else
7616         gcc_unreachable ();
7617     }
7618    else
7619     {
7620       rtx zero = gen_reg_rtx (DFmode);
7621       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7623       if (<MODE>mode == TFmode)
7624         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7625       else if (<MODE>mode == IFmode)
7626         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7627       else
7628         gcc_unreachable ();
7629     }
7630   DONE;
7633 ;; Allow memory operands for the source to be created by the combiner.
7634 (define_insn_and_split "extenddf<mode>2_fprs"
7635   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7636         (float_extend:IBM128
7637          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7638    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7639   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7640    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7641   "#"
7642   "&& reload_completed"
7643   [(set (match_dup 3) (match_dup 1))
7644    (set (match_dup 4) (match_dup 2))]
7646   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7647   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7649   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7650   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7653 (define_insn_and_split "extenddf<mode>2_vsx"
7654   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7655         (float_extend:IBM128
7656          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7657   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7658   "#"
7659   "&& reload_completed"
7660   [(set (match_dup 2) (match_dup 1))
7661    (set (match_dup 3) (match_dup 4))]
7663   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7664   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7666   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7667   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7668   operands[4] = CONST0_RTX (DFmode);
7671 (define_expand "extendsf<mode>2"
7672   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7673         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7674   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7676   if (FLOAT128_IEEE_P (<MODE>mode))
7677     rs6000_expand_float128_convert (operands[0], operands[1], false);
7678   else
7679     {
7680       rtx tmp = gen_reg_rtx (DFmode);
7681       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7682       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7683     }
7684   DONE;
7687 (define_expand "trunc<mode>df2"
7688   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7689         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7690   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7692   if (FLOAT128_IEEE_P (<MODE>mode))
7693     {
7694       rs6000_expand_float128_convert (operands[0], operands[1], false);
7695       DONE;
7696     }
7699 (define_insn_and_split "trunc<mode>df2_internal1"
7700   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7701         (float_truncate:DF
7702          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7703   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7704    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7705   "@
7706    #
7707    fmr %0,%1"
7708   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7709   [(const_int 0)]
7711   emit_note (NOTE_INSN_DELETED);
7712   DONE;
7714   [(set_attr "type" "fpsimple")])
7716 (define_insn "trunc<mode>df2_internal2"
7717   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7718         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7719   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7720    && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7721   "fadd %0,%1,%L1"
7722   [(set_attr "type" "fp")
7723    (set_attr "fp_type" "fp_addsub_d")])
7725 (define_expand "trunc<mode>sf2"
7726   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7727         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7728   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7730   if (FLOAT128_IEEE_P (<MODE>mode))
7731     rs6000_expand_float128_convert (operands[0], operands[1], false);
7732   else if (<MODE>mode == TFmode)
7733     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7734   else if (<MODE>mode == IFmode)
7735     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7736   else
7737     gcc_unreachable ();
7738   DONE;
7741 (define_insn_and_split "trunc<mode>sf2_fprs"
7742   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7743         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7744    (clobber (match_scratch:DF 2 "=d"))]
7745   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 
7746    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7747   "#"
7748   "&& reload_completed"
7749   [(set (match_dup 2)
7750         (float_truncate:DF (match_dup 1)))
7751    (set (match_dup 0)
7752         (float_truncate:SF (match_dup 2)))]
7753   "")
7755 (define_expand "floatsi<mode>2"
7756   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7757                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7758               (clobber (match_scratch:DI 2))])]
7759   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7761   rtx op0 = operands[0];
7762   rtx op1 = operands[1];
7764   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7765     ;
7766   else if (FLOAT128_IEEE_P (<MODE>mode))
7767     {
7768       rs6000_expand_float128_convert (op0, op1, false);
7769       DONE;
7770     }
7771   else
7772     {
7773       rtx tmp = gen_reg_rtx (DFmode);
7774       expand_float (tmp, op1, false);
7775       if (<MODE>mode == TFmode)
7776         emit_insn (gen_extenddftf2 (op0, tmp));
7777       else if (<MODE>mode == IFmode)
7778         emit_insn (gen_extenddfif2 (op0, tmp));
7779       else
7780         gcc_unreachable ();
7781       DONE;
7782     }
7785 ; fadd, but rounding towards zero.
7786 ; This is probably not the optimal code sequence.
7787 (define_insn "fix_trunc_helper<mode>"
7788   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7789         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7790                    UNSPEC_FIX_TRUNC_TF))
7791    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7792   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7793   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7794   [(set_attr "type" "fp")
7795    (set_attr "length" "20")])
7797 (define_expand "fix_trunc<mode>si2"
7798   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7799         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7800   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7802   rtx op0 = operands[0];
7803   rtx op1 = operands[1];
7805   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7806     ;
7807   else
7808     {
7809       if (FLOAT128_IEEE_P (<MODE>mode))
7810         rs6000_expand_float128_convert (op0, op1, false);
7811       else if (<MODE>mode == TFmode)
7812         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7813       else if (<MODE>mode == IFmode)
7814         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7815       else
7816         gcc_unreachable ();
7817       DONE;
7818     }
7821 (define_expand "fix_trunc<mode>si2_fprs"
7822   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7823                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7824               (clobber (match_dup 2))
7825               (clobber (match_dup 3))
7826               (clobber (match_dup 4))
7827               (clobber (match_dup 5))])]
7828   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7830   operands[2] = gen_reg_rtx (DFmode);
7831   operands[3] = gen_reg_rtx (DFmode);
7832   operands[4] = gen_reg_rtx (DImode);
7833   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7836 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7837   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7838         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7839    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7840    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7841    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7842    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7843   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7844   "#"
7845   ""
7846   [(pc)]
7848   rtx lowword;
7849   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7850                                          operands[3]));
7852   gcc_assert (MEM_P (operands[5]));
7853   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7855   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7856   emit_move_insn (operands[5], operands[4]);
7857   emit_move_insn (operands[0], lowword);
7858   DONE;
7861 (define_expand "fix_trunc<mode>di2"
7862   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7863         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7864   "TARGET_FLOAT128_TYPE"
7866   if (!TARGET_FLOAT128_HW)
7867     {
7868       rs6000_expand_float128_convert (operands[0], operands[1], false);
7869       DONE;
7870     }
7873 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7874   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7875         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7876   "TARGET_FLOAT128_TYPE"
7878   rs6000_expand_float128_convert (operands[0], operands[1], true);
7879   DONE;
7882 (define_expand "floatdi<mode>2"
7883   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7884         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7885   "TARGET_FLOAT128_TYPE"
7887   if (!TARGET_FLOAT128_HW)
7888     {
7889       rs6000_expand_float128_convert (operands[0], operands[1], false);
7890       DONE;
7891     }
7894 (define_expand "floatunsdi<IEEE128:mode>2"
7895   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7896         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7897   "TARGET_FLOAT128_TYPE"
7899   if (!TARGET_FLOAT128_HW)
7900     {
7901       rs6000_expand_float128_convert (operands[0], operands[1], true);
7902       DONE;
7903     }
7906 (define_expand "floatuns<IEEE128:mode>2"
7907   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7908         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7909   "TARGET_FLOAT128_TYPE"
7911   rtx op0 = operands[0];
7912   rtx op1 = operands[1];
7914   if (TARGET_FLOAT128_HW)
7915     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7916   else
7917     rs6000_expand_float128_convert (op0, op1, true);
7918   DONE;
7921 (define_expand "neg<mode>2"
7922   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7923         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7924   "FLOAT128_IEEE_P (<MODE>mode)
7925    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7926   "
7928   if (FLOAT128_IEEE_P (<MODE>mode))
7929     {
7930       if (TARGET_FLOAT128_HW)
7931         {
7932           if (<MODE>mode == TFmode)
7933             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7934           else if (<MODE>mode == KFmode)
7935             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7936           else
7937             gcc_unreachable ();
7938         }
7939       else if (TARGET_FLOAT128_TYPE)
7940         {
7941           if (<MODE>mode == TFmode)
7942             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7943           else if (<MODE>mode == KFmode)
7944             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7945           else
7946             gcc_unreachable ();
7947         }
7948       else
7949         {
7950           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7951           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7952                                                 <MODE>mode,
7953                                                 operands[1], <MODE>mode);
7955           if (target && !rtx_equal_p (target, operands[0]))
7956             emit_move_insn (operands[0], target);
7957         }
7958       DONE;
7959     }
7962 (define_insn "neg<mode>2_internal"
7963   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7964         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7965   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7966   "*
7968   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7969     return \"fneg %L0,%L1\;fneg %0,%1\";
7970   else
7971     return \"fneg %0,%1\;fneg %L0,%L1\";
7973   [(set_attr "type" "fpsimple")
7974    (set_attr "length" "8")])
7976 (define_expand "abs<mode>2"
7977   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7978         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7979   "FLOAT128_IEEE_P (<MODE>mode)
7980    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7981   "
7983   rtx label;
7985   if (FLOAT128_IEEE_P (<MODE>mode))
7986     {
7987       if (TARGET_FLOAT128_HW)
7988         {
7989           if (<MODE>mode == TFmode)
7990             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7991           else if (<MODE>mode == KFmode)
7992             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7993           else
7994             FAIL;
7995           DONE;
7996         }
7997       else if (TARGET_FLOAT128_TYPE)
7998         {
7999           if (<MODE>mode == TFmode)
8000             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8001           else if (<MODE>mode == KFmode)
8002             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8003           else
8004             FAIL;
8005           DONE;
8006         }
8007       else
8008         FAIL;
8009     }
8011   label = gen_label_rtx ();
8012   if (<MODE>mode == TFmode)
8013     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8014   else if (<MODE>mode == TFmode)
8015     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8016   else
8017     FAIL;
8018   emit_label (label);
8019   DONE;
8022 (define_expand "abs<mode>2_internal"
8023   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8024         (match_operand:IBM128 1 "gpc_reg_operand" ""))
8025    (set (match_dup 3) (match_dup 5))
8026    (set (match_dup 5) (abs:DF (match_dup 5)))
8027    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8028    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8029                            (label_ref (match_operand 2 "" ""))
8030                            (pc)))
8031    (set (match_dup 6) (neg:DF (match_dup 6)))]
8032   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
8033   "
8035   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8036   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8037   operands[3] = gen_reg_rtx (DFmode);
8038   operands[4] = gen_reg_rtx (CCFPmode);
8039   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8040   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8044 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8045 ;; register
8047 (define_expand "ieee_128bit_negative_zero"
8048   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8049   "TARGET_FLOAT128_TYPE"
8051   rtvec v = rtvec_alloc (16);
8052   int i, high;
8054   for (i = 0; i < 16; i++)
8055     RTVEC_ELT (v, i) = const0_rtx;
8057   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8058   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8060   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8061   DONE;
8064 ;; IEEE 128-bit negate
8066 ;; We have 2 insns here for negate and absolute value.  The first uses
8067 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8068 ;; insns, and second insn after the first split pass loads up the bit to
8069 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8070 ;; neg/abs to create the constant just once.
8072 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8073   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8074         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8075    (clobber (match_scratch:V16QI 2 "=v"))]
8076   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8077   "#"
8078   "&& 1"
8079   [(parallel [(set (match_dup 0)
8080                    (neg:IEEE128 (match_dup 1)))
8081               (use (match_dup 2))])]
8083   if (GET_CODE (operands[2]) == SCRATCH)
8084     operands[2] = gen_reg_rtx (V16QImode);
8086   operands[3] = gen_reg_rtx (V16QImode);
8087   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8089   [(set_attr "length" "8")
8090    (set_attr "type" "vecsimple")])
8092 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8093   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8094         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8095    (use (match_operand:V16QI 2 "register_operand" "v"))]
8096   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8097   "xxlxor %x0,%x1,%x2"
8098   [(set_attr "type" "veclogical")])
8100 ;; IEEE 128-bit absolute value
8101 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8102   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8103         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8104    (clobber (match_scratch:V16QI 2 "=v"))]
8105   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8106   "#"
8107   "&& 1"
8108   [(parallel [(set (match_dup 0)
8109                    (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_abs<mode>2_internal"
8122   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8123         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8124    (use (match_operand:V16QI 2 "register_operand" "v"))]
8125   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8126   "xxlandc %x0,%x1,%x2"
8127   [(set_attr "type" "veclogical")])
8129 ;; IEEE 128-bit negative absolute value
8130 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8131   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8132         (neg:IEEE128
8133          (abs:IEEE128
8134           (match_operand:IEEE128 1 "register_operand" "wa"))))
8135    (clobber (match_scratch:V16QI 2 "=v"))]
8136   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8137    && FLOAT128_IEEE_P (<MODE>mode)"
8138   "#"
8139   "&& 1"
8140   [(parallel [(set (match_dup 0)
8141                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8142               (use (match_dup 2))])]
8144   if (GET_CODE (operands[2]) == SCRATCH)
8145     operands[2] = gen_reg_rtx (V16QImode);
8147   operands[3] = gen_reg_rtx (V16QImode);
8148   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8150   [(set_attr "length" "8")
8151    (set_attr "type" "vecsimple")])
8153 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8154   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8155         (neg:IEEE128
8156          (abs:IEEE128
8157           (match_operand:IEEE128 1 "register_operand" "wa"))))
8158    (use (match_operand:V16QI 2 "register_operand" "v"))]
8159   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8160   "xxlor %x0,%x1,%x2"
8161   [(set_attr "type" "veclogical")])
8163 ;; Float128 conversion functions.  These expand to library function calls.
8164 ;; We use expand to convert from IBM double double to IEEE 128-bit
8165 ;; and trunc for the opposite.
8166 (define_expand "extendiftf2"
8167   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8168         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8169   "TARGET_FLOAT128_TYPE"
8171   rs6000_expand_float128_convert (operands[0], operands[1], false);
8172   DONE;
8175 (define_expand "extendifkf2"
8176   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8177         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8178   "TARGET_FLOAT128_TYPE"
8180   rs6000_expand_float128_convert (operands[0], operands[1], false);
8181   DONE;
8184 (define_expand "extendtfkf2"
8185   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8186         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8187   "TARGET_FLOAT128_TYPE"
8189   rs6000_expand_float128_convert (operands[0], operands[1], false);
8190   DONE;
8193 (define_expand "trunciftf2"
8194   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8195         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8196   "TARGET_FLOAT128_TYPE"
8198   rs6000_expand_float128_convert (operands[0], operands[1], false);
8199   DONE;
8202 (define_expand "truncifkf2"
8203   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8204         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8205   "TARGET_FLOAT128_TYPE"
8207   rs6000_expand_float128_convert (operands[0], operands[1], false);
8208   DONE;
8211 (define_expand "trunckftf2"
8212   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8213         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8214   "TARGET_FLOAT128_TYPE"
8216   rs6000_expand_float128_convert (operands[0], operands[1], false);
8217   DONE;
8220 (define_expand "trunctfif2"
8221   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8222         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8223   "TARGET_FLOAT128_TYPE"
8225   rs6000_expand_float128_convert (operands[0], operands[1], false);
8226   DONE;
8230 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8231 ;; must have 3 arguments, and scratch register constraint must be a single
8232 ;; constraint.
8234 ;; Reload patterns to support gpr load/store with misaligned mem.
8235 ;; and multiple gpr load/store at offset >= 0xfffc
8236 (define_expand "reload_<mode>_store"
8237   [(parallel [(match_operand 0 "memory_operand" "=m")
8238               (match_operand 1 "gpc_reg_operand" "r")
8239               (match_operand:GPR 2 "register_operand" "=&b")])]
8240   ""
8242   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8243   DONE;
8246 (define_expand "reload_<mode>_load"
8247   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8248               (match_operand 1 "memory_operand" "m")
8249               (match_operand:GPR 2 "register_operand" "=b")])]
8250   ""
8252   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8253   DONE;
8257 ;; Reload patterns for various types using the vector registers.  We may need
8258 ;; an additional base register to convert the reg+offset addressing to reg+reg
8259 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8260 ;; index register for gpr registers.
8261 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8262   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8263               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8264               (match_operand:P 2 "register_operand" "=b")])]
8265   "<P:tptrsize>"
8267   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8268   DONE;
8271 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8272   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8273               (match_operand:RELOAD 1 "memory_operand" "m")
8274               (match_operand:P 2 "register_operand" "=b")])]
8275   "<P:tptrsize>"
8277   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8278   DONE;
8282 ;; Reload sometimes tries to move the address to a GPR, and can generate
8283 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8284 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8286 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8287   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8288         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8289                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8290                (const_int -16)))]
8291   "TARGET_ALTIVEC && reload_completed"
8292   "#"
8293   "&& reload_completed"
8294   [(set (match_dup 0)
8295         (plus:P (match_dup 1)
8296                 (match_dup 2)))
8297    (set (match_dup 0)
8298         (and:P (match_dup 0)
8299                (const_int -16)))])
8301 ;; Power8 merge instructions to allow direct move to/from floating point
8302 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8303 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8304 ;; value, since it is allocated in reload and not all of the flow information
8305 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8306 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8307 ;; schedule other instructions between the two instructions.
8309 (define_insn "p8_fmrgow_<mode>"
8310   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8311         (unspec:FMOVE64X [
8312                 (match_operand:DF 1 "register_operand" "d")
8313                 (match_operand:DF 2 "register_operand" "d")]
8314                          UNSPEC_P8V_FMRGOW))]
8315   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8316   "fmrgow %0,%1,%2"
8317   [(set_attr "type" "fpsimple")])
8319 (define_insn "p8_mtvsrwz"
8320   [(set (match_operand:DF 0 "register_operand" "=d")
8321         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8322                    UNSPEC_P8V_MTVSRWZ))]
8323   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8324   "mtvsrwz %x0,%1"
8325   [(set_attr "type" "mftgpr")])
8327 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8328   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8329         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8330                          UNSPEC_P8V_RELOAD_FROM_GPR))
8331    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8332   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8333   "#"
8334   "&& reload_completed"
8335   [(const_int 0)]
8337   rtx dest = operands[0];
8338   rtx src = operands[1];
8339   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8340   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8341   rtx gpr_hi_reg = gen_highpart (SImode, src);
8342   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8344   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8345   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8346   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8347   DONE;
8349   [(set_attr "length" "12")
8350    (set_attr "type" "three")])
8352 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8353 (define_insn "p8_mtvsrd_df"
8354   [(set (match_operand:DF 0 "register_operand" "=wa")
8355         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8356                    UNSPEC_P8V_MTVSRD))]
8357   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8358   "mtvsrd %x0,%1"
8359   [(set_attr "type" "mftgpr")])
8361 (define_insn "p8_xxpermdi_<mode>"
8362   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8363         (unspec:FMOVE128_GPR [
8364                 (match_operand:DF 1 "register_operand" "wa")
8365                 (match_operand:DF 2 "register_operand" "wa")]
8366                 UNSPEC_P8V_XXPERMDI))]
8367   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8368   "xxpermdi %x0,%x1,%x2,0"
8369   [(set_attr "type" "vecperm")])
8371 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8372   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8373         (unspec:FMOVE128_GPR
8374          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8375          UNSPEC_P8V_RELOAD_FROM_GPR))
8376    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8377   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8378   "#"
8379   "&& reload_completed"
8380   [(const_int 0)]
8382   rtx dest = operands[0];
8383   rtx src = operands[1];
8384   /* You might think that we could use op0 as one temp and a DF clobber
8385      as op2, but you'd be wrong.  Secondary reload move patterns don't
8386      check for overlap of the clobber and the destination.  */
8387   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8388   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8389   rtx gpr_hi_reg = gen_highpart (DImode, src);
8390   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8392   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8393   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8394   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8395   DONE;
8397   [(set_attr "length" "12")
8398    (set_attr "type" "three")])
8400 (define_split
8401   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8402         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8403   "reload_completed
8404    && (int_reg_operand (operands[0], <MODE>mode)
8405        || int_reg_operand (operands[1], <MODE>mode))
8406    && (!TARGET_DIRECT_MOVE_128
8407        || (!vsx_register_operand (operands[0], <MODE>mode)
8408            && !vsx_register_operand (operands[1], <MODE>mode)))"
8409   [(pc)]
8410 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8412 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8413 ;; type is stored internally as double precision in the VSX registers, we have
8414 ;; to convert it from the vector format.
8415 (define_insn "p8_mtvsrd_sf"
8416   [(set (match_operand:SF 0 "register_operand" "=wa")
8417         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8418                    UNSPEC_P8V_MTVSRD))]
8419   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8420   "mtvsrd %x0,%1"
8421   [(set_attr "type" "mftgpr")])
8423 (define_insn_and_split "reload_vsx_from_gprsf"
8424   [(set (match_operand:SF 0 "register_operand" "=wa")
8425         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8426                    UNSPEC_P8V_RELOAD_FROM_GPR))
8427    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8428   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8429   "#"
8430   "&& reload_completed"
8431   [(const_int 0)]
8433   rtx op0 = operands[0];
8434   rtx op1 = operands[1];
8435   rtx op2 = operands[2];
8436   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8438   /* Move SF value to upper 32-bits for xscvspdpn.  */
8439   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8440   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8441   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8442   DONE;
8444   [(set_attr "length" "8")
8445    (set_attr "type" "two")])
8447 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8448 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8449 ;; and then doing a move of that.
8450 (define_insn "p8_mfvsrd_3_<mode>"
8451   [(set (match_operand:DF 0 "register_operand" "=r")
8452         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8453                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8454   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8455   "mfvsrd %0,%x1"
8456   [(set_attr "type" "mftgpr")])
8458 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8459   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8460         (unspec:FMOVE128_GPR
8461          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8462          UNSPEC_P8V_RELOAD_FROM_VSX))
8463    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8464   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8465   "#"
8466   "&& reload_completed"
8467   [(const_int 0)]
8469   rtx dest = operands[0];
8470   rtx src = operands[1];
8471   rtx tmp = operands[2];
8472   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8473   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8475   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8476   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8477   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8478   DONE;
8480   [(set_attr "length" "12")
8481    (set_attr "type" "three")])
8483 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8484 ;; type is stored internally as double precision, we have to convert it to the
8485 ;; vector format.
8487 (define_insn_and_split "reload_gpr_from_vsxsf"
8488   [(set (match_operand:SF 0 "register_operand" "=r")
8489         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8490                    UNSPEC_P8V_RELOAD_FROM_VSX))
8491    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8492   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8493   "#"
8494   "&& reload_completed"
8495   [(const_int 0)]
8497   rtx op0 = operands[0];
8498   rtx op1 = operands[1];
8499   rtx op2 = operands[2];
8500   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8501   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8503   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8504   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8505   DONE;
8507   [(set_attr "length" "8")
8508    (set_attr "type" "two")])
8511 ;; Next come the multi-word integer load and store and the load and store
8512 ;; multiple insns.
8514 ;; List r->r after r->Y, otherwise reload will try to reload a
8515 ;; non-offsettable address by using r->r which won't make progress.
8516 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8517 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8519 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8520 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8521 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8522 ;;        AVX const  
8524 (define_insn "*movdi_internal32"
8525   [(set (match_operand:DI 0 "nonimmediate_operand"
8526          "=Y,        r,         r,         ^m,        ^d,         ^d,
8527           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8528           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8529           *wv")
8531         (match_operand:DI 1 "input_operand"
8532           "r,        Y,         r,         d,         m,          d,
8533            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8534            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8535            wB"))]
8537   "! TARGET_POWERPC64
8538    && (gpc_reg_operand (operands[0], DImode)
8539        || gpc_reg_operand (operands[1], DImode))"
8540   "@
8541    #
8542    #
8543    #
8544    stfd%U0%X0 %1,%0
8545    lfd%U1%X1 %0,%1
8546    fmr %0,%1
8547    #
8548    stxsd %1,%0
8549    stxsdx %x1,%y0
8550    lxsd %0,%1
8551    lxsdx %x0,%y1
8552    xxlor %x0,%x1,%x1
8553    xxspltib %x0,0
8554    xxspltib %x0,255
8555    vspltisw %0,%1
8556    xxlxor %x0,%x0,%x0
8557    xxlorc %x0,%x0,%x0
8558    #
8559    #"
8560   [(set_attr "type"
8561                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8562                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8563                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8564                 vecsimple")
8565    (set_attr "size" "64")])
8567 (define_split
8568   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8569         (match_operand:DI 1 "const_int_operand" ""))]
8570   "! TARGET_POWERPC64 && reload_completed
8571    && gpr_or_gpr_p (operands[0], operands[1])
8572    && !direct_move_p (operands[0], operands[1])"
8573   [(set (match_dup 2) (match_dup 4))
8574    (set (match_dup 3) (match_dup 1))]
8575   "
8577   HOST_WIDE_INT value = INTVAL (operands[1]);
8578   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8579                                        DImode);
8580   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8581                                        DImode);
8582   operands[4] = GEN_INT (value >> 32);
8583   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8586 (define_split
8587   [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
8588         (match_operand:DIFD 1 "input_operand" ""))]
8589   "reload_completed && !TARGET_POWERPC64
8590    && gpr_or_gpr_p (operands[0], operands[1])
8591    && !direct_move_p (operands[0], operands[1])"
8592   [(pc)]
8593 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8595 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8596 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8597 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8598 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8599 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8600 (define_insn "*movdi_internal64"
8601   [(set (match_operand:DI 0 "nonimmediate_operand"
8602                "=Y,        r,         r,         r,         r,          r,
8603                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8604                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8605                 *wi,       *wv,       *wv,       r,         *h,         *h,
8606                 ?*r,       ?*wg,      ?*r,       ?*wj")
8608         (match_operand:DI 1 "input_operand"
8609                 "r,        Y,         r,         I,         L,          nF,
8610                  d,        m,         d,         wb,        wv,         wY,
8611                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8612                  wM,       wS,        wB,        *h,        r,          0,
8613                  wg,       r,         wj,        r"))]
8615   "TARGET_POWERPC64
8616    && (gpc_reg_operand (operands[0], DImode)
8617        || gpc_reg_operand (operands[1], DImode))"
8618   "@
8619    std%U0%X0 %1,%0
8620    ld%U1%X1 %0,%1
8621    mr %0,%1
8622    li %0,%1
8623    lis %0,%v1
8624    #
8625    stfd%U0%X0 %1,%0
8626    lfd%U1%X1 %0,%1
8627    fmr %0,%1
8628    stxsd %1,%0
8629    stxsdx %x1,%y0
8630    lxsd %0,%1
8631    lxsdx %x0,%y1
8632    xxlor %x0,%x1,%x1
8633    xxspltib %x0,0
8634    xxspltib %x0,255
8635    #
8636    xxlxor %x0,%x0,%x0
8637    xxlorc %x0,%x0,%x0
8638    #
8639    #
8640    mf%1 %0
8641    mt%0 %1
8642    nop
8643    mftgpr %0,%1
8644    mffgpr %0,%1
8645    mfvsrd %0,%x1
8646    mtvsrd %x0,%1"
8647   [(set_attr "type"
8648                "store,      load,       *,         *,         *,         *,
8649                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8650                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8651                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8652                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8654    (set_attr "size" "64")
8655    (set_attr "length"
8656                "4,         4,         4,         4,         4,          20,
8657                 4,         4,         4,         4,         4,          4,
8658                 4,         4,         4,         4,         4,          8,
8659                 8,         4,         4,         4,         4,          4,
8660                 4,         4,         4,         4")])
8662 ; Some DImode loads are best done as a load of -1 followed by a mask
8663 ; instruction.
8664 (define_split
8665   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8666         (match_operand:DI 1 "const_int_operand"))]
8667   "TARGET_POWERPC64
8668    && num_insns_constant (operands[1], DImode) > 1
8669    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8670    && rs6000_is_valid_and_mask (operands[1], DImode)"
8671   [(set (match_dup 0)
8672         (const_int -1))
8673    (set (match_dup 0)
8674         (and:DI (match_dup 0)
8675                 (match_dup 1)))]
8676   "")
8678 ;; Split a load of a large constant into the appropriate five-instruction
8679 ;; sequence.  Handle anything in a constant number of insns.
8680 ;; When non-easy constants can go in the TOC, this should use
8681 ;; easy_fp_constant predicate.
8682 (define_split
8683   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8684         (match_operand:DI 1 "const_int_operand" ""))]
8685   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8686   [(set (match_dup 0) (match_dup 2))
8687    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8688   "
8690   if (rs6000_emit_set_const (operands[0], operands[1]))
8691     DONE;
8692   else
8693     FAIL;
8696 (define_split
8697   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8698         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8699   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8700   [(set (match_dup 0) (match_dup 2))
8701    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8702   "
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   "*
8769   switch (which_alternative)
8770     {
8771     default:
8772       gcc_unreachable ();
8773     case 0:
8774       if (TARGET_STRING)
8775         return \"stswi %1,%P0,16\";
8776       /* FALLTHRU */
8777     case 1:
8778       return \"#\";
8779     case 2:
8780       /* If the address is not used in the output, we can use lsi.  Otherwise,
8781          fall through to generating four loads.  */
8782       if (TARGET_STRING
8783           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8784         return \"lswi %0,%P1,16\";
8785       /* fall through */
8786     case 3:
8787     case 4:
8788     case 5:
8789       return \"#\";
8790     }
8792   [(set_attr "type" "store,store,load,load,*,*")
8793    (set_attr "update" "yes")
8794    (set_attr "indexed" "yes")
8795    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8796                                           (const_string "always")
8797                                           (const_string "conditional")))])
8799 (define_insn "*mov<mode>_ppc64"
8800   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8801         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8802   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8803    && (gpc_reg_operand (operands[0], <MODE>mode)
8804        || gpc_reg_operand (operands[1], <MODE>mode)))"
8806   return rs6000_output_move_128bit (operands);
8808   [(set_attr "type" "store,store,load,load,*,*")
8809    (set_attr "length" "8")])
8811 (define_split
8812   [(set (match_operand:TI2 0 "int_reg_operand" "")
8813         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8814   "TARGET_POWERPC64
8815    && (VECTOR_MEM_NONE_P (<MODE>mode)
8816        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8817   [(set (match_dup 2) (match_dup 4))
8818    (set (match_dup 3) (match_dup 5))]
8819   "
8821   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8822                                        <MODE>mode);
8823   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8824                                        <MODE>mode);
8825   if (CONST_WIDE_INT_P (operands[1]))
8826     {
8827       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8828       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8829     }
8830   else if (CONST_INT_P (operands[1]))
8831     {
8832       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8833       operands[5] = operands[1];
8834     }
8835   else
8836     FAIL;
8839 (define_split
8840   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8841         (match_operand:TI2 1 "input_operand" ""))]
8842   "reload_completed
8843    && gpr_or_gpr_p (operands[0], operands[1])
8844    && !direct_move_p (operands[0], operands[1])
8845    && !quad_load_store_p (operands[0], operands[1])"
8846   [(pc)]
8847 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8849 (define_expand "load_multiple"
8850   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8851                           (match_operand:SI 1 "" ""))
8852                      (use (match_operand:SI 2 "" ""))])]
8853   "TARGET_STRING && !TARGET_POWERPC64"
8854   "
8856   int regno;
8857   int count;
8858   rtx op1;
8859   int i;
8861   /* Support only loading a constant number of fixed-point registers from
8862      memory and only bother with this if more than two; the machine
8863      doesn't support more than eight.  */
8864   if (GET_CODE (operands[2]) != CONST_INT
8865       || INTVAL (operands[2]) <= 2
8866       || INTVAL (operands[2]) > 8
8867       || GET_CODE (operands[1]) != MEM
8868       || GET_CODE (operands[0]) != REG
8869       || REGNO (operands[0]) >= 32)
8870     FAIL;
8872   count = INTVAL (operands[2]);
8873   regno = REGNO (operands[0]);
8875   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8876   op1 = replace_equiv_address (operands[1],
8877                                force_reg (SImode, XEXP (operands[1], 0)));
8879   for (i = 0; i < count; i++)
8880     XVECEXP (operands[3], 0, i)
8881       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8882                      adjust_address_nv (op1, SImode, i * 4));
8885 (define_insn "*ldmsi8"
8886   [(match_parallel 0 "load_multiple_operation"
8887     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8888           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8889      (set (match_operand:SI 3 "gpc_reg_operand" "")
8890           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8891      (set (match_operand:SI 4 "gpc_reg_operand" "")
8892           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8893      (set (match_operand:SI 5 "gpc_reg_operand" "")
8894           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8895      (set (match_operand:SI 6 "gpc_reg_operand" "")
8896           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8897      (set (match_operand:SI 7 "gpc_reg_operand" "")
8898           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8899      (set (match_operand:SI 8 "gpc_reg_operand" "")
8900           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8901      (set (match_operand:SI 9 "gpc_reg_operand" "")
8902           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8903   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8904   "*
8905 { return rs6000_output_load_multiple (operands); }"
8906   [(set_attr "type" "load")
8907    (set_attr "update" "yes")
8908    (set_attr "indexed" "yes")
8909    (set_attr "length" "32")])
8911 (define_insn "*ldmsi7"
8912   [(match_parallel 0 "load_multiple_operation"
8913     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8914           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8915      (set (match_operand:SI 3 "gpc_reg_operand" "")
8916           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8917      (set (match_operand:SI 4 "gpc_reg_operand" "")
8918           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8919      (set (match_operand:SI 5 "gpc_reg_operand" "")
8920           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8921      (set (match_operand:SI 6 "gpc_reg_operand" "")
8922           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8923      (set (match_operand:SI 7 "gpc_reg_operand" "")
8924           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8925      (set (match_operand:SI 8 "gpc_reg_operand" "")
8926           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8927   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8928   "*
8929 { return rs6000_output_load_multiple (operands); }"
8930   [(set_attr "type" "load")
8931    (set_attr "update" "yes")
8932    (set_attr "indexed" "yes")
8933    (set_attr "length" "32")])
8935 (define_insn "*ldmsi6"
8936   [(match_parallel 0 "load_multiple_operation"
8937     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8938           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8939      (set (match_operand:SI 3 "gpc_reg_operand" "")
8940           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8941      (set (match_operand:SI 4 "gpc_reg_operand" "")
8942           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8943      (set (match_operand:SI 5 "gpc_reg_operand" "")
8944           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8945      (set (match_operand:SI 6 "gpc_reg_operand" "")
8946           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8947      (set (match_operand:SI 7 "gpc_reg_operand" "")
8948           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8949   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8950   "*
8951 { return rs6000_output_load_multiple (operands); }"
8952   [(set_attr "type" "load")
8953    (set_attr "update" "yes")
8954    (set_attr "indexed" "yes")
8955    (set_attr "length" "32")])
8957 (define_insn "*ldmsi5"
8958   [(match_parallel 0 "load_multiple_operation"
8959     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8960           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8961      (set (match_operand:SI 3 "gpc_reg_operand" "")
8962           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8963      (set (match_operand:SI 4 "gpc_reg_operand" "")
8964           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8965      (set (match_operand:SI 5 "gpc_reg_operand" "")
8966           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8967      (set (match_operand:SI 6 "gpc_reg_operand" "")
8968           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8969   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8970   "*
8971 { return rs6000_output_load_multiple (operands); }"
8972   [(set_attr "type" "load")
8973    (set_attr "update" "yes")
8974    (set_attr "indexed" "yes")
8975    (set_attr "length" "32")])
8977 (define_insn "*ldmsi4"
8978   [(match_parallel 0 "load_multiple_operation"
8979     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8980           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8981      (set (match_operand:SI 3 "gpc_reg_operand" "")
8982           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8983      (set (match_operand:SI 4 "gpc_reg_operand" "")
8984           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8985      (set (match_operand:SI 5 "gpc_reg_operand" "")
8986           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8987   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8988   "*
8989 { return rs6000_output_load_multiple (operands); }"
8990   [(set_attr "type" "load")
8991    (set_attr "update" "yes")
8992    (set_attr "indexed" "yes")
8993    (set_attr "length" "32")])
8995 (define_insn "*ldmsi3"
8996   [(match_parallel 0 "load_multiple_operation"
8997     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8998           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8999      (set (match_operand:SI 3 "gpc_reg_operand" "")
9000           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9001      (set (match_operand:SI 4 "gpc_reg_operand" "")
9002           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9003   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9004   "*
9005 { return rs6000_output_load_multiple (operands); }"
9006   [(set_attr "type" "load")
9007    (set_attr "update" "yes")
9008    (set_attr "indexed" "yes")
9009    (set_attr "length" "32")])
9011 (define_expand "store_multiple"
9012   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9013                           (match_operand:SI 1 "" ""))
9014                      (clobber (scratch:SI))
9015                      (use (match_operand:SI 2 "" ""))])]
9016   "TARGET_STRING && !TARGET_POWERPC64"
9017   "
9019   int regno;
9020   int count;
9021   rtx to;
9022   rtx op0;
9023   int i;
9025   /* Support only storing a constant number of fixed-point registers to
9026      memory and only bother with this if more than two; the machine
9027      doesn't support more than eight.  */
9028   if (GET_CODE (operands[2]) != CONST_INT
9029       || INTVAL (operands[2]) <= 2
9030       || INTVAL (operands[2]) > 8
9031       || GET_CODE (operands[0]) != MEM
9032       || GET_CODE (operands[1]) != REG
9033       || REGNO (operands[1]) >= 32)
9034     FAIL;
9036   count = INTVAL (operands[2]);
9037   regno = REGNO (operands[1]);
9039   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9040   to = force_reg (SImode, XEXP (operands[0], 0));
9041   op0 = replace_equiv_address (operands[0], to);
9043   XVECEXP (operands[3], 0, 0)
9044     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9045   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9046                                                  gen_rtx_SCRATCH (SImode));
9048   for (i = 1; i < count; i++)
9049     XVECEXP (operands[3], 0, i + 1)
9050       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9051                      gen_rtx_REG (SImode, regno + i));
9054 (define_insn "*stmsi8"
9055   [(match_parallel 0 "store_multiple_operation"
9056     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9057           (match_operand:SI 2 "gpc_reg_operand" "r"))
9058      (clobber (match_scratch:SI 3 "=X"))
9059      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9060           (match_operand:SI 4 "gpc_reg_operand" "r"))
9061      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9062           (match_operand:SI 5 "gpc_reg_operand" "r"))
9063      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9064           (match_operand:SI 6 "gpc_reg_operand" "r"))
9065      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9066           (match_operand:SI 7 "gpc_reg_operand" "r"))
9067      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9068           (match_operand:SI 8 "gpc_reg_operand" "r"))
9069      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9070           (match_operand:SI 9 "gpc_reg_operand" "r"))
9071      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9072           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9073   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9074   "stswi %2,%1,%O0"
9075   [(set_attr "type" "store")
9076    (set_attr "update" "yes")
9077    (set_attr "indexed" "yes")
9078    (set_attr "cell_micro" "always")])
9080 (define_insn "*stmsi7"
9081   [(match_parallel 0 "store_multiple_operation"
9082     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9083           (match_operand:SI 2 "gpc_reg_operand" "r"))
9084      (clobber (match_scratch:SI 3 "=X"))
9085      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9086           (match_operand:SI 4 "gpc_reg_operand" "r"))
9087      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9088           (match_operand:SI 5 "gpc_reg_operand" "r"))
9089      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9090           (match_operand:SI 6 "gpc_reg_operand" "r"))
9091      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9092           (match_operand:SI 7 "gpc_reg_operand" "r"))
9093      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9094           (match_operand:SI 8 "gpc_reg_operand" "r"))
9095      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9096           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9097   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9098   "stswi %2,%1,%O0"
9099   [(set_attr "type" "store")
9100    (set_attr "update" "yes")
9101    (set_attr "indexed" "yes")
9102    (set_attr "cell_micro" "always")])
9104 (define_insn "*stmsi6"
9105   [(match_parallel 0 "store_multiple_operation"
9106     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9107           (match_operand:SI 2 "gpc_reg_operand" "r"))
9108      (clobber (match_scratch:SI 3 "=X"))
9109      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9110           (match_operand:SI 4 "gpc_reg_operand" "r"))
9111      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9112           (match_operand:SI 5 "gpc_reg_operand" "r"))
9113      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9114           (match_operand:SI 6 "gpc_reg_operand" "r"))
9115      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9116           (match_operand:SI 7 "gpc_reg_operand" "r"))
9117      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9118           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9119   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9120   "stswi %2,%1,%O0"
9121   [(set_attr "type" "store")
9122    (set_attr "update" "yes")
9123    (set_attr "indexed" "yes")
9124    (set_attr "cell_micro" "always")])
9126 (define_insn "*stmsi5"
9127   [(match_parallel 0 "store_multiple_operation"
9128     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9129           (match_operand:SI 2 "gpc_reg_operand" "r"))
9130      (clobber (match_scratch:SI 3 "=X"))
9131      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9132           (match_operand:SI 4 "gpc_reg_operand" "r"))
9133      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9134           (match_operand:SI 5 "gpc_reg_operand" "r"))
9135      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9136           (match_operand:SI 6 "gpc_reg_operand" "r"))
9137      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9138           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9139   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9140   "stswi %2,%1,%O0"
9141   [(set_attr "type" "store")
9142    (set_attr "update" "yes")
9143    (set_attr "indexed" "yes")
9144    (set_attr "cell_micro" "always")])
9146 (define_insn "*stmsi4"
9147   [(match_parallel 0 "store_multiple_operation"
9148     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9149           (match_operand:SI 2 "gpc_reg_operand" "r"))
9150      (clobber (match_scratch:SI 3 "=X"))
9151      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9152           (match_operand:SI 4 "gpc_reg_operand" "r"))
9153      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9154           (match_operand:SI 5 "gpc_reg_operand" "r"))
9155      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9156           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9157   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9158   "stswi %2,%1,%O0"
9159   [(set_attr "type" "store")
9160    (set_attr "update" "yes")
9161    (set_attr "indexed" "yes")
9162    (set_attr "cell_micro" "always")])
9164 (define_insn "*stmsi3"
9165   [(match_parallel 0 "store_multiple_operation"
9166     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9167           (match_operand:SI 2 "gpc_reg_operand" "r"))
9168      (clobber (match_scratch:SI 3 "=X"))
9169      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9170           (match_operand:SI 4 "gpc_reg_operand" "r"))
9171      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9172           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9173   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9174   "stswi %2,%1,%O0"
9175   [(set_attr "type" "store")
9176    (set_attr "update" "yes")
9177    (set_attr "indexed" "yes")
9178    (set_attr "cell_micro" "always")])
9180 (define_expand "setmemsi"
9181   [(parallel [(set (match_operand:BLK 0 "" "")
9182                    (match_operand 2 "const_int_operand" ""))
9183               (use (match_operand:SI 1 "" ""))
9184               (use (match_operand:SI 3 "" ""))])]
9185   ""
9186   "
9188   /* If value to set is not zero, use the library routine.  */
9189   if (operands[2] != const0_rtx)
9190     FAIL;
9192   if (expand_block_clear (operands))
9193     DONE;
9194   else
9195     FAIL;
9198 ;; String compare N insn.
9199 ;; Argument 0 is the target (result)
9200 ;; Argument 1 is the destination
9201 ;; Argument 2 is the source
9202 ;; Argument 3 is the length
9203 ;; Argument 4 is the alignment
9205 (define_expand "cmpstrnsi"
9206   [(parallel [(set (match_operand:SI 0)
9207                (compare:SI (match_operand:BLK 1)
9208                            (match_operand:BLK 2)))
9209               (use (match_operand:SI 3))
9210               (use (match_operand:SI 4))])]
9211   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9213   if (optimize_insn_for_size_p ())
9214     FAIL;
9216   if (expand_strn_compare (operands, 0))
9217     DONE;
9218   else  
9219     FAIL;
9222 ;; String compare insn.
9223 ;; Argument 0 is the target (result)
9224 ;; Argument 1 is the destination
9225 ;; Argument 2 is the source
9226 ;; Argument 3 is the alignment
9228 (define_expand "cmpstrsi"
9229   [(parallel [(set (match_operand:SI 0)
9230                (compare:SI (match_operand:BLK 1)
9231                            (match_operand:BLK 2)))
9232               (use (match_operand:SI 3))])]
9233   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9235   if (optimize_insn_for_size_p ())
9236     FAIL;
9238   if (expand_strn_compare (operands, 1))
9239     DONE;
9240   else  
9241     FAIL;
9244 ;; Block compare insn.
9245 ;; Argument 0 is the target (result)
9246 ;; Argument 1 is the destination
9247 ;; Argument 2 is the source
9248 ;; Argument 3 is the length
9249 ;; Argument 4 is the alignment
9251 (define_expand "cmpmemsi"
9252   [(parallel [(set (match_operand:SI 0)
9253                (compare:SI (match_operand:BLK 1)
9254                            (match_operand:BLK 2)))
9255               (use (match_operand:SI 3))
9256               (use (match_operand:SI 4))])]
9257   "TARGET_POPCNTD"
9259   if (expand_block_compare (operands))
9260     DONE;
9261   else
9262     FAIL;
9265 ;; String/block move insn.
9266 ;; Argument 0 is the destination
9267 ;; Argument 1 is the source
9268 ;; Argument 2 is the length
9269 ;; Argument 3 is the alignment
9271 (define_expand "movmemsi"
9272   [(parallel [(set (match_operand:BLK 0 "" "")
9273                    (match_operand:BLK 1 "" ""))
9274               (use (match_operand:SI 2 "" ""))
9275               (use (match_operand:SI 3 "" ""))])]
9276   ""
9277   "
9279   if (expand_block_move (operands))
9280     DONE;
9281   else
9282     FAIL;
9285 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9286 ;; register allocator doesn't have a clue about allocating 8 word registers.
9287 ;; rD/rS = r5 is preferred, efficient form.
9288 (define_expand "movmemsi_8reg"
9289   [(parallel [(set (match_operand 0 "" "")
9290                    (match_operand 1 "" ""))
9291               (use (match_operand 2 "" ""))
9292               (use (match_operand 3 "" ""))
9293               (clobber (reg:SI  5))
9294               (clobber (reg:SI  6))
9295               (clobber (reg:SI  7))
9296               (clobber (reg:SI  8))
9297               (clobber (reg:SI  9))
9298               (clobber (reg:SI 10))
9299               (clobber (reg:SI 11))
9300               (clobber (reg:SI 12))
9301               (clobber (match_scratch:SI 4 ""))])]
9302   "TARGET_STRING"
9303   "")
9305 (define_insn ""
9306   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9307         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9308    (use (match_operand:SI 2 "immediate_operand" "i"))
9309    (use (match_operand:SI 3 "immediate_operand" "i"))
9310    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9311    (clobber (reg:SI  6))
9312    (clobber (reg:SI  7))
9313    (clobber (reg:SI  8))
9314    (clobber (reg:SI  9))
9315    (clobber (reg:SI 10))
9316    (clobber (reg:SI 11))
9317    (clobber (reg:SI 12))
9318    (clobber (match_scratch:SI 5 "=X"))]
9319   "TARGET_STRING
9320    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9321        || INTVAL (operands[2]) == 0)
9322    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9323    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9324    && REGNO (operands[4]) == 5"
9325   "lswi %4,%1,%2\;stswi %4,%0,%2"
9326   [(set_attr "type" "store")
9327    (set_attr "update" "yes")
9328    (set_attr "indexed" "yes")
9329    (set_attr "cell_micro" "always")
9330    (set_attr "length" "8")])
9332 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9333 ;; register allocator doesn't have a clue about allocating 6 word registers.
9334 ;; rD/rS = r5 is preferred, efficient form.
9335 (define_expand "movmemsi_6reg"
9336   [(parallel [(set (match_operand 0 "" "")
9337                    (match_operand 1 "" ""))
9338               (use (match_operand 2 "" ""))
9339               (use (match_operand 3 "" ""))
9340               (clobber (reg:SI  5))
9341               (clobber (reg:SI  6))
9342               (clobber (reg:SI  7))
9343               (clobber (reg:SI  8))
9344               (clobber (reg:SI  9))
9345               (clobber (reg:SI 10))
9346               (clobber (match_scratch:SI 4 ""))])]
9347   "TARGET_STRING"
9348   "")
9350 (define_insn ""
9351   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9352         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9353    (use (match_operand:SI 2 "immediate_operand" "i"))
9354    (use (match_operand:SI 3 "immediate_operand" "i"))
9355    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9356    (clobber (reg:SI  6))
9357    (clobber (reg:SI  7))
9358    (clobber (reg:SI  8))
9359    (clobber (reg:SI  9))
9360    (clobber (reg:SI 10))
9361    (clobber (match_scratch:SI 5 "=X"))]
9362   "TARGET_STRING
9363    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9364    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9365    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9366    && REGNO (operands[4]) == 5"
9367   "lswi %4,%1,%2\;stswi %4,%0,%2"
9368   [(set_attr "type" "store")
9369    (set_attr "update" "yes")
9370    (set_attr "indexed" "yes")
9371    (set_attr "cell_micro" "always")
9372    (set_attr "length" "8")])
9374 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9375 ;; problems with TImode.
9376 ;; rD/rS = r5 is preferred, efficient form.
9377 (define_expand "movmemsi_4reg"
9378   [(parallel [(set (match_operand 0 "" "")
9379                    (match_operand 1 "" ""))
9380               (use (match_operand 2 "" ""))
9381               (use (match_operand 3 "" ""))
9382               (clobber (reg:SI 5))
9383               (clobber (reg:SI 6))
9384               (clobber (reg:SI 7))
9385               (clobber (reg:SI 8))
9386               (clobber (match_scratch:SI 4 ""))])]
9387   "TARGET_STRING"
9388   "")
9390 (define_insn ""
9391   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9392         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9393    (use (match_operand:SI 2 "immediate_operand" "i"))
9394    (use (match_operand:SI 3 "immediate_operand" "i"))
9395    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9396    (clobber (reg:SI 6))
9397    (clobber (reg:SI 7))
9398    (clobber (reg:SI 8))
9399    (clobber (match_scratch:SI 5 "=X"))]
9400   "TARGET_STRING
9401    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9402    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9403    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9404    && REGNO (operands[4]) == 5"
9405   "lswi %4,%1,%2\;stswi %4,%0,%2"
9406   [(set_attr "type" "store")
9407    (set_attr "update" "yes")
9408    (set_attr "indexed" "yes")
9409    (set_attr "cell_micro" "always")
9410    (set_attr "length" "8")])
9412 ;; Move up to 8 bytes at a time.
9413 (define_expand "movmemsi_2reg"
9414   [(parallel [(set (match_operand 0 "" "")
9415                    (match_operand 1 "" ""))
9416               (use (match_operand 2 "" ""))
9417               (use (match_operand 3 "" ""))
9418               (clobber (match_scratch:DI 4 ""))
9419               (clobber (match_scratch:SI 5 ""))])]
9420   "TARGET_STRING && ! TARGET_POWERPC64"
9421   "")
9423 (define_insn ""
9424   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9425         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9426    (use (match_operand:SI 2 "immediate_operand" "i"))
9427    (use (match_operand:SI 3 "immediate_operand" "i"))
9428    (clobber (match_scratch:DI 4 "=&r"))
9429    (clobber (match_scratch:SI 5 "=X"))]
9430   "TARGET_STRING && ! TARGET_POWERPC64
9431    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9432   "lswi %4,%1,%2\;stswi %4,%0,%2"
9433   [(set_attr "type" "store")
9434    (set_attr "update" "yes")
9435    (set_attr "indexed" "yes")
9436    (set_attr "cell_micro" "always")
9437    (set_attr "length" "8")])
9439 ;; Move up to 4 bytes at a time.
9440 (define_expand "movmemsi_1reg"
9441   [(parallel [(set (match_operand 0 "" "")
9442                    (match_operand 1 "" ""))
9443               (use (match_operand 2 "" ""))
9444               (use (match_operand 3 "" ""))
9445               (clobber (match_scratch:SI 4 ""))
9446               (clobber (match_scratch:SI 5 ""))])]
9447   "TARGET_STRING"
9448   "")
9450 (define_insn ""
9451   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9452         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9453    (use (match_operand:SI 2 "immediate_operand" "i"))
9454    (use (match_operand:SI 3 "immediate_operand" "i"))
9455    (clobber (match_scratch:SI 4 "=&r"))
9456    (clobber (match_scratch:SI 5 "=X"))]
9457   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9458   "lswi %4,%1,%2\;stswi %4,%0,%2"
9459   [(set_attr "type" "store")
9460    (set_attr "update" "yes")
9461    (set_attr "indexed" "yes")
9462    (set_attr "cell_micro" "always")
9463    (set_attr "length" "8")])
9465 ;; Define insns that do load or store with update.  Some of these we can
9466 ;; get by using pre-decrement or pre-increment, but the hardware can also
9467 ;; do cases where the increment is not the size of the object.
9469 ;; In all these cases, we use operands 0 and 1 for the register being
9470 ;; incremented because those are the operands that local-alloc will
9471 ;; tie and these are the pair most likely to be tieable (and the ones
9472 ;; that will benefit the most).
9474 (define_insn "*movdi_update1"
9475   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9476         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9477                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9478    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9479         (plus:DI (match_dup 1) (match_dup 2)))]
9480   "TARGET_POWERPC64 && TARGET_UPDATE
9481    && (!avoiding_indexed_address_p (DImode)
9482        || !gpc_reg_operand (operands[2], DImode))"
9483   "@
9484    ldux %3,%0,%2
9485    ldu %3,%2(%0)"
9486   [(set_attr "type" "load")
9487    (set_attr "update" "yes")
9488    (set_attr "indexed" "yes,no")])
9490 (define_insn "movdi_<mode>_update"
9491   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9492                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9493         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9494    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9495         (plus:P (match_dup 1) (match_dup 2)))]
9496   "TARGET_POWERPC64 && TARGET_UPDATE
9497    && (!avoiding_indexed_address_p (Pmode)
9498        || !gpc_reg_operand (operands[2], Pmode)
9499        || (REG_P (operands[0])
9500            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9501   "@
9502    stdux %3,%0,%2
9503    stdu %3,%2(%0)"
9504   [(set_attr "type" "store")
9505    (set_attr "update" "yes")
9506    (set_attr "indexed" "yes,no")])
9508 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9509 ;; needed for stack allocation, even if the user passes -mno-update.
9510 (define_insn "movdi_<mode>_update_stack"
9511   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9512                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9513         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9514    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9515         (plus:P (match_dup 1) (match_dup 2)))]
9516   "TARGET_POWERPC64"
9517   "@
9518    stdux %3,%0,%2
9519    stdu %3,%2(%0)"
9520   [(set_attr "type" "store")
9521    (set_attr "update" "yes")
9522    (set_attr "indexed" "yes,no")])
9524 (define_insn "*movsi_update1"
9525   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9526         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9527                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9528    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9529         (plus:SI (match_dup 1) (match_dup 2)))]
9530   "TARGET_UPDATE
9531    && (!avoiding_indexed_address_p (SImode)
9532        || !gpc_reg_operand (operands[2], SImode))"
9533   "@
9534    lwzux %3,%0,%2
9535    lwzu %3,%2(%0)"
9536   [(set_attr "type" "load")
9537    (set_attr "update" "yes")
9538    (set_attr "indexed" "yes,no")])
9540 (define_insn "*movsi_update2"
9541   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9542         (sign_extend:DI
9543          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9544                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9545    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9546         (plus:DI (match_dup 1) (match_dup 2)))]
9547   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9548   "lwaux %3,%0,%2"
9549   [(set_attr "type" "load")
9550    (set_attr "sign_extend" "yes")
9551    (set_attr "update" "yes")
9552    (set_attr "indexed" "yes")])
9554 (define_insn "movsi_update"
9555   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9556                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9557         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9558    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9559         (plus:SI (match_dup 1) (match_dup 2)))]
9560   "TARGET_UPDATE
9561    && (!avoiding_indexed_address_p (SImode)
9562        || !gpc_reg_operand (operands[2], SImode)
9563        || (REG_P (operands[0])
9564            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9565   "@
9566    stwux %3,%0,%2
9567    stwu %3,%2(%0)"
9568   [(set_attr "type" "store")
9569    (set_attr "update" "yes")
9570    (set_attr "indexed" "yes,no")])
9572 ;; This is an unconditional pattern; needed for stack allocation, even
9573 ;; if the user passes -mno-update.
9574 (define_insn "movsi_update_stack"
9575   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9576                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9577         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9578    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9579         (plus:SI (match_dup 1) (match_dup 2)))]
9580   ""
9581   "@
9582    stwux %3,%0,%2
9583    stwu %3,%2(%0)"
9584   [(set_attr "type" "store")
9585    (set_attr "update" "yes")
9586    (set_attr "indexed" "yes,no")])
9588 (define_insn "*movhi_update1"
9589   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9590         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9591                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9592    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9593         (plus:SI (match_dup 1) (match_dup 2)))]
9594   "TARGET_UPDATE
9595    && (!avoiding_indexed_address_p (SImode)
9596        || !gpc_reg_operand (operands[2], SImode))"
9597   "@
9598    lhzux %3,%0,%2
9599    lhzu %3,%2(%0)"
9600   [(set_attr "type" "load")
9601    (set_attr "update" "yes")
9602    (set_attr "indexed" "yes,no")])
9604 (define_insn "*movhi_update2"
9605   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9606         (zero_extend:SI
9607          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9608                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9609    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9610         (plus:SI (match_dup 1) (match_dup 2)))]
9611   "TARGET_UPDATE
9612    && (!avoiding_indexed_address_p (SImode)
9613        || !gpc_reg_operand (operands[2], SImode))"
9614   "@
9615    lhzux %3,%0,%2
9616    lhzu %3,%2(%0)"
9617   [(set_attr "type" "load")
9618    (set_attr "update" "yes")
9619    (set_attr "indexed" "yes,no")])
9621 (define_insn "*movhi_update3"
9622   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9623         (sign_extend:SI
9624          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9625                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9626    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9627         (plus:SI (match_dup 1) (match_dup 2)))]
9628   "TARGET_UPDATE
9629    && !(avoiding_indexed_address_p (SImode)
9630         && gpc_reg_operand (operands[2], SImode))"
9631   "@
9632    lhaux %3,%0,%2
9633    lhau %3,%2(%0)"
9634   [(set_attr "type" "load")
9635    (set_attr "sign_extend" "yes")
9636    (set_attr "update" "yes")
9637    (set_attr "indexed" "yes,no")])
9639 (define_insn "*movhi_update4"
9640   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9641                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9642         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9643    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9644         (plus:SI (match_dup 1) (match_dup 2)))]
9645   "TARGET_UPDATE
9646    && (!avoiding_indexed_address_p (SImode)
9647        || !gpc_reg_operand (operands[2], SImode))"
9648   "@
9649    sthux %3,%0,%2
9650    sthu %3,%2(%0)"
9651   [(set_attr "type" "store")
9652    (set_attr "update" "yes")
9653    (set_attr "indexed" "yes,no")])
9655 (define_insn "*movqi_update1"
9656   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9657         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9658                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9659    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9660         (plus:SI (match_dup 1) (match_dup 2)))]
9661   "TARGET_UPDATE
9662    && (!avoiding_indexed_address_p (SImode)
9663        || !gpc_reg_operand (operands[2], SImode))"
9664   "@
9665    lbzux %3,%0,%2
9666    lbzu %3,%2(%0)"
9667   [(set_attr "type" "load")
9668    (set_attr "update" "yes")
9669    (set_attr "indexed" "yes,no")])
9671 (define_insn "*movqi_update2"
9672   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9673         (zero_extend:SI
9674          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9675                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9676    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9677         (plus:SI (match_dup 1) (match_dup 2)))]
9678   "TARGET_UPDATE
9679    && (!avoiding_indexed_address_p (SImode)
9680        || !gpc_reg_operand (operands[2], SImode))"
9681   "@
9682    lbzux %3,%0,%2
9683    lbzu %3,%2(%0)"
9684   [(set_attr "type" "load")
9685    (set_attr "update" "yes")
9686    (set_attr "indexed" "yes,no")])
9688 (define_insn "*movqi_update3"
9689   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9690                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9691         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9692    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9693         (plus:SI (match_dup 1) (match_dup 2)))]
9694   "TARGET_UPDATE
9695    && (!avoiding_indexed_address_p (SImode)
9696        || !gpc_reg_operand (operands[2], SImode))"
9697   "@
9698    stbux %3,%0,%2
9699    stbu %3,%2(%0)"
9700   [(set_attr "type" "store")
9701    (set_attr "update" "yes")
9702    (set_attr "indexed" "yes,no")])
9704 (define_insn "*movsf_update1"
9705   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9706         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9707                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9708    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9709         (plus:SI (match_dup 1) (match_dup 2)))]
9710   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9711    && (!avoiding_indexed_address_p (SImode)
9712        || !gpc_reg_operand (operands[2], SImode))"
9713   "@
9714    lfsux %3,%0,%2
9715    lfsu %3,%2(%0)"
9716   [(set_attr "type" "fpload")
9717    (set_attr "update" "yes")
9718    (set_attr "indexed" "yes,no")])
9720 (define_insn "*movsf_update2"
9721   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9722                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9723         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9724    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9725         (plus:SI (match_dup 1) (match_dup 2)))]
9726   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9727    && (!avoiding_indexed_address_p (SImode)
9728        || !gpc_reg_operand (operands[2], SImode))"
9729   "@
9730    stfsux %3,%0,%2
9731    stfsu %3,%2(%0)"
9732   [(set_attr "type" "fpstore")
9733    (set_attr "update" "yes")
9734    (set_attr "indexed" "yes,no")])
9736 (define_insn "*movsf_update3"
9737   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9738         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9739                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9740    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9741         (plus:SI (match_dup 1) (match_dup 2)))]
9742   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9743    && (!avoiding_indexed_address_p (SImode)
9744        || !gpc_reg_operand (operands[2], SImode))"
9745   "@
9746    lwzux %3,%0,%2
9747    lwzu %3,%2(%0)"
9748   [(set_attr "type" "load")
9749    (set_attr "update" "yes")
9750    (set_attr "indexed" "yes,no")])
9752 (define_insn "*movsf_update4"
9753   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9754                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9755         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9756    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9757         (plus:SI (match_dup 1) (match_dup 2)))]
9758   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9759    && (!avoiding_indexed_address_p (SImode)
9760        || !gpc_reg_operand (operands[2], SImode))"
9761   "@
9762    stwux %3,%0,%2
9763    stwu %3,%2(%0)"
9764   [(set_attr "type" "store")
9765    (set_attr "update" "yes")
9766    (set_attr "indexed" "yes,no")])
9768 (define_insn "*movdf_update1"
9769   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9770         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9771                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9772    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9773         (plus:SI (match_dup 1) (match_dup 2)))]
9774   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9775    && (!avoiding_indexed_address_p (SImode)
9776        || !gpc_reg_operand (operands[2], SImode))"
9777   "@
9778    lfdux %3,%0,%2
9779    lfdu %3,%2(%0)"
9780   [(set_attr "type" "fpload")
9781    (set_attr "update" "yes")
9782    (set_attr "indexed" "yes,no")
9783    (set_attr "size" "64")])
9785 (define_insn "*movdf_update2"
9786   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9787                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9788         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9789    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9790         (plus:SI (match_dup 1) (match_dup 2)))]
9791   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9792    && (!avoiding_indexed_address_p (SImode)
9793        || !gpc_reg_operand (operands[2], SImode))"
9794   "@
9795    stfdux %3,%0,%2
9796    stfdu %3,%2(%0)"
9797   [(set_attr "type" "fpstore")
9798    (set_attr "update" "yes")
9799    (set_attr "indexed" "yes,no")])
9802 ;; After inserting conditional returns we can sometimes have
9803 ;; unnecessary register moves.  Unfortunately we cannot have a
9804 ;; modeless peephole here, because some single SImode sets have early
9805 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9806 ;; sequences, using get_attr_length here will smash the operands
9807 ;; array.  Neither is there an early_cobbler_p predicate.
9808 ;; Also this optimization interferes with scalars going into
9809 ;; altivec registers (the code does reloading through the FPRs).
9810 (define_peephole2
9811   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9812         (match_operand:DF 1 "any_operand" ""))
9813    (set (match_operand:DF 2 "gpc_reg_operand" "")
9814         (match_dup 0))]
9815   "!TARGET_VSX
9816    && peep2_reg_dead_p (2, operands[0])"
9817   [(set (match_dup 2) (match_dup 1))])
9819 (define_peephole2
9820   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9821         (match_operand:SF 1 "any_operand" ""))
9822    (set (match_operand:SF 2 "gpc_reg_operand" "")
9823         (match_dup 0))]
9824   "!TARGET_P8_VECTOR
9825    && peep2_reg_dead_p (2, operands[0])"
9826   [(set (match_dup 2) (match_dup 1))])
9829 ;; TLS support.
9831 ;; Mode attributes for different ABIs.
9832 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9833 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9834 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9835 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9837 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9838   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9839         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9840               (match_operand 4 "" "g")))
9841    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9842                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9843                    UNSPEC_TLSGD)
9844    (clobber (reg:SI LR_REGNO))]
9845   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9847   if (TARGET_CMODEL != CMODEL_SMALL)
9848     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9849            "bl %z3\;nop";
9850   else
9851     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9853   "&& TARGET_TLS_MARKERS"
9854   [(set (match_dup 0)
9855         (unspec:TLSmode [(match_dup 1)
9856                          (match_dup 2)]
9857                         UNSPEC_TLSGD))
9858    (parallel [(set (match_dup 0)
9859                    (call (mem:TLSmode (match_dup 3))
9860                          (match_dup 4)))
9861               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9862               (clobber (reg:SI LR_REGNO))])]
9863   ""
9864   [(set_attr "type" "two")
9865    (set (attr "length")
9866      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9867                    (const_int 16)
9868                    (const_int 12)))])
9870 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9871   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9872         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9873               (match_operand 4 "" "g")))
9874    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9875                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9876                    UNSPEC_TLSGD)
9877    (clobber (reg:SI LR_REGNO))]
9878   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9880   if (flag_pic)
9881     {
9882       if (TARGET_SECURE_PLT && flag_pic == 2)
9883         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9884       else
9885         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9886     }
9887   else
9888     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9890   "&& TARGET_TLS_MARKERS"
9891   [(set (match_dup 0)
9892         (unspec:TLSmode [(match_dup 1)
9893                          (match_dup 2)]
9894                         UNSPEC_TLSGD))
9895    (parallel [(set (match_dup 0)
9896                    (call (mem:TLSmode (match_dup 3))
9897                          (match_dup 4)))
9898               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9899               (clobber (reg:SI LR_REGNO))])]
9900   ""
9901   [(set_attr "type" "two")
9902    (set_attr "length" "8")])
9904 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9905   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9906         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9907                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9908                         UNSPEC_TLSGD))]
9909   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9910   "addi %0,%1,%2@got@tlsgd"
9911   "&& TARGET_CMODEL != CMODEL_SMALL"
9912   [(set (match_dup 3)
9913         (high:TLSmode
9914             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9915    (set (match_dup 0)
9916         (lo_sum:TLSmode (match_dup 3)
9917             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9918   "
9920   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9922   [(set (attr "length")
9923      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9924                    (const_int 8)
9925                    (const_int 4)))])
9927 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9928   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9929      (high:TLSmode
9930        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9931                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9932                        UNSPEC_TLSGD)))]
9933   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9934   "addis %0,%1,%2@got@tlsgd@ha"
9935   [(set_attr "length" "4")])
9937 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9938   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9939      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9940        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9941                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9942                        UNSPEC_TLSGD)))]
9943   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9944   "addi %0,%1,%2@got@tlsgd@l"
9945   [(set_attr "length" "4")])
9947 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9948   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9949         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9950               (match_operand 2 "" "g")))
9951    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9952                    UNSPEC_TLSGD)
9953    (clobber (reg:SI LR_REGNO))]
9954   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9955    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9956   "bl %z1(%3@tlsgd)\;nop"
9957   [(set_attr "type" "branch")
9958    (set_attr "length" "8")])
9960 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9961   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9962         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9963               (match_operand 2 "" "g")))
9964    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9965                    UNSPEC_TLSGD)
9966    (clobber (reg:SI LR_REGNO))]
9967   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9969   if (flag_pic)
9970     {
9971       if (TARGET_SECURE_PLT && flag_pic == 2)
9972         return "bl %z1+32768(%3@tlsgd)@plt";
9973       return "bl %z1(%3@tlsgd)@plt";
9974     }
9975   return "bl %z1(%3@tlsgd)";
9977   [(set_attr "type" "branch")
9978    (set_attr "length" "4")])
9980 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9981   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9982         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9983               (match_operand 3 "" "g")))
9984    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9985                    UNSPEC_TLSLD)
9986    (clobber (reg:SI LR_REGNO))]
9987   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9989   if (TARGET_CMODEL != CMODEL_SMALL)
9990     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9991            "bl %z2\;nop";
9992   else
9993     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9995   "&& TARGET_TLS_MARKERS"
9996   [(set (match_dup 0)
9997         (unspec:TLSmode [(match_dup 1)]
9998                         UNSPEC_TLSLD))
9999    (parallel [(set (match_dup 0)
10000                    (call (mem:TLSmode (match_dup 2))
10001                          (match_dup 3)))
10002               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10003               (clobber (reg:SI LR_REGNO))])]
10004   ""
10005   [(set_attr "type" "two")
10006    (set (attr "length")
10007      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10008                    (const_int 16)
10009                    (const_int 12)))])
10011 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10012   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10013         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10014               (match_operand 3 "" "g")))
10015    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10016                    UNSPEC_TLSLD)
10017    (clobber (reg:SI LR_REGNO))]
10018   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10020   if (flag_pic)
10021     {
10022       if (TARGET_SECURE_PLT && flag_pic == 2)
10023         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10024       else
10025         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10026     }
10027   else
10028     return "addi %0,%1,%&@got@tlsld\;bl %z2";
10030   "&& TARGET_TLS_MARKERS"
10031   [(set (match_dup 0)
10032         (unspec:TLSmode [(match_dup 1)]
10033                         UNSPEC_TLSLD))
10034    (parallel [(set (match_dup 0)
10035                    (call (mem:TLSmode (match_dup 2))
10036                          (match_dup 3)))
10037               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10038               (clobber (reg:SI LR_REGNO))])]
10039   ""
10040   [(set_attr "length" "8")])
10042 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10043   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10044         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10045                         UNSPEC_TLSLD))]
10046   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10047   "addi %0,%1,%&@got@tlsld"
10048   "&& TARGET_CMODEL != CMODEL_SMALL"
10049   [(set (match_dup 2)
10050         (high:TLSmode
10051             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10052    (set (match_dup 0)
10053         (lo_sum:TLSmode (match_dup 2)
10054             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10055   "
10057   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10059   [(set (attr "length")
10060      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10061                    (const_int 8)
10062                    (const_int 4)))])
10064 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10065   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10066      (high:TLSmode
10067        (unspec:TLSmode [(const_int 0)
10068                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10069                        UNSPEC_TLSLD)))]
10070   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10071   "addis %0,%1,%&@got@tlsld@ha"
10072   [(set_attr "length" "4")])
10074 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10075   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10076      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10077        (unspec:TLSmode [(const_int 0)
10078                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10079                        UNSPEC_TLSLD)))]
10080   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10081   "addi %0,%1,%&@got@tlsld@l"
10082   [(set_attr "length" "4")])
10084 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10085   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10086         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10087               (match_operand 2 "" "g")))
10088    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10089    (clobber (reg:SI LR_REGNO))]
10090   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10091    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10092   "bl %z1(%&@tlsld)\;nop"
10093   [(set_attr "type" "branch")
10094    (set_attr "length" "8")])
10096 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10097   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10098         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10099               (match_operand 2 "" "g")))
10100    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10101    (clobber (reg:SI LR_REGNO))]
10102   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10104   if (flag_pic)
10105     {
10106       if (TARGET_SECURE_PLT && flag_pic == 2)
10107         return "bl %z1+32768(%&@tlsld)@plt";
10108       return "bl %z1(%&@tlsld)@plt";
10109     }
10110   return "bl %z1(%&@tlsld)";
10112   [(set_attr "type" "branch")
10113    (set_attr "length" "4")])
10115 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10116   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10117         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10118                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10119                         UNSPEC_TLSDTPREL))]
10120   "HAVE_AS_TLS"
10121   "addi %0,%1,%2@dtprel")
10123 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10124   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10125         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10126                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10127                         UNSPEC_TLSDTPRELHA))]
10128   "HAVE_AS_TLS"
10129   "addis %0,%1,%2@dtprel@ha")
10131 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10132   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10133         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10134                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10135                         UNSPEC_TLSDTPRELLO))]
10136   "HAVE_AS_TLS"
10137   "addi %0,%1,%2@dtprel@l")
10139 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10140   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10141         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10142                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10143                         UNSPEC_TLSGOTDTPREL))]
10144   "HAVE_AS_TLS"
10145   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10146   "&& TARGET_CMODEL != CMODEL_SMALL"
10147   [(set (match_dup 3)
10148         (high:TLSmode
10149             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10150    (set (match_dup 0)
10151         (lo_sum:TLSmode (match_dup 3)
10152             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10153   "
10155   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10157   [(set (attr "length")
10158      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10159                    (const_int 8)
10160                    (const_int 4)))])
10162 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10163   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10164      (high:TLSmode
10165        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10166                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10167                        UNSPEC_TLSGOTDTPREL)))]
10168   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10169   "addis %0,%1,%2@got@dtprel@ha"
10170   [(set_attr "length" "4")])
10172 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10173   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10174      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10175          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10176                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10177                          UNSPEC_TLSGOTDTPREL)))]
10178   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10179   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10180   [(set_attr "length" "4")])
10182 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10183   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10184         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10185                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10186                         UNSPEC_TLSTPREL))]
10187   "HAVE_AS_TLS"
10188   "addi %0,%1,%2@tprel")
10190 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10191   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10192         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10193                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10194                         UNSPEC_TLSTPRELHA))]
10195   "HAVE_AS_TLS"
10196   "addis %0,%1,%2@tprel@ha")
10198 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10199   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10200         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10201                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10202                         UNSPEC_TLSTPRELLO))]
10203   "HAVE_AS_TLS"
10204   "addi %0,%1,%2@tprel@l")
10206 ;; "b" output constraint here and on tls_tls input to support linker tls
10207 ;; optimization.  The linker may edit the instructions emitted by a
10208 ;; tls_got_tprel/tls_tls pair to addis,addi.
10209 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10210   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10211         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10212                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10213                         UNSPEC_TLSGOTTPREL))]
10214   "HAVE_AS_TLS"
10215   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10216   "&& TARGET_CMODEL != CMODEL_SMALL"
10217   [(set (match_dup 3)
10218         (high:TLSmode
10219             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10220    (set (match_dup 0)
10221         (lo_sum:TLSmode (match_dup 3)
10222             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10223   "
10225   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10227   [(set (attr "length")
10228      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10229                    (const_int 8)
10230                    (const_int 4)))])
10232 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10233   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10234      (high:TLSmode
10235        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10236                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10237                        UNSPEC_TLSGOTTPREL)))]
10238   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10239   "addis %0,%1,%2@got@tprel@ha"
10240   [(set_attr "length" "4")])
10242 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10243   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10244      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10245          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10246                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10247                          UNSPEC_TLSGOTTPREL)))]
10248   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10249   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10250   [(set_attr "length" "4")])
10252 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10253   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10254         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10255                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10256                         UNSPEC_TLSTLS))]
10257   "TARGET_ELF && HAVE_AS_TLS"
10258   "add %0,%1,%2@tls")
10260 (define_expand "tls_get_tpointer"
10261   [(set (match_operand:SI 0 "gpc_reg_operand" "")
10262         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10263   "TARGET_XCOFF && HAVE_AS_TLS"
10264   "
10266   emit_insn (gen_tls_get_tpointer_internal ());
10267   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10268   DONE;
10271 (define_insn "tls_get_tpointer_internal"
10272   [(set (reg:SI 3)
10273         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10274    (clobber (reg:SI LR_REGNO))]
10275   "TARGET_XCOFF && HAVE_AS_TLS"
10276   "bla __get_tpointer")
10278 (define_expand "tls_get_addr<mode>"
10279   [(set (match_operand:P 0 "gpc_reg_operand" "")
10280         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10281                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10282   "TARGET_XCOFF && HAVE_AS_TLS"
10283   "
10285   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10286   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10287   emit_insn (gen_tls_get_addr_internal<mode> ());
10288   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10289   DONE;
10292 (define_insn "tls_get_addr_internal<mode>"
10293   [(set (reg:P 3)
10294         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10295    (clobber (reg:P 0))
10296    (clobber (reg:P 4))
10297    (clobber (reg:P 5))
10298    (clobber (reg:P 11))
10299    (clobber (reg:CC CR0_REGNO))
10300    (clobber (reg:P LR_REGNO))]
10301   "TARGET_XCOFF && HAVE_AS_TLS"
10302   "bla __tls_get_addr")
10304 ;; Next come insns related to the calling sequence.
10306 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10307 ;; We move the back-chain and decrement the stack pointer.
10309 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
10310 ;; constant alloca, using that predicate will force the generic code to put
10311 ;; the constant size into a register before calling the expander.
10313 ;; As a result the expander would not have the constant size information
10314 ;; in those cases and would have to generate less efficient code.
10316 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10317 ;; the constant size.  The value is forced into a register if necessary.
10319 (define_expand "allocate_stack"
10320   [(set (match_operand 0 "gpc_reg_operand" "")
10321         (minus (reg 1) (match_operand 1 "reg_or_cint_operand" "")))
10322    (set (reg 1)
10323         (minus (reg 1) (match_dup 1)))]
10324   ""
10325   "
10326 { rtx chain = gen_reg_rtx (Pmode);
10327   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10328   rtx neg_op0;
10329   rtx insn, par, set, mem;
10331   /* By allowing reg_or_cint_operand as the predicate we can get
10332      better code for stack-clash-protection because we do not lose
10333      size information.  But the rest of the code expects the operand
10334      to be reg_or_short_operand.  If it isn't, then force it into
10335      a register.  */
10336   rtx orig_op1 = operands[1];
10337   if (!reg_or_short_operand (operands[1], Pmode))
10338     operands[1] = force_reg (Pmode, operands[1]);
10340   emit_move_insn (chain, stack_bot);
10342   /* Check stack bounds if necessary.  */
10343   if (crtl->limit_stack)
10344     {
10345       rtx available;
10346       available = expand_binop (Pmode, sub_optab,
10347                                 stack_pointer_rtx, stack_limit_rtx,
10348                                 NULL_RTX, 1, OPTAB_WIDEN);
10349       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10350     }
10352   /* Allocate and probe if requested.
10353      This may look similar to the loop we use for prologue allocations,
10354      but it is critically different.  For the former we know the loop
10355      will iterate, but do not know that generally here.  The former
10356      uses that knowledge to rotate the loop.  Combining them would be
10357      possible with some performance cost.  */
10358   if (flag_stack_clash_protection)
10359     {
10360       rtx rounded_size, last_addr, residual;
10361       HOST_WIDE_INT probe_interval;
10362       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10363                                                 &residual, &probe_interval,
10364                                                 orig_op1);
10365       
10366       /* We do occasionally get in here with constant sizes, we might
10367          as well do a reasonable job when we obviously can.  */
10368       if (rounded_size != const0_rtx)
10369         {
10370           rtx loop_lab, end_loop;
10371           bool rotated = CONST_INT_P (rounded_size);
10372           rtx update = GEN_INT (-probe_interval);
10373           if (probe_interval > 32768)
10374             update = force_reg (Pmode, update);
10376           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10377                                                         last_addr, rotated);
10379           if (Pmode == SImode)
10380             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10381                                                stack_pointer_rtx,
10382                                                update, chain));
10383           else
10384             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
10385                                                   stack_pointer_rtx,
10386                                                   update, chain));
10387           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10388                                                       last_addr, rotated);
10389         }
10391       /* Now handle residuals.  We just have to set operands[1] correctly
10392          and let the rest of the expander run.  */
10393       operands[1] = residual;
10394       if (!CONST_INT_P (residual))
10395         operands[1] = force_reg (Pmode, operands[1]);
10396     }
10398   if (GET_CODE (operands[1]) != CONST_INT
10399       || INTVAL (operands[1]) < -32767
10400       || INTVAL (operands[1]) > 32768)
10401     {
10402       neg_op0 = gen_reg_rtx (Pmode);
10403       if (TARGET_32BIT)
10404         emit_insn (gen_negsi2 (neg_op0, operands[1]));
10405       else
10406         emit_insn (gen_negdi2 (neg_op0, operands[1]));
10407     }
10408   else
10409     neg_op0 = GEN_INT (- INTVAL (operands[1]));
10411   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10412                                        : gen_movdi_di_update_stack))
10413                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10414                          chain));
10415   /* Since we didn't use gen_frame_mem to generate the MEM, grab
10416      it now and set the alias set/attributes. The above gen_*_update
10417      calls will generate a PARALLEL with the MEM set being the first
10418      operation. */
10419   par = PATTERN (insn);
10420   gcc_assert (GET_CODE (par) == PARALLEL);
10421   set = XVECEXP (par, 0, 0);
10422   gcc_assert (GET_CODE (set) == SET);
10423   mem = SET_DEST (set);
10424   gcc_assert (MEM_P (mem));
10425   MEM_NOTRAP_P (mem) = 1;
10426   set_mem_alias_set (mem, get_frame_alias_set ());
10428   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10429   DONE;
10432 ;; These patterns say how to save and restore the stack pointer.  We need not
10433 ;; save the stack pointer at function level since we are careful to
10434 ;; preserve the backchain.  At block level, we have to restore the backchain
10435 ;; when we restore the stack pointer.
10437 ;; For nonlocal gotos, we must save both the stack pointer and its
10438 ;; backchain and restore both.  Note that in the nonlocal case, the
10439 ;; save area is a memory location.
10441 (define_expand "save_stack_function"
10442   [(match_operand 0 "any_operand" "")
10443    (match_operand 1 "any_operand" "")]
10444   ""
10445   "DONE;")
10447 (define_expand "restore_stack_function"
10448   [(match_operand 0 "any_operand" "")
10449    (match_operand 1 "any_operand" "")]
10450   ""
10451   "DONE;")
10453 ;; Adjust stack pointer (op0) to a new value (op1).
10454 ;; First copy old stack backchain to new location, and ensure that the
10455 ;; scheduler won't reorder the sp assignment before the backchain write.
10456 (define_expand "restore_stack_block"
10457   [(set (match_dup 2) (match_dup 3))
10458    (set (match_dup 4) (match_dup 2))
10459    (match_dup 5)
10460    (set (match_operand 0 "register_operand" "")
10461         (match_operand 1 "register_operand" ""))]
10462   ""
10463   "
10465   rtvec p;
10467   operands[1] = force_reg (Pmode, operands[1]);
10468   operands[2] = gen_reg_rtx (Pmode);
10469   operands[3] = gen_frame_mem (Pmode, operands[0]);
10470   operands[4] = gen_frame_mem (Pmode, operands[1]);
10471   p = rtvec_alloc (1);
10472   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10473                                   const0_rtx);
10474   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10477 (define_expand "save_stack_nonlocal"
10478   [(set (match_dup 3) (match_dup 4))
10479    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10480    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10481   ""
10482   "
10484   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10486   /* Copy the backchain to the first word, sp to the second.  */
10487   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10488   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10489   operands[3] = gen_reg_rtx (Pmode);
10490   operands[4] = gen_frame_mem (Pmode, operands[1]);
10493 (define_expand "restore_stack_nonlocal"
10494   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10495    (set (match_dup 3) (match_dup 4))
10496    (set (match_dup 5) (match_dup 2))
10497    (match_dup 6)
10498    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10499   ""
10500   "
10502   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10503   rtvec p;
10505   /* Restore the backchain from the first word, sp from the second.  */
10506   operands[2] = gen_reg_rtx (Pmode);
10507   operands[3] = gen_reg_rtx (Pmode);
10508   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10509   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10510   operands[5] = gen_frame_mem (Pmode, operands[3]);
10511   p = rtvec_alloc (1);
10512   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10513                                   const0_rtx);
10514   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10517 ;; TOC register handling.
10519 ;; Code to initialize the TOC register...
10521 (define_insn "load_toc_aix_si"
10522   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10523                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10524               (use (reg:SI 2))])]
10525   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10526   "*
10528   char buf[30];
10529   extern int need_toc_init;
10530   need_toc_init = 1;
10531   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10532   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10533   operands[2] = gen_rtx_REG (Pmode, 2);
10534   return \"lwz %0,%1(%2)\";
10536   [(set_attr "type" "load")
10537    (set_attr "update" "no")
10538    (set_attr "indexed" "no")])
10540 (define_insn "load_toc_aix_di"
10541   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10542                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10543               (use (reg:DI 2))])]
10544   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10545   "*
10547   char buf[30];
10548   extern int need_toc_init;
10549   need_toc_init = 1;
10550   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10551                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10552   if (TARGET_ELF)
10553     strcat (buf, \"@toc\");
10554   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10555   operands[2] = gen_rtx_REG (Pmode, 2);
10556   return \"ld %0,%1(%2)\";
10558   [(set_attr "type" "load")
10559    (set_attr "update" "no")
10560    (set_attr "indexed" "no")])
10562 (define_insn "load_toc_v4_pic_si"
10563   [(set (reg:SI LR_REGNO)
10564         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10565   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10566   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10567   [(set_attr "type" "branch")
10568    (set_attr "length" "4")])
10570 (define_expand "load_toc_v4_PIC_1"
10571   [(parallel [(set (reg:SI LR_REGNO)
10572                    (match_operand:SI 0 "immediate_operand" "s"))
10573               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10574   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10575    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10576   "")
10578 (define_insn "load_toc_v4_PIC_1_normal"
10579   [(set (reg:SI LR_REGNO)
10580         (match_operand:SI 0 "immediate_operand" "s"))
10581    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10582   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10583    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10584   "bcl 20,31,%0\\n%0:"
10585   [(set_attr "type" "branch")
10586    (set_attr "length" "4")
10587    (set_attr "cannot_copy" "yes")])
10589 (define_insn "load_toc_v4_PIC_1_476"
10590   [(set (reg:SI LR_REGNO)
10591         (match_operand:SI 0 "immediate_operand" "s"))
10592    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10593   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10594    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10595   "*
10597   char name[32];
10598   static char templ[32];
10600   get_ppc476_thunk_name (name);
10601   sprintf (templ, \"bl %s\\n%%0:\", name);
10602   return templ;
10604   [(set_attr "type" "branch")
10605    (set_attr "length" "4")
10606    (set_attr "cannot_copy" "yes")])
10608 (define_expand "load_toc_v4_PIC_1b"
10609   [(parallel [(set (reg:SI LR_REGNO)
10610                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10611                                (label_ref (match_operand 1 "" ""))]
10612                            UNSPEC_TOCPTR))
10613               (match_dup 1)])]
10614   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10615   "")
10617 (define_insn "load_toc_v4_PIC_1b_normal"
10618   [(set (reg:SI LR_REGNO)
10619         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10620                     (label_ref (match_operand 1 "" ""))]
10621                 UNSPEC_TOCPTR))
10622    (match_dup 1)]
10623   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10624   "bcl 20,31,$+8\;.long %0-$"
10625   [(set_attr "type" "branch")
10626    (set_attr "length" "8")])
10628 (define_insn "load_toc_v4_PIC_1b_476"
10629   [(set (reg:SI LR_REGNO)
10630         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10631                     (label_ref (match_operand 1 "" ""))]
10632                 UNSPEC_TOCPTR))
10633    (match_dup 1)]
10634   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10635   "*
10637   char name[32];
10638   static char templ[32];
10640   get_ppc476_thunk_name (name);
10641   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10642   return templ;
10644   [(set_attr "type" "branch")
10645    (set_attr "length" "16")])
10647 (define_insn "load_toc_v4_PIC_2"
10648   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10649         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10650                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10651                              (match_operand:SI 3 "immediate_operand" "s")))))]
10652   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10653   "lwz %0,%2-%3(%1)"
10654   [(set_attr "type" "load")])
10656 (define_insn "load_toc_v4_PIC_3b"
10657   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10658         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10659                  (high:SI
10660                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10661                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10662   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10663   "addis %0,%1,%2-%3@ha")
10665 (define_insn "load_toc_v4_PIC_3c"
10666   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10667         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10668                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10669                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10670   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10671   "addi %0,%1,%2-%3@l")
10673 ;; If the TOC is shared over a translation unit, as happens with all
10674 ;; the kinds of PIC that we support, we need to restore the TOC
10675 ;; pointer only when jumping over units of translation.
10676 ;; On Darwin, we need to reload the picbase.
10678 (define_expand "builtin_setjmp_receiver"
10679   [(use (label_ref (match_operand 0 "" "")))]
10680   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10681    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10682    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10683   "
10685 #if TARGET_MACHO
10686   if (DEFAULT_ABI == ABI_DARWIN)
10687     {
10688       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10689       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10690       rtx tmplabrtx;
10691       char tmplab[20];
10693       crtl->uses_pic_offset_table = 1;
10694       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10695                                   CODE_LABEL_NUMBER (operands[0]));
10696       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10698       emit_insn (gen_load_macho_picbase (tmplabrtx));
10699       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10700       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10701     }
10702   else
10703 #endif
10704     rs6000_emit_load_toc_table (FALSE);
10705   DONE;
10708 ;; Largetoc support
10709 (define_insn "*largetoc_high"
10710   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10711         (high:DI
10712           (unspec [(match_operand:DI 1 "" "")
10713                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10714                   UNSPEC_TOCREL)))]
10715    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10716    "addis %0,%2,%1@toc@ha")
10718 (define_insn "*largetoc_high_aix<mode>"
10719   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10720         (high:P
10721           (unspec [(match_operand:P 1 "" "")
10722                    (match_operand:P 2 "gpc_reg_operand" "b")]
10723                   UNSPEC_TOCREL)))]
10724    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10725    "addis %0,%1@u(%2)")
10727 (define_insn "*largetoc_high_plus"
10728   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10729         (high:DI
10730           (plus:DI
10731             (unspec [(match_operand:DI 1 "" "")
10732                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10733                     UNSPEC_TOCREL)
10734             (match_operand:DI 3 "add_cint_operand" "n"))))]
10735    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10736    "addis %0,%2,%1+%3@toc@ha")
10738 (define_insn "*largetoc_high_plus_aix<mode>"
10739   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10740         (high:P
10741           (plus:P
10742             (unspec [(match_operand:P 1 "" "")
10743                      (match_operand:P 2 "gpc_reg_operand" "b")]
10744                     UNSPEC_TOCREL)
10745             (match_operand:P 3 "add_cint_operand" "n"))))]
10746    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10747    "addis %0,%1+%3@u(%2)")
10749 (define_insn "*largetoc_low"
10750   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10751         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10752                    (match_operand:DI 2 "" "")))]
10753    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10754    "addi %0,%1,%2@l")
10756 (define_insn "*largetoc_low_aix<mode>"
10757   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10758         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10759                    (match_operand:P 2 "" "")))]
10760    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10761    "la %0,%2@l(%1)")
10763 (define_insn_and_split "*tocref<mode>"
10764   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10765         (match_operand:P 1 "small_toc_ref" "R"))]
10766    "TARGET_TOC"
10767    "la %0,%a1"
10768    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10769   [(set (match_dup 0) (high:P (match_dup 1)))
10770    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10772 ;; Elf specific ways of loading addresses for non-PIC code.
10773 ;; The output of this could be r0, but we make a very strong
10774 ;; preference for a base register because it will usually
10775 ;; be needed there.
10776 (define_insn "elf_high"
10777   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10778         (high:SI (match_operand 1 "" "")))]
10779   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10780   "lis %0,%1@ha")
10782 (define_insn "elf_low"
10783   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10784         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10785                    (match_operand 2 "" "")))]
10786    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10787    "la %0,%2@l(%1)")
10789 ;; Call and call_value insns
10790 (define_expand "call"
10791   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10792                     (match_operand 1 "" ""))
10793               (use (match_operand 2 "" ""))
10794               (clobber (reg:SI LR_REGNO))])]
10795   ""
10796   "
10798 #if TARGET_MACHO
10799   if (MACHOPIC_INDIRECT)
10800     operands[0] = machopic_indirect_call_target (operands[0]);
10801 #endif
10803   gcc_assert (GET_CODE (operands[0]) == MEM);
10804   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10806   operands[0] = XEXP (operands[0], 0);
10808   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10809     {
10810       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10811       DONE;
10812     }
10814   if (GET_CODE (operands[0]) != SYMBOL_REF
10815       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10816     {
10817       if (INTVAL (operands[2]) & CALL_LONG)
10818         operands[0] = rs6000_longcall_ref (operands[0]);
10820       switch (DEFAULT_ABI)
10821         {
10822         case ABI_V4:
10823         case ABI_DARWIN:
10824           operands[0] = force_reg (Pmode, operands[0]);
10825           break;
10827         default:
10828           gcc_unreachable ();
10829         }
10830     }
10833 (define_expand "call_value"
10834   [(parallel [(set (match_operand 0 "" "")
10835                    (call (mem:SI (match_operand 1 "address_operand" ""))
10836                          (match_operand 2 "" "")))
10837               (use (match_operand 3 "" ""))
10838               (clobber (reg:SI LR_REGNO))])]
10839   ""
10840   "
10842 #if TARGET_MACHO
10843   if (MACHOPIC_INDIRECT)
10844     operands[1] = machopic_indirect_call_target (operands[1]);
10845 #endif
10847   gcc_assert (GET_CODE (operands[1]) == MEM);
10848   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10850   operands[1] = XEXP (operands[1], 0);
10852   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10853     {
10854       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10855       DONE;
10856     }
10858   if (GET_CODE (operands[1]) != SYMBOL_REF
10859       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10860     {
10861       if (INTVAL (operands[3]) & CALL_LONG)
10862         operands[1] = rs6000_longcall_ref (operands[1]);
10864       switch (DEFAULT_ABI)
10865         {
10866         case ABI_V4:
10867         case ABI_DARWIN:
10868           operands[1] = force_reg (Pmode, operands[1]);
10869           break;
10871         default:
10872           gcc_unreachable ();
10873         }
10874     }
10877 ;; Call to function in current module.  No TOC pointer reload needed.
10878 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10879 ;; either the function was not prototyped, or it was prototyped as a
10880 ;; variable argument function.  It is > 0 if FP registers were passed
10881 ;; and < 0 if they were not.
10883 (define_insn "*call_local32"
10884   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10885          (match_operand 1 "" "g,g"))
10886    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10887    (clobber (reg:SI LR_REGNO))]
10888   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10889   "*
10891   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10892     output_asm_insn (\"crxor 6,6,6\", operands);
10894   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10895     output_asm_insn (\"creqv 6,6,6\", operands);
10897   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10899   [(set_attr "type" "branch")
10900    (set_attr "length" "4,8")])
10902 (define_insn "*call_local64"
10903   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10904          (match_operand 1 "" "g,g"))
10905    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10906    (clobber (reg:SI LR_REGNO))]
10907   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10908   "*
10910   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10911     output_asm_insn (\"crxor 6,6,6\", operands);
10913   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10914     output_asm_insn (\"creqv 6,6,6\", operands);
10916   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10918   [(set_attr "type" "branch")
10919    (set_attr "length" "4,8")])
10921 (define_insn "*call_value_local32"
10922   [(set (match_operand 0 "" "")
10923         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10924               (match_operand 2 "" "g,g")))
10925    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10926    (clobber (reg:SI LR_REGNO))]
10927   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10928   "*
10930   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10931     output_asm_insn (\"crxor 6,6,6\", operands);
10933   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10934     output_asm_insn (\"creqv 6,6,6\", operands);
10936   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10938   [(set_attr "type" "branch")
10939    (set_attr "length" "4,8")])
10942 (define_insn "*call_value_local64"
10943   [(set (match_operand 0 "" "")
10944         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10945               (match_operand 2 "" "g,g")))
10946    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10947    (clobber (reg:SI LR_REGNO))]
10948   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10949   "*
10951   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10952     output_asm_insn (\"crxor 6,6,6\", operands);
10954   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10955     output_asm_insn (\"creqv 6,6,6\", operands);
10957   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10959   [(set_attr "type" "branch")
10960    (set_attr "length" "4,8")])
10963 ;; A function pointer under System V is just a normal pointer
10964 ;; operands[0] is the function pointer
10965 ;; operands[1] is the stack size to clean up
10966 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10967 ;; which indicates how to set cr1
10969 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10970   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10971          (match_operand 1 "" "g,g,g,g"))
10972    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10973    (clobber (reg:SI LR_REGNO))]
10974   "DEFAULT_ABI == ABI_V4
10975    || DEFAULT_ABI == ABI_DARWIN"
10977   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10978     output_asm_insn ("crxor 6,6,6", operands);
10980   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10981     output_asm_insn ("creqv 6,6,6", operands);
10983   return "b%T0l";
10985   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10986    (set_attr "length" "4,4,8,8")])
10988 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10989   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10990          (match_operand 1 "" "g,g"))
10991    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10992    (clobber (reg:SI LR_REGNO))]
10993   "(DEFAULT_ABI == ABI_DARWIN
10994    || (DEFAULT_ABI == ABI_V4
10995        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10997   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10998     output_asm_insn ("crxor 6,6,6", operands);
11000   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11001     output_asm_insn ("creqv 6,6,6", operands);
11003 #if TARGET_MACHO
11004   return output_call(insn, operands, 0, 2);
11005 #else
11006   if (DEFAULT_ABI == ABI_V4 && flag_pic)
11007     {
11008       gcc_assert (!TARGET_SECURE_PLT);
11009       return "bl %z0@plt";
11010     }
11011   else
11012     return "bl %z0";
11013 #endif
11015   "DEFAULT_ABI == ABI_V4
11016    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11017    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11018   [(parallel [(call (mem:SI (match_dup 0))
11019                     (match_dup 1))
11020               (use (match_dup 2))
11021               (use (match_dup 3))
11022               (clobber (reg:SI LR_REGNO))])]
11024   operands[3] = pic_offset_table_rtx;
11026   [(set_attr "type" "branch,branch")
11027    (set_attr "length" "4,8")])
11029 (define_insn "*call_nonlocal_sysv_secure<mode>"
11030   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11031          (match_operand 1 "" "g,g"))
11032    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11033    (use (match_operand:SI 3 "register_operand" "r,r"))
11034    (clobber (reg:SI LR_REGNO))]
11035   "(DEFAULT_ABI == ABI_V4
11036     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11037     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11039   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11040     output_asm_insn ("crxor 6,6,6", operands);
11042   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11043     output_asm_insn ("creqv 6,6,6", operands);
11045   if (flag_pic == 2)
11046     /* The magic 32768 offset here and in the other sysv call insns
11047        corresponds to the offset of r30 in .got2, as given by LCTOC1.
11048        See sysv4.h:toc_section.  */
11049     return "bl %z0+32768@plt";
11050   else
11051     return "bl %z0@plt";
11053   [(set_attr "type" "branch,branch")
11054    (set_attr "length" "4,8")])
11056 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11057   [(set (match_operand 0 "" "")
11058         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11059               (match_operand 2 "" "g,g,g,g")))
11060    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11061    (clobber (reg:SI LR_REGNO))]
11062   "DEFAULT_ABI == ABI_V4
11063    || DEFAULT_ABI == ABI_DARWIN"
11065   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11066     output_asm_insn ("crxor 6,6,6", operands);
11068   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11069     output_asm_insn ("creqv 6,6,6", operands);
11071   return "b%T1l";
11073   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11074    (set_attr "length" "4,4,8,8")])
11076 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11077   [(set (match_operand 0 "" "")
11078         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11079               (match_operand 2 "" "g,g")))
11080    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11081    (clobber (reg:SI LR_REGNO))]
11082   "(DEFAULT_ABI == ABI_DARWIN
11083    || (DEFAULT_ABI == ABI_V4
11084        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11086   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11087     output_asm_insn ("crxor 6,6,6", operands);
11089   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11090     output_asm_insn ("creqv 6,6,6", operands);
11092 #if TARGET_MACHO
11093   return output_call(insn, operands, 1, 3);
11094 #else
11095   if (DEFAULT_ABI == ABI_V4 && flag_pic)
11096     {
11097       gcc_assert (!TARGET_SECURE_PLT);
11098       return "bl %z1@plt";
11099     }
11100   else
11101     return "bl %z1";
11102 #endif
11104   "DEFAULT_ABI == ABI_V4
11105    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11106    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11107   [(parallel [(set (match_dup 0)
11108                    (call (mem:SI (match_dup 1))
11109                          (match_dup 2)))
11110               (use (match_dup 3))
11111               (use (match_dup 4))
11112               (clobber (reg:SI LR_REGNO))])]
11114   operands[4] = pic_offset_table_rtx;
11116   [(set_attr "type" "branch,branch")
11117    (set_attr "length" "4,8")])
11119 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11120   [(set (match_operand 0 "" "")
11121         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11122               (match_operand 2 "" "g,g")))
11123    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11124    (use (match_operand:SI 4 "register_operand" "r,r"))
11125    (clobber (reg:SI LR_REGNO))]
11126   "(DEFAULT_ABI == ABI_V4
11127     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11128     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11130   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11131     output_asm_insn ("crxor 6,6,6", operands);
11133   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11134     output_asm_insn ("creqv 6,6,6", operands);
11136   if (flag_pic == 2)
11137     return "bl %z1+32768@plt";
11138   else
11139     return "bl %z1@plt";
11141   [(set_attr "type" "branch,branch")
11142    (set_attr "length" "4,8")])
11145 ;; Call to AIX abi function in the same module.
11147 (define_insn "*call_local_aix<mode>"
11148   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11149          (match_operand 1 "" "g"))
11150    (clobber (reg:P LR_REGNO))]
11151   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11152   "bl %z0"
11153   [(set_attr "type" "branch")
11154    (set_attr "length" "4")])
11156 (define_insn "*call_value_local_aix<mode>"
11157   [(set (match_operand 0 "" "")
11158         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11159               (match_operand 2 "" "g")))
11160    (clobber (reg:P LR_REGNO))]
11161   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11162   "bl %z1"
11163   [(set_attr "type" "branch")
11164    (set_attr "length" "4")])
11166 ;; Call to AIX abi function which may be in another module.
11167 ;; Restore the TOC pointer (r2) after the call.
11169 (define_insn "*call_nonlocal_aix<mode>"
11170   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11171          (match_operand 1 "" "g"))
11172    (clobber (reg:P LR_REGNO))]
11173   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11174   "bl %z0\;nop"
11175   [(set_attr "type" "branch")
11176    (set_attr "length" "8")])
11178 (define_insn "*call_value_nonlocal_aix<mode>"
11179   [(set (match_operand 0 "" "")
11180         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11181               (match_operand 2 "" "g")))
11182    (clobber (reg:P LR_REGNO))]
11183   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11184   "bl %z1\;nop"
11185   [(set_attr "type" "branch")
11186    (set_attr "length" "8")])
11188 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11189 ;; Operand0 is the addresss of the function to call
11190 ;; Operand2 is the location in the function descriptor to load r2 from
11191 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11193 (define_insn "*call_indirect_aix<mode>"
11194   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11195          (match_operand 1 "" "g,g"))
11196    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11197    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11198    (clobber (reg:P LR_REGNO))]
11199   "DEFAULT_ABI == ABI_AIX"
11200   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11201   [(set_attr "type" "jmpreg")
11202    (set_attr "length" "12")])
11204 (define_insn "*call_value_indirect_aix<mode>"
11205   [(set (match_operand 0 "" "")
11206         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11207               (match_operand 2 "" "g,g")))
11208    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11209    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11210    (clobber (reg:P LR_REGNO))]
11211   "DEFAULT_ABI == ABI_AIX"
11212   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11213   [(set_attr "type" "jmpreg")
11214    (set_attr "length" "12")])
11216 ;; Call to indirect functions with the ELFv2 ABI.
11217 ;; Operand0 is the addresss of the function to call
11218 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11220 (define_insn "*call_indirect_elfv2<mode>"
11221   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11222          (match_operand 1 "" "g,g"))
11223    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11224    (clobber (reg:P LR_REGNO))]
11225   "DEFAULT_ABI == ABI_ELFv2"
11226   "b%T0l\;<ptrload> 2,%2(1)"
11227   [(set_attr "type" "jmpreg")
11228    (set_attr "length" "8")])
11230 (define_insn "*call_value_indirect_elfv2<mode>"
11231   [(set (match_operand 0 "" "")
11232         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11233               (match_operand 2 "" "g,g")))
11234    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11235    (clobber (reg:P LR_REGNO))]
11236   "DEFAULT_ABI == ABI_ELFv2"
11237   "b%T1l\;<ptrload> 2,%3(1)"
11238   [(set_attr "type" "jmpreg")
11239    (set_attr "length" "8")])
11242 ;; Call subroutine returning any type.
11243 (define_expand "untyped_call"
11244   [(parallel [(call (match_operand 0 "" "")
11245                     (const_int 0))
11246               (match_operand 1 "" "")
11247               (match_operand 2 "" "")])]
11248   ""
11249   "
11251   int i;
11253   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11255   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11256     {
11257       rtx set = XVECEXP (operands[2], 0, i);
11258       emit_move_insn (SET_DEST (set), SET_SRC (set));
11259     }
11261   /* The optimizer does not know that the call sets the function value
11262      registers we stored in the result block.  We avoid problems by
11263      claiming that all hard registers are used and clobbered at this
11264      point.  */
11265   emit_insn (gen_blockage ());
11267   DONE;
11270 ;; sibling call patterns
11271 (define_expand "sibcall"
11272   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11273                     (match_operand 1 "" ""))
11274               (use (match_operand 2 "" ""))
11275               (simple_return)])]
11276   ""
11277   "
11279 #if TARGET_MACHO
11280   if (MACHOPIC_INDIRECT)
11281     operands[0] = machopic_indirect_call_target (operands[0]);
11282 #endif
11284   gcc_assert (GET_CODE (operands[0]) == MEM);
11285   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11287   operands[0] = XEXP (operands[0], 0);
11289   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11290     {
11291       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11292       DONE;
11293     }
11296 (define_expand "sibcall_value"
11297   [(parallel [(set (match_operand 0 "register_operand" "")
11298                 (call (mem:SI (match_operand 1 "address_operand" ""))
11299                       (match_operand 2 "" "")))
11300               (use (match_operand 3 "" ""))
11301               (simple_return)])]
11302   ""
11303   "
11305 #if TARGET_MACHO
11306   if (MACHOPIC_INDIRECT)
11307     operands[1] = machopic_indirect_call_target (operands[1]);
11308 #endif
11310   gcc_assert (GET_CODE (operands[1]) == MEM);
11311   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11313   operands[1] = XEXP (operands[1], 0);
11315   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11316     {
11317       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11318       DONE;
11319     }
11322 (define_insn "*sibcall_local32"
11323   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11324          (match_operand 1 "" "g,g"))
11325    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11326    (simple_return)]
11327   "(INTVAL (operands[2]) & CALL_LONG) == 0"
11328   "*
11330   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11331     output_asm_insn (\"crxor 6,6,6\", operands);
11333   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11334     output_asm_insn (\"creqv 6,6,6\", operands);
11336   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11338   [(set_attr "type" "branch")
11339    (set_attr "length" "4,8")])
11341 (define_insn "*sibcall_local64"
11342   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11343          (match_operand 1 "" "g,g"))
11344    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11345    (simple_return)]
11346   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11347   "*
11349   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11350     output_asm_insn (\"crxor 6,6,6\", operands);
11352   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11353     output_asm_insn (\"creqv 6,6,6\", operands);
11355   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11357   [(set_attr "type" "branch")
11358    (set_attr "length" "4,8")])
11360 (define_insn "*sibcall_value_local32"
11361   [(set (match_operand 0 "" "")
11362         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11363               (match_operand 2 "" "g,g")))
11364    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11365    (simple_return)]
11366   "(INTVAL (operands[3]) & CALL_LONG) == 0"
11367   "*
11369   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11370     output_asm_insn (\"crxor 6,6,6\", operands);
11372   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11373     output_asm_insn (\"creqv 6,6,6\", operands);
11375   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11377   [(set_attr "type" "branch")
11378    (set_attr "length" "4,8")])
11380 (define_insn "*sibcall_value_local64"
11381   [(set (match_operand 0 "" "")
11382         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11383               (match_operand 2 "" "g,g")))
11384    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11385    (simple_return)]
11386   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11387   "*
11389   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11390     output_asm_insn (\"crxor 6,6,6\", operands);
11392   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11393     output_asm_insn (\"creqv 6,6,6\", operands);
11395   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11397   [(set_attr "type" "branch")
11398    (set_attr "length" "4,8")])
11400 (define_insn "*sibcall_nonlocal_sysv<mode>"
11401   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11402          (match_operand 1 "" ""))
11403    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11404    (simple_return)]
11405   "(DEFAULT_ABI == ABI_DARWIN
11406     || DEFAULT_ABI == ABI_V4)
11407    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11408   "*
11410   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11411     output_asm_insn (\"crxor 6,6,6\", operands);
11413   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11414     output_asm_insn (\"creqv 6,6,6\", operands);
11416   if (which_alternative >= 2)
11417     return \"b%T0\";
11418   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11419     {
11420       gcc_assert (!TARGET_SECURE_PLT);
11421       return \"b %z0@plt\";
11422     }
11423   else
11424     return \"b %z0\";
11426   [(set_attr "type" "branch")
11427    (set_attr "length" "4,8,4,8")])
11429 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11430   [(set (match_operand 0 "" "")
11431         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11432               (match_operand 2 "" "")))
11433    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11434    (simple_return)]
11435   "(DEFAULT_ABI == ABI_DARWIN
11436     || DEFAULT_ABI == ABI_V4)
11437    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11438   "*
11440   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11441     output_asm_insn (\"crxor 6,6,6\", operands);
11443   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11444     output_asm_insn (\"creqv 6,6,6\", operands);
11446   if (which_alternative >= 2)
11447     return \"b%T1\";
11448   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11449     {
11450       gcc_assert (!TARGET_SECURE_PLT);
11451       return \"b %z1@plt\";
11452     }
11453   else
11454     return \"b %z1\";
11456   [(set_attr "type" "branch")
11457    (set_attr "length" "4,8,4,8")])
11459 ;; AIX ABI sibling call patterns.
11461 (define_insn "*sibcall_aix<mode>"
11462   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11463          (match_operand 1 "" "g,g"))
11464    (simple_return)]
11465   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11466   "@
11467    b %z0
11468    b%T0"
11469   [(set_attr "type" "branch")
11470    (set_attr "length" "4")])
11472 (define_insn "*sibcall_value_aix<mode>"
11473   [(set (match_operand 0 "" "")
11474         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11475               (match_operand 2 "" "g,g")))
11476    (simple_return)]
11477   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11478   "@
11479    b %z1
11480    b%T1"
11481   [(set_attr "type" "branch")
11482    (set_attr "length" "4")])
11484 (define_expand "sibcall_epilogue"
11485   [(use (const_int 0))]
11486   ""
11488   if (!TARGET_SCHED_PROLOG)
11489     emit_insn (gen_blockage ());
11490   rs6000_emit_epilogue (TRUE);
11491   DONE;
11494 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11495 ;; all of memory.  This blocks insns from being moved across this point.
11497 (define_insn "blockage"
11498   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11499   ""
11500   "")
11502 (define_expand "probe_stack_address"
11503   [(use (match_operand 0 "address_operand"))]
11504   ""
11506   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11507   MEM_VOLATILE_P (operands[0]) = 1;
11509   if (TARGET_64BIT)
11510     emit_insn (gen_probe_stack_di (operands[0]));
11511   else
11512     emit_insn (gen_probe_stack_si (operands[0]));
11513   DONE;
11516 (define_insn "probe_stack_<mode>"
11517   [(set (match_operand:P 0 "memory_operand" "=m")
11518         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11519   ""
11521   operands[1] = gen_rtx_REG (Pmode, 0);
11522   return "st<wd>%U0%X0 %1,%0";
11524   [(set_attr "type" "store")
11525    (set (attr "update")
11526         (if_then_else (match_operand 0 "update_address_mem")
11527                       (const_string "yes")
11528                       (const_string "no")))
11529    (set (attr "indexed")
11530         (if_then_else (match_operand 0 "indexed_address_mem")
11531                       (const_string "yes")
11532                       (const_string "no")))
11533    (set_attr "length" "4")])
11535 (define_insn "probe_stack_range<P:mode>"
11536   [(set (match_operand:P 0 "register_operand" "=&r")
11537         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11538                             (match_operand:P 2 "register_operand" "r")
11539                             (match_operand:P 3 "register_operand" "r")]
11540                            UNSPECV_PROBE_STACK_RANGE))]
11541   ""
11542   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11543   [(set_attr "type" "three")])
11545 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11546 ;; signed & unsigned, and one type of branch.
11548 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11549 ;; insns, and branches.
11551 (define_expand "cbranch<mode>4"
11552   [(use (match_operator 0 "comparison_operator"
11553          [(match_operand:GPR 1 "gpc_reg_operand" "")
11554           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11555    (use (match_operand 3 ""))]
11556   ""
11557   "
11559   /* Take care of the possibility that operands[2] might be negative but
11560      this might be a logical operation.  That insn doesn't exist.  */
11561   if (GET_CODE (operands[2]) == CONST_INT
11562       && INTVAL (operands[2]) < 0)
11563     {
11564       operands[2] = force_reg (<MODE>mode, operands[2]);
11565       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11566                                     GET_MODE (operands[0]),
11567                                     operands[1], operands[2]);
11568    }
11570   rs6000_emit_cbranch (<MODE>mode, operands);
11571   DONE;
11574 (define_expand "cbranch<mode>4"
11575   [(use (match_operator 0 "comparison_operator"
11576          [(match_operand:FP 1 "gpc_reg_operand" "")
11577           (match_operand:FP 2 "gpc_reg_operand" "")]))
11578    (use (match_operand 3 ""))]
11579   ""
11580   "
11582   rs6000_emit_cbranch (<MODE>mode, operands);
11583   DONE;
11586 (define_expand "cstore<mode>4_signed"
11587   [(use (match_operator 1 "signed_comparison_operator"
11588          [(match_operand:P 2 "gpc_reg_operand")
11589           (match_operand:P 3 "gpc_reg_operand")]))
11590    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11591   ""
11593   enum rtx_code cond_code = GET_CODE (operands[1]);
11595   rtx op0 = operands[0];
11596   rtx op1 = operands[2];
11597   rtx op2 = operands[3];
11599   if (cond_code == GE || cond_code == LT)
11600     {
11601       cond_code = swap_condition (cond_code);
11602       std::swap (op1, op2);
11603     }
11605   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11606   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11607   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11609   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11610   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11611   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11613   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11615   if (cond_code == LE)
11616     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11617   else
11618     {
11619       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11620       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11621       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11622     }
11624   DONE;
11627 (define_expand "cstore<mode>4_unsigned"
11628   [(use (match_operator 1 "unsigned_comparison_operator"
11629          [(match_operand:P 2 "gpc_reg_operand")
11630           (match_operand:P 3 "reg_or_short_operand")]))
11631    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11632   ""
11634   enum rtx_code cond_code = GET_CODE (operands[1]);
11636   rtx op0 = operands[0];
11637   rtx op1 = operands[2];
11638   rtx op2 = operands[3];
11640   if (cond_code == GEU || cond_code == LTU)
11641     {
11642       cond_code = swap_condition (cond_code);
11643       std::swap (op1, op2);
11644     }
11646   if (!gpc_reg_operand (op1, <MODE>mode))
11647     op1 = force_reg (<MODE>mode, op1);
11648   if (!reg_or_short_operand (op2, <MODE>mode))
11649     op2 = force_reg (<MODE>mode, op2);
11651   rtx tmp = gen_reg_rtx (<MODE>mode);
11652   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11654   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11655   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11657   if (cond_code == LEU)
11658     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11659   else
11660     emit_insn (gen_neg<mode>2 (op0, tmp2));
11662   DONE;
11665 (define_expand "cstore_si_as_di"
11666   [(use (match_operator 1 "unsigned_comparison_operator"
11667          [(match_operand:SI 2 "gpc_reg_operand")
11668           (match_operand:SI 3 "reg_or_short_operand")]))
11669    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11670   ""
11672   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11673   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11675   operands[2] = force_reg (SImode, operands[2]);
11676   operands[3] = force_reg (SImode, operands[3]);
11677   rtx op1 = gen_reg_rtx (DImode);
11678   rtx op2 = gen_reg_rtx (DImode);
11679   convert_move (op1, operands[2], uns_flag);
11680   convert_move (op2, operands[3], uns_flag);
11682   if (cond_code == GT || cond_code == LE)
11683     {
11684       cond_code = swap_condition (cond_code);
11685       std::swap (op1, op2);
11686     }
11688   rtx tmp = gen_reg_rtx (DImode);
11689   rtx tmp2 = gen_reg_rtx (DImode);
11690   emit_insn (gen_subdi3 (tmp, op1, op2));
11691   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11693   rtx tmp3;
11694   switch (cond_code)
11695     {
11696     default:
11697       gcc_unreachable ();
11698     case LT:
11699       tmp3 = tmp2;
11700       break;
11701     case GE:
11702       tmp3 = gen_reg_rtx (DImode);
11703       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11704       break;
11705     }
11707   convert_move (operands[0], tmp3, 1);
11709   DONE;
11712 (define_expand "cstore<mode>4_signed_imm"
11713   [(use (match_operator 1 "signed_comparison_operator"
11714          [(match_operand:GPR 2 "gpc_reg_operand")
11715           (match_operand:GPR 3 "immediate_operand")]))
11716    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11717   ""
11719   bool invert = false;
11721   enum rtx_code cond_code = GET_CODE (operands[1]);
11723   rtx op0 = operands[0];
11724   rtx op1 = operands[2];
11725   HOST_WIDE_INT val = INTVAL (operands[3]);
11727   if (cond_code == GE || cond_code == GT)
11728     {
11729       cond_code = reverse_condition (cond_code);
11730       invert = true;
11731     }
11733   if (cond_code == LE)
11734     val++;
11736   rtx tmp = gen_reg_rtx (<MODE>mode);
11737   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11738   rtx x = gen_reg_rtx (<MODE>mode);
11739   if (val < 0)
11740     emit_insn (gen_and<mode>3 (x, op1, tmp));
11741   else
11742     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11744   if (invert)
11745     {
11746       rtx tmp = gen_reg_rtx (<MODE>mode);
11747       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11748       x = tmp;
11749     }
11751   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11752   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11754   DONE;
11757 (define_expand "cstore<mode>4_unsigned_imm"
11758   [(use (match_operator 1 "unsigned_comparison_operator"
11759          [(match_operand:GPR 2 "gpc_reg_operand")
11760           (match_operand:GPR 3 "immediate_operand")]))
11761    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11762   ""
11764   bool invert = false;
11766   enum rtx_code cond_code = GET_CODE (operands[1]);
11768   rtx op0 = operands[0];
11769   rtx op1 = operands[2];
11770   HOST_WIDE_INT val = INTVAL (operands[3]);
11772   if (cond_code == GEU || cond_code == GTU)
11773     {
11774       cond_code = reverse_condition (cond_code);
11775       invert = true;
11776     }
11778   if (cond_code == LEU)
11779     val++;
11781   rtx tmp = gen_reg_rtx (<MODE>mode);
11782   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11783   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11784   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11785   rtx x = gen_reg_rtx (<MODE>mode);
11786   if (val < 0)
11787     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11788   else
11789     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11791   if (invert)
11792     {
11793       rtx tmp = gen_reg_rtx (<MODE>mode);
11794       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11795       x = tmp;
11796     }
11798   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11799   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11801   DONE;
11804 (define_expand "cstore<mode>4"
11805   [(use (match_operator 1 "comparison_operator"
11806          [(match_operand:GPR 2 "gpc_reg_operand")
11807           (match_operand:GPR 3 "reg_or_short_operand")]))
11808    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11809   ""
11811   /* Expanding EQ and NE directly to some machine instructions does not help
11812      but does hurt combine.  So don't.  */
11813   if (GET_CODE (operands[1]) == EQ)
11814     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11815   else if (<MODE>mode == Pmode
11816            && GET_CODE (operands[1]) == NE)
11817     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11818   else if (GET_CODE (operands[1]) == NE)
11819     {
11820       rtx tmp = gen_reg_rtx (<MODE>mode);
11821       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11822       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11823     }
11825   /* If ISEL is fast, expand to it.  */
11826   else if (TARGET_ISEL)
11827     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11829   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11830      etc. combinations magically work out just right.  */
11831   else if (<MODE>mode == Pmode
11832            && unsigned_comparison_operator (operands[1], VOIDmode))
11833     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11834                                            operands[2], operands[3]));
11836   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11837   else if (<MODE>mode == SImode && Pmode == DImode)
11838     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11839                                     operands[2], operands[3]));
11841   /* For signed comparisons against a constant, we can do some simple
11842      bit-twiddling.  */
11843   else if (signed_comparison_operator (operands[1], VOIDmode)
11844            && CONST_INT_P (operands[3]))
11845     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11846                                              operands[2], operands[3]));
11848   /* And similarly for unsigned comparisons.  */
11849   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11850            && CONST_INT_P (operands[3]))
11851     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11852                                                operands[2], operands[3]));
11854   /* We also do not want to use mfcr for signed comparisons.  */
11855   else if (<MODE>mode == Pmode
11856            && signed_comparison_operator (operands[1], VOIDmode))
11857     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11858                                          operands[2], operands[3]));
11860   /* Everything else, use the mfcr brute force.  */
11861   else
11862     rs6000_emit_sCOND (<MODE>mode, operands);
11864   DONE;
11867 (define_expand "cstore<mode>4"
11868   [(use (match_operator 1 "comparison_operator"
11869          [(match_operand:FP 2 "gpc_reg_operand")
11870           (match_operand:FP 3 "gpc_reg_operand")]))
11871    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11872   ""
11874   rs6000_emit_sCOND (<MODE>mode, operands);
11875   DONE;
11879 (define_expand "stack_protect_set"
11880   [(match_operand 0 "memory_operand")
11881    (match_operand 1 "memory_operand")]
11882   ""
11884   if (rs6000_stack_protector_guard == SSP_TLS)
11885     {
11886       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11887       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11888       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11889       operands[1] = gen_rtx_MEM (Pmode, addr);
11890     }
11892   if (TARGET_64BIT)
11893     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11894   else
11895     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11897   DONE;
11900 (define_insn "stack_protect_setsi"
11901   [(set (match_operand:SI 0 "memory_operand" "=m")
11902         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11903    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11904   "TARGET_32BIT"
11905   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11906   [(set_attr "type" "three")
11907    (set_attr "length" "12")])
11909 (define_insn "stack_protect_setdi"
11910   [(set (match_operand:DI 0 "memory_operand" "=Y")
11911         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11912    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11913   "TARGET_64BIT"
11914   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11915   [(set_attr "type" "three")
11916    (set_attr "length" "12")])
11918 (define_expand "stack_protect_test"
11919   [(match_operand 0 "memory_operand")
11920    (match_operand 1 "memory_operand")
11921    (match_operand 2 "")]
11922   ""
11924   rtx guard = operands[1];
11926   if (rs6000_stack_protector_guard == SSP_TLS)
11927     {
11928       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11929       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11930       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11931       guard = gen_rtx_MEM (Pmode, addr);
11932     }
11934   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11935   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11936   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11937   emit_jump_insn (jump);
11939   DONE;
11942 (define_insn "stack_protect_testsi"
11943   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11944         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11945                       (match_operand:SI 2 "memory_operand" "m,m")]
11946                      UNSPEC_SP_TEST))
11947    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11948    (clobber (match_scratch:SI 3 "=&r,&r"))]
11949   "TARGET_32BIT"
11950   "@
11951    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11952    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11953   [(set_attr "length" "16,20")])
11955 (define_insn "stack_protect_testdi"
11956   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11957         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11958                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11959                      UNSPEC_SP_TEST))
11960    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11961    (clobber (match_scratch:DI 3 "=&r,&r"))]
11962   "TARGET_64BIT"
11963   "@
11964    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11965    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11966   [(set_attr "length" "16,20")])
11969 ;; Here are the actual compare insns.
11970 (define_insn "*cmp<mode>_signed"
11971   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11972         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11973                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11974   ""
11975   "cmp<wd>%I2 %0,%1,%2"
11976   [(set_attr "type" "cmp")])
11978 (define_insn "*cmp<mode>_unsigned"
11979   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11980         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11981                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11982   ""
11983   "cmpl<wd>%I2 %0,%1,%2"
11984   [(set_attr "type" "cmp")])
11986 ;; If we are comparing a register for equality with a large constant,
11987 ;; we can do this with an XOR followed by a compare.  But this is profitable
11988 ;; only if the large constant is only used for the comparison (and in this
11989 ;; case we already have a register to reuse as scratch).
11991 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11992 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11994 (define_peephole2
11995   [(set (match_operand:SI 0 "register_operand")
11996         (match_operand:SI 1 "logical_const_operand" ""))
11997    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11998                        [(match_dup 0)
11999                         (match_operand:SI 2 "logical_const_operand" "")]))
12000    (set (match_operand:CC 4 "cc_reg_operand" "")
12001         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
12002                     (match_dup 0)))
12003    (set (pc)
12004         (if_then_else (match_operator 6 "equality_operator"
12005                        [(match_dup 4) (const_int 0)])
12006                       (match_operand 7 "" "")
12007                       (match_operand 8 "" "")))]
12008   "peep2_reg_dead_p (3, operands[0])
12009    && peep2_reg_dead_p (4, operands[4])
12010    && REGNO (operands[0]) != REGNO (operands[5])"
12011  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12012   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12013   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12016   /* Get the constant we are comparing against, and see what it looks like
12017      when sign-extended from 16 to 32 bits.  Then see what constant we could
12018      XOR with SEXTC to get the sign-extended value.  */
12019   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12020                                               SImode,
12021                                               operands[1], operands[2]);
12022   HOST_WIDE_INT c = INTVAL (cnst);
12023   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
12024   HOST_WIDE_INT xorv = c ^ sextc;
12026   operands[9] = GEN_INT (xorv);
12027   operands[10] = GEN_INT (sextc);
12030 ;; The following two insns don't exist as single insns, but if we provide
12031 ;; them, we can swap an add and compare, which will enable us to overlap more
12032 ;; of the required delay between a compare and branch.  We generate code for
12033 ;; them by splitting.
12035 (define_insn ""
12036   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12037         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12038                     (match_operand:SI 2 "short_cint_operand" "i")))
12039    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12040         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12041   ""
12042   "#"
12043   [(set_attr "length" "8")])
12045 (define_insn ""
12046   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12047         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12048                        (match_operand:SI 2 "u_short_cint_operand" "i")))
12049    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12050         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12051   ""
12052   "#"
12053   [(set_attr "length" "8")])
12055 (define_split
12056   [(set (match_operand:CC 3 "cc_reg_operand" "")
12057         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12058                     (match_operand:SI 2 "short_cint_operand" "")))
12059    (set (match_operand:SI 0 "gpc_reg_operand" "")
12060         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12061   ""
12062   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12063    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12065 (define_split
12066   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12067         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12068                        (match_operand:SI 2 "u_short_cint_operand" "")))
12069    (set (match_operand:SI 0 "gpc_reg_operand" "")
12070         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12071   ""
12072   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12073    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12075 ;; Only need to compare second words if first words equal
12076 (define_insn "*cmp<mode>_internal1"
12077   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12078         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12079                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12080   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12081    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12082   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12083   [(set_attr "type" "fpcompare")
12084    (set_attr "length" "12")])
12086 (define_insn_and_split "*cmp<mode>_internal2"
12087   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12088         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12089                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12090     (clobber (match_scratch:DF 3 "=d"))
12091     (clobber (match_scratch:DF 4 "=d"))
12092     (clobber (match_scratch:DF 5 "=d"))
12093     (clobber (match_scratch:DF 6 "=d"))
12094     (clobber (match_scratch:DF 7 "=d"))
12095     (clobber (match_scratch:DF 8 "=d"))
12096     (clobber (match_scratch:DF 9 "=d"))
12097     (clobber (match_scratch:DF 10 "=d"))
12098     (clobber (match_scratch:GPR 11 "=b"))]
12099   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12100    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12101   "#"
12102   "&& reload_completed"
12103   [(set (match_dup 3) (match_dup 14))
12104    (set (match_dup 4) (match_dup 15))
12105    (set (match_dup 9) (abs:DF (match_dup 5)))
12106    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12107    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12108                            (label_ref (match_dup 12))
12109                            (pc)))
12110    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12111    (set (pc) (label_ref (match_dup 13)))
12112    (match_dup 12)
12113    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12114    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12115    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12116    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12117    (match_dup 13)]
12119   REAL_VALUE_TYPE rv;
12120   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12121   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12123   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12124   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12125   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12126   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12127   operands[12] = gen_label_rtx ();
12128   operands[13] = gen_label_rtx ();
12129   real_inf (&rv);
12130   operands[14] = force_const_mem (DFmode,
12131                                   const_double_from_real_value (rv, DFmode));
12132   operands[15] = force_const_mem (DFmode,
12133                                   const_double_from_real_value (dconst0,
12134                                                                 DFmode));
12135   if (TARGET_TOC)
12136     {
12137       rtx tocref;
12138       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12139       operands[14] = gen_const_mem (DFmode, tocref);
12140       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12141       operands[15] = gen_const_mem (DFmode, tocref);
12142       set_mem_alias_set (operands[14], get_TOC_alias_set ());
12143       set_mem_alias_set (operands[15], get_TOC_alias_set ());
12144     }
12147 ;; Now we have the scc insns.  We can do some combinations because of the
12148 ;; way the machine works.
12150 ;; Note that this is probably faster if we can put an insn between the
12151 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
12152 ;; cases the insns below which don't use an intermediate CR field will
12153 ;; be used instead.
12154 (define_insn ""
12155   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12156         (match_operator:SI 1 "scc_comparison_operator"
12157                            [(match_operand 2 "cc_reg_operand" "y")
12158                             (const_int 0)]))]
12159   ""
12160   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12161   [(set (attr "type")
12162      (cond [(match_test "TARGET_MFCRF")
12163                 (const_string "mfcrf")
12164            ]
12165         (const_string "mfcr")))
12166    (set_attr "length" "8")])
12168 ;; Same as above, but get the OV/ORDERED bit.
12169 (define_insn "move_from_CR_ov_bit"
12170   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12171         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12172                    UNSPEC_MV_CR_OV))]
12173   "TARGET_PAIRED_FLOAT"
12174   "mfcr %0\;rlwinm %0,%0,%t1,1"
12175   [(set_attr "type" "mfcr")
12176    (set_attr "length" "8")])
12178 (define_insn ""
12179   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12180         (match_operator:DI 1 "scc_comparison_operator"
12181                            [(match_operand 2 "cc_reg_operand" "y")
12182                             (const_int 0)]))]
12183   "TARGET_POWERPC64"
12184   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12185   [(set (attr "type")
12186      (cond [(match_test "TARGET_MFCRF")
12187                 (const_string "mfcrf")
12188            ]
12189         (const_string "mfcr")))
12190    (set_attr "length" "8")])
12192 (define_insn ""
12193   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12194         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12195                                        [(match_operand 2 "cc_reg_operand" "y,y")
12196                                         (const_int 0)])
12197                     (const_int 0)))
12198    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12199         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12200   "TARGET_32BIT"
12201   "@
12202    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12203    #"
12204   [(set_attr "type" "shift")
12205    (set_attr "dot" "yes")
12206    (set_attr "length" "8,16")])
12208 (define_split
12209   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12210         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12211                                        [(match_operand 2 "cc_reg_operand" "")
12212                                         (const_int 0)])
12213                     (const_int 0)))
12214    (set (match_operand:SI 3 "gpc_reg_operand" "")
12215         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12216   "TARGET_32BIT && reload_completed"
12217   [(set (match_dup 3)
12218         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12219    (set (match_dup 0)
12220         (compare:CC (match_dup 3)
12221                     (const_int 0)))]
12222   "")
12224 (define_insn ""
12225   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12226         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12227                                       [(match_operand 2 "cc_reg_operand" "y")
12228                                        (const_int 0)])
12229                    (match_operand:SI 3 "const_int_operand" "n")))]
12230   ""
12231   "*
12233   int is_bit = ccr_bit (operands[1], 1);
12234   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12235   int count;
12237   if (is_bit >= put_bit)
12238     count = is_bit - put_bit;
12239   else
12240     count = 32 - (put_bit - is_bit);
12242   operands[4] = GEN_INT (count);
12243   operands[5] = GEN_INT (put_bit);
12245   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12247   [(set (attr "type")
12248      (cond [(match_test "TARGET_MFCRF")
12249                 (const_string "mfcrf")
12250            ]
12251         (const_string "mfcr")))
12252    (set_attr "length" "8")])
12254 (define_insn ""
12255   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12256         (compare:CC
12257          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12258                                        [(match_operand 2 "cc_reg_operand" "y,y")
12259                                         (const_int 0)])
12260                     (match_operand:SI 3 "const_int_operand" "n,n"))
12261          (const_int 0)))
12262    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12263         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12264                    (match_dup 3)))]
12265   ""
12266   "*
12268   int is_bit = ccr_bit (operands[1], 1);
12269   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12270   int count;
12272   /* Force split for non-cc0 compare.  */
12273   if (which_alternative == 1)
12274      return \"#\";
12276   if (is_bit >= put_bit)
12277     count = is_bit - put_bit;
12278   else
12279     count = 32 - (put_bit - is_bit);
12281   operands[5] = GEN_INT (count);
12282   operands[6] = GEN_INT (put_bit);
12284   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12286   [(set_attr "type" "shift")
12287    (set_attr "dot" "yes")
12288    (set_attr "length" "8,16")])
12290 (define_split
12291   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
12292         (compare:CC
12293          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12294                                        [(match_operand 2 "cc_reg_operand")
12295                                         (const_int 0)])
12296                     (match_operand:SI 3 "const_int_operand"))
12297          (const_int 0)))
12298    (set (match_operand:SI 4 "gpc_reg_operand")
12299         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12300                    (match_dup 3)))]
12301   "reload_completed"
12302   [(set (match_dup 4)
12303         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12304                    (match_dup 3)))
12305    (set (match_dup 0)
12306         (compare:CC (match_dup 4)
12307                     (const_int 0)))]
12308   "")
12311 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
12312 (define_code_attr UNS [(eq "CC")
12313                        (ne "CC")
12314                        (lt "CC") (ltu "CCUNS")
12315                        (gt "CC") (gtu "CCUNS")
12316                        (le "CC") (leu "CCUNS")
12317                        (ge "CC") (geu "CCUNS")])
12318 (define_code_attr UNSu_ [(eq "")
12319                          (ne "")
12320                          (lt "") (ltu "u_")
12321                          (gt "") (gtu "u_")
12322                          (le "") (leu "u_")
12323                          (ge "") (geu "u_")])
12324 (define_code_attr UNSIK [(eq "I")
12325                          (ne "I")
12326                          (lt "I") (ltu "K")
12327                          (gt "I") (gtu "K")
12328                          (le "I") (leu "K")
12329                          (ge "I") (geu "K")])
12331 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
12332   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12333         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
12334                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
12335    (clobber (match_scratch:GPR 3 "=r"))
12336    (clobber (match_scratch:GPR 4 "=r"))
12337    (clobber (match_scratch:<UNS> 5 "=y"))]
12338   "TARGET_ISEL
12339    && !(<CODE> == EQ && operands[2] == const0_rtx)
12340    && !(<CODE> == NE && operands[2] == const0_rtx
12341         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
12342   "#"
12343   "&& 1"
12344   [(pc)]
12346   rtx_code code = <CODE>;
12347   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
12348     {
12349       HOST_WIDE_INT val = INTVAL (operands[2]);
12350       if (code == LT && val != -0x8000)
12351         {
12352           code = LE;
12353           val--;
12354         }
12355       if (code == GT && val != 0x7fff)
12356         {
12357           code = GE;
12358           val++;
12359         }
12360       if (code == LTU && val != 0)
12361         {
12362           code = LEU;
12363           val--;
12364         }
12365       if (code == GTU && val != 0xffff)
12366         {
12367           code = GEU;
12368           val++;
12369         }
12370       operands[2] = GEN_INT (val);
12371     }
12373   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12374     operands[3] = const0_rtx;
12375   else
12376     {
12377       if (GET_CODE (operands[3]) == SCRATCH)
12378         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12379       emit_move_insn (operands[3], const0_rtx);
12380     }
12382   if (GET_CODE (operands[4]) == SCRATCH)
12383     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12384   emit_move_insn (operands[4], const1_rtx);
12386   if (GET_CODE (operands[5]) == SCRATCH)
12387     operands[5] = gen_reg_rtx (<UNS>mode);
12389   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12390   emit_insn (gen_rtx_SET (operands[5], c1));
12392   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12393   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12394   emit_move_insn (operands[0], x);
12396   DONE;
12398   [(set (attr "cost")
12399         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12400                                    || <CODE> == NE
12401                                    || <CODE> == LE || <CODE> == GE
12402                                    || <CODE> == LEU || <CODE> == GEU")
12403                       (const_string "9")
12404                       (const_string "10")))])
12406 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12407                               (DI "rKJI")])
12409 (define_expand "eq<mode>3"
12410   [(parallel [
12411      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12412           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12413                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12414      (clobber (match_scratch:GPR 3 "=r"))
12415      (clobber (match_scratch:GPR 4 "=r"))])]
12416   ""
12418   if (TARGET_ISEL && operands[2] != const0_rtx)
12419     {
12420       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12421                                            operands[2]));
12422       DONE;
12423     }
12426 (define_insn_and_split "*eq<mode>3"
12427   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12428         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12429                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12430    (clobber (match_scratch:GPR 3 "=r"))
12431    (clobber (match_scratch:GPR 4 "=r"))]
12432   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12433   "#"
12434   "&& 1"
12435   [(set (match_dup 4)
12436         (clz:GPR (match_dup 3)))
12437    (set (match_dup 0)
12438         (lshiftrt:GPR (match_dup 4)
12439                       (match_dup 5)))]
12441   operands[3] = rs6000_emit_eqne (<MODE>mode,
12442                                   operands[1], operands[2], operands[3]);
12444   if (GET_CODE (operands[4]) == SCRATCH)
12445     operands[4] = gen_reg_rtx (<MODE>mode);
12447   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12449   [(set (attr "length")
12450         (if_then_else (match_test "operands[2] == const0_rtx")
12451                       (const_string "8")
12452                       (const_string "12")))])
12454 (define_expand "ne<mode>3"
12455   [(parallel [
12456      (set (match_operand:P 0 "gpc_reg_operand" "=r")
12457           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12458                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12459      (clobber (match_scratch:P 3 "=r"))
12460      (clobber (match_scratch:P 4 "=r"))
12461      (clobber (reg:P CA_REGNO))])]
12462   ""
12464   if (TARGET_ISEL && operands[2] != const0_rtx)
12465     {
12466       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12467                                            operands[2]));
12468       DONE;
12469     }
12472 (define_insn_and_split "*ne<mode>3"
12473   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12474         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12475               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12476    (clobber (match_scratch:P 3 "=r"))
12477    (clobber (match_scratch:P 4 "=r"))
12478    (clobber (reg:P CA_REGNO))]
12479   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12480   "#"
12481   "&& 1"
12482   [(parallel [(set (match_dup 4)
12483                    (plus:P (match_dup 3)
12484                            (const_int -1)))
12485               (set (reg:P CA_REGNO)
12486                    (ne:P (match_dup 3)
12487                          (const_int 0)))])
12488    (parallel [(set (match_dup 0)
12489                    (plus:P (plus:P (not:P (match_dup 4))
12490                                    (reg:P CA_REGNO))
12491                            (match_dup 3)))
12492               (clobber (reg:P CA_REGNO))])]
12494   operands[3] = rs6000_emit_eqne (<MODE>mode,
12495                                   operands[1], operands[2], operands[3]);
12497   if (GET_CODE (operands[4]) == SCRATCH)
12498     operands[4] = gen_reg_rtx (<MODE>mode);
12500   [(set (attr "length")
12501         (if_then_else (match_test "operands[2] == const0_rtx")
12502                       (const_string "8")
12503                       (const_string "12")))])
12505 (define_insn_and_split "*neg_eq_<mode>"
12506   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12507         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12508                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12509    (clobber (match_scratch:P 3 "=r"))
12510    (clobber (match_scratch:P 4 "=r"))
12511    (clobber (reg:P CA_REGNO))]
12512   ""
12513   "#"
12514   ""
12515   [(parallel [(set (match_dup 4)
12516                    (plus:P (match_dup 3)
12517                            (const_int -1)))
12518               (set (reg:P CA_REGNO)
12519                    (ne:P (match_dup 3)
12520                          (const_int 0)))])
12521    (parallel [(set (match_dup 0)
12522                    (plus:P (reg:P CA_REGNO)
12523                            (const_int -1)))
12524               (clobber (reg:P CA_REGNO))])]
12526   operands[3] = rs6000_emit_eqne (<MODE>mode,
12527                                   operands[1], operands[2], operands[3]);
12529   if (GET_CODE (operands[4]) == SCRATCH)
12530     operands[4] = gen_reg_rtx (<MODE>mode);
12532   [(set (attr "length")
12533         (if_then_else (match_test "operands[2] == const0_rtx")
12534                       (const_string "8")
12535                       (const_string "12")))])
12537 (define_insn_and_split "*neg_ne_<mode>"
12538   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12539         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12540                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12541    (clobber (match_scratch:P 3 "=r"))
12542    (clobber (match_scratch:P 4 "=r"))
12543    (clobber (reg:P CA_REGNO))]
12544   ""
12545   "#"
12546   ""
12547   [(parallel [(set (match_dup 4)
12548                    (neg:P (match_dup 3)))
12549               (set (reg:P CA_REGNO)
12550                    (eq:P (match_dup 3)
12551                          (const_int 0)))])
12552    (parallel [(set (match_dup 0)
12553                    (plus:P (reg:P CA_REGNO)
12554                            (const_int -1)))
12555               (clobber (reg:P CA_REGNO))])]
12557   operands[3] = rs6000_emit_eqne (<MODE>mode,
12558                                   operands[1], operands[2], operands[3]);
12560   if (GET_CODE (operands[4]) == SCRATCH)
12561     operands[4] = gen_reg_rtx (<MODE>mode);
12563   [(set (attr "length")
12564         (if_then_else (match_test "operands[2] == const0_rtx")
12565                       (const_string "8")
12566                       (const_string "12")))])
12568 (define_insn_and_split "*plus_eq_<mode>"
12569   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12570         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12571                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12572                 (match_operand:P 3 "gpc_reg_operand" "r")))
12573    (clobber (match_scratch:P 4 "=r"))
12574    (clobber (match_scratch:P 5 "=r"))
12575    (clobber (reg:P CA_REGNO))]
12576   ""
12577   "#"
12578   ""
12579   [(parallel [(set (match_dup 5)
12580                    (neg:P (match_dup 4)))
12581               (set (reg:P CA_REGNO)
12582                    (eq:P (match_dup 4)
12583                          (const_int 0)))])
12584    (parallel [(set (match_dup 0)
12585                    (plus:P (match_dup 3)
12586                            (reg:P CA_REGNO)))
12587               (clobber (reg:P CA_REGNO))])]
12589   operands[4] = rs6000_emit_eqne (<MODE>mode,
12590                                   operands[1], operands[2], operands[4]);
12592   if (GET_CODE (operands[5]) == SCRATCH)
12593     operands[5] = gen_reg_rtx (<MODE>mode);
12595   [(set (attr "length")
12596         (if_then_else (match_test "operands[2] == const0_rtx")
12597                       (const_string "8")
12598                       (const_string "12")))])
12600 (define_insn_and_split "*plus_ne_<mode>"
12601   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12602         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12603                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12604                 (match_operand:P 3 "gpc_reg_operand" "r")))
12605    (clobber (match_scratch:P 4 "=r"))
12606    (clobber (match_scratch:P 5 "=r"))
12607    (clobber (reg:P CA_REGNO))]
12608   ""
12609   "#"
12610   ""
12611   [(parallel [(set (match_dup 5)
12612                    (plus:P (match_dup 4)
12613                            (const_int -1)))
12614               (set (reg:P CA_REGNO)
12615                    (ne:P (match_dup 4)
12616                          (const_int 0)))])
12617    (parallel [(set (match_dup 0)
12618                    (plus:P (match_dup 3)
12619                            (reg:P CA_REGNO)))
12620               (clobber (reg:P CA_REGNO))])]
12622   operands[4] = rs6000_emit_eqne (<MODE>mode,
12623                                   operands[1], operands[2], operands[4]);
12625   if (GET_CODE (operands[5]) == SCRATCH)
12626     operands[5] = gen_reg_rtx (<MODE>mode);
12628   [(set (attr "length")
12629         (if_then_else (match_test "operands[2] == const0_rtx")
12630                       (const_string "8")
12631                       (const_string "12")))])
12633 (define_insn_and_split "*minus_eq_<mode>"
12634   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12635         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12636                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12637                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12638    (clobber (match_scratch:P 4 "=r"))
12639    (clobber (match_scratch:P 5 "=r"))
12640    (clobber (reg:P CA_REGNO))]
12641   ""
12642   "#"
12643   ""
12644   [(parallel [(set (match_dup 5)
12645                    (plus:P (match_dup 4)
12646                            (const_int -1)))
12647               (set (reg:P CA_REGNO)
12648                    (ne:P (match_dup 4)
12649                          (const_int 0)))])
12650    (parallel [(set (match_dup 0)
12651                    (plus:P (plus:P (match_dup 3)
12652                                    (reg:P CA_REGNO))
12653                            (const_int -1)))
12654               (clobber (reg:P CA_REGNO))])]
12656   operands[4] = rs6000_emit_eqne (<MODE>mode,
12657                                   operands[1], operands[2], operands[4]);
12659   if (GET_CODE (operands[5]) == SCRATCH)
12660     operands[5] = gen_reg_rtx (<MODE>mode);
12662   [(set (attr "length")
12663         (if_then_else (match_test "operands[2] == const0_rtx")
12664                       (const_string "8")
12665                       (const_string "12")))])
12667 (define_insn_and_split "*minus_ne_<mode>"
12668   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12669         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12670                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12671                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12672    (clobber (match_scratch:P 4 "=r"))
12673    (clobber (match_scratch:P 5 "=r"))
12674    (clobber (reg:P CA_REGNO))]
12675   ""
12676   "#"
12677   ""
12678   [(parallel [(set (match_dup 5)
12679                    (neg:P (match_dup 4)))
12680               (set (reg:P CA_REGNO)
12681                    (eq:P (match_dup 4)
12682                          (const_int 0)))])
12683    (parallel [(set (match_dup 0)
12684                    (plus:P (plus:P (match_dup 3)
12685                                    (reg:P CA_REGNO))
12686                            (const_int -1)))
12687               (clobber (reg:P CA_REGNO))])]
12689   operands[4] = rs6000_emit_eqne (<MODE>mode,
12690                                   operands[1], operands[2], operands[4]);
12692   if (GET_CODE (operands[5]) == SCRATCH)
12693     operands[5] = gen_reg_rtx (<MODE>mode);
12695   [(set (attr "length")
12696         (if_then_else (match_test "operands[2] == const0_rtx")
12697                       (const_string "8")
12698                       (const_string "12")))])
12700 (define_insn_and_split "*eqsi3_ext<mode>"
12701   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12702         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12703                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12704    (clobber (match_scratch:SI 3 "=r"))
12705    (clobber (match_scratch:SI 4 "=r"))]
12706   ""
12707   "#"
12708   ""
12709   [(set (match_dup 4)
12710         (clz:SI (match_dup 3)))
12711    (set (match_dup 0)
12712         (zero_extend:EXTSI
12713           (lshiftrt:SI (match_dup 4)
12714                        (const_int 5))))]
12716   operands[3] = rs6000_emit_eqne (SImode,
12717                                   operands[1], operands[2], operands[3]);
12719   if (GET_CODE (operands[4]) == SCRATCH)
12720     operands[4] = gen_reg_rtx (SImode);
12722   [(set (attr "length")
12723         (if_then_else (match_test "operands[2] == const0_rtx")
12724                       (const_string "8")
12725                       (const_string "12")))])
12727 (define_insn_and_split "*nesi3_ext<mode>"
12728   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12729         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12730                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12731    (clobber (match_scratch:SI 3 "=r"))
12732    (clobber (match_scratch:SI 4 "=r"))
12733    (clobber (match_scratch:EXTSI 5 "=r"))]
12734   "!TARGET_ISEL"
12735   "#"
12736   "&& 1"
12737   [(set (match_dup 4)
12738         (clz:SI (match_dup 3)))
12739    (set (match_dup 5)
12740         (zero_extend:EXTSI
12741           (lshiftrt:SI (match_dup 4)
12742                        (const_int 5))))
12743    (set (match_dup 0)
12744         (xor:EXTSI (match_dup 5)
12745                    (const_int 1)))]
12747   operands[3] = rs6000_emit_eqne (SImode,
12748                                   operands[1], operands[2], operands[3]);
12750   if (GET_CODE (operands[4]) == SCRATCH)
12751     operands[4] = gen_reg_rtx (SImode);
12752   if (GET_CODE (operands[5]) == SCRATCH)
12753     operands[5] = gen_reg_rtx (<MODE>mode);
12755   [(set (attr "length")
12756         (if_then_else (match_test "operands[2] == const0_rtx")
12757                       (const_string "12")
12758                       (const_string "16")))])
12760 ;; Define both directions of branch and return.  If we need a reload
12761 ;; register, we'd rather use CR0 since it is much easier to copy a
12762 ;; register CC value to there.
12764 (define_insn ""
12765   [(set (pc)
12766         (if_then_else (match_operator 1 "branch_comparison_operator"
12767                                       [(match_operand 2 "cc_reg_operand" "y")
12768                                        (const_int 0)])
12769                       (label_ref (match_operand 0))
12770                       (pc)))]
12771   ""
12773   return output_cbranch (operands[1], "%l0", 0, insn);
12775   [(set_attr "type" "branch")])
12777 (define_insn ""
12778   [(set (pc)
12779         (if_then_else (match_operator 0 "branch_comparison_operator"
12780                                       [(match_operand 1 "cc_reg_operand" "y")
12781                                        (const_int 0)])
12782                       (any_return)
12783                       (pc)))]
12784   "<return_pred>"
12786   return output_cbranch (operands[0], NULL, 0, insn);
12788   [(set_attr "type" "jmpreg")
12789    (set_attr "length" "4")])
12791 ;; Logic on condition register values.
12793 ; This pattern matches things like
12794 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12795 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12796 ;                                  (const_int 1)))
12797 ; which are generated by the branch logic.
12798 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12800 (define_insn "*cceq_ior_compare"
12801   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12802         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12803                         [(match_operator:SI 2
12804                                       "branch_positive_comparison_operator"
12805                                       [(match_operand 3
12806                                                       "cc_reg_operand" "y,y")
12807                                        (const_int 0)])
12808                          (match_operator:SI 4
12809                                       "branch_positive_comparison_operator"
12810                                       [(match_operand 5
12811                                                       "cc_reg_operand" "0,y")
12812                                        (const_int 0)])])
12813                       (const_int 1)))]
12814   ""
12815   "cr%q1 %E0,%j2,%j4"
12816   [(set_attr "type" "cr_logical,delayed_cr")])
12818 ; Why is the constant -1 here, but 1 in the previous pattern?
12819 ; Because ~1 has all but the low bit set.
12820 (define_insn ""
12821   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12822         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12823                         [(not:SI (match_operator:SI 2
12824                                       "branch_positive_comparison_operator"
12825                                       [(match_operand 3
12826                                                       "cc_reg_operand" "y,y")
12827                                        (const_int 0)]))
12828                          (match_operator:SI 4
12829                                 "branch_positive_comparison_operator"
12830                                 [(match_operand 5
12831                                                 "cc_reg_operand" "0,y")
12832                                  (const_int 0)])])
12833                       (const_int -1)))]
12834   ""
12835   "cr%q1 %E0,%j2,%j4"
12836   [(set_attr "type" "cr_logical,delayed_cr")])
12838 (define_insn "*cceq_rev_compare"
12839   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12840         (compare:CCEQ (match_operator:SI 1
12841                                       "branch_positive_comparison_operator"
12842                                       [(match_operand 2
12843                                                       "cc_reg_operand" "0,y")
12844                                        (const_int 0)])
12845                       (const_int 0)))]
12846   ""
12847   "crnot %E0,%j1"
12848   [(set_attr "type" "cr_logical,delayed_cr")])
12850 ;; If we are comparing the result of two comparisons, this can be done
12851 ;; using creqv or crxor.
12853 (define_insn_and_split ""
12854   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12855         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12856                               [(match_operand 2 "cc_reg_operand" "y")
12857                                (const_int 0)])
12858                       (match_operator 3 "branch_comparison_operator"
12859                               [(match_operand 4 "cc_reg_operand" "y")
12860                                (const_int 0)])))]
12861   ""
12862   "#"
12863   ""
12864   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12865                                     (match_dup 5)))]
12866   "
12868   int positive_1, positive_2;
12870   positive_1 = branch_positive_comparison_operator (operands[1],
12871                                                     GET_MODE (operands[1]));
12872   positive_2 = branch_positive_comparison_operator (operands[3],
12873                                                     GET_MODE (operands[3]));
12875   if (! positive_1)
12876     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12877                                                             GET_CODE (operands[1])),
12878                                   SImode,
12879                                   operands[2], const0_rtx);
12880   else if (GET_MODE (operands[1]) != SImode)
12881     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12882                                   operands[2], const0_rtx);
12884   if (! positive_2)
12885     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12886                                                             GET_CODE (operands[3])),
12887                                   SImode,
12888                                   operands[4], const0_rtx);
12889   else if (GET_MODE (operands[3]) != SImode)
12890     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12891                                   operands[4], const0_rtx);
12893   if (positive_1 == positive_2)
12894     {
12895       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12896       operands[5] = constm1_rtx;
12897     }
12898   else
12899     {
12900       operands[5] = const1_rtx;
12901     }
12904 ;; Unconditional branch and return.
12906 (define_insn "jump"
12907   [(set (pc)
12908         (label_ref (match_operand 0)))]
12909   ""
12910   "b %l0"
12911   [(set_attr "type" "branch")])
12913 (define_insn "<return_str>return"
12914   [(any_return)]
12915   "<return_pred>"
12916   "blr"
12917   [(set_attr "type" "jmpreg")])
12919 (define_expand "indirect_jump"
12920   [(set (pc) (match_operand 0 "register_operand"))])
12922 (define_insn "*indirect_jump<mode>"
12923   [(set (pc)
12924         (match_operand:P 0 "register_operand" "c,*l"))]
12925   ""
12926   "b%T0"
12927   [(set_attr "type" "jmpreg")])
12929 ;; Table jump for switch statements:
12930 (define_expand "tablejump"
12931   [(use (match_operand 0))
12932    (use (label_ref (match_operand 1)))]
12933   ""
12935   if (TARGET_32BIT)
12936     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12937   else
12938     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12939   DONE;
12942 (define_expand "tablejumpsi"
12943   [(set (match_dup 3)
12944         (plus:SI (match_operand:SI 0)
12945                  (match_dup 2)))
12946    (parallel [(set (pc)
12947                    (match_dup 3))
12948               (use (label_ref (match_operand 1)))])]
12949   "TARGET_32BIT"
12951   operands[0] = force_reg (SImode, operands[0]);
12952   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12953   operands[3] = gen_reg_rtx (SImode);
12956 (define_expand "tablejumpdi"
12957   [(set (match_dup 4)
12958         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12959    (set (match_dup 3)
12960         (plus:DI (match_dup 4)
12961                  (match_dup 2)))
12962    (parallel [(set (pc)
12963                    (match_dup 3))
12964               (use (label_ref (match_operand 1)))])]
12965   "TARGET_64BIT"
12967   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12968   operands[3] = gen_reg_rtx (DImode);
12969   operands[4] = gen_reg_rtx (DImode);
12972 (define_insn "*tablejump<mode>_internal1"
12973   [(set (pc)
12974         (match_operand:P 0 "register_operand" "c,*l"))
12975    (use (label_ref (match_operand 1)))]
12976   ""
12977   "b%T0"
12978   [(set_attr "type" "jmpreg")])
12980 (define_insn "nop"
12981   [(unspec [(const_int 0)] UNSPEC_NOP)]
12982   ""
12983   "nop")
12985 (define_insn "group_ending_nop"
12986   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12987   ""
12989   if (rs6000_tune == PROCESSOR_POWER6)
12990     return "ori 1,1,0";
12991   return "ori 2,2,0";
12994 ;; Define the subtract-one-and-jump insns, starting with the template
12995 ;; so loop.c knows what to generate.
12997 (define_expand "doloop_end"
12998   [(use (match_operand 0))      ; loop pseudo
12999    (use (match_operand 1))]     ; label
13000   ""
13002   if (TARGET_64BIT)
13003     {
13004       if (GET_MODE (operands[0]) != DImode)
13005         FAIL;
13006       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
13007     }
13008   else
13009     {
13010       if (GET_MODE (operands[0]) != SImode)
13011         FAIL;
13012       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
13013     }
13014   DONE;
13017 (define_expand "ctr<mode>"
13018   [(parallel [(set (pc)
13019                    (if_then_else (ne (match_operand:P 0 "register_operand")
13020                                      (const_int 1))
13021                                  (label_ref (match_operand 1))
13022                                  (pc)))
13023               (set (match_dup 0)
13024                    (plus:P (match_dup 0)
13025                             (const_int -1)))
13026               (clobber (match_scratch:CC 2))
13027               (clobber (match_scratch:P 3))])]
13028   ""
13029   "")
13031 ;; We need to be able to do this for any operand, including MEM, or we
13032 ;; will cause reload to blow up since we don't allow output reloads on
13033 ;; JUMP_INSNs.
13034 ;; For the length attribute to be calculated correctly, the
13035 ;; label MUST be operand 0.
13036 ;; rs6000_legitimate_combined_insn prevents combine creating any of
13037 ;; the ctr<mode> insns.
13039 (define_insn "ctr<mode>_internal1"
13040   [(set (pc)
13041         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13042                           (const_int 1))
13043                       (label_ref (match_operand 0))
13044                       (pc)))
13045    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13046         (plus:P (match_dup 1)
13047                 (const_int -1)))
13048    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13049    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13050   ""
13052   if (which_alternative != 0)
13053     return "#";
13054   else if (get_attr_length (insn) == 4)
13055     return "bdnz %l0";
13056   else
13057     return "bdz $+8\;b %l0";
13059   [(set_attr "type" "branch")
13060    (set_attr "length" "*,16,20,20")])
13062 ;; Similar but use EQ
13064 (define_insn "ctr<mode>_internal2"
13065   [(set (pc)
13066         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13067                           (const_int 1))
13068                       (label_ref (match_operand 0))
13069                       (pc)))
13070    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13071         (plus:P (match_dup 1)
13072                 (const_int -1)))
13073    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13074    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13075   ""
13077   if (which_alternative != 0)
13078     return "#";
13079   else if (get_attr_length (insn) == 4)
13080     return "bdz %l0";
13081   else
13082     return "bdnz $+8\;b %l0";
13084   [(set_attr "type" "branch")
13085    (set_attr "length" "*,16,20,20")])
13087 ;; Now the splitters if we could not allocate the CTR register
13089 (define_split
13090   [(set (pc)
13091         (if_then_else (match_operator 2 "comparison_operator"
13092                                       [(match_operand:P 1 "gpc_reg_operand")
13093                                        (const_int 1)])
13094                       (match_operand 5)
13095                       (match_operand 6)))
13096    (set (match_operand:P 0 "int_reg_operand")
13097         (plus:P (match_dup 1)
13098                 (const_int -1)))
13099    (clobber (match_scratch:CC 3))
13100    (clobber (match_scratch:P 4))]
13101   "reload_completed"
13102   [(set (match_dup 3)
13103         (compare:CC (match_dup 1)
13104                     (const_int 1)))
13105    (set (match_dup 0)
13106         (plus:P (match_dup 1)
13107                 (const_int -1)))
13108    (set (pc)
13109         (if_then_else (match_dup 7)
13110                       (match_dup 5)
13111                       (match_dup 6)))]
13113   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
13114                                 const0_rtx);
13117 (define_split
13118   [(set (pc)
13119         (if_then_else (match_operator 2 "comparison_operator"
13120                                       [(match_operand:P 1 "gpc_reg_operand")
13121                                        (const_int 1)])
13122                       (match_operand 5)
13123                       (match_operand 6)))
13124    (set (match_operand:P 0 "nonimmediate_operand")
13125         (plus:P (match_dup 1)
13126                 (const_int -1)))
13127    (clobber (match_scratch:CC 3))
13128    (clobber (match_scratch:P 4))]
13129   "reload_completed && !gpc_reg_operand (operands[0], SImode)"
13130   [(set (match_dup 3)
13131         (compare:CC (match_dup 1)
13132                     (const_int 1)))
13133    (set (match_dup 4)
13134         (plus:P (match_dup 1)
13135                 (const_int -1)))
13136    (set (match_dup 0)
13137         (match_dup 4))
13138    (set (pc)
13139         (if_then_else (match_dup 7)
13140                       (match_dup 5)
13141                       (match_dup 6)))]
13143   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
13144                                 const0_rtx);
13147 (define_insn "trap"
13148   [(trap_if (const_int 1) (const_int 0))]
13149   ""
13150   "trap"
13151   [(set_attr "type" "trap")])
13153 (define_expand "ctrap<mode>4"
13154   [(trap_if (match_operator 0 "ordered_comparison_operator"
13155                             [(match_operand:GPR 1 "register_operand")
13156                              (match_operand:GPR 2 "reg_or_short_operand")])
13157             (match_operand 3 "zero_constant" ""))]
13158   ""
13159   "")
13161 (define_insn ""
13162   [(trap_if (match_operator 0 "ordered_comparison_operator"
13163                             [(match_operand:GPR 1 "register_operand" "r")
13164                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13165             (const_int 0))]
13166   ""
13167   "t<wd>%V0%I2 %1,%2"
13168   [(set_attr "type" "trap")])
13170 ;; Insns related to generating the function prologue and epilogue.
13172 (define_expand "prologue"
13173   [(use (const_int 0))]
13174   ""
13176   rs6000_emit_prologue ();
13177   if (!TARGET_SCHED_PROLOG)
13178     emit_insn (gen_blockage ());
13179   DONE;
13182 (define_insn "*movesi_from_cr_one"
13183   [(match_parallel 0 "mfcr_operation"
13184                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13185                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13186                                      (match_operand 3 "immediate_operand" "n")]
13187                           UNSPEC_MOVESI_FROM_CR))])]
13188   "TARGET_MFCRF"
13189   "*
13191   int mask = 0;
13192   int i;
13193   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13194   {
13195     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13196     operands[4] = GEN_INT (mask);
13197     output_asm_insn (\"mfcr %1,%4\", operands);
13198   }
13199   return \"\";
13201   [(set_attr "type" "mfcrf")])
13203 ;; Don't include the volatile CRs since their values are not used wrt CR save
13204 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13205 ;; prologue past an insn (early exit test) that defines a register used in the
13206 ;; prologue.
13207 (define_insn "prologue_movesi_from_cr"
13208   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13209         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13210                     (reg:CC CR4_REGNO)]
13211                    UNSPEC_MOVESI_FROM_CR))]
13212   ""
13213   "mfcr %0"
13214   [(set_attr "type" "mfcr")])
13216 (define_insn "*crsave"
13217   [(match_parallel 0 "crsave_operation"
13218                    [(set (match_operand:SI 1 "memory_operand" "=m")
13219                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13220   ""
13221   "stw %2,%1"
13222   [(set_attr "type" "store")])
13224 (define_insn "*stmw"
13225   [(match_parallel 0 "stmw_operation"
13226                    [(set (match_operand:SI 1 "memory_operand" "=m")
13227                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13228   "TARGET_MULTIPLE"
13229   "stmw %2,%1"
13230   [(set_attr "type" "store")
13231    (set_attr "update" "yes")
13232    (set_attr "indexed" "yes")])
13234 ; The following comment applies to:
13235 ;     save_gpregs_*
13236 ;     save_fpregs_*
13237 ;     restore_gpregs*
13238 ;     return_and_restore_gpregs*
13239 ;     return_and_restore_fpregs*
13240 ;     return_and_restore_fpregs_aix*
13242 ; The out-of-line save / restore functions expects one input argument.
13243 ; Since those are not standard call_insn's, we must avoid using
13244 ; MATCH_OPERAND for that argument. That way the register rename
13245 ; optimization will not try to rename this register.
13246 ; Each pattern is repeated for each possible register number used in 
13247 ; various ABIs (r11, r1, and for some functions r12)
13249 (define_insn "*save_gpregs_<mode>_r11"
13250   [(match_parallel 0 "any_parallel_operand"
13251                    [(clobber (reg:P LR_REGNO))
13252                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13253                     (use (reg:P 11))
13254                     (set (match_operand:P 2 "memory_operand" "=m")
13255                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13256   ""
13257   "bl %1"
13258   [(set_attr "type" "branch")
13259    (set_attr "length" "4")])
13261 (define_insn "*save_gpregs_<mode>_r12"
13262   [(match_parallel 0 "any_parallel_operand"
13263                    [(clobber (reg:P LR_REGNO))
13264                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13265                     (use (reg:P 12))
13266                     (set (match_operand:P 2 "memory_operand" "=m")
13267                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13268   ""
13269   "bl %1"
13270   [(set_attr "type" "branch")
13271    (set_attr "length" "4")])
13273 (define_insn "*save_gpregs_<mode>_r1"
13274   [(match_parallel 0 "any_parallel_operand"
13275                    [(clobber (reg:P LR_REGNO))
13276                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13277                     (use (reg:P 1))
13278                     (set (match_operand:P 2 "memory_operand" "=m")
13279                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13280   ""
13281   "bl %1"
13282   [(set_attr "type" "branch")
13283    (set_attr "length" "4")])
13285 (define_insn "*save_fpregs_<mode>_r11"
13286   [(match_parallel 0 "any_parallel_operand"
13287                    [(clobber (reg:P LR_REGNO))
13288                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13289                     (use (reg:P 11))
13290                     (set (match_operand:DF 2 "memory_operand" "=m")
13291                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13292   ""
13293   "bl %1"
13294   [(set_attr "type" "branch")
13295    (set_attr "length" "4")])
13297 (define_insn "*save_fpregs_<mode>_r12"
13298   [(match_parallel 0 "any_parallel_operand"
13299                    [(clobber (reg:P LR_REGNO))
13300                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13301                     (use (reg:P 12))
13302                     (set (match_operand:DF 2 "memory_operand" "=m")
13303                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13304   ""
13305   "bl %1"
13306   [(set_attr "type" "branch")
13307    (set_attr "length" "4")])
13309 (define_insn "*save_fpregs_<mode>_r1"
13310   [(match_parallel 0 "any_parallel_operand"
13311                    [(clobber (reg:P LR_REGNO))
13312                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13313                     (use (reg:P 1))
13314                     (set (match_operand:DF 2 "memory_operand" "=m")
13315                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13316   ""
13317   "bl %1"
13318   [(set_attr "type" "branch")
13319    (set_attr "length" "4")])
13321 ; This is to explain that changes to the stack pointer should
13322 ; not be moved over loads from or stores to stack memory.
13323 (define_insn "stack_tie"
13324   [(match_parallel 0 "tie_operand"
13325                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13326   ""
13327   ""
13328   [(set_attr "length" "0")])
13330 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13331 ; stay behind all restores from the stack, it cannot be reordered to before
13332 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13333 (define_insn "stack_restore_tie"
13334   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13335         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13336                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13337    (set (mem:BLK (scratch)) (const_int 0))]
13338   "TARGET_32BIT"
13339   "@
13340    mr %0,%1
13341    add%I2 %0,%1,%2"
13342   [(set_attr "type" "*,add")])
13344 (define_expand "epilogue"
13345   [(use (const_int 0))]
13346   ""
13348   if (!TARGET_SCHED_PROLOG)
13349     emit_insn (gen_blockage ());
13350   rs6000_emit_epilogue (FALSE);
13351   DONE;
13354 ; On some processors, doing the mtcrf one CC register at a time is
13355 ; faster (like on the 604e).  On others, doing them all at once is
13356 ; faster; for instance, on the 601 and 750.
13358 (define_expand "movsi_to_cr_one"
13359   [(set (match_operand:CC 0 "cc_reg_operand" "")
13360         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13361                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13362   ""
13363   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13365 (define_insn "*movsi_to_cr"
13366   [(match_parallel 0 "mtcrf_operation"
13367                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13368                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13369                                      (match_operand 3 "immediate_operand" "n")]
13370                                     UNSPEC_MOVESI_TO_CR))])]
13371  ""
13372  "*
13374   int mask = 0;
13375   int i;
13376   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13377     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13378   operands[4] = GEN_INT (mask);
13379   return \"mtcrf %4,%2\";
13381   [(set_attr "type" "mtcr")])
13383 (define_insn "*mtcrfsi"
13384   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13385         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13386                     (match_operand 2 "immediate_operand" "n")]
13387                    UNSPEC_MOVESI_TO_CR))]
13388   "GET_CODE (operands[0]) == REG
13389    && CR_REGNO_P (REGNO (operands[0]))
13390    && GET_CODE (operands[2]) == CONST_INT
13391    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13392   "mtcrf %R0,%1"
13393   [(set_attr "type" "mtcr")])
13395 ; The load-multiple instructions have similar properties.
13396 ; Note that "load_multiple" is a name known to the machine-independent
13397 ; code that actually corresponds to the PowerPC load-string.
13399 (define_insn "*lmw"
13400   [(match_parallel 0 "lmw_operation"
13401                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13402                          (match_operand:SI 2 "memory_operand" "m"))])]
13403   "TARGET_MULTIPLE"
13404   "lmw %1,%2"
13405   [(set_attr "type" "load")
13406    (set_attr "update" "yes")
13407    (set_attr "indexed" "yes")
13408    (set_attr "cell_micro" "always")])
13410 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13411 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13413 ; The following comment applies to:
13414 ;     save_gpregs_*
13415 ;     save_fpregs_*
13416 ;     restore_gpregs*
13417 ;     return_and_restore_gpregs*
13418 ;     return_and_restore_fpregs*
13419 ;     return_and_restore_fpregs_aix*
13421 ; The out-of-line save / restore functions expects one input argument.
13422 ; Since those are not standard call_insn's, we must avoid using
13423 ; MATCH_OPERAND for that argument. That way the register rename
13424 ; optimization will not try to rename this register.
13425 ; Each pattern is repeated for each possible register number used in 
13426 ; various ABIs (r11, r1, and for some functions r12)
13428 (define_insn "*restore_gpregs_<mode>_r11"
13429  [(match_parallel 0 "any_parallel_operand"
13430                   [(clobber (reg:P LR_REGNO))
13431                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13432                    (use (reg:P 11))
13433                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13434                         (match_operand:P 3 "memory_operand" "m"))])]
13435  ""
13436  "bl %1"
13437  [(set_attr "type" "branch")
13438   (set_attr "length" "4")])
13440 (define_insn "*restore_gpregs_<mode>_r12"
13441  [(match_parallel 0 "any_parallel_operand"
13442                   [(clobber (reg:P LR_REGNO))
13443                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13444                    (use (reg:P 12))
13445                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13446                         (match_operand:P 3 "memory_operand" "m"))])]
13447  ""
13448  "bl %1"
13449  [(set_attr "type" "branch")
13450   (set_attr "length" "4")])
13452 (define_insn "*restore_gpregs_<mode>_r1"
13453  [(match_parallel 0 "any_parallel_operand"
13454                   [(clobber (reg:P LR_REGNO))
13455                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13456                    (use (reg:P 1))
13457                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13458                         (match_operand:P 3 "memory_operand" "m"))])]
13459  ""
13460  "bl %1"
13461  [(set_attr "type" "branch")
13462   (set_attr "length" "4")])
13464 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13465  [(match_parallel 0 "any_parallel_operand"
13466                   [(return)
13467                    (clobber (reg:P LR_REGNO))
13468                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13469                    (use (reg:P 11))
13470                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13471                         (match_operand:P 3 "memory_operand" "m"))])]
13472  ""
13473  "b %1"
13474  [(set_attr "type" "branch")
13475   (set_attr "length" "4")])
13477 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13478  [(match_parallel 0 "any_parallel_operand"
13479                   [(return)
13480                    (clobber (reg:P LR_REGNO))
13481                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13482                    (use (reg:P 12))
13483                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13484                         (match_operand:P 3 "memory_operand" "m"))])]
13485  ""
13486  "b %1"
13487  [(set_attr "type" "branch")
13488   (set_attr "length" "4")])
13490 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13491  [(match_parallel 0 "any_parallel_operand"
13492                   [(return)
13493                    (clobber (reg:P LR_REGNO))
13494                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13495                    (use (reg:P 1))
13496                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13497                         (match_operand:P 3 "memory_operand" "m"))])]
13498  ""
13499  "b %1"
13500  [(set_attr "type" "branch")
13501   (set_attr "length" "4")])
13503 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13504  [(match_parallel 0 "any_parallel_operand"
13505                   [(return)
13506                    (clobber (reg:P LR_REGNO))
13507                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13508                    (use (reg:P 11))
13509                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13510                         (match_operand:DF 3 "memory_operand" "m"))])]
13511  ""
13512  "b %1"
13513  [(set_attr "type" "branch")
13514   (set_attr "length" "4")])
13516 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13517  [(match_parallel 0 "any_parallel_operand"
13518                   [(return)
13519                    (clobber (reg:P LR_REGNO))
13520                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13521                    (use (reg:P 12))
13522                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13523                         (match_operand:DF 3 "memory_operand" "m"))])]
13524  ""
13525  "b %1"
13526  [(set_attr "type" "branch")
13527   (set_attr "length" "4")])
13529 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13530  [(match_parallel 0 "any_parallel_operand"
13531                   [(return)
13532                    (clobber (reg:P LR_REGNO))
13533                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13534                    (use (reg:P 1))
13535                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13536                         (match_operand:DF 3 "memory_operand" "m"))])]
13537  ""
13538  "b %1"
13539  [(set_attr "type" "branch")
13540   (set_attr "length" "4")])
13542 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13543  [(match_parallel 0 "any_parallel_operand"
13544                   [(return)
13545                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13546                    (use (reg:P 11))
13547                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13548                         (match_operand:DF 3 "memory_operand" "m"))])]
13549  ""
13550  "b %1"
13551  [(set_attr "type" "branch")
13552   (set_attr "length" "4")])
13554 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13555  [(match_parallel 0 "any_parallel_operand"
13556                   [(return)
13557                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13558                    (use (reg:P 1))
13559                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13560                         (match_operand:DF 3 "memory_operand" "m"))])]
13561  ""
13562  "b %1"
13563  [(set_attr "type" "branch")
13564   (set_attr "length" "4")])
13566 ; This is used in compiling the unwind routines.
13567 (define_expand "eh_return"
13568   [(use (match_operand 0 "general_operand" ""))]
13569   ""
13570   "
13572   if (TARGET_32BIT)
13573     emit_insn (gen_eh_set_lr_si (operands[0]));
13574   else
13575     emit_insn (gen_eh_set_lr_di (operands[0]));
13576   DONE;
13579 ; We can't expand this before we know where the link register is stored.
13580 (define_insn "eh_set_lr_<mode>"
13581   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13582                     UNSPECV_EH_RR)
13583    (clobber (match_scratch:P 1 "=&b"))]
13584   ""
13585   "#")
13587 (define_split
13588   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13589    (clobber (match_scratch 1 ""))]
13590   "reload_completed"
13591   [(const_int 0)]
13592   "
13594   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13595   DONE;
13598 (define_insn "prefetch"
13599   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13600              (match_operand:SI 1 "const_int_operand" "n")
13601              (match_operand:SI 2 "const_int_operand" "n"))]
13602   ""
13603   "*
13605   if (GET_CODE (operands[0]) == REG)
13606     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13607   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13609   [(set_attr "type" "load")])
13611 ;; Handle -fsplit-stack.
13613 (define_expand "split_stack_prologue"
13614   [(const_int 0)]
13615   ""
13617   rs6000_expand_split_stack_prologue ();
13618   DONE;
13621 (define_expand "load_split_stack_limit"
13622   [(set (match_operand 0)
13623         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13624   ""
13626   emit_insn (gen_rtx_SET (operands[0],
13627                           gen_rtx_UNSPEC (Pmode,
13628                                           gen_rtvec (1, const0_rtx),
13629                                           UNSPEC_STACK_CHECK)));
13630   DONE;
13633 (define_insn "load_split_stack_limit_di"
13634   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13635         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13636   "TARGET_64BIT"
13637   "ld %0,-0x7040(13)"
13638   [(set_attr "type" "load")
13639    (set_attr "update" "no")
13640    (set_attr "indexed" "no")])
13642 (define_insn "load_split_stack_limit_si"
13643   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13644         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13645   "!TARGET_64BIT"
13646   "lwz %0,-0x7020(2)"
13647   [(set_attr "type" "load")
13648    (set_attr "update" "no")
13649    (set_attr "indexed" "no")])
13651 ;; A return instruction which the middle-end doesn't see.
13652 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13653 ;; after the call to __morestack.
13654 (define_insn "split_stack_return"
13655   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13656   ""
13657   "blr"
13658   [(set_attr "type" "jmpreg")])
13660 ;; If there are operand 0 bytes available on the stack, jump to
13661 ;; operand 1.
13662 (define_expand "split_stack_space_check"
13663   [(set (match_dup 2)
13664         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13665    (set (match_dup 3)
13666         (minus (reg STACK_POINTER_REGNUM)
13667                (match_operand 0)))
13668    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13669    (set (pc) (if_then_else
13670               (geu (match_dup 4) (const_int 0))
13671               (label_ref (match_operand 1))
13672               (pc)))]
13673   ""
13675   rs6000_split_stack_space_check (operands[0], operands[1]);
13676   DONE;
13679 (define_insn "bpermd_<mode>"
13680   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13681         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13682                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13683   "TARGET_POPCNTD"
13684   "bpermd %0,%1,%2"
13685   [(set_attr "type" "popcnt")])
13688 ;; Builtin fma support.  Handle 
13689 ;; Note that the conditions for expansion are in the FMA_F iterator.
13691 (define_expand "fma<mode>4"
13692   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13693         (fma:FMA_F
13694           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13695           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13696           (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13697   ""
13698   "")
13700 (define_insn "*fma<mode>4_fpr"
13701   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13702         (fma:SFDF
13703           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13704           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13705           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13706   "TARGET_<MODE>_FPR"
13707   "@
13708    fmadd<Ftrad> %0,%1,%2,%3
13709    xsmadda<Fvsx> %x0,%x1,%x2
13710    xsmaddm<Fvsx> %x0,%x1,%x3"
13711   [(set_attr "type" "fp")
13712    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13714 ; Altivec only has fma and nfms.
13715 (define_expand "fms<mode>4"
13716   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13717         (fma:FMA_F
13718           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13719           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13720           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13721   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13722   "")
13724 (define_insn "*fms<mode>4_fpr"
13725   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13726         (fma:SFDF
13727          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13728          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13729          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13730   "TARGET_<MODE>_FPR"
13731   "@
13732    fmsub<Ftrad> %0,%1,%2,%3
13733    xsmsuba<Fvsx> %x0,%x1,%x2
13734    xsmsubm<Fvsx> %x0,%x1,%x3"
13735   [(set_attr "type" "fp")
13736    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13738 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13739 (define_expand "fnma<mode>4"
13740   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13741         (neg:FMA_F
13742           (fma:FMA_F
13743             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13744             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13745             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13746   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13747   "")
13749 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13750 (define_expand "fnms<mode>4"
13751   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13752         (neg:FMA_F
13753           (fma:FMA_F
13754             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13755             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13756             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13757   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13758   "")
13760 ; Not an official optab name, but used from builtins.
13761 (define_expand "nfma<mode>4"
13762   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13763         (neg:FMA_F
13764           (fma:FMA_F
13765             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13766             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13767             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13768   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13769   "")
13771 (define_insn "*nfma<mode>4_fpr"
13772   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13773         (neg:SFDF
13774          (fma:SFDF
13775           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13776           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13777           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13778   "TARGET_<MODE>_FPR"
13779   "@
13780    fnmadd<Ftrad> %0,%1,%2,%3
13781    xsnmadda<Fvsx> %x0,%x1,%x2
13782    xsnmaddm<Fvsx> %x0,%x1,%x3"
13783   [(set_attr "type" "fp")
13784    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13786 ; Not an official optab name, but used from builtins.
13787 (define_expand "nfms<mode>4"
13788   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13789         (neg:FMA_F
13790           (fma:FMA_F
13791             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13792             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13793             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13794   ""
13795   "")
13797 (define_insn "*nfmssf4_fpr"
13798   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13799         (neg:SFDF
13800          (fma:SFDF
13801           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13802           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13803           (neg:SFDF
13804            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13805   "TARGET_<MODE>_FPR"
13806   "@
13807    fnmsub<Ftrad> %0,%1,%2,%3
13808    xsnmsuba<Fvsx> %x0,%x1,%x2
13809    xsnmsubm<Fvsx> %x0,%x1,%x3"
13810   [(set_attr "type" "fp")
13811    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13814 (define_expand "rs6000_get_timebase"
13815   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13816   ""
13818   if (TARGET_POWERPC64)
13819     emit_insn (gen_rs6000_mftb_di (operands[0]));
13820   else
13821     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13822   DONE;
13825 (define_insn "rs6000_get_timebase_ppc32"
13826   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13827         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13828    (clobber (match_scratch:SI 1 "=r"))
13829    (clobber (match_scratch:CC 2 "=y"))]
13830   "!TARGET_POWERPC64"
13832   if (WORDS_BIG_ENDIAN)
13833     if (TARGET_MFCRF)
13834       {
13835         return "mfspr %0,269\;"
13836                "mfspr %L0,268\;"
13837                "mfspr %1,269\;"
13838                "cmpw %2,%0,%1\;"
13839                "bne- %2,$-16";
13840       }
13841     else
13842       {
13843         return "mftbu %0\;"
13844                "mftb %L0\;"
13845                "mftbu %1\;"
13846                "cmpw %2,%0,%1\;"
13847                "bne- %2,$-16";
13848       }
13849   else
13850     if (TARGET_MFCRF)
13851       {
13852         return "mfspr %L0,269\;"
13853                "mfspr %0,268\;"
13854                "mfspr %1,269\;"
13855                "cmpw %2,%L0,%1\;"
13856                "bne- %2,$-16";
13857       }
13858     else
13859       {
13860         return "mftbu %L0\;"
13861                "mftb %0\;"
13862                "mftbu %1\;"
13863                "cmpw %2,%L0,%1\;"
13864                "bne- %2,$-16";
13865       }
13867   [(set_attr "length" "20")])
13869 (define_insn "rs6000_mftb_<mode>"
13870   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13871         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13872   ""
13874   if (TARGET_MFCRF)
13875     return "mfspr %0,268";
13876   else
13877     return "mftb %0";
13881 (define_insn "rs6000_mffs"
13882   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13883         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13884   "TARGET_HARD_FLOAT"
13885   "mffs %0")
13887 (define_insn "rs6000_mtfsf"
13888   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13889                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13890                     UNSPECV_MTFSF)]
13891   "TARGET_HARD_FLOAT"
13892   "mtfsf %0,%1")
13895 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13896 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13897 ;; register that is being loaded.  The fused ops must be physically adjacent.
13899 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13900 ;; before register allocation, and is meant to reduce the lifetime for the
13901 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13902 ;; to use the register that is being load.  The peephole2 then gathers any
13903 ;; other fused possibilities that it can find after register allocation.  If
13904 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13906 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13907 ;; before register allocation, so that we can avoid allocating a temporary base
13908 ;; register that won't be used, and that we try to load into base registers,
13909 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13910 ;; (addis followed by load) even on power8.
13912 (define_split
13913   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13914         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13915   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13916   [(parallel [(set (match_dup 0) (match_dup 2))
13917               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13918               (use (match_dup 3))
13919               (clobber (scratch:DI))])]
13921   operands[2] = fusion_wrap_memory_address (operands[1]);
13922   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13925 (define_insn "*toc_fusionload_<mode>"
13926   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13927         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13928    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13929    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13930    (clobber (match_scratch:DI 3 "=X,&b"))]
13931   "TARGET_TOC_FUSION_INT"
13933   if (base_reg_operand (operands[0], <MODE>mode))
13934     return emit_fusion_gpr_load (operands[0], operands[1]);
13936   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13938   [(set_attr "type" "load")
13939    (set_attr "length" "8")])
13941 (define_insn "*toc_fusionload_di"
13942   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13943         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13944    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13945    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13946    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13947   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13948    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13950   if (base_reg_operand (operands[0], DImode))
13951     return emit_fusion_gpr_load (operands[0], operands[1]);
13953   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13955   [(set_attr "type" "load")
13956    (set_attr "length" "8")])
13959 ;; Find cases where the addis that feeds into a load instruction is either used
13960 ;; once or is the same as the target register, and replace it with the fusion
13961 ;; insn
13963 (define_peephole2
13964   [(set (match_operand:P 0 "base_reg_operand" "")
13965         (match_operand:P 1 "fusion_gpr_addis" ""))
13966    (set (match_operand:INT1 2 "base_reg_operand" "")
13967         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13968   "TARGET_P8_FUSION
13969    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13970                          operands[3])"
13971   [(const_int 0)]
13973   expand_fusion_gpr_load (operands);
13974   DONE;
13977 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13978 ;; reload)
13980 (define_insn "fusion_gpr_load_<mode>"
13981   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13982         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13983                      UNSPEC_FUSION_GPR))]
13984   "TARGET_P8_FUSION"
13986   return emit_fusion_gpr_load (operands[0], operands[1]);
13988   [(set_attr "type" "load")
13989    (set_attr "length" "8")])
13992 ;; ISA 3.0 (power9) fusion support
13993 ;; Merge addis with floating load/store to FPRs (or GPRs).
13994 (define_peephole2
13995   [(set (match_operand:P 0 "base_reg_operand" "")
13996         (match_operand:P 1 "fusion_gpr_addis" ""))
13997    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13998         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13999   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
14000    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
14001   [(const_int 0)]
14003   expand_fusion_p9_load (operands);
14004   DONE;
14007 (define_peephole2
14008   [(set (match_operand:P 0 "base_reg_operand" "")
14009         (match_operand:P 1 "fusion_gpr_addis" ""))
14010    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
14011         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
14012   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
14013    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
14014    && !rtx_equal_p (operands[0], operands[3])"
14015   [(const_int 0)]
14017   expand_fusion_p9_store (operands);
14018   DONE;
14021 (define_peephole2
14022   [(set (match_operand:SDI 0 "int_reg_operand" "")
14023         (match_operand:SDI 1 "upper16_cint_operand" ""))
14024    (set (match_dup 0)
14025         (ior:SDI (match_dup 0)
14026                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
14027   "TARGET_P9_FUSION"
14028   [(set (match_dup 0)
14029         (unspec:SDI [(match_dup 1)
14030                      (match_dup 2)] UNSPEC_FUSION_P9))])
14032 (define_peephole2
14033   [(set (match_operand:SDI 0 "int_reg_operand" "")
14034         (match_operand:SDI 1 "upper16_cint_operand" ""))
14035    (set (match_operand:SDI 2 "int_reg_operand" "")
14036         (ior:SDI (match_dup 0)
14037                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
14038   "TARGET_P9_FUSION
14039    && !rtx_equal_p (operands[0], operands[2])
14040    && peep2_reg_dead_p (2, operands[0])"
14041   [(set (match_dup 2)
14042         (unspec:SDI [(match_dup 1)
14043                      (match_dup 3)] UNSPEC_FUSION_P9))])
14045 ;; Fusion insns, created by the define_peephole2 above (and eventually by
14046 ;; reload).  Because we want to eventually have secondary_reload generate
14047 ;; these, they have to have a single alternative that gives the register
14048 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
14049 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
14050   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
14051         (unspec:GPR_FUSION
14052          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14053          UNSPEC_FUSION_P9))
14054    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14055   "TARGET_P9_FUSION"
14057   /* This insn is a secondary reload insn, which cannot have alternatives.
14058      If we are not loading up register 0, use the power8 fusion instead.  */
14059   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
14060     return emit_fusion_gpr_load (operands[0], operands[1]);
14062   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14064   [(set_attr "type" "load")
14065    (set_attr "length" "8")])
14067 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
14068   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14069         (unspec:GPR_FUSION
14070          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
14071          UNSPEC_FUSION_P9))
14072    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14073   "TARGET_P9_FUSION"
14075   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14077   [(set_attr "type" "store")
14078    (set_attr "length" "8")])
14080 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
14081   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
14082         (unspec:FPR_FUSION
14083          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14084          UNSPEC_FUSION_P9))
14085    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14086   "TARGET_P9_FUSION"
14088   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14090   [(set_attr "type" "fpload")
14091    (set_attr "length" "8")])
14093 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14094   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14095         (unspec:FPR_FUSION
14096          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14097          UNSPEC_FUSION_P9))
14098    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14099   "TARGET_P9_FUSION"
14101   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14103   [(set_attr "type" "fpstore")
14104    (set_attr "length" "8")])
14106 (define_insn "*fusion_p9_<mode>_constant"
14107   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14108         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14109                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
14110                     UNSPEC_FUSION_P9))] 
14111   "TARGET_P9_FUSION"
14113   emit_fusion_addis (operands[0], operands[1]);
14114   return "ori %0,%0,%2";
14116   [(set_attr "type" "two")
14117    (set_attr "length" "8")])
14120 ;; Optimize cases where we want to do a D-form load (register+offset) on
14121 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14122 ;; has generated:
14123 ;;      LFD 0,32(3)
14124 ;;      XXLOR 32,0,0
14126 ;; and we change this to:
14127 ;;      LI 0,32
14128 ;;      LXSDX 32,3,9
14130 (define_peephole2
14131   [(match_scratch:P 0 "b")
14132    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14133         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14134    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14135         (match_dup 1))]
14136   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14137   [(set (match_dup 0)
14138         (match_dup 4))
14139    (set (match_dup 3)
14140         (match_dup 5))]
14142   rtx tmp_reg = operands[0];
14143   rtx mem = operands[2];
14144   rtx addr = XEXP (mem, 0);
14145   rtx add_op0, add_op1, new_addr;
14147   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14148   add_op0 = XEXP (addr, 0);
14149   add_op1 = XEXP (addr, 1);
14150   gcc_assert (REG_P (add_op0));
14151   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14153   operands[4] = add_op1;
14154   operands[5] = change_address (mem, <MODE>mode, new_addr);
14157 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14158 ;; Altivec register, and the register allocator has generated:
14159 ;;      XXLOR 0,32,32
14160 ;;      STFD 0,32(3)
14162 ;; and we change this to:
14163 ;;      LI 0,32
14164 ;;      STXSDX 32,3,9
14166 (define_peephole2
14167   [(match_scratch:P 0 "b")
14168    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14169         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14170    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14171         (match_dup 1))]
14172   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14173   [(set (match_dup 0)
14174         (match_dup 4))
14175    (set (match_dup 5)
14176         (match_dup 2))]
14178   rtx tmp_reg = operands[0];
14179   rtx mem = operands[3];
14180   rtx addr = XEXP (mem, 0);
14181   rtx add_op0, add_op1, new_addr;
14183   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14184   add_op0 = XEXP (addr, 0);
14185   add_op1 = XEXP (addr, 1);
14186   gcc_assert (REG_P (add_op0));
14187   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14189   operands[4] = add_op1;
14190   operands[5] = change_address (mem, <MODE>mode, new_addr);
14192    
14194 ;; Miscellaneous ISA 2.06 (power7) instructions
14195 (define_insn "addg6s"
14196   [(set (match_operand:SI 0 "register_operand" "=r")
14197         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14198                     (match_operand:SI 2 "register_operand" "r")]
14199                    UNSPEC_ADDG6S))]
14200   "TARGET_POPCNTD"
14201   "addg6s %0,%1,%2"
14202   [(set_attr "type" "integer")
14203    (set_attr "length" "4")])
14205 (define_insn "cdtbcd"
14206   [(set (match_operand:SI 0 "register_operand" "=r")
14207         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14208                    UNSPEC_CDTBCD))]
14209   "TARGET_POPCNTD"
14210   "cdtbcd %0,%1"
14211   [(set_attr "type" "integer")
14212    (set_attr "length" "4")])
14214 (define_insn "cbcdtd"
14215   [(set (match_operand:SI 0 "register_operand" "=r")
14216         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14217                    UNSPEC_CBCDTD))]
14218   "TARGET_POPCNTD"
14219   "cbcdtd %0,%1"
14220   [(set_attr "type" "integer")
14221    (set_attr "length" "4")])
14223 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14224                                         UNSPEC_DIVEO
14225                                         UNSPEC_DIVEU
14226                                         UNSPEC_DIVEUO])
14228 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
14229                              (UNSPEC_DIVEO      "eo")
14230                              (UNSPEC_DIVEU      "eu")
14231                              (UNSPEC_DIVEUO     "euo")])
14233 (define_insn "div<div_extend>_<mode>"
14234   [(set (match_operand:GPR 0 "register_operand" "=r")
14235         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14236                      (match_operand:GPR 2 "register_operand" "r")]
14237                     UNSPEC_DIV_EXTEND))]
14238   "TARGET_POPCNTD"
14239   "div<wd><div_extend> %0,%1,%2"
14240   [(set_attr "type" "div")
14241    (set_attr "size" "<bits>")])
14244 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14246 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14247 (define_mode_attr FP128_64 [(TF "DF")
14248                             (IF "DF")
14249                             (TD "DI")
14250                             (KF "DI")])
14252 (define_expand "unpack<mode>"
14253   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14254         (unspec:<FP128_64>
14255          [(match_operand:FMOVE128 1 "register_operand" "")
14256           (match_operand:QI 2 "const_0_to_1_operand" "")]
14257          UNSPEC_UNPACK_128BIT))]
14258   "FLOAT128_2REG_P (<MODE>mode)"
14259   "")
14261 (define_insn_and_split "unpack<mode>_dm"
14262   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14263         (unspec:<FP128_64>
14264          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14265           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14266          UNSPEC_UNPACK_128BIT))]
14267   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14268   "#"
14269   "&& reload_completed"
14270   [(set (match_dup 0) (match_dup 3))]
14272   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14274   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14275     {
14276       emit_note (NOTE_INSN_DELETED);
14277       DONE;
14278     }
14280   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14282   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14283    (set_attr "length" "4")])
14285 (define_insn_and_split "unpack<mode>_nodm"
14286   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14287         (unspec:<FP128_64>
14288          [(match_operand:FMOVE128 1 "register_operand" "d,d")
14289           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14290          UNSPEC_UNPACK_128BIT))]
14291   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14292   "#"
14293   "&& reload_completed"
14294   [(set (match_dup 0) (match_dup 3))]
14296   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14298   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14299     {
14300       emit_note (NOTE_INSN_DELETED);
14301       DONE;
14302     }
14304   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14306   [(set_attr "type" "fp,fpstore")
14307    (set_attr "length" "4")])
14309 (define_insn_and_split "pack<mode>"
14310   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14311         (unspec:FMOVE128
14312          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14313           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14314          UNSPEC_PACK_128BIT))]
14315   "FLOAT128_2REG_P (<MODE>mode)"
14316   "@
14317    fmr %L0,%2
14318    #"
14319   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14320   [(set (match_dup 3) (match_dup 1))
14321    (set (match_dup 4) (match_dup 2))]
14323   unsigned dest_hi = REGNO (operands[0]);
14324   unsigned dest_lo = dest_hi + 1;
14326   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14327   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14329   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14330   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14332   [(set_attr "type" "fpsimple,fp")
14333    (set_attr "length" "4,8")])
14335 (define_insn "unpack<mode>"
14336   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14337         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14338                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14339          UNSPEC_UNPACK_128BIT))]
14340   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14342   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14343     return ASM_COMMENT_START " xxpermdi to same register";
14345   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14346   return "xxpermdi %x0,%x1,%x1,%3";
14348   [(set_attr "type" "vecperm")])
14350 (define_insn "pack<mode>"
14351   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14352         (unspec:FMOVE128_VSX
14353          [(match_operand:DI 1 "register_operand" "wa")
14354           (match_operand:DI 2 "register_operand" "wa")]
14355          UNSPEC_PACK_128BIT))]
14356   "TARGET_VSX"
14357   "xxpermdi %x0,%x1,%x2,0"
14358   [(set_attr "type" "vecperm")])
14362 ;; ISA 2.08 IEEE 128-bit floating point support.
14364 (define_insn "add<mode>3"
14365   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14366         (plus:IEEE128
14367          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14368          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14369   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14370   "xsaddqp %0,%1,%2"
14371   [(set_attr "type" "vecfloat")
14372    (set_attr "size" "128")])
14374 (define_insn "sub<mode>3"
14375   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14376         (minus:IEEE128
14377          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14378          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14379   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14380   "xssubqp %0,%1,%2"
14381   [(set_attr "type" "vecfloat")
14382    (set_attr "size" "128")])
14384 (define_insn "mul<mode>3"
14385   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14386         (mult:IEEE128
14387          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14388          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14389   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14390   "xsmulqp %0,%1,%2"
14391   [(set_attr "type" "qmul")
14392    (set_attr "size" "128")])
14394 (define_insn "div<mode>3"
14395   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14396         (div:IEEE128
14397          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14398          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14399   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14400   "xsdivqp %0,%1,%2"
14401   [(set_attr "type" "vecdiv")
14402    (set_attr "size" "128")])
14404 (define_insn "sqrt<mode>2"
14405   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14406         (sqrt:IEEE128
14407          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14408   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14409    "xssqrtqp %0,%1"
14410   [(set_attr "type" "vecdiv")
14411    (set_attr "size" "128")])
14413 (define_expand "copysign<mode>3"
14414   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14415    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14416    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14417   "FLOAT128_IEEE_P (<MODE>mode)"
14419   if (TARGET_FLOAT128_HW)
14420     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14421                                          operands[2]));
14422   else
14423     {
14424       rtx tmp = gen_reg_rtx (<MODE>mode);
14425       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14426                                            operands[2], tmp));
14427     }
14428   DONE;
14431 (define_insn "copysign<mode>3_hard"
14432   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14433         (unspec:IEEE128
14434          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14435           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14436          UNSPEC_COPYSIGN))]
14437   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14438    "xscpsgnqp %0,%2,%1"
14439   [(set_attr "type" "vecmove")
14440    (set_attr "size" "128")])
14442 (define_insn "copysign<mode>3_soft"
14443   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14444         (unspec:IEEE128
14445          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14446           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14447           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14448          UNSPEC_COPYSIGN))]
14449   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14450    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14451   [(set_attr "type" "veccomplex")
14452    (set_attr "length" "8")])
14454 (define_insn "neg<mode>2_hw"
14455   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14456         (neg:IEEE128
14457          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14458   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14459   "xsnegqp %0,%1"
14460   [(set_attr "type" "vecmove")
14461    (set_attr "size" "128")])
14464 (define_insn "abs<mode>2_hw"
14465   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14466         (abs:IEEE128
14467          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14468   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14469   "xsabsqp %0,%1"
14470   [(set_attr "type" "vecmove")
14471    (set_attr "size" "128")])
14474 (define_insn "*nabs<mode>2_hw"
14475   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14476         (neg:IEEE128
14477          (abs:IEEE128
14478           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14479   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14480   "xsnabsqp %0,%1"
14481   [(set_attr "type" "vecmove")
14482    (set_attr "size" "128")])
14484 ;; Initially don't worry about doing fusion
14485 (define_insn "fma<mode>4_hw"
14486   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14487         (fma:IEEE128
14488          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14489          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14490          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14491   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14492   "xsmaddqp %0,%1,%2"
14493   [(set_attr "type" "qmul")
14494    (set_attr "size" "128")])
14496 (define_insn "*fms<mode>4_hw"
14497   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14498         (fma:IEEE128
14499          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14500          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14501          (neg:IEEE128
14502           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14503   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14504   "xsmsubqp %0,%1,%2"
14505   [(set_attr "type" "qmul")
14506    (set_attr "size" "128")])
14508 (define_insn "*nfma<mode>4_hw"
14509   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14510         (neg:IEEE128
14511          (fma:IEEE128
14512           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14513           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14514           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14515   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14516   "xsnmaddqp %0,%1,%2"
14517   [(set_attr "type" "qmul")
14518    (set_attr "size" "128")])
14520 (define_insn "*nfms<mode>4_hw"
14521   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14522         (neg:IEEE128
14523          (fma:IEEE128
14524           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14525           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14526           (neg:IEEE128
14527            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14528   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14529   "xsnmsubqp %0,%1,%2"
14530   [(set_attr "type" "qmul")
14531    (set_attr "size" "128")])
14533 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14534   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14535         (float_extend:IEEE128
14536          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14537   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14538   "xscvdpqp %0,%1"
14539   [(set_attr "type" "vecfloat")
14540    (set_attr "size" "128")])
14542 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14543 ;; point is a simple copy.
14544 (define_insn_and_split "extendkftf2"
14545   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14546         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14547   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14548   "@
14549    #
14550    xxlor %x0,%x1,%x1"
14551   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14552   [(const_int 0)]
14554   emit_note (NOTE_INSN_DELETED);
14555   DONE;
14557   [(set_attr "type" "*,veclogical")
14558    (set_attr "length" "0,4")])
14560 (define_insn_and_split "trunctfkf2"
14561   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14562         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14563   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14564   "@
14565    #
14566    xxlor %x0,%x1,%x1"
14567   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14568   [(const_int 0)]
14570   emit_note (NOTE_INSN_DELETED);
14571   DONE;
14573   [(set_attr "type" "*,veclogical")
14574    (set_attr "length" "0,4")])
14576 (define_insn "trunc<mode>df2_hw"
14577   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14578         (float_truncate:DF
14579          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14580   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14581   "xscvqpdp %0,%1"
14582   [(set_attr "type" "vecfloat")
14583    (set_attr "size" "128")])
14585 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14586 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14587 ;; conversion
14588 (define_insn_and_split "trunc<mode>sf2_hw"
14589   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14590         (float_truncate:SF
14591          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14592    (clobber (match_scratch:DF 2 "=v"))]
14593   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14594   "#"
14595   "&& 1"
14596   [(set (match_dup 2)
14597         (unspec:DF [(match_dup 1)]
14598                    UNSPEC_TRUNC_ROUND_TO_ODD))
14599    (set (match_dup 0)
14600         (float_truncate:SF (match_dup 2)))]
14602   if (GET_CODE (operands[2]) == SCRATCH)
14603     operands[2] = gen_reg_rtx (DFmode);
14605   [(set_attr "type" "vecfloat")
14606    (set_attr "length" "8")])
14608 ;; Conversion between IEEE 128-bit and integer types
14609 (define_insn "fix_<mode>di2_hw"
14610   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14611         (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14612   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14613   "xscvqpsdz %0,%1"
14614   [(set_attr "type" "vecfloat")
14615    (set_attr "size" "128")])
14617 (define_insn "fixuns_<mode>di2_hw"
14618   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14619         (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14620   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14621   "xscvqpudz %0,%1"
14622   [(set_attr "type" "vecfloat")
14623    (set_attr "size" "128")])
14625 (define_insn "fix_<mode>si2_hw"
14626   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14627         (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14628   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14629   "xscvqpswz %0,%1"
14630   [(set_attr "type" "vecfloat")
14631    (set_attr "size" "128")])
14633 (define_insn "fixuns_<mode>si2_hw"
14634   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14635         (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14636   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14637   "xscvqpuwz %0,%1"
14638   [(set_attr "type" "vecfloat")
14639    (set_attr "size" "128")])
14641 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14642 ;; floating point value to 32-bit integer to GPR in order to save it.
14643 (define_insn_and_split "*fix<uns>_<mode>_mem"
14644   [(set (match_operand:SI 0 "memory_operand" "=Z")
14645         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14646    (clobber (match_scratch:SI 2 "=v"))]
14647   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14648   "#"
14649   "&& reload_completed"
14650   [(set (match_dup 2)
14651         (any_fix:SI (match_dup 1)))
14652    (set (match_dup 0)
14653         (match_dup 2))])
14655 (define_insn "float_<mode>di2_hw"
14656   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14657         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14658   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14659   "xscvsdqp %0,%1"
14660   [(set_attr "type" "vecfloat")
14661    (set_attr "size" "128")])
14663 (define_insn_and_split "float_<mode>si2_hw"
14664   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14665         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14666    (clobber (match_scratch:DI 2 "=v"))]
14667   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14668   "#"
14669   "&& 1"
14670   [(set (match_dup 2)
14671         (sign_extend:DI (match_dup 1)))
14672    (set (match_dup 0)
14673         (float:IEEE128 (match_dup 2)))]
14675   if (GET_CODE (operands[2]) == SCRATCH)
14676     operands[2] = gen_reg_rtx (DImode);
14678   if (MEM_P (operands[1]))
14679     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14682 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14683   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14684         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14685    (clobber (match_scratch:DI 2 "=X,r,X"))]
14686   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14687   "#"
14688   "&& reload_completed"
14689   [(const_int 0)]
14691   rtx dest = operands[0];
14692   rtx src = operands[1];
14693   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14695   if (altivec_register_operand (src, <QHI:MODE>mode))
14696     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14697   else if (int_reg_operand (src, <QHI:MODE>mode))
14698     {
14699       rtx ext_di = operands[2];
14700       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14701       emit_move_insn (dest_di, ext_di);
14702     }
14703   else if (MEM_P (src))
14704     {
14705       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14706       emit_move_insn (dest_qhi, src);
14707       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14708     }
14709   else
14710     gcc_unreachable ();
14712   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14713   DONE;
14715   [(set_attr "length" "8,12,12")
14716    (set_attr "type" "vecfloat")
14717    (set_attr "size" "128")])
14719 (define_insn "floatuns_<mode>di2_hw"
14720   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14721         (unsigned_float:IEEE128
14722          (match_operand:DI 1 "altivec_register_operand" "v")))]
14723   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14724   "xscvudqp %0,%1"
14725   [(set_attr "type" "vecfloat")
14726    (set_attr "size" "128")])
14728 (define_insn_and_split "floatuns_<mode>si2_hw"
14729   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14730         (unsigned_float:IEEE128
14731          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14732    (clobber (match_scratch:DI 2 "=v"))]
14733   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14734   "#"
14735   "&& 1"
14736   [(set (match_dup 2)
14737         (zero_extend:DI (match_dup 1)))
14738    (set (match_dup 0)
14739         (float:IEEE128 (match_dup 2)))]
14741   if (GET_CODE (operands[2]) == SCRATCH)
14742     operands[2] = gen_reg_rtx (DImode);
14744   if (MEM_P (operands[1]))
14745     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14748 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14749   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14750         (unsigned_float:IEEE128
14751          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14752    (clobber (match_scratch:DI 2 "=X,r,X"))]
14753   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14754   "#"
14755   "&& reload_completed"
14756   [(const_int 0)]
14758   rtx dest = operands[0];
14759   rtx src = operands[1];
14760   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14762   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14763     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14764   else if (int_reg_operand (src, <QHI:MODE>mode))
14765     {
14766       rtx ext_di = operands[2];
14767       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14768       emit_move_insn (dest_di, ext_di);
14769     }
14770   else
14771     gcc_unreachable ();
14773   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14774   DONE;
14776   [(set_attr "length" "8,12,8")
14777    (set_attr "type" "vecfloat")
14778    (set_attr "size" "128")])
14780 ;; IEEE 128-bit instructions with round to odd semantics
14781 (define_insn "add<mode>3_odd"
14782   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14783         (unspec:IEEE128
14784          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14785           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14786          UNSPEC_ADD_ROUND_TO_ODD))]
14787   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14788   "xsaddqpo %0,%1,%2"
14789   [(set_attr "type" "vecfloat")
14790    (set_attr "size" "128")])
14792 (define_insn "sub<mode>3_odd"
14793   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14794         (unspec:IEEE128
14795          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14796           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14797          UNSPEC_SUB_ROUND_TO_ODD))]
14798   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14799   "xssubqpo %0,%1,%2"
14800   [(set_attr "type" "vecfloat")
14801    (set_attr "size" "128")])
14803 (define_insn "mul<mode>3_odd"
14804   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14805         (unspec:IEEE128
14806          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14807           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14808          UNSPEC_MUL_ROUND_TO_ODD))]
14809   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14810   "xsmulqpo %0,%1,%2"
14811   [(set_attr "type" "qmul")
14812    (set_attr "size" "128")])
14814 (define_insn "div<mode>3_odd"
14815   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14816         (unspec:IEEE128
14817          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14818           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14819          UNSPEC_DIV_ROUND_TO_ODD))]
14820   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14821   "xsdivqpo %0,%1,%2"
14822   [(set_attr "type" "vecdiv")
14823    (set_attr "size" "128")])
14825 (define_insn "sqrt<mode>2_odd"
14826   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14827         (unspec:IEEE128
14828          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14829          UNSPEC_SQRT_ROUND_TO_ODD))]
14830   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14831    "xssqrtqpo %0,%1"
14832   [(set_attr "type" "vecdiv")
14833    (set_attr "size" "128")])
14835 (define_insn "fma<mode>4_odd"
14836   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14837         (unspec:IEEE128
14838          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14839           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14840           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14841          UNSPEC_FMA_ROUND_TO_ODD))]
14842   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14843   "xsmaddqpo %0,%1,%2"
14844   [(set_attr "type" "qmul")
14845    (set_attr "size" "128")])
14847 (define_insn "*fms<mode>4_odd"
14848   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14849         (unspec:IEEE128
14850          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14851           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14852           (neg:IEEE128
14853            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14854          UNSPEC_FMA_ROUND_TO_ODD))]
14855   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14856   "xsmsubqpo %0,%1,%2"
14857   [(set_attr "type" "qmul")
14858    (set_attr "size" "128")])
14860 (define_insn "*nfma<mode>4_odd"
14861   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14862         (neg:IEEE128
14863          (unspec:IEEE128
14864           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14865            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14866            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14867           UNSPEC_FMA_ROUND_TO_ODD)))]
14868   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14869   "xsnmaddqpo %0,%1,%2"
14870   [(set_attr "type" "qmul")
14871    (set_attr "size" "128")])
14873 (define_insn "*nfms<mode>4_odd"
14874   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14875         (neg:IEEE128
14876          (unspec:IEEE128
14877           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14878            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14879            (neg:IEEE128
14880             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14881           UNSPEC_FMA_ROUND_TO_ODD)))]
14882   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14883   "xsnmsubqpo %0,%1,%2"
14884   [(set_attr "type" "qmul")
14885    (set_attr "size" "128")])
14887 (define_insn "trunc<mode>df2_odd"
14888   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14889         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14890                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14891   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14892   "xscvqpdpo %0,%1"
14893   [(set_attr "type" "vecfloat")
14894    (set_attr "size" "128")])
14896 ;; IEEE 128-bit comparisons
14897 (define_insn "*cmp<mode>_hw"
14898   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14899         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14900                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14901   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14902    "xscmpuqp %0,%1,%2"
14903   [(set_attr "type" "veccmp")
14904    (set_attr "size" "128")])
14908 (include "sync.md")
14909 (include "vector.md")
14910 (include "vsx.md")
14911 (include "altivec.md")
14912 (include "dfp.md")
14913 (include "paired.md")
14914 (include "crypto.md")
14915 (include "htm.md")