rs6000-builtin.def (BU_FLOAT128_2_HW): Define new helper macro for IEEE float128...
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobd8767dee05c7b33dee28d1f0978d5b300b2592a1
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,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 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197 ;; This is used for add, logical, shift, exts, mul.
198 (define_attr "dot" "no,yes" (const_string "no"))
200 ;; Does this instruction sign-extend its result?
201 ;; This is used for load insns.
202 (define_attr "sign_extend" "no,yes" (const_string "no"))
204 ;; Does this instruction use indexed (that is, reg+reg) addressing?
205 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
206 ;; it is automatically set based on that.  If a load or store instruction
207 ;; has fewer than two operands it needs to set this attribute manually
208 ;; or the compiler will crash.
209 (define_attr "indexed" "no,yes"
210   (if_then_else (ior (match_operand 0 "indexed_address_mem")
211                      (match_operand 1 "indexed_address_mem"))
212                 (const_string "yes")
213                 (const_string "no")))
215 ;; Does this instruction use update addressing?
216 ;; This is used for load and store insns.  See the comments for "indexed".
217 (define_attr "update" "no,yes"
218   (if_then_else (ior (match_operand 0 "update_address_mem")
219                      (match_operand 1 "update_address_mem"))
220                 (const_string "yes")
221                 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
224 ;; register?
225 ;; This is used for shift insns.
226 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
228 ;; Is this instruction using a shift amount from a register?
229 ;; This is used for shift insns.
230 (define_attr "var_shift" "no,yes"
231   (if_then_else (and (eq_attr "type" "shift")
232                      (eq_attr "maybe_var_shift" "yes"))
233                 (if_then_else (match_operand 2 "gpc_reg_operand")
234                               (const_string "yes")
235                               (const_string "no"))
236                 (const_string "no")))
238 ;; Is copying of this instruction disallowed?
239 (define_attr "cannot_copy" "no,yes" (const_string "no"))
241 ;; Define floating point instruction sub-types for use with Xfpu.md
242 (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"))
244 ;; Length (in bytes).
245 ; '(pc)' in the following doesn't include the instruction itself; it is
246 ; calculated as if the instruction had zero size.
247 (define_attr "length" ""
248   (if_then_else (eq_attr "type" "branch")
249                 (if_then_else (and (ge (minus (match_dup 0) (pc))
250                                        (const_int -32768))
251                                    (lt (minus (match_dup 0) (pc))
252                                        (const_int 32764)))
253                               (const_int 4)
254                               (const_int 8))
255                 (const_int 4)))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
259 (define_attr "cpu"
260   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261    ppc750,ppc7400,ppc7450,
262    ppc403,ppc405,ppc440,ppc476,
263    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264    power4,power5,power6,power7,power8,power9,
265    rs64a,mpccore,cell,ppca2,titan"
266   (const (symbol_ref "rs6000_cpu_attr")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273                           (eq_attr "dot" "yes"))
274                      (and (eq_attr "type" "load")
275                           (eq_attr "sign_extend" "yes"))
276                      (and (eq_attr "type" "shift")
277                           (eq_attr "var_shift" "yes")))
278                 (const_string "always")
279                 (const_string "not")))
281 (automata_option "ndfa")
283 (include "rs64.md")
284 (include "mpc.md")
285 (include "40x.md")
286 (include "440.md")
287 (include "476.md")
288 (include "601.md")
289 (include "603.md")
290 (include "6xx.md")
291 (include "7xx.md")
292 (include "7450.md")
293 (include "8540.md")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
297 (include "e5500.md")
298 (include "e6500.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
305 (include "cell.md")
306 (include "xfpu.md")
307 (include "a2.md")
308 (include "titan.md")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
316 ;; Mode iterators
318 ; This mode iterator allows :GPR to be used to indicate the allowable size
319 ; of whole values in GPRs.
320 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
322 ; Any supported integer mode.
323 (define_mode_iterator INT [QI HI SI DI TI PTI])
325 ; Any supported integer mode that fits in one register.
326 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
328 ; Integer modes supported in VSX registers with ISA 3.0 instructions
329 (define_mode_iterator INT_ISA3 [QI HI SI DI])
331 ; Everything we can extend QImode to.
332 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend HImode to.
335 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
337 ; Everything we can extend SImode to.
338 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
340 ; QImode or HImode for small integer moves and small atomic ops
341 (define_mode_iterator QHI [QI HI])
343 ; QImode, HImode, SImode for fused ops only for GPR loads
344 (define_mode_iterator QHSI [QI HI SI])
346 ; HImode or SImode for sign extended fusion ops
347 (define_mode_iterator HSI [HI SI])
349 ; SImode or DImode, even if DImode doesn't fit in GPRs.
350 (define_mode_iterator SDI [SI DI])
352 ; Types that can be fused with an ADDIS instruction to load or store a GPR
353 ; register that has reg+offset addressing.
354 (define_mode_iterator GPR_FUSION [QI
355                                   HI
356                                   SI
357                                   (DI   "TARGET_POWERPC64")
358                                   SF
359                                   (DF   "TARGET_POWERPC64")])
361 ; Types that can be fused with an ADDIS instruction to load or store a FPR
362 ; register that has reg+offset addressing.
363 (define_mode_iterator FPR_FUSION [DI SF DF])
365 ; The size of a pointer.  Also, the size of the value that a record-condition
366 ; (one with a '.') will compare; and the size used for arithmetic carries.
367 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
369 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
370 ; PTImode is GPR only)
371 (define_mode_iterator TI2 [TI PTI])
373 ; Any hardware-supported floating-point mode
374 (define_mode_iterator FP [
375   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
376   (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
377   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
378   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
379   (KF "TARGET_FLOAT128_TYPE")
380   (DD "TARGET_DFP")
381   (TD "TARGET_DFP")])
383 ; Any fma capable floating-point mode.
384 (define_mode_iterator FMA_F [
385   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
386   (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
387        || VECTOR_UNIT_VSX_P (DFmode)")
388   (V2SF "TARGET_PAIRED_FLOAT")
389   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
390   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
391   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
392   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
393   ])
395 ; Floating point move iterators to combine binary and decimal moves
396 (define_mode_iterator FMOVE32 [SF SD])
397 (define_mode_iterator FMOVE64 [DF DD])
398 (define_mode_iterator FMOVE64X [DI DF DD])
399 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
400                                 (IF "FLOAT128_IBM_P (IFmode)")
401                                 (TD "TARGET_HARD_FLOAT")])
403 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
404                                     (IF "FLOAT128_2REG_P (IFmode)")
405                                     (TD "TARGET_HARD_FLOAT")])
407 ; Iterators for 128 bit types for direct move
408 (define_mode_iterator FMOVE128_GPR [TI
409                                     V16QI
410                                     V8HI
411                                     V4SI
412                                     V4SF
413                                     V2DI
414                                     V2DF
415                                     V1TI
416                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
417                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
419 ; Iterator for 128-bit VSX types for pack/unpack
420 (define_mode_iterator FMOVE128_VSX [V1TI KF])
422 ; Whether a floating point move is ok, don't allow SD without hardware FP
423 (define_mode_attr fmove_ok [(SF "")
424                             (DF "")
425                             (SD "TARGET_HARD_FLOAT")
426                             (DD "")])
428 ; Convert REAL_VALUE to the appropriate bits
429 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
430                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
431                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
432                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
434 ; Whether 0.0 has an all-zero bit pattern
435 (define_mode_attr zero_fp [(SF "j")
436                            (DF "j")
437                            (TF "j")
438                            (IF "j")
439                            (KF "j")
440                            (SD "wn")
441                            (DD "wn")
442                            (TD "wn")])
444 ; Definitions for 64-bit VSX
445 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
447 ; Definitions for 64-bit direct move
448 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
450 ; Definitions for 64-bit use of altivec registers
451 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
453 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
454 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
456 ; These modes do not fit in integer registers in 32-bit mode.
457 (define_mode_iterator DIFD [DI DF DD])
459 ; Iterator for reciprocal estimate instructions
460 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
462 ; Iterator for just SF/DF
463 (define_mode_iterator SFDF [SF DF])
465 ; Like SFDF, but a different name to match conditional move where the
466 ; comparison operands may be a different mode than the input operands.
467 (define_mode_iterator SFDF2 [SF DF])
469 ; Iterator for 128-bit floating point that uses the IBM double-double format
470 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
471                               (TF "FLOAT128_IBM_P (TFmode)")])
473 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
474 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
475                                (TF "FLOAT128_IEEE_P (TFmode)")])
477 ; Iterator for 128-bit floating point
478 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
479                                 (IF "TARGET_FLOAT128_TYPE")
480                                 (TF "TARGET_LONG_DOUBLE_128")])
482 ; Iterator for signbit on 64-bit machines with direct move
483 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
484                                (TF "FLOAT128_VECTOR_P (TFmode)")])
486 ; Iterator for ISA 3.0 supported floating point types
487 (define_mode_iterator FP_ISA3 [SF DF])
489 ; SF/DF suffix for traditional floating instructions
490 (define_mode_attr Ftrad         [(SF "s") (DF "")])
492 ; SF/DF suffix for VSX instructions
493 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
495 ; SF/DF constraint for arithmetic on traditional floating point registers
496 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
498 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
499 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
500 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
501 ; format.
502 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
504 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
505 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
506 ; instructions added in ISA 2.07 (power8)
507 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
509 ; SF/DF constraint for arithmetic on altivec registers
510 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
512 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
513 (define_mode_attr Fs            [(SF "s")  (DF "d")])
515 ; FRE/FRES support
516 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
517 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
519 ; Conditional returns.
520 (define_code_iterator any_return [return simple_return])
521 (define_code_attr return_pred [(return "direct_return ()")
522                                (simple_return "1")])
523 (define_code_attr return_str [(return "") (simple_return "simple_")])
525 ; Logical operators.
526 (define_code_iterator iorxor            [ior xor])
527 (define_code_iterator and_ior_xor       [and ior xor])
529 ; Signed/unsigned variants of ops.
530 (define_code_iterator any_extend        [sign_extend zero_extend])
531 (define_code_iterator any_fix           [fix unsigned_fix])
532 (define_code_iterator any_float         [float unsigned_float])
534 (define_code_attr u  [(sign_extend      "")
535                       (zero_extend      "u")
536                       (fix              "")
537                       (unsigned_fix     "u")])
539 (define_code_attr su [(sign_extend      "s")
540                       (zero_extend      "u")
541                       (fix              "s")
542                       (unsigned_fix     "s")
543                       (float            "s")
544                       (unsigned_float   "u")])
546 (define_code_attr az [(sign_extend      "a")
547                       (zero_extend      "z")
548                       (fix              "a")
549                       (unsigned_fix     "z")
550                       (float            "a")
551                       (unsigned_float   "z")])
553 (define_code_attr uns [(fix             "")
554                        (unsigned_fix    "uns")
555                        (float           "")
556                        (unsigned_float  "uns")])
558 ; Various instructions that come in SI and DI forms.
559 ; A generic w/d attribute, for things like cmpw/cmpd.
560 (define_mode_attr wd [(QI    "b")
561                       (HI    "h")
562                       (SI    "w")
563                       (DI    "d")
564                       (V16QI "b")
565                       (V8HI  "h")
566                       (V4SI  "w")
567                       (V2DI  "d")
568                       (V1TI  "q")
569                       (TI    "q")])
571 ;; How many bits in this mode?
572 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
574 ; DImode bits
575 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
577 ;; ISEL/ISEL64 target selection
578 (define_mode_attr sel [(SI "") (DI "64")])
580 ;; Bitmask for shift instructions
581 (define_mode_attr hH [(SI "h") (DI "H")])
583 ;; A mode twice the size of the given mode
584 (define_mode_attr dmode [(SI "di") (DI "ti")])
585 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
587 ;; Suffix for reload patterns
588 (define_mode_attr ptrsize [(SI "32bit")
589                            (DI "64bit")])
591 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
592                             (DI "TARGET_64BIT")])
594 (define_mode_attr mptrsize [(SI "si")
595                             (DI "di")])
597 (define_mode_attr ptrload [(SI "lwz")
598                            (DI "ld")])
600 (define_mode_attr ptrm [(SI "m")
601                         (DI "Y")])
603 (define_mode_attr rreg [(SF   "f")
604                         (DF   "ws")
605                         (TF   "f")
606                         (TD   "f")
607                         (V4SF "wf")
608                         (V2DF "wd")])
610 (define_mode_attr rreg2 [(SF   "f")
611                          (DF   "d")])
613 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
614                                  (DF "TARGET_FCFID")])
616 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
617                                 (DF "TARGET_DOUBLE_FLOAT")])
619 ;; Mode iterator for logical operations on 128-bit types
620 (define_mode_iterator BOOL_128          [TI
621                                          PTI
622                                          (V16QI "TARGET_ALTIVEC")
623                                          (V8HI  "TARGET_ALTIVEC")
624                                          (V4SI  "TARGET_ALTIVEC")
625                                          (V4SF  "TARGET_ALTIVEC")
626                                          (V2DI  "TARGET_ALTIVEC")
627                                          (V2DF  "TARGET_ALTIVEC")
628                                          (V1TI  "TARGET_ALTIVEC")])
630 ;; For the GPRs we use 3 constraints for register outputs, two that are the
631 ;; same as the output register, and a third where the output register is an
632 ;; early clobber, so we don't have to deal with register overlaps.  For the
633 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
634 ;; either.
636 ;; Mode attribute for boolean operation register constraints for output
637 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
638                                          (PTI   "&r,r,r")
639                                          (V16QI "wa,v,&?r,?r,?r")
640                                          (V8HI  "wa,v,&?r,?r,?r")
641                                          (V4SI  "wa,v,&?r,?r,?r")
642                                          (V4SF  "wa,v,&?r,?r,?r")
643                                          (V2DI  "wa,v,&?r,?r,?r")
644                                          (V2DF  "wa,v,&?r,?r,?r")
645                                          (V1TI  "wa,v,&?r,?r,?r")])
647 ;; Mode attribute for boolean operation register constraints for operand1
648 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
649                                          (PTI   "r,0,r")
650                                          (V16QI "wa,v,r,0,r")
651                                          (V8HI  "wa,v,r,0,r")
652                                          (V4SI  "wa,v,r,0,r")
653                                          (V4SF  "wa,v,r,0,r")
654                                          (V2DI  "wa,v,r,0,r")
655                                          (V2DF  "wa,v,r,0,r")
656                                          (V1TI  "wa,v,r,0,r")])
658 ;; Mode attribute for boolean operation register constraints for operand2
659 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
660                                          (PTI   "r,r,0")
661                                          (V16QI "wa,v,r,r,0")
662                                          (V8HI  "wa,v,r,r,0")
663                                          (V4SI  "wa,v,r,r,0")
664                                          (V4SF  "wa,v,r,r,0")
665                                          (V2DI  "wa,v,r,r,0")
666                                          (V2DF  "wa,v,r,r,0")
667                                          (V1TI  "wa,v,r,r,0")])
669 ;; Mode attribute for boolean operation register constraints for operand1
670 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
671 ;; is used for operand1 or operand2
672 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
673                                          (PTI   "r,0,0")
674                                          (V16QI "wa,v,r,0,0")
675                                          (V8HI  "wa,v,r,0,0")
676                                          (V4SI  "wa,v,r,0,0")
677                                          (V4SF  "wa,v,r,0,0")
678                                          (V2DI  "wa,v,r,0,0")
679                                          (V2DF  "wa,v,r,0,0")
680                                          (V1TI  "wa,v,r,0,0")])
682 ;; Reload iterator for creating the function to allocate a base register to
683 ;; supplement addressing modes.
684 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
685                               SF SD SI DF DD DI TI PTI KF IF TF])
687 ;; Iterate over smin, smax
688 (define_code_iterator fp_minmax [smin smax])
690 (define_code_attr     minmax    [(smin "min")
691                                  (smax "max")])
693 (define_code_attr     SMINMAX   [(smin "SMIN")
694                                  (smax "SMAX")])
696 ;; Iterator to optimize the following cases:
697 ;;      D-form load to FPR register & move to Altivec register
698 ;;      Move Altivec register to FPR register and store
699 (define_mode_iterator ALTIVEC_DFORM [DF
700                                      (SF "TARGET_P8_VECTOR")
701                                      (DI "TARGET_POWERPC64")])
704 ;; Start with fixed-point load and store insns.  Here we put only the more
705 ;; complex forms.  Basic data transfer is done later.
707 (define_insn "zero_extendqi<mode>2"
708   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
709         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
710   ""
711   "@
712    lbz%U1%X1 %0,%1
713    rlwinm %0,%1,0,0xff
714    lxsibzx %x0,%y1
715    vextractub %0,%1,7"
716   [(set_attr "type" "load,shift,fpload,vecperm")])
718 (define_insn_and_split "*zero_extendqi<mode>2_dot"
719   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
720         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
721                     (const_int 0)))
722    (clobber (match_scratch:EXTQI 0 "=r,r"))]
723   ""
724   "@
725    andi. %0,%1,0xff
726    #"
727   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
728   [(set (match_dup 0)
729         (zero_extend:EXTQI (match_dup 1)))
730    (set (match_dup 2)
731         (compare:CC (match_dup 0)
732                     (const_int 0)))]
733   ""
734   [(set_attr "type" "logical")
735    (set_attr "dot" "yes")
736    (set_attr "length" "4,8")])
738 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
739   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
740         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
741                     (const_int 0)))
742    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
743         (zero_extend:EXTQI (match_dup 1)))]
744   ""
745   "@
746    andi. %0,%1,0xff
747    #"
748   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
749   [(set (match_dup 0)
750         (zero_extend:EXTQI (match_dup 1)))
751    (set (match_dup 2)
752         (compare:CC (match_dup 0)
753                     (const_int 0)))]
754   ""
755   [(set_attr "type" "logical")
756    (set_attr "dot" "yes")
757    (set_attr "length" "4,8")])
760 (define_insn "zero_extendhi<mode>2"
761   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
762         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
763   ""
764   "@
765    lhz%U1%X1 %0,%1
766    rlwinm %0,%1,0,0xffff
767    lxsihzx %x0,%y1
768    vextractuh %0,%1,6"
769   [(set_attr "type" "load,shift,fpload,vecperm")])
771 (define_insn_and_split "*zero_extendhi<mode>2_dot"
772   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
773         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
774                     (const_int 0)))
775    (clobber (match_scratch:EXTHI 0 "=r,r"))]
776   ""
777   "@
778    andi. %0,%1,0xffff
779    #"
780   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
781   [(set (match_dup 0)
782         (zero_extend:EXTHI (match_dup 1)))
783    (set (match_dup 2)
784         (compare:CC (match_dup 0)
785                     (const_int 0)))]
786   ""
787   [(set_attr "type" "logical")
788    (set_attr "dot" "yes")
789    (set_attr "length" "4,8")])
791 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
792   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
793         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
794                     (const_int 0)))
795    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
796         (zero_extend:EXTHI (match_dup 1)))]
797   ""
798   "@
799    andi. %0,%1,0xffff
800    #"
801   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
802   [(set (match_dup 0)
803         (zero_extend:EXTHI (match_dup 1)))
804    (set (match_dup 2)
805         (compare:CC (match_dup 0)
806                     (const_int 0)))]
807   ""
808   [(set_attr "type" "logical")
809    (set_attr "dot" "yes")
810    (set_attr "length" "4,8")])
813 (define_insn "zero_extendsi<mode>2"
814   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
815         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
816   ""
817   "@
818    lwz%U1%X1 %0,%1
819    rldicl %0,%1,0,32
820    lfiwzx %0,%y1
821    lxsiwzx %x0,%y1
822    mtvsrwz %x0,%1
823    mfvsrwz %0,%x1
824    xxextractuw %x0,%x1,4"
825   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
827 (define_insn_and_split "*zero_extendsi<mode>2_dot"
828   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
829         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
830                     (const_int 0)))
831    (clobber (match_scratch:EXTSI 0 "=r,r"))]
832   ""
833   "@
834    rldicl. %0,%1,0,32
835    #"
836   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
837   [(set (match_dup 0)
838         (zero_extend:DI (match_dup 1)))
839    (set (match_dup 2)
840         (compare:CC (match_dup 0)
841                     (const_int 0)))]
842   ""
843   [(set_attr "type" "shift")
844    (set_attr "dot" "yes")
845    (set_attr "length" "4,8")])
847 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
848   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
849         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
850                     (const_int 0)))
851    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
852         (zero_extend:EXTSI (match_dup 1)))]
853   ""
854   "@
855    rldicl. %0,%1,0,32
856    #"
857   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
858   [(set (match_dup 0)
859         (zero_extend:EXTSI (match_dup 1)))
860    (set (match_dup 2)
861         (compare:CC (match_dup 0)
862                     (const_int 0)))]
863   ""
864   [(set_attr "type" "shift")
865    (set_attr "dot" "yes")
866    (set_attr "length" "4,8")])
869 (define_insn "extendqi<mode>2"
870   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
871         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
872   ""
873   "@
874    extsb %0,%1
875    vextsb2d %0,%1"
876   [(set_attr "type" "exts,vecperm")])
878 (define_insn_and_split "*extendqi<mode>2_dot"
879   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
880         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
881                     (const_int 0)))
882    (clobber (match_scratch:EXTQI 0 "=r,r"))]
883   ""
884   "@
885    extsb. %0,%1
886    #"
887   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
888   [(set (match_dup 0)
889         (sign_extend:EXTQI (match_dup 1)))
890    (set (match_dup 2)
891         (compare:CC (match_dup 0)
892                     (const_int 0)))]
893   ""
894   [(set_attr "type" "exts")
895    (set_attr "dot" "yes")
896    (set_attr "length" "4,8")])
898 (define_insn_and_split "*extendqi<mode>2_dot2"
899   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
900         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
901                     (const_int 0)))
902    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
903         (sign_extend:EXTQI (match_dup 1)))]
904   ""
905   "@
906    extsb. %0,%1
907    #"
908   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
909   [(set (match_dup 0)
910         (sign_extend:EXTQI (match_dup 1)))
911    (set (match_dup 2)
912         (compare:CC (match_dup 0)
913                     (const_int 0)))]
914   ""
915   [(set_attr "type" "exts")
916    (set_attr "dot" "yes")
917    (set_attr "length" "4,8")])
920 (define_expand "extendhi<mode>2"
921   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
922         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
923   ""
924   "")
926 (define_insn "*extendhi<mode>2"
927   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
928         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
929   ""
930   "@
931    lha%U1%X1 %0,%1
932    extsh %0,%1
933    #
934    vextsh2d %0,%1"
935   [(set_attr "type" "load,exts,fpload,vecperm")
936    (set_attr "sign_extend" "yes")
937    (set_attr "length" "4,4,8,4")])
939 (define_split
940   [(set (match_operand:EXTHI 0 "altivec_register_operand")
941         (sign_extend:EXTHI
942          (match_operand:HI 1 "indexed_or_indirect_operand")))]
943   "TARGET_P9_VECTOR && reload_completed"
944   [(set (match_dup 2)
945         (match_dup 1))
946    (set (match_dup 0)
947         (sign_extend:EXTHI (match_dup 2)))]
949   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
952 (define_insn_and_split "*extendhi<mode>2_dot"
953   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
954         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
955                     (const_int 0)))
956    (clobber (match_scratch:EXTHI 0 "=r,r"))]
957   ""
958   "@
959    extsh. %0,%1
960    #"
961   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
962   [(set (match_dup 0)
963         (sign_extend:EXTHI (match_dup 1)))
964    (set (match_dup 2)
965         (compare:CC (match_dup 0)
966                     (const_int 0)))]
967   ""
968   [(set_attr "type" "exts")
969    (set_attr "dot" "yes")
970    (set_attr "length" "4,8")])
972 (define_insn_and_split "*extendhi<mode>2_dot2"
973   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
974         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
975                     (const_int 0)))
976    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
977         (sign_extend:EXTHI (match_dup 1)))]
978   ""
979   "@
980    extsh. %0,%1
981    #"
982   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
983   [(set (match_dup 0)
984         (sign_extend:EXTHI (match_dup 1)))
985    (set (match_dup 2)
986         (compare:CC (match_dup 0)
987                     (const_int 0)))]
988   ""
989   [(set_attr "type" "exts")
990    (set_attr "dot" "yes")
991    (set_attr "length" "4,8")])
994 (define_insn "extendsi<mode>2"
995   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
996                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
998         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
999                      "Y,  r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
1000   ""
1001   "@
1002    lwa%U1%X1 %0,%1
1003    extsw %0,%1
1004    lfiwax %0,%y1
1005    lxsiwax %x0,%y1
1006    mtvsrwa %x0,%1
1007    vextsw2d %0,%1
1008    #
1009    #"
1010   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1011    (set_attr "sign_extend" "yes")
1012    (set_attr "length" "4,4,4,4,4,4,8,8")])
1014 (define_split
1015   [(set (match_operand:EXTSI 0 "int_reg_operand")
1016         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1017   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1018   [(set (match_dup 2)
1019         (match_dup 1))
1020    (set (match_dup 0)
1021         (sign_extend:DI (match_dup 2)))]
1023   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1026 (define_split
1027   [(set (match_operand:DI 0 "altivec_register_operand")
1028         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1029   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1030   [(const_int 0)]
1032   rtx dest = operands[0];
1033   rtx src = operands[1];
1034   int dest_regno = REGNO (dest);
1035   int src_regno = REGNO (src);
1036   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1037   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1039   if (VECTOR_ELT_ORDER_BIG)
1040     {
1041       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1042       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1043     }
1044   else
1045     {
1046       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1047       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1048     }
1049   DONE;
1052 (define_insn_and_split "*extendsi<mode>2_dot"
1053   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1054         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1055                     (const_int 0)))
1056    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1057   ""
1058   "@
1059    extsw. %0,%1
1060    #"
1061   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1062   [(set (match_dup 0)
1063         (sign_extend:EXTSI (match_dup 1)))
1064    (set (match_dup 2)
1065         (compare:CC (match_dup 0)
1066                     (const_int 0)))]
1067   ""
1068   [(set_attr "type" "exts")
1069    (set_attr "dot" "yes")
1070    (set_attr "length" "4,8")])
1072 (define_insn_and_split "*extendsi<mode>2_dot2"
1073   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1074         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1075                     (const_int 0)))
1076    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1077         (sign_extend:EXTSI (match_dup 1)))]
1078   ""
1079   "@
1080    extsw. %0,%1
1081    #"
1082   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1083   [(set (match_dup 0)
1084         (sign_extend:EXTSI (match_dup 1)))
1085    (set (match_dup 2)
1086         (compare:CC (match_dup 0)
1087                     (const_int 0)))]
1088   ""
1089   [(set_attr "type" "exts")
1090    (set_attr "dot" "yes")
1091    (set_attr "length" "4,8")])
1093 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1095 (define_insn "*macchwc"
1096   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1097         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1098                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1099                                        (const_int 16))
1100                                       (sign_extend:SI
1101                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1102                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1103                     (const_int 0)))
1104    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1105         (plus:SI (mult:SI (ashiftrt:SI
1106                            (match_dup 2)
1107                            (const_int 16))
1108                           (sign_extend:SI
1109                            (match_dup 1)))
1110                  (match_dup 4)))]
1111   "TARGET_MULHW"
1112   "macchw. %0,%1,%2"
1113   [(set_attr "type" "halfmul")])
1115 (define_insn "*macchw"
1116   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1117         (plus:SI (mult:SI (ashiftrt:SI
1118                            (match_operand:SI 2 "gpc_reg_operand" "r")
1119                            (const_int 16))
1120                           (sign_extend:SI
1121                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1122                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1123   "TARGET_MULHW"
1124   "macchw %0,%1,%2"
1125   [(set_attr "type" "halfmul")])
1127 (define_insn "*macchwuc"
1128   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1129         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1130                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1131                                        (const_int 16))
1132                                       (zero_extend:SI
1133                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1134                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1135                     (const_int 0)))
1136    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1137         (plus:SI (mult:SI (lshiftrt:SI
1138                            (match_dup 2)
1139                            (const_int 16))
1140                           (zero_extend:SI
1141                            (match_dup 1)))
1142                  (match_dup 4)))]
1143   "TARGET_MULHW"
1144   "macchwu. %0,%1,%2"
1145   [(set_attr "type" "halfmul")])
1147 (define_insn "*macchwu"
1148   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1149         (plus:SI (mult:SI (lshiftrt:SI
1150                            (match_operand:SI 2 "gpc_reg_operand" "r")
1151                            (const_int 16))
1152                           (zero_extend:SI
1153                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1154                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1155   "TARGET_MULHW"
1156   "macchwu %0,%1,%2"
1157   [(set_attr "type" "halfmul")])
1159 (define_insn "*machhwc"
1160   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1161         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1162                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1163                                        (const_int 16))
1164                                       (ashiftrt:SI
1165                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1166                                        (const_int 16)))
1167                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1168                     (const_int 0)))
1169    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1170         (plus:SI (mult:SI (ashiftrt:SI
1171                            (match_dup 1)
1172                            (const_int 16))
1173                           (ashiftrt:SI
1174                            (match_dup 2)
1175                            (const_int 16)))
1176                  (match_dup 4)))]
1177   "TARGET_MULHW"
1178   "machhw. %0,%1,%2"
1179   [(set_attr "type" "halfmul")])
1181 (define_insn "*machhw"
1182   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1183         (plus:SI (mult:SI (ashiftrt:SI
1184                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1185                            (const_int 16))
1186                           (ashiftrt:SI
1187                            (match_operand:SI 2 "gpc_reg_operand" "r")
1188                            (const_int 16)))
1189                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1190   "TARGET_MULHW"
1191   "machhw %0,%1,%2"
1192   [(set_attr "type" "halfmul")])
1194 (define_insn "*machhwuc"
1195   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1196         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1197                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1198                                        (const_int 16))
1199                                       (lshiftrt:SI
1200                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1201                                        (const_int 16)))
1202                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1203                     (const_int 0)))
1204    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1205         (plus:SI (mult:SI (lshiftrt:SI
1206                            (match_dup 1)
1207                            (const_int 16))
1208                           (lshiftrt:SI
1209                            (match_dup 2)
1210                            (const_int 16)))
1211                  (match_dup 4)))]
1212   "TARGET_MULHW"
1213   "machhwu. %0,%1,%2"
1214   [(set_attr "type" "halfmul")])
1216 (define_insn "*machhwu"
1217   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1218         (plus:SI (mult:SI (lshiftrt:SI
1219                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1220                            (const_int 16))
1221                           (lshiftrt:SI
1222                            (match_operand:SI 2 "gpc_reg_operand" "r")
1223                            (const_int 16)))
1224                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1225   "TARGET_MULHW"
1226   "machhwu %0,%1,%2"
1227   [(set_attr "type" "halfmul")])
1229 (define_insn "*maclhwc"
1230   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1231         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1232                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1233                                       (sign_extend:SI
1234                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1235                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1236                     (const_int 0)))
1237    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1238         (plus:SI (mult:SI (sign_extend:SI
1239                            (match_dup 1))
1240                           (sign_extend:SI
1241                            (match_dup 2)))
1242                  (match_dup 4)))]
1243   "TARGET_MULHW"
1244   "maclhw. %0,%1,%2"
1245   [(set_attr "type" "halfmul")])
1247 (define_insn "*maclhw"
1248   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1249         (plus:SI (mult:SI (sign_extend:SI
1250                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1251                           (sign_extend:SI
1252                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1253                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1254   "TARGET_MULHW"
1255   "maclhw %0,%1,%2"
1256   [(set_attr "type" "halfmul")])
1258 (define_insn "*maclhwuc"
1259   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1260         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1261                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1262                                       (zero_extend:SI
1263                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1264                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1265                     (const_int 0)))
1266    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1267         (plus:SI (mult:SI (zero_extend:SI
1268                            (match_dup 1))
1269                           (zero_extend:SI
1270                            (match_dup 2)))
1271                  (match_dup 4)))]
1272   "TARGET_MULHW"
1273   "maclhwu. %0,%1,%2"
1274   [(set_attr "type" "halfmul")])
1276 (define_insn "*maclhwu"
1277   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1278         (plus:SI (mult:SI (zero_extend:SI
1279                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1280                           (zero_extend:SI
1281                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1282                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1283   "TARGET_MULHW"
1284   "maclhwu %0,%1,%2"
1285   [(set_attr "type" "halfmul")])
1287 (define_insn "*nmacchwc"
1288   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1289         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1290                               (mult:SI (ashiftrt:SI
1291                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1292                                         (const_int 16))
1293                                        (sign_extend:SI
1294                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1295                     (const_int 0)))
1296    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1297         (minus:SI (match_dup 4)
1298                   (mult:SI (ashiftrt:SI
1299                             (match_dup 2)
1300                             (const_int 16))
1301                            (sign_extend:SI
1302                             (match_dup 1)))))]
1303   "TARGET_MULHW"
1304   "nmacchw. %0,%1,%2"
1305   [(set_attr "type" "halfmul")])
1307 (define_insn "*nmacchw"
1308   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1309         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1310                   (mult:SI (ashiftrt:SI
1311                             (match_operand:SI 2 "gpc_reg_operand" "r")
1312                             (const_int 16))
1313                            (sign_extend:SI
1314                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1315   "TARGET_MULHW"
1316   "nmacchw %0,%1,%2"
1317   [(set_attr "type" "halfmul")])
1319 (define_insn "*nmachhwc"
1320   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1321         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1322                               (mult:SI (ashiftrt:SI
1323                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1324                                         (const_int 16))
1325                                        (ashiftrt:SI
1326                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1327                                         (const_int 16))))
1328                     (const_int 0)))
1329    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330         (minus:SI (match_dup 4)
1331                   (mult:SI (ashiftrt:SI
1332                             (match_dup 1)
1333                             (const_int 16))
1334                            (ashiftrt:SI
1335                             (match_dup 2)
1336                             (const_int 16)))))]
1337   "TARGET_MULHW"
1338   "nmachhw. %0,%1,%2"
1339   [(set_attr "type" "halfmul")])
1341 (define_insn "*nmachhw"
1342   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1343         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1344                   (mult:SI (ashiftrt:SI
1345                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1346                             (const_int 16))
1347                            (ashiftrt:SI
1348                             (match_operand:SI 2 "gpc_reg_operand" "r")
1349                             (const_int 16)))))]
1350   "TARGET_MULHW"
1351   "nmachhw %0,%1,%2"
1352   [(set_attr "type" "halfmul")])
1354 (define_insn "*nmaclhwc"
1355   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1356         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1357                               (mult:SI (sign_extend:SI
1358                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1359                                        (sign_extend:SI
1360                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1361                     (const_int 0)))
1362    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1363         (minus:SI (match_dup 4)
1364                   (mult:SI (sign_extend:SI
1365                             (match_dup 1))
1366                            (sign_extend:SI
1367                             (match_dup 2)))))]
1368   "TARGET_MULHW"
1369   "nmaclhw. %0,%1,%2"
1370   [(set_attr "type" "halfmul")])
1372 (define_insn "*nmaclhw"
1373   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1374         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1375                   (mult:SI (sign_extend:SI
1376                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1377                            (sign_extend:SI
1378                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1379   "TARGET_MULHW"
1380   "nmaclhw %0,%1,%2"
1381   [(set_attr "type" "halfmul")])
1383 (define_insn "*mulchwc"
1384   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1385         (compare:CC (mult:SI (ashiftrt:SI
1386                               (match_operand:SI 2 "gpc_reg_operand" "r")
1387                               (const_int 16))
1388                              (sign_extend:SI
1389                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1390                     (const_int 0)))
1391    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1392         (mult:SI (ashiftrt:SI
1393                   (match_dup 2)
1394                   (const_int 16))
1395                  (sign_extend:SI
1396                   (match_dup 1))))]
1397   "TARGET_MULHW"
1398   "mulchw. %0,%1,%2"
1399   [(set_attr "type" "halfmul")])
1401 (define_insn "*mulchw"
1402   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1403         (mult:SI (ashiftrt:SI
1404                   (match_operand:SI 2 "gpc_reg_operand" "r")
1405                   (const_int 16))
1406                  (sign_extend:SI
1407                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1408   "TARGET_MULHW"
1409   "mulchw %0,%1,%2"
1410   [(set_attr "type" "halfmul")])
1412 (define_insn "*mulchwuc"
1413   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1414         (compare:CC (mult:SI (lshiftrt:SI
1415                               (match_operand:SI 2 "gpc_reg_operand" "r")
1416                               (const_int 16))
1417                              (zero_extend:SI
1418                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1419                     (const_int 0)))
1420    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1421         (mult:SI (lshiftrt:SI
1422                   (match_dup 2)
1423                   (const_int 16))
1424                  (zero_extend:SI
1425                   (match_dup 1))))]
1426   "TARGET_MULHW"
1427   "mulchwu. %0,%1,%2"
1428   [(set_attr "type" "halfmul")])
1430 (define_insn "*mulchwu"
1431   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1432         (mult:SI (lshiftrt:SI
1433                   (match_operand:SI 2 "gpc_reg_operand" "r")
1434                   (const_int 16))
1435                  (zero_extend:SI
1436                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1437   "TARGET_MULHW"
1438   "mulchwu %0,%1,%2"
1439   [(set_attr "type" "halfmul")])
1441 (define_insn "*mulhhwc"
1442   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1443         (compare:CC (mult:SI (ashiftrt:SI
1444                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1445                               (const_int 16))
1446                              (ashiftrt:SI
1447                               (match_operand:SI 2 "gpc_reg_operand" "r")
1448                               (const_int 16)))
1449                     (const_int 0)))
1450    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1451         (mult:SI (ashiftrt:SI
1452                   (match_dup 1)
1453                   (const_int 16))
1454                  (ashiftrt:SI
1455                   (match_dup 2)
1456                   (const_int 16))))]
1457   "TARGET_MULHW"
1458   "mulhhw. %0,%1,%2"
1459   [(set_attr "type" "halfmul")])
1461 (define_insn "*mulhhw"
1462   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1463         (mult:SI (ashiftrt:SI
1464                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1465                   (const_int 16))
1466                  (ashiftrt:SI
1467                   (match_operand:SI 2 "gpc_reg_operand" "r")
1468                   (const_int 16))))]
1469   "TARGET_MULHW"
1470   "mulhhw %0,%1,%2"
1471   [(set_attr "type" "halfmul")])
1473 (define_insn "*mulhhwuc"
1474   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1475         (compare:CC (mult:SI (lshiftrt:SI
1476                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1477                               (const_int 16))
1478                              (lshiftrt:SI
1479                               (match_operand:SI 2 "gpc_reg_operand" "r")
1480                               (const_int 16)))
1481                     (const_int 0)))
1482    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1483         (mult:SI (lshiftrt:SI
1484                   (match_dup 1)
1485                   (const_int 16))
1486                  (lshiftrt:SI
1487                   (match_dup 2)
1488                   (const_int 16))))]
1489   "TARGET_MULHW"
1490   "mulhhwu. %0,%1,%2"
1491   [(set_attr "type" "halfmul")])
1493 (define_insn "*mulhhwu"
1494   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1495         (mult:SI (lshiftrt:SI
1496                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1497                   (const_int 16))
1498                  (lshiftrt:SI
1499                   (match_operand:SI 2 "gpc_reg_operand" "r")
1500                   (const_int 16))))]
1501   "TARGET_MULHW"
1502   "mulhhwu %0,%1,%2"
1503   [(set_attr "type" "halfmul")])
1505 (define_insn "*mullhwc"
1506   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1507         (compare:CC (mult:SI (sign_extend:SI
1508                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1509                              (sign_extend:SI
1510                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1511                     (const_int 0)))
1512    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1513         (mult:SI (sign_extend:SI
1514                   (match_dup 1))
1515                  (sign_extend:SI
1516                   (match_dup 2))))]
1517   "TARGET_MULHW"
1518   "mullhw. %0,%1,%2"
1519   [(set_attr "type" "halfmul")])
1521 (define_insn "*mullhw"
1522   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1523         (mult:SI (sign_extend:SI
1524                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1525                  (sign_extend:SI
1526                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1527   "TARGET_MULHW"
1528   "mullhw %0,%1,%2"
1529   [(set_attr "type" "halfmul")])
1531 (define_insn "*mullhwuc"
1532   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1533         (compare:CC (mult:SI (zero_extend:SI
1534                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1535                              (zero_extend:SI
1536                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1537                     (const_int 0)))
1538    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1539         (mult:SI (zero_extend:SI
1540                   (match_dup 1))
1541                  (zero_extend:SI
1542                   (match_dup 2))))]
1543   "TARGET_MULHW"
1544   "mullhwu. %0,%1,%2"
1545   [(set_attr "type" "halfmul")])
1547 (define_insn "*mullhwu"
1548   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1549         (mult:SI (zero_extend:SI
1550                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1551                  (zero_extend:SI
1552                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1553   "TARGET_MULHW"
1554   "mullhwu %0,%1,%2"
1555   [(set_attr "type" "halfmul")])
1557 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1558 (define_insn "dlmzb"
1559   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1560         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1561                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1562                    UNSPEC_DLMZB_CR))
1563    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1564         (unspec:SI [(match_dup 1)
1565                     (match_dup 2)]
1566                    UNSPEC_DLMZB))]
1567   "TARGET_DLMZB"
1568   "dlmzb. %0,%1,%2")
1570 (define_expand "strlensi"
1571   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1572         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1573                     (match_operand:QI 2 "const_int_operand" "")
1574                     (match_operand 3 "const_int_operand" "")]
1575                    UNSPEC_DLMZB_STRLEN))
1576    (clobber (match_scratch:CC 4 "=x"))]
1577   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1579   rtx result = operands[0];
1580   rtx src = operands[1];
1581   rtx search_char = operands[2];
1582   rtx align = operands[3];
1583   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1584   rtx loop_label, end_label, mem, cr0, cond;
1585   if (search_char != const0_rtx
1586       || GET_CODE (align) != CONST_INT
1587       || INTVAL (align) < 8)
1588         FAIL;
1589   word1 = gen_reg_rtx (SImode);
1590   word2 = gen_reg_rtx (SImode);
1591   scratch_dlmzb = gen_reg_rtx (SImode);
1592   scratch_string = gen_reg_rtx (Pmode);
1593   loop_label = gen_label_rtx ();
1594   end_label = gen_label_rtx ();
1595   addr = force_reg (Pmode, XEXP (src, 0));
1596   emit_move_insn (scratch_string, addr);
1597   emit_label (loop_label);
1598   mem = change_address (src, SImode, scratch_string);
1599   emit_move_insn (word1, mem);
1600   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1601   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1602   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1603   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1604   emit_jump_insn (gen_rtx_SET (pc_rtx,
1605                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1606                                                      cond,
1607                                                      gen_rtx_LABEL_REF
1608                                                        (VOIDmode,
1609                                                         end_label),
1610                                                      pc_rtx)));
1611   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1612   emit_jump_insn (gen_rtx_SET (pc_rtx,
1613                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1614   emit_barrier ();
1615   emit_label (end_label);
1616   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1617   emit_insn (gen_subsi3 (result, scratch_string, addr));
1618   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1619   DONE;
1622 ;; Fixed-point arithmetic insns.
1624 (define_expand "add<mode>3"
1625   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1626         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1627                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1628   ""
1630   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1631     {
1632       rtx lo0 = gen_lowpart (SImode, operands[0]);
1633       rtx lo1 = gen_lowpart (SImode, operands[1]);
1634       rtx lo2 = gen_lowpart (SImode, operands[2]);
1635       rtx hi0 = gen_highpart (SImode, operands[0]);
1636       rtx hi1 = gen_highpart (SImode, operands[1]);
1637       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1639       if (!reg_or_short_operand (lo2, SImode))
1640         lo2 = force_reg (SImode, lo2);
1641       if (!adde_operand (hi2, SImode))
1642         hi2 = force_reg (SImode, hi2);
1644       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1645       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1646       DONE;
1647     }
1649   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1650     {
1651       rtx tmp = ((!can_create_pseudo_p ()
1652                   || rtx_equal_p (operands[0], operands[1]))
1653                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1655       /* Adding a constant to r0 is not a valid insn, so use a different
1656          strategy in that case.  */
1657       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1658         {
1659           if (operands[0] == operands[1])
1660             FAIL;
1661           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1662           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1663           DONE;
1664         }
1666       HOST_WIDE_INT val = INTVAL (operands[2]);
1667       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1668       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1670       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1671         FAIL;
1673       /* The ordering here is important for the prolog expander.
1674          When space is allocated from the stack, adding 'low' first may
1675          produce a temporary deallocation (which would be bad).  */
1676       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1677       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1678       DONE;
1679     }
1682 (define_insn "*add<mode>3"
1683   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1684         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1685                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1686   ""
1687   "@
1688    add %0,%1,%2
1689    addi %0,%1,%2
1690    addis %0,%1,%v2"
1691   [(set_attr "type" "add")])
1693 (define_insn "addsi3_high"
1694   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1695         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1696                  (high:SI (match_operand 2 "" ""))))]
1697   "TARGET_MACHO && !TARGET_64BIT"
1698   "addis %0,%1,ha16(%2)"
1699   [(set_attr "type" "add")])
1701 (define_insn_and_split "*add<mode>3_dot"
1702   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1703         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1704                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1705                     (const_int 0)))
1706    (clobber (match_scratch:GPR 0 "=r,r"))]
1707   "<MODE>mode == Pmode"
1708   "@
1709    add. %0,%1,%2
1710    #"
1711   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1712   [(set (match_dup 0)
1713         (plus:GPR (match_dup 1)
1714                  (match_dup 2)))
1715    (set (match_dup 3)
1716         (compare:CC (match_dup 0)
1717                     (const_int 0)))]
1718   ""
1719   [(set_attr "type" "add")
1720    (set_attr "dot" "yes")
1721    (set_attr "length" "4,8")])
1723 (define_insn_and_split "*add<mode>3_dot2"
1724   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1725         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1726                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1727                     (const_int 0)))
1728    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1729         (plus:GPR (match_dup 1)
1730                   (match_dup 2)))]
1731   "<MODE>mode == Pmode"
1732   "@
1733    add. %0,%1,%2
1734    #"
1735   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1736   [(set (match_dup 0)
1737         (plus:GPR (match_dup 1)
1738                   (match_dup 2)))
1739    (set (match_dup 3)
1740         (compare:CC (match_dup 0)
1741                     (const_int 0)))]
1742   ""
1743   [(set_attr "type" "add")
1744    (set_attr "dot" "yes")
1745    (set_attr "length" "4,8")])
1747 (define_insn_and_split "*add<mode>3_imm_dot"
1748   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1749         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1750                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1751                     (const_int 0)))
1752    (clobber (match_scratch:GPR 0 "=r,r"))
1753    (clobber (reg:GPR CA_REGNO))]
1754   "<MODE>mode == Pmode"
1755   "@
1756    addic. %0,%1,%2
1757    #"
1758   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1759   [(set (match_dup 0)
1760         (plus:GPR (match_dup 1)
1761                   (match_dup 2)))
1762    (set (match_dup 3)
1763         (compare:CC (match_dup 0)
1764                     (const_int 0)))]
1765   ""
1766   [(set_attr "type" "add")
1767    (set_attr "dot" "yes")
1768    (set_attr "length" "4,8")])
1770 (define_insn_and_split "*add<mode>3_imm_dot2"
1771   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1772         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1773                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1774                     (const_int 0)))
1775    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1776         (plus:GPR (match_dup 1)
1777                   (match_dup 2)))
1778    (clobber (reg:GPR CA_REGNO))]
1779   "<MODE>mode == Pmode"
1780   "@
1781    addic. %0,%1,%2
1782    #"
1783   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1784   [(set (match_dup 0)
1785         (plus:GPR (match_dup 1)
1786                   (match_dup 2)))
1787    (set (match_dup 3)
1788         (compare:CC (match_dup 0)
1789                     (const_int 0)))]
1790   ""
1791   [(set_attr "type" "add")
1792    (set_attr "dot" "yes")
1793    (set_attr "length" "4,8")])
1795 ;; Split an add that we can't do in one insn into two insns, each of which
1796 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1797 ;; add should be last in case the result gets used in an address.
1799 (define_split
1800   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1801         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1802                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1803   ""
1804   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1805    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1807   HOST_WIDE_INT val = INTVAL (operands[2]);
1808   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1809   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1811   operands[4] = GEN_INT (low);
1812   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1813     operands[3] = GEN_INT (rest);
1814   else if (can_create_pseudo_p ())
1815     {
1816       operands[3] = gen_reg_rtx (DImode);
1817       emit_move_insn (operands[3], operands[2]);
1818       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1819       DONE;
1820     }
1821   else
1822     FAIL;
1826 (define_insn "add<mode>3_carry"
1827   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1828         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1829                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1830    (set (reg:P CA_REGNO)
1831         (ltu:P (plus:P (match_dup 1)
1832                        (match_dup 2))
1833                (match_dup 1)))]
1834   ""
1835   "add%I2c %0,%1,%2"
1836   [(set_attr "type" "add")])
1838 (define_insn "*add<mode>3_imm_carry_pos"
1839   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1840         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1841                 (match_operand:P 2 "short_cint_operand" "n")))
1842    (set (reg:P CA_REGNO)
1843         (geu:P (match_dup 1)
1844                (match_operand:P 3 "const_int_operand" "n")))]
1845   "INTVAL (operands[2]) > 0
1846    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1847   "addic %0,%1,%2"
1848   [(set_attr "type" "add")])
1850 (define_insn "*add<mode>3_imm_carry_0"
1851   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1852         (match_operand:P 1 "gpc_reg_operand" "r"))
1853    (set (reg:P CA_REGNO)
1854         (const_int 0))]
1855   ""
1856   "addic %0,%1,0"
1857   [(set_attr "type" "add")])
1859 (define_insn "*add<mode>3_imm_carry_m1"
1860   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1861         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1862                 (const_int -1)))
1863    (set (reg:P CA_REGNO)
1864         (ne:P (match_dup 1)
1865               (const_int 0)))]
1866   ""
1867   "addic %0,%1,-1"
1868   [(set_attr "type" "add")])
1870 (define_insn "*add<mode>3_imm_carry_neg"
1871   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1872         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1873                 (match_operand:P 2 "short_cint_operand" "n")))
1874    (set (reg:P CA_REGNO)
1875         (gtu:P (match_dup 1)
1876                (match_operand:P 3 "const_int_operand" "n")))]
1877   "INTVAL (operands[2]) < 0
1878    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1879   "addic %0,%1,%2"
1880   [(set_attr "type" "add")])
1883 (define_expand "add<mode>3_carry_in"
1884   [(parallel [
1885      (set (match_operand:GPR 0 "gpc_reg_operand")
1886           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1887                               (match_operand:GPR 2 "adde_operand"))
1888                     (reg:GPR CA_REGNO)))
1889      (clobber (reg:GPR CA_REGNO))])]
1890   ""
1892   if (operands[2] == const0_rtx)
1893     {
1894       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1895       DONE;
1896     }
1897   if (operands[2] == constm1_rtx)
1898     {
1899       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1900       DONE;
1901     }
1904 (define_insn "*add<mode>3_carry_in_internal"
1905   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1906         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1907                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1908                   (reg:GPR CA_REGNO)))
1909    (clobber (reg:GPR CA_REGNO))]
1910   ""
1911   "adde %0,%1,%2"
1912   [(set_attr "type" "add")])
1914 (define_insn "add<mode>3_carry_in_0"
1915   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1916         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1917                   (reg:GPR CA_REGNO)))
1918    (clobber (reg:GPR CA_REGNO))]
1919   ""
1920   "addze %0,%1"
1921   [(set_attr "type" "add")])
1923 (define_insn "add<mode>3_carry_in_m1"
1924   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1925         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1926                             (reg:GPR CA_REGNO))
1927                   (const_int -1)))
1928    (clobber (reg:GPR CA_REGNO))]
1929   ""
1930   "addme %0,%1"
1931   [(set_attr "type" "add")])
1934 (define_expand "one_cmpl<mode>2"
1935   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1936         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1937   ""
1939   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1940     {
1941       rs6000_split_logical (operands, NOT, false, false, false);
1942       DONE;
1943     }
1946 (define_insn "*one_cmpl<mode>2"
1947   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1948         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1949   ""
1950   "not %0,%1")
1952 (define_insn_and_split "*one_cmpl<mode>2_dot"
1953   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1954         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1955                     (const_int 0)))
1956    (clobber (match_scratch:GPR 0 "=r,r"))]
1957   "<MODE>mode == Pmode"
1958   "@
1959    not. %0,%1
1960    #"
1961   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1962   [(set (match_dup 0)
1963         (not:GPR (match_dup 1)))
1964    (set (match_dup 2)
1965         (compare:CC (match_dup 0)
1966                     (const_int 0)))]
1967   ""
1968   [(set_attr "type" "logical")
1969    (set_attr "dot" "yes")
1970    (set_attr "length" "4,8")])
1972 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1973   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1974         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1975                     (const_int 0)))
1976    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1977         (not:GPR (match_dup 1)))]
1978   "<MODE>mode == Pmode"
1979   "@
1980    not. %0,%1
1981    #"
1982   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1983   [(set (match_dup 0)
1984         (not:GPR (match_dup 1)))
1985    (set (match_dup 2)
1986         (compare:CC (match_dup 0)
1987                     (const_int 0)))]
1988   ""
1989   [(set_attr "type" "logical")
1990    (set_attr "dot" "yes")
1991    (set_attr "length" "4,8")])
1994 (define_expand "sub<mode>3"
1995   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1996         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1997                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1998   ""
2000   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2001     {
2002       rtx lo0 = gen_lowpart (SImode, operands[0]);
2003       rtx lo1 = gen_lowpart (SImode, operands[1]);
2004       rtx lo2 = gen_lowpart (SImode, operands[2]);
2005       rtx hi0 = gen_highpart (SImode, operands[0]);
2006       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2007       rtx hi2 = gen_highpart (SImode, operands[2]);
2009       if (!reg_or_short_operand (lo1, SImode))
2010         lo1 = force_reg (SImode, lo1);
2011       if (!adde_operand (hi1, SImode))
2012         hi1 = force_reg (SImode, hi1);
2014       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2015       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2016       DONE;
2017     }
2019   if (short_cint_operand (operands[1], <MODE>mode))
2020     {
2021       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2022       DONE;
2023     }
2026 (define_insn "*subf<mode>3"
2027   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2028         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2029                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2030   ""
2031   "subf %0,%1,%2"
2032   [(set_attr "type" "add")])
2034 (define_insn_and_split "*subf<mode>3_dot"
2035   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2036         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2037                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2038                     (const_int 0)))
2039    (clobber (match_scratch:GPR 0 "=r,r"))]
2040   "<MODE>mode == Pmode"
2041   "@
2042    subf. %0,%1,%2
2043    #"
2044   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2045   [(set (match_dup 0)
2046         (minus:GPR (match_dup 2)
2047                    (match_dup 1)))
2048    (set (match_dup 3)
2049         (compare:CC (match_dup 0)
2050                     (const_int 0)))]
2051   ""
2052   [(set_attr "type" "add")
2053    (set_attr "dot" "yes")
2054    (set_attr "length" "4,8")])
2056 (define_insn_and_split "*subf<mode>3_dot2"
2057   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2058         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2059                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2060                     (const_int 0)))
2061    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2062         (minus:GPR (match_dup 2)
2063                    (match_dup 1)))]
2064   "<MODE>mode == Pmode"
2065   "@
2066    subf. %0,%1,%2
2067    #"
2068   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2069   [(set (match_dup 0)
2070         (minus:GPR (match_dup 2)
2071                    (match_dup 1)))
2072    (set (match_dup 3)
2073         (compare:CC (match_dup 0)
2074                     (const_int 0)))]
2075   ""
2076   [(set_attr "type" "add")
2077    (set_attr "dot" "yes")
2078    (set_attr "length" "4,8")])
2080 (define_insn "subf<mode>3_imm"
2081   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2082         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2083                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2084    (clobber (reg:GPR CA_REGNO))]
2085   ""
2086   "subfic %0,%1,%2"
2087   [(set_attr "type" "add")])
2089 (define_insn_and_split "subf<mode>3_carry_dot2"
2090   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2091         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2092                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2093                     (const_int 0)))
2094    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2095         (minus:P (match_dup 2)
2096                    (match_dup 1)))
2097    (set (reg:P CA_REGNO)
2098         (leu:P (match_dup 1)
2099                (match_dup 2)))]
2100   "<MODE>mode == Pmode"
2101   "@
2102    subfc. %0,%1,%2
2103    #"
2104   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2105   [(parallel [(set (match_dup 0)
2106                    (minus:P (match_dup 2)
2107                             (match_dup 1)))
2108               (set (reg:P CA_REGNO)
2109                    (leu:P (match_dup 1)
2110                           (match_dup 2)))])
2111    (set (match_dup 3)
2112         (compare:CC (match_dup 0)
2113                     (const_int 0)))]
2114   ""
2115   [(set_attr "type" "add")
2116    (set_attr "dot" "yes")
2117    (set_attr "length" "4,8")])
2119 (define_insn "subf<mode>3_carry"
2120   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2121         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2122                  (match_operand:P 1 "gpc_reg_operand" "r")))
2123    (set (reg:P CA_REGNO)
2124         (leu:P (match_dup 1)
2125                (match_dup 2)))]
2126   ""
2127   "subf%I2c %0,%1,%2"
2128   [(set_attr "type" "add")])
2130 (define_insn "*subf<mode>3_imm_carry_0"
2131   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2132         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2133    (set (reg:P CA_REGNO)
2134         (eq:P (match_dup 1)
2135               (const_int 0)))]
2136   ""
2137   "subfic %0,%1,0"
2138   [(set_attr "type" "add")])
2140 (define_insn "*subf<mode>3_imm_carry_m1"
2141   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2142         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2143    (set (reg:P CA_REGNO)
2144         (const_int 1))]
2145   ""
2146   "subfic %0,%1,-1"
2147   [(set_attr "type" "add")])
2150 (define_expand "subf<mode>3_carry_in"
2151   [(parallel [
2152      (set (match_operand:GPR 0 "gpc_reg_operand")
2153           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2154                               (reg:GPR CA_REGNO))
2155                     (match_operand:GPR 2 "adde_operand")))
2156      (clobber (reg:GPR CA_REGNO))])]
2157   ""
2159   if (operands[2] == const0_rtx)
2160     {
2161       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2162       DONE;
2163     }
2164   if (operands[2] == constm1_rtx)
2165     {
2166       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2167       DONE;
2168     }
2171 (define_insn "*subf<mode>3_carry_in_internal"
2172   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2173         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2174                             (reg:GPR CA_REGNO))
2175                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2176    (clobber (reg:GPR CA_REGNO))]
2177   ""
2178   "subfe %0,%1,%2"
2179   [(set_attr "type" "add")])
2181 (define_insn "subf<mode>3_carry_in_0"
2182   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2183         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2184                   (reg:GPR CA_REGNO)))
2185    (clobber (reg:GPR CA_REGNO))]
2186   ""
2187   "subfze %0,%1"
2188   [(set_attr "type" "add")])
2190 (define_insn "subf<mode>3_carry_in_m1"
2191   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2192         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2193                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2194                   (const_int -2)))
2195    (clobber (reg:GPR CA_REGNO))]
2196   ""
2197   "subfme %0,%1"
2198   [(set_attr "type" "add")])
2200 (define_insn "subf<mode>3_carry_in_xx"
2201   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2202         (plus:GPR (reg:GPR CA_REGNO)
2203                   (const_int -1)))
2204    (clobber (reg:GPR CA_REGNO))]
2205   ""
2206   "subfe %0,%0,%0"
2207   [(set_attr "type" "add")])
2210 (define_insn "neg<mode>2"
2211   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2212         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2213   ""
2214   "neg %0,%1"
2215   [(set_attr "type" "add")])
2217 (define_insn_and_split "*neg<mode>2_dot"
2218   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2219         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2220                     (const_int 0)))
2221    (clobber (match_scratch:GPR 0 "=r,r"))]
2222   "<MODE>mode == Pmode"
2223   "@
2224    neg. %0,%1
2225    #"
2226   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2227   [(set (match_dup 0)
2228         (neg:GPR (match_dup 1)))
2229    (set (match_dup 2)
2230         (compare:CC (match_dup 0)
2231                     (const_int 0)))]
2232   ""
2233   [(set_attr "type" "add")
2234    (set_attr "dot" "yes")
2235    (set_attr "length" "4,8")])
2237 (define_insn_and_split "*neg<mode>2_dot2"
2238   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2239         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2240                     (const_int 0)))
2241    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2242         (neg:GPR (match_dup 1)))]
2243   "<MODE>mode == Pmode"
2244   "@
2245    neg. %0,%1
2246    #"
2247   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2248   [(set (match_dup 0)
2249         (neg:GPR (match_dup 1)))
2250    (set (match_dup 2)
2251         (compare:CC (match_dup 0)
2252                     (const_int 0)))]
2253   ""
2254   [(set_attr "type" "add")
2255    (set_attr "dot" "yes")
2256    (set_attr "length" "4,8")])
2259 (define_insn "clz<mode>2"
2260   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2261         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2262   ""
2263   "cntlz<wd> %0,%1"
2264   [(set_attr "type" "cntlz")])
2266 (define_expand "ctz<mode>2"
2267    [(set (match_operand:GPR 0 "gpc_reg_operand")
2268          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2269   ""
2271   if (TARGET_CTZ)
2272     {
2273       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2274       DONE;
2275     }
2277   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2278   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2279   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2281   if (TARGET_POPCNTD)
2282     {
2283       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2284       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2285       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2286       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2287     }
2288   else
2289     {
2290       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2291       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2292       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2293       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2294     }
2296   DONE;
2299 (define_insn "ctz<mode>2_hw"
2300   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2301         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2302   "TARGET_CTZ"
2303   "cnttz<wd> %0,%1"
2304   [(set_attr "type" "cntlz")])
2306 (define_expand "ffs<mode>2"
2307   [(set (match_operand:GPR 0 "gpc_reg_operand")
2308         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2309   ""
2311   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2312   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2313   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2314   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2315   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2316   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2317   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2318   DONE;
2322 (define_expand "popcount<mode>2"
2323   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2324         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2325   "TARGET_POPCNTB || TARGET_POPCNTD"
2327   rs6000_emit_popcount (operands[0], operands[1]);
2328   DONE;
2331 (define_insn "popcntb<mode>2"
2332   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2333         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2334                     UNSPEC_POPCNTB))]
2335   "TARGET_POPCNTB"
2336   "popcntb %0,%1"
2337   [(set_attr "type" "popcnt")])
2339 (define_insn "popcntd<mode>2"
2340   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2341         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2342   "TARGET_POPCNTD"
2343   "popcnt<wd> %0,%1"
2344   [(set_attr "type" "popcnt")])
2347 (define_expand "parity<mode>2"
2348   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2349         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2350   "TARGET_POPCNTB"
2352   rs6000_emit_parity (operands[0], operands[1]);
2353   DONE;
2356 (define_insn "parity<mode>2_cmpb"
2357   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2358         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2359   "TARGET_CMPB && TARGET_POPCNTB"
2360   "prty<wd> %0,%1"
2361   [(set_attr "type" "popcnt")])
2363 (define_insn "cmpb<mode>3"
2364   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2365         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2366                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2367   "TARGET_CMPB"
2368   "cmpb %0,%1,%2"
2369   [(set_attr "type" "cmp")])
2371 ;; Since the hardware zeros the upper part of the register, save generating the
2372 ;; AND immediate if we are converting to unsigned
2373 (define_insn "*bswap<mode>2_extenddi"
2374   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2375         (zero_extend:DI
2376          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2377   "TARGET_POWERPC64"
2378   "l<wd>brx %0,%y1"
2379   [(set_attr "length" "4")
2380    (set_attr "type" "load")])
2382 (define_insn "*bswaphi2_extendsi"
2383   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2384         (zero_extend:SI
2385          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2386   ""
2387   "lhbrx %0,%y1"
2388   [(set_attr "length" "4")
2389    (set_attr "type" "load")])
2391 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2392 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2393 ;; load with byte swap, which can be slower than doing it in the registers.  It
2394 ;; also prevents certain failures with the RELOAD register allocator.
2396 (define_expand "bswap<mode>2"
2397   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2398    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2399   ""
2401   rtx dest = operands[0];
2402   rtx src = operands[1];
2404   if (!REG_P (dest) && !REG_P (src))
2405     src = force_reg (<MODE>mode, src);
2407   if (MEM_P (src))
2408     emit_insn (gen_bswap<mode>2_load (dest, src));
2409   else if (MEM_P (dest))
2410     emit_insn (gen_bswap<mode>2_store (dest, src));
2411   else
2412     emit_insn (gen_bswap<mode>2_reg (dest, src));
2413   DONE;
2416 (define_insn "bswap<mode>2_load"
2417   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2418         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2419   ""
2420   "l<wd>brx %0,%y1"
2421   [(set_attr "type" "load")])
2423 (define_insn "bswap<mode>2_store"
2424   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2425         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2426   ""
2427   "st<wd>brx %1,%y0"
2428   [(set_attr "type" "store")])
2430 (define_insn_and_split "bswaphi2_reg"
2431   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2432         (bswap:HI
2433          (match_operand:HI 1 "gpc_reg_operand" "r")))
2434    (clobber (match_scratch:SI 2 "=&r"))]
2435   ""
2436   "#"
2437   "reload_completed"
2438   [(set (match_dup 3)
2439         (and:SI (lshiftrt:SI (match_dup 4)
2440                              (const_int 8))
2441                 (const_int 255)))
2442    (set (match_dup 2)
2443         (and:SI (ashift:SI (match_dup 4)
2444                            (const_int 8))
2445                 (const_int 65280)))             ;; 0xff00
2446    (set (match_dup 3)
2447         (ior:SI (match_dup 3)
2448                 (match_dup 2)))]
2450   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2451   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2453   [(set_attr "length" "12")
2454    (set_attr "type" "*")])
2456 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2457 ;; zero_extract insns do not change for -mlittle.
2458 (define_insn_and_split "bswapsi2_reg"
2459   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2460         (bswap:SI
2461          (match_operand:SI 1 "gpc_reg_operand" "r")))]
2462   ""
2463   "#"
2464   "reload_completed"
2465   [(set (match_dup 0)                                   ; DABC
2466         (rotate:SI (match_dup 1)
2467                    (const_int 24)))
2468    (set (match_dup 0)                                   ; DCBC
2469         (ior:SI (and:SI (ashift:SI (match_dup 1)
2470                                    (const_int 8))
2471                         (const_int 16711680))
2472                 (and:SI (match_dup 0)
2473                         (const_int -16711681))))
2474    (set (match_dup 0)                                   ; DCBA
2475         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2476                                      (const_int 24))
2477                         (const_int 255))
2478                 (and:SI (match_dup 0)
2479                         (const_int -256))))]
2480   "")
2482 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2483 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2484 ;; complex code.
2486 (define_expand "bswapdi2"
2487   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2488                    (bswap:DI
2489                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2490               (clobber (match_scratch:DI 2 ""))
2491               (clobber (match_scratch:DI 3 ""))])]
2492   ""
2494   rtx dest = operands[0];
2495   rtx src = operands[1];
2497   if (!REG_P (dest) && !REG_P (src))
2498     operands[1] = src = force_reg (DImode, src);
2500   if (TARGET_POWERPC64 && TARGET_LDBRX)
2501     {
2502       if (MEM_P (src))
2503         emit_insn (gen_bswapdi2_load (dest, src));
2504       else if (MEM_P (dest))
2505         emit_insn (gen_bswapdi2_store (dest, src));
2506       else
2507         emit_insn (gen_bswapdi2_reg (dest, src));
2508       DONE;
2509     }
2511   if (!TARGET_POWERPC64)
2512     {
2513       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2514          that uses 64-bit registers needs the same scratch registers as 64-bit
2515          mode.  */
2516       emit_insn (gen_bswapdi2_32bit (dest, src));
2517       DONE;
2518     }
2521 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2522 (define_insn "bswapdi2_load"
2523   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2524         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2525   "TARGET_POWERPC64 && TARGET_LDBRX"
2526   "ldbrx %0,%y1"
2527   [(set_attr "type" "load")])
2529 (define_insn "bswapdi2_store"
2530   [(set (match_operand:DI 0 "memory_operand" "=Z")
2531         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2532   "TARGET_POWERPC64 && TARGET_LDBRX"
2533   "stdbrx %1,%y0"
2534   [(set_attr "type" "store")])
2536 (define_insn "bswapdi2_reg"
2537   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2538         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2539    (clobber (match_scratch:DI 2 "=&r"))
2540    (clobber (match_scratch:DI 3 "=&r"))]
2541   "TARGET_POWERPC64 && TARGET_LDBRX"
2542   "#"
2543   [(set_attr "length" "36")])
2545 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2546 (define_insn "*bswapdi2_64bit"
2547   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2548         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2549    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2550    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2551   "TARGET_POWERPC64 && !TARGET_LDBRX
2552    && (REG_P (operands[0]) || REG_P (operands[1]))
2553    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2554    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2555   "#"
2556   [(set_attr "length" "16,12,36")])
2558 (define_split
2559   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2560         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2561    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2562    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2563   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2564   [(const_int 0)]
2565   "
2567   rtx dest   = operands[0];
2568   rtx src    = operands[1];
2569   rtx op2    = operands[2];
2570   rtx op3    = operands[3];
2571   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2572                                     BYTES_BIG_ENDIAN ? 4 : 0);
2573   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2574                                      BYTES_BIG_ENDIAN ? 4 : 0);
2575   rtx addr1;
2576   rtx addr2;
2577   rtx word1;
2578   rtx word2;
2580   addr1 = XEXP (src, 0);
2581   if (GET_CODE (addr1) == PLUS)
2582     {
2583       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2584       if (TARGET_AVOID_XFORM)
2585         {
2586           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2587           addr2 = op2;
2588         }
2589       else
2590         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2591     }
2592   else if (TARGET_AVOID_XFORM)
2593     {
2594       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2595       addr2 = op2;
2596     }
2597   else
2598     {
2599       emit_move_insn (op2, GEN_INT (4));
2600       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2601     }
2603   word1 = change_address (src, SImode, addr1);
2604   word2 = change_address (src, SImode, addr2);
2606   if (BYTES_BIG_ENDIAN)
2607     {
2608       emit_insn (gen_bswapsi2 (op3_32, word2));
2609       emit_insn (gen_bswapsi2 (dest_32, word1));
2610     }
2611   else
2612     {
2613       emit_insn (gen_bswapsi2 (op3_32, word1));
2614       emit_insn (gen_bswapsi2 (dest_32, word2));
2615     }
2617   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2618   emit_insn (gen_iordi3 (dest, dest, op3));
2619   DONE;
2622 (define_split
2623   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2624         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2625    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2626    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2627   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2628   [(const_int 0)]
2629   "
2631   rtx dest   = operands[0];
2632   rtx src    = operands[1];
2633   rtx op2    = operands[2];
2634   rtx op3    = operands[3];
2635   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2636                                     BYTES_BIG_ENDIAN ? 4 : 0);
2637   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2638                                     BYTES_BIG_ENDIAN ? 4 : 0);
2639   rtx addr1;
2640   rtx addr2;
2641   rtx word1;
2642   rtx word2;
2644   addr1 = XEXP (dest, 0);
2645   if (GET_CODE (addr1) == PLUS)
2646     {
2647       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2648       if (TARGET_AVOID_XFORM)
2649         {
2650           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2651           addr2 = op2;
2652         }
2653       else
2654         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2655     }
2656   else if (TARGET_AVOID_XFORM)
2657     {
2658       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2659       addr2 = op2;
2660     }
2661   else
2662     {
2663       emit_move_insn (op2, GEN_INT (4));
2664       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2665     }
2667   word1 = change_address (dest, SImode, addr1);
2668   word2 = change_address (dest, SImode, addr2);
2670   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2672   if (BYTES_BIG_ENDIAN)
2673     {
2674       emit_insn (gen_bswapsi2 (word1, src_si));
2675       emit_insn (gen_bswapsi2 (word2, op3_si));
2676     }
2677   else
2678     {
2679       emit_insn (gen_bswapsi2 (word2, src_si));
2680       emit_insn (gen_bswapsi2 (word1, op3_si));
2681     }
2682   DONE;
2685 (define_split
2686   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2687         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2688    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2689    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2690   "TARGET_POWERPC64 && reload_completed"
2691   [(const_int 0)]
2692   "
2694   rtx dest    = operands[0];
2695   rtx src     = operands[1];
2696   rtx op2     = operands[2];
2697   rtx op3     = operands[3];
2698   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2699   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2700   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2701   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2702   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2704   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2705   emit_insn (gen_bswapsi2 (dest_si, src_si));
2706   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2707   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2708   emit_insn (gen_iordi3 (dest, dest, op3));
2709   DONE;
2712 (define_insn "bswapdi2_32bit"
2713   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2714         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2715    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2716   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2717   "#"
2718   [(set_attr "length" "16,12,36")])
2720 (define_split
2721   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2722         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2723    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2724   "!TARGET_POWERPC64 && reload_completed"
2725   [(const_int 0)]
2726   "
2728   rtx dest  = operands[0];
2729   rtx src   = operands[1];
2730   rtx op2   = operands[2];
2731   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2732   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2733   rtx addr1;
2734   rtx addr2;
2735   rtx word1;
2736   rtx word2;
2738   addr1 = XEXP (src, 0);
2739   if (GET_CODE (addr1) == PLUS)
2740     {
2741       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2742       if (TARGET_AVOID_XFORM
2743           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2744         {
2745           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2746           addr2 = op2;
2747         }
2748       else
2749         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2750     }
2751   else if (TARGET_AVOID_XFORM
2752            || REGNO (addr1) == REGNO (dest2))
2753     {
2754       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2755       addr2 = op2;
2756     }
2757   else
2758     {
2759       emit_move_insn (op2, GEN_INT (4));
2760       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2761     }
2763   word1 = change_address (src, SImode, addr1);
2764   word2 = change_address (src, SImode, addr2);
2766   emit_insn (gen_bswapsi2 (dest2, word1));
2767   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2768      thus allowing us to omit an early clobber on the output.  */
2769   emit_insn (gen_bswapsi2 (dest1, word2));
2770   DONE;
2773 (define_split
2774   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2775         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2776    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2777   "!TARGET_POWERPC64 && reload_completed"
2778   [(const_int 0)]
2779   "
2781   rtx dest = operands[0];
2782   rtx src  = operands[1];
2783   rtx op2  = operands[2];
2784   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2785   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2786   rtx addr1;
2787   rtx addr2;
2788   rtx word1;
2789   rtx word2;
2791   addr1 = XEXP (dest, 0);
2792   if (GET_CODE (addr1) == PLUS)
2793     {
2794       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2795       if (TARGET_AVOID_XFORM)
2796         {
2797           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2798           addr2 = op2;
2799         }
2800       else
2801         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2802     }
2803   else if (TARGET_AVOID_XFORM)
2804     {
2805       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2806       addr2 = op2;
2807     }
2808   else
2809     {
2810       emit_move_insn (op2, GEN_INT (4));
2811       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2812     }
2814   word1 = change_address (dest, SImode, addr1);
2815   word2 = change_address (dest, SImode, addr2);
2817   emit_insn (gen_bswapsi2 (word2, src1));
2818   emit_insn (gen_bswapsi2 (word1, src2));
2819   DONE;
2822 (define_split
2823   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2824         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2825    (clobber (match_operand:SI 2 "" ""))]
2826   "!TARGET_POWERPC64 && reload_completed"
2827   [(const_int 0)]
2828   "
2830   rtx dest  = operands[0];
2831   rtx src   = operands[1];
2832   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2833   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2834   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2835   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2837   emit_insn (gen_bswapsi2 (dest1, src2));
2838   emit_insn (gen_bswapsi2 (dest2, src1));
2839   DONE;
2843 (define_insn "mul<mode>3"
2844   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2845         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2846                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2847   ""
2848   "@
2849    mull<wd> %0,%1,%2
2850    mulli %0,%1,%2"
2851    [(set_attr "type" "mul")
2852     (set (attr "size")
2853       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2854                 (const_string "8")
2855              (match_operand:GPR 2 "short_cint_operand" "")
2856                 (const_string "16")]
2857         (const_string "<bits>")))])
2859 (define_insn_and_split "*mul<mode>3_dot"
2860   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2861         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2862                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2863                     (const_int 0)))
2864    (clobber (match_scratch:GPR 0 "=r,r"))]
2865   "<MODE>mode == Pmode"
2866   "@
2867    mull<wd>. %0,%1,%2
2868    #"
2869   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2870   [(set (match_dup 0)
2871         (mult:GPR (match_dup 1)
2872                   (match_dup 2)))
2873    (set (match_dup 3)
2874         (compare:CC (match_dup 0)
2875                     (const_int 0)))]
2876   ""
2877   [(set_attr "type" "mul")
2878    (set_attr "size" "<bits>")
2879    (set_attr "dot" "yes")
2880    (set_attr "length" "4,8")])
2882 (define_insn_and_split "*mul<mode>3_dot2"
2883   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2884         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2885                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2886                     (const_int 0)))
2887    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2888         (mult:GPR (match_dup 1)
2889                   (match_dup 2)))]
2890   "<MODE>mode == Pmode"
2891   "@
2892    mull<wd>. %0,%1,%2
2893    #"
2894   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2895   [(set (match_dup 0)
2896         (mult:GPR (match_dup 1)
2897                   (match_dup 2)))
2898    (set (match_dup 3)
2899         (compare:CC (match_dup 0)
2900                     (const_int 0)))]
2901   ""
2902   [(set_attr "type" "mul")
2903    (set_attr "size" "<bits>")
2904    (set_attr "dot" "yes")
2905    (set_attr "length" "4,8")])
2908 (define_expand "<su>mul<mode>3_highpart"
2909   [(set (match_operand:GPR 0 "gpc_reg_operand")
2910         (subreg:GPR
2911           (mult:<DMODE> (any_extend:<DMODE>
2912                           (match_operand:GPR 1 "gpc_reg_operand"))
2913                         (any_extend:<DMODE>
2914                           (match_operand:GPR 2 "gpc_reg_operand")))
2915          0))]
2916   ""
2918   if (<MODE>mode == SImode && TARGET_POWERPC64)
2919     {
2920       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2921                                              operands[2]));
2922       DONE;
2923     }
2925   if (!WORDS_BIG_ENDIAN)
2926     {
2927       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2928                                                  operands[2]));
2929       DONE;
2930     }
2933 (define_insn "*<su>mul<mode>3_highpart"
2934   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2935         (subreg:GPR
2936           (mult:<DMODE> (any_extend:<DMODE>
2937                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2938                         (any_extend:<DMODE>
2939                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2940          0))]
2941   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2942   "mulh<wd><u> %0,%1,%2"
2943   [(set_attr "type" "mul")
2944    (set_attr "size" "<bits>")])
2946 (define_insn "<su>mulsi3_highpart_le"
2947   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2948         (subreg:SI
2949           (mult:DI (any_extend:DI
2950                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2951                    (any_extend:DI
2952                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2953          4))]
2954   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2955   "mulhw<u> %0,%1,%2"
2956   [(set_attr "type" "mul")])
2958 (define_insn "<su>muldi3_highpart_le"
2959   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2960         (subreg:DI
2961           (mult:TI (any_extend:TI
2962                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2963                    (any_extend:TI
2964                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2965          8))]
2966   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2967   "mulhd<u> %0,%1,%2"
2968   [(set_attr "type" "mul")
2969    (set_attr "size" "64")])
2971 (define_insn "<su>mulsi3_highpart_64"
2972   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2973         (truncate:SI
2974           (lshiftrt:DI
2975             (mult:DI (any_extend:DI
2976                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2977                      (any_extend:DI
2978                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2979             (const_int 32))))]
2980   "TARGET_POWERPC64"
2981   "mulhw<u> %0,%1,%2"
2982   [(set_attr "type" "mul")])
2984 (define_expand "<u>mul<mode><dmode>3"
2985   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2986         (mult:<DMODE> (any_extend:<DMODE>
2987                         (match_operand:GPR 1 "gpc_reg_operand"))
2988                       (any_extend:<DMODE>
2989                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2990   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2992   rtx l = gen_reg_rtx (<MODE>mode);
2993   rtx h = gen_reg_rtx (<MODE>mode);
2994   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2995   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2996   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2997   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2998   DONE;
3001 (define_insn "*maddld4"
3002   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3003         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3004                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3005                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3006   "TARGET_MADDLD"
3007   "maddld %0,%1,%2,%3"
3008   [(set_attr "type" "mul")])
3010 (define_insn "udiv<mode>3"
3011   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3012         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3013                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3014   ""
3015   "div<wd>u %0,%1,%2"
3016   [(set_attr "type" "div")
3017    (set_attr "size" "<bits>")])
3020 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3021 ;; modulus.  If it isn't a power of two, force operands into register and do
3022 ;; a normal divide.
3023 (define_expand "div<mode>3"
3024   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3025         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3026                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3027   ""
3029   if (CONST_INT_P (operands[2])
3030       && INTVAL (operands[2]) > 0
3031       && exact_log2 (INTVAL (operands[2])) >= 0)
3032     {
3033       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3034       DONE;
3035     }
3037   operands[2] = force_reg (<MODE>mode, operands[2]);
3040 (define_insn "*div<mode>3"
3041   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3042         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3043                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3044   ""
3045   "div<wd> %0,%1,%2"
3046   [(set_attr "type" "div")
3047    (set_attr "size" "<bits>")])
3049 (define_insn "div<mode>3_sra"
3050   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3051         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3052                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3053    (clobber (reg:GPR CA_REGNO))]
3054   ""
3055   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3056   [(set_attr "type" "two")
3057    (set_attr "length" "8")])
3059 (define_insn_and_split "*div<mode>3_sra_dot"
3060   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3061         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3062                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3063                     (const_int 0)))
3064    (clobber (match_scratch:GPR 0 "=r,r"))
3065    (clobber (reg:GPR CA_REGNO))]
3066   "<MODE>mode == Pmode"
3067   "@
3068    sra<wd>i %0,%1,%p2\;addze. %0,%0
3069    #"
3070   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3071   [(parallel [(set (match_dup 0)
3072                    (div:GPR (match_dup 1)
3073                             (match_dup 2)))
3074               (clobber (reg:GPR CA_REGNO))])
3075    (set (match_dup 3)
3076         (compare:CC (match_dup 0)
3077                     (const_int 0)))]
3078   ""
3079   [(set_attr "type" "two")
3080    (set_attr "length" "8,12")
3081    (set_attr "cell_micro" "not")])
3083 (define_insn_and_split "*div<mode>3_sra_dot2"
3084   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3085         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3086                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3087                     (const_int 0)))
3088    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3089         (div:GPR (match_dup 1)
3090                  (match_dup 2)))
3091    (clobber (reg:GPR CA_REGNO))]
3092   "<MODE>mode == Pmode"
3093   "@
3094    sra<wd>i %0,%1,%p2\;addze. %0,%0
3095    #"
3096   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3097   [(parallel [(set (match_dup 0)
3098                    (div:GPR (match_dup 1)
3099                             (match_dup 2)))
3100               (clobber (reg:GPR CA_REGNO))])
3101    (set (match_dup 3)
3102         (compare:CC (match_dup 0)
3103                     (const_int 0)))]
3104   ""
3105   [(set_attr "type" "two")
3106    (set_attr "length" "8,12")
3107    (set_attr "cell_micro" "not")])
3109 (define_expand "mod<mode>3"
3110   [(set (match_operand:GPR 0 "gpc_reg_operand")
3111         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3112                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3113   ""
3115   int i;
3116   rtx temp1;
3117   rtx temp2;
3119   if (GET_CODE (operands[2]) != CONST_INT
3120       || INTVAL (operands[2]) <= 0
3121       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3122     {
3123       if (!TARGET_MODULO)
3124         FAIL;
3126       operands[2] = force_reg (<MODE>mode, operands[2]);
3127     }
3128   else
3129     {
3130       temp1 = gen_reg_rtx (<MODE>mode);
3131       temp2 = gen_reg_rtx (<MODE>mode);
3133       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3134       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3135       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3136       DONE;
3137     }
3140 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3141 ;; mod, prefer putting the result of mod into a different register
3142 (define_insn "*mod<mode>3"
3143   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3144         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3145                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3146   "TARGET_MODULO"
3147   "mods<wd> %0,%1,%2"
3148   [(set_attr "type" "div")
3149    (set_attr "size" "<bits>")])
3152 (define_insn "umod<mode>3"
3153   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3154         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3155                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3156   "TARGET_MODULO"
3157   "modu<wd> %0,%1,%2"
3158   [(set_attr "type" "div")
3159    (set_attr "size" "<bits>")])
3161 ;; On machines with modulo support, do a combined div/mod the old fashioned
3162 ;; method, since the multiply/subtract is faster than doing the mod instruction
3163 ;; after a divide.
3165 (define_peephole2
3166   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3167         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3168                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3169    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3170         (mod:GPR (match_dup 1)
3171                  (match_dup 2)))]
3172   "TARGET_MODULO
3173    && ! reg_mentioned_p (operands[0], operands[1])
3174    && ! reg_mentioned_p (operands[0], operands[2])
3175    && ! reg_mentioned_p (operands[3], operands[1])
3176    && ! reg_mentioned_p (operands[3], operands[2])"
3177   [(set (match_dup 0)
3178         (div:GPR (match_dup 1)
3179                  (match_dup 2)))
3180    (set (match_dup 3)
3181         (mult:GPR (match_dup 0)
3182                   (match_dup 2)))
3183    (set (match_dup 3)
3184         (minus:GPR (match_dup 1)
3185                    (match_dup 3)))])
3187 (define_peephole2
3188   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3189         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3190                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3191    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3192         (umod:GPR (match_dup 1)
3193                   (match_dup 2)))]
3194   "TARGET_MODULO
3195    && ! reg_mentioned_p (operands[0], operands[1])
3196    && ! reg_mentioned_p (operands[0], operands[2])
3197    && ! reg_mentioned_p (operands[3], operands[1])
3198    && ! reg_mentioned_p (operands[3], operands[2])"
3199   [(set (match_dup 0)
3200         (udiv:GPR (match_dup 1)
3201                   (match_dup 2)))
3202    (set (match_dup 3)
3203         (mult:GPR (match_dup 0)
3204                   (match_dup 2)))
3205    (set (match_dup 3)
3206         (minus:GPR (match_dup 1)
3207                    (match_dup 3)))])
3210 ;; Logical instructions
3211 ;; The logical instructions are mostly combined by using match_operator,
3212 ;; but the plain AND insns are somewhat different because there is no
3213 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3214 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3216 (define_expand "and<mode>3"
3217   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3218         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3219                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3220   ""
3222   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3223     {
3224       rs6000_split_logical (operands, AND, false, false, false);
3225       DONE;
3226     }
3228   if (CONST_INT_P (operands[2]))
3229     {
3230       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3231         {
3232           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3233           DONE;
3234         }
3236       if (logical_const_operand (operands[2], <MODE>mode))
3237         {
3238           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3239           DONE;
3240         }
3242       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3243         {
3244           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3245           DONE;
3246         }
3248       operands[2] = force_reg (<MODE>mode, operands[2]);
3249     }
3253 (define_insn "and<mode>3_imm"
3254   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3255         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3256                  (match_operand:GPR 2 "logical_const_operand" "n")))
3257    (clobber (match_scratch:CC 3 "=x"))]
3258   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3259   "andi%e2. %0,%1,%u2"
3260   [(set_attr "type" "logical")
3261    (set_attr "dot" "yes")])
3263 (define_insn_and_split "*and<mode>3_imm_dot"
3264   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3265         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3266                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3267                     (const_int 0)))
3268    (clobber (match_scratch:GPR 0 "=r,r"))
3269    (clobber (match_scratch:CC 4 "=X,x"))]
3270   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3271    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3272   "@
3273    andi%e2. %0,%1,%u2
3274    #"
3275   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3276   [(parallel [(set (match_dup 0)
3277                    (and:GPR (match_dup 1)
3278                             (match_dup 2)))
3279               (clobber (match_dup 4))])
3280    (set (match_dup 3)
3281         (compare:CC (match_dup 0)
3282                     (const_int 0)))]
3283   ""
3284   [(set_attr "type" "logical")
3285    (set_attr "dot" "yes")
3286    (set_attr "length" "4,8")])
3288 (define_insn_and_split "*and<mode>3_imm_dot2"
3289   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3290         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3291                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3292                     (const_int 0)))
3293    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3294         (and:GPR (match_dup 1)
3295                  (match_dup 2)))
3296    (clobber (match_scratch:CC 4 "=X,x"))]
3297   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3298    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3299   "@
3300    andi%e2. %0,%1,%u2
3301    #"
3302   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3303   [(parallel [(set (match_dup 0)
3304                    (and:GPR (match_dup 1)
3305                             (match_dup 2)))
3306               (clobber (match_dup 4))])
3307    (set (match_dup 3)
3308         (compare:CC (match_dup 0)
3309                     (const_int 0)))]
3310   ""
3311   [(set_attr "type" "logical")
3312    (set_attr "dot" "yes")
3313    (set_attr "length" "4,8")])
3315 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3316   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3317         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3318                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3319                     (const_int 0)))
3320    (clobber (match_scratch:GPR 0 "=r,r"))]
3321   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3322    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3323   "@
3324    andi%e2. %0,%1,%u2
3325    #"
3326   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3327   [(set (match_dup 0)
3328         (and:GPR (match_dup 1)
3329                  (match_dup 2)))
3330    (set (match_dup 3)
3331         (compare:CC (match_dup 0)
3332                     (const_int 0)))]
3333   ""
3334   [(set_attr "type" "logical")
3335    (set_attr "dot" "yes")
3336    (set_attr "length" "4,8")])
3338 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3339   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3340         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3341                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3342                     (const_int 0)))
3343    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3344         (and:GPR (match_dup 1)
3345                  (match_dup 2)))]
3346   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3347    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3348   "@
3349    andi%e2. %0,%1,%u2
3350    #"
3351   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3352   [(set (match_dup 0)
3353         (and:GPR (match_dup 1)
3354                  (match_dup 2)))
3355    (set (match_dup 3)
3356         (compare:CC (match_dup 0)
3357                     (const_int 0)))]
3358   ""
3359   [(set_attr "type" "logical")
3360    (set_attr "dot" "yes")
3361    (set_attr "length" "4,8")])
3363 (define_insn "*and<mode>3_imm_dot_shifted"
3364   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3365         (compare:CC
3366           (and:GPR
3367             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3368                           (match_operand:SI 4 "const_int_operand" "n"))
3369             (match_operand:GPR 2 "const_int_operand" "n"))
3370           (const_int 0)))
3371    (clobber (match_scratch:GPR 0 "=r"))]
3372   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3373                                    << INTVAL (operands[4])),
3374                           DImode)
3375    && (<MODE>mode == Pmode
3376        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3378   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3379   return "andi%e2. %0,%1,%u2";
3381   [(set_attr "type" "logical")
3382    (set_attr "dot" "yes")])
3385 (define_insn "and<mode>3_mask"
3386   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3387         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3388                  (match_operand:GPR 2 "const_int_operand" "n")))]
3389   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3391   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3393   [(set_attr "type" "shift")])
3395 (define_insn_and_split "*and<mode>3_mask_dot"
3396   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3397         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3398                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3399                     (const_int 0)))
3400    (clobber (match_scratch:GPR 0 "=r,r"))]
3401   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3402    && !logical_const_operand (operands[2], <MODE>mode)
3403    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3405   if (which_alternative == 0)
3406     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3407   else
3408     return "#";
3410   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3411   [(set (match_dup 0)
3412         (and:GPR (match_dup 1)
3413                  (match_dup 2)))
3414    (set (match_dup 3)
3415         (compare:CC (match_dup 0)
3416                     (const_int 0)))]
3417   ""
3418   [(set_attr "type" "shift")
3419    (set_attr "dot" "yes")
3420    (set_attr "length" "4,8")])
3422 (define_insn_and_split "*and<mode>3_mask_dot2"
3423   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3424         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3425                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3426                     (const_int 0)))
3427    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3428         (and:GPR (match_dup 1)
3429                  (match_dup 2)))]
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")])
3452 (define_insn_and_split "*and<mode>3_2insn"
3453   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3454         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3455                  (match_operand:GPR 2 "const_int_operand" "n")))]
3456   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3457    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3458         || logical_const_operand (operands[2], <MODE>mode))"
3459   "#"
3460   "&& 1"
3461   [(pc)]
3463   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3464   DONE;
3466   [(set_attr "type" "shift")
3467    (set_attr "length" "8")])
3469 (define_insn_and_split "*and<mode>3_2insn_dot"
3470   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3471         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3472                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3473                     (const_int 0)))
3474    (clobber (match_scratch:GPR 0 "=r,r"))]
3475   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3476    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3477    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3478         || logical_const_operand (operands[2], <MODE>mode))"
3479   "#"
3480   "&& reload_completed"
3481   [(pc)]
3483   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3484   DONE;
3486   [(set_attr "type" "shift")
3487    (set_attr "dot" "yes")
3488    (set_attr "length" "8,12")])
3490 (define_insn_and_split "*and<mode>3_2insn_dot2"
3491   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3492         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3493                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3494                     (const_int 0)))
3495    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3496         (and:GPR (match_dup 1)
3497                  (match_dup 2)))]
3498   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3499    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3500    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3501         || logical_const_operand (operands[2], <MODE>mode))"
3502   "#"
3503   "&& reload_completed"
3504   [(pc)]
3506   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3507   DONE;
3509   [(set_attr "type" "shift")
3510    (set_attr "dot" "yes")
3511    (set_attr "length" "8,12")])
3514 (define_expand "<code><mode>3"
3515   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3516         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3517                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3518   ""
3520   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3521     {
3522       rs6000_split_logical (operands, <CODE>, false, false, false);
3523       DONE;
3524     }
3526   if (non_logical_cint_operand (operands[2], <MODE>mode))
3527     {
3528       rtx tmp = ((!can_create_pseudo_p ()
3529                   || rtx_equal_p (operands[0], operands[1]))
3530                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3532       HOST_WIDE_INT value = INTVAL (operands[2]);
3533       HOST_WIDE_INT lo = value & 0xffff;
3534       HOST_WIDE_INT hi = value - lo;
3536       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3537       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3538       DONE;
3539     }
3541   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3542     operands[2] = force_reg (<MODE>mode, operands[2]);
3545 (define_split
3546   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3547         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3548                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3549   ""
3550   [(set (match_dup 3)
3551         (iorxor:GPR (match_dup 1)
3552                     (match_dup 4)))
3553    (set (match_dup 0)
3554         (iorxor:GPR (match_dup 3)
3555                     (match_dup 5)))]
3557   operands[3] = ((!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   operands[4] = GEN_INT (hi);
3566   operands[5] = GEN_INT (lo);
3569 (define_insn "*bool<mode>3_imm"
3570   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3571         (match_operator:GPR 3 "boolean_or_operator"
3572          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3573           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3574   ""
3575   "%q3i%e2 %0,%1,%u2"
3576   [(set_attr "type" "logical")])
3578 (define_insn "*bool<mode>3"
3579   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3580         (match_operator:GPR 3 "boolean_operator"
3581          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3582           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3583   ""
3584   "%q3 %0,%1,%2"
3585   [(set_attr "type" "logical")])
3587 (define_insn_and_split "*bool<mode>3_dot"
3588   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3589         (compare:CC (match_operator:GPR 3 "boolean_operator"
3590          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3591           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3592          (const_int 0)))
3593    (clobber (match_scratch:GPR 0 "=r,r"))]
3594   "<MODE>mode == Pmode"
3595   "@
3596    %q3. %0,%1,%2
3597    #"
3598   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3599   [(set (match_dup 0)
3600         (match_dup 3))
3601    (set (match_dup 4)
3602         (compare:CC (match_dup 0)
3603                     (const_int 0)))]
3604   ""
3605   [(set_attr "type" "logical")
3606    (set_attr "dot" "yes")
3607    (set_attr "length" "4,8")])
3609 (define_insn_and_split "*bool<mode>3_dot2"
3610   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3611         (compare:CC (match_operator:GPR 3 "boolean_operator"
3612          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3613           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3614          (const_int 0)))
3615    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3616         (match_dup 3))]
3617   "<MODE>mode == Pmode"
3618   "@
3619    %q3. %0,%1,%2
3620    #"
3621   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3622   [(set (match_dup 0)
3623         (match_dup 3))
3624    (set (match_dup 4)
3625         (compare:CC (match_dup 0)
3626                     (const_int 0)))]
3627   ""
3628   [(set_attr "type" "logical")
3629    (set_attr "dot" "yes")
3630    (set_attr "length" "4,8")])
3633 (define_insn "*boolc<mode>3"
3634   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3635         (match_operator:GPR 3 "boolean_operator"
3636          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3637           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3638   ""
3639   "%q3 %0,%1,%2"
3640   [(set_attr "type" "logical")])
3642 (define_insn_and_split "*boolc<mode>3_dot"
3643   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3644         (compare:CC (match_operator:GPR 3 "boolean_operator"
3645          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3646           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3647          (const_int 0)))
3648    (clobber (match_scratch:GPR 0 "=r,r"))]
3649   "<MODE>mode == Pmode"
3650   "@
3651    %q3. %0,%1,%2
3652    #"
3653   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3654   [(set (match_dup 0)
3655         (match_dup 3))
3656    (set (match_dup 4)
3657         (compare:CC (match_dup 0)
3658                     (const_int 0)))]
3659   ""
3660   [(set_attr "type" "logical")
3661    (set_attr "dot" "yes")
3662    (set_attr "length" "4,8")])
3664 (define_insn_and_split "*boolc<mode>3_dot2"
3665   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3666         (compare:CC (match_operator:GPR 3 "boolean_operator"
3667          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3668           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3669          (const_int 0)))
3670    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3671         (match_dup 3))]
3672   "<MODE>mode == Pmode"
3673   "@
3674    %q3. %0,%1,%2
3675    #"
3676   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3677   [(set (match_dup 0)
3678         (match_dup 3))
3679    (set (match_dup 4)
3680         (compare:CC (match_dup 0)
3681                     (const_int 0)))]
3682   ""
3683   [(set_attr "type" "logical")
3684    (set_attr "dot" "yes")
3685    (set_attr "length" "4,8")])
3688 (define_insn "*boolcc<mode>3"
3689   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3690         (match_operator:GPR 3 "boolean_operator"
3691          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3692           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3693   ""
3694   "%q3 %0,%1,%2"
3695   [(set_attr "type" "logical")])
3697 (define_insn_and_split "*boolcc<mode>3_dot"
3698   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3699         (compare:CC (match_operator:GPR 3 "boolean_operator"
3700          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3701           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3702          (const_int 0)))
3703    (clobber (match_scratch:GPR 0 "=r,r"))]
3704   "<MODE>mode == Pmode"
3705   "@
3706    %q3. %0,%1,%2
3707    #"
3708   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3709   [(set (match_dup 0)
3710         (match_dup 3))
3711    (set (match_dup 4)
3712         (compare:CC (match_dup 0)
3713                     (const_int 0)))]
3714   ""
3715   [(set_attr "type" "logical")
3716    (set_attr "dot" "yes")
3717    (set_attr "length" "4,8")])
3719 (define_insn_and_split "*boolcc<mode>3_dot2"
3720   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3721         (compare:CC (match_operator:GPR 3 "boolean_operator"
3722          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3723           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3724          (const_int 0)))
3725    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3726         (match_dup 3))]
3727   "<MODE>mode == Pmode"
3728   "@
3729    %q3. %0,%1,%2
3730    #"
3731   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3732   [(set (match_dup 0)
3733         (match_dup 3))
3734    (set (match_dup 4)
3735         (compare:CC (match_dup 0)
3736                     (const_int 0)))]
3737   ""
3738   [(set_attr "type" "logical")
3739    (set_attr "dot" "yes")
3740    (set_attr "length" "4,8")])
3743 ;; TODO: Should have dots of this as well.
3744 (define_insn "*eqv<mode>3"
3745   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3746         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3747                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3748   ""
3749   "eqv %0,%1,%2"
3750   [(set_attr "type" "logical")])
3752 ;; Rotate-and-mask and insert.
3754 (define_insn "*rotl<mode>3_mask"
3755   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3756         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3757                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3758                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3759                  (match_operand:GPR 3 "const_int_operand" "n")))]
3760   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3762   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3764   [(set_attr "type" "shift")
3765    (set_attr "maybe_var_shift" "yes")])
3767 (define_insn_and_split "*rotl<mode>3_mask_dot"
3768   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3769         (compare:CC
3770           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3771                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3772                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3773                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3774           (const_int 0)))
3775    (clobber (match_scratch:GPR 0 "=r,r"))]
3776   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3777    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3779   if (which_alternative == 0)
3780     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3781   else
3782     return "#";
3784   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3785   [(set (match_dup 0)
3786         (and:GPR (match_dup 4)
3787                  (match_dup 3)))
3788    (set (match_dup 5)
3789         (compare:CC (match_dup 0)
3790                     (const_int 0)))]
3791   ""
3792   [(set_attr "type" "shift")
3793    (set_attr "maybe_var_shift" "yes")
3794    (set_attr "dot" "yes")
3795    (set_attr "length" "4,8")])
3797 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3798   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3799         (compare:CC
3800           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3801                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3802                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3803                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3804           (const_int 0)))
3805    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3806         (and:GPR (match_dup 4)
3807                  (match_dup 3)))]
3808   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3809    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3811   if (which_alternative == 0)
3812     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3813   else
3814     return "#";
3816   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3817   [(set (match_dup 0)
3818         (and:GPR (match_dup 4)
3819                  (match_dup 3)))
3820    (set (match_dup 5)
3821         (compare:CC (match_dup 0)
3822                     (const_int 0)))]
3823   ""
3824   [(set_attr "type" "shift")
3825    (set_attr "maybe_var_shift" "yes")
3826    (set_attr "dot" "yes")
3827    (set_attr "length" "4,8")])
3829 ; Special case for less-than-0.  We can do it with just one machine
3830 ; instruction, but the generic optimizers do not realise it is cheap.
3831 (define_insn "*lt0_disi"
3832   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3833         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3834                (const_int 0)))]
3835   "TARGET_POWERPC64"
3836   "rlwinm %0,%1,1,31,31"
3837   [(set_attr "type" "shift")])
3841 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3842 ; both are an AND so are the same precedence).
3843 (define_insn "*rotl<mode>3_insert"
3844   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3845         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3846                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3847                             (match_operand:SI 2 "const_int_operand" "n")])
3848                           (match_operand:GPR 3 "const_int_operand" "n"))
3849                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3850                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3851   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3852    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3854   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3856   [(set_attr "type" "insert")])
3857 ; FIXME: this needs an attr "size", so that the scheduler can see the
3858 ; difference between rlwimi and rldimi.  We also might want dot forms,
3859 ; but not for rlwimi on POWER4 and similar processors.
3861 (define_insn "*rotl<mode>3_insert_2"
3862   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3863         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3864                           (match_operand:GPR 6 "const_int_operand" "n"))
3865                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3866                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3867                             (match_operand:SI 2 "const_int_operand" "n")])
3868                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3869   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3870    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3872   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3874   [(set_attr "type" "insert")])
3876 ; There are also some forms without one of the ANDs.
3877 (define_insn "*rotl<mode>3_insert_3"
3878   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3879         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3880                           (match_operand:GPR 4 "const_int_operand" "n"))
3881                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3882                              (match_operand:SI 2 "const_int_operand" "n"))))]
3883   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3885   if (<MODE>mode == SImode)
3886     return "rlwimi %0,%1,%h2,0,31-%h2";
3887   else
3888     return "rldimi %0,%1,%H2,0";
3890   [(set_attr "type" "insert")])
3892 (define_insn "*rotl<mode>3_insert_4"
3893   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3894         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3895                           (match_operand:GPR 4 "const_int_operand" "n"))
3896                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3897                                (match_operand:SI 2 "const_int_operand" "n"))))]
3898   "<MODE>mode == SImode &&
3899    GET_MODE_PRECISION (<MODE>mode)
3900    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3902   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3903                          - INTVAL (operands[2]));
3904   if (<MODE>mode == SImode)
3905     return "rlwimi %0,%1,%h2,32-%h2,31";
3906   else
3907     return "rldimi %0,%1,%H2,64-%H2";
3909   [(set_attr "type" "insert")])
3911 (define_insn "*rotlsi3_insert_5"
3912   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3913         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3914                         (match_operand:SI 2 "const_int_operand" "n,n"))
3915                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3916                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3917   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3918    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3919    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3920   "@
3921    rlwimi %0,%3,0,%4
3922    rlwimi %0,%1,0,%2"
3923   [(set_attr "type" "insert")])
3925 (define_insn "*rotldi3_insert_6"
3926   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3927         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3928                         (match_operand:DI 2 "const_int_operand" "n"))
3929                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3930                         (match_operand:DI 4 "const_int_operand" "n"))))]
3931   "exact_log2 (-UINTVAL (operands[2])) > 0
3932    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3934   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3935   return "rldimi %0,%3,0,%5";
3937   [(set_attr "type" "insert")
3938    (set_attr "size" "64")])
3940 (define_insn "*rotldi3_insert_7"
3941   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3942         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3943                         (match_operand:DI 4 "const_int_operand" "n"))
3944                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3945                         (match_operand:DI 2 "const_int_operand" "n"))))]
3946   "exact_log2 (-UINTVAL (operands[2])) > 0
3947    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3949   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3950   return "rldimi %0,%3,0,%5";
3952   [(set_attr "type" "insert")
3953    (set_attr "size" "64")])
3956 ; This handles the important case of multiple-precision shifts.  There is
3957 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3958 (define_split
3959   [(set (match_operand:GPR 0 "gpc_reg_operand")
3960         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3961                              (match_operand:SI 3 "const_int_operand"))
3962                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3963                                (match_operand:SI 4 "const_int_operand"))))]
3964   "can_create_pseudo_p ()
3965    && INTVAL (operands[3]) + INTVAL (operands[4])
3966       >= GET_MODE_PRECISION (<MODE>mode)"
3967   [(set (match_dup 5)
3968         (lshiftrt:GPR (match_dup 2)
3969                       (match_dup 4)))
3970    (set (match_dup 0)
3971         (ior:GPR (and:GPR (match_dup 5)
3972                           (match_dup 6))
3973                  (ashift:GPR (match_dup 1)
3974                              (match_dup 3))))]
3976   unsigned HOST_WIDE_INT mask = 1;
3977   mask = (mask << INTVAL (operands[3])) - 1;
3978   operands[5] = gen_reg_rtx (<MODE>mode);
3979   operands[6] = GEN_INT (mask);
3982 (define_split
3983   [(set (match_operand:GPR 0 "gpc_reg_operand")
3984         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3985                                (match_operand:SI 4 "const_int_operand"))
3986                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3987                              (match_operand:SI 3 "const_int_operand"))))]
3988   "can_create_pseudo_p ()
3989    && INTVAL (operands[3]) + INTVAL (operands[4])
3990       >= GET_MODE_PRECISION (<MODE>mode)"
3991   [(set (match_dup 5)
3992         (lshiftrt:GPR (match_dup 2)
3993                       (match_dup 4)))
3994    (set (match_dup 0)
3995         (ior:GPR (and:GPR (match_dup 5)
3996                           (match_dup 6))
3997                  (ashift:GPR (match_dup 1)
3998                              (match_dup 3))))]
4000   unsigned HOST_WIDE_INT mask = 1;
4001   mask = (mask << INTVAL (operands[3])) - 1;
4002   operands[5] = gen_reg_rtx (<MODE>mode);
4003   operands[6] = GEN_INT (mask);
4007 ; Another important case is setting some bits to 1; we can do that with
4008 ; an insert instruction, in many cases.
4009 (define_insn_and_split "*ior<mode>_mask"
4010   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4011         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4012                  (match_operand:GPR 2 "const_int_operand" "n")))
4013    (clobber (match_scratch:GPR 3 "=r"))]
4014   "!logical_const_operand (operands[2], <MODE>mode)
4015    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4016   "#"
4017   "&& 1"
4018   [(set (match_dup 3)
4019         (const_int -1))
4020    (set (match_dup 0)
4021         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4022                                       (match_dup 4))
4023                           (match_dup 2))
4024                  (and:GPR (match_dup 1)
4025                           (match_dup 5))))]
4027   int nb, ne;
4028   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4029   if (GET_CODE (operands[3]) == SCRATCH)
4030     operands[3] = gen_reg_rtx (<MODE>mode);
4031   operands[4] = GEN_INT (ne);
4032   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4034   [(set_attr "type" "two")
4035    (set_attr "length" "8")])
4038 ;; Now the simple shifts.
4040 (define_insn "rotl<mode>3"
4041   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4042         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4043                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4044   ""
4045   "rotl<wd>%I2 %0,%1,%<hH>2"
4046   [(set_attr "type" "shift")
4047    (set_attr "maybe_var_shift" "yes")])
4049 (define_insn "*rotlsi3_64"
4050   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4051         (zero_extend:DI
4052             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4053                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4054   "TARGET_POWERPC64"
4055   "rotlw%I2 %0,%1,%h2"
4056   [(set_attr "type" "shift")
4057    (set_attr "maybe_var_shift" "yes")])
4059 (define_insn_and_split "*rotl<mode>3_dot"
4060   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4061         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4062                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4063                     (const_int 0)))
4064    (clobber (match_scratch:GPR 0 "=r,r"))]
4065   "<MODE>mode == Pmode"
4066   "@
4067    rotl<wd>%I2. %0,%1,%<hH>2
4068    #"
4069   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4070   [(set (match_dup 0)
4071         (rotate:GPR (match_dup 1)
4072                     (match_dup 2)))
4073    (set (match_dup 3)
4074         (compare:CC (match_dup 0)
4075                     (const_int 0)))]
4076   ""
4077   [(set_attr "type" "shift")
4078    (set_attr "maybe_var_shift" "yes")
4079    (set_attr "dot" "yes")
4080    (set_attr "length" "4,8")])
4082 (define_insn_and_split "*rotl<mode>3_dot2"
4083   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4084         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4085                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4086                     (const_int 0)))
4087    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4088         (rotate:GPR (match_dup 1)
4089                     (match_dup 2)))]
4090   "<MODE>mode == Pmode"
4091   "@
4092    rotl<wd>%I2. %0,%1,%<hH>2
4093    #"
4094   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4095   [(set (match_dup 0)
4096         (rotate:GPR (match_dup 1)
4097                     (match_dup 2)))
4098    (set (match_dup 3)
4099         (compare:CC (match_dup 0)
4100                     (const_int 0)))]
4101   ""
4102   [(set_attr "type" "shift")
4103    (set_attr "maybe_var_shift" "yes")
4104    (set_attr "dot" "yes")
4105    (set_attr "length" "4,8")])
4108 (define_insn "ashl<mode>3"
4109   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4110         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4111                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4112   ""
4113   "sl<wd>%I2 %0,%1,%<hH>2"
4114   [(set_attr "type" "shift")
4115    (set_attr "maybe_var_shift" "yes")])
4117 (define_insn "*ashlsi3_64"
4118   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4119         (zero_extend:DI
4120             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4121                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4122   "TARGET_POWERPC64"
4123   "slw%I2 %0,%1,%h2"
4124   [(set_attr "type" "shift")
4125    (set_attr "maybe_var_shift" "yes")])
4127 (define_insn_and_split "*ashl<mode>3_dot"
4128   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4129         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4130                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4131                     (const_int 0)))
4132    (clobber (match_scratch:GPR 0 "=r,r"))]
4133   "<MODE>mode == Pmode"
4134   "@
4135    sl<wd>%I2. %0,%1,%<hH>2
4136    #"
4137   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4138   [(set (match_dup 0)
4139         (ashift:GPR (match_dup 1)
4140                     (match_dup 2)))
4141    (set (match_dup 3)
4142         (compare:CC (match_dup 0)
4143                     (const_int 0)))]
4144   ""
4145   [(set_attr "type" "shift")
4146    (set_attr "maybe_var_shift" "yes")
4147    (set_attr "dot" "yes")
4148    (set_attr "length" "4,8")])
4150 (define_insn_and_split "*ashl<mode>3_dot2"
4151   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4152         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4153                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4154                     (const_int 0)))
4155    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4156         (ashift:GPR (match_dup 1)
4157                     (match_dup 2)))]
4158   "<MODE>mode == Pmode"
4159   "@
4160    sl<wd>%I2. %0,%1,%<hH>2
4161    #"
4162   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4163   [(set (match_dup 0)
4164         (ashift:GPR (match_dup 1)
4165                     (match_dup 2)))
4166    (set (match_dup 3)
4167         (compare:CC (match_dup 0)
4168                     (const_int 0)))]
4169   ""
4170   [(set_attr "type" "shift")
4171    (set_attr "maybe_var_shift" "yes")
4172    (set_attr "dot" "yes")
4173    (set_attr "length" "4,8")])
4175 ;; Pretend we have a memory form of extswsli until register allocation is done
4176 ;; so that we use LWZ to load the value from memory, instead of LWA.
4177 (define_insn_and_split "ashdi3_extswsli"
4178   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4179         (ashift:DI
4180          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4181          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4182   "TARGET_EXTSWSLI"
4183   "@
4184    extswsli %0,%1,%2
4185    #"
4186   "&& reload_completed && MEM_P (operands[1])"
4187   [(set (match_dup 3)
4188         (match_dup 1))
4189    (set (match_dup 0)
4190         (ashift:DI (sign_extend:DI (match_dup 3))
4191                    (match_dup 2)))]
4193   operands[3] = gen_lowpart (SImode, operands[0]);
4195   [(set_attr "type" "shift")
4196    (set_attr "maybe_var_shift" "no")])
4199 (define_insn_and_split "ashdi3_extswsli_dot"
4200   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4201         (compare:CC
4202          (ashift:DI
4203           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4204           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4205          (const_int 0)))
4206    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4207   "TARGET_EXTSWSLI"
4208   "@
4209    extswsli. %0,%1,%2
4210    #
4211    #
4212    #"
4213   "&& reload_completed
4214    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4215        || memory_operand (operands[1], SImode))"
4216   [(pc)]
4218   rtx dest = operands[0];
4219   rtx src = operands[1];
4220   rtx shift = operands[2];
4221   rtx cr = operands[3];
4222   rtx src2;
4224   if (!MEM_P (src))
4225     src2 = src;
4226   else
4227     {
4228       src2 = gen_lowpart (SImode, dest);
4229       emit_move_insn (src2, src);
4230     }
4232   if (REGNO (cr) == CR0_REGNO)
4233     {
4234       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4235       DONE;
4236     }
4238   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4239   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4240   DONE;
4242   [(set_attr "type" "shift")
4243    (set_attr "maybe_var_shift" "no")
4244    (set_attr "dot" "yes")
4245    (set_attr "length" "4,8,8,12")])
4247 (define_insn_and_split "ashdi3_extswsli_dot2"
4248   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4249         (compare:CC
4250          (ashift:DI
4251           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4252           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4253          (const_int 0)))
4254    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4255         (ashift:DI (sign_extend:DI (match_dup 1))
4256                    (match_dup 2)))]
4257   "TARGET_EXTSWSLI"
4258   "@
4259    extswsli. %0,%1,%2
4260    #
4261    #
4262    #"
4263   "&& reload_completed
4264    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4265        || memory_operand (operands[1], SImode))"
4266   [(pc)]
4268   rtx dest = operands[0];
4269   rtx src = operands[1];
4270   rtx shift = operands[2];
4271   rtx cr = operands[3];
4272   rtx src2;
4274   if (!MEM_P (src))
4275     src2 = src;
4276   else
4277     {
4278       src2 = gen_lowpart (SImode, dest);
4279       emit_move_insn (src2, src);
4280     }
4282   if (REGNO (cr) == CR0_REGNO)
4283     {
4284       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4285       DONE;
4286     }
4288   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4289   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4290   DONE;
4292   [(set_attr "type" "shift")
4293    (set_attr "maybe_var_shift" "no")
4294    (set_attr "dot" "yes")
4295    (set_attr "length" "4,8,8,12")])
4297 (define_insn "lshr<mode>3"
4298   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4299         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4300                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4301   ""
4302   "sr<wd>%I2 %0,%1,%<hH>2"
4303   [(set_attr "type" "shift")
4304    (set_attr "maybe_var_shift" "yes")])
4306 (define_insn "*lshrsi3_64"
4307   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4308         (zero_extend:DI
4309             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4310                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4311   "TARGET_POWERPC64"
4312   "srw%I2 %0,%1,%h2"
4313   [(set_attr "type" "shift")
4314    (set_attr "maybe_var_shift" "yes")])
4316 (define_insn_and_split "*lshr<mode>3_dot"
4317   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4318         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4319                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4320                     (const_int 0)))
4321    (clobber (match_scratch:GPR 0 "=r,r"))]
4322   "<MODE>mode == Pmode"
4323   "@
4324    sr<wd>%I2. %0,%1,%<hH>2
4325    #"
4326   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4327   [(set (match_dup 0)
4328         (lshiftrt:GPR (match_dup 1)
4329                       (match_dup 2)))
4330    (set (match_dup 3)
4331         (compare:CC (match_dup 0)
4332                     (const_int 0)))]
4333   ""
4334   [(set_attr "type" "shift")
4335    (set_attr "maybe_var_shift" "yes")
4336    (set_attr "dot" "yes")
4337    (set_attr "length" "4,8")])
4339 (define_insn_and_split "*lshr<mode>3_dot2"
4340   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4341         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4342                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4343                     (const_int 0)))
4344    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4345         (lshiftrt:GPR (match_dup 1)
4346                       (match_dup 2)))]
4347   "<MODE>mode == Pmode"
4348   "@
4349    sr<wd>%I2. %0,%1,%<hH>2
4350    #"
4351   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4352   [(set (match_dup 0)
4353         (lshiftrt:GPR (match_dup 1)
4354                       (match_dup 2)))
4355    (set (match_dup 3)
4356         (compare:CC (match_dup 0)
4357                     (const_int 0)))]
4358   ""
4359   [(set_attr "type" "shift")
4360    (set_attr "maybe_var_shift" "yes")
4361    (set_attr "dot" "yes")
4362    (set_attr "length" "4,8")])
4365 (define_insn "ashr<mode>3"
4366   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4367         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4368                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4369    (clobber (reg:GPR CA_REGNO))]
4370   ""
4371   "sra<wd>%I2 %0,%1,%<hH>2"
4372   [(set_attr "type" "shift")
4373    (set_attr "maybe_var_shift" "yes")])
4375 (define_insn "*ashrsi3_64"
4376   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4377         (sign_extend:DI
4378             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4379                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4380    (clobber (reg:SI CA_REGNO))]
4381   "TARGET_POWERPC64"
4382   "sraw%I2 %0,%1,%h2"
4383   [(set_attr "type" "shift")
4384    (set_attr "maybe_var_shift" "yes")])
4386 (define_insn_and_split "*ashr<mode>3_dot"
4387   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4388         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4389                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4390                     (const_int 0)))
4391    (clobber (match_scratch:GPR 0 "=r,r"))
4392    (clobber (reg:GPR CA_REGNO))]
4393   "<MODE>mode == Pmode"
4394   "@
4395    sra<wd>%I2. %0,%1,%<hH>2
4396    #"
4397   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4398   [(parallel [(set (match_dup 0)
4399                    (ashiftrt:GPR (match_dup 1)
4400                                  (match_dup 2)))
4401               (clobber (reg:GPR CA_REGNO))])
4402    (set (match_dup 3)
4403         (compare:CC (match_dup 0)
4404                     (const_int 0)))]
4405   ""
4406   [(set_attr "type" "shift")
4407    (set_attr "maybe_var_shift" "yes")
4408    (set_attr "dot" "yes")
4409    (set_attr "length" "4,8")])
4411 (define_insn_and_split "*ashr<mode>3_dot2"
4412   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4413         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4414                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4415                     (const_int 0)))
4416    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4417         (ashiftrt:GPR (match_dup 1)
4418                       (match_dup 2)))
4419    (clobber (reg:GPR CA_REGNO))]
4420   "<MODE>mode == Pmode"
4421   "@
4422    sra<wd>%I2. %0,%1,%<hH>2
4423    #"
4424   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4425   [(parallel [(set (match_dup 0)
4426                    (ashiftrt:GPR (match_dup 1)
4427                                  (match_dup 2)))
4428               (clobber (reg:GPR CA_REGNO))])
4429    (set (match_dup 3)
4430         (compare:CC (match_dup 0)
4431                     (const_int 0)))]
4432   ""
4433   [(set_attr "type" "shift")
4434    (set_attr "maybe_var_shift" "yes")
4435    (set_attr "dot" "yes")
4436    (set_attr "length" "4,8")])
4438 ;; Builtins to replace a division to generate FRE reciprocal estimate
4439 ;; instructions and the necessary fixup instructions
4440 (define_expand "recip<mode>3"
4441   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4442    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4443    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4444   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4446    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4447    DONE;
4450 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4451 ;; hardware division.  This is only done before register allocation and with
4452 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4453 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4454 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4455 (define_split
4456   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4457         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4458                     (match_operand 2 "gpc_reg_operand" "")))]
4459   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4460    && can_create_pseudo_p () && flag_finite_math_only
4461    && !flag_trapping_math && flag_reciprocal_math"
4462   [(const_int 0)]
4464   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4465   DONE;
4468 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4469 ;; appropriate fixup.
4470 (define_expand "rsqrt<mode>2"
4471   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4472    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4473   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4475   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4476   DONE;
4479 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4480 ;; modes here, and also add in conditional vsx/power8-vector support to access
4481 ;; values in the traditional Altivec registers if the appropriate
4482 ;; -mupper-regs-{df,sf} option is enabled.
4484 (define_expand "abs<mode>2"
4485   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4486         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4487   "TARGET_<MODE>_INSN"
4488   "")
4490 (define_insn "*abs<mode>2_fpr"
4491   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4492         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4493   "TARGET_<MODE>_FPR"
4494   "@
4495    fabs %0,%1
4496    xsabsdp %x0,%x1"
4497   [(set_attr "type" "fpsimple")
4498    (set_attr "fp_type" "fp_addsub_<Fs>")])
4500 (define_insn "*nabs<mode>2_fpr"
4501   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4502         (neg:SFDF
4503          (abs:SFDF
4504           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4505   "TARGET_<MODE>_FPR"
4506   "@
4507    fnabs %0,%1
4508    xsnabsdp %x0,%x1"
4509   [(set_attr "type" "fpsimple")
4510    (set_attr "fp_type" "fp_addsub_<Fs>")])
4512 (define_expand "neg<mode>2"
4513   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4514         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4515   "TARGET_<MODE>_INSN"
4516   "")
4518 (define_insn "*neg<mode>2_fpr"
4519   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4520         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4521   "TARGET_<MODE>_FPR"
4522   "@
4523    fneg %0,%1
4524    xsnegdp %x0,%x1"
4525   [(set_attr "type" "fpsimple")
4526    (set_attr "fp_type" "fp_addsub_<Fs>")])
4528 (define_expand "add<mode>3"
4529   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4530         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4531                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4532   "TARGET_<MODE>_INSN"
4533   "")
4535 (define_insn "*add<mode>3_fpr"
4536   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4537         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4538                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4539   "TARGET_<MODE>_FPR"
4540   "@
4541    fadd<Ftrad> %0,%1,%2
4542    xsadd<Fvsx> %x0,%x1,%x2"
4543   [(set_attr "type" "fp")
4544    (set_attr "fp_type" "fp_addsub_<Fs>")])
4546 (define_expand "sub<mode>3"
4547   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4548         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4549                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4550   "TARGET_<MODE>_INSN"
4551   "")
4553 (define_insn "*sub<mode>3_fpr"
4554   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4555         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4556                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4557   "TARGET_<MODE>_FPR"
4558   "@
4559    fsub<Ftrad> %0,%1,%2
4560    xssub<Fvsx> %x0,%x1,%x2"
4561   [(set_attr "type" "fp")
4562    (set_attr "fp_type" "fp_addsub_<Fs>")])
4564 (define_expand "mul<mode>3"
4565   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4566         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4567                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4568   "TARGET_<MODE>_INSN"
4569   "")
4571 (define_insn "*mul<mode>3_fpr"
4572   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4573         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4574                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4575   "TARGET_<MODE>_FPR"
4576   "@
4577    fmul<Ftrad> %0,%1,%2
4578    xsmul<Fvsx> %x0,%x1,%x2"
4579   [(set_attr "type" "dmul")
4580    (set_attr "fp_type" "fp_mul_<Fs>")])
4582 (define_expand "div<mode>3"
4583   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4584         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4585                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4586   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4588   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4589       && can_create_pseudo_p () && flag_finite_math_only
4590       && !flag_trapping_math && flag_reciprocal_math)
4591     {
4592       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4593       DONE;
4594     }
4597 (define_insn "*div<mode>3_fpr"
4598   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4599         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4600                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4601   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4602   "@
4603    fdiv<Ftrad> %0,%1,%2
4604    xsdiv<Fvsx> %x0,%x1,%x2"
4605   [(set_attr "type" "<Fs>div")
4606    (set_attr "fp_type" "fp_div_<Fs>")])
4608 (define_insn "*sqrt<mode>2_internal"
4609   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4610         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4611   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4612    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4613   "@
4614    fsqrt<Ftrad> %0,%1
4615    xssqrt<Fvsx> %x0,%x1"
4616   [(set_attr "type" "<Fs>sqrt")
4617    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4619 (define_expand "sqrt<mode>2"
4620   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4621         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4622   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4623    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4625   if (<MODE>mode == SFmode
4626       && TARGET_RECIP_PRECISION
4627       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4628       && !optimize_function_for_size_p (cfun)
4629       && flag_finite_math_only && !flag_trapping_math
4630       && flag_unsafe_math_optimizations)
4631     {
4632       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4633       DONE;
4634     }
4637 ;; Floating point reciprocal approximation
4638 (define_insn "fre<Fs>"
4639   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4640         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4641                      UNSPEC_FRES))]
4642   "TARGET_<FFRE>"
4643   "@
4644    fre<Ftrad> %0,%1
4645    xsre<Fvsx> %x0,%x1"
4646   [(set_attr "type" "fp")])
4648 (define_insn "*rsqrt<mode>2"
4649   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4650         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4651                      UNSPEC_RSQRT))]
4652   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4653   "@
4654    frsqrte<Ftrad> %0,%1
4655    xsrsqrte<Fvsx> %x0,%x1"
4656   [(set_attr "type" "fp")])
4658 ;; Floating point comparisons
4659 (define_insn "*cmp<mode>_fpr"
4660   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4661         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4662                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4663   "TARGET_<MODE>_FPR"
4664   "@
4665    fcmpu %0,%1,%2
4666    xscmpudp %0,%x1,%x2"
4667   [(set_attr "type" "fpcompare")])
4669 ;; Floating point conversions
4670 (define_expand "extendsfdf2"
4671   [(set (match_operand:DF 0 "gpc_reg_operand")
4672         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4673   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4675   if (HONOR_SNANS (SFmode))
4676     operands[1] = force_reg (SFmode, operands[1]);
4679 (define_insn_and_split "*extendsfdf2_fpr"
4680   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4681         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4682   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4683   "@
4684    #
4685    fmr %0,%1
4686    lfs%U1%X1 %0,%1
4687    #
4688    xscpsgndp %x0,%x1,%x1
4689    lxsspx %x0,%y1
4690    lxssp %0,%1"
4691   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4692   [(const_int 0)]
4694   emit_note (NOTE_INSN_DELETED);
4695   DONE;
4697   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4699 (define_insn "*extendsfdf2_snan"
4700   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4701         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4702   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4703   "@
4704    frsp %0,%1
4705    xsrsp %x0,%x1"
4706   [(set_attr "type" "fp")])
4708 (define_expand "truncdfsf2"
4709   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4710         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4711   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4712   "")
4714 (define_insn "*truncdfsf2_fpr"
4715   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4716         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4717   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4718   "@
4719    frsp %0,%1
4720    xsrsp %x0,%x1"
4721   [(set_attr "type" "fp")])
4723 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4724 ;; builtins.c and optabs.c that are not correct for IBM long double
4725 ;; when little-endian.
4726 (define_expand "signbit<mode>2"
4727   [(set (match_dup 2)
4728         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4729    (set (match_dup 3)
4730         (subreg:DI (match_dup 2) 0))
4731    (set (match_dup 4)
4732         (match_dup 5))
4733    (set (match_operand:SI 0 "gpc_reg_operand" "")
4734         (match_dup 6))]
4735   "TARGET_HARD_FLOAT
4736    && (!FLOAT128_IEEE_P (<MODE>mode)
4737        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4739   if (FLOAT128_IEEE_P (<MODE>mode))
4740     {
4741       if (<MODE>mode == KFmode)
4742         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4743       else if (<MODE>mode == TFmode)
4744         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4745       else
4746         gcc_unreachable ();
4747       DONE;
4748     }
4749   operands[2] = gen_reg_rtx (DFmode);
4750   operands[3] = gen_reg_rtx (DImode);
4751   if (TARGET_POWERPC64)
4752     {
4753       operands[4] = gen_reg_rtx (DImode);
4754       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4755       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4756                                     WORDS_BIG_ENDIAN ? 4 : 0);
4757     }
4758   else
4759     {
4760       operands[4] = gen_reg_rtx (SImode);
4761       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4762                                     WORDS_BIG_ENDIAN ? 0 : 4);
4763       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4764     }
4767 (define_expand "copysign<mode>3"
4768   [(set (match_dup 3)
4769         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4770    (set (match_dup 4)
4771         (neg:SFDF (abs:SFDF (match_dup 1))))
4772    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4773         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4774                                (match_dup 5))
4775                          (match_dup 3)
4776                          (match_dup 4)))]
4777   "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4778    && ((TARGET_PPC_GFXOPT
4779         && !HONOR_NANS (<MODE>mode)
4780         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4781        || TARGET_CMPB
4782        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4784   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4785     {
4786       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4787                                              operands[2]));
4788       DONE;
4789     }
4791    operands[3] = gen_reg_rtx (<MODE>mode);
4792    operands[4] = gen_reg_rtx (<MODE>mode);
4793    operands[5] = CONST0_RTX (<MODE>mode);
4794   })
4796 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4797 ;; and load.
4798 (define_insn_and_split "signbit<mode>2_dm"
4799   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4800         (unspec:SI
4801          [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4802          UNSPEC_SIGNBIT))]
4803   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4804   "#"
4805   "&& reload_completed"
4806   [(const_int 0)]
4808   rs6000_split_signbit (operands[0], operands[1]);
4809   DONE;
4811  [(set_attr "length" "8,8,4")
4812   (set_attr "type" "mftgpr,load,integer")])
4814 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4815   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4816         (any_extend:DI
4817          (unspec:SI
4818           [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4819           UNSPEC_SIGNBIT)))]
4820   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4821   "#"
4822   "&& reload_completed"
4823   [(const_int 0)]
4825   rs6000_split_signbit (operands[0], operands[1]);
4826   DONE;
4828  [(set_attr "length" "8,8,4")
4829   (set_attr "type" "mftgpr,load,integer")])
4831 ;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
4832 ;; floating point types, which makes normal SUBREG's problematical.  Instead
4833 ;; use a special pattern to avoid using a normal movdi.
4834 (define_insn "signbit<mode>2_dm2"
4835   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4836         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4837                     (const_int 0)]
4838                    UNSPEC_SIGNBIT))]
4839   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4840   "mfvsrd %0,%x1"
4841  [(set_attr "type" "mftgpr")])
4844 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4845 ;; compiler from optimizing -0.0
4846 (define_insn "copysign<mode>3_fcpsgn"
4847   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4848         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4849                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4850                      UNSPEC_COPYSIGN))]
4851   "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4852   "@
4853    fcpsgn %0,%2,%1
4854    xscpsgndp %x0,%x2,%x1"
4855   [(set_attr "type" "fpsimple")])
4857 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4858 ;; fsel instruction and some auxiliary computations.  Then we just have a
4859 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4860 ;; combine.
4861 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4862 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4863 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4864 ;; define_splits to make them if made by combine.  On VSX machines we have the
4865 ;; min/max instructions.
4867 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4868 ;; to allow either DF/SF to use only traditional registers.
4870 (define_expand "s<minmax><mode>3"
4871   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4872         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4873                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4874   "TARGET_MINMAX_<MODE>"
4876   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4877   DONE;
4880 (define_insn "*s<minmax><mode>3_vsx"
4881   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4882         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4883                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4884   "TARGET_VSX && TARGET_<MODE>_FPR"
4886   return (TARGET_P9_MINMAX
4887           ? "xs<minmax>cdp %x0,%x1,%x2"
4888           : "xs<minmax>dp %x0,%x1,%x2");
4890   [(set_attr "type" "fp")])
4892 ;; The conditional move instructions allow us to perform max and min operations
4893 ;; even when we don't have the appropriate max/min instruction using the FSEL
4894 ;; instruction.
4896 (define_insn_and_split "*s<minmax><mode>3_fpr"
4897   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4898         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4899                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4900   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4901   "#"
4902   "&& 1"
4903   [(const_int 0)]
4905   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4906   DONE;
4909 (define_expand "mov<mode>cc"
4910    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4911          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4912                            (match_operand:GPR 2 "gpc_reg_operand" "")
4913                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4914   "TARGET_ISEL<sel>"
4915   "
4917   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4918     DONE;
4919   else
4920     FAIL;
4923 ;; We use the BASE_REGS for the isel input operands because, if rA is
4924 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4925 ;; because we may switch the operands and rB may end up being rA.
4927 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4928 ;; leave out the mode in operand 4 and use one pattern, but reload can
4929 ;; change the mode underneath our feet and then gets confused trying
4930 ;; to reload the value.
4931 (define_insn "isel_signed_<mode>"
4932   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4933         (if_then_else:GPR
4934          (match_operator 1 "scc_comparison_operator"
4935                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4936                           (const_int 0)])
4937          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4938          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4939   "TARGET_ISEL<sel>"
4940   "*
4941 { return output_isel (operands); }"
4942   [(set_attr "type" "isel")
4943    (set_attr "length" "4")])
4945 (define_insn "isel_unsigned_<mode>"
4946   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4947         (if_then_else:GPR
4948          (match_operator 1 "scc_comparison_operator"
4949                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4950                           (const_int 0)])
4951          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4952          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4953   "TARGET_ISEL<sel>"
4954   "*
4955 { return output_isel (operands); }"
4956   [(set_attr "type" "isel")
4957    (set_attr "length" "4")])
4959 ;; These patterns can be useful for combine; they let combine know that
4960 ;; isel can handle reversed comparisons so long as the operands are
4961 ;; registers.
4963 (define_insn "*isel_reversed_signed_<mode>"
4964   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4965         (if_then_else:GPR
4966          (match_operator 1 "scc_rev_comparison_operator"
4967                          [(match_operand:CC 4 "cc_reg_operand" "y")
4968                           (const_int 0)])
4969          (match_operand:GPR 2 "gpc_reg_operand" "b")
4970          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4971   "TARGET_ISEL<sel>"
4972   "*
4973 { return output_isel (operands); }"
4974   [(set_attr "type" "isel")
4975    (set_attr "length" "4")])
4977 (define_insn "*isel_reversed_unsigned_<mode>"
4978   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4979         (if_then_else:GPR
4980          (match_operator 1 "scc_rev_comparison_operator"
4981                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4982                           (const_int 0)])
4983          (match_operand:GPR 2 "gpc_reg_operand" "b")
4984          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4985   "TARGET_ISEL<sel>"
4986   "*
4987 { return output_isel (operands); }"
4988   [(set_attr "type" "isel")
4989    (set_attr "length" "4")])
4991 ;; Floating point conditional move
4992 (define_expand "mov<mode>cc"
4993    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4994          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4995                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4996                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4997   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4998   "
5000   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5001     DONE;
5002   else
5003     FAIL;
5006 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5007   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5008         (if_then_else:SFDF
5009          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5010              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5011          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5012          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5013   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5014   "fsel %0,%1,%2,%3"
5015   [(set_attr "type" "fp")])
5017 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5018   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5019         (if_then_else:SFDF
5020          (match_operator:CCFP 1 "fpmask_comparison_operator"
5021                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5022                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5023          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5024          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5025    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5026   "TARGET_P9_MINMAX"
5027   "#"
5028   ""
5029   [(set (match_dup 6)
5030         (if_then_else:V2DI (match_dup 1)
5031                            (match_dup 7)
5032                            (match_dup 8)))
5033    (set (match_dup 0)
5034         (if_then_else:SFDF (ne (match_dup 6)
5035                                (match_dup 8))
5036                            (match_dup 4)
5037                            (match_dup 5)))]
5039   if (GET_CODE (operands[6]) == SCRATCH)
5040     operands[6] = gen_reg_rtx (V2DImode);
5042   operands[7] = CONSTM1_RTX (V2DImode);
5043   operands[8] = CONST0_RTX (V2DImode);
5045  [(set_attr "length" "8")
5046   (set_attr "type" "vecperm")])
5048 ;; Handle inverting the fpmask comparisons.
5049 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5050   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5051         (if_then_else:SFDF
5052          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5053                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5054                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5055          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5056          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5057    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5058   "TARGET_P9_MINMAX"
5059   "#"
5060   "&& 1"
5061   [(set (match_dup 6)
5062         (if_then_else:V2DI (match_dup 9)
5063                            (match_dup 7)
5064                            (match_dup 8)))
5065    (set (match_dup 0)
5066         (if_then_else:SFDF (ne (match_dup 6)
5067                                (match_dup 8))
5068                            (match_dup 5)
5069                            (match_dup 4)))]
5071   rtx op1 = operands[1];
5072   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
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   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5082  [(set_attr "length" "8")
5083   (set_attr "type" "vecperm")])
5085 (define_insn "*fpmask<mode>"
5086   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5087         (if_then_else:V2DI
5088          (match_operator:CCFP 1 "fpmask_comparison_operator"
5089                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5090                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5091          (match_operand:V2DI 4 "all_ones_constant" "")
5092          (match_operand:V2DI 5 "zero_constant" "")))]
5093   "TARGET_P9_MINMAX"
5094   "xscmp%V1dp %x0,%x2,%x3"
5095   [(set_attr "type" "fpcompare")])
5097 (define_insn "*xxsel<mode>"
5098   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5099         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5100                                (match_operand:V2DI 2 "zero_constant" ""))
5101                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5102                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5103   "TARGET_P9_MINMAX"
5104   "xxsel %x0,%x4,%x3,%x1"
5105   [(set_attr "type" "vecmove")])
5108 ;; Conversions to and from floating-point.
5110 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5111 ; don't want to support putting SImode in FPR registers.
5112 (define_insn "lfiwax"
5113   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5114         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5115                    UNSPEC_LFIWAX))]
5116   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5117   "@
5118    lfiwax %0,%y1
5119    lxsiwax %x0,%y1
5120    mtvsrwa %x0,%1
5121    vextsw2d %0,%1"
5122   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5124 ; This split must be run before register allocation because it allocates the
5125 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5126 ; it earlier to allow for the combiner to merge insns together where it might
5127 ; not be needed and also in case the insns are deleted as dead code.
5129 (define_insn_and_split "floatsi<mode>2_lfiwax"
5130   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5131         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5132    (clobber (match_scratch:DI 2 "=wi"))]
5133   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5134    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5135   "#"
5136   ""
5137   [(pc)]
5138   "
5140   rtx dest = operands[0];
5141   rtx src = operands[1];
5142   rtx tmp;
5144   if (!MEM_P (src) && TARGET_POWERPC64
5145       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5146     tmp = convert_to_mode (DImode, src, false);
5147   else
5148     {
5149       tmp = operands[2];
5150       if (GET_CODE (tmp) == SCRATCH)
5151         tmp = gen_reg_rtx (DImode);
5152       if (MEM_P (src))
5153         {
5154           src = rs6000_address_for_fpconvert (src);
5155           emit_insn (gen_lfiwax (tmp, src));
5156         }
5157       else
5158         {
5159           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5160           emit_move_insn (stack, src);
5161           emit_insn (gen_lfiwax (tmp, stack));
5162         }
5163     }
5164   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5165   DONE;
5167   [(set_attr "length" "12")
5168    (set_attr "type" "fpload")])
5170 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5171   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5172         (float:SFDF
5173          (sign_extend:DI
5174           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5175    (clobber (match_scratch:DI 2 "=wi"))]
5176   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5177   "#"
5178   ""
5179   [(pc)]
5180   "
5182   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5183   if (GET_CODE (operands[2]) == SCRATCH)
5184     operands[2] = gen_reg_rtx (DImode);
5185   if (TARGET_P8_VECTOR)
5186     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5187   else
5188     emit_insn (gen_lfiwax (operands[2], operands[1]));
5189   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5190   DONE;
5192   [(set_attr "length" "8")
5193    (set_attr "type" "fpload")])
5195 (define_insn "lfiwzx"
5196   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5197         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5198                    UNSPEC_LFIWZX))]
5199   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5200   "@
5201    lfiwzx %0,%y1
5202    lxsiwzx %x0,%y1
5203    mtvsrwz %x0,%1
5204    xxextractuw %x0,%x1,4"
5205   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5207 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5208   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5209         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5210    (clobber (match_scratch:DI 2 "=wi"))]
5211   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5212   "#"
5213   ""
5214   [(pc)]
5215   "
5217   rtx dest = operands[0];
5218   rtx src = operands[1];
5219   rtx tmp;
5221   if (!MEM_P (src) && TARGET_POWERPC64
5222       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5223     tmp = convert_to_mode (DImode, src, true);
5224   else
5225     {
5226       tmp = operands[2];
5227       if (GET_CODE (tmp) == SCRATCH)
5228         tmp = gen_reg_rtx (DImode);
5229       if (MEM_P (src))
5230         {
5231           src = rs6000_address_for_fpconvert (src);
5232           emit_insn (gen_lfiwzx (tmp, src));
5233         }
5234       else
5235         {
5236           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5237           emit_move_insn (stack, src);
5238           emit_insn (gen_lfiwzx (tmp, stack));
5239         }
5240     }
5241   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5242   DONE;
5244   [(set_attr "length" "12")
5245    (set_attr "type" "fpload")])
5247 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5248   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5249         (unsigned_float:SFDF
5250          (zero_extend:DI
5251           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5252    (clobber (match_scratch:DI 2 "=wi"))]
5253   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5254   "#"
5255   ""
5256   [(pc)]
5257   "
5259   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5260   if (GET_CODE (operands[2]) == SCRATCH)
5261     operands[2] = gen_reg_rtx (DImode);
5262   if (TARGET_P8_VECTOR)
5263     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5264   else
5265     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5266   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5267   DONE;
5269   [(set_attr "length" "8")
5270    (set_attr "type" "fpload")])
5272 ; For each of these conversions, there is a define_expand, a define_insn
5273 ; with a '#' template, and a define_split (with C code).  The idea is
5274 ; to allow constant folding with the template of the define_insn,
5275 ; then to have the insns split later (between sched1 and final).
5277 (define_expand "floatsidf2"
5278   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5279                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5280               (use (match_dup 2))
5281               (use (match_dup 3))
5282               (clobber (match_dup 4))
5283               (clobber (match_dup 5))
5284               (clobber (match_dup 6))])]
5285   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5286   "
5288   if (TARGET_LFIWAX && TARGET_FCFID)
5289     {
5290       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5291       DONE;
5292     }
5293   else if (TARGET_FCFID)
5294     {
5295       rtx dreg = operands[1];
5296       if (!REG_P (dreg))
5297         dreg = force_reg (SImode, dreg);
5298       dreg = convert_to_mode (DImode, dreg, false);
5299       emit_insn (gen_floatdidf2 (operands[0], dreg));
5300       DONE;
5301     }
5303   if (!REG_P (operands[1]))
5304     operands[1] = force_reg (SImode, operands[1]);
5305   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5306   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5307   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5308   operands[5] = gen_reg_rtx (DFmode);
5309   operands[6] = gen_reg_rtx (SImode);
5312 (define_insn_and_split "*floatsidf2_internal"
5313   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5314         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5315    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5316    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5317    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5318    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5319    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5320   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5321   "#"
5322   ""
5323   [(pc)]
5324   "
5326   rtx lowword, highword;
5327   gcc_assert (MEM_P (operands[4]));
5328   highword = adjust_address (operands[4], SImode, 0);
5329   lowword = adjust_address (operands[4], SImode, 4);
5330   if (! WORDS_BIG_ENDIAN)
5331     std::swap (lowword, highword);
5333   emit_insn (gen_xorsi3 (operands[6], operands[1],
5334                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5335   emit_move_insn (lowword, operands[6]);
5336   emit_move_insn (highword, operands[2]);
5337   emit_move_insn (operands[5], operands[4]);
5338   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5339   DONE;
5341   [(set_attr "length" "24")
5342    (set_attr "type" "fp")])
5344 ;; If we don't have a direct conversion to single precision, don't enable this
5345 ;; conversion for 32-bit without fast math, because we don't have the insn to
5346 ;; generate the fixup swizzle to avoid double rounding problems.
5347 (define_expand "floatunssisf2"
5348   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5349         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5350   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5351    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5352        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5353            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5354   "
5356   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5357     {
5358       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5359       DONE;
5360     }
5361   else
5362     {
5363       rtx dreg = operands[1];
5364       if (!REG_P (dreg))
5365         dreg = force_reg (SImode, dreg);
5366       dreg = convert_to_mode (DImode, dreg, true);
5367       emit_insn (gen_floatdisf2 (operands[0], dreg));
5368       DONE;
5369     }
5372 (define_expand "floatunssidf2"
5373   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5374                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5375               (use (match_dup 2))
5376               (use (match_dup 3))
5377               (clobber (match_dup 4))
5378               (clobber (match_dup 5))])]
5379   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5380   "
5382   if (TARGET_LFIWZX && TARGET_FCFID)
5383     {
5384       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5385       DONE;
5386     }
5387   else if (TARGET_FCFID)
5388     {
5389       rtx dreg = operands[1];
5390       if (!REG_P (dreg))
5391         dreg = force_reg (SImode, dreg);
5392       dreg = convert_to_mode (DImode, dreg, true);
5393       emit_insn (gen_floatdidf2 (operands[0], dreg));
5394       DONE;
5395     }
5397   if (!REG_P (operands[1]))
5398     operands[1] = force_reg (SImode, operands[1]);
5399   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5400   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5401   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5402   operands[5] = gen_reg_rtx (DFmode);
5405 (define_insn_and_split "*floatunssidf2_internal"
5406   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5407         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5408    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5409    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5410    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5411    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5412   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5413    && !(TARGET_FCFID && TARGET_POWERPC64)"
5414   "#"
5415   ""
5416   [(pc)]
5417   "
5419   rtx lowword, highword;
5420   gcc_assert (MEM_P (operands[4]));
5421   highword = adjust_address (operands[4], SImode, 0);
5422   lowword = adjust_address (operands[4], SImode, 4);
5423   if (! WORDS_BIG_ENDIAN)
5424     std::swap (lowword, highword);
5426   emit_move_insn (lowword, operands[1]);
5427   emit_move_insn (highword, operands[2]);
5428   emit_move_insn (operands[5], operands[4]);
5429   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5430   DONE;
5432   [(set_attr "length" "20")
5433    (set_attr "type" "fp")])
5435 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5436 ;; vector registers.  These insns favor doing the sign/zero extension in
5437 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5438 ;; extension and then a direct move.
5440 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5441   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5442                    (float:FP_ISA3
5443                     (match_operand:QHI 1 "input_operand")))
5444               (clobber (match_scratch:DI 2))
5445               (clobber (match_scratch:DI 3))
5446               (clobber (match_scratch:<QHI:MODE> 4))])]
5447   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5449   if (MEM_P (operands[1]))
5450     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5453 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5454   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5455         (float:FP_ISA3
5456          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5457    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5458    (clobber (match_scratch:DI 3 "=X,r,X"))
5459    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5460   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5461   "#"
5462   "&& reload_completed"
5463   [(const_int 0)]
5465   rtx result = operands[0];
5466   rtx input = operands[1];
5467   rtx di = operands[2];
5469   if (!MEM_P (input))
5470     {
5471       rtx tmp = operands[3];
5472       if (altivec_register_operand (input, <QHI:MODE>mode))
5473         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5474       else if (GET_CODE (tmp) == SCRATCH)
5475         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5476       else
5477         {
5478           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5479           emit_move_insn (di, tmp);
5480         }
5481     }
5482   else
5483     {
5484       rtx tmp = operands[4];
5485       emit_move_insn (tmp, input);
5486       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5487     }
5489   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5490   DONE;
5493 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5494   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5495                    (unsigned_float:FP_ISA3
5496                     (match_operand:QHI 1 "input_operand" "")))
5497               (clobber (match_scratch:DI 2 ""))
5498               (clobber (match_scratch:DI 3 ""))])]
5499   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5501   if (MEM_P (operands[1]))
5502     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5505 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5506   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5507         (unsigned_float:FP_ISA3
5508          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5509    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5510    (clobber (match_scratch:DI 3 "=X,r,X"))]
5511   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5512   "#"
5513   "&& reload_completed"
5514   [(const_int 0)]
5516   rtx result = operands[0];
5517   rtx input = operands[1];
5518   rtx di = operands[2];
5520   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5521     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5522   else
5523     {
5524       rtx tmp = operands[3];
5525       if (GET_CODE (tmp) == SCRATCH)
5526         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5527       else
5528         {
5529           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5530           emit_move_insn (di, tmp);
5531         }
5532     }
5534   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5535   DONE;
5538 (define_expand "fix_trunc<mode>si2"
5539   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5540         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5541   "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5542   "
5544   if (!TARGET_P8_VECTOR)
5545     {
5546       rtx src = force_reg (<MODE>mode, operands[1]);
5548       if (TARGET_STFIWX)
5549         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5550       else
5551         {
5552           rtx tmp = gen_reg_rtx (DImode);
5553           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5554           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5555                                                       tmp, stack));
5556         }
5557       DONE;
5558     }
5561 ; Like the convert to float patterns, this insn must be split before
5562 ; register allocation so that it can allocate the memory slot if it
5563 ; needed
5564 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5565   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5566         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5567    (clobber (match_scratch:DI 2 "=d"))]
5568   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5569    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5570    && TARGET_STFIWX && can_create_pseudo_p ()
5571    && !TARGET_P8_VECTOR"
5572   "#"
5573   ""
5574   [(pc)]
5576   rtx dest = operands[0];
5577   rtx src = operands[1];
5578   rtx tmp = operands[2];
5580   if (GET_CODE (tmp) == SCRATCH)
5581     tmp = gen_reg_rtx (DImode);
5583   emit_insn (gen_fctiwz_<mode> (tmp, src));
5584   if (MEM_P (dest))
5585     {
5586       dest = rs6000_address_for_fpconvert (dest);
5587       emit_insn (gen_stfiwx (dest, tmp));
5588       DONE;
5589     }
5590   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5591     {
5592       dest = gen_lowpart (DImode, dest);
5593       emit_move_insn (dest, tmp);
5594       DONE;
5595     }
5596   else
5597     {
5598       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5599       emit_insn (gen_stfiwx (stack, tmp));
5600       emit_move_insn (dest, stack);
5601       DONE;
5602     }
5604   [(set_attr "length" "12")
5605    (set_attr "type" "fp")])
5607 (define_insn_and_split "fix_trunc<mode>si2_internal"
5608   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5609         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5610    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5611    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5612   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5613   "#"
5614   ""
5615   [(pc)]
5616   "
5618   rtx lowword;
5619   gcc_assert (MEM_P (operands[3]));
5620   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5622   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5623   emit_move_insn (operands[3], operands[2]);
5624   emit_move_insn (operands[0], lowword);
5625   DONE;
5627   [(set_attr "length" "16")
5628    (set_attr "type" "fp")])
5630 (define_expand "fix_trunc<mode>di2"
5631   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5632         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5633   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5634   "")
5636 (define_insn "*fix_trunc<mode>di2_fctidz"
5637   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5638         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5639   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5640   "@
5641    fctidz %0,%1
5642    xscvdpsxds %x0,%x1"
5643   [(set_attr "type" "fp")])
5645 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5646   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5647                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5648               (clobber (match_scratch:DI 2))])]
5649   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5651   if (MEM_P (operands[0]))
5652     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5655 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5656   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5657         (fix:QHI
5658          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5659    (clobber (match_scratch:DI 2 "=X,wi"))]
5660   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5661   "#"
5662   "&& reload_completed"
5663   [(const_int 0)]
5665   rtx dest = operands[0];
5666   rtx src = operands[1];
5668   if (vsx_register_operand (dest, <QHI:MODE>mode))
5669     {
5670       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5671       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5672     }
5673   else
5674     {
5675       rtx tmp = operands[2];
5676       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5678       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5679       emit_move_insn (dest, tmp2);
5680     }
5681   DONE;
5684 (define_expand "fixuns_trunc<mode>si2"
5685   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5686         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5687   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5688   "
5690   if (!TARGET_P8_VECTOR)
5691     {
5692       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5693       DONE;
5694     }
5697 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5698   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5699         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5700    (clobber (match_scratch:DI 2 "=d"))]
5701   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5702    && TARGET_STFIWX && can_create_pseudo_p ()
5703    && !TARGET_P8_VECTOR"
5704   "#"
5705   ""
5706   [(pc)]
5708   rtx dest = operands[0];
5709   rtx src = operands[1];
5710   rtx tmp = operands[2];
5712   if (GET_CODE (tmp) == SCRATCH)
5713     tmp = gen_reg_rtx (DImode);
5715   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5716   if (MEM_P (dest))
5717     {
5718       dest = rs6000_address_for_fpconvert (dest);
5719       emit_insn (gen_stfiwx (dest, tmp));
5720       DONE;
5721     }
5722   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5723     {
5724       dest = gen_lowpart (DImode, dest);
5725       emit_move_insn (dest, tmp);
5726       DONE;
5727     }
5728   else
5729     {
5730       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5731       emit_insn (gen_stfiwx (stack, tmp));
5732       emit_move_insn (dest, stack);
5733       DONE;
5734     }
5736   [(set_attr "length" "12")
5737    (set_attr "type" "fp")])
5739 (define_insn "fixuns_trunc<mode>di2"
5740   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5741         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5742   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5743   "@
5744    fctiduz %0,%1
5745    xscvdpuxds %x0,%x1"
5746   [(set_attr "type" "fp")])
5748 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5749   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5750                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5751               (clobber (match_scratch:DI 2))])]
5752   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5754   if (MEM_P (operands[0]))
5755     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5758 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5759   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5760         (unsigned_fix:QHI
5761          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5762    (clobber (match_scratch:DI 2 "=X,wi"))]
5763   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5764   "#"
5765   "&& reload_completed"
5766   [(const_int 0)]
5768   rtx dest = operands[0];
5769   rtx src = operands[1];
5771   if (vsx_register_operand (dest, <QHI:MODE>mode))
5772     {
5773       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5774       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5775     }
5776   else
5777     {
5778       rtx tmp = operands[2];
5779       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5781       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5782       emit_move_insn (dest, tmp2);
5783     }
5784   DONE;
5787 ;; If -mvsx-small-integer, we can represent the FIX operation directly.  On
5788 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5789 ;; to another location, since SImode is not allowed in vector registers.
5790 (define_insn "*fctiw<u>z_<mode>_smallint"
5791   [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5792         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5793   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5794   "@
5795    fctiw<u>z %0,%1
5796    xscvdp<su>xws %x0,%x1"
5797   [(set_attr "type" "fp")])
5799 ;; Combiner pattern to prevent moving the result of converting a floating point
5800 ;; value to 32-bit integer to GPR in order to save it.
5801 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5802   [(set (match_operand:SI 0 "memory_operand" "=Z")
5803         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5804    (clobber (match_scratch:SI 2 "=wa"))]
5805   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5806   "#"
5807   "&& reload_completed"
5808   [(set (match_dup 2)
5809         (any_fix:SI (match_dup 1)))
5810    (set (match_dup 0)
5811         (match_dup 2))])
5813 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5814 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5815 ;; because the first makes it clear that operand 0 is not live
5816 ;; before the instruction.
5817 (define_insn "fctiwz_<mode>"
5818   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5819         (unspec:DI [(fix:SI
5820                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5821                    UNSPEC_FCTIWZ))]
5822   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5823   "@
5824    fctiwz %0,%1
5825    xscvdpsxws %x0,%x1"
5826   [(set_attr "type" "fp")])
5828 (define_insn "fctiwuz_<mode>"
5829   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5830         (unspec:DI [(unsigned_fix:SI
5831                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5832                    UNSPEC_FCTIWUZ))]
5833   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5834   "@
5835    fctiwuz %0,%1
5836    xscvdpuxws %x0,%x1"
5837   [(set_attr "type" "fp")])
5839 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5840 ;; since the friz instruction does not truncate the value if the floating
5841 ;; point value is < LONG_MIN or > LONG_MAX.
5842 (define_insn "*friz"
5843   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5844         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5845   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5846    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5847   "@
5848    friz %0,%1
5849    xsrdpiz %x0,%x1"
5850   [(set_attr "type" "fp")])
5852 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5853 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5854 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5855 ;; extend it, store it back on the stack from the GPR, load it back into the
5856 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5857 ;; disable using store and load to sign/zero extend the value.
5858 (define_insn_and_split "*round32<mode>2_fprs"
5859   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5860         (float:SFDF
5861          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5862    (clobber (match_scratch:DI 2 "=d"))
5863    (clobber (match_scratch:DI 3 "=d"))]
5864   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5865    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5866    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5867   "#"
5868   ""
5869   [(pc)]
5871   rtx dest = operands[0];
5872   rtx src = operands[1];
5873   rtx tmp1 = operands[2];
5874   rtx tmp2 = operands[3];
5875   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5877   if (GET_CODE (tmp1) == SCRATCH)
5878     tmp1 = gen_reg_rtx (DImode);
5879   if (GET_CODE (tmp2) == SCRATCH)
5880     tmp2 = gen_reg_rtx (DImode);
5882   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5883   emit_insn (gen_stfiwx (stack, tmp1));
5884   emit_insn (gen_lfiwax (tmp2, stack));
5885   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5886   DONE;
5888   [(set_attr "type" "fpload")
5889    (set_attr "length" "16")])
5891 (define_insn_and_split "*roundu32<mode>2_fprs"
5892   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5893         (unsigned_float:SFDF
5894          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5895    (clobber (match_scratch:DI 2 "=d"))
5896    (clobber (match_scratch:DI 3 "=d"))]
5897   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5898    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5899    && can_create_pseudo_p ()"
5900   "#"
5901   ""
5902   [(pc)]
5904   rtx dest = operands[0];
5905   rtx src = operands[1];
5906   rtx tmp1 = operands[2];
5907   rtx tmp2 = operands[3];
5908   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5910   if (GET_CODE (tmp1) == SCRATCH)
5911     tmp1 = gen_reg_rtx (DImode);
5912   if (GET_CODE (tmp2) == SCRATCH)
5913     tmp2 = gen_reg_rtx (DImode);
5915   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5916   emit_insn (gen_stfiwx (stack, tmp1));
5917   emit_insn (gen_lfiwzx (tmp2, stack));
5918   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5919   DONE;
5921   [(set_attr "type" "fpload")
5922    (set_attr "length" "16")])
5924 (define_insn "lrintsfsi2"
5925   [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
5926         (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
5927                    UNSPEC_FCTIW))]
5928   "TARGET_SF_FPR && TARGET_FPRND"
5929   "fctiw %0,%1"
5930   [(set_attr "type" "fp")])
5932 ;; No VSX equivalent to fctid
5933 (define_insn "lrint<mode>di2"
5934   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5935         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5936                    UNSPEC_FCTID))]
5937   "TARGET_<MODE>_FPR && TARGET_FPRND"
5938   "fctid %0,%1"
5939   [(set_attr "type" "fp")])
5941 (define_insn "btrunc<mode>2"
5942   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5943         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5944                      UNSPEC_FRIZ))]
5945   "TARGET_<MODE>_FPR && TARGET_FPRND"
5946   "@
5947    friz %0,%1
5948    xsrdpiz %x0,%x1"
5949   [(set_attr "type" "fp")
5950    (set_attr "fp_type" "fp_addsub_<Fs>")])
5952 (define_insn "ceil<mode>2"
5953   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5954         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5955                      UNSPEC_FRIP))]
5956   "TARGET_<MODE>_FPR && TARGET_FPRND"
5957   "@
5958    frip %0,%1
5959    xsrdpip %x0,%x1"
5960   [(set_attr "type" "fp")
5961    (set_attr "fp_type" "fp_addsub_<Fs>")])
5963 (define_insn "floor<mode>2"
5964   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5965         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5966                      UNSPEC_FRIM))]
5967   "TARGET_<MODE>_FPR && TARGET_FPRND"
5968   "@
5969    frim %0,%1
5970    xsrdpim %x0,%x1"
5971   [(set_attr "type" "fp")
5972    (set_attr "fp_type" "fp_addsub_<Fs>")])
5974 ;; No VSX equivalent to frin
5975 (define_insn "round<mode>2"
5976   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5977         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5978                      UNSPEC_FRIN))]
5979   "TARGET_<MODE>_FPR && TARGET_FPRND"
5980   "frin %0,%1"
5981   [(set_attr "type" "fp")
5982    (set_attr "fp_type" "fp_addsub_<Fs>")])
5984 (define_insn "*xsrdpi<mode>2"
5985   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5986         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5987                      UNSPEC_XSRDPI))]
5988   "TARGET_<MODE>_FPR && TARGET_VSX"
5989   "xsrdpi %x0,%x1"
5990   [(set_attr "type" "fp")
5991    (set_attr "fp_type" "fp_addsub_<Fs>")])
5993 (define_expand "lround<mode>di2"
5994   [(set (match_dup 2)
5995         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5996                      UNSPEC_XSRDPI))
5997    (set (match_operand:DI 0 "gpc_reg_operand" "")
5998         (unspec:DI [(match_dup 2)]
5999                    UNSPEC_FCTID))]
6000   "TARGET_<MODE>_FPR && TARGET_VSX"
6002   operands[2] = gen_reg_rtx (<MODE>mode);
6005 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6006 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6007 ; is only generated for Power8 or later.
6008 (define_insn "stfiwx"
6009   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6010         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6011                    UNSPEC_STFIWX))]
6012   "TARGET_PPC_GFXOPT"
6013   "@
6014    stfiwx %1,%y0
6015    stxsiwx %x1,%y0"
6016   [(set_attr "type" "fpstore")])
6018 ;; If we don't have a direct conversion to single precision, don't enable this
6019 ;; conversion for 32-bit without fast math, because we don't have the insn to
6020 ;; generate the fixup swizzle to avoid double rounding problems.
6021 (define_expand "floatsisf2"
6022   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6023         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6024   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6025    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6026        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6027            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6028   "
6030   if (TARGET_FCFIDS && TARGET_LFIWAX)
6031     {
6032       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6033       DONE;
6034     }
6035   else if (TARGET_FCFID && TARGET_LFIWAX)
6036     {
6037       rtx dfreg = gen_reg_rtx (DFmode);
6038       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6039       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6040       DONE;
6041     }
6042   else
6043     {
6044       rtx dreg = operands[1];
6045       if (!REG_P (dreg))
6046         dreg = force_reg (SImode, dreg);
6047       dreg = convert_to_mode (DImode, dreg, false);
6048       emit_insn (gen_floatdisf2 (operands[0], dreg));
6049       DONE;
6050     }
6053 (define_insn "floatdidf2"
6054   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6055         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6056   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6057   "@
6058    fcfid %0,%1
6059    xscvsxddp %x0,%x1"
6060   [(set_attr "type" "fp")])
6062 ; Allow the combiner to merge source memory operands to the conversion so that
6063 ; the optimizer/register allocator doesn't try to load the value too early in a
6064 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6065 ; hit.  We will split after reload to avoid the trip through the GPRs
6067 (define_insn_and_split "*floatdidf2_mem"
6068   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6069         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6070    (clobber (match_scratch:DI 2 "=d,wi"))]
6071   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6072   "#"
6073   "&& reload_completed"
6074   [(set (match_dup 2) (match_dup 1))
6075    (set (match_dup 0) (float:DF (match_dup 2)))]
6076   ""
6077   [(set_attr "length" "8")
6078    (set_attr "type" "fpload")])
6080 (define_expand "floatunsdidf2"
6081   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6082         (unsigned_float:DF
6083          (match_operand:DI 1 "gpc_reg_operand" "")))]
6084   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6085   "")
6087 (define_insn "*floatunsdidf2_fcfidu"
6088   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6089         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6090   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6091   "@
6092    fcfidu %0,%1
6093    xscvuxddp %x0,%x1"
6094   [(set_attr "type" "fp")
6095    (set_attr "length" "4")])
6097 (define_insn_and_split "*floatunsdidf2_mem"
6098   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6099         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6100    (clobber (match_scratch:DI 2 "=d,wi"))]
6101   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6102   "#"
6103   "&& reload_completed"
6104   [(set (match_dup 2) (match_dup 1))
6105    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6106   ""
6107   [(set_attr "length" "8")
6108    (set_attr "type" "fpload")])
6110 (define_expand "floatdisf2"
6111   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6112         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6113   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6114    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6115   "
6117   if (!TARGET_FCFIDS)
6118     {
6119       rtx val = operands[1];
6120       if (!flag_unsafe_math_optimizations)
6121         {
6122           rtx label = gen_label_rtx ();
6123           val = gen_reg_rtx (DImode);
6124           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6125           emit_label (label);
6126         }
6127       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6128       DONE;
6129     }
6132 (define_insn "floatdisf2_fcfids"
6133   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6134         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6135   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6136    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6137   "@
6138    fcfids %0,%1
6139    xscvsxdsp %x0,%x1"
6140   [(set_attr "type" "fp")])
6142 (define_insn_and_split "*floatdisf2_mem"
6143   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6144         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6145    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6146   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6147    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6148   "#"
6149   "&& reload_completed"
6150   [(pc)]
6151   "
6153   emit_move_insn (operands[2], operands[1]);
6154   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6155   DONE;
6157   [(set_attr "length" "8")])
6159 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6160 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6161 ;; from double rounding.
6162 ;; Instead of creating a new cpu type for two FP operations, just use fp
6163 (define_insn_and_split "floatdisf2_internal1"
6164   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6165         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6166    (clobber (match_scratch:DF 2 "=d"))]
6167   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6168   "#"
6169   "&& reload_completed"
6170   [(set (match_dup 2)
6171         (float:DF (match_dup 1)))
6172    (set (match_dup 0)
6173         (float_truncate:SF (match_dup 2)))]
6174   ""
6175   [(set_attr "length" "8")
6176    (set_attr "type" "fp")])
6178 ;; Twiddles bits to avoid double rounding.
6179 ;; Bits that might be truncated when converting to DFmode are replaced
6180 ;; by a bit that won't be lost at that stage, but is below the SFmode
6181 ;; rounding position.
6182 (define_expand "floatdisf2_internal2"
6183   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6184                                               (const_int 53)))
6185               (clobber (reg:DI CA_REGNO))])
6186    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6187                                            (const_int 2047)))
6188    (set (match_dup 3) (plus:DI (match_dup 3)
6189                                (const_int 1)))
6190    (set (match_dup 0) (plus:DI (match_dup 0)
6191                                (const_int 2047)))
6192    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6193                                      (const_int 2)))
6194    (set (match_dup 0) (ior:DI (match_dup 0)
6195                               (match_dup 1)))
6196    (set (match_dup 0) (and:DI (match_dup 0)
6197                               (const_int -2048)))
6198    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6199                            (label_ref (match_operand:DI 2 "" ""))
6200                            (pc)))
6201    (set (match_dup 0) (match_dup 1))]
6202   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6203    && !TARGET_FCFIDS"
6204   "
6206   operands[3] = gen_reg_rtx (DImode);
6207   operands[4] = gen_reg_rtx (CCUNSmode);
6210 (define_expand "floatunsdisf2"
6211   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6212         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6213   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6214    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6215   "")
6217 (define_insn "floatunsdisf2_fcfidus"
6218   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6219         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6220   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6221    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6222   "@
6223    fcfidus %0,%1
6224    xscvuxdsp %x0,%x1"
6225   [(set_attr "type" "fp")])
6227 (define_insn_and_split "*floatunsdisf2_mem"
6228   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6229         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6230    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6231   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6232    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6233   "#"
6234   "&& reload_completed"
6235   [(pc)]
6236   "
6238   emit_move_insn (operands[2], operands[1]);
6239   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6240   DONE;
6242   [(set_attr "length" "8")
6243    (set_attr "type" "fpload")])
6245 ;; Define the TImode operations that can be done in a small number
6246 ;; of instructions.  The & constraints are to prevent the register
6247 ;; allocator from allocating registers that overlap with the inputs
6248 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6249 ;; also allow for the output being the same as one of the inputs.
6251 (define_expand "addti3"
6252   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6253         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6254                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6255   "TARGET_64BIT"
6257   rtx lo0 = gen_lowpart (DImode, operands[0]);
6258   rtx lo1 = gen_lowpart (DImode, operands[1]);
6259   rtx lo2 = gen_lowpart (DImode, operands[2]);
6260   rtx hi0 = gen_highpart (DImode, operands[0]);
6261   rtx hi1 = gen_highpart (DImode, operands[1]);
6262   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6264   if (!reg_or_short_operand (lo2, DImode))
6265     lo2 = force_reg (DImode, lo2);
6266   if (!adde_operand (hi2, DImode))
6267     hi2 = force_reg (DImode, hi2);
6269   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6270   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6271   DONE;
6274 (define_expand "subti3"
6275   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6276         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6277                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6278   "TARGET_64BIT"
6280   rtx lo0 = gen_lowpart (DImode, operands[0]);
6281   rtx lo1 = gen_lowpart (DImode, operands[1]);
6282   rtx lo2 = gen_lowpart (DImode, operands[2]);
6283   rtx hi0 = gen_highpart (DImode, operands[0]);
6284   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6285   rtx hi2 = gen_highpart (DImode, operands[2]);
6287   if (!reg_or_short_operand (lo1, DImode))
6288     lo1 = force_reg (DImode, lo1);
6289   if (!adde_operand (hi1, DImode))
6290     hi1 = force_reg (DImode, hi1);
6292   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6293   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6294   DONE;
6297 ;; 128-bit logical operations expanders
6299 (define_expand "and<mode>3"
6300   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6301         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6302                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6303   ""
6304   "")
6306 (define_expand "ior<mode>3"
6307   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6308         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6309                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6310   ""
6311   "")
6313 (define_expand "xor<mode>3"
6314   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6315         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6316                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6317   ""
6318   "")
6320 (define_expand "one_cmpl<mode>2"
6321   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6322         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6323   ""
6324   "")
6326 (define_expand "nor<mode>3"
6327   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6328         (and:BOOL_128
6329          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6330          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6331   ""
6332   "")
6334 (define_expand "andc<mode>3"
6335   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6336         (and:BOOL_128
6337          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6338          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6339   ""
6340   "")
6342 ;; Power8 vector logical instructions.
6343 (define_expand "eqv<mode>3"
6344   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6345         (not:BOOL_128
6346          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6347                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6348   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6349   "")
6351 ;; Rewrite nand into canonical form
6352 (define_expand "nand<mode>3"
6353   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6354         (ior:BOOL_128
6355          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6356          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6357   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6358   "")
6360 ;; The canonical form is to have the negated element first, so we need to
6361 ;; reverse arguments.
6362 (define_expand "orc<mode>3"
6363   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6364         (ior:BOOL_128
6365          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6366          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6367   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6368   "")
6370 ;; 128-bit logical operations insns and split operations
6371 (define_insn_and_split "*and<mode>3_internal"
6372   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6373         (and:BOOL_128
6374          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6375          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6376   ""
6378   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6379     return "xxland %x0,%x1,%x2";
6381   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6382     return "vand %0,%1,%2";
6384   return "#";
6386   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6387   [(const_int 0)]
6389   rs6000_split_logical (operands, AND, false, false, false);
6390   DONE;
6392   [(set (attr "type")
6393       (if_then_else
6394         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6395         (const_string "veclogical")
6396         (const_string "integer")))
6397    (set (attr "length")
6398       (if_then_else
6399         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6400         (const_string "4")
6401         (if_then_else
6402          (match_test "TARGET_POWERPC64")
6403          (const_string "8")
6404          (const_string "16"))))])
6406 ;; 128-bit IOR/XOR
6407 (define_insn_and_split "*bool<mode>3_internal"
6408   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6409         (match_operator:BOOL_128 3 "boolean_or_operator"
6410          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6411           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6412   ""
6414   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6415     return "xxl%q3 %x0,%x1,%x2";
6417   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6418     return "v%q3 %0,%1,%2";
6420   return "#";
6422   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6423   [(const_int 0)]
6425   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6426   DONE;
6428   [(set (attr "type")
6429       (if_then_else
6430         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6431         (const_string "veclogical")
6432         (const_string "integer")))
6433    (set (attr "length")
6434       (if_then_else
6435         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6436         (const_string "4")
6437         (if_then_else
6438          (match_test "TARGET_POWERPC64")
6439          (const_string "8")
6440          (const_string "16"))))])
6442 ;; 128-bit ANDC/ORC
6443 (define_insn_and_split "*boolc<mode>3_internal1"
6444   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6445         (match_operator:BOOL_128 3 "boolean_operator"
6446          [(not:BOOL_128
6447            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6448           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6449   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6451   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6452     return "xxl%q3 %x0,%x1,%x2";
6454   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6455     return "v%q3 %0,%1,%2";
6457   return "#";
6459   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6460    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6461   [(const_int 0)]
6463   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6464   DONE;
6466   [(set (attr "type")
6467       (if_then_else
6468         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6469         (const_string "veclogical")
6470         (const_string "integer")))
6471    (set (attr "length")
6472       (if_then_else
6473         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6474         (const_string "4")
6475         (if_then_else
6476          (match_test "TARGET_POWERPC64")
6477          (const_string "8")
6478          (const_string "16"))))])
6480 (define_insn_and_split "*boolc<mode>3_internal2"
6481   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6482         (match_operator:TI2 3 "boolean_operator"
6483          [(not:TI2
6484            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6485           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6486   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6487   "#"
6488   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6489   [(const_int 0)]
6491   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6492   DONE;
6494   [(set_attr "type" "integer")
6495    (set (attr "length")
6496         (if_then_else
6497          (match_test "TARGET_POWERPC64")
6498          (const_string "8")
6499          (const_string "16")))])
6501 ;; 128-bit NAND/NOR
6502 (define_insn_and_split "*boolcc<mode>3_internal1"
6503   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6504         (match_operator:BOOL_128 3 "boolean_operator"
6505          [(not:BOOL_128
6506            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6507           (not:BOOL_128
6508            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6509   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6511   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6512     return "xxl%q3 %x0,%x1,%x2";
6514   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6515     return "v%q3 %0,%1,%2";
6517   return "#";
6519   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6520    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6521   [(const_int 0)]
6523   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6524   DONE;
6526   [(set (attr "type")
6527       (if_then_else
6528         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6529         (const_string "veclogical")
6530         (const_string "integer")))
6531    (set (attr "length")
6532       (if_then_else
6533         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6534         (const_string "4")
6535         (if_then_else
6536          (match_test "TARGET_POWERPC64")
6537          (const_string "8")
6538          (const_string "16"))))])
6540 (define_insn_and_split "*boolcc<mode>3_internal2"
6541   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6542         (match_operator:TI2 3 "boolean_operator"
6543          [(not:TI2
6544            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6545           (not:TI2
6546            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6547   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6548   "#"
6549   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6550   [(const_int 0)]
6552   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6553   DONE;
6555   [(set_attr "type" "integer")
6556    (set (attr "length")
6557         (if_then_else
6558          (match_test "TARGET_POWERPC64")
6559          (const_string "8")
6560          (const_string "16")))])
6563 ;; 128-bit EQV
6564 (define_insn_and_split "*eqv<mode>3_internal1"
6565   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6566         (not:BOOL_128
6567          (xor:BOOL_128
6568           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6569           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6570   "TARGET_P8_VECTOR"
6572   if (vsx_register_operand (operands[0], <MODE>mode))
6573     return "xxleqv %x0,%x1,%x2";
6575   return "#";
6577   "TARGET_P8_VECTOR && reload_completed
6578    && int_reg_operand (operands[0], <MODE>mode)"
6579   [(const_int 0)]
6581   rs6000_split_logical (operands, XOR, true, false, false);
6582   DONE;
6584   [(set (attr "type")
6585       (if_then_else
6586         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6587         (const_string "veclogical")
6588         (const_string "integer")))
6589    (set (attr "length")
6590       (if_then_else
6591         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6592         (const_string "4")
6593         (if_then_else
6594          (match_test "TARGET_POWERPC64")
6595          (const_string "8")
6596          (const_string "16"))))])
6598 (define_insn_and_split "*eqv<mode>3_internal2"
6599   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6600         (not:TI2
6601          (xor:TI2
6602           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6603           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6604   "!TARGET_P8_VECTOR"
6605   "#"
6606   "reload_completed && !TARGET_P8_VECTOR"
6607   [(const_int 0)]
6609   rs6000_split_logical (operands, XOR, true, false, false);
6610   DONE;
6612   [(set_attr "type" "integer")
6613    (set (attr "length")
6614         (if_then_else
6615          (match_test "TARGET_POWERPC64")
6616          (const_string "8")
6617          (const_string "16")))])
6619 ;; 128-bit one's complement
6620 (define_insn_and_split "*one_cmpl<mode>3_internal"
6621   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6622         (not:BOOL_128
6623           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6624   ""
6626   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6627     return "xxlnor %x0,%x1,%x1";
6629   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6630     return "vnor %0,%1,%1";
6632   return "#";
6634   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6635   [(const_int 0)]
6637   rs6000_split_logical (operands, NOT, false, false, false);
6638   DONE;
6640   [(set (attr "type")
6641       (if_then_else
6642         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6643         (const_string "veclogical")
6644         (const_string "integer")))
6645    (set (attr "length")
6646       (if_then_else
6647         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6648         (const_string "4")
6649         (if_then_else
6650          (match_test "TARGET_POWERPC64")
6651          (const_string "8")
6652          (const_string "16"))))])
6655 ;; Now define ways of moving data around.
6657 ;; Set up a register with a value from the GOT table
6659 (define_expand "movsi_got"
6660   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6661         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6662                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6663   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6664   "
6666   if (GET_CODE (operands[1]) == CONST)
6667     {
6668       rtx offset = const0_rtx;
6669       HOST_WIDE_INT value;
6671       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6672       value = INTVAL (offset);
6673       if (value != 0)
6674         {
6675           rtx tmp = (!can_create_pseudo_p ()
6676                      ? operands[0]
6677                      : gen_reg_rtx (Pmode));
6678           emit_insn (gen_movsi_got (tmp, operands[1]));
6679           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6680           DONE;
6681         }
6682     }
6684   operands[2] = rs6000_got_register (operands[1]);
6687 (define_insn "*movsi_got_internal"
6688   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6689         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6690                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6691                    UNSPEC_MOVSI_GOT))]
6692   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6693   "lwz %0,%a1@got(%2)"
6694   [(set_attr "type" "load")])
6696 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6697 ;; didn't get allocated to a hard register.
6698 (define_split
6699   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6700         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6701                     (match_operand:SI 2 "memory_operand" "")]
6702                    UNSPEC_MOVSI_GOT))]
6703   "DEFAULT_ABI == ABI_V4
6704     && flag_pic == 1
6705     && reload_completed"
6706   [(set (match_dup 0) (match_dup 2))
6707    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6708                                  UNSPEC_MOVSI_GOT))]
6709   "")
6711 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6712 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6713 ;; and this is even supposed to be faster, but it is simpler not to get
6714 ;; integers in the TOC.
6715 (define_insn "movsi_low"
6716   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6717         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6718                            (match_operand 2 "" ""))))]
6719   "TARGET_MACHO && ! TARGET_64BIT"
6720   "lwz %0,lo16(%2)(%1)"
6721   [(set_attr "type" "load")
6722    (set_attr "length" "4")])
6724 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6725 ;;              STW          STFIWX       STXSIWX      LI           LIS
6726 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6727 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6728 ;;              MF%1         MT%0         MT%0         NOP
6729 (define_insn "*movsi_internal1"
6730   [(set (match_operand:SI 0 "nonimmediate_operand"
6731                 "=r,         r,           r,           ?*wI,        ?*wH,
6732                  m,          ?Z,          ?Z,          r,           r,
6733                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6734                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6735                  r,          *c*l,        *h,          *h")
6737         (match_operand:SI 1 "input_operand"
6738                 "r,          U,           m,           Z,           Z,
6739                  r,          wI,          wH,          I,           L,
6740                  n,          wIwH,        O,           wM,          wB,
6741                  O,          wM,          wS,          r,           wIwH,
6742                  *h,         r,           r,           0"))]
6744   "!TARGET_SINGLE_FPU &&
6745    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6746   "@
6747    mr %0,%1
6748    la %0,%a1
6749    lwz%U1%X1 %0,%1
6750    lfiwzx %0,%y1
6751    lxsiwzx %x0,%y1
6752    stw%U0%X0 %1,%0
6753    stfiwx %1,%y0
6754    stxsiwx %x1,%y0
6755    li %0,%1
6756    lis %0,%v1
6757    #
6758    xxlor %x0,%x1,%x1
6759    xxspltib %x0,0
6760    xxspltib %x0,255
6761    vspltisw %0,%1
6762    xxlxor %x0,%x0,%x0
6763    xxlorc %x0,%x0,%x0
6764    #
6765    mtvsrwz %x0,%1
6766    mfvsrwz %0,%x1
6767    mf%1 %0
6768    mt%0 %1
6769    mt%0 %1
6770    nop"
6771   [(set_attr "type"
6772                 "*,          *,           load,        fpload,      fpload,
6773                  store,      fpstore,     fpstore,     *,           *,
6774                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6775                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6776                  *,           *,           *,           *")
6778    (set_attr "length"
6779                 "4,          4,           4,           4,           4,
6780                  4,          4,           4,           4,           4,
6781                  8,          4,           4,           4,           4,
6782                  4,          4,           8,           4,           4,
6783                  4,          4,           4,           4")])
6785 (define_insn "*movsi_internal1_single"
6786   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6787         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6788   "TARGET_SINGLE_FPU &&
6789    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6790   "@
6791    mr %0,%1
6792    la %0,%a1
6793    lwz%U1%X1 %0,%1
6794    stw%U0%X0 %1,%0
6795    li %0,%1
6796    lis %0,%v1
6797    #
6798    mf%1 %0
6799    mt%0 %1
6800    mt%0 %1
6801    nop
6802    stfs%U0%X0 %1,%0
6803    lfs%U1%X1 %0,%1"
6804   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6805    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6807 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6808 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6810 ;; Because SF values are actually stored as DF values within the vector
6811 ;; registers, we need to convert the value to the vector SF format when
6812 ;; we need to use the bits in a union or similar cases.  We only need
6813 ;; to do this transformation when the value is a vector register.  Loads,
6814 ;; stores, and transfers within GPRs are assumed to be safe.
6816 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6817 ;; no alternatives, because the call is created as part of secondary_reload,
6818 ;; and operand #2's register class is used to allocate the temporary register.
6819 ;; This function is called before reload, and it creates the temporary as
6820 ;; needed.
6822 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6823 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6824 ;;              MTVSRWZ
6826 (define_insn_and_split "movsi_from_sf"
6827   [(set (match_operand:SI 0 "nonimmediate_operand"
6828                 "=r,         r,           ?*wI,        ?*wH,     m,
6829                  m,          wY,          Z,           r,        ?*wIwH,
6830                  wIwH")
6832         (unspec:SI [(match_operand:SF 1 "input_operand"
6833                 "r,          m,           Z,           Z,        r,
6834                  f,          wb,          wu,          wIwH,     wIwH,
6835                  r")]
6836                     UNSPEC_SI_FROM_SF))
6838    (clobber (match_scratch:V4SF 2
6839                 "=X,         X,           X,           X,        X,
6840                  X,          X,           X,           wIwH,     X,
6841                  X"))]
6843   "TARGET_NO_SF_SUBREG
6844    && (register_operand (operands[0], SImode)
6845        || register_operand (operands[1], SFmode))"
6846   "@
6847    mr %0,%1
6848    lwz%U1%X1 %0,%1
6849    lfiwzx %0,%y1
6850    lxsiwzx %x0,%y1
6851    stw%U0%X0 %1,%0
6852    stfs%U0%X0 %1,%0
6853    stxssp %1,%0
6854    stxsspx %x1,%y0
6855    #
6856    xscvdpspn %x0,%x1
6857    mtvsrwz %x0,%1"
6858   "&& reload_completed
6859    && int_reg_operand (operands[0], SImode)
6860    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6861   [(const_int 0)]
6863   rtx op0 = operands[0];
6864   rtx op1 = operands[1];
6865   rtx op2 = operands[2];
6866   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6867   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6869   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6870   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6871   DONE;
6873   [(set_attr "type"
6874                 "*,          load,        fpload,      fpload,   store,
6875                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6876                  mffgpr")
6878    (set_attr "length"
6879                 "4,          4,           4,           4,        4,
6880                  4,          4,           4,           8,        4,
6881                  4")])
6883 ;; movsi_from_sf with zero extension
6885 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6886 ;;              VSX->VSX     MTVSRWZ
6888 (define_insn_and_split "*movdi_from_sf_zero_ext"
6889   [(set (match_operand:DI 0 "gpc_reg_operand"
6890                 "=r,         r,           ?*wI,        ?*wH,     r,
6891                  ?wK,        wIwH")
6893         (zero_extend:DI
6894          (unspec:SI [(match_operand:SF 1 "input_operand"
6895                 "r,          m,           Z,           Z,        wIwH,
6896                  wIwH,       r")]
6897                     UNSPEC_SI_FROM_SF)))
6899    (clobber (match_scratch:V4SF 2
6900                 "=X,         X,           X,           X,        wa,
6901                  wIwH,       X"))]
6903   "TARGET_DIRECT_MOVE_64BIT
6904    && (register_operand (operands[0], DImode)
6905        || register_operand (operands[1], SImode))"
6906   "@
6907    rldicl %0,%1,0,32
6908    lwz%U1%X1 %0,%1
6909    lfiwzx %0,%y1
6910    lxsiwzx %x0,%y1
6911    #
6912    #
6913    mtvsrwz %x0,%1"
6914   "&& reload_completed
6915    && register_operand (operands[0], DImode)
6916    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6917   [(const_int 0)]
6919   rtx op0 = operands[0];
6920   rtx op1 = operands[1];
6921   rtx op2 = operands[2];
6922   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6924   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6925   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6926   DONE;
6928   [(set_attr "type"
6929                 "*,          load,        fpload,      fpload,   two,
6930                  two,        mffgpr")
6932    (set_attr "length"
6933                 "4,          4,           4,           4,        8,
6934                  8,          4")])
6936 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6937 ;; moving it to SImode.  We can do a SFmode store without having to do the
6938 ;; conversion explicitly.  If we are doing a register->register conversion, use
6939 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6940 ;; input will not fit in a SFmode, and the later assumes the value has already
6941 ;; been rounded.
6942 (define_insn "*movsi_from_df"
6943   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
6944         (unspec:SI [(float_truncate:SF
6945                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6946                     UNSPEC_SI_FROM_SF))]
6948   "TARGET_NO_SF_SUBREG"
6949   "@
6950    xscvdpsp %x0,%x1
6951    stfs%U0%X0 %1,%0
6952    stxssp %1,%0
6953    stxsspx %x1,%y0"
6954   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
6956 ;; Split a load of a large constant into the appropriate two-insn
6957 ;; sequence.
6959 (define_split
6960   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6961         (match_operand:SI 1 "const_int_operand" ""))]
6962   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6963    && (INTVAL (operands[1]) & 0xffff) != 0"
6964   [(set (match_dup 0)
6965         (match_dup 2))
6966    (set (match_dup 0)
6967         (ior:SI (match_dup 0)
6968                 (match_dup 3)))]
6969   "
6971   if (rs6000_emit_set_const (operands[0], operands[1]))
6972     DONE;
6973   else
6974     FAIL;
6977 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6978 (define_split
6979   [(set (match_operand:DI 0 "altivec_register_operand")
6980         (match_operand:DI 1 "xxspltib_constant_split"))]
6981   "TARGET_P9_VECTOR && reload_completed"
6982   [(const_int 0)]
6984   rtx op0 = operands[0];
6985   rtx op1 = operands[1];
6986   int r = REGNO (op0);
6987   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6989   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6990   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6991   DONE;
6994 (define_insn "*mov<mode>_internal2"
6995   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6996         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6997                     (const_int 0)))
6998    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6999   ""
7000   "@
7001    cmp<wd>i %2,%0,0
7002    mr. %0,%1
7003    #"
7004   [(set_attr "type" "cmp,logical,cmp")
7005    (set_attr "dot" "yes")
7006    (set_attr "length" "4,4,8")])
7008 (define_split
7009   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7010         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7011                     (const_int 0)))
7012    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7013   "reload_completed"
7014   [(set (match_dup 0) (match_dup 1))
7015    (set (match_dup 2)
7016         (compare:CC (match_dup 0)
7017                     (const_int 0)))]
7018   "")
7020 (define_expand "mov<mode>"
7021   [(set (match_operand:INT 0 "general_operand" "")
7022         (match_operand:INT 1 "any_operand" ""))]
7023   ""
7024   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7026 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7027 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7028 ;;              MTVSRWZ     MF%1       MT%1       NOP
7029 (define_insn "*mov<mode>_internal"
7030   [(set (match_operand:QHI 0 "nonimmediate_operand"
7031                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7032                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7033                  ?*wJwK,    r,         *c*l,      *h")
7035         (match_operand:QHI 1 "input_operand"
7036                 "r,         m,         Z,         r,         wJwK,      i,
7037                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7038                  r,         *h,        r,         0"))]
7040   "gpc_reg_operand (operands[0], <MODE>mode)
7041    || gpc_reg_operand (operands[1], <MODE>mode)"
7042   "@
7043    mr %0,%1
7044    l<wd>z%U1%X1 %0,%1
7045    lxsi<wd>zx %x0,%y1
7046    st<wd>%U0%X0 %1,%0
7047    stxsi<wd>x %x1,%y0
7048    li %0,%1
7049    xxlor %x0,%x1,%x1
7050    xxspltib %x0,0
7051    xxspltib %x0,255
7052    vspltis<wd> %0,%1
7053    #
7054    mfvsrwz %0,%x1
7055    mtvsrwz %x0,%1
7056    mf%1 %0
7057    mt%0 %1
7058    nop"
7059   [(set_attr "type"
7060                 "*,         load,      fpload,    store,     fpstore,   *,
7061                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7062                  mffgpr,    mfjmpr,    mtjmpr,    *")
7064    (set_attr "length"
7065                 "4,         4,         4,         4,         4,         4,
7066                  4,         4,         4,         4,         8,         4,
7067                  4,         4,         4,         4")])
7070 ;; Here is how to move condition codes around.  When we store CC data in
7071 ;; an integer register or memory, we store just the high-order 4 bits.
7072 ;; This lets us not shift in the most common case of CR0.
7073 (define_expand "movcc"
7074   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7075         (match_operand:CC 1 "nonimmediate_operand" ""))]
7076   ""
7077   "")
7079 (define_insn "*movcc_internal1"
7080   [(set (match_operand:CC 0 "nonimmediate_operand"
7081                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7082         (match_operand:CC 1 "general_operand"
7083                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7084   "register_operand (operands[0], CCmode)
7085    || register_operand (operands[1], CCmode)"
7086   "@
7087    mcrf %0,%1
7088    mtcrf 128,%1
7089    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7090    crxor %0,%0,%0
7091    mfcr %0%Q1
7092    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7093    mr %0,%1
7094    li %0,%1
7095    mf%1 %0
7096    mt%0 %1
7097    lwz%U1%X1 %0,%1
7098    stw%U0%X0 %1,%0"
7099   [(set (attr "type")
7100      (cond [(eq_attr "alternative" "0,3")
7101                 (const_string "cr_logical")
7102             (eq_attr "alternative" "1,2")
7103                 (const_string "mtcr")
7104             (eq_attr "alternative" "6,7")
7105                 (const_string "integer")
7106             (eq_attr "alternative" "8")
7107                 (const_string "mfjmpr")
7108             (eq_attr "alternative" "9")
7109                 (const_string "mtjmpr")
7110             (eq_attr "alternative" "10")
7111                 (const_string "load")
7112             (eq_attr "alternative" "11")
7113                 (const_string "store")
7114             (match_test "TARGET_MFCRF")
7115                 (const_string "mfcrf")
7116            ]
7117         (const_string "mfcr")))
7118    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7120 ;; For floating-point, we normally deal with the floating-point registers
7121 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7122 ;; can produce floating-point values in fixed-point registers.  Unless the
7123 ;; value is a simple constant or already in memory, we deal with this by
7124 ;; allocating memory and copying the value explicitly via that memory location.
7126 ;; Move 32-bit binary/decimal floating point
7127 (define_expand "mov<mode>"
7128   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7129         (match_operand:FMOVE32 1 "any_operand" ""))]
7130   "<fmove_ok>"
7131   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7133 (define_split
7134   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7135         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7136   "reload_completed
7137    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7138        || (GET_CODE (operands[0]) == SUBREG
7139            && GET_CODE (SUBREG_REG (operands[0])) == REG
7140            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7141   [(set (match_dup 2) (match_dup 3))]
7142   "
7144   long l;
7146   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7148   if (! TARGET_POWERPC64)
7149     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7150   else
7151     operands[2] = gen_lowpart (SImode, operands[0]);
7153   operands[3] = gen_int_mode (l, SImode);
7156 ;; Originally, we tried to keep movsf and movsd common, but the differences
7157 ;; addressing was making it rather difficult to hide with mode attributes.  In
7158 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7159 ;; before the VSX stores meant that the register allocator would tend to do a
7160 ;; direct move to the GPR (which involves conversion from scalar to
7161 ;; vector/memory formats) to save values in the traditional Altivec registers,
7162 ;; while SDmode had problems on power6 if the GPR store was not first due to
7163 ;; the power6 not having an integer store operation.
7165 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7166 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7167 ;;      MR           MT<x>      MF<x>       NOP
7169 (define_insn "movsf_hardfloat"
7170   [(set (match_operand:SF 0 "nonimmediate_operand"
7171          "=!r,       f,         wb,         wu,        m,         wY,
7172           Z,         m,         ww,         !r,        f,         ww,
7173           !r,        *c*l,      !r,         *h")
7174         (match_operand:SF 1 "input_operand"
7175          "m,         m,         wY,         Z,         f,         wb,
7176           wu,        r,         j,          j,         f,         ww,
7177           r,         r,         *h,         0"))]
7178   "(register_operand (operands[0], SFmode)
7179    || register_operand (operands[1], SFmode))
7180    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7181    && (TARGET_ALLOW_SF_SUBREG
7182        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7183   "@
7184    lwz%U1%X1 %0,%1
7185    lfs%U1%X1 %0,%1
7186    lxssp %0,%1
7187    lxsspx %x0,%y1
7188    stfs%U0%X0 %1,%0
7189    stxssp %1,%0
7190    stxsspx %x1,%y0
7191    stw%U0%X0 %1,%0
7192    xxlxor %x0,%x0,%x0
7193    li %0,0
7194    fmr %0,%1
7195    xscpsgndp %x0,%x1,%x1
7196    mr %0,%1
7197    mt%0 %1
7198    mf%1 %0
7199    nop"
7200   [(set_attr "type"
7201         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7202          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7203          *,          mtjmpr,    mfjmpr,     *")])
7205 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7206 ;;      FMR          MR         MT%0       MF%1       NOP
7207 (define_insn "movsd_hardfloat"
7208   [(set (match_operand:SD 0 "nonimmediate_operand"
7209          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7210           f,         !r,        *c*l,      !r,        *h")
7211         (match_operand:SD 1 "input_operand"
7212          "m,         Z,         r,         wx,        r,         wh,
7213           f,         r,         r,         *h,        0"))]
7214   "(register_operand (operands[0], SDmode)
7215    || register_operand (operands[1], SDmode))
7216    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7217   "@
7218    lwz%U1%X1 %0,%1
7219    lfiwzx %0,%y1
7220    stw%U0%X0 %1,%0
7221    stfiwx %1,%y0
7222    mtvsrwz %x0,%1
7223    mfvsrwz %0,%x1
7224    fmr %0,%1
7225    mr %0,%1
7226    mt%0 %1
7227    mf%1 %0
7228    nop"
7229   [(set_attr "type"
7230         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7231          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7233 (define_insn "*mov<mode>_softfloat"
7234   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7235         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7236   "(gpc_reg_operand (operands[0], <MODE>mode)
7237    || gpc_reg_operand (operands[1], <MODE>mode))
7238    && TARGET_SOFT_FLOAT"
7239   "@
7240    mr %0,%1
7241    mt%0 %1
7242    mf%1 %0
7243    lwz%U1%X1 %0,%1
7244    stw%U0%X0 %1,%0
7245    li %0,%1
7246    lis %0,%v1
7247    #
7248    #
7249    nop"
7250   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7251    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7253 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7254 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7256 ;; Because SF values are actually stored as DF values within the vector
7257 ;; registers, we need to convert the value to the vector SF format when
7258 ;; we need to use the bits in a union or similar cases.  We only need
7259 ;; to do this transformation when the value is a vector register.  Loads,
7260 ;; stores, and transfers within GPRs are assumed to be safe.
7262 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7263 ;; no alternatives, because the call is created as part of secondary_reload,
7264 ;; and operand #2's register class is used to allocate the temporary register.
7265 ;; This function is called before reload, and it creates the temporary as
7266 ;; needed.
7268 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7269 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7270 (define_insn_and_split "movsf_from_si"
7271   [(set (match_operand:SF 0 "nonimmediate_operand"
7272             "=!r,       f,         wb,        wu,        m,         Z,
7273              Z,         wy,        ?r,        !r")
7275         (unspec:SF [(match_operand:SI 1 "input_operand" 
7276             "m,         m,         wY,        Z,         r,         f,
7277              wu,        r,         wy,        r")]
7278                    UNSPEC_SF_FROM_SI))
7280    (clobber (match_scratch:DI 2
7281             "=X,        X,         X,         X,         X,         X,
7282              X,         r,         X,         X"))]
7284   "TARGET_NO_SF_SUBREG
7285    && (register_operand (operands[0], SFmode)
7286        || register_operand (operands[1], SImode))"
7287   "@
7288    lwz%U1%X1 %0,%1
7289    lfs%U1%X1 %0,%1
7290    lxssp %0,%1
7291    lxsspx %x0,%y1
7292    stw%U0%X0 %1,%0
7293    stfiwx %1,%y0
7294    stxsiwx %x1,%y0
7295    #
7296    mfvsrwz %0,%x1
7297    mr %0,%1"
7299   "&& reload_completed
7300    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7301    && int_reg_operand_not_pseudo (operands[1], SImode)"
7302   [(const_int 0)]
7304   rtx op0 = operands[0];
7305   rtx op1 = operands[1];
7306   rtx op2 = operands[2];
7307   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7309   /* Move SF value to upper 32-bits for xscvspdpn.  */
7310   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7311   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7312   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7313   DONE;
7315   [(set_attr "length"
7316             "4,          4,         4,         4,         4,         4,
7317              4,          12,        4,         4")
7318    (set_attr "type"
7319             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7320              fpstore,    vecfloat,  mffgpr,    *")])
7323 ;; Move 64-bit binary/decimal floating point
7324 (define_expand "mov<mode>"
7325   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7326         (match_operand:FMOVE64 1 "any_operand" ""))]
7327   ""
7328   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7330 (define_split
7331   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7332         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7333   "! TARGET_POWERPC64 && reload_completed
7334    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7335        || (GET_CODE (operands[0]) == SUBREG
7336            && GET_CODE (SUBREG_REG (operands[0])) == REG
7337            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7338   [(set (match_dup 2) (match_dup 4))
7339    (set (match_dup 3) (match_dup 1))]
7340   "
7342   int endian = (WORDS_BIG_ENDIAN == 0);
7343   HOST_WIDE_INT value = INTVAL (operands[1]);
7345   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7346   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7347   operands[4] = GEN_INT (value >> 32);
7348   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7351 (define_split
7352   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7353         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7354   "! TARGET_POWERPC64 && reload_completed
7355    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7356        || (GET_CODE (operands[0]) == SUBREG
7357            && GET_CODE (SUBREG_REG (operands[0])) == REG
7358            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7359   [(set (match_dup 2) (match_dup 4))
7360    (set (match_dup 3) (match_dup 5))]
7361   "
7363   int endian = (WORDS_BIG_ENDIAN == 0);
7364   long l[2];
7366   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7368   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7369   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7370   operands[4] = gen_int_mode (l[endian], SImode);
7371   operands[5] = gen_int_mode (l[1 - endian], SImode);
7374 (define_split
7375   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7376         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7377   "TARGET_POWERPC64 && reload_completed
7378    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7379        || (GET_CODE (operands[0]) == SUBREG
7380            && GET_CODE (SUBREG_REG (operands[0])) == REG
7381            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7382   [(set (match_dup 2) (match_dup 3))]
7383   "
7385   int endian = (WORDS_BIG_ENDIAN == 0);
7386   long l[2];
7387   HOST_WIDE_INT val;
7389   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7391   operands[2] = gen_lowpart (DImode, operands[0]);
7392   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7393   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7394          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7396   operands[3] = gen_int_mode (val, DImode);
7399 ;; Don't have reload use general registers to load a constant.  It is
7400 ;; less efficient than loading the constant into an FP register, since
7401 ;; it will probably be used there.
7403 ;; The move constraints are ordered to prefer floating point registers before
7404 ;; general purpose registers to avoid doing a store and a load to get the value
7405 ;; into a floating point register when it is needed for a floating point
7406 ;; operation.  Prefer traditional floating point registers over VSX registers,
7407 ;; since the D-form version of the memory instructions does not need a GPR for
7408 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7409 ;; registers.
7411 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7412 ;; except for 0.0 which can be created on VSX with an xor instruction.
7414 (define_insn "*mov<mode>_hardfloat32"
7415   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7416         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7417   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 
7418    && (gpc_reg_operand (operands[0], <MODE>mode)
7419        || gpc_reg_operand (operands[1], <MODE>mode))"
7420   "@
7421    stfd%U0%X0 %1,%0
7422    lfd%U1%X1 %0,%1
7423    fmr %0,%1
7424    lxsd %0,%1
7425    stxsd %1,%0
7426    lxsd%U1x %x0,%y1
7427    stxsd%U0x %x1,%y0
7428    xxlor %x0,%x1,%x1
7429    xxlxor %x0,%x0,%x0
7430    #
7431    #
7432    #
7433    #"
7434   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7435    (set_attr "size" "64")
7436    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7438 (define_insn "*mov<mode>_softfloat32"
7439   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7440         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7441   "! TARGET_POWERPC64 
7442    && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7443    && (gpc_reg_operand (operands[0], <MODE>mode)
7444        || gpc_reg_operand (operands[1], <MODE>mode))"
7445   "#"
7446   [(set_attr "type" "store,load,two,*,*,*")
7447    (set_attr "length" "8,8,8,8,12,16")])
7449 ; ld/std require word-aligned displacements -> 'Y' constraint.
7450 ; List Y->r and r->Y before r->r for reload.
7451 (define_insn "*mov<mode>_hardfloat64"
7452   [(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>")
7453         (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"))]
7454   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7455    && (gpc_reg_operand (operands[0], <MODE>mode)
7456        || gpc_reg_operand (operands[1], <MODE>mode))"
7457   "@
7458    stfd%U0%X0 %1,%0
7459    lfd%U1%X1 %0,%1
7460    fmr %0,%1
7461    lxsd %0,%1
7462    stxsd %1,%0
7463    lxsd%U1x %x0,%y1
7464    stxsd%U0x %x1,%y0
7465    xxlor %x0,%x1,%x1
7466    xxlxor %x0,%x0,%x0
7467    li %0,0
7468    std%U0%X0 %1,%0
7469    ld%U1%X1 %0,%1
7470    mr %0,%1
7471    mt%0 %1
7472    mf%1 %0
7473    nop
7474    mftgpr %0,%1
7475    mffgpr %0,%1
7476    mfvsrd %0,%x1
7477    mtvsrd %x0,%1"
7478   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7479    (set_attr "size" "64")
7480    (set_attr "length" "4")])
7482 (define_insn "*mov<mode>_softfloat64"
7483   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7484         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7485   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7486    && (gpc_reg_operand (operands[0], <MODE>mode)
7487        || gpc_reg_operand (operands[1], <MODE>mode))"
7488   "@
7489    std%U0%X0 %1,%0
7490    ld%U1%X1 %0,%1
7491    mr %0,%1
7492    mt%0 %1
7493    mf%1 %0
7494    #
7495    #
7496    #
7497    nop"
7498   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7499    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7501 (define_expand "mov<mode>"
7502   [(set (match_operand:FMOVE128 0 "general_operand" "")
7503         (match_operand:FMOVE128 1 "any_operand" ""))]
7504   ""
7505   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7507 ;; It's important to list Y->r and r->Y before r->r because otherwise
7508 ;; reload, given m->r, will try to pick r->r and reload it, which
7509 ;; doesn't make progress.
7511 ;; We can't split little endian direct moves of TDmode, because the words are
7512 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7513 ;; problematical.  Don't allow direct move for this case.
7515 (define_insn_and_split "*mov<mode>_64bit_dm"
7516   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7517         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7518   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7519    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7520    && (gpc_reg_operand (operands[0], <MODE>mode)
7521        || gpc_reg_operand (operands[1], <MODE>mode))"
7522   "#"
7523   "&& reload_completed"
7524   [(pc)]
7525 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7526   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7528 (define_insn_and_split "*movtd_64bit_nodm"
7529   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7530         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7531   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7532    && (gpc_reg_operand (operands[0], TDmode)
7533        || gpc_reg_operand (operands[1], TDmode))"
7534   "#"
7535   "&& reload_completed"
7536   [(pc)]
7537 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7538   [(set_attr "length" "8,8,8,12,12,8")])
7540 (define_insn_and_split "*mov<mode>_32bit"
7541   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7542         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7543   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7544    && (FLOAT128_2REG_P (<MODE>mode)
7545        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7546        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7547    && (gpc_reg_operand (operands[0], <MODE>mode)
7548        || gpc_reg_operand (operands[1], <MODE>mode))"
7549   "#"
7550   "&& reload_completed"
7551   [(pc)]
7552 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7553   [(set_attr "length" "8,8,8,8,20,20,16")])
7555 (define_insn_and_split "*mov<mode>_softfloat"
7556   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7557         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7558   "TARGET_SOFT_FLOAT
7559    && (gpc_reg_operand (operands[0], <MODE>mode)
7560        || gpc_reg_operand (operands[1], <MODE>mode))"
7561   "#"
7562   "&& reload_completed"
7563   [(pc)]
7564 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7565   [(set_attr "length" "20,20,16")])
7567 (define_expand "extenddf<mode>2"
7568   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7569         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7570   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7572   if (FLOAT128_IEEE_P (<MODE>mode))
7573     rs6000_expand_float128_convert (operands[0], operands[1], false);
7574   else if (TARGET_VSX)
7575     {
7576       if (<MODE>mode == TFmode)
7577         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7578       else if (<MODE>mode == IFmode)
7579         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7580       else
7581         gcc_unreachable ();
7582     }
7583    else
7584     {
7585       rtx zero = gen_reg_rtx (DFmode);
7586       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7588       if (<MODE>mode == TFmode)
7589         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7590       else if (<MODE>mode == IFmode)
7591         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7592       else
7593         gcc_unreachable ();
7594     }
7595   DONE;
7598 ;; Allow memory operands for the source to be created by the combiner.
7599 (define_insn_and_split "extenddf<mode>2_fprs"
7600   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7601         (float_extend:IBM128
7602          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7603    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7604   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7605    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7606   "#"
7607   "&& reload_completed"
7608   [(set (match_dup 3) (match_dup 1))
7609    (set (match_dup 4) (match_dup 2))]
7611   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7612   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7614   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7615   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7618 (define_insn_and_split "extenddf<mode>2_vsx"
7619   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7620         (float_extend:IBM128
7621          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7622   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7623   "#"
7624   "&& reload_completed"
7625   [(set (match_dup 2) (match_dup 1))
7626    (set (match_dup 3) (match_dup 4))]
7628   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7629   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7631   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7632   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7633   operands[4] = CONST0_RTX (DFmode);
7636 (define_expand "extendsf<mode>2"
7637   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7638         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7639   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7641   if (FLOAT128_IEEE_P (<MODE>mode))
7642     rs6000_expand_float128_convert (operands[0], operands[1], false);
7643   else
7644     {
7645       rtx tmp = gen_reg_rtx (DFmode);
7646       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7647       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7648     }
7649   DONE;
7652 (define_expand "trunc<mode>df2"
7653   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7654         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7655   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7657   if (FLOAT128_IEEE_P (<MODE>mode))
7658     {
7659       rs6000_expand_float128_convert (operands[0], operands[1], false);
7660       DONE;
7661     }
7664 (define_insn_and_split "trunc<mode>df2_internal1"
7665   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7666         (float_truncate:DF
7667          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7668   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7669    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7670   "@
7671    #
7672    fmr %0,%1"
7673   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7674   [(const_int 0)]
7676   emit_note (NOTE_INSN_DELETED);
7677   DONE;
7679   [(set_attr "type" "fpsimple")])
7681 (define_insn "trunc<mode>df2_internal2"
7682   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7683         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7684   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7685    && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7686   "fadd %0,%1,%L1"
7687   [(set_attr "type" "fp")
7688    (set_attr "fp_type" "fp_addsub_d")])
7690 (define_expand "trunc<mode>sf2"
7691   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7692         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7693   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7695   if (FLOAT128_IEEE_P (<MODE>mode))
7696     rs6000_expand_float128_convert (operands[0], operands[1], false);
7697   else if (<MODE>mode == TFmode)
7698     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7699   else if (<MODE>mode == IFmode)
7700     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7701   else
7702     gcc_unreachable ();
7703   DONE;
7706 (define_insn_and_split "trunc<mode>sf2_fprs"
7707   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7708         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7709    (clobber (match_scratch:DF 2 "=d"))]
7710   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 
7711    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7712   "#"
7713   "&& reload_completed"
7714   [(set (match_dup 2)
7715         (float_truncate:DF (match_dup 1)))
7716    (set (match_dup 0)
7717         (float_truncate:SF (match_dup 2)))]
7718   "")
7720 (define_expand "floatsi<mode>2"
7721   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7722                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7723               (clobber (match_scratch:DI 2))])]
7724   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7726   rtx op0 = operands[0];
7727   rtx op1 = operands[1];
7729   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7730     ;
7731   else if (FLOAT128_IEEE_P (<MODE>mode))
7732     {
7733       rs6000_expand_float128_convert (op0, op1, false);
7734       DONE;
7735     }
7736   else
7737     {
7738       rtx tmp = gen_reg_rtx (DFmode);
7739       expand_float (tmp, op1, false);
7740       if (<MODE>mode == TFmode)
7741         emit_insn (gen_extenddftf2 (op0, tmp));
7742       else if (<MODE>mode == IFmode)
7743         emit_insn (gen_extenddfif2 (op0, tmp));
7744       else
7745         gcc_unreachable ();
7746       DONE;
7747     }
7750 ; fadd, but rounding towards zero.
7751 ; This is probably not the optimal code sequence.
7752 (define_insn "fix_trunc_helper<mode>"
7753   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7754         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7755                    UNSPEC_FIX_TRUNC_TF))
7756    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7757   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7758   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7759   [(set_attr "type" "fp")
7760    (set_attr "length" "20")])
7762 (define_expand "fix_trunc<mode>si2"
7763   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7764         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7765   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7767   rtx op0 = operands[0];
7768   rtx op1 = operands[1];
7770   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7771     ;
7772   else
7773     {
7774       if (FLOAT128_IEEE_P (<MODE>mode))
7775         rs6000_expand_float128_convert (op0, op1, false);
7776       else if (<MODE>mode == TFmode)
7777         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7778       else if (<MODE>mode == IFmode)
7779         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7780       else
7781         gcc_unreachable ();
7782       DONE;
7783     }
7786 (define_expand "fix_trunc<mode>si2_fprs"
7787   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7788                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7789               (clobber (match_dup 2))
7790               (clobber (match_dup 3))
7791               (clobber (match_dup 4))
7792               (clobber (match_dup 5))])]
7793   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7795   operands[2] = gen_reg_rtx (DFmode);
7796   operands[3] = gen_reg_rtx (DFmode);
7797   operands[4] = gen_reg_rtx (DImode);
7798   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7801 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7802   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7803         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7804    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7805    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7806    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7807    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7808   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7809   "#"
7810   ""
7811   [(pc)]
7813   rtx lowword;
7814   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7815                                          operands[3]));
7817   gcc_assert (MEM_P (operands[5]));
7818   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7820   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7821   emit_move_insn (operands[5], operands[4]);
7822   emit_move_insn (operands[0], lowword);
7823   DONE;
7826 (define_expand "fix_trunc<mode>di2"
7827   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7828         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7829   "TARGET_FLOAT128_TYPE"
7831   if (!TARGET_FLOAT128_HW)
7832     {
7833       rs6000_expand_float128_convert (operands[0], operands[1], false);
7834       DONE;
7835     }
7838 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7839   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7840         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7841   "TARGET_FLOAT128_TYPE"
7843   rs6000_expand_float128_convert (operands[0], operands[1], true);
7844   DONE;
7847 (define_expand "floatdi<mode>2"
7848   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7849         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7850   "TARGET_FLOAT128_TYPE"
7852   if (!TARGET_FLOAT128_HW)
7853     {
7854       rs6000_expand_float128_convert (operands[0], operands[1], false);
7855       DONE;
7856     }
7859 (define_expand "floatunsdi<IEEE128:mode>2"
7860   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7861         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7862   "TARGET_FLOAT128_TYPE"
7864   if (!TARGET_FLOAT128_HW)
7865     {
7866       rs6000_expand_float128_convert (operands[0], operands[1], true);
7867       DONE;
7868     }
7871 (define_expand "floatuns<IEEE128:mode>2"
7872   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7873         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7874   "TARGET_FLOAT128_TYPE"
7876   rtx op0 = operands[0];
7877   rtx op1 = operands[1];
7879   if (TARGET_FLOAT128_HW)
7880     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7881   else
7882     rs6000_expand_float128_convert (op0, op1, true);
7883   DONE;
7886 (define_expand "neg<mode>2"
7887   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7888         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7889   "FLOAT128_IEEE_P (<MODE>mode)
7890    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7891   "
7893   if (FLOAT128_IEEE_P (<MODE>mode))
7894     {
7895       if (TARGET_FLOAT128_HW)
7896         {
7897           if (<MODE>mode == TFmode)
7898             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7899           else if (<MODE>mode == KFmode)
7900             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7901           else
7902             gcc_unreachable ();
7903         }
7904       else if (TARGET_FLOAT128_TYPE)
7905         {
7906           if (<MODE>mode == TFmode)
7907             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7908           else if (<MODE>mode == KFmode)
7909             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7910           else
7911             gcc_unreachable ();
7912         }
7913       else
7914         {
7915           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7916           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7917                                                 <MODE>mode,
7918                                                 operands[1], <MODE>mode);
7920           if (target && !rtx_equal_p (target, operands[0]))
7921             emit_move_insn (operands[0], target);
7922         }
7923       DONE;
7924     }
7927 (define_insn "neg<mode>2_internal"
7928   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7929         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7930   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7931   "*
7933   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7934     return \"fneg %L0,%L1\;fneg %0,%1\";
7935   else
7936     return \"fneg %0,%1\;fneg %L0,%L1\";
7938   [(set_attr "type" "fpsimple")
7939    (set_attr "length" "8")])
7941 (define_expand "abs<mode>2"
7942   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7943         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7944   "FLOAT128_IEEE_P (<MODE>mode)
7945    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7946   "
7948   rtx label;
7950   if (FLOAT128_IEEE_P (<MODE>mode))
7951     {
7952       if (TARGET_FLOAT128_HW)
7953         {
7954           if (<MODE>mode == TFmode)
7955             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7956           else if (<MODE>mode == KFmode)
7957             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7958           else
7959             FAIL;
7960           DONE;
7961         }
7962       else if (TARGET_FLOAT128_TYPE)
7963         {
7964           if (<MODE>mode == TFmode)
7965             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7966           else if (<MODE>mode == KFmode)
7967             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7968           else
7969             FAIL;
7970           DONE;
7971         }
7972       else
7973         FAIL;
7974     }
7976   label = gen_label_rtx ();
7977   if (<MODE>mode == TFmode)
7978     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7979   else if (<MODE>mode == TFmode)
7980     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7981   else
7982     FAIL;
7983   emit_label (label);
7984   DONE;
7987 (define_expand "abs<mode>2_internal"
7988   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7989         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7990    (set (match_dup 3) (match_dup 5))
7991    (set (match_dup 5) (abs:DF (match_dup 5)))
7992    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7993    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7994                            (label_ref (match_operand 2 "" ""))
7995                            (pc)))
7996    (set (match_dup 6) (neg:DF (match_dup 6)))]
7997   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7998   "
8000   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8001   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8002   operands[3] = gen_reg_rtx (DFmode);
8003   operands[4] = gen_reg_rtx (CCFPmode);
8004   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8005   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8009 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8010 ;; register
8012 (define_expand "ieee_128bit_negative_zero"
8013   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8014   "TARGET_FLOAT128_TYPE"
8016   rtvec v = rtvec_alloc (16);
8017   int i, high;
8019   for (i = 0; i < 16; i++)
8020     RTVEC_ELT (v, i) = const0_rtx;
8022   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8023   RTVEC_ELT (v, high) = GEN_INT (0x80);
8025   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8026   DONE;
8029 ;; IEEE 128-bit negate
8031 ;; We have 2 insns here for negate and absolute value.  The first uses
8032 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8033 ;; insns, and second insn after the first split pass loads up the bit to
8034 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8035 ;; neg/abs to create the constant just once.
8037 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8038   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8039         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8040    (clobber (match_scratch:V16QI 2 "=v"))]
8041   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8042   "#"
8043   "&& 1"
8044   [(parallel [(set (match_dup 0)
8045                    (neg:IEEE128 (match_dup 1)))
8046               (use (match_dup 2))])]
8048   if (GET_CODE (operands[2]) == SCRATCH)
8049     operands[2] = gen_reg_rtx (V16QImode);
8051   operands[3] = gen_reg_rtx (V16QImode);
8052   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8054   [(set_attr "length" "8")
8055    (set_attr "type" "vecsimple")])
8057 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8058   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8059         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8060    (use (match_operand:V16QI 2 "register_operand" "v"))]
8061   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8062   "xxlxor %x0,%x1,%x2"
8063   [(set_attr "type" "veclogical")])
8065 ;; IEEE 128-bit absolute value
8066 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8067   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8068         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8069    (clobber (match_scratch:V16QI 2 "=v"))]
8070   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8071   "#"
8072   "&& 1"
8073   [(parallel [(set (match_dup 0)
8074                    (abs:IEEE128 (match_dup 1)))
8075               (use (match_dup 2))])]
8077   if (GET_CODE (operands[2]) == SCRATCH)
8078     operands[2] = gen_reg_rtx (V16QImode);
8080   operands[3] = gen_reg_rtx (V16QImode);
8081   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8083   [(set_attr "length" "8")
8084    (set_attr "type" "vecsimple")])
8086 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8087   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8088         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8089    (use (match_operand:V16QI 2 "register_operand" "v"))]
8090   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8091   "xxlandc %x0,%x1,%x2"
8092   [(set_attr "type" "veclogical")])
8094 ;; IEEE 128-bit negative absolute value
8095 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8096   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8097         (neg:IEEE128
8098          (abs:IEEE128
8099           (match_operand:IEEE128 1 "register_operand" "wa"))))
8100    (clobber (match_scratch:V16QI 2 "=v"))]
8101   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8102    && FLOAT128_IEEE_P (<MODE>mode)"
8103   "#"
8104   "&& 1"
8105   [(parallel [(set (match_dup 0)
8106                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8107               (use (match_dup 2))])]
8109   if (GET_CODE (operands[2]) == SCRATCH)
8110     operands[2] = gen_reg_rtx (V16QImode);
8112   operands[3] = gen_reg_rtx (V16QImode);
8113   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8115   [(set_attr "length" "8")
8116    (set_attr "type" "vecsimple")])
8118 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8119   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8120         (neg:IEEE128
8121          (abs:IEEE128
8122           (match_operand:IEEE128 1 "register_operand" "wa"))))
8123    (use (match_operand:V16QI 2 "register_operand" "v"))]
8124   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8125   "xxlor %x0,%x1,%x2"
8126   [(set_attr "type" "veclogical")])
8128 ;; Float128 conversion functions.  These expand to library function calls.
8129 ;; We use expand to convert from IBM double double to IEEE 128-bit
8130 ;; and trunc for the opposite.
8131 (define_expand "extendiftf2"
8132   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8133         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8134   "TARGET_FLOAT128_TYPE"
8136   rs6000_expand_float128_convert (operands[0], operands[1], false);
8137   DONE;
8140 (define_expand "extendifkf2"
8141   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8142         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8143   "TARGET_FLOAT128_TYPE"
8145   rs6000_expand_float128_convert (operands[0], operands[1], false);
8146   DONE;
8149 (define_expand "extendtfkf2"
8150   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8151         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8152   "TARGET_FLOAT128_TYPE"
8154   rs6000_expand_float128_convert (operands[0], operands[1], false);
8155   DONE;
8158 (define_expand "trunciftf2"
8159   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8160         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8161   "TARGET_FLOAT128_TYPE"
8163   rs6000_expand_float128_convert (operands[0], operands[1], false);
8164   DONE;
8167 (define_expand "truncifkf2"
8168   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8169         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8170   "TARGET_FLOAT128_TYPE"
8172   rs6000_expand_float128_convert (operands[0], operands[1], false);
8173   DONE;
8176 (define_expand "trunckftf2"
8177   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8178         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8179   "TARGET_FLOAT128_TYPE"
8181   rs6000_expand_float128_convert (operands[0], operands[1], false);
8182   DONE;
8185 (define_expand "trunctfif2"
8186   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8187         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8188   "TARGET_FLOAT128_TYPE"
8190   rs6000_expand_float128_convert (operands[0], operands[1], false);
8191   DONE;
8195 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8196 ;; must have 3 arguments, and scratch register constraint must be a single
8197 ;; constraint.
8199 ;; Reload patterns to support gpr load/store with misaligned mem.
8200 ;; and multiple gpr load/store at offset >= 0xfffc
8201 (define_expand "reload_<mode>_store"
8202   [(parallel [(match_operand 0 "memory_operand" "=m")
8203               (match_operand 1 "gpc_reg_operand" "r")
8204               (match_operand:GPR 2 "register_operand" "=&b")])]
8205   ""
8207   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8208   DONE;
8211 (define_expand "reload_<mode>_load"
8212   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8213               (match_operand 1 "memory_operand" "m")
8214               (match_operand:GPR 2 "register_operand" "=b")])]
8215   ""
8217   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8218   DONE;
8222 ;; Reload patterns for various types using the vector registers.  We may need
8223 ;; an additional base register to convert the reg+offset addressing to reg+reg
8224 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8225 ;; index register for gpr registers.
8226 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8227   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8228               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8229               (match_operand:P 2 "register_operand" "=b")])]
8230   "<P:tptrsize>"
8232   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8233   DONE;
8236 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8237   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8238               (match_operand:RELOAD 1 "memory_operand" "m")
8239               (match_operand:P 2 "register_operand" "=b")])]
8240   "<P:tptrsize>"
8242   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8243   DONE;
8247 ;; Reload sometimes tries to move the address to a GPR, and can generate
8248 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8249 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8251 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8252   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8253         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8254                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8255                (const_int -16)))]
8256   "TARGET_ALTIVEC && reload_completed"
8257   "#"
8258   "&& reload_completed"
8259   [(set (match_dup 0)
8260         (plus:P (match_dup 1)
8261                 (match_dup 2)))
8262    (set (match_dup 0)
8263         (and:P (match_dup 0)
8264                (const_int -16)))])
8266 ;; Power8 merge instructions to allow direct move to/from floating point
8267 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8268 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8269 ;; value, since it is allocated in reload and not all of the flow information
8270 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8271 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8272 ;; schedule other instructions between the two instructions.
8274 (define_insn "p8_fmrgow_<mode>"
8275   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8276         (unspec:FMOVE64X [
8277                 (match_operand:DF 1 "register_operand" "d")
8278                 (match_operand:DF 2 "register_operand" "d")]
8279                          UNSPEC_P8V_FMRGOW))]
8280   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8281   "fmrgow %0,%1,%2"
8282   [(set_attr "type" "fpsimple")])
8284 (define_insn "p8_mtvsrwz"
8285   [(set (match_operand:DF 0 "register_operand" "=d")
8286         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8287                    UNSPEC_P8V_MTVSRWZ))]
8288   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8289   "mtvsrwz %x0,%1"
8290   [(set_attr "type" "mftgpr")])
8292 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8293   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8294         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8295                          UNSPEC_P8V_RELOAD_FROM_GPR))
8296    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8297   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8298   "#"
8299   "&& reload_completed"
8300   [(const_int 0)]
8302   rtx dest = operands[0];
8303   rtx src = operands[1];
8304   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8305   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8306   rtx gpr_hi_reg = gen_highpart (SImode, src);
8307   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8309   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8310   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8311   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8312   DONE;
8314   [(set_attr "length" "12")
8315    (set_attr "type" "three")])
8317 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8318 (define_insn "p8_mtvsrd_df"
8319   [(set (match_operand:DF 0 "register_operand" "=wa")
8320         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8321                    UNSPEC_P8V_MTVSRD))]
8322   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8323   "mtvsrd %x0,%1"
8324   [(set_attr "type" "mftgpr")])
8326 (define_insn "p8_xxpermdi_<mode>"
8327   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8328         (unspec:FMOVE128_GPR [
8329                 (match_operand:DF 1 "register_operand" "wa")
8330                 (match_operand:DF 2 "register_operand" "wa")]
8331                 UNSPEC_P8V_XXPERMDI))]
8332   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8333   "xxpermdi %x0,%x1,%x2,0"
8334   [(set_attr "type" "vecperm")])
8336 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8337   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8338         (unspec:FMOVE128_GPR
8339          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8340          UNSPEC_P8V_RELOAD_FROM_GPR))
8341    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8342   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8343   "#"
8344   "&& reload_completed"
8345   [(const_int 0)]
8347   rtx dest = operands[0];
8348   rtx src = operands[1];
8349   /* You might think that we could use op0 as one temp and a DF clobber
8350      as op2, but you'd be wrong.  Secondary reload move patterns don't
8351      check for overlap of the clobber and the destination.  */
8352   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8353   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8354   rtx gpr_hi_reg = gen_highpart (DImode, src);
8355   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8357   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8358   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8359   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8360   DONE;
8362   [(set_attr "length" "12")
8363    (set_attr "type" "three")])
8365 (define_split
8366   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8367         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8368   "reload_completed
8369    && (int_reg_operand (operands[0], <MODE>mode)
8370        || int_reg_operand (operands[1], <MODE>mode))
8371    && (!TARGET_DIRECT_MOVE_128
8372        || (!vsx_register_operand (operands[0], <MODE>mode)
8373            && !vsx_register_operand (operands[1], <MODE>mode)))"
8374   [(pc)]
8375 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8377 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8378 ;; type is stored internally as double precision in the VSX registers, we have
8379 ;; to convert it from the vector format.
8380 (define_insn "p8_mtvsrd_sf"
8381   [(set (match_operand:SF 0 "register_operand" "=wa")
8382         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8383                    UNSPEC_P8V_MTVSRD))]
8384   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8385   "mtvsrd %x0,%1"
8386   [(set_attr "type" "mftgpr")])
8388 (define_insn_and_split "reload_vsx_from_gprsf"
8389   [(set (match_operand:SF 0 "register_operand" "=wa")
8390         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8391                    UNSPEC_P8V_RELOAD_FROM_GPR))
8392    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8393   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8394   "#"
8395   "&& reload_completed"
8396   [(const_int 0)]
8398   rtx op0 = operands[0];
8399   rtx op1 = operands[1];
8400   rtx op2 = operands[2];
8401   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8403   /* Move SF value to upper 32-bits for xscvspdpn.  */
8404   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8405   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8406   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8407   DONE;
8409   [(set_attr "length" "8")
8410    (set_attr "type" "two")])
8412 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8413 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8414 ;; and then doing a move of that.
8415 (define_insn "p8_mfvsrd_3_<mode>"
8416   [(set (match_operand:DF 0 "register_operand" "=r")
8417         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8418                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8419   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8420   "mfvsrd %0,%x1"
8421   [(set_attr "type" "mftgpr")])
8423 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8424   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8425         (unspec:FMOVE128_GPR
8426          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8427          UNSPEC_P8V_RELOAD_FROM_VSX))
8428    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8429   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8430   "#"
8431   "&& reload_completed"
8432   [(const_int 0)]
8434   rtx dest = operands[0];
8435   rtx src = operands[1];
8436   rtx tmp = operands[2];
8437   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8438   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8440   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8441   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8442   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8443   DONE;
8445   [(set_attr "length" "12")
8446    (set_attr "type" "three")])
8448 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8449 ;; type is stored internally as double precision, we have to convert it to the
8450 ;; vector format.
8452 (define_insn_and_split "reload_gpr_from_vsxsf"
8453   [(set (match_operand:SF 0 "register_operand" "=r")
8454         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8455                    UNSPEC_P8V_RELOAD_FROM_VSX))
8456    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8457   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8458   "#"
8459   "&& reload_completed"
8460   [(const_int 0)]
8462   rtx op0 = operands[0];
8463   rtx op1 = operands[1];
8464   rtx op2 = operands[2];
8465   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8466   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8468   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8469   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8470   DONE;
8472   [(set_attr "length" "8")
8473    (set_attr "type" "two")])
8476 ;; Next come the multi-word integer load and store and the load and store
8477 ;; multiple insns.
8479 ;; List r->r after r->Y, otherwise reload will try to reload a
8480 ;; non-offsettable address by using r->r which won't make progress.
8481 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8482 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8484 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8485 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8486 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8487 ;;        AVX const  
8489 (define_insn "*movdi_internal32"
8490   [(set (match_operand:DI 0 "nonimmediate_operand"
8491          "=Y,        r,         r,         ^m,        ^d,         ^d,
8492           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8493           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8494           *wv")
8496         (match_operand:DI 1 "input_operand"
8497           "r,        Y,         r,         d,         m,          d,
8498            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8499            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8500            wB"))]
8502   "! TARGET_POWERPC64
8503    && (gpc_reg_operand (operands[0], DImode)
8504        || gpc_reg_operand (operands[1], DImode))"
8505   "@
8506    #
8507    #
8508    #
8509    stfd%U0%X0 %1,%0
8510    lfd%U1%X1 %0,%1
8511    fmr %0,%1
8512    #
8513    stxsd %1,%0
8514    stxsdx %x1,%y0
8515    lxsd %0,%1
8516    lxsdx %x0,%y1
8517    xxlor %x0,%x1,%x1
8518    xxspltib %x0,0
8519    xxspltib %x0,255
8520    vspltisw %0,%1
8521    xxlxor %x0,%x0,%x0
8522    xxlorc %x0,%x0,%x0
8523    #
8524    #"
8525   [(set_attr "type"
8526                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8527                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8528                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8529                 vecsimple")
8530    (set_attr "size" "64")])
8532 (define_split
8533   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8534         (match_operand:DI 1 "const_int_operand" ""))]
8535   "! TARGET_POWERPC64 && reload_completed
8536    && gpr_or_gpr_p (operands[0], operands[1])
8537    && !direct_move_p (operands[0], operands[1])"
8538   [(set (match_dup 2) (match_dup 4))
8539    (set (match_dup 3) (match_dup 1))]
8540   "
8542   HOST_WIDE_INT value = INTVAL (operands[1]);
8543   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8544                                        DImode);
8545   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8546                                        DImode);
8547   operands[4] = GEN_INT (value >> 32);
8548   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8551 (define_split
8552   [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
8553         (match_operand:DIFD 1 "input_operand" ""))]
8554   "reload_completed && !TARGET_POWERPC64
8555    && gpr_or_gpr_p (operands[0], operands[1])
8556    && !direct_move_p (operands[0], operands[1])"
8557   [(pc)]
8558 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8560 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8561 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8562 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8563 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8564 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8565 (define_insn "*movdi_internal64"
8566   [(set (match_operand:DI 0 "nonimmediate_operand"
8567                "=Y,        r,         r,         r,         r,          r,
8568                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8569                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8570                 *wi,       *wv,       *wv,       r,         *h,         *h,
8571                 ?*r,       ?*wg,      ?*r,       ?*wj")
8573         (match_operand:DI 1 "input_operand"
8574                 "r,        Y,         r,         I,         L,          nF,
8575                  d,        m,         d,         wb,        wv,         wY,
8576                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8577                  wM,       wS,        wB,        *h,        r,          0,
8578                  wg,       r,         wj,        r"))]
8580   "TARGET_POWERPC64
8581    && (gpc_reg_operand (operands[0], DImode)
8582        || gpc_reg_operand (operands[1], DImode))"
8583   "@
8584    std%U0%X0 %1,%0
8585    ld%U1%X1 %0,%1
8586    mr %0,%1
8587    li %0,%1
8588    lis %0,%v1
8589    #
8590    stfd%U0%X0 %1,%0
8591    lfd%U1%X1 %0,%1
8592    fmr %0,%1
8593    stxsd %1,%0
8594    stxsdx %x1,%y0
8595    lxsd %0,%1
8596    lxsdx %x0,%y1
8597    xxlor %x0,%x1,%x1
8598    xxspltib %x0,0
8599    xxspltib %x0,255
8600    #
8601    xxlxor %x0,%x0,%x0
8602    xxlorc %x0,%x0,%x0
8603    #
8604    #
8605    mf%1 %0
8606    mt%0 %1
8607    nop
8608    mftgpr %0,%1
8609    mffgpr %0,%1
8610    mfvsrd %0,%x1
8611    mtvsrd %x0,%1"
8612   [(set_attr "type"
8613                "store,      load,       *,         *,         *,         *,
8614                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8615                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8616                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8617                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8619    (set_attr "size" "64")
8620    (set_attr "length"
8621                "4,         4,         4,         4,         4,          20,
8622                 4,         4,         4,         4,         4,          4,
8623                 4,         4,         4,         4,         4,          8,
8624                 8,         4,         4,         4,         4,          4,
8625                 4,         4,         4,         4")])
8627 ; Some DImode loads are best done as a load of -1 followed by a mask
8628 ; instruction.
8629 (define_split
8630   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8631         (match_operand:DI 1 "const_int_operand"))]
8632   "TARGET_POWERPC64
8633    && num_insns_constant (operands[1], DImode) > 1
8634    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8635    && rs6000_is_valid_and_mask (operands[1], DImode)"
8636   [(set (match_dup 0)
8637         (const_int -1))
8638    (set (match_dup 0)
8639         (and:DI (match_dup 0)
8640                 (match_dup 1)))]
8641   "")
8643 ;; Split a load of a large constant into the appropriate five-instruction
8644 ;; sequence.  Handle anything in a constant number of insns.
8645 ;; When non-easy constants can go in the TOC, this should use
8646 ;; easy_fp_constant predicate.
8647 (define_split
8648   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8649         (match_operand:DI 1 "const_int_operand" ""))]
8650   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8651   [(set (match_dup 0) (match_dup 2))
8652    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8653   "
8655   if (rs6000_emit_set_const (operands[0], operands[1]))
8656     DONE;
8657   else
8658     FAIL;
8661 (define_split
8662   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8663         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8664   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8665   [(set (match_dup 0) (match_dup 2))
8666    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8667   "
8669   if (rs6000_emit_set_const (operands[0], operands[1]))
8670     DONE;
8671   else
8672     FAIL;
8675 (define_split
8676   [(set (match_operand:DI 0 "altivec_register_operand" "")
8677         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8678   "TARGET_VSX && reload_completed"
8679   [(const_int 0)]
8681   rtx op0 = operands[0];
8682   rtx op1 = operands[1];
8683   int r = REGNO (op0);
8684   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8686   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8687   if (op1 != const0_rtx && op1 != constm1_rtx)
8688     {
8689       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8690       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8691     }
8692   DONE;
8695 ;; Split integer constants that can be loaded with XXSPLTIB and a
8696 ;; sign extend operation.
8697 (define_split
8698   [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8699         (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8700   "TARGET_P9_VECTOR && reload_completed"
8701   [(const_int 0)]
8703   rtx op0 = operands[0];
8704   rtx op1 = operands[1];
8705   int r = REGNO (op0);
8706   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8708   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8709   if (<MODE>mode == DImode)
8710     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8711   else if (<MODE>mode == SImode)
8712     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8713   else if (<MODE>mode == HImode)
8714     {
8715       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8716       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8717     }
8718   DONE;
8722 ;; TImode/PTImode is similar, except that we usually want to compute the
8723 ;; address into a register and use lsi/stsi (the exception is during reload).
8725 (define_insn "*mov<mode>_string"
8726   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8727         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8728   "! TARGET_POWERPC64
8729    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8730    && (gpc_reg_operand (operands[0], <MODE>mode)
8731        || gpc_reg_operand (operands[1], <MODE>mode))"
8732   "*
8734   switch (which_alternative)
8735     {
8736     default:
8737       gcc_unreachable ();
8738     case 0:
8739       if (TARGET_STRING)
8740         return \"stswi %1,%P0,16\";
8741       /* FALLTHRU */
8742     case 1:
8743       return \"#\";
8744     case 2:
8745       /* If the address is not used in the output, we can use lsi.  Otherwise,
8746          fall through to generating four loads.  */
8747       if (TARGET_STRING
8748           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8749         return \"lswi %0,%P1,16\";
8750       /* fall through */
8751     case 3:
8752     case 4:
8753     case 5:
8754       return \"#\";
8755     }
8757   [(set_attr "type" "store,store,load,load,*,*")
8758    (set_attr "update" "yes")
8759    (set_attr "indexed" "yes")
8760    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8761                                           (const_string "always")
8762                                           (const_string "conditional")))])
8764 (define_insn "*mov<mode>_ppc64"
8765   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8766         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8767   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8768    && (gpc_reg_operand (operands[0], <MODE>mode)
8769        || gpc_reg_operand (operands[1], <MODE>mode)))"
8771   return rs6000_output_move_128bit (operands);
8773   [(set_attr "type" "store,store,load,load,*,*")
8774    (set_attr "length" "8")])
8776 (define_split
8777   [(set (match_operand:TI2 0 "int_reg_operand" "")
8778         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8779   "TARGET_POWERPC64
8780    && (VECTOR_MEM_NONE_P (<MODE>mode)
8781        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8782   [(set (match_dup 2) (match_dup 4))
8783    (set (match_dup 3) (match_dup 5))]
8784   "
8786   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8787                                        <MODE>mode);
8788   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8789                                        <MODE>mode);
8790   if (CONST_WIDE_INT_P (operands[1]))
8791     {
8792       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8793       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8794     }
8795   else if (CONST_INT_P (operands[1]))
8796     {
8797       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8798       operands[5] = operands[1];
8799     }
8800   else
8801     FAIL;
8804 (define_split
8805   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8806         (match_operand:TI2 1 "input_operand" ""))]
8807   "reload_completed
8808    && gpr_or_gpr_p (operands[0], operands[1])
8809    && !direct_move_p (operands[0], operands[1])
8810    && !quad_load_store_p (operands[0], operands[1])"
8811   [(pc)]
8812 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8814 (define_expand "load_multiple"
8815   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8816                           (match_operand:SI 1 "" ""))
8817                      (use (match_operand:SI 2 "" ""))])]
8818   "TARGET_STRING && !TARGET_POWERPC64"
8819   "
8821   int regno;
8822   int count;
8823   rtx op1;
8824   int i;
8826   /* Support only loading a constant number of fixed-point registers from
8827      memory and only bother with this if more than two; the machine
8828      doesn't support more than eight.  */
8829   if (GET_CODE (operands[2]) != CONST_INT
8830       || INTVAL (operands[2]) <= 2
8831       || INTVAL (operands[2]) > 8
8832       || GET_CODE (operands[1]) != MEM
8833       || GET_CODE (operands[0]) != REG
8834       || REGNO (operands[0]) >= 32)
8835     FAIL;
8837   count = INTVAL (operands[2]);
8838   regno = REGNO (operands[0]);
8840   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8841   op1 = replace_equiv_address (operands[1],
8842                                force_reg (SImode, XEXP (operands[1], 0)));
8844   for (i = 0; i < count; i++)
8845     XVECEXP (operands[3], 0, i)
8846       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8847                      adjust_address_nv (op1, SImode, i * 4));
8850 (define_insn "*ldmsi8"
8851   [(match_parallel 0 "load_multiple_operation"
8852     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8853           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8854      (set (match_operand:SI 3 "gpc_reg_operand" "")
8855           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8856      (set (match_operand:SI 4 "gpc_reg_operand" "")
8857           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8858      (set (match_operand:SI 5 "gpc_reg_operand" "")
8859           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8860      (set (match_operand:SI 6 "gpc_reg_operand" "")
8861           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8862      (set (match_operand:SI 7 "gpc_reg_operand" "")
8863           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8864      (set (match_operand:SI 8 "gpc_reg_operand" "")
8865           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8866      (set (match_operand:SI 9 "gpc_reg_operand" "")
8867           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8868   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8869   "*
8870 { return rs6000_output_load_multiple (operands); }"
8871   [(set_attr "type" "load")
8872    (set_attr "update" "yes")
8873    (set_attr "indexed" "yes")
8874    (set_attr "length" "32")])
8876 (define_insn "*ldmsi7"
8877   [(match_parallel 0 "load_multiple_operation"
8878     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8879           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8880      (set (match_operand:SI 3 "gpc_reg_operand" "")
8881           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8882      (set (match_operand:SI 4 "gpc_reg_operand" "")
8883           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8884      (set (match_operand:SI 5 "gpc_reg_operand" "")
8885           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8886      (set (match_operand:SI 6 "gpc_reg_operand" "")
8887           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8888      (set (match_operand:SI 7 "gpc_reg_operand" "")
8889           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8890      (set (match_operand:SI 8 "gpc_reg_operand" "")
8891           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8892   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8893   "*
8894 { return rs6000_output_load_multiple (operands); }"
8895   [(set_attr "type" "load")
8896    (set_attr "update" "yes")
8897    (set_attr "indexed" "yes")
8898    (set_attr "length" "32")])
8900 (define_insn "*ldmsi6"
8901   [(match_parallel 0 "load_multiple_operation"
8902     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8903           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8904      (set (match_operand:SI 3 "gpc_reg_operand" "")
8905           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8906      (set (match_operand:SI 4 "gpc_reg_operand" "")
8907           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8908      (set (match_operand:SI 5 "gpc_reg_operand" "")
8909           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8910      (set (match_operand:SI 6 "gpc_reg_operand" "")
8911           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8912      (set (match_operand:SI 7 "gpc_reg_operand" "")
8913           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8914   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8915   "*
8916 { return rs6000_output_load_multiple (operands); }"
8917   [(set_attr "type" "load")
8918    (set_attr "update" "yes")
8919    (set_attr "indexed" "yes")
8920    (set_attr "length" "32")])
8922 (define_insn "*ldmsi5"
8923   [(match_parallel 0 "load_multiple_operation"
8924     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8925           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8926      (set (match_operand:SI 3 "gpc_reg_operand" "")
8927           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8928      (set (match_operand:SI 4 "gpc_reg_operand" "")
8929           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8930      (set (match_operand:SI 5 "gpc_reg_operand" "")
8931           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8932      (set (match_operand:SI 6 "gpc_reg_operand" "")
8933           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8934   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8935   "*
8936 { return rs6000_output_load_multiple (operands); }"
8937   [(set_attr "type" "load")
8938    (set_attr "update" "yes")
8939    (set_attr "indexed" "yes")
8940    (set_attr "length" "32")])
8942 (define_insn "*ldmsi4"
8943   [(match_parallel 0 "load_multiple_operation"
8944     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8945           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8946      (set (match_operand:SI 3 "gpc_reg_operand" "")
8947           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8948      (set (match_operand:SI 4 "gpc_reg_operand" "")
8949           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8950      (set (match_operand:SI 5 "gpc_reg_operand" "")
8951           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8952   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8953   "*
8954 { return rs6000_output_load_multiple (operands); }"
8955   [(set_attr "type" "load")
8956    (set_attr "update" "yes")
8957    (set_attr "indexed" "yes")
8958    (set_attr "length" "32")])
8960 (define_insn "*ldmsi3"
8961   [(match_parallel 0 "load_multiple_operation"
8962     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8963           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8964      (set (match_operand:SI 3 "gpc_reg_operand" "")
8965           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8966      (set (match_operand:SI 4 "gpc_reg_operand" "")
8967           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8968   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8969   "*
8970 { return rs6000_output_load_multiple (operands); }"
8971   [(set_attr "type" "load")
8972    (set_attr "update" "yes")
8973    (set_attr "indexed" "yes")
8974    (set_attr "length" "32")])
8976 (define_expand "store_multiple"
8977   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8978                           (match_operand:SI 1 "" ""))
8979                      (clobber (scratch:SI))
8980                      (use (match_operand:SI 2 "" ""))])]
8981   "TARGET_STRING && !TARGET_POWERPC64"
8982   "
8984   int regno;
8985   int count;
8986   rtx to;
8987   rtx op0;
8988   int i;
8990   /* Support only storing a constant number of fixed-point registers to
8991      memory and only bother with this if more than two; the machine
8992      doesn't support more than eight.  */
8993   if (GET_CODE (operands[2]) != CONST_INT
8994       || INTVAL (operands[2]) <= 2
8995       || INTVAL (operands[2]) > 8
8996       || GET_CODE (operands[0]) != MEM
8997       || GET_CODE (operands[1]) != REG
8998       || REGNO (operands[1]) >= 32)
8999     FAIL;
9001   count = INTVAL (operands[2]);
9002   regno = REGNO (operands[1]);
9004   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9005   to = force_reg (SImode, XEXP (operands[0], 0));
9006   op0 = replace_equiv_address (operands[0], to);
9008   XVECEXP (operands[3], 0, 0)
9009     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9010   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9011                                                  gen_rtx_SCRATCH (SImode));
9013   for (i = 1; i < count; i++)
9014     XVECEXP (operands[3], 0, i + 1)
9015       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9016                      gen_rtx_REG (SImode, regno + i));
9019 (define_insn "*stmsi8"
9020   [(match_parallel 0 "store_multiple_operation"
9021     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9022           (match_operand:SI 2 "gpc_reg_operand" "r"))
9023      (clobber (match_scratch:SI 3 "=X"))
9024      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9025           (match_operand:SI 4 "gpc_reg_operand" "r"))
9026      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9027           (match_operand:SI 5 "gpc_reg_operand" "r"))
9028      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9029           (match_operand:SI 6 "gpc_reg_operand" "r"))
9030      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9031           (match_operand:SI 7 "gpc_reg_operand" "r"))
9032      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9033           (match_operand:SI 8 "gpc_reg_operand" "r"))
9034      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9035           (match_operand:SI 9 "gpc_reg_operand" "r"))
9036      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9037           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9038   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9039   "stswi %2,%1,%O0"
9040   [(set_attr "type" "store")
9041    (set_attr "update" "yes")
9042    (set_attr "indexed" "yes")
9043    (set_attr "cell_micro" "always")])
9045 (define_insn "*stmsi7"
9046   [(match_parallel 0 "store_multiple_operation"
9047     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9048           (match_operand:SI 2 "gpc_reg_operand" "r"))
9049      (clobber (match_scratch:SI 3 "=X"))
9050      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9051           (match_operand:SI 4 "gpc_reg_operand" "r"))
9052      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9053           (match_operand:SI 5 "gpc_reg_operand" "r"))
9054      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9055           (match_operand:SI 6 "gpc_reg_operand" "r"))
9056      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9057           (match_operand:SI 7 "gpc_reg_operand" "r"))
9058      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9059           (match_operand:SI 8 "gpc_reg_operand" "r"))
9060      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9061           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9062   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9063   "stswi %2,%1,%O0"
9064   [(set_attr "type" "store")
9065    (set_attr "update" "yes")
9066    (set_attr "indexed" "yes")
9067    (set_attr "cell_micro" "always")])
9069 (define_insn "*stmsi6"
9070   [(match_parallel 0 "store_multiple_operation"
9071     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9072           (match_operand:SI 2 "gpc_reg_operand" "r"))
9073      (clobber (match_scratch:SI 3 "=X"))
9074      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9075           (match_operand:SI 4 "gpc_reg_operand" "r"))
9076      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9077           (match_operand:SI 5 "gpc_reg_operand" "r"))
9078      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9079           (match_operand:SI 6 "gpc_reg_operand" "r"))
9080      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9081           (match_operand:SI 7 "gpc_reg_operand" "r"))
9082      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9083           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9084   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9085   "stswi %2,%1,%O0"
9086   [(set_attr "type" "store")
9087    (set_attr "update" "yes")
9088    (set_attr "indexed" "yes")
9089    (set_attr "cell_micro" "always")])
9091 (define_insn "*stmsi5"
9092   [(match_parallel 0 "store_multiple_operation"
9093     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9094           (match_operand:SI 2 "gpc_reg_operand" "r"))
9095      (clobber (match_scratch:SI 3 "=X"))
9096      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9097           (match_operand:SI 4 "gpc_reg_operand" "r"))
9098      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9099           (match_operand:SI 5 "gpc_reg_operand" "r"))
9100      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9101           (match_operand:SI 6 "gpc_reg_operand" "r"))
9102      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9103           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9104   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9105   "stswi %2,%1,%O0"
9106   [(set_attr "type" "store")
9107    (set_attr "update" "yes")
9108    (set_attr "indexed" "yes")
9109    (set_attr "cell_micro" "always")])
9111 (define_insn "*stmsi4"
9112   [(match_parallel 0 "store_multiple_operation"
9113     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9114           (match_operand:SI 2 "gpc_reg_operand" "r"))
9115      (clobber (match_scratch:SI 3 "=X"))
9116      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9117           (match_operand:SI 4 "gpc_reg_operand" "r"))
9118      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9119           (match_operand:SI 5 "gpc_reg_operand" "r"))
9120      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9121           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9122   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9123   "stswi %2,%1,%O0"
9124   [(set_attr "type" "store")
9125    (set_attr "update" "yes")
9126    (set_attr "indexed" "yes")
9127    (set_attr "cell_micro" "always")])
9129 (define_insn "*stmsi3"
9130   [(match_parallel 0 "store_multiple_operation"
9131     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9132           (match_operand:SI 2 "gpc_reg_operand" "r"))
9133      (clobber (match_scratch:SI 3 "=X"))
9134      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9135           (match_operand:SI 4 "gpc_reg_operand" "r"))
9136      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9137           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9138   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9139   "stswi %2,%1,%O0"
9140   [(set_attr "type" "store")
9141    (set_attr "update" "yes")
9142    (set_attr "indexed" "yes")
9143    (set_attr "cell_micro" "always")])
9145 (define_expand "setmemsi"
9146   [(parallel [(set (match_operand:BLK 0 "" "")
9147                    (match_operand 2 "const_int_operand" ""))
9148               (use (match_operand:SI 1 "" ""))
9149               (use (match_operand:SI 3 "" ""))])]
9150   ""
9151   "
9153   /* If value to set is not zero, use the library routine.  */
9154   if (operands[2] != const0_rtx)
9155     FAIL;
9157   if (expand_block_clear (operands))
9158     DONE;
9159   else
9160     FAIL;
9163 ;; String compare N insn.
9164 ;; Argument 0 is the target (result)
9165 ;; Argument 1 is the destination
9166 ;; Argument 2 is the source
9167 ;; Argument 3 is the length
9168 ;; Argument 4 is the alignment
9170 (define_expand "cmpstrnsi"
9171   [(parallel [(set (match_operand:SI 0)
9172                (compare:SI (match_operand:BLK 1)
9173                            (match_operand:BLK 2)))
9174               (use (match_operand:SI 3))
9175               (use (match_operand:SI 4))])]
9176   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9178   if (optimize_insn_for_size_p ())
9179     FAIL;
9181   if (expand_strn_compare (operands, 0))
9182     DONE;
9183   else  
9184     FAIL;
9187 ;; String compare insn.
9188 ;; Argument 0 is the target (result)
9189 ;; Argument 1 is the destination
9190 ;; Argument 2 is the source
9191 ;; Argument 3 is the alignment
9193 (define_expand "cmpstrsi"
9194   [(parallel [(set (match_operand:SI 0)
9195                (compare:SI (match_operand:BLK 1)
9196                            (match_operand:BLK 2)))
9197               (use (match_operand:SI 3))])]
9198   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9200   if (optimize_insn_for_size_p ())
9201     FAIL;
9203   if (expand_strn_compare (operands, 1))
9204     DONE;
9205   else  
9206     FAIL;
9209 ;; Block compare insn.
9210 ;; Argument 0 is the target (result)
9211 ;; Argument 1 is the destination
9212 ;; Argument 2 is the source
9213 ;; Argument 3 is the length
9214 ;; Argument 4 is the alignment
9216 (define_expand "cmpmemsi"
9217   [(parallel [(set (match_operand:SI 0)
9218                (compare:SI (match_operand:BLK 1)
9219                            (match_operand:BLK 2)))
9220               (use (match_operand:SI 3))
9221               (use (match_operand:SI 4))])]
9222   "TARGET_POPCNTD"
9224   if (expand_block_compare (operands))
9225     DONE;
9226   else
9227     FAIL;
9230 ;; String/block move insn.
9231 ;; Argument 0 is the destination
9232 ;; Argument 1 is the source
9233 ;; Argument 2 is the length
9234 ;; Argument 3 is the alignment
9236 (define_expand "movmemsi"
9237   [(parallel [(set (match_operand:BLK 0 "" "")
9238                    (match_operand:BLK 1 "" ""))
9239               (use (match_operand:SI 2 "" ""))
9240               (use (match_operand:SI 3 "" ""))])]
9241   ""
9242   "
9244   if (expand_block_move (operands))
9245     DONE;
9246   else
9247     FAIL;
9250 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9251 ;; register allocator doesn't have a clue about allocating 8 word registers.
9252 ;; rD/rS = r5 is preferred, efficient form.
9253 (define_expand "movmemsi_8reg"
9254   [(parallel [(set (match_operand 0 "" "")
9255                    (match_operand 1 "" ""))
9256               (use (match_operand 2 "" ""))
9257               (use (match_operand 3 "" ""))
9258               (clobber (reg:SI  5))
9259               (clobber (reg:SI  6))
9260               (clobber (reg:SI  7))
9261               (clobber (reg:SI  8))
9262               (clobber (reg:SI  9))
9263               (clobber (reg:SI 10))
9264               (clobber (reg:SI 11))
9265               (clobber (reg:SI 12))
9266               (clobber (match_scratch:SI 4 ""))])]
9267   "TARGET_STRING"
9268   "")
9270 (define_insn ""
9271   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9272         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9273    (use (match_operand:SI 2 "immediate_operand" "i"))
9274    (use (match_operand:SI 3 "immediate_operand" "i"))
9275    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9276    (clobber (reg:SI  6))
9277    (clobber (reg:SI  7))
9278    (clobber (reg:SI  8))
9279    (clobber (reg:SI  9))
9280    (clobber (reg:SI 10))
9281    (clobber (reg:SI 11))
9282    (clobber (reg:SI 12))
9283    (clobber (match_scratch:SI 5 "=X"))]
9284   "TARGET_STRING
9285    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9286        || INTVAL (operands[2]) == 0)
9287    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9288    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9289    && REGNO (operands[4]) == 5"
9290   "lswi %4,%1,%2\;stswi %4,%0,%2"
9291   [(set_attr "type" "store")
9292    (set_attr "update" "yes")
9293    (set_attr "indexed" "yes")
9294    (set_attr "cell_micro" "always")
9295    (set_attr "length" "8")])
9297 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9298 ;; register allocator doesn't have a clue about allocating 6 word registers.
9299 ;; rD/rS = r5 is preferred, efficient form.
9300 (define_expand "movmemsi_6reg"
9301   [(parallel [(set (match_operand 0 "" "")
9302                    (match_operand 1 "" ""))
9303               (use (match_operand 2 "" ""))
9304               (use (match_operand 3 "" ""))
9305               (clobber (reg:SI  5))
9306               (clobber (reg:SI  6))
9307               (clobber (reg:SI  7))
9308               (clobber (reg:SI  8))
9309               (clobber (reg:SI  9))
9310               (clobber (reg:SI 10))
9311               (clobber (match_scratch:SI 4 ""))])]
9312   "TARGET_STRING"
9313   "")
9315 (define_insn ""
9316   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9317         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9318    (use (match_operand:SI 2 "immediate_operand" "i"))
9319    (use (match_operand:SI 3 "immediate_operand" "i"))
9320    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9321    (clobber (reg:SI  6))
9322    (clobber (reg:SI  7))
9323    (clobber (reg:SI  8))
9324    (clobber (reg:SI  9))
9325    (clobber (reg:SI 10))
9326    (clobber (match_scratch:SI 5 "=X"))]
9327   "TARGET_STRING
9328    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9329    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9330    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9331    && REGNO (operands[4]) == 5"
9332   "lswi %4,%1,%2\;stswi %4,%0,%2"
9333   [(set_attr "type" "store")
9334    (set_attr "update" "yes")
9335    (set_attr "indexed" "yes")
9336    (set_attr "cell_micro" "always")
9337    (set_attr "length" "8")])
9339 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9340 ;; problems with TImode.
9341 ;; rD/rS = r5 is preferred, efficient form.
9342 (define_expand "movmemsi_4reg"
9343   [(parallel [(set (match_operand 0 "" "")
9344                    (match_operand 1 "" ""))
9345               (use (match_operand 2 "" ""))
9346               (use (match_operand 3 "" ""))
9347               (clobber (reg:SI 5))
9348               (clobber (reg:SI 6))
9349               (clobber (reg:SI 7))
9350               (clobber (reg:SI 8))
9351               (clobber (match_scratch:SI 4 ""))])]
9352   "TARGET_STRING"
9353   "")
9355 (define_insn ""
9356   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9357         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9358    (use (match_operand:SI 2 "immediate_operand" "i"))
9359    (use (match_operand:SI 3 "immediate_operand" "i"))
9360    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9361    (clobber (reg:SI 6))
9362    (clobber (reg:SI 7))
9363    (clobber (reg:SI 8))
9364    (clobber (match_scratch:SI 5 "=X"))]
9365   "TARGET_STRING
9366    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9367    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9368    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9369    && REGNO (operands[4]) == 5"
9370   "lswi %4,%1,%2\;stswi %4,%0,%2"
9371   [(set_attr "type" "store")
9372    (set_attr "update" "yes")
9373    (set_attr "indexed" "yes")
9374    (set_attr "cell_micro" "always")
9375    (set_attr "length" "8")])
9377 ;; Move up to 8 bytes at a time.
9378 (define_expand "movmemsi_2reg"
9379   [(parallel [(set (match_operand 0 "" "")
9380                    (match_operand 1 "" ""))
9381               (use (match_operand 2 "" ""))
9382               (use (match_operand 3 "" ""))
9383               (clobber (match_scratch:DI 4 ""))
9384               (clobber (match_scratch:SI 5 ""))])]
9385   "TARGET_STRING && ! TARGET_POWERPC64"
9386   "")
9388 (define_insn ""
9389   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9390         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9391    (use (match_operand:SI 2 "immediate_operand" "i"))
9392    (use (match_operand:SI 3 "immediate_operand" "i"))
9393    (clobber (match_scratch:DI 4 "=&r"))
9394    (clobber (match_scratch:SI 5 "=X"))]
9395   "TARGET_STRING && ! TARGET_POWERPC64
9396    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9397   "lswi %4,%1,%2\;stswi %4,%0,%2"
9398   [(set_attr "type" "store")
9399    (set_attr "update" "yes")
9400    (set_attr "indexed" "yes")
9401    (set_attr "cell_micro" "always")
9402    (set_attr "length" "8")])
9404 ;; Move up to 4 bytes at a time.
9405 (define_expand "movmemsi_1reg"
9406   [(parallel [(set (match_operand 0 "" "")
9407                    (match_operand 1 "" ""))
9408               (use (match_operand 2 "" ""))
9409               (use (match_operand 3 "" ""))
9410               (clobber (match_scratch:SI 4 ""))
9411               (clobber (match_scratch:SI 5 ""))])]
9412   "TARGET_STRING"
9413   "")
9415 (define_insn ""
9416   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9417         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9418    (use (match_operand:SI 2 "immediate_operand" "i"))
9419    (use (match_operand:SI 3 "immediate_operand" "i"))
9420    (clobber (match_scratch:SI 4 "=&r"))
9421    (clobber (match_scratch:SI 5 "=X"))]
9422   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9423   "lswi %4,%1,%2\;stswi %4,%0,%2"
9424   [(set_attr "type" "store")
9425    (set_attr "update" "yes")
9426    (set_attr "indexed" "yes")
9427    (set_attr "cell_micro" "always")
9428    (set_attr "length" "8")])
9430 ;; Define insns that do load or store with update.  Some of these we can
9431 ;; get by using pre-decrement or pre-increment, but the hardware can also
9432 ;; do cases where the increment is not the size of the object.
9434 ;; In all these cases, we use operands 0 and 1 for the register being
9435 ;; incremented because those are the operands that local-alloc will
9436 ;; tie and these are the pair most likely to be tieable (and the ones
9437 ;; that will benefit the most).
9439 (define_insn "*movdi_update1"
9440   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9441         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9442                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9443    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9444         (plus:DI (match_dup 1) (match_dup 2)))]
9445   "TARGET_POWERPC64 && TARGET_UPDATE
9446    && (!avoiding_indexed_address_p (DImode)
9447        || !gpc_reg_operand (operands[2], DImode))"
9448   "@
9449    ldux %3,%0,%2
9450    ldu %3,%2(%0)"
9451   [(set_attr "type" "load")
9452    (set_attr "update" "yes")
9453    (set_attr "indexed" "yes,no")])
9455 (define_insn "movdi_<mode>_update"
9456   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9457                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9458         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9459    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9460         (plus:P (match_dup 1) (match_dup 2)))]
9461   "TARGET_POWERPC64 && TARGET_UPDATE
9462    && (!avoiding_indexed_address_p (Pmode)
9463        || !gpc_reg_operand (operands[2], Pmode)
9464        || (REG_P (operands[0])
9465            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9466   "@
9467    stdux %3,%0,%2
9468    stdu %3,%2(%0)"
9469   [(set_attr "type" "store")
9470    (set_attr "update" "yes")
9471    (set_attr "indexed" "yes,no")])
9473 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9474 ;; needed for stack allocation, even if the user passes -mno-update.
9475 (define_insn "movdi_<mode>_update_stack"
9476   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9477                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9478         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9479    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9480         (plus:P (match_dup 1) (match_dup 2)))]
9481   "TARGET_POWERPC64"
9482   "@
9483    stdux %3,%0,%2
9484    stdu %3,%2(%0)"
9485   [(set_attr "type" "store")
9486    (set_attr "update" "yes")
9487    (set_attr "indexed" "yes,no")])
9489 (define_insn "*movsi_update1"
9490   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9491         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9492                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9493    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9494         (plus:SI (match_dup 1) (match_dup 2)))]
9495   "TARGET_UPDATE
9496    && (!avoiding_indexed_address_p (SImode)
9497        || !gpc_reg_operand (operands[2], SImode))"
9498   "@
9499    lwzux %3,%0,%2
9500    lwzu %3,%2(%0)"
9501   [(set_attr "type" "load")
9502    (set_attr "update" "yes")
9503    (set_attr "indexed" "yes,no")])
9505 (define_insn "*movsi_update2"
9506   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9507         (sign_extend:DI
9508          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9509                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9510    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9511         (plus:DI (match_dup 1) (match_dup 2)))]
9512   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9513   "lwaux %3,%0,%2"
9514   [(set_attr "type" "load")
9515    (set_attr "sign_extend" "yes")
9516    (set_attr "update" "yes")
9517    (set_attr "indexed" "yes")])
9519 (define_insn "movsi_update"
9520   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9521                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9522         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9523    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9524         (plus:SI (match_dup 1) (match_dup 2)))]
9525   "TARGET_UPDATE
9526    && (!avoiding_indexed_address_p (SImode)
9527        || !gpc_reg_operand (operands[2], SImode)
9528        || (REG_P (operands[0])
9529            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9530   "@
9531    stwux %3,%0,%2
9532    stwu %3,%2(%0)"
9533   [(set_attr "type" "store")
9534    (set_attr "update" "yes")
9535    (set_attr "indexed" "yes,no")])
9537 ;; This is an unconditional pattern; needed for stack allocation, even
9538 ;; if the user passes -mno-update.
9539 (define_insn "movsi_update_stack"
9540   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9541                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9542         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9543    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9544         (plus:SI (match_dup 1) (match_dup 2)))]
9545   ""
9546   "@
9547    stwux %3,%0,%2
9548    stwu %3,%2(%0)"
9549   [(set_attr "type" "store")
9550    (set_attr "update" "yes")
9551    (set_attr "indexed" "yes,no")])
9553 (define_insn "*movhi_update1"
9554   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9555         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9556                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9557    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9558         (plus:SI (match_dup 1) (match_dup 2)))]
9559   "TARGET_UPDATE
9560    && (!avoiding_indexed_address_p (SImode)
9561        || !gpc_reg_operand (operands[2], SImode))"
9562   "@
9563    lhzux %3,%0,%2
9564    lhzu %3,%2(%0)"
9565   [(set_attr "type" "load")
9566    (set_attr "update" "yes")
9567    (set_attr "indexed" "yes,no")])
9569 (define_insn "*movhi_update2"
9570   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9571         (zero_extend:SI
9572          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9573                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9574    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9575         (plus:SI (match_dup 1) (match_dup 2)))]
9576   "TARGET_UPDATE
9577    && (!avoiding_indexed_address_p (SImode)
9578        || !gpc_reg_operand (operands[2], SImode))"
9579   "@
9580    lhzux %3,%0,%2
9581    lhzu %3,%2(%0)"
9582   [(set_attr "type" "load")
9583    (set_attr "update" "yes")
9584    (set_attr "indexed" "yes,no")])
9586 (define_insn "*movhi_update3"
9587   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9588         (sign_extend:SI
9589          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9590                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9591    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9592         (plus:SI (match_dup 1) (match_dup 2)))]
9593   "TARGET_UPDATE
9594    && !(avoiding_indexed_address_p (SImode)
9595         && gpc_reg_operand (operands[2], SImode))"
9596   "@
9597    lhaux %3,%0,%2
9598    lhau %3,%2(%0)"
9599   [(set_attr "type" "load")
9600    (set_attr "sign_extend" "yes")
9601    (set_attr "update" "yes")
9602    (set_attr "indexed" "yes,no")])
9604 (define_insn "*movhi_update4"
9605   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9606                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9607         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9608    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9609         (plus:SI (match_dup 1) (match_dup 2)))]
9610   "TARGET_UPDATE
9611    && (!avoiding_indexed_address_p (SImode)
9612        || !gpc_reg_operand (operands[2], SImode))"
9613   "@
9614    sthux %3,%0,%2
9615    sthu %3,%2(%0)"
9616   [(set_attr "type" "store")
9617    (set_attr "update" "yes")
9618    (set_attr "indexed" "yes,no")])
9620 (define_insn "*movqi_update1"
9621   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9622         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9623                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9624    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9625         (plus:SI (match_dup 1) (match_dup 2)))]
9626   "TARGET_UPDATE
9627    && (!avoiding_indexed_address_p (SImode)
9628        || !gpc_reg_operand (operands[2], SImode))"
9629   "@
9630    lbzux %3,%0,%2
9631    lbzu %3,%2(%0)"
9632   [(set_attr "type" "load")
9633    (set_attr "update" "yes")
9634    (set_attr "indexed" "yes,no")])
9636 (define_insn "*movqi_update2"
9637   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9638         (zero_extend:SI
9639          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9640                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9641    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9642         (plus:SI (match_dup 1) (match_dup 2)))]
9643   "TARGET_UPDATE
9644    && (!avoiding_indexed_address_p (SImode)
9645        || !gpc_reg_operand (operands[2], SImode))"
9646   "@
9647    lbzux %3,%0,%2
9648    lbzu %3,%2(%0)"
9649   [(set_attr "type" "load")
9650    (set_attr "update" "yes")
9651    (set_attr "indexed" "yes,no")])
9653 (define_insn "*movqi_update3"
9654   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9655                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9656         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9657    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9658         (plus:SI (match_dup 1) (match_dup 2)))]
9659   "TARGET_UPDATE
9660    && (!avoiding_indexed_address_p (SImode)
9661        || !gpc_reg_operand (operands[2], SImode))"
9662   "@
9663    stbux %3,%0,%2
9664    stbu %3,%2(%0)"
9665   [(set_attr "type" "store")
9666    (set_attr "update" "yes")
9667    (set_attr "indexed" "yes,no")])
9669 (define_insn "*movsf_update1"
9670   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9671         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9672                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9673    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9674         (plus:SI (match_dup 1) (match_dup 2)))]
9675   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9676    && (!avoiding_indexed_address_p (SImode)
9677        || !gpc_reg_operand (operands[2], SImode))"
9678   "@
9679    lfsux %3,%0,%2
9680    lfsu %3,%2(%0)"
9681   [(set_attr "type" "fpload")
9682    (set_attr "update" "yes")
9683    (set_attr "indexed" "yes,no")])
9685 (define_insn "*movsf_update2"
9686   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9687                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9688         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9689    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9690         (plus:SI (match_dup 1) (match_dup 2)))]
9691   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9692    && (!avoiding_indexed_address_p (SImode)
9693        || !gpc_reg_operand (operands[2], SImode))"
9694   "@
9695    stfsux %3,%0,%2
9696    stfsu %3,%2(%0)"
9697   [(set_attr "type" "fpstore")
9698    (set_attr "update" "yes")
9699    (set_attr "indexed" "yes,no")])
9701 (define_insn "*movsf_update3"
9702   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9703         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9704                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9705    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9706         (plus:SI (match_dup 1) (match_dup 2)))]
9707   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9708    && (!avoiding_indexed_address_p (SImode)
9709        || !gpc_reg_operand (operands[2], SImode))"
9710   "@
9711    lwzux %3,%0,%2
9712    lwzu %3,%2(%0)"
9713   [(set_attr "type" "load")
9714    (set_attr "update" "yes")
9715    (set_attr "indexed" "yes,no")])
9717 (define_insn "*movsf_update4"
9718   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9719                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9720         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9721    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9722         (plus:SI (match_dup 1) (match_dup 2)))]
9723   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9724    && (!avoiding_indexed_address_p (SImode)
9725        || !gpc_reg_operand (operands[2], SImode))"
9726   "@
9727    stwux %3,%0,%2
9728    stwu %3,%2(%0)"
9729   [(set_attr "type" "store")
9730    (set_attr "update" "yes")
9731    (set_attr "indexed" "yes,no")])
9733 (define_insn "*movdf_update1"
9734   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9735         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9736                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9737    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9738         (plus:SI (match_dup 1) (match_dup 2)))]
9739   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9740    && (!avoiding_indexed_address_p (SImode)
9741        || !gpc_reg_operand (operands[2], SImode))"
9742   "@
9743    lfdux %3,%0,%2
9744    lfdu %3,%2(%0)"
9745   [(set_attr "type" "fpload")
9746    (set_attr "update" "yes")
9747    (set_attr "indexed" "yes,no")
9748    (set_attr "size" "64")])
9750 (define_insn "*movdf_update2"
9751   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9752                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9753         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9754    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9755         (plus:SI (match_dup 1) (match_dup 2)))]
9756   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9757    && (!avoiding_indexed_address_p (SImode)
9758        || !gpc_reg_operand (operands[2], SImode))"
9759   "@
9760    stfdux %3,%0,%2
9761    stfdu %3,%2(%0)"
9762   [(set_attr "type" "fpstore")
9763    (set_attr "update" "yes")
9764    (set_attr "indexed" "yes,no")])
9767 ;; After inserting conditional returns we can sometimes have
9768 ;; unnecessary register moves.  Unfortunately we cannot have a
9769 ;; modeless peephole here, because some single SImode sets have early
9770 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9771 ;; sequences, using get_attr_length here will smash the operands
9772 ;; array.  Neither is there an early_cobbler_p predicate.
9773 ;; Also this optimization interferes with scalars going into
9774 ;; altivec registers (the code does reloading through the FPRs).
9775 (define_peephole2
9776   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9777         (match_operand:DF 1 "any_operand" ""))
9778    (set (match_operand:DF 2 "gpc_reg_operand" "")
9779         (match_dup 0))]
9780   "!TARGET_VSX
9781    && peep2_reg_dead_p (2, operands[0])"
9782   [(set (match_dup 2) (match_dup 1))])
9784 (define_peephole2
9785   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9786         (match_operand:SF 1 "any_operand" ""))
9787    (set (match_operand:SF 2 "gpc_reg_operand" "")
9788         (match_dup 0))]
9789   "!TARGET_P8_VECTOR
9790    && peep2_reg_dead_p (2, operands[0])"
9791   [(set (match_dup 2) (match_dup 1))])
9794 ;; TLS support.
9796 ;; Mode attributes for different ABIs.
9797 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9798 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9799 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9800 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9802 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9803   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9804         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9805               (match_operand 4 "" "g")))
9806    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9807                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9808                    UNSPEC_TLSGD)
9809    (clobber (reg:SI LR_REGNO))]
9810   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9812   if (TARGET_CMODEL != CMODEL_SMALL)
9813     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9814            "bl %z3\;nop";
9815   else
9816     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9818   "&& TARGET_TLS_MARKERS"
9819   [(set (match_dup 0)
9820         (unspec:TLSmode [(match_dup 1)
9821                          (match_dup 2)]
9822                         UNSPEC_TLSGD))
9823    (parallel [(set (match_dup 0)
9824                    (call (mem:TLSmode (match_dup 3))
9825                          (match_dup 4)))
9826               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9827               (clobber (reg:SI LR_REGNO))])]
9828   ""
9829   [(set_attr "type" "two")
9830    (set (attr "length")
9831      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9832                    (const_int 16)
9833                    (const_int 12)))])
9835 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9836   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9837         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9838               (match_operand 4 "" "g")))
9839    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9840                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9841                    UNSPEC_TLSGD)
9842    (clobber (reg:SI LR_REGNO))]
9843   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9845   if (flag_pic)
9846     {
9847       if (TARGET_SECURE_PLT && flag_pic == 2)
9848         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9849       else
9850         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9851     }
9852   else
9853     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9855   "&& TARGET_TLS_MARKERS"
9856   [(set (match_dup 0)
9857         (unspec:TLSmode [(match_dup 1)
9858                          (match_dup 2)]
9859                         UNSPEC_TLSGD))
9860    (parallel [(set (match_dup 0)
9861                    (call (mem:TLSmode (match_dup 3))
9862                          (match_dup 4)))
9863               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9864               (clobber (reg:SI LR_REGNO))])]
9865   ""
9866   [(set_attr "type" "two")
9867    (set_attr "length" "8")])
9869 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9870   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9871         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9872                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9873                         UNSPEC_TLSGD))]
9874   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9875   "addi %0,%1,%2@got@tlsgd"
9876   "&& TARGET_CMODEL != CMODEL_SMALL"
9877   [(set (match_dup 3)
9878         (high:TLSmode
9879             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9880    (set (match_dup 0)
9881         (lo_sum:TLSmode (match_dup 3)
9882             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9883   "
9885   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9887   [(set (attr "length")
9888      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9889                    (const_int 8)
9890                    (const_int 4)))])
9892 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9893   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9894      (high:TLSmode
9895        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9896                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9897                        UNSPEC_TLSGD)))]
9898   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9899   "addis %0,%1,%2@got@tlsgd@ha"
9900   [(set_attr "length" "4")])
9902 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9903   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9904      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9905        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9906                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9907                        UNSPEC_TLSGD)))]
9908   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9909   "addi %0,%1,%2@got@tlsgd@l"
9910   [(set_attr "length" "4")])
9912 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9913   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9914         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9915               (match_operand 2 "" "g")))
9916    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9917                    UNSPEC_TLSGD)
9918    (clobber (reg:SI LR_REGNO))]
9919   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9920    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9921   "bl %z1(%3@tlsgd)\;nop"
9922   [(set_attr "type" "branch")
9923    (set_attr "length" "8")])
9925 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9926   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9927         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9928               (match_operand 2 "" "g")))
9929    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9930                    UNSPEC_TLSGD)
9931    (clobber (reg:SI LR_REGNO))]
9932   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9934   if (flag_pic)
9935     {
9936       if (TARGET_SECURE_PLT && flag_pic == 2)
9937         return "bl %z1+32768(%3@tlsgd)@plt";
9938       return "bl %z1(%3@tlsgd)@plt";
9939     }
9940   return "bl %z1(%3@tlsgd)";
9942   [(set_attr "type" "branch")
9943    (set_attr "length" "4")])
9945 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9946   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9947         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9948               (match_operand 3 "" "g")))
9949    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9950                    UNSPEC_TLSLD)
9951    (clobber (reg:SI LR_REGNO))]
9952   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9954   if (TARGET_CMODEL != CMODEL_SMALL)
9955     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9956            "bl %z2\;nop";
9957   else
9958     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9960   "&& TARGET_TLS_MARKERS"
9961   [(set (match_dup 0)
9962         (unspec:TLSmode [(match_dup 1)]
9963                         UNSPEC_TLSLD))
9964    (parallel [(set (match_dup 0)
9965                    (call (mem:TLSmode (match_dup 2))
9966                          (match_dup 3)))
9967               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9968               (clobber (reg:SI LR_REGNO))])]
9969   ""
9970   [(set_attr "type" "two")
9971    (set (attr "length")
9972      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9973                    (const_int 16)
9974                    (const_int 12)))])
9976 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9977   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9978         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9979               (match_operand 3 "" "g")))
9980    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9981                    UNSPEC_TLSLD)
9982    (clobber (reg:SI LR_REGNO))]
9983   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9985   if (flag_pic)
9986     {
9987       if (TARGET_SECURE_PLT && flag_pic == 2)
9988         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9989       else
9990         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9991     }
9992   else
9993     return "addi %0,%1,%&@got@tlsld\;bl %z2";
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 "length" "8")])
10007 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10008   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10009         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10010                         UNSPEC_TLSLD))]
10011   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10012   "addi %0,%1,%&@got@tlsld"
10013   "&& TARGET_CMODEL != CMODEL_SMALL"
10014   [(set (match_dup 2)
10015         (high:TLSmode
10016             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10017    (set (match_dup 0)
10018         (lo_sum:TLSmode (match_dup 2)
10019             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10020   "
10022   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10024   [(set (attr "length")
10025      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10026                    (const_int 8)
10027                    (const_int 4)))])
10029 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10030   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10031      (high:TLSmode
10032        (unspec:TLSmode [(const_int 0)
10033                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10034                        UNSPEC_TLSLD)))]
10035   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10036   "addis %0,%1,%&@got@tlsld@ha"
10037   [(set_attr "length" "4")])
10039 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10040   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10041      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10042        (unspec:TLSmode [(const_int 0)
10043                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10044                        UNSPEC_TLSLD)))]
10045   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10046   "addi %0,%1,%&@got@tlsld@l"
10047   [(set_attr "length" "4")])
10049 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10050   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10051         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10052               (match_operand 2 "" "g")))
10053    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10054    (clobber (reg:SI LR_REGNO))]
10055   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10056    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10057   "bl %z1(%&@tlsld)\;nop"
10058   [(set_attr "type" "branch")
10059    (set_attr "length" "8")])
10061 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10062   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10063         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10064               (match_operand 2 "" "g")))
10065    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10066    (clobber (reg:SI LR_REGNO))]
10067   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10069   if (flag_pic)
10070     {
10071       if (TARGET_SECURE_PLT && flag_pic == 2)
10072         return "bl %z1+32768(%&@tlsld)@plt";
10073       return "bl %z1(%&@tlsld)@plt";
10074     }
10075   return "bl %z1(%&@tlsld)";
10077   [(set_attr "type" "branch")
10078    (set_attr "length" "4")])
10080 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10081   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10082         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10083                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10084                         UNSPEC_TLSDTPREL))]
10085   "HAVE_AS_TLS"
10086   "addi %0,%1,%2@dtprel")
10088 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10089   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10090         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10091                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10092                         UNSPEC_TLSDTPRELHA))]
10093   "HAVE_AS_TLS"
10094   "addis %0,%1,%2@dtprel@ha")
10096 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10097   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10098         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10099                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10100                         UNSPEC_TLSDTPRELLO))]
10101   "HAVE_AS_TLS"
10102   "addi %0,%1,%2@dtprel@l")
10104 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10105   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10106         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10107                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10108                         UNSPEC_TLSGOTDTPREL))]
10109   "HAVE_AS_TLS"
10110   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10111   "&& TARGET_CMODEL != CMODEL_SMALL"
10112   [(set (match_dup 3)
10113         (high:TLSmode
10114             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10115    (set (match_dup 0)
10116         (lo_sum:TLSmode (match_dup 3)
10117             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10118   "
10120   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10122   [(set (attr "length")
10123      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10124                    (const_int 8)
10125                    (const_int 4)))])
10127 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10128   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10129      (high:TLSmode
10130        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10131                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10132                        UNSPEC_TLSGOTDTPREL)))]
10133   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10134   "addis %0,%1,%2@got@dtprel@ha"
10135   [(set_attr "length" "4")])
10137 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10138   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10139      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10140          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10141                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10142                          UNSPEC_TLSGOTDTPREL)))]
10143   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10144   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10145   [(set_attr "length" "4")])
10147 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10148   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10149         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10150                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10151                         UNSPEC_TLSTPREL))]
10152   "HAVE_AS_TLS"
10153   "addi %0,%1,%2@tprel")
10155 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10156   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10157         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10158                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10159                         UNSPEC_TLSTPRELHA))]
10160   "HAVE_AS_TLS"
10161   "addis %0,%1,%2@tprel@ha")
10163 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10164   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10165         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10166                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10167                         UNSPEC_TLSTPRELLO))]
10168   "HAVE_AS_TLS"
10169   "addi %0,%1,%2@tprel@l")
10171 ;; "b" output constraint here and on tls_tls input to support linker tls
10172 ;; optimization.  The linker may edit the instructions emitted by a
10173 ;; tls_got_tprel/tls_tls pair to addis,addi.
10174 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10175   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10176         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10177                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10178                         UNSPEC_TLSGOTTPREL))]
10179   "HAVE_AS_TLS"
10180   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10181   "&& TARGET_CMODEL != CMODEL_SMALL"
10182   [(set (match_dup 3)
10183         (high:TLSmode
10184             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10185    (set (match_dup 0)
10186         (lo_sum:TLSmode (match_dup 3)
10187             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10188   "
10190   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10192   [(set (attr "length")
10193      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10194                    (const_int 8)
10195                    (const_int 4)))])
10197 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10198   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10199      (high:TLSmode
10200        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10201                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10202                        UNSPEC_TLSGOTTPREL)))]
10203   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10204   "addis %0,%1,%2@got@tprel@ha"
10205   [(set_attr "length" "4")])
10207 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10208   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10209      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10210          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10211                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10212                          UNSPEC_TLSGOTTPREL)))]
10213   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10214   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10215   [(set_attr "length" "4")])
10217 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10218   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10219         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10220                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10221                         UNSPEC_TLSTLS))]
10222   "TARGET_ELF && HAVE_AS_TLS"
10223   "add %0,%1,%2@tls")
10225 (define_expand "tls_get_tpointer"
10226   [(set (match_operand:SI 0 "gpc_reg_operand" "")
10227         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10228   "TARGET_XCOFF && HAVE_AS_TLS"
10229   "
10231   emit_insn (gen_tls_get_tpointer_internal ());
10232   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10233   DONE;
10236 (define_insn "tls_get_tpointer_internal"
10237   [(set (reg:SI 3)
10238         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10239    (clobber (reg:SI LR_REGNO))]
10240   "TARGET_XCOFF && HAVE_AS_TLS"
10241   "bla __get_tpointer")
10243 (define_expand "tls_get_addr<mode>"
10244   [(set (match_operand:P 0 "gpc_reg_operand" "")
10245         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10246                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10247   "TARGET_XCOFF && HAVE_AS_TLS"
10248   "
10250   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10251   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10252   emit_insn (gen_tls_get_addr_internal<mode> ());
10253   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10254   DONE;
10257 (define_insn "tls_get_addr_internal<mode>"
10258   [(set (reg:P 3)
10259         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10260    (clobber (reg:P 0))
10261    (clobber (reg:P 4))
10262    (clobber (reg:P 5))
10263    (clobber (reg:P 11))
10264    (clobber (reg:CC CR0_REGNO))
10265    (clobber (reg:P LR_REGNO))]
10266   "TARGET_XCOFF && HAVE_AS_TLS"
10267   "bla __tls_get_addr")
10269 ;; Next come insns related to the calling sequence.
10271 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10272 ;; We move the back-chain and decrement the stack pointer.
10274 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
10275 ;; constant alloca, using that predicate will force the generic code to put
10276 ;; the constant size into a register before calling the expander.
10278 ;; As a result the expander would not have the constant size information
10279 ;; in those cases and would have to generate less efficient code.
10281 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10282 ;; the constant size.  The value is forced into a register if necessary.
10284 (define_expand "allocate_stack"
10285   [(set (match_operand 0 "gpc_reg_operand" "")
10286         (minus (reg 1) (match_operand 1 "reg_or_cint_operand" "")))
10287    (set (reg 1)
10288         (minus (reg 1) (match_dup 1)))]
10289   ""
10290   "
10291 { rtx chain = gen_reg_rtx (Pmode);
10292   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10293   rtx neg_op0;
10294   rtx insn, par, set, mem;
10296   /* By allowing reg_or_cint_operand as the predicate we can get
10297      better code for stack-clash-protection because we do not lose
10298      size information.  But the rest of the code expects the operand
10299      to be reg_or_short_operand.  If it isn't, then force it into
10300      a register.  */
10301   rtx orig_op1 = operands[1];
10302   if (!reg_or_short_operand (operands[1], Pmode))
10303     operands[1] = force_reg (Pmode, operands[1]);
10305   emit_move_insn (chain, stack_bot);
10307   /* Check stack bounds if necessary.  */
10308   if (crtl->limit_stack)
10309     {
10310       rtx available;
10311       available = expand_binop (Pmode, sub_optab,
10312                                 stack_pointer_rtx, stack_limit_rtx,
10313                                 NULL_RTX, 1, OPTAB_WIDEN);
10314       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10315     }
10317   /* Allocate and probe if requested.
10318      This may look similar to the loop we use for prologue allocations,
10319      but it is critically different.  For the former we know the loop
10320      will iterate, but do not know that generally here.  The former
10321      uses that knowledge to rotate the loop.  Combining them would be
10322      possible with some performance cost.  */
10323   if (flag_stack_clash_protection)
10324     {
10325       rtx rounded_size, last_addr, residual;
10326       HOST_WIDE_INT probe_interval;
10327       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10328                                                 &residual, &probe_interval,
10329                                                 orig_op1);
10330       
10331       /* We do occasionally get in here with constant sizes, we might
10332          as well do a reasonable job when we obviously can.  */
10333       if (rounded_size != const0_rtx)
10334         {
10335           rtx loop_lab, end_loop;
10336           bool rotated = CONST_INT_P (rounded_size);
10338           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10339                                                         last_addr, rotated);
10341           if (Pmode == SImode)
10342             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10343                                                stack_pointer_rtx,
10344                                                GEN_INT (-probe_interval),
10345                                                chain));
10346           else
10347             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
10348                                                   stack_pointer_rtx,
10349                                                   GEN_INT (-probe_interval),
10350                                                   chain));
10351           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10352                                                       last_addr, rotated);
10353         }
10355       /* Now handle residuals.  We just have to set operands[1] correctly
10356          and let the rest of the expander run.  */
10357       operands[1] = residual;
10358       if (!CONST_INT_P (residual))
10359         operands[1] = force_reg (Pmode, operands[1]);
10360     }
10362   if (GET_CODE (operands[1]) != CONST_INT
10363       || INTVAL (operands[1]) < -32767
10364       || INTVAL (operands[1]) > 32768)
10365     {
10366       neg_op0 = gen_reg_rtx (Pmode);
10367       if (TARGET_32BIT)
10368         emit_insn (gen_negsi2 (neg_op0, operands[1]));
10369       else
10370         emit_insn (gen_negdi2 (neg_op0, operands[1]));
10371     }
10372   else
10373     neg_op0 = GEN_INT (- INTVAL (operands[1]));
10375   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10376                                        : gen_movdi_di_update_stack))
10377                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10378                          chain));
10379   /* Since we didn't use gen_frame_mem to generate the MEM, grab
10380      it now and set the alias set/attributes. The above gen_*_update
10381      calls will generate a PARALLEL with the MEM set being the first
10382      operation. */
10383   par = PATTERN (insn);
10384   gcc_assert (GET_CODE (par) == PARALLEL);
10385   set = XVECEXP (par, 0, 0);
10386   gcc_assert (GET_CODE (set) == SET);
10387   mem = SET_DEST (set);
10388   gcc_assert (MEM_P (mem));
10389   MEM_NOTRAP_P (mem) = 1;
10390   set_mem_alias_set (mem, get_frame_alias_set ());
10392   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10393   DONE;
10396 ;; These patterns say how to save and restore the stack pointer.  We need not
10397 ;; save the stack pointer at function level since we are careful to
10398 ;; preserve the backchain.  At block level, we have to restore the backchain
10399 ;; when we restore the stack pointer.
10401 ;; For nonlocal gotos, we must save both the stack pointer and its
10402 ;; backchain and restore both.  Note that in the nonlocal case, the
10403 ;; save area is a memory location.
10405 (define_expand "save_stack_function"
10406   [(match_operand 0 "any_operand" "")
10407    (match_operand 1 "any_operand" "")]
10408   ""
10409   "DONE;")
10411 (define_expand "restore_stack_function"
10412   [(match_operand 0 "any_operand" "")
10413    (match_operand 1 "any_operand" "")]
10414   ""
10415   "DONE;")
10417 ;; Adjust stack pointer (op0) to a new value (op1).
10418 ;; First copy old stack backchain to new location, and ensure that the
10419 ;; scheduler won't reorder the sp assignment before the backchain write.
10420 (define_expand "restore_stack_block"
10421   [(set (match_dup 2) (match_dup 3))
10422    (set (match_dup 4) (match_dup 2))
10423    (match_dup 5)
10424    (set (match_operand 0 "register_operand" "")
10425         (match_operand 1 "register_operand" ""))]
10426   ""
10427   "
10429   rtvec p;
10431   operands[1] = force_reg (Pmode, operands[1]);
10432   operands[2] = gen_reg_rtx (Pmode);
10433   operands[3] = gen_frame_mem (Pmode, operands[0]);
10434   operands[4] = gen_frame_mem (Pmode, operands[1]);
10435   p = rtvec_alloc (1);
10436   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10437                                   const0_rtx);
10438   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10441 (define_expand "save_stack_nonlocal"
10442   [(set (match_dup 3) (match_dup 4))
10443    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10444    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10445   ""
10446   "
10448   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10450   /* Copy the backchain to the first word, sp to the second.  */
10451   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10452   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10453   operands[3] = gen_reg_rtx (Pmode);
10454   operands[4] = gen_frame_mem (Pmode, operands[1]);
10457 (define_expand "restore_stack_nonlocal"
10458   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10459    (set (match_dup 3) (match_dup 4))
10460    (set (match_dup 5) (match_dup 2))
10461    (match_dup 6)
10462    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10463   ""
10464   "
10466   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10467   rtvec p;
10469   /* Restore the backchain from the first word, sp from the second.  */
10470   operands[2] = gen_reg_rtx (Pmode);
10471   operands[3] = gen_reg_rtx (Pmode);
10472   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10473   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10474   operands[5] = gen_frame_mem (Pmode, operands[3]);
10475   p = rtvec_alloc (1);
10476   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10477                                   const0_rtx);
10478   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10481 ;; TOC register handling.
10483 ;; Code to initialize the TOC register...
10485 (define_insn "load_toc_aix_si"
10486   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10487                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10488               (use (reg:SI 2))])]
10489   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10490   "*
10492   char buf[30];
10493   extern int need_toc_init;
10494   need_toc_init = 1;
10495   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10496   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10497   operands[2] = gen_rtx_REG (Pmode, 2);
10498   return \"lwz %0,%1(%2)\";
10500   [(set_attr "type" "load")
10501    (set_attr "update" "no")
10502    (set_attr "indexed" "no")])
10504 (define_insn "load_toc_aix_di"
10505   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10506                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10507               (use (reg:DI 2))])]
10508   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10509   "*
10511   char buf[30];
10512   extern int need_toc_init;
10513   need_toc_init = 1;
10514   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10515                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10516   if (TARGET_ELF)
10517     strcat (buf, \"@toc\");
10518   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10519   operands[2] = gen_rtx_REG (Pmode, 2);
10520   return \"ld %0,%1(%2)\";
10522   [(set_attr "type" "load")
10523    (set_attr "update" "no")
10524    (set_attr "indexed" "no")])
10526 (define_insn "load_toc_v4_pic_si"
10527   [(set (reg:SI LR_REGNO)
10528         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10529   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10530   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10531   [(set_attr "type" "branch")
10532    (set_attr "length" "4")])
10534 (define_expand "load_toc_v4_PIC_1"
10535   [(parallel [(set (reg:SI LR_REGNO)
10536                    (match_operand:SI 0 "immediate_operand" "s"))
10537               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10538   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10539    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10540   "")
10542 (define_insn "load_toc_v4_PIC_1_normal"
10543   [(set (reg:SI LR_REGNO)
10544         (match_operand:SI 0 "immediate_operand" "s"))
10545    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10546   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10547    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10548   "bcl 20,31,%0\\n%0:"
10549   [(set_attr "type" "branch")
10550    (set_attr "length" "4")
10551    (set_attr "cannot_copy" "yes")])
10553 (define_insn "load_toc_v4_PIC_1_476"
10554   [(set (reg:SI LR_REGNO)
10555         (match_operand:SI 0 "immediate_operand" "s"))
10556    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10557   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10558    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10559   "*
10561   char name[32];
10562   static char templ[32];
10564   get_ppc476_thunk_name (name);
10565   sprintf (templ, \"bl %s\\n%%0:\", name);
10566   return templ;
10568   [(set_attr "type" "branch")
10569    (set_attr "length" "4")
10570    (set_attr "cannot_copy" "yes")])
10572 (define_expand "load_toc_v4_PIC_1b"
10573   [(parallel [(set (reg:SI LR_REGNO)
10574                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10575                                (label_ref (match_operand 1 "" ""))]
10576                            UNSPEC_TOCPTR))
10577               (match_dup 1)])]
10578   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10579   "")
10581 (define_insn "load_toc_v4_PIC_1b_normal"
10582   [(set (reg:SI LR_REGNO)
10583         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10584                     (label_ref (match_operand 1 "" ""))]
10585                 UNSPEC_TOCPTR))
10586    (match_dup 1)]
10587   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10588   "bcl 20,31,$+8\;.long %0-$"
10589   [(set_attr "type" "branch")
10590    (set_attr "length" "8")])
10592 (define_insn "load_toc_v4_PIC_1b_476"
10593   [(set (reg:SI LR_REGNO)
10594         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10595                     (label_ref (match_operand 1 "" ""))]
10596                 UNSPEC_TOCPTR))
10597    (match_dup 1)]
10598   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10599   "*
10601   char name[32];
10602   static char templ[32];
10604   get_ppc476_thunk_name (name);
10605   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10606   return templ;
10608   [(set_attr "type" "branch")
10609    (set_attr "length" "16")])
10611 (define_insn "load_toc_v4_PIC_2"
10612   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10613         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10614                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10615                              (match_operand:SI 3 "immediate_operand" "s")))))]
10616   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10617   "lwz %0,%2-%3(%1)"
10618   [(set_attr "type" "load")])
10620 (define_insn "load_toc_v4_PIC_3b"
10621   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10622         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10623                  (high:SI
10624                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10625                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10626   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10627   "addis %0,%1,%2-%3@ha")
10629 (define_insn "load_toc_v4_PIC_3c"
10630   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10631         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10632                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10633                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10634   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10635   "addi %0,%1,%2-%3@l")
10637 ;; If the TOC is shared over a translation unit, as happens with all
10638 ;; the kinds of PIC that we support, we need to restore the TOC
10639 ;; pointer only when jumping over units of translation.
10640 ;; On Darwin, we need to reload the picbase.
10642 (define_expand "builtin_setjmp_receiver"
10643   [(use (label_ref (match_operand 0 "" "")))]
10644   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10645    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10646    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10647   "
10649 #if TARGET_MACHO
10650   if (DEFAULT_ABI == ABI_DARWIN)
10651     {
10652       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10653       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10654       rtx tmplabrtx;
10655       char tmplab[20];
10657       crtl->uses_pic_offset_table = 1;
10658       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10659                                   CODE_LABEL_NUMBER (operands[0]));
10660       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10662       emit_insn (gen_load_macho_picbase (tmplabrtx));
10663       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10664       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10665     }
10666   else
10667 #endif
10668     rs6000_emit_load_toc_table (FALSE);
10669   DONE;
10672 ;; Largetoc support
10673 (define_insn "*largetoc_high"
10674   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10675         (high:DI
10676           (unspec [(match_operand:DI 1 "" "")
10677                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10678                   UNSPEC_TOCREL)))]
10679    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10680    "addis %0,%2,%1@toc@ha")
10682 (define_insn "*largetoc_high_aix<mode>"
10683   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10684         (high:P
10685           (unspec [(match_operand:P 1 "" "")
10686                    (match_operand:P 2 "gpc_reg_operand" "b")]
10687                   UNSPEC_TOCREL)))]
10688    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10689    "addis %0,%1@u(%2)")
10691 (define_insn "*largetoc_high_plus"
10692   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10693         (high:DI
10694           (plus:DI
10695             (unspec [(match_operand:DI 1 "" "")
10696                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10697                     UNSPEC_TOCREL)
10698             (match_operand:DI 3 "add_cint_operand" "n"))))]
10699    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10700    "addis %0,%2,%1+%3@toc@ha")
10702 (define_insn "*largetoc_high_plus_aix<mode>"
10703   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10704         (high:P
10705           (plus:P
10706             (unspec [(match_operand:P 1 "" "")
10707                      (match_operand:P 2 "gpc_reg_operand" "b")]
10708                     UNSPEC_TOCREL)
10709             (match_operand:P 3 "add_cint_operand" "n"))))]
10710    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10711    "addis %0,%1+%3@u(%2)")
10713 (define_insn "*largetoc_low"
10714   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10715         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10716                    (match_operand:DI 2 "" "")))]
10717    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10718    "addi %0,%1,%2@l")
10720 (define_insn "*largetoc_low_aix<mode>"
10721   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10722         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10723                    (match_operand:P 2 "" "")))]
10724    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10725    "la %0,%2@l(%1)")
10727 (define_insn_and_split "*tocref<mode>"
10728   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10729         (match_operand:P 1 "small_toc_ref" "R"))]
10730    "TARGET_TOC"
10731    "la %0,%a1"
10732    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10733   [(set (match_dup 0) (high:P (match_dup 1)))
10734    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10736 ;; Elf specific ways of loading addresses for non-PIC code.
10737 ;; The output of this could be r0, but we make a very strong
10738 ;; preference for a base register because it will usually
10739 ;; be needed there.
10740 (define_insn "elf_high"
10741   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10742         (high:SI (match_operand 1 "" "")))]
10743   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10744   "lis %0,%1@ha")
10746 (define_insn "elf_low"
10747   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10748         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10749                    (match_operand 2 "" "")))]
10750    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10751    "la %0,%2@l(%1)")
10753 ;; Call and call_value insns
10754 (define_expand "call"
10755   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10756                     (match_operand 1 "" ""))
10757               (use (match_operand 2 "" ""))
10758               (clobber (reg:SI LR_REGNO))])]
10759   ""
10760   "
10762 #if TARGET_MACHO
10763   if (MACHOPIC_INDIRECT)
10764     operands[0] = machopic_indirect_call_target (operands[0]);
10765 #endif
10767   gcc_assert (GET_CODE (operands[0]) == MEM);
10768   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10770   operands[0] = XEXP (operands[0], 0);
10772   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10773     {
10774       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10775       DONE;
10776     }
10778   if (GET_CODE (operands[0]) != SYMBOL_REF
10779       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10780     {
10781       if (INTVAL (operands[2]) & CALL_LONG)
10782         operands[0] = rs6000_longcall_ref (operands[0]);
10784       switch (DEFAULT_ABI)
10785         {
10786         case ABI_V4:
10787         case ABI_DARWIN:
10788           operands[0] = force_reg (Pmode, operands[0]);
10789           break;
10791         default:
10792           gcc_unreachable ();
10793         }
10794     }
10797 (define_expand "call_value"
10798   [(parallel [(set (match_operand 0 "" "")
10799                    (call (mem:SI (match_operand 1 "address_operand" ""))
10800                          (match_operand 2 "" "")))
10801               (use (match_operand 3 "" ""))
10802               (clobber (reg:SI LR_REGNO))])]
10803   ""
10804   "
10806 #if TARGET_MACHO
10807   if (MACHOPIC_INDIRECT)
10808     operands[1] = machopic_indirect_call_target (operands[1]);
10809 #endif
10811   gcc_assert (GET_CODE (operands[1]) == MEM);
10812   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10814   operands[1] = XEXP (operands[1], 0);
10816   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10817     {
10818       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10819       DONE;
10820     }
10822   if (GET_CODE (operands[1]) != SYMBOL_REF
10823       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10824     {
10825       if (INTVAL (operands[3]) & CALL_LONG)
10826         operands[1] = rs6000_longcall_ref (operands[1]);
10828       switch (DEFAULT_ABI)
10829         {
10830         case ABI_V4:
10831         case ABI_DARWIN:
10832           operands[1] = force_reg (Pmode, operands[1]);
10833           break;
10835         default:
10836           gcc_unreachable ();
10837         }
10838     }
10841 ;; Call to function in current module.  No TOC pointer reload needed.
10842 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10843 ;; either the function was not prototyped, or it was prototyped as a
10844 ;; variable argument function.  It is > 0 if FP registers were passed
10845 ;; and < 0 if they were not.
10847 (define_insn "*call_local32"
10848   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10849          (match_operand 1 "" "g,g"))
10850    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10851    (clobber (reg:SI LR_REGNO))]
10852   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10853   "*
10855   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10856     output_asm_insn (\"crxor 6,6,6\", operands);
10858   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10859     output_asm_insn (\"creqv 6,6,6\", operands);
10861   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10863   [(set_attr "type" "branch")
10864    (set_attr "length" "4,8")])
10866 (define_insn "*call_local64"
10867   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10868          (match_operand 1 "" "g,g"))
10869    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10870    (clobber (reg:SI LR_REGNO))]
10871   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10872   "*
10874   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10875     output_asm_insn (\"crxor 6,6,6\", operands);
10877   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10878     output_asm_insn (\"creqv 6,6,6\", operands);
10880   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10882   [(set_attr "type" "branch")
10883    (set_attr "length" "4,8")])
10885 (define_insn "*call_value_local32"
10886   [(set (match_operand 0 "" "")
10887         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10888               (match_operand 2 "" "g,g")))
10889    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10890    (clobber (reg:SI LR_REGNO))]
10891   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10892   "*
10894   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10895     output_asm_insn (\"crxor 6,6,6\", operands);
10897   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10898     output_asm_insn (\"creqv 6,6,6\", operands);
10900   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10902   [(set_attr "type" "branch")
10903    (set_attr "length" "4,8")])
10906 (define_insn "*call_value_local64"
10907   [(set (match_operand 0 "" "")
10908         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10909               (match_operand 2 "" "g,g")))
10910    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10911    (clobber (reg:SI LR_REGNO))]
10912   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10913   "*
10915   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10916     output_asm_insn (\"crxor 6,6,6\", operands);
10918   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10919     output_asm_insn (\"creqv 6,6,6\", operands);
10921   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10923   [(set_attr "type" "branch")
10924    (set_attr "length" "4,8")])
10927 ;; A function pointer under System V is just a normal pointer
10928 ;; operands[0] is the function pointer
10929 ;; operands[1] is the stack size to clean up
10930 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10931 ;; which indicates how to set cr1
10933 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10934   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10935          (match_operand 1 "" "g,g,g,g"))
10936    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10937    (clobber (reg:SI LR_REGNO))]
10938   "DEFAULT_ABI == ABI_V4
10939    || DEFAULT_ABI == ABI_DARWIN"
10941   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10942     output_asm_insn ("crxor 6,6,6", operands);
10944   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10945     output_asm_insn ("creqv 6,6,6", operands);
10947   return "b%T0l";
10949   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10950    (set_attr "length" "4,4,8,8")])
10952 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10953   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10954          (match_operand 1 "" "g,g"))
10955    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10956    (clobber (reg:SI LR_REGNO))]
10957   "(DEFAULT_ABI == ABI_DARWIN
10958    || (DEFAULT_ABI == ABI_V4
10959        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10961   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10962     output_asm_insn ("crxor 6,6,6", operands);
10964   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10965     output_asm_insn ("creqv 6,6,6", operands);
10967 #if TARGET_MACHO
10968   return output_call(insn, operands, 0, 2);
10969 #else
10970   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10971     {
10972       gcc_assert (!TARGET_SECURE_PLT);
10973       return "bl %z0@plt";
10974     }
10975   else
10976     return "bl %z0";
10977 #endif
10979   "DEFAULT_ABI == ABI_V4
10980    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10981    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10982   [(parallel [(call (mem:SI (match_dup 0))
10983                     (match_dup 1))
10984               (use (match_dup 2))
10985               (use (match_dup 3))
10986               (clobber (reg:SI LR_REGNO))])]
10988   operands[3] = pic_offset_table_rtx;
10990   [(set_attr "type" "branch,branch")
10991    (set_attr "length" "4,8")])
10993 (define_insn "*call_nonlocal_sysv_secure<mode>"
10994   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10995          (match_operand 1 "" "g,g"))
10996    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10997    (use (match_operand:SI 3 "register_operand" "r,r"))
10998    (clobber (reg:SI LR_REGNO))]
10999   "(DEFAULT_ABI == ABI_V4
11000     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11001     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11003   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11004     output_asm_insn ("crxor 6,6,6", operands);
11006   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11007     output_asm_insn ("creqv 6,6,6", operands);
11009   if (flag_pic == 2)
11010     /* The magic 32768 offset here and in the other sysv call insns
11011        corresponds to the offset of r30 in .got2, as given by LCTOC1.
11012        See sysv4.h:toc_section.  */
11013     return "bl %z0+32768@plt";
11014   else
11015     return "bl %z0@plt";
11017   [(set_attr "type" "branch,branch")
11018    (set_attr "length" "4,8")])
11020 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11021   [(set (match_operand 0 "" "")
11022         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11023               (match_operand 2 "" "g,g,g,g")))
11024    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11025    (clobber (reg:SI LR_REGNO))]
11026   "DEFAULT_ABI == ABI_V4
11027    || DEFAULT_ABI == ABI_DARWIN"
11029   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11030     output_asm_insn ("crxor 6,6,6", operands);
11032   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11033     output_asm_insn ("creqv 6,6,6", operands);
11035   return "b%T1l";
11037   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11038    (set_attr "length" "4,4,8,8")])
11040 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11041   [(set (match_operand 0 "" "")
11042         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11043               (match_operand 2 "" "g,g")))
11044    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11045    (clobber (reg:SI LR_REGNO))]
11046   "(DEFAULT_ABI == ABI_DARWIN
11047    || (DEFAULT_ABI == ABI_V4
11048        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11050   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11051     output_asm_insn ("crxor 6,6,6", operands);
11053   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11054     output_asm_insn ("creqv 6,6,6", operands);
11056 #if TARGET_MACHO
11057   return output_call(insn, operands, 1, 3);
11058 #else
11059   if (DEFAULT_ABI == ABI_V4 && flag_pic)
11060     {
11061       gcc_assert (!TARGET_SECURE_PLT);
11062       return "bl %z1@plt";
11063     }
11064   else
11065     return "bl %z1";
11066 #endif
11068   "DEFAULT_ABI == ABI_V4
11069    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11070    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11071   [(parallel [(set (match_dup 0)
11072                    (call (mem:SI (match_dup 1))
11073                          (match_dup 2)))
11074               (use (match_dup 3))
11075               (use (match_dup 4))
11076               (clobber (reg:SI LR_REGNO))])]
11078   operands[4] = pic_offset_table_rtx;
11080   [(set_attr "type" "branch,branch")
11081    (set_attr "length" "4,8")])
11083 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11084   [(set (match_operand 0 "" "")
11085         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11086               (match_operand 2 "" "g,g")))
11087    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11088    (use (match_operand:SI 4 "register_operand" "r,r"))
11089    (clobber (reg:SI LR_REGNO))]
11090   "(DEFAULT_ABI == ABI_V4
11091     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11092     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11094   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11095     output_asm_insn ("crxor 6,6,6", operands);
11097   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11098     output_asm_insn ("creqv 6,6,6", operands);
11100   if (flag_pic == 2)
11101     return "bl %z1+32768@plt";
11102   else
11103     return "bl %z1@plt";
11105   [(set_attr "type" "branch,branch")
11106    (set_attr "length" "4,8")])
11109 ;; Call to AIX abi function in the same module.
11111 (define_insn "*call_local_aix<mode>"
11112   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11113          (match_operand 1 "" "g"))
11114    (clobber (reg:P LR_REGNO))]
11115   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11116   "bl %z0"
11117   [(set_attr "type" "branch")
11118    (set_attr "length" "4")])
11120 (define_insn "*call_value_local_aix<mode>"
11121   [(set (match_operand 0 "" "")
11122         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11123               (match_operand 2 "" "g")))
11124    (clobber (reg:P LR_REGNO))]
11125   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11126   "bl %z1"
11127   [(set_attr "type" "branch")
11128    (set_attr "length" "4")])
11130 ;; Call to AIX abi function which may be in another module.
11131 ;; Restore the TOC pointer (r2) after the call.
11133 (define_insn "*call_nonlocal_aix<mode>"
11134   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11135          (match_operand 1 "" "g"))
11136    (clobber (reg:P LR_REGNO))]
11137   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11138   "bl %z0\;nop"
11139   [(set_attr "type" "branch")
11140    (set_attr "length" "8")])
11142 (define_insn "*call_value_nonlocal_aix<mode>"
11143   [(set (match_operand 0 "" "")
11144         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11145               (match_operand 2 "" "g")))
11146    (clobber (reg:P LR_REGNO))]
11147   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11148   "bl %z1\;nop"
11149   [(set_attr "type" "branch")
11150    (set_attr "length" "8")])
11152 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11153 ;; Operand0 is the addresss of the function to call
11154 ;; Operand2 is the location in the function descriptor to load r2 from
11155 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11157 (define_insn "*call_indirect_aix<mode>"
11158   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11159          (match_operand 1 "" "g,g"))
11160    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11161    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11162    (clobber (reg:P LR_REGNO))]
11163   "DEFAULT_ABI == ABI_AIX"
11164   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11165   [(set_attr "type" "jmpreg")
11166    (set_attr "length" "12")])
11168 (define_insn "*call_value_indirect_aix<mode>"
11169   [(set (match_operand 0 "" "")
11170         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11171               (match_operand 2 "" "g,g")))
11172    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11173    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11174    (clobber (reg:P LR_REGNO))]
11175   "DEFAULT_ABI == ABI_AIX"
11176   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11177   [(set_attr "type" "jmpreg")
11178    (set_attr "length" "12")])
11180 ;; Call to indirect functions with the ELFv2 ABI.
11181 ;; Operand0 is the addresss of the function to call
11182 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11184 (define_insn "*call_indirect_elfv2<mode>"
11185   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11186          (match_operand 1 "" "g,g"))
11187    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11188    (clobber (reg:P LR_REGNO))]
11189   "DEFAULT_ABI == ABI_ELFv2"
11190   "b%T0l\;<ptrload> 2,%2(1)"
11191   [(set_attr "type" "jmpreg")
11192    (set_attr "length" "8")])
11194 (define_insn "*call_value_indirect_elfv2<mode>"
11195   [(set (match_operand 0 "" "")
11196         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11197               (match_operand 2 "" "g,g")))
11198    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11199    (clobber (reg:P LR_REGNO))]
11200   "DEFAULT_ABI == ABI_ELFv2"
11201   "b%T1l\;<ptrload> 2,%3(1)"
11202   [(set_attr "type" "jmpreg")
11203    (set_attr "length" "8")])
11206 ;; Call subroutine returning any type.
11207 (define_expand "untyped_call"
11208   [(parallel [(call (match_operand 0 "" "")
11209                     (const_int 0))
11210               (match_operand 1 "" "")
11211               (match_operand 2 "" "")])]
11212   ""
11213   "
11215   int i;
11217   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11219   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11220     {
11221       rtx set = XVECEXP (operands[2], 0, i);
11222       emit_move_insn (SET_DEST (set), SET_SRC (set));
11223     }
11225   /* The optimizer does not know that the call sets the function value
11226      registers we stored in the result block.  We avoid problems by
11227      claiming that all hard registers are used and clobbered at this
11228      point.  */
11229   emit_insn (gen_blockage ());
11231   DONE;
11234 ;; sibling call patterns
11235 (define_expand "sibcall"
11236   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11237                     (match_operand 1 "" ""))
11238               (use (match_operand 2 "" ""))
11239               (simple_return)])]
11240   ""
11241   "
11243 #if TARGET_MACHO
11244   if (MACHOPIC_INDIRECT)
11245     operands[0] = machopic_indirect_call_target (operands[0]);
11246 #endif
11248   gcc_assert (GET_CODE (operands[0]) == MEM);
11249   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11251   operands[0] = XEXP (operands[0], 0);
11253   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11254     {
11255       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11256       DONE;
11257     }
11260 (define_expand "sibcall_value"
11261   [(parallel [(set (match_operand 0 "register_operand" "")
11262                 (call (mem:SI (match_operand 1 "address_operand" ""))
11263                       (match_operand 2 "" "")))
11264               (use (match_operand 3 "" ""))
11265               (simple_return)])]
11266   ""
11267   "
11269 #if TARGET_MACHO
11270   if (MACHOPIC_INDIRECT)
11271     operands[1] = machopic_indirect_call_target (operands[1]);
11272 #endif
11274   gcc_assert (GET_CODE (operands[1]) == MEM);
11275   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11277   operands[1] = XEXP (operands[1], 0);
11279   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11280     {
11281       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11282       DONE;
11283     }
11286 (define_insn "*sibcall_local32"
11287   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11288          (match_operand 1 "" "g,g"))
11289    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11290    (simple_return)]
11291   "(INTVAL (operands[2]) & CALL_LONG) == 0"
11292   "*
11294   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11295     output_asm_insn (\"crxor 6,6,6\", operands);
11297   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11298     output_asm_insn (\"creqv 6,6,6\", operands);
11300   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11302   [(set_attr "type" "branch")
11303    (set_attr "length" "4,8")])
11305 (define_insn "*sibcall_local64"
11306   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11307          (match_operand 1 "" "g,g"))
11308    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11309    (simple_return)]
11310   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11311   "*
11313   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11314     output_asm_insn (\"crxor 6,6,6\", operands);
11316   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11317     output_asm_insn (\"creqv 6,6,6\", operands);
11319   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11321   [(set_attr "type" "branch")
11322    (set_attr "length" "4,8")])
11324 (define_insn "*sibcall_value_local32"
11325   [(set (match_operand 0 "" "")
11326         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11327               (match_operand 2 "" "g,g")))
11328    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11329    (simple_return)]
11330   "(INTVAL (operands[3]) & CALL_LONG) == 0"
11331   "*
11333   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11334     output_asm_insn (\"crxor 6,6,6\", operands);
11336   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11337     output_asm_insn (\"creqv 6,6,6\", operands);
11339   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11341   [(set_attr "type" "branch")
11342    (set_attr "length" "4,8")])
11344 (define_insn "*sibcall_value_local64"
11345   [(set (match_operand 0 "" "")
11346         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11347               (match_operand 2 "" "g,g")))
11348    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11349    (simple_return)]
11350   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11351   "*
11353   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11354     output_asm_insn (\"crxor 6,6,6\", operands);
11356   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11357     output_asm_insn (\"creqv 6,6,6\", operands);
11359   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11361   [(set_attr "type" "branch")
11362    (set_attr "length" "4,8")])
11364 (define_insn "*sibcall_nonlocal_sysv<mode>"
11365   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11366          (match_operand 1 "" ""))
11367    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11368    (simple_return)]
11369   "(DEFAULT_ABI == ABI_DARWIN
11370     || DEFAULT_ABI == ABI_V4)
11371    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11372   "*
11374   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11375     output_asm_insn (\"crxor 6,6,6\", operands);
11377   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11378     output_asm_insn (\"creqv 6,6,6\", operands);
11380   if (which_alternative >= 2)
11381     return \"b%T0\";
11382   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11383     {
11384       gcc_assert (!TARGET_SECURE_PLT);
11385       return \"b %z0@plt\";
11386     }
11387   else
11388     return \"b %z0\";
11390   [(set_attr "type" "branch")
11391    (set_attr "length" "4,8,4,8")])
11393 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11394   [(set (match_operand 0 "" "")
11395         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11396               (match_operand 2 "" "")))
11397    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11398    (simple_return)]
11399   "(DEFAULT_ABI == ABI_DARWIN
11400     || DEFAULT_ABI == ABI_V4)
11401    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11402   "*
11404   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11405     output_asm_insn (\"crxor 6,6,6\", operands);
11407   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11408     output_asm_insn (\"creqv 6,6,6\", operands);
11410   if (which_alternative >= 2)
11411     return \"b%T1\";
11412   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11413     {
11414       gcc_assert (!TARGET_SECURE_PLT);
11415       return \"b %z1@plt\";
11416     }
11417   else
11418     return \"b %z1\";
11420   [(set_attr "type" "branch")
11421    (set_attr "length" "4,8,4,8")])
11423 ;; AIX ABI sibling call patterns.
11425 (define_insn "*sibcall_aix<mode>"
11426   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11427          (match_operand 1 "" "g,g"))
11428    (simple_return)]
11429   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11430   "@
11431    b %z0
11432    b%T0"
11433   [(set_attr "type" "branch")
11434    (set_attr "length" "4")])
11436 (define_insn "*sibcall_value_aix<mode>"
11437   [(set (match_operand 0 "" "")
11438         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11439               (match_operand 2 "" "g,g")))
11440    (simple_return)]
11441   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11442   "@
11443    b %z1
11444    b%T1"
11445   [(set_attr "type" "branch")
11446    (set_attr "length" "4")])
11448 (define_expand "sibcall_epilogue"
11449   [(use (const_int 0))]
11450   ""
11452   if (!TARGET_SCHED_PROLOG)
11453     emit_insn (gen_blockage ());
11454   rs6000_emit_epilogue (TRUE);
11455   DONE;
11458 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11459 ;; all of memory.  This blocks insns from being moved across this point.
11461 (define_insn "blockage"
11462   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11463   ""
11464   "")
11466 (define_expand "probe_stack_address"
11467   [(use (match_operand 0 "address_operand"))]
11468   ""
11470   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11471   MEM_VOLATILE_P (operands[0]) = 1;
11473   if (TARGET_64BIT)
11474     emit_insn (gen_probe_stack_di (operands[0]));
11475   else
11476     emit_insn (gen_probe_stack_si (operands[0]));
11477   DONE;
11480 (define_insn "probe_stack_<mode>"
11481   [(set (match_operand:P 0 "memory_operand" "=m")
11482         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11483   ""
11485   operands[1] = gen_rtx_REG (Pmode, 0);
11486   return "st<wd>%U0%X0 %1,%0";
11488   [(set_attr "type" "store")
11489    (set (attr "update")
11490         (if_then_else (match_operand 0 "update_address_mem")
11491                       (const_string "yes")
11492                       (const_string "no")))
11493    (set (attr "indexed")
11494         (if_then_else (match_operand 0 "indexed_address_mem")
11495                       (const_string "yes")
11496                       (const_string "no")))
11497    (set_attr "length" "4")])
11499 (define_insn "probe_stack_range<P:mode>"
11500   [(set (match_operand:P 0 "register_operand" "=&r")
11501         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11502                             (match_operand:P 2 "register_operand" "r")
11503                             (match_operand:P 3 "register_operand" "r")]
11504                            UNSPECV_PROBE_STACK_RANGE))]
11505   ""
11506   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11507   [(set_attr "type" "three")])
11509 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11510 ;; signed & unsigned, and one type of branch.
11512 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11513 ;; insns, and branches.
11515 (define_expand "cbranch<mode>4"
11516   [(use (match_operator 0 "comparison_operator"
11517          [(match_operand:GPR 1 "gpc_reg_operand" "")
11518           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11519    (use (match_operand 3 ""))]
11520   ""
11521   "
11523   /* Take care of the possibility that operands[2] might be negative but
11524      this might be a logical operation.  That insn doesn't exist.  */
11525   if (GET_CODE (operands[2]) == CONST_INT
11526       && INTVAL (operands[2]) < 0)
11527     {
11528       operands[2] = force_reg (<MODE>mode, operands[2]);
11529       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11530                                     GET_MODE (operands[0]),
11531                                     operands[1], operands[2]);
11532    }
11534   rs6000_emit_cbranch (<MODE>mode, operands);
11535   DONE;
11538 (define_expand "cbranch<mode>4"
11539   [(use (match_operator 0 "comparison_operator"
11540          [(match_operand:FP 1 "gpc_reg_operand" "")
11541           (match_operand:FP 2 "gpc_reg_operand" "")]))
11542    (use (match_operand 3 ""))]
11543   ""
11544   "
11546   rs6000_emit_cbranch (<MODE>mode, operands);
11547   DONE;
11550 (define_expand "cstore<mode>4_signed"
11551   [(use (match_operator 1 "signed_comparison_operator"
11552          [(match_operand:P 2 "gpc_reg_operand")
11553           (match_operand:P 3 "gpc_reg_operand")]))
11554    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11555   ""
11557   enum rtx_code cond_code = GET_CODE (operands[1]);
11559   rtx op0 = operands[0];
11560   rtx op1 = operands[2];
11561   rtx op2 = operands[3];
11563   if (cond_code == GE || cond_code == LT)
11564     {
11565       cond_code = swap_condition (cond_code);
11566       std::swap (op1, op2);
11567     }
11569   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11570   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11571   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11573   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11574   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11575   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11577   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11579   if (cond_code == LE)
11580     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11581   else
11582     {
11583       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11584       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11585       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11586     }
11588   DONE;
11591 (define_expand "cstore<mode>4_unsigned"
11592   [(use (match_operator 1 "unsigned_comparison_operator"
11593          [(match_operand:P 2 "gpc_reg_operand")
11594           (match_operand:P 3 "reg_or_short_operand")]))
11595    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11596   ""
11598   enum rtx_code cond_code = GET_CODE (operands[1]);
11600   rtx op0 = operands[0];
11601   rtx op1 = operands[2];
11602   rtx op2 = operands[3];
11604   if (cond_code == GEU || cond_code == LTU)
11605     {
11606       cond_code = swap_condition (cond_code);
11607       std::swap (op1, op2);
11608     }
11610   if (!gpc_reg_operand (op1, <MODE>mode))
11611     op1 = force_reg (<MODE>mode, op1);
11612   if (!reg_or_short_operand (op2, <MODE>mode))
11613     op2 = force_reg (<MODE>mode, op2);
11615   rtx tmp = gen_reg_rtx (<MODE>mode);
11616   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11618   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11619   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11621   if (cond_code == LEU)
11622     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11623   else
11624     emit_insn (gen_neg<mode>2 (op0, tmp2));
11626   DONE;
11629 (define_expand "cstore_si_as_di"
11630   [(use (match_operator 1 "unsigned_comparison_operator"
11631          [(match_operand:SI 2 "gpc_reg_operand")
11632           (match_operand:SI 3 "reg_or_short_operand")]))
11633    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11634   ""
11636   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11637   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11639   operands[2] = force_reg (SImode, operands[2]);
11640   operands[3] = force_reg (SImode, operands[3]);
11641   rtx op1 = gen_reg_rtx (DImode);
11642   rtx op2 = gen_reg_rtx (DImode);
11643   convert_move (op1, operands[2], uns_flag);
11644   convert_move (op2, operands[3], uns_flag);
11646   if (cond_code == GT || cond_code == LE)
11647     {
11648       cond_code = swap_condition (cond_code);
11649       std::swap (op1, op2);
11650     }
11652   rtx tmp = gen_reg_rtx (DImode);
11653   rtx tmp2 = gen_reg_rtx (DImode);
11654   emit_insn (gen_subdi3 (tmp, op1, op2));
11655   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11657   rtx tmp3;
11658   switch (cond_code)
11659     {
11660     default:
11661       gcc_unreachable ();
11662     case LT:
11663       tmp3 = tmp2;
11664       break;
11665     case GE:
11666       tmp3 = gen_reg_rtx (DImode);
11667       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11668       break;
11669     }
11671   convert_move (operands[0], tmp3, 1);
11673   DONE;
11676 (define_expand "cstore<mode>4_signed_imm"
11677   [(use (match_operator 1 "signed_comparison_operator"
11678          [(match_operand:GPR 2 "gpc_reg_operand")
11679           (match_operand:GPR 3 "immediate_operand")]))
11680    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11681   ""
11683   bool invert = false;
11685   enum rtx_code cond_code = GET_CODE (operands[1]);
11687   rtx op0 = operands[0];
11688   rtx op1 = operands[2];
11689   HOST_WIDE_INT val = INTVAL (operands[3]);
11691   if (cond_code == GE || cond_code == GT)
11692     {
11693       cond_code = reverse_condition (cond_code);
11694       invert = true;
11695     }
11697   if (cond_code == LE)
11698     val++;
11700   rtx tmp = gen_reg_rtx (<MODE>mode);
11701   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11702   rtx x = gen_reg_rtx (<MODE>mode);
11703   if (val < 0)
11704     emit_insn (gen_and<mode>3 (x, op1, tmp));
11705   else
11706     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11708   if (invert)
11709     {
11710       rtx tmp = gen_reg_rtx (<MODE>mode);
11711       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11712       x = tmp;
11713     }
11715   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11716   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11718   DONE;
11721 (define_expand "cstore<mode>4_unsigned_imm"
11722   [(use (match_operator 1 "unsigned_comparison_operator"
11723          [(match_operand:GPR 2 "gpc_reg_operand")
11724           (match_operand:GPR 3 "immediate_operand")]))
11725    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11726   ""
11728   bool invert = false;
11730   enum rtx_code cond_code = GET_CODE (operands[1]);
11732   rtx op0 = operands[0];
11733   rtx op1 = operands[2];
11734   HOST_WIDE_INT val = INTVAL (operands[3]);
11736   if (cond_code == GEU || cond_code == GTU)
11737     {
11738       cond_code = reverse_condition (cond_code);
11739       invert = true;
11740     }
11742   if (cond_code == LEU)
11743     val++;
11745   rtx tmp = gen_reg_rtx (<MODE>mode);
11746   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11747   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11748   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11749   rtx x = gen_reg_rtx (<MODE>mode);
11750   if (val < 0)
11751     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11752   else
11753     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11755   if (invert)
11756     {
11757       rtx tmp = gen_reg_rtx (<MODE>mode);
11758       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11759       x = tmp;
11760     }
11762   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11763   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11765   DONE;
11768 (define_expand "cstore<mode>4"
11769   [(use (match_operator 1 "comparison_operator"
11770          [(match_operand:GPR 2 "gpc_reg_operand")
11771           (match_operand:GPR 3 "reg_or_short_operand")]))
11772    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11773   ""
11775   /* Use ISEL if the user asked for it.  */
11776   if (TARGET_ISEL)
11777     rs6000_emit_sISEL (<MODE>mode, operands);
11779   /* Expanding EQ and NE directly to some machine instructions does not help
11780      but does hurt combine.  So don't.  */
11781   else if (GET_CODE (operands[1]) == EQ)
11782     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11783   else if (<MODE>mode == Pmode
11784            && GET_CODE (operands[1]) == NE)
11785     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11786   else if (GET_CODE (operands[1]) == NE)
11787     {
11788       rtx tmp = gen_reg_rtx (<MODE>mode);
11789       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11790       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11791     }
11793   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11794      etc. combinations magically work out just right.  */
11795   else if (<MODE>mode == Pmode
11796            && unsigned_comparison_operator (operands[1], VOIDmode))
11797     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11798                                            operands[2], operands[3]));
11800   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11801   else if (<MODE>mode == SImode && Pmode == DImode)
11802     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11803                                     operands[2], operands[3]));
11805   /* For signed comparisons against a constant, we can do some simple
11806      bit-twiddling.  */
11807   else if (signed_comparison_operator (operands[1], VOIDmode)
11808            && CONST_INT_P (operands[3]))
11809     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11810                                              operands[2], operands[3]));
11812   /* And similarly for unsigned comparisons.  */
11813   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11814            && CONST_INT_P (operands[3]))
11815     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11816                                                operands[2], operands[3]));
11818   /* We also do not want to use mfcr for signed comparisons.  */
11819   else if (<MODE>mode == Pmode
11820            && signed_comparison_operator (operands[1], VOIDmode))
11821     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11822                                          operands[2], operands[3]));
11824   /* Everything else, use the mfcr brute force.  */
11825   else
11826     rs6000_emit_sCOND (<MODE>mode, operands);
11828   DONE;
11831 (define_expand "cstore<mode>4"
11832   [(use (match_operator 1 "comparison_operator"
11833          [(match_operand:FP 2 "gpc_reg_operand")
11834           (match_operand:FP 3 "gpc_reg_operand")]))
11835    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11836   ""
11838   rs6000_emit_sCOND (<MODE>mode, operands);
11839   DONE;
11843 (define_expand "stack_protect_set"
11844   [(match_operand 0 "memory_operand")
11845    (match_operand 1 "memory_operand")]
11846   ""
11848   if (rs6000_stack_protector_guard == SSP_TLS)
11849     {
11850       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11851       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11852       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11853       operands[1] = gen_rtx_MEM (Pmode, addr);
11854     }
11856   if (TARGET_64BIT)
11857     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11858   else
11859     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11861   DONE;
11864 (define_insn "stack_protect_setsi"
11865   [(set (match_operand:SI 0 "memory_operand" "=m")
11866         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11867    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11868   "TARGET_32BIT"
11869   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11870   [(set_attr "type" "three")
11871    (set_attr "length" "12")])
11873 (define_insn "stack_protect_setdi"
11874   [(set (match_operand:DI 0 "memory_operand" "=Y")
11875         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11876    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11877   "TARGET_64BIT"
11878   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11879   [(set_attr "type" "three")
11880    (set_attr "length" "12")])
11882 (define_expand "stack_protect_test"
11883   [(match_operand 0 "memory_operand")
11884    (match_operand 1 "memory_operand")
11885    (match_operand 2 "")]
11886   ""
11888   rtx guard = operands[1];
11890   if (rs6000_stack_protector_guard == SSP_TLS)
11891     {
11892       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11893       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11894       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11895       guard = gen_rtx_MEM (Pmode, addr);
11896     }
11898   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11899   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11900   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11901   emit_jump_insn (jump);
11903   DONE;
11906 (define_insn "stack_protect_testsi"
11907   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11908         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11909                       (match_operand:SI 2 "memory_operand" "m,m")]
11910                      UNSPEC_SP_TEST))
11911    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11912    (clobber (match_scratch:SI 3 "=&r,&r"))]
11913   "TARGET_32BIT"
11914   "@
11915    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11916    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11917   [(set_attr "length" "16,20")])
11919 (define_insn "stack_protect_testdi"
11920   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11921         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11922                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11923                      UNSPEC_SP_TEST))
11924    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11925    (clobber (match_scratch:DI 3 "=&r,&r"))]
11926   "TARGET_64BIT"
11927   "@
11928    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11929    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11930   [(set_attr "length" "16,20")])
11933 ;; Here are the actual compare insns.
11934 (define_insn "*cmp<mode>_signed"
11935   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11936         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11937                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11938   ""
11939   "cmp<wd>%I2 %0,%1,%2"
11940   [(set_attr "type" "cmp")])
11942 (define_insn "*cmp<mode>_unsigned"
11943   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11944         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11945                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11946   ""
11947   "cmpl<wd>%I2 %0,%1,%2"
11948   [(set_attr "type" "cmp")])
11950 ;; If we are comparing a register for equality with a large constant,
11951 ;; we can do this with an XOR followed by a compare.  But this is profitable
11952 ;; only if the large constant is only used for the comparison (and in this
11953 ;; case we already have a register to reuse as scratch).
11955 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11956 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11958 (define_peephole2
11959   [(set (match_operand:SI 0 "register_operand")
11960         (match_operand:SI 1 "logical_const_operand" ""))
11961    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11962                        [(match_dup 0)
11963                         (match_operand:SI 2 "logical_const_operand" "")]))
11964    (set (match_operand:CC 4 "cc_reg_operand" "")
11965         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11966                     (match_dup 0)))
11967    (set (pc)
11968         (if_then_else (match_operator 6 "equality_operator"
11969                        [(match_dup 4) (const_int 0)])
11970                       (match_operand 7 "" "")
11971                       (match_operand 8 "" "")))]
11972   "peep2_reg_dead_p (3, operands[0])
11973    && peep2_reg_dead_p (4, operands[4])
11974    && REGNO (operands[0]) != REGNO (operands[5])"
11975  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11976   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11977   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11980   /* Get the constant we are comparing against, and see what it looks like
11981      when sign-extended from 16 to 32 bits.  Then see what constant we could
11982      XOR with SEXTC to get the sign-extended value.  */
11983   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11984                                               SImode,
11985                                               operands[1], operands[2]);
11986   HOST_WIDE_INT c = INTVAL (cnst);
11987   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11988   HOST_WIDE_INT xorv = c ^ sextc;
11990   operands[9] = GEN_INT (xorv);
11991   operands[10] = GEN_INT (sextc);
11994 ;; The following two insns don't exist as single insns, but if we provide
11995 ;; them, we can swap an add and compare, which will enable us to overlap more
11996 ;; of the required delay between a compare and branch.  We generate code for
11997 ;; them by splitting.
11999 (define_insn ""
12000   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12001         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12002                     (match_operand:SI 2 "short_cint_operand" "i")))
12003    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12004         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12005   ""
12006   "#"
12007   [(set_attr "length" "8")])
12009 (define_insn ""
12010   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12011         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12012                        (match_operand:SI 2 "u_short_cint_operand" "i")))
12013    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12014         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12015   ""
12016   "#"
12017   [(set_attr "length" "8")])
12019 (define_split
12020   [(set (match_operand:CC 3 "cc_reg_operand" "")
12021         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12022                     (match_operand:SI 2 "short_cint_operand" "")))
12023    (set (match_operand:SI 0 "gpc_reg_operand" "")
12024         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12025   ""
12026   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12027    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12029 (define_split
12030   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12031         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12032                        (match_operand:SI 2 "u_short_cint_operand" "")))
12033    (set (match_operand:SI 0 "gpc_reg_operand" "")
12034         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12035   ""
12036   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12037    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12039 ;; Only need to compare second words if first words equal
12040 (define_insn "*cmp<mode>_internal1"
12041   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12042         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12043                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12044   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12045    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12046   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12047   [(set_attr "type" "fpcompare")
12048    (set_attr "length" "12")])
12050 (define_insn_and_split "*cmp<mode>_internal2"
12051   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12052         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12053                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12054     (clobber (match_scratch:DF 3 "=d"))
12055     (clobber (match_scratch:DF 4 "=d"))
12056     (clobber (match_scratch:DF 5 "=d"))
12057     (clobber (match_scratch:DF 6 "=d"))
12058     (clobber (match_scratch:DF 7 "=d"))
12059     (clobber (match_scratch:DF 8 "=d"))
12060     (clobber (match_scratch:DF 9 "=d"))
12061     (clobber (match_scratch:DF 10 "=d"))
12062     (clobber (match_scratch:GPR 11 "=b"))]
12063   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12064    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12065   "#"
12066   "&& reload_completed"
12067   [(set (match_dup 3) (match_dup 14))
12068    (set (match_dup 4) (match_dup 15))
12069    (set (match_dup 9) (abs:DF (match_dup 5)))
12070    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12071    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12072                            (label_ref (match_dup 12))
12073                            (pc)))
12074    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12075    (set (pc) (label_ref (match_dup 13)))
12076    (match_dup 12)
12077    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12078    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12079    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12080    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12081    (match_dup 13)]
12083   REAL_VALUE_TYPE rv;
12084   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12085   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12087   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12088   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12089   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12090   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12091   operands[12] = gen_label_rtx ();
12092   operands[13] = gen_label_rtx ();
12093   real_inf (&rv);
12094   operands[14] = force_const_mem (DFmode,
12095                                   const_double_from_real_value (rv, DFmode));
12096   operands[15] = force_const_mem (DFmode,
12097                                   const_double_from_real_value (dconst0,
12098                                                                 DFmode));
12099   if (TARGET_TOC)
12100     {
12101       rtx tocref;
12102       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12103       operands[14] = gen_const_mem (DFmode, tocref);
12104       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12105       operands[15] = gen_const_mem (DFmode, tocref);
12106       set_mem_alias_set (operands[14], get_TOC_alias_set ());
12107       set_mem_alias_set (operands[15], get_TOC_alias_set ());
12108     }
12111 ;; Now we have the scc insns.  We can do some combinations because of the
12112 ;; way the machine works.
12114 ;; Note that this is probably faster if we can put an insn between the
12115 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
12116 ;; cases the insns below which don't use an intermediate CR field will
12117 ;; be used instead.
12118 (define_insn ""
12119   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12120         (match_operator:SI 1 "scc_comparison_operator"
12121                            [(match_operand 2 "cc_reg_operand" "y")
12122                             (const_int 0)]))]
12123   ""
12124   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12125   [(set (attr "type")
12126      (cond [(match_test "TARGET_MFCRF")
12127                 (const_string "mfcrf")
12128            ]
12129         (const_string "mfcr")))
12130    (set_attr "length" "8")])
12132 ;; Same as above, but get the OV/ORDERED bit.
12133 (define_insn "move_from_CR_ov_bit"
12134   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12135         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12136                    UNSPEC_MV_CR_OV))]
12137   "TARGET_ISEL"
12138   "mfcr %0\;rlwinm %0,%0,%t1,1"
12139   [(set_attr "type" "mfcr")
12140    (set_attr "length" "8")])
12142 (define_insn ""
12143   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12144         (match_operator:DI 1 "scc_comparison_operator"
12145                            [(match_operand 2 "cc_reg_operand" "y")
12146                             (const_int 0)]))]
12147   "TARGET_POWERPC64"
12148   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12149   [(set (attr "type")
12150      (cond [(match_test "TARGET_MFCRF")
12151                 (const_string "mfcrf")
12152            ]
12153         (const_string "mfcr")))
12154    (set_attr "length" "8")])
12156 (define_insn ""
12157   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12158         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12159                                        [(match_operand 2 "cc_reg_operand" "y,y")
12160                                         (const_int 0)])
12161                     (const_int 0)))
12162    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12163         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12164   "TARGET_32BIT"
12165   "@
12166    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12167    #"
12168   [(set_attr "type" "shift")
12169    (set_attr "dot" "yes")
12170    (set_attr "length" "8,16")])
12172 (define_split
12173   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12174         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12175                                        [(match_operand 2 "cc_reg_operand" "")
12176                                         (const_int 0)])
12177                     (const_int 0)))
12178    (set (match_operand:SI 3 "gpc_reg_operand" "")
12179         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12180   "TARGET_32BIT && reload_completed"
12181   [(set (match_dup 3)
12182         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12183    (set (match_dup 0)
12184         (compare:CC (match_dup 3)
12185                     (const_int 0)))]
12186   "")
12188 (define_insn ""
12189   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12190         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12191                                       [(match_operand 2 "cc_reg_operand" "y")
12192                                        (const_int 0)])
12193                    (match_operand:SI 3 "const_int_operand" "n")))]
12194   ""
12195   "*
12197   int is_bit = ccr_bit (operands[1], 1);
12198   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12199   int count;
12201   if (is_bit >= put_bit)
12202     count = is_bit - put_bit;
12203   else
12204     count = 32 - (put_bit - is_bit);
12206   operands[4] = GEN_INT (count);
12207   operands[5] = GEN_INT (put_bit);
12209   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12211   [(set (attr "type")
12212      (cond [(match_test "TARGET_MFCRF")
12213                 (const_string "mfcrf")
12214            ]
12215         (const_string "mfcr")))
12216    (set_attr "length" "8")])
12218 (define_insn ""
12219   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12220         (compare:CC
12221          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12222                                        [(match_operand 2 "cc_reg_operand" "y,y")
12223                                         (const_int 0)])
12224                     (match_operand:SI 3 "const_int_operand" "n,n"))
12225          (const_int 0)))
12226    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12227         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12228                    (match_dup 3)))]
12229   ""
12230   "*
12232   int is_bit = ccr_bit (operands[1], 1);
12233   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12234   int count;
12236   /* Force split for non-cc0 compare.  */
12237   if (which_alternative == 1)
12238      return \"#\";
12240   if (is_bit >= put_bit)
12241     count = is_bit - put_bit;
12242   else
12243     count = 32 - (put_bit - is_bit);
12245   operands[5] = GEN_INT (count);
12246   operands[6] = GEN_INT (put_bit);
12248   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12250   [(set_attr "type" "shift")
12251    (set_attr "dot" "yes")
12252    (set_attr "length" "8,16")])
12254 (define_split
12255   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
12256         (compare:CC
12257          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12258                                        [(match_operand 2 "cc_reg_operand")
12259                                         (const_int 0)])
12260                     (match_operand:SI 3 "const_int_operand"))
12261          (const_int 0)))
12262    (set (match_operand:SI 4 "gpc_reg_operand")
12263         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12264                    (match_dup 3)))]
12265   "reload_completed"
12266   [(set (match_dup 4)
12267         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12268                    (match_dup 3)))
12269    (set (match_dup 0)
12270         (compare:CC (match_dup 4)
12271                     (const_int 0)))]
12272   "")
12275 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12276                               (DI "rKJI")])
12278 (define_insn_and_split "eq<mode>3"
12279   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12280         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12281                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12282    (clobber (match_scratch:GPR 3 "=r"))
12283    (clobber (match_scratch:GPR 4 "=r"))]
12284   ""
12285   "#"
12286   ""
12287   [(set (match_dup 4)
12288         (clz:GPR (match_dup 3)))
12289    (set (match_dup 0)
12290         (lshiftrt:GPR (match_dup 4)
12291                       (match_dup 5)))]
12293   operands[3] = rs6000_emit_eqne (<MODE>mode,
12294                                   operands[1], operands[2], operands[3]);
12296   if (GET_CODE (operands[4]) == SCRATCH)
12297     operands[4] = gen_reg_rtx (<MODE>mode);
12299   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12301   [(set (attr "length")
12302         (if_then_else (match_test "operands[2] == const0_rtx")
12303                       (const_string "8")
12304                       (const_string "12")))])
12306 (define_insn_and_split "ne<mode>3"
12307   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12308         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12309               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12310    (clobber (match_scratch:P 3 "=r"))
12311    (clobber (match_scratch:P 4 "=r"))
12312    (clobber (reg:P CA_REGNO))]
12313   "!TARGET_ISEL"
12314   "#"
12315   ""
12316   [(parallel [(set (match_dup 4)
12317                    (plus:P (match_dup 3)
12318                            (const_int -1)))
12319               (set (reg:P CA_REGNO)
12320                    (ne:P (match_dup 3)
12321                          (const_int 0)))])
12322    (parallel [(set (match_dup 0)
12323                    (plus:P (plus:P (not:P (match_dup 4))
12324                                    (reg:P CA_REGNO))
12325                            (match_dup 3)))
12326               (clobber (reg:P CA_REGNO))])]
12328   operands[3] = rs6000_emit_eqne (<MODE>mode,
12329                                   operands[1], operands[2], operands[3]);
12331   if (GET_CODE (operands[4]) == SCRATCH)
12332     operands[4] = gen_reg_rtx (<MODE>mode);
12334   [(set (attr "length")
12335         (if_then_else (match_test "operands[2] == const0_rtx")
12336                       (const_string "8")
12337                       (const_string "12")))])
12339 (define_insn_and_split "*neg_eq_<mode>"
12340   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12341         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12342                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12343    (clobber (match_scratch:P 3 "=r"))
12344    (clobber (match_scratch:P 4 "=r"))
12345    (clobber (reg:P CA_REGNO))]
12346   ""
12347   "#"
12348   ""
12349   [(parallel [(set (match_dup 4)
12350                    (plus:P (match_dup 3)
12351                            (const_int -1)))
12352               (set (reg:P CA_REGNO)
12353                    (ne:P (match_dup 3)
12354                          (const_int 0)))])
12355    (parallel [(set (match_dup 0)
12356                    (plus:P (reg:P CA_REGNO)
12357                            (const_int -1)))
12358               (clobber (reg:P CA_REGNO))])]
12360   operands[3] = rs6000_emit_eqne (<MODE>mode,
12361                                   operands[1], operands[2], operands[3]);
12363   if (GET_CODE (operands[4]) == SCRATCH)
12364     operands[4] = gen_reg_rtx (<MODE>mode);
12366   [(set (attr "length")
12367         (if_then_else (match_test "operands[2] == const0_rtx")
12368                       (const_string "8")
12369                       (const_string "12")))])
12371 (define_insn_and_split "*neg_ne_<mode>"
12372   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12373         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12374                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12375    (clobber (match_scratch:P 3 "=r"))
12376    (clobber (match_scratch:P 4 "=r"))
12377    (clobber (reg:P CA_REGNO))]
12378   ""
12379   "#"
12380   ""
12381   [(parallel [(set (match_dup 4)
12382                    (neg:P (match_dup 3)))
12383               (set (reg:P CA_REGNO)
12384                    (eq:P (match_dup 3)
12385                          (const_int 0)))])
12386    (parallel [(set (match_dup 0)
12387                    (plus:P (reg:P CA_REGNO)
12388                            (const_int -1)))
12389               (clobber (reg:P CA_REGNO))])]
12391   operands[3] = rs6000_emit_eqne (<MODE>mode,
12392                                   operands[1], operands[2], operands[3]);
12394   if (GET_CODE (operands[4]) == SCRATCH)
12395     operands[4] = gen_reg_rtx (<MODE>mode);
12397   [(set (attr "length")
12398         (if_then_else (match_test "operands[2] == const0_rtx")
12399                       (const_string "8")
12400                       (const_string "12")))])
12402 (define_insn_and_split "*plus_eq_<mode>"
12403   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12404         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12405                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12406                 (match_operand:P 3 "gpc_reg_operand" "r")))
12407    (clobber (match_scratch:P 4 "=r"))
12408    (clobber (match_scratch:P 5 "=r"))
12409    (clobber (reg:P CA_REGNO))]
12410   ""
12411   "#"
12412   ""
12413   [(parallel [(set (match_dup 5)
12414                    (neg:P (match_dup 4)))
12415               (set (reg:P CA_REGNO)
12416                    (eq:P (match_dup 4)
12417                          (const_int 0)))])
12418    (parallel [(set (match_dup 0)
12419                    (plus:P (match_dup 3)
12420                            (reg:P CA_REGNO)))
12421               (clobber (reg:P CA_REGNO))])]
12423   operands[4] = rs6000_emit_eqne (<MODE>mode,
12424                                   operands[1], operands[2], operands[4]);
12426   if (GET_CODE (operands[5]) == SCRATCH)
12427     operands[5] = gen_reg_rtx (<MODE>mode);
12429   [(set (attr "length")
12430         (if_then_else (match_test "operands[2] == const0_rtx")
12431                       (const_string "8")
12432                       (const_string "12")))])
12434 (define_insn_and_split "*plus_ne_<mode>"
12435   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12436         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12437                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12438                 (match_operand:P 3 "gpc_reg_operand" "r")))
12439    (clobber (match_scratch:P 4 "=r"))
12440    (clobber (match_scratch:P 5 "=r"))
12441    (clobber (reg:P CA_REGNO))]
12442   ""
12443   "#"
12444   ""
12445   [(parallel [(set (match_dup 5)
12446                    (plus:P (match_dup 4)
12447                            (const_int -1)))
12448               (set (reg:P CA_REGNO)
12449                    (ne:P (match_dup 4)
12450                          (const_int 0)))])
12451    (parallel [(set (match_dup 0)
12452                    (plus:P (match_dup 3)
12453                            (reg:P CA_REGNO)))
12454               (clobber (reg:P CA_REGNO))])]
12456   operands[4] = rs6000_emit_eqne (<MODE>mode,
12457                                   operands[1], operands[2], operands[4]);
12459   if (GET_CODE (operands[5]) == SCRATCH)
12460     operands[5] = gen_reg_rtx (<MODE>mode);
12462   [(set (attr "length")
12463         (if_then_else (match_test "operands[2] == const0_rtx")
12464                       (const_string "8")
12465                       (const_string "12")))])
12467 (define_insn_and_split "*minus_eq_<mode>"
12468   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12469         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12470                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12471                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12472    (clobber (match_scratch:P 4 "=r"))
12473    (clobber (match_scratch:P 5 "=r"))
12474    (clobber (reg:P CA_REGNO))]
12475   ""
12476   "#"
12477   ""
12478   [(parallel [(set (match_dup 5)
12479                    (plus:P (match_dup 4)
12480                            (const_int -1)))
12481               (set (reg:P CA_REGNO)
12482                    (ne:P (match_dup 4)
12483                          (const_int 0)))])
12484    (parallel [(set (match_dup 0)
12485                    (plus:P (plus:P (match_dup 3)
12486                                    (reg:P CA_REGNO))
12487                            (const_int -1)))
12488               (clobber (reg:P CA_REGNO))])]
12490   operands[4] = rs6000_emit_eqne (<MODE>mode,
12491                                   operands[1], operands[2], operands[4]);
12493   if (GET_CODE (operands[5]) == SCRATCH)
12494     operands[5] = gen_reg_rtx (<MODE>mode);
12496   [(set (attr "length")
12497         (if_then_else (match_test "operands[2] == const0_rtx")
12498                       (const_string "8")
12499                       (const_string "12")))])
12501 (define_insn_and_split "*minus_ne_<mode>"
12502   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12503         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12504                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12505                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12506    (clobber (match_scratch:P 4 "=r"))
12507    (clobber (match_scratch:P 5 "=r"))
12508    (clobber (reg:P CA_REGNO))]
12509   ""
12510   "#"
12511   ""
12512   [(parallel [(set (match_dup 5)
12513                    (neg:P (match_dup 4)))
12514               (set (reg:P CA_REGNO)
12515                    (eq:P (match_dup 4)
12516                          (const_int 0)))])
12517    (parallel [(set (match_dup 0)
12518                    (plus:P (plus:P (match_dup 3)
12519                                    (reg:P CA_REGNO))
12520                            (const_int -1)))
12521               (clobber (reg:P CA_REGNO))])]
12523   operands[4] = rs6000_emit_eqne (<MODE>mode,
12524                                   operands[1], operands[2], operands[4]);
12526   if (GET_CODE (operands[5]) == SCRATCH)
12527     operands[5] = gen_reg_rtx (<MODE>mode);
12529   [(set (attr "length")
12530         (if_then_else (match_test "operands[2] == const0_rtx")
12531                       (const_string "8")
12532                       (const_string "12")))])
12534 (define_insn_and_split "*eqsi3_ext<mode>"
12535   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12536         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12537                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12538    (clobber (match_scratch:SI 3 "=r"))
12539    (clobber (match_scratch:SI 4 "=r"))]
12540   ""
12541   "#"
12542   ""
12543   [(set (match_dup 4)
12544         (clz:SI (match_dup 3)))
12545    (set (match_dup 0)
12546         (zero_extend:EXTSI
12547           (lshiftrt:SI (match_dup 4)
12548                        (const_int 5))))]
12550   operands[3] = rs6000_emit_eqne (SImode,
12551                                   operands[1], operands[2], operands[3]);
12553   if (GET_CODE (operands[4]) == SCRATCH)
12554     operands[4] = gen_reg_rtx (SImode);
12556   [(set (attr "length")
12557         (if_then_else (match_test "operands[2] == const0_rtx")
12558                       (const_string "8")
12559                       (const_string "12")))])
12561 (define_insn_and_split "*nesi3_ext<mode>"
12562   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12563         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12564                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12565    (clobber (match_scratch:SI 3 "=r"))
12566    (clobber (match_scratch:SI 4 "=r"))
12567    (clobber (match_scratch:EXTSI 5 "=r"))]
12568   ""
12569   "#"
12570   ""
12571   [(set (match_dup 4)
12572         (clz:SI (match_dup 3)))
12573    (set (match_dup 5)
12574         (zero_extend:EXTSI
12575           (lshiftrt:SI (match_dup 4)
12576                        (const_int 5))))
12577    (set (match_dup 0)
12578         (xor:EXTSI (match_dup 5)
12579                    (const_int 1)))]
12581   operands[3] = rs6000_emit_eqne (SImode,
12582                                   operands[1], operands[2], operands[3]);
12584   if (GET_CODE (operands[4]) == SCRATCH)
12585     operands[4] = gen_reg_rtx (SImode);
12586   if (GET_CODE (operands[5]) == SCRATCH)
12587     operands[5] = gen_reg_rtx (<MODE>mode);
12589   [(set (attr "length")
12590         (if_then_else (match_test "operands[2] == const0_rtx")
12591                       (const_string "12")
12592                       (const_string "16")))])
12594 ;; Define both directions of branch and return.  If we need a reload
12595 ;; register, we'd rather use CR0 since it is much easier to copy a
12596 ;; register CC value to there.
12598 (define_insn ""
12599   [(set (pc)
12600         (if_then_else (match_operator 1 "branch_comparison_operator"
12601                                       [(match_operand 2
12602                                                       "cc_reg_operand" "y")
12603                                        (const_int 0)])
12604                       (label_ref (match_operand 0 "" ""))
12605                       (pc)))]
12606   ""
12607   "*
12609   return output_cbranch (operands[1], \"%l0\", 0, insn);
12611   [(set_attr "type" "branch")])
12613 (define_insn ""
12614   [(set (pc)
12615         (if_then_else (match_operator 0 "branch_comparison_operator"
12616                                       [(match_operand 1
12617                                                       "cc_reg_operand" "y")
12618                                        (const_int 0)])
12619                       (any_return)
12620                       (pc)))]
12621   "<return_pred>"
12622   "*
12624   return output_cbranch (operands[0], NULL, 0, insn);
12626   [(set_attr "type" "jmpreg")
12627    (set_attr "length" "4")])
12629 (define_insn ""
12630   [(set (pc)
12631         (if_then_else (match_operator 1 "branch_comparison_operator"
12632                                       [(match_operand 2
12633                                                       "cc_reg_operand" "y")
12634                                        (const_int 0)])
12635                       (pc)
12636                       (label_ref (match_operand 0 "" ""))))]
12637   ""
12638   "*
12640   return output_cbranch (operands[1], \"%l0\", 1, insn);
12642   [(set_attr "type" "branch")])
12644 (define_insn ""
12645   [(set (pc)
12646         (if_then_else (match_operator 0 "branch_comparison_operator"
12647                                       [(match_operand 1
12648                                                       "cc_reg_operand" "y")
12649                                        (const_int 0)])
12650                       (pc)
12651                       (any_return)))]
12652   "<return_pred>"
12653   "*
12655   return output_cbranch (operands[0], NULL, 1, insn);
12657   [(set_attr "type" "jmpreg")
12658    (set_attr "length" "4")])
12660 ;; Logic on condition register values.
12662 ; This pattern matches things like
12663 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12664 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12665 ;                                  (const_int 1)))
12666 ; which are generated by the branch logic.
12667 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12669 (define_insn "*cceq_ior_compare"
12670   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12671         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12672                         [(match_operator:SI 2
12673                                       "branch_positive_comparison_operator"
12674                                       [(match_operand 3
12675                                                       "cc_reg_operand" "y,y")
12676                                        (const_int 0)])
12677                          (match_operator:SI 4
12678                                       "branch_positive_comparison_operator"
12679                                       [(match_operand 5
12680                                                       "cc_reg_operand" "0,y")
12681                                        (const_int 0)])])
12682                       (const_int 1)))]
12683   ""
12684   "cr%q1 %E0,%j2,%j4"
12685   [(set_attr "type" "cr_logical,delayed_cr")])
12687 ; Why is the constant -1 here, but 1 in the previous pattern?
12688 ; Because ~1 has all but the low bit set.
12689 (define_insn ""
12690   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12691         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12692                         [(not:SI (match_operator:SI 2
12693                                       "branch_positive_comparison_operator"
12694                                       [(match_operand 3
12695                                                       "cc_reg_operand" "y,y")
12696                                        (const_int 0)]))
12697                          (match_operator:SI 4
12698                                 "branch_positive_comparison_operator"
12699                                 [(match_operand 5
12700                                                 "cc_reg_operand" "0,y")
12701                                  (const_int 0)])])
12702                       (const_int -1)))]
12703   ""
12704   "cr%q1 %E0,%j2,%j4"
12705   [(set_attr "type" "cr_logical,delayed_cr")])
12707 (define_insn "*cceq_rev_compare"
12708   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12709         (compare:CCEQ (match_operator:SI 1
12710                                       "branch_positive_comparison_operator"
12711                                       [(match_operand 2
12712                                                       "cc_reg_operand" "0,y")
12713                                        (const_int 0)])
12714                       (const_int 0)))]
12715   ""
12716   "crnot %E0,%j1"
12717   [(set_attr "type" "cr_logical,delayed_cr")])
12719 ;; If we are comparing the result of two comparisons, this can be done
12720 ;; using creqv or crxor.
12722 (define_insn_and_split ""
12723   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12724         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12725                               [(match_operand 2 "cc_reg_operand" "y")
12726                                (const_int 0)])
12727                       (match_operator 3 "branch_comparison_operator"
12728                               [(match_operand 4 "cc_reg_operand" "y")
12729                                (const_int 0)])))]
12730   ""
12731   "#"
12732   ""
12733   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12734                                     (match_dup 5)))]
12735   "
12737   int positive_1, positive_2;
12739   positive_1 = branch_positive_comparison_operator (operands[1],
12740                                                     GET_MODE (operands[1]));
12741   positive_2 = branch_positive_comparison_operator (operands[3],
12742                                                     GET_MODE (operands[3]));
12744   if (! positive_1)
12745     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12746                                                             GET_CODE (operands[1])),
12747                                   SImode,
12748                                   operands[2], const0_rtx);
12749   else if (GET_MODE (operands[1]) != SImode)
12750     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12751                                   operands[2], const0_rtx);
12753   if (! positive_2)
12754     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12755                                                             GET_CODE (operands[3])),
12756                                   SImode,
12757                                   operands[4], const0_rtx);
12758   else if (GET_MODE (operands[3]) != SImode)
12759     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12760                                   operands[4], const0_rtx);
12762   if (positive_1 == positive_2)
12763     {
12764       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12765       operands[5] = constm1_rtx;
12766     }
12767   else
12768     {
12769       operands[5] = const1_rtx;
12770     }
12773 ;; Unconditional branch and return.
12775 (define_insn "jump"
12776   [(set (pc)
12777         (label_ref (match_operand 0 "" "")))]
12778   ""
12779   "b %l0"
12780   [(set_attr "type" "branch")])
12782 (define_insn "<return_str>return"
12783   [(any_return)]
12784   "<return_pred>"
12785   "blr"
12786   [(set_attr "type" "jmpreg")])
12788 (define_expand "indirect_jump"
12789   [(set (pc) (match_operand 0 "register_operand" ""))])
12791 (define_insn "*indirect_jump<mode>"
12792   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12793   ""
12794   "@
12795    bctr
12796    blr"
12797   [(set_attr "type" "jmpreg")])
12799 ;; Table jump for switch statements:
12800 (define_expand "tablejump"
12801   [(use (match_operand 0 "" ""))
12802    (use (label_ref (match_operand 1 "" "")))]
12803   ""
12804   "
12806   if (TARGET_32BIT)
12807     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12808   else
12809     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12810   DONE;
12813 (define_expand "tablejumpsi"
12814   [(set (match_dup 3)
12815         (plus:SI (match_operand:SI 0 "" "")
12816                  (match_dup 2)))
12817    (parallel [(set (pc) (match_dup 3))
12818               (use (label_ref (match_operand 1 "" "")))])]
12819   "TARGET_32BIT"
12820   "
12821 { operands[0] = force_reg (SImode, operands[0]);
12822   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12823   operands[3] = gen_reg_rtx (SImode);
12826 (define_expand "tablejumpdi"
12827   [(set (match_dup 4)
12828         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12829    (set (match_dup 3)
12830         (plus:DI (match_dup 4)
12831                  (match_dup 2)))
12832    (parallel [(set (pc) (match_dup 3))
12833               (use (label_ref (match_operand 1 "" "")))])]
12834   "TARGET_64BIT"
12835   "
12836 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12837   operands[3] = gen_reg_rtx (DImode);
12838   operands[4] = gen_reg_rtx (DImode);
12841 (define_insn "*tablejump<mode>_internal1"
12842   [(set (pc)
12843         (match_operand:P 0 "register_operand" "c,*l"))
12844    (use (label_ref (match_operand 1 "" "")))]
12845   ""
12846   "@
12847    bctr
12848    blr"
12849   [(set_attr "type" "jmpreg")])
12851 (define_insn "nop"
12852   [(unspec [(const_int 0)] UNSPEC_NOP)]
12853   ""
12854   "nop")
12856 (define_insn "group_ending_nop"
12857   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12858   ""
12859   "*
12861   if (rs6000_cpu_attr == CPU_POWER6)
12862     return \"ori 1,1,0\";
12863   return \"ori 2,2,0\";
12866 ;; Define the subtract-one-and-jump insns, starting with the template
12867 ;; so loop.c knows what to generate.
12869 (define_expand "doloop_end"
12870   [(use (match_operand 0 "" ""))        ; loop pseudo
12871    (use (match_operand 1 "" ""))]       ; label
12872   ""
12873   "
12875   if (TARGET_64BIT)
12876     {
12877       if (GET_MODE (operands[0]) != DImode)
12878         FAIL;
12879       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12880     }
12881   else
12882     {
12883       if (GET_MODE (operands[0]) != SImode)
12884         FAIL;
12885       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12886     }
12887   DONE;
12890 (define_expand "ctr<mode>"
12891   [(parallel [(set (pc)
12892                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12893                                      (const_int 1))
12894                                  (label_ref (match_operand 1 "" ""))
12895                                  (pc)))
12896               (set (match_dup 0)
12897                    (plus:P (match_dup 0)
12898                             (const_int -1)))
12899               (clobber (match_scratch:CC 2 ""))
12900               (clobber (match_scratch:P 3 ""))])]
12901   ""
12902   "")
12904 ;; We need to be able to do this for any operand, including MEM, or we
12905 ;; will cause reload to blow up since we don't allow output reloads on
12906 ;; JUMP_INSNs.
12907 ;; For the length attribute to be calculated correctly, the
12908 ;; label MUST be operand 0.
12909 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12910 ;; the ctr<mode> insns.
12912 (define_insn "ctr<mode>_internal1"
12913   [(set (pc)
12914         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12915                           (const_int 1))
12916                       (label_ref (match_operand 0 "" ""))
12917                       (pc)))
12918    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12919         (plus:P (match_dup 1)
12920                  (const_int -1)))
12921    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12922    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12923   ""
12924   "*
12926   if (which_alternative != 0)
12927     return \"#\";
12928   else if (get_attr_length (insn) == 4)
12929     return \"bdnz %l0\";
12930   else
12931     return \"bdz $+8\;b %l0\";
12933   [(set_attr "type" "branch")
12934    (set_attr "length" "*,16,20,20")])
12936 (define_insn "ctr<mode>_internal2"
12937   [(set (pc)
12938         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12939                           (const_int 1))
12940                       (pc)
12941                       (label_ref (match_operand 0 "" ""))))
12942    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12943         (plus:P (match_dup 1)
12944                  (const_int -1)))
12945    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12946    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12947   ""
12948   "*
12950   if (which_alternative != 0)
12951     return \"#\";
12952   else if (get_attr_length (insn) == 4)
12953     return \"bdz %l0\";
12954   else
12955     return \"bdnz $+8\;b %l0\";
12957   [(set_attr "type" "branch")
12958    (set_attr "length" "*,16,20,20")])
12960 ;; Similar but use EQ
12962 (define_insn "ctr<mode>_internal3"
12963   [(set (pc)
12964         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12965                           (const_int 1))
12966                       (label_ref (match_operand 0 "" ""))
12967                       (pc)))
12968    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12969         (plus:P (match_dup 1)
12970                  (const_int -1)))
12971    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12972    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12973   ""
12974   "*
12976   if (which_alternative != 0)
12977     return \"#\";
12978   else if (get_attr_length (insn) == 4)
12979     return \"bdz %l0\";
12980   else
12981     return \"bdnz $+8\;b %l0\";
12983   [(set_attr "type" "branch")
12984    (set_attr "length" "*,16,20,20")])
12986 (define_insn "ctr<mode>_internal4"
12987   [(set (pc)
12988         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12989                           (const_int 1))
12990                       (pc)
12991                       (label_ref (match_operand 0 "" ""))))
12992    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12993         (plus:P (match_dup 1)
12994                  (const_int -1)))
12995    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12996    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12997   ""
12998   "*
13000   if (which_alternative != 0)
13001     return \"#\";
13002   else if (get_attr_length (insn) == 4)
13003     return \"bdnz %l0\";
13004   else
13005     return \"bdz $+8\;b %l0\";
13007   [(set_attr "type" "branch")
13008    (set_attr "length" "*,16,20,20")])
13010 ;; Now the splitters if we could not allocate the CTR register
13012 (define_split
13013   [(set (pc)
13014         (if_then_else (match_operator 2 "comparison_operator"
13015                                       [(match_operand:P 1 "gpc_reg_operand" "")
13016                                        (const_int 1)])
13017                       (match_operand 5 "" "")
13018                       (match_operand 6 "" "")))
13019    (set (match_operand:P 0 "int_reg_operand" "")
13020         (plus:P (match_dup 1) (const_int -1)))
13021    (clobber (match_scratch:CC 3 ""))
13022    (clobber (match_scratch:P 4 ""))]
13023   "reload_completed"
13024   [(set (match_dup 3)
13025         (compare:CC (match_dup 1)
13026                     (const_int 1)))
13027    (set (match_dup 0)
13028         (plus:P (match_dup 1)
13029                 (const_int -1)))
13030    (set (pc) (if_then_else (match_dup 7)
13031                            (match_dup 5)
13032                            (match_dup 6)))]
13033   "
13034 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13035                                 operands[3], const0_rtx); }")
13037 (define_split
13038   [(set (pc)
13039         (if_then_else (match_operator 2 "comparison_operator"
13040                                       [(match_operand:P 1 "gpc_reg_operand" "")
13041                                        (const_int 1)])
13042                       (match_operand 5 "" "")
13043                       (match_operand 6 "" "")))
13044    (set (match_operand:P 0 "nonimmediate_operand" "")
13045         (plus:P (match_dup 1) (const_int -1)))
13046    (clobber (match_scratch:CC 3 ""))
13047    (clobber (match_scratch:P 4 ""))]
13048   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13049   [(set (match_dup 3)
13050         (compare:CC (match_dup 1)
13051                     (const_int 1)))
13052    (set (match_dup 4)
13053         (plus:P (match_dup 1)
13054                 (const_int -1)))
13055    (set (match_dup 0)
13056         (match_dup 4))
13057    (set (pc) (if_then_else (match_dup 7)
13058                            (match_dup 5)
13059                            (match_dup 6)))]
13060   "
13061 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13062                                 operands[3], const0_rtx); }")
13064 (define_insn "trap"
13065   [(trap_if (const_int 1) (const_int 0))]
13066   ""
13067   "trap"
13068   [(set_attr "type" "trap")])
13070 (define_expand "ctrap<mode>4"
13071   [(trap_if (match_operator 0 "ordered_comparison_operator"
13072                             [(match_operand:GPR 1 "register_operand")
13073                              (match_operand:GPR 2 "reg_or_short_operand")])
13074             (match_operand 3 "zero_constant" ""))]
13075   ""
13076   "")
13078 (define_insn ""
13079   [(trap_if (match_operator 0 "ordered_comparison_operator"
13080                             [(match_operand:GPR 1 "register_operand" "r")
13081                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13082             (const_int 0))]
13083   ""
13084   "t<wd>%V0%I2 %1,%2"
13085   [(set_attr "type" "trap")])
13087 ;; Insns related to generating the function prologue and epilogue.
13089 (define_expand "prologue"
13090   [(use (const_int 0))]
13091   ""
13093   rs6000_emit_prologue ();
13094   if (!TARGET_SCHED_PROLOG)
13095     emit_insn (gen_blockage ());
13096   DONE;
13099 (define_insn "*movesi_from_cr_one"
13100   [(match_parallel 0 "mfcr_operation"
13101                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13102                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13103                                      (match_operand 3 "immediate_operand" "n")]
13104                           UNSPEC_MOVESI_FROM_CR))])]
13105   "TARGET_MFCRF"
13106   "*
13108   int mask = 0;
13109   int i;
13110   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13111   {
13112     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13113     operands[4] = GEN_INT (mask);
13114     output_asm_insn (\"mfcr %1,%4\", operands);
13115   }
13116   return \"\";
13118   [(set_attr "type" "mfcrf")])
13120 ;; Don't include the volatile CRs since their values are not used wrt CR save
13121 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13122 ;; prologue past an insn (early exit test) that defines a register used in the
13123 ;; prologue.
13124 (define_insn "prologue_movesi_from_cr"
13125   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13126         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13127                     (reg:CC CR4_REGNO)]
13128                    UNSPEC_MOVESI_FROM_CR))]
13129   ""
13130   "mfcr %0"
13131   [(set_attr "type" "mfcr")])
13133 (define_insn "*crsave"
13134   [(match_parallel 0 "crsave_operation"
13135                    [(set (match_operand:SI 1 "memory_operand" "=m")
13136                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13137   ""
13138   "stw %2,%1"
13139   [(set_attr "type" "store")])
13141 (define_insn "*stmw"
13142   [(match_parallel 0 "stmw_operation"
13143                    [(set (match_operand:SI 1 "memory_operand" "=m")
13144                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13145   "TARGET_MULTIPLE"
13146   "stmw %2,%1"
13147   [(set_attr "type" "store")
13148    (set_attr "update" "yes")
13149    (set_attr "indexed" "yes")])
13151 ; The following comment applies to:
13152 ;     save_gpregs_*
13153 ;     save_fpregs_*
13154 ;     restore_gpregs*
13155 ;     return_and_restore_gpregs*
13156 ;     return_and_restore_fpregs*
13157 ;     return_and_restore_fpregs_aix*
13159 ; The out-of-line save / restore functions expects one input argument.
13160 ; Since those are not standard call_insn's, we must avoid using
13161 ; MATCH_OPERAND for that argument. That way the register rename
13162 ; optimization will not try to rename this register.
13163 ; Each pattern is repeated for each possible register number used in 
13164 ; various ABIs (r11, r1, and for some functions r12)
13166 (define_insn "*save_gpregs_<mode>_r11"
13167   [(match_parallel 0 "any_parallel_operand"
13168                    [(clobber (reg:P LR_REGNO))
13169                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13170                     (use (reg:P 11))
13171                     (set (match_operand:P 2 "memory_operand" "=m")
13172                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13173   ""
13174   "bl %1"
13175   [(set_attr "type" "branch")
13176    (set_attr "length" "4")])
13178 (define_insn "*save_gpregs_<mode>_r12"
13179   [(match_parallel 0 "any_parallel_operand"
13180                    [(clobber (reg:P LR_REGNO))
13181                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13182                     (use (reg:P 12))
13183                     (set (match_operand:P 2 "memory_operand" "=m")
13184                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13185   ""
13186   "bl %1"
13187   [(set_attr "type" "branch")
13188    (set_attr "length" "4")])
13190 (define_insn "*save_gpregs_<mode>_r1"
13191   [(match_parallel 0 "any_parallel_operand"
13192                    [(clobber (reg:P LR_REGNO))
13193                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13194                     (use (reg:P 1))
13195                     (set (match_operand:P 2 "memory_operand" "=m")
13196                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13197   ""
13198   "bl %1"
13199   [(set_attr "type" "branch")
13200    (set_attr "length" "4")])
13202 (define_insn "*save_fpregs_<mode>_r11"
13203   [(match_parallel 0 "any_parallel_operand"
13204                    [(clobber (reg:P LR_REGNO))
13205                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13206                     (use (reg:P 11))
13207                     (set (match_operand:DF 2 "memory_operand" "=m")
13208                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13209   ""
13210   "bl %1"
13211   [(set_attr "type" "branch")
13212    (set_attr "length" "4")])
13214 (define_insn "*save_fpregs_<mode>_r12"
13215   [(match_parallel 0 "any_parallel_operand"
13216                    [(clobber (reg:P LR_REGNO))
13217                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13218                     (use (reg:P 12))
13219                     (set (match_operand:DF 2 "memory_operand" "=m")
13220                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13221   ""
13222   "bl %1"
13223   [(set_attr "type" "branch")
13224    (set_attr "length" "4")])
13226 (define_insn "*save_fpregs_<mode>_r1"
13227   [(match_parallel 0 "any_parallel_operand"
13228                    [(clobber (reg:P LR_REGNO))
13229                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13230                     (use (reg:P 1))
13231                     (set (match_operand:DF 2 "memory_operand" "=m")
13232                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13233   ""
13234   "bl %1"
13235   [(set_attr "type" "branch")
13236    (set_attr "length" "4")])
13238 ; This is to explain that changes to the stack pointer should
13239 ; not be moved over loads from or stores to stack memory.
13240 (define_insn "stack_tie"
13241   [(match_parallel 0 "tie_operand"
13242                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13243   ""
13244   ""
13245   [(set_attr "length" "0")])
13247 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13248 ; stay behind all restores from the stack, it cannot be reordered to before
13249 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13250 (define_insn "stack_restore_tie"
13251   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13252         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13253                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13254    (set (mem:BLK (scratch)) (const_int 0))]
13255   "TARGET_32BIT"
13256   "@
13257    mr %0,%1
13258    add%I2 %0,%1,%2"
13259   [(set_attr "type" "*,add")])
13261 (define_expand "epilogue"
13262   [(use (const_int 0))]
13263   ""
13265   if (!TARGET_SCHED_PROLOG)
13266     emit_insn (gen_blockage ());
13267   rs6000_emit_epilogue (FALSE);
13268   DONE;
13271 ; On some processors, doing the mtcrf one CC register at a time is
13272 ; faster (like on the 604e).  On others, doing them all at once is
13273 ; faster; for instance, on the 601 and 750.
13275 (define_expand "movsi_to_cr_one"
13276   [(set (match_operand:CC 0 "cc_reg_operand" "")
13277         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13278                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13279   ""
13280   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13282 (define_insn "*movsi_to_cr"
13283   [(match_parallel 0 "mtcrf_operation"
13284                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13285                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13286                                      (match_operand 3 "immediate_operand" "n")]
13287                                     UNSPEC_MOVESI_TO_CR))])]
13288  ""
13289  "*
13291   int mask = 0;
13292   int i;
13293   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13294     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13295   operands[4] = GEN_INT (mask);
13296   return \"mtcrf %4,%2\";
13298   [(set_attr "type" "mtcr")])
13300 (define_insn "*mtcrfsi"
13301   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13302         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13303                     (match_operand 2 "immediate_operand" "n")]
13304                    UNSPEC_MOVESI_TO_CR))]
13305   "GET_CODE (operands[0]) == REG
13306    && CR_REGNO_P (REGNO (operands[0]))
13307    && GET_CODE (operands[2]) == CONST_INT
13308    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13309   "mtcrf %R0,%1"
13310   [(set_attr "type" "mtcr")])
13312 ; The load-multiple instructions have similar properties.
13313 ; Note that "load_multiple" is a name known to the machine-independent
13314 ; code that actually corresponds to the PowerPC load-string.
13316 (define_insn "*lmw"
13317   [(match_parallel 0 "lmw_operation"
13318                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13319                          (match_operand:SI 2 "memory_operand" "m"))])]
13320   "TARGET_MULTIPLE"
13321   "lmw %1,%2"
13322   [(set_attr "type" "load")
13323    (set_attr "update" "yes")
13324    (set_attr "indexed" "yes")
13325    (set_attr "cell_micro" "always")])
13327 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13328 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13330 ; The following comment applies to:
13331 ;     save_gpregs_*
13332 ;     save_fpregs_*
13333 ;     restore_gpregs*
13334 ;     return_and_restore_gpregs*
13335 ;     return_and_restore_fpregs*
13336 ;     return_and_restore_fpregs_aix*
13338 ; The out-of-line save / restore functions expects one input argument.
13339 ; Since those are not standard call_insn's, we must avoid using
13340 ; MATCH_OPERAND for that argument. That way the register rename
13341 ; optimization will not try to rename this register.
13342 ; Each pattern is repeated for each possible register number used in 
13343 ; various ABIs (r11, r1, and for some functions r12)
13345 (define_insn "*restore_gpregs_<mode>_r11"
13346  [(match_parallel 0 "any_parallel_operand"
13347                   [(clobber (reg:P LR_REGNO))
13348                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13349                    (use (reg:P 11))
13350                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13351                         (match_operand:P 3 "memory_operand" "m"))])]
13352  ""
13353  "bl %1"
13354  [(set_attr "type" "branch")
13355   (set_attr "length" "4")])
13357 (define_insn "*restore_gpregs_<mode>_r12"
13358  [(match_parallel 0 "any_parallel_operand"
13359                   [(clobber (reg:P LR_REGNO))
13360                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13361                    (use (reg:P 12))
13362                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13363                         (match_operand:P 3 "memory_operand" "m"))])]
13364  ""
13365  "bl %1"
13366  [(set_attr "type" "branch")
13367   (set_attr "length" "4")])
13369 (define_insn "*restore_gpregs_<mode>_r1"
13370  [(match_parallel 0 "any_parallel_operand"
13371                   [(clobber (reg:P LR_REGNO))
13372                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13373                    (use (reg:P 1))
13374                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13375                         (match_operand:P 3 "memory_operand" "m"))])]
13376  ""
13377  "bl %1"
13378  [(set_attr "type" "branch")
13379   (set_attr "length" "4")])
13381 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13382  [(match_parallel 0 "any_parallel_operand"
13383                   [(return)
13384                    (clobber (reg:P LR_REGNO))
13385                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13386                    (use (reg:P 11))
13387                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13388                         (match_operand:P 3 "memory_operand" "m"))])]
13389  ""
13390  "b %1"
13391  [(set_attr "type" "branch")
13392   (set_attr "length" "4")])
13394 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13395  [(match_parallel 0 "any_parallel_operand"
13396                   [(return)
13397                    (clobber (reg:P LR_REGNO))
13398                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13399                    (use (reg:P 12))
13400                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13401                         (match_operand:P 3 "memory_operand" "m"))])]
13402  ""
13403  "b %1"
13404  [(set_attr "type" "branch")
13405   (set_attr "length" "4")])
13407 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13408  [(match_parallel 0 "any_parallel_operand"
13409                   [(return)
13410                    (clobber (reg:P LR_REGNO))
13411                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13412                    (use (reg:P 1))
13413                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13414                         (match_operand:P 3 "memory_operand" "m"))])]
13415  ""
13416  "b %1"
13417  [(set_attr "type" "branch")
13418   (set_attr "length" "4")])
13420 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13421  [(match_parallel 0 "any_parallel_operand"
13422                   [(return)
13423                    (clobber (reg:P LR_REGNO))
13424                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13425                    (use (reg:P 11))
13426                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13427                         (match_operand:DF 3 "memory_operand" "m"))])]
13428  ""
13429  "b %1"
13430  [(set_attr "type" "branch")
13431   (set_attr "length" "4")])
13433 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13434  [(match_parallel 0 "any_parallel_operand"
13435                   [(return)
13436                    (clobber (reg:P LR_REGNO))
13437                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13438                    (use (reg:P 12))
13439                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13440                         (match_operand:DF 3 "memory_operand" "m"))])]
13441  ""
13442  "b %1"
13443  [(set_attr "type" "branch")
13444   (set_attr "length" "4")])
13446 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13447  [(match_parallel 0 "any_parallel_operand"
13448                   [(return)
13449                    (clobber (reg:P LR_REGNO))
13450                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13451                    (use (reg:P 1))
13452                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13453                         (match_operand:DF 3 "memory_operand" "m"))])]
13454  ""
13455  "b %1"
13456  [(set_attr "type" "branch")
13457   (set_attr "length" "4")])
13459 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13460  [(match_parallel 0 "any_parallel_operand"
13461                   [(return)
13462                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13463                    (use (reg:P 11))
13464                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13465                         (match_operand:DF 3 "memory_operand" "m"))])]
13466  ""
13467  "b %1"
13468  [(set_attr "type" "branch")
13469   (set_attr "length" "4")])
13471 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13472  [(match_parallel 0 "any_parallel_operand"
13473                   [(return)
13474                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13475                    (use (reg:P 1))
13476                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13477                         (match_operand:DF 3 "memory_operand" "m"))])]
13478  ""
13479  "b %1"
13480  [(set_attr "type" "branch")
13481   (set_attr "length" "4")])
13483 ; This is used in compiling the unwind routines.
13484 (define_expand "eh_return"
13485   [(use (match_operand 0 "general_operand" ""))]
13486   ""
13487   "
13489   if (TARGET_32BIT)
13490     emit_insn (gen_eh_set_lr_si (operands[0]));
13491   else
13492     emit_insn (gen_eh_set_lr_di (operands[0]));
13493   DONE;
13496 ; We can't expand this before we know where the link register is stored.
13497 (define_insn "eh_set_lr_<mode>"
13498   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13499                     UNSPECV_EH_RR)
13500    (clobber (match_scratch:P 1 "=&b"))]
13501   ""
13502   "#")
13504 (define_split
13505   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13506    (clobber (match_scratch 1 ""))]
13507   "reload_completed"
13508   [(const_int 0)]
13509   "
13511   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13512   DONE;
13515 (define_insn "prefetch"
13516   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13517              (match_operand:SI 1 "const_int_operand" "n")
13518              (match_operand:SI 2 "const_int_operand" "n"))]
13519   ""
13520   "*
13522   if (GET_CODE (operands[0]) == REG)
13523     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13524   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13526   [(set_attr "type" "load")])
13528 ;; Handle -fsplit-stack.
13530 (define_expand "split_stack_prologue"
13531   [(const_int 0)]
13532   ""
13534   rs6000_expand_split_stack_prologue ();
13535   DONE;
13538 (define_expand "load_split_stack_limit"
13539   [(set (match_operand 0)
13540         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13541   ""
13543   emit_insn (gen_rtx_SET (operands[0],
13544                           gen_rtx_UNSPEC (Pmode,
13545                                           gen_rtvec (1, const0_rtx),
13546                                           UNSPEC_STACK_CHECK)));
13547   DONE;
13550 (define_insn "load_split_stack_limit_di"
13551   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13552         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13553   "TARGET_64BIT"
13554   "ld %0,-0x7040(13)"
13555   [(set_attr "type" "load")
13556    (set_attr "update" "no")
13557    (set_attr "indexed" "no")])
13559 (define_insn "load_split_stack_limit_si"
13560   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13561         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13562   "!TARGET_64BIT"
13563   "lwz %0,-0x7020(2)"
13564   [(set_attr "type" "load")
13565    (set_attr "update" "no")
13566    (set_attr "indexed" "no")])
13568 ;; A return instruction which the middle-end doesn't see.
13569 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13570 ;; after the call to __morestack.
13571 (define_insn "split_stack_return"
13572   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13573   ""
13574   "blr"
13575   [(set_attr "type" "jmpreg")])
13577 ;; If there are operand 0 bytes available on the stack, jump to
13578 ;; operand 1.
13579 (define_expand "split_stack_space_check"
13580   [(set (match_dup 2)
13581         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13582    (set (match_dup 3)
13583         (minus (reg STACK_POINTER_REGNUM)
13584                (match_operand 0)))
13585    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13586    (set (pc) (if_then_else
13587               (geu (match_dup 4) (const_int 0))
13588               (label_ref (match_operand 1))
13589               (pc)))]
13590   ""
13592   rs6000_split_stack_space_check (operands[0], operands[1]);
13593   DONE;
13596 (define_insn "bpermd_<mode>"
13597   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13598         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13599                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13600   "TARGET_POPCNTD"
13601   "bpermd %0,%1,%2"
13602   [(set_attr "type" "popcnt")])
13605 ;; Builtin fma support.  Handle 
13606 ;; Note that the conditions for expansion are in the FMA_F iterator.
13608 (define_expand "fma<mode>4"
13609   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13610         (fma:FMA_F
13611           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13612           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13613           (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13614   ""
13615   "")
13617 (define_insn "*fma<mode>4_fpr"
13618   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13619         (fma:SFDF
13620           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13621           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13622           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13623   "TARGET_<MODE>_FPR"
13624   "@
13625    fmadd<Ftrad> %0,%1,%2,%3
13626    xsmadda<Fvsx> %x0,%x1,%x2
13627    xsmaddm<Fvsx> %x0,%x1,%x3"
13628   [(set_attr "type" "fp")
13629    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13631 ; Altivec only has fma and nfms.
13632 (define_expand "fms<mode>4"
13633   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13634         (fma:FMA_F
13635           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13636           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13637           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13638   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13639   "")
13641 (define_insn "*fms<mode>4_fpr"
13642   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13643         (fma:SFDF
13644          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13645          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13646          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13647   "TARGET_<MODE>_FPR"
13648   "@
13649    fmsub<Ftrad> %0,%1,%2,%3
13650    xsmsuba<Fvsx> %x0,%x1,%x2
13651    xsmsubm<Fvsx> %x0,%x1,%x3"
13652   [(set_attr "type" "fp")
13653    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13655 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13656 (define_expand "fnma<mode>4"
13657   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13658         (neg:FMA_F
13659           (fma:FMA_F
13660             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13661             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13662             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13663   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13664   "")
13666 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13667 (define_expand "fnms<mode>4"
13668   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13669         (neg:FMA_F
13670           (fma:FMA_F
13671             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13672             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13673             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13674   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13675   "")
13677 ; Not an official optab name, but used from builtins.
13678 (define_expand "nfma<mode>4"
13679   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13680         (neg:FMA_F
13681           (fma:FMA_F
13682             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13683             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13684             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13685   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13686   "")
13688 (define_insn "*nfma<mode>4_fpr"
13689   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13690         (neg:SFDF
13691          (fma:SFDF
13692           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13693           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13694           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13695   "TARGET_<MODE>_FPR"
13696   "@
13697    fnmadd<Ftrad> %0,%1,%2,%3
13698    xsnmadda<Fvsx> %x0,%x1,%x2
13699    xsnmaddm<Fvsx> %x0,%x1,%x3"
13700   [(set_attr "type" "fp")
13701    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13703 ; Not an official optab name, but used from builtins.
13704 (define_expand "nfms<mode>4"
13705   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13706         (neg:FMA_F
13707           (fma:FMA_F
13708             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13709             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13710             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13711   ""
13712   "")
13714 (define_insn "*nfmssf4_fpr"
13715   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13716         (neg:SFDF
13717          (fma:SFDF
13718           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13719           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13720           (neg:SFDF
13721            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13722   "TARGET_<MODE>_FPR"
13723   "@
13724    fnmsub<Ftrad> %0,%1,%2,%3
13725    xsnmsuba<Fvsx> %x0,%x1,%x2
13726    xsnmsubm<Fvsx> %x0,%x1,%x3"
13727   [(set_attr "type" "fp")
13728    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13731 (define_expand "rs6000_get_timebase"
13732   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13733   ""
13735   if (TARGET_POWERPC64)
13736     emit_insn (gen_rs6000_mftb_di (operands[0]));
13737   else
13738     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13739   DONE;
13742 (define_insn "rs6000_get_timebase_ppc32"
13743   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13744         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13745    (clobber (match_scratch:SI 1 "=r"))
13746    (clobber (match_scratch:CC 2 "=y"))]
13747   "!TARGET_POWERPC64"
13749   if (WORDS_BIG_ENDIAN)
13750     if (TARGET_MFCRF)
13751       {
13752         return "mfspr %0,269\;"
13753                "mfspr %L0,268\;"
13754                "mfspr %1,269\;"
13755                "cmpw %2,%0,%1\;"
13756                "bne- %2,$-16";
13757       }
13758     else
13759       {
13760         return "mftbu %0\;"
13761                "mftb %L0\;"
13762                "mftbu %1\;"
13763                "cmpw %2,%0,%1\;"
13764                "bne- %2,$-16";
13765       }
13766   else
13767     if (TARGET_MFCRF)
13768       {
13769         return "mfspr %L0,269\;"
13770                "mfspr %0,268\;"
13771                "mfspr %1,269\;"
13772                "cmpw %2,%L0,%1\;"
13773                "bne- %2,$-16";
13774       }
13775     else
13776       {
13777         return "mftbu %L0\;"
13778                "mftb %0\;"
13779                "mftbu %1\;"
13780                "cmpw %2,%L0,%1\;"
13781                "bne- %2,$-16";
13782       }
13784   [(set_attr "length" "20")])
13786 (define_insn "rs6000_mftb_<mode>"
13787   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13788         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13789   ""
13791   if (TARGET_MFCRF)
13792     return "mfspr %0,268";
13793   else
13794     return "mftb %0";
13798 (define_insn "rs6000_mffs"
13799   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13800         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13801   "TARGET_HARD_FLOAT"
13802   "mffs %0")
13804 (define_insn "rs6000_mtfsf"
13805   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13806                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13807                     UNSPECV_MTFSF)]
13808   "TARGET_HARD_FLOAT"
13809   "mtfsf %0,%1")
13812 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13813 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13814 ;; register that is being loaded.  The fused ops must be physically adjacent.
13816 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13817 ;; before register allocation, and is meant to reduce the lifetime for the
13818 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13819 ;; to use the register that is being load.  The peephole2 then gathers any
13820 ;; other fused possibilities that it can find after register allocation.  If
13821 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13823 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13824 ;; before register allocation, so that we can avoid allocating a temporary base
13825 ;; register that won't be used, and that we try to load into base registers,
13826 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13827 ;; (addis followed by load) even on power8.
13829 (define_split
13830   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13831         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13832   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13833   [(parallel [(set (match_dup 0) (match_dup 2))
13834               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13835               (use (match_dup 3))
13836               (clobber (scratch:DI))])]
13838   operands[2] = fusion_wrap_memory_address (operands[1]);
13839   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13842 (define_insn "*toc_fusionload_<mode>"
13843   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13844         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13845    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13846    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13847    (clobber (match_scratch:DI 3 "=X,&b"))]
13848   "TARGET_TOC_FUSION_INT"
13850   if (base_reg_operand (operands[0], <MODE>mode))
13851     return emit_fusion_gpr_load (operands[0], operands[1]);
13853   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13855   [(set_attr "type" "load")
13856    (set_attr "length" "8")])
13858 (define_insn "*toc_fusionload_di"
13859   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13860         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13861    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13862    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13863    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13864   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13865    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13867   if (base_reg_operand (operands[0], DImode))
13868     return emit_fusion_gpr_load (operands[0], operands[1]);
13870   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13872   [(set_attr "type" "load")
13873    (set_attr "length" "8")])
13876 ;; Find cases where the addis that feeds into a load instruction is either used
13877 ;; once or is the same as the target register, and replace it with the fusion
13878 ;; insn
13880 (define_peephole2
13881   [(set (match_operand:P 0 "base_reg_operand" "")
13882         (match_operand:P 1 "fusion_gpr_addis" ""))
13883    (set (match_operand:INT1 2 "base_reg_operand" "")
13884         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13885   "TARGET_P8_FUSION
13886    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13887                          operands[3])"
13888   [(const_int 0)]
13890   expand_fusion_gpr_load (operands);
13891   DONE;
13894 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13895 ;; reload)
13897 (define_insn "fusion_gpr_load_<mode>"
13898   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13899         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13900                      UNSPEC_FUSION_GPR))]
13901   "TARGET_P8_FUSION"
13903   return emit_fusion_gpr_load (operands[0], operands[1]);
13905   [(set_attr "type" "load")
13906    (set_attr "length" "8")])
13909 ;; ISA 3.0 (power9) fusion support
13910 ;; Merge addis with floating load/store to FPRs (or GPRs).
13911 (define_peephole2
13912   [(set (match_operand:P 0 "base_reg_operand" "")
13913         (match_operand:P 1 "fusion_gpr_addis" ""))
13914    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13915         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13916   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13917    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13918   [(const_int 0)]
13920   expand_fusion_p9_load (operands);
13921   DONE;
13924 (define_peephole2
13925   [(set (match_operand:P 0 "base_reg_operand" "")
13926         (match_operand:P 1 "fusion_gpr_addis" ""))
13927    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13928         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13929   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13930    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13931    && !rtx_equal_p (operands[0], operands[3])"
13932   [(const_int 0)]
13934   expand_fusion_p9_store (operands);
13935   DONE;
13938 (define_peephole2
13939   [(set (match_operand:SDI 0 "int_reg_operand" "")
13940         (match_operand:SDI 1 "upper16_cint_operand" ""))
13941    (set (match_dup 0)
13942         (ior:SDI (match_dup 0)
13943                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13944   "TARGET_P9_FUSION"
13945   [(set (match_dup 0)
13946         (unspec:SDI [(match_dup 1)
13947                      (match_dup 2)] UNSPEC_FUSION_P9))])
13949 (define_peephole2
13950   [(set (match_operand:SDI 0 "int_reg_operand" "")
13951         (match_operand:SDI 1 "upper16_cint_operand" ""))
13952    (set (match_operand:SDI 2 "int_reg_operand" "")
13953         (ior:SDI (match_dup 0)
13954                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13955   "TARGET_P9_FUSION
13956    && !rtx_equal_p (operands[0], operands[2])
13957    && peep2_reg_dead_p (2, operands[0])"
13958   [(set (match_dup 2)
13959         (unspec:SDI [(match_dup 1)
13960                      (match_dup 3)] UNSPEC_FUSION_P9))])
13962 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13963 ;; reload).  Because we want to eventually have secondary_reload generate
13964 ;; these, they have to have a single alternative that gives the register
13965 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13966 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13967   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13968         (unspec:GPR_FUSION
13969          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13970          UNSPEC_FUSION_P9))
13971    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13972   "TARGET_P9_FUSION"
13974   /* This insn is a secondary reload insn, which cannot have alternatives.
13975      If we are not loading up register 0, use the power8 fusion instead.  */
13976   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13977     return emit_fusion_gpr_load (operands[0], operands[1]);
13979   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13981   [(set_attr "type" "load")
13982    (set_attr "length" "8")])
13984 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13985   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13986         (unspec:GPR_FUSION
13987          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13988          UNSPEC_FUSION_P9))
13989    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13990   "TARGET_P9_FUSION"
13992   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13994   [(set_attr "type" "store")
13995    (set_attr "length" "8")])
13997 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13998   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13999         (unspec:FPR_FUSION
14000          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14001          UNSPEC_FUSION_P9))
14002    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14003   "TARGET_P9_FUSION"
14005   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14007   [(set_attr "type" "fpload")
14008    (set_attr "length" "8")])
14010 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14011   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14012         (unspec:FPR_FUSION
14013          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14014          UNSPEC_FUSION_P9))
14015    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14016   "TARGET_P9_FUSION"
14018   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14020   [(set_attr "type" "fpstore")
14021    (set_attr "length" "8")])
14023 (define_insn "*fusion_p9_<mode>_constant"
14024   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14025         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14026                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
14027                     UNSPEC_FUSION_P9))] 
14028   "TARGET_P9_FUSION"
14030   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
14031   return "ori %0,%0,%2";
14033   [(set_attr "type" "two")
14034    (set_attr "length" "8")])
14037 ;; Optimize cases where we want to do a D-form load (register+offset) on
14038 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14039 ;; has generated:
14040 ;;      LFD 0,32(3)
14041 ;;      XXLOR 32,0,0
14043 ;; and we change this to:
14044 ;;      LI 0,32
14045 ;;      LXSDX 32,3,9
14047 (define_peephole2
14048   [(match_scratch:P 0 "b")
14049    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14050         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14051    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14052         (match_dup 1))]
14053   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14054   [(set (match_dup 0)
14055         (match_dup 4))
14056    (set (match_dup 3)
14057         (match_dup 5))]
14059   rtx tmp_reg = operands[0];
14060   rtx mem = operands[2];
14061   rtx addr = XEXP (mem, 0);
14062   rtx add_op0, add_op1, new_addr;
14064   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14065   add_op0 = XEXP (addr, 0);
14066   add_op1 = XEXP (addr, 1);
14067   gcc_assert (REG_P (add_op0));
14068   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14070   operands[4] = add_op1;
14071   operands[5] = change_address (mem, <MODE>mode, new_addr);
14074 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14075 ;; Altivec register, and the register allocator has generated:
14076 ;;      XXLOR 0,32,32
14077 ;;      STFD 0,32(3)
14079 ;; and we change this to:
14080 ;;      LI 0,32
14081 ;;      STXSDX 32,3,9
14083 (define_peephole2
14084   [(match_scratch:P 0 "b")
14085    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14086         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14087    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14088         (match_dup 1))]
14089   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14090   [(set (match_dup 0)
14091         (match_dup 4))
14092    (set (match_dup 5)
14093         (match_dup 2))]
14095   rtx tmp_reg = operands[0];
14096   rtx mem = operands[3];
14097   rtx addr = XEXP (mem, 0);
14098   rtx add_op0, add_op1, new_addr;
14100   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14101   add_op0 = XEXP (addr, 0);
14102   add_op1 = XEXP (addr, 1);
14103   gcc_assert (REG_P (add_op0));
14104   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14106   operands[4] = add_op1;
14107   operands[5] = change_address (mem, <MODE>mode, new_addr);
14109    
14111 ;; Miscellaneous ISA 2.06 (power7) instructions
14112 (define_insn "addg6s"
14113   [(set (match_operand:SI 0 "register_operand" "=r")
14114         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14115                     (match_operand:SI 2 "register_operand" "r")]
14116                    UNSPEC_ADDG6S))]
14117   "TARGET_POPCNTD"
14118   "addg6s %0,%1,%2"
14119   [(set_attr "type" "integer")
14120    (set_attr "length" "4")])
14122 (define_insn "cdtbcd"
14123   [(set (match_operand:SI 0 "register_operand" "=r")
14124         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14125                    UNSPEC_CDTBCD))]
14126   "TARGET_POPCNTD"
14127   "cdtbcd %0,%1"
14128   [(set_attr "type" "integer")
14129    (set_attr "length" "4")])
14131 (define_insn "cbcdtd"
14132   [(set (match_operand:SI 0 "register_operand" "=r")
14133         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14134                    UNSPEC_CBCDTD))]
14135   "TARGET_POPCNTD"
14136   "cbcdtd %0,%1"
14137   [(set_attr "type" "integer")
14138    (set_attr "length" "4")])
14140 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14141                                         UNSPEC_DIVEO
14142                                         UNSPEC_DIVEU
14143                                         UNSPEC_DIVEUO])
14145 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
14146                              (UNSPEC_DIVEO      "eo")
14147                              (UNSPEC_DIVEU      "eu")
14148                              (UNSPEC_DIVEUO     "euo")])
14150 (define_insn "div<div_extend>_<mode>"
14151   [(set (match_operand:GPR 0 "register_operand" "=r")
14152         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14153                      (match_operand:GPR 2 "register_operand" "r")]
14154                     UNSPEC_DIV_EXTEND))]
14155   "TARGET_POPCNTD"
14156   "div<wd><div_extend> %0,%1,%2"
14157   [(set_attr "type" "div")
14158    (set_attr "size" "<bits>")])
14161 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14163 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14164 (define_mode_attr FP128_64 [(TF "DF")
14165                             (IF "DF")
14166                             (TD "DI")
14167                             (KF "DI")])
14169 (define_expand "unpack<mode>"
14170   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14171         (unspec:<FP128_64>
14172          [(match_operand:FMOVE128 1 "register_operand" "")
14173           (match_operand:QI 2 "const_0_to_1_operand" "")]
14174          UNSPEC_UNPACK_128BIT))]
14175   "FLOAT128_2REG_P (<MODE>mode)"
14176   "")
14178 (define_insn_and_split "unpack<mode>_dm"
14179   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14180         (unspec:<FP128_64>
14181          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14182           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14183          UNSPEC_UNPACK_128BIT))]
14184   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14185   "#"
14186   "&& reload_completed"
14187   [(set (match_dup 0) (match_dup 3))]
14189   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14191   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14192     {
14193       emit_note (NOTE_INSN_DELETED);
14194       DONE;
14195     }
14197   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14199   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14200    (set_attr "length" "4")])
14202 (define_insn_and_split "unpack<mode>_nodm"
14203   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14204         (unspec:<FP128_64>
14205          [(match_operand:FMOVE128 1 "register_operand" "d,d")
14206           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14207          UNSPEC_UNPACK_128BIT))]
14208   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14209   "#"
14210   "&& reload_completed"
14211   [(set (match_dup 0) (match_dup 3))]
14213   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14215   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14216     {
14217       emit_note (NOTE_INSN_DELETED);
14218       DONE;
14219     }
14221   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14223   [(set_attr "type" "fp,fpstore")
14224    (set_attr "length" "4")])
14226 (define_insn_and_split "pack<mode>"
14227   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14228         (unspec:FMOVE128
14229          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14230           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14231          UNSPEC_PACK_128BIT))]
14232   "FLOAT128_2REG_P (<MODE>mode)"
14233   "@
14234    fmr %L0,%2
14235    #"
14236   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14237   [(set (match_dup 3) (match_dup 1))
14238    (set (match_dup 4) (match_dup 2))]
14240   unsigned dest_hi = REGNO (operands[0]);
14241   unsigned dest_lo = dest_hi + 1;
14243   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14244   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14246   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14247   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14249   [(set_attr "type" "fpsimple,fp")
14250    (set_attr "length" "4,8")])
14252 (define_insn "unpack<mode>"
14253   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14254         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14255                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14256          UNSPEC_UNPACK_128BIT))]
14257   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14259   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14260     return ASM_COMMENT_START " xxpermdi to same register";
14262   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14263   return "xxpermdi %x0,%x1,%x1,%3";
14265   [(set_attr "type" "vecperm")])
14267 (define_insn "pack<mode>"
14268   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14269         (unspec:FMOVE128_VSX
14270          [(match_operand:DI 1 "register_operand" "wa")
14271           (match_operand:DI 2 "register_operand" "wa")]
14272          UNSPEC_PACK_128BIT))]
14273   "TARGET_VSX"
14274   "xxpermdi %x0,%x1,%x2,0"
14275   [(set_attr "type" "vecperm")])
14279 ;; ISA 2.08 IEEE 128-bit floating point support.
14281 (define_insn "add<mode>3"
14282   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14283         (plus:IEEE128
14284          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14285          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14286   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14287   "xsaddqp %0,%1,%2"
14288   [(set_attr "type" "vecfloat")
14289    (set_attr "size" "128")])
14291 (define_insn "sub<mode>3"
14292   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14293         (minus:IEEE128
14294          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14295          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14296   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14297   "xssubqp %0,%1,%2"
14298   [(set_attr "type" "vecfloat")
14299    (set_attr "size" "128")])
14301 (define_insn "mul<mode>3"
14302   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14303         (mult:IEEE128
14304          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14305          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14306   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14307   "xsmulqp %0,%1,%2"
14308   [(set_attr "type" "vecfloat")
14309    (set_attr "size" "128")])
14311 (define_insn "div<mode>3"
14312   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14313         (div:IEEE128
14314          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14315          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14316   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14317   "xsdivqp %0,%1,%2"
14318   [(set_attr "type" "vecdiv")
14319    (set_attr "size" "128")])
14321 (define_insn "sqrt<mode>2"
14322   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14323         (sqrt:IEEE128
14324          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14325   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14326    "xssqrtqp %0,%1"
14327   [(set_attr "type" "vecdiv")
14328    (set_attr "size" "128")])
14330 (define_expand "copysign<mode>3"
14331   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14332    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14333    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14334   "FLOAT128_IEEE_P (<MODE>mode)"
14336   if (TARGET_FLOAT128_HW)
14337     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14338                                          operands[2]));
14339   else
14340     {
14341       rtx tmp = gen_reg_rtx (<MODE>mode);
14342       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14343                                            operands[2], tmp));
14344     }
14345   DONE;
14348 (define_insn "copysign<mode>3_hard"
14349   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14350         (unspec:IEEE128
14351          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14352           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14353          UNSPEC_COPYSIGN))]
14354   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14355    "xscpsgnqp %0,%2,%1"
14356   [(set_attr "type" "vecmove")
14357    (set_attr "size" "128")])
14359 (define_insn "copysign<mode>3_soft"
14360   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14361         (unspec:IEEE128
14362          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14363           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14364           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14365          UNSPEC_COPYSIGN))]
14366   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14367    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14368   [(set_attr "type" "veccomplex")
14369    (set_attr "length" "8")])
14371 (define_insn "neg<mode>2_hw"
14372   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14373         (neg:IEEE128
14374          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14375   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14376   "xsnegqp %0,%1"
14377   [(set_attr "type" "vecmove")
14378    (set_attr "size" "128")])
14381 (define_insn "abs<mode>2_hw"
14382   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14383         (abs:IEEE128
14384          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14385   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14386   "xsabsqp %0,%1"
14387   [(set_attr "type" "vecmove")
14388    (set_attr "size" "128")])
14391 (define_insn "*nabs<mode>2_hw"
14392   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14393         (neg:IEEE128
14394          (abs:IEEE128
14395           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14396   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14397   "xsnabsqp %0,%1"
14398   [(set_attr "type" "vecmove")
14399    (set_attr "size" "128")])
14401 ;; Initially don't worry about doing fusion
14402 (define_insn "fma<mode>4_hw"
14403   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14404         (fma:IEEE128
14405          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14406          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14407          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14408   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14409   "xsmaddqp %0,%1,%2"
14410   [(set_attr "type" "vecfloat")
14411    (set_attr "size" "128")])
14413 (define_insn "*fms<mode>4_hw"
14414   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14415         (fma:IEEE128
14416          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14417          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14418          (neg:IEEE128
14419           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14420   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14421   "xsmsubqp %0,%1,%2"
14422   [(set_attr "type" "vecfloat")
14423    (set_attr "size" "128")])
14425 (define_insn "*nfma<mode>4_hw"
14426   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14427         (neg:IEEE128
14428          (fma:IEEE128
14429           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14430           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14431           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14432   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14433   "xsnmaddqp %0,%1,%2"
14434   [(set_attr "type" "vecfloat")
14435    (set_attr "size" "128")])
14437 (define_insn "*nfms<mode>4_hw"
14438   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14439         (neg:IEEE128
14440          (fma:IEEE128
14441           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14442           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14443           (neg:IEEE128
14444            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14445   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14446   "xsnmsubqp %0,%1,%2"
14447   [(set_attr "type" "vecfloat")
14448    (set_attr "size" "128")])
14450 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14451   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14452         (float_extend:IEEE128
14453          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14454   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14455   "xscvdpqp %0,%1"
14456   [(set_attr "type" "vecfloat")
14457    (set_attr "size" "128")])
14459 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14460 ;; point is a simple copy.
14461 (define_insn_and_split "extendkftf2"
14462   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14463         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14464   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14465   "@
14466    #
14467    xxlor %x0,%x1,%x1"
14468   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14469   [(const_int 0)]
14471   emit_note (NOTE_INSN_DELETED);
14472   DONE;
14474   [(set_attr "type" "*,veclogical")
14475    (set_attr "length" "0,4")])
14477 (define_insn_and_split "trunctfkf2"
14478   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14479         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14480   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14481   "@
14482    #
14483    xxlor %x0,%x1,%x1"
14484   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14485   [(const_int 0)]
14487   emit_note (NOTE_INSN_DELETED);
14488   DONE;
14490   [(set_attr "type" "*,veclogical")
14491    (set_attr "length" "0,4")])
14493 (define_insn "trunc<mode>df2_hw"
14494   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14495         (float_truncate:DF
14496          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14497   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14498   "xscvqpdp %0,%1"
14499   [(set_attr "type" "vecfloat")
14500    (set_attr "size" "128")])
14502 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14503 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14504 ;; conversion
14505 (define_insn_and_split "trunc<mode>sf2_hw"
14506   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14507         (float_truncate:SF
14508          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14509    (clobber (match_scratch:DF 2 "=v"))]
14510   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14511   "#"
14512   "&& 1"
14513   [(set (match_dup 2)
14514         (unspec:DF [(match_dup 1)]
14515                    UNSPEC_TRUNC_ROUND_TO_ODD))
14516    (set (match_dup 0)
14517         (float_truncate:SF (match_dup 2)))]
14519   if (GET_CODE (operands[2]) == SCRATCH)
14520     operands[2] = gen_reg_rtx (DFmode);
14522   [(set_attr "type" "vecfloat")
14523    (set_attr "length" "8")])
14525 ;; Conversion between IEEE 128-bit and integer types
14526 (define_insn "fix_<mode>di2_hw"
14527   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14528         (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14529   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14530   "xscvqpsdz %0,%1"
14531   [(set_attr "type" "vecfloat")
14532    (set_attr "size" "128")])
14534 (define_insn "fixuns_<mode>di2_hw"
14535   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14536         (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14537   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14538   "xscvqpudz %0,%1"
14539   [(set_attr "type" "vecfloat")
14540    (set_attr "size" "128")])
14542 (define_insn "fix_<mode>si2_hw"
14543   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14544         (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14545   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14546   "xscvqpswz %0,%1"
14547   [(set_attr "type" "vecfloat")
14548    (set_attr "size" "128")])
14550 (define_insn "fixuns_<mode>si2_hw"
14551   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14552         (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14553   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14554   "xscvqpuwz %0,%1"
14555   [(set_attr "type" "vecfloat")
14556    (set_attr "size" "128")])
14558 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14559 ;; floating point value to 32-bit integer to GPR in order to save it.
14560 (define_insn_and_split "*fix<uns>_<mode>_mem"
14561   [(set (match_operand:SI 0 "memory_operand" "=Z")
14562         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14563    (clobber (match_scratch:SI 2 "=v"))]
14564   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14565   "#"
14566   "&& reload_completed"
14567   [(set (match_dup 2)
14568         (any_fix:SI (match_dup 1)))
14569    (set (match_dup 0)
14570         (match_dup 2))])
14572 (define_insn "float_<mode>di2_hw"
14573   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14574         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14575   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14576   "xscvsdqp %0,%1"
14577   [(set_attr "type" "vecfloat")
14578    (set_attr "size" "128")])
14580 (define_insn_and_split "float_<mode>si2_hw"
14581   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14582         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14583    (clobber (match_scratch:DI 2 "=v"))]
14584   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14585   "#"
14586   "&& 1"
14587   [(set (match_dup 2)
14588         (sign_extend:DI (match_dup 1)))
14589    (set (match_dup 0)
14590         (float:IEEE128 (match_dup 2)))]
14592   if (GET_CODE (operands[2]) == SCRATCH)
14593     operands[2] = gen_reg_rtx (DImode);
14596 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14597   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14598         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14599    (clobber (match_scratch:DI 2 "=X,r,X"))]
14600   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14601   "#"
14602   "&& reload_completed"
14603   [(const_int 0)]
14605   rtx dest = operands[0];
14606   rtx src = operands[1];
14607   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14609   if (altivec_register_operand (src, <QHI:MODE>mode))
14610     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14611   else if (int_reg_operand (src, <QHI:MODE>mode))
14612     {
14613       rtx ext_di = operands[2];
14614       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14615       emit_move_insn (dest_di, ext_di);
14616     }
14617   else if (MEM_P (src))
14618     {
14619       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14620       emit_move_insn (dest_qhi, src);
14621       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14622     }
14623   else
14624     gcc_unreachable ();
14626   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14627   DONE;
14629   [(set_attr "length" "8,12,12")
14630    (set_attr "type" "vecfloat")
14631    (set_attr "size" "128")])
14633 (define_insn "floatuns_<mode>di2_hw"
14634   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14635         (unsigned_float:IEEE128
14636          (match_operand:DI 1 "altivec_register_operand" "v")))]
14637   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14638   "xscvudqp %0,%1"
14639   [(set_attr "type" "vecfloat")
14640    (set_attr "size" "128")])
14642 (define_insn_and_split "floatuns_<mode>si2_hw"
14643   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14644         (unsigned_float:IEEE128
14645          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14646    (clobber (match_scratch:DI 2 "=v"))]
14647   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14648   "#"
14649   "&& 1"
14650   [(set (match_dup 2)
14651         (zero_extend:DI (match_dup 1)))
14652    (set (match_dup 0)
14653         (float:IEEE128 (match_dup 2)))]
14655   if (GET_CODE (operands[2]) == SCRATCH)
14656     operands[2] = gen_reg_rtx (DImode);
14659 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14660   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14661         (unsigned_float:IEEE128
14662          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14663    (clobber (match_scratch:DI 2 "=X,r,X"))]
14664   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14665   "#"
14666   "&& reload_completed"
14667   [(const_int 0)]
14669   rtx dest = operands[0];
14670   rtx src = operands[1];
14671   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14673   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14674     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14675   else if (int_reg_operand (src, <QHI:MODE>mode))
14676     {
14677       rtx ext_di = operands[2];
14678       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14679       emit_move_insn (dest_di, ext_di);
14680     }
14681   else
14682     gcc_unreachable ();
14684   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14685   DONE;
14687   [(set_attr "length" "8,12,8")
14688    (set_attr "type" "vecfloat")
14689    (set_attr "size" "128")])
14691 ;; IEEE 128-bit instructions with round to odd semantics
14692 (define_insn "add<mode>3_odd"
14693   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14694         (unspec:IEEE128
14695          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14696           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14697          UNSPEC_ADD_ROUND_TO_ODD))]
14698   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14699   "xsaddqpo %0,%1,%2"
14700   [(set_attr "type" "vecfloat")
14701    (set_attr "size" "128")])
14703 (define_insn "sub<mode>3_odd"
14704   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14705         (unspec:IEEE128
14706          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14707           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14708          UNSPEC_SUB_ROUND_TO_ODD))]
14709   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14710   "xssubqpo %0,%1,%2"
14711   [(set_attr "type" "vecfloat")
14712    (set_attr "size" "128")])
14714 (define_insn "mul<mode>3_odd"
14715   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14716         (unspec:IEEE128
14717          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14718           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14719          UNSPEC_MUL_ROUND_TO_ODD))]
14720   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14721   "xsmulqpo %0,%1,%2"
14722   [(set_attr "type" "vecfloat")
14723    (set_attr "size" "128")])
14725 (define_insn "div<mode>3_odd"
14726   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14727         (unspec:IEEE128
14728          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14729           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14730          UNSPEC_DIV_ROUND_TO_ODD))]
14731   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14732   "xsdivqpo %0,%1,%2"
14733   [(set_attr "type" "vecdiv")
14734    (set_attr "size" "128")])
14736 (define_insn "sqrt<mode>2_odd"
14737   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14738         (unspec:IEEE128
14739          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14740          UNSPEC_SQRT_ROUND_TO_ODD))]
14741   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14742    "xssqrtqpo %0,%1"
14743   [(set_attr "type" "vecdiv")
14744    (set_attr "size" "128")])
14746 (define_insn "fma<mode>4_odd"
14747   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14748         (unspec:IEEE128
14749          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14750           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14751           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14752          UNSPEC_FMA_ROUND_TO_ODD))]
14753   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14754   "xsmaddqpo %0,%1,%2"
14755   [(set_attr "type" "vecfloat")
14756    (set_attr "size" "128")])
14758 (define_insn "*fms<mode>4_odd"
14759   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14760         (unspec:IEEE128
14761          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14762           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14763           (neg:IEEE128
14764            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14765          UNSPEC_FMA_ROUND_TO_ODD))]
14766   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14767   "xsmsubqpo %0,%1,%2"
14768   [(set_attr "type" "vecfloat")
14769    (set_attr "size" "128")])
14771 (define_insn "*nfma<mode>4_odd"
14772   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14773         (neg:IEEE128
14774          (unspec:IEEE128
14775           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14776            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14777            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14778           UNSPEC_FMA_ROUND_TO_ODD)))]
14779   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14780   "xsnmaddqpo %0,%1,%2"
14781   [(set_attr "type" "vecfloat")
14782    (set_attr "size" "128")])
14784 (define_insn "*nfms<mode>4_odd"
14785   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14786         (neg:IEEE128
14787          (unspec:IEEE128
14788           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14789            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14790            (neg:IEEE128
14791             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14792           UNSPEC_FMA_ROUND_TO_ODD)))]
14793   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14794   "xsnmsubqpo %0,%1,%2"
14795   [(set_attr "type" "vecfloat")
14796    (set_attr "size" "128")])
14798 (define_insn "trunc<mode>df2_odd"
14799   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14800         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14801                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14802   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14803   "xscvqpdpo %0,%1"
14804   [(set_attr "type" "vecfloat")
14805    (set_attr "size" "128")])
14807 ;; IEEE 128-bit comparisons
14808 (define_insn "*cmp<mode>_hw"
14809   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14810         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14811                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14812   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14813    "xscmpuqp %0,%1,%2"
14814   [(set_attr "type" "veccmp")
14815    (set_attr "size" "128")])
14819 (include "sync.md")
14820 (include "vector.md")
14821 (include "vsx.md")
14822 (include "altivec.md")
14823 (include "dfp.md")
14824 (include "paired.md")
14825 (include "crypto.md")
14826 (include "htm.md")