re PR target/82015 (PowerPC should check if 2nd argument to __builtin_unpackv1ti...
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobc0c392ce596f7ee834a811327b697072328172f1
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_ROUND_TO_ODD
144    UNSPEC_SIGNBIT
145    UNSPEC_SF_FROM_SI
146    UNSPEC_SI_FROM_SF
147   ])
150 ;; UNSPEC_VOLATILE usage
153 (define_c_enum "unspecv"
154   [UNSPECV_BLOCK
155    UNSPECV_LL                   ; load-locked
156    UNSPECV_SC                   ; store-conditional
157    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
158    UNSPECV_EH_RR                ; eh_reg_restore
159    UNSPECV_ISYNC                ; isync instruction
160    UNSPECV_MFTB                 ; move from time base
161    UNSPECV_NLGR                 ; non-local goto receiver
162    UNSPECV_MFFS                 ; Move from FPSCR
163    UNSPECV_MTFSF                ; Move to FPSCR Fields
164    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
165   ])
168 ;; Define an insn type attribute.  This is used in function unit delay
169 ;; computations.
170 (define_attr "type"
171   "integer,two,three,
172    add,logical,shift,insert,
173    mul,halfmul,div,
174    exts,cntlz,popcnt,isel,
175    load,store,fpload,fpstore,vecload,vecstore,
176    cmp,
177    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
178    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
179    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
180    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
181    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
182    veclogical,veccmpfx,vecexts,vecmove,
183    htm,htmsimple,dfp"
184   (const_string "integer"))
186 ;; What data size does this instruction work on?
187 ;; This is used for insert, mul and others as necessary.
188 (define_attr "size" "8,16,32,64,128" (const_string "32"))
190 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
191 ;; This is used for add, logical, shift, exts, mul.
192 (define_attr "dot" "no,yes" (const_string "no"))
194 ;; Does this instruction sign-extend its result?
195 ;; This is used for load insns.
196 (define_attr "sign_extend" "no,yes" (const_string "no"))
198 ;; Does this instruction use indexed (that is, reg+reg) addressing?
199 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
200 ;; it is automatically set based on that.  If a load or store instruction
201 ;; has fewer than two operands it needs to set this attribute manually
202 ;; or the compiler will crash.
203 (define_attr "indexed" "no,yes"
204   (if_then_else (ior (match_operand 0 "indexed_address_mem")
205                      (match_operand 1 "indexed_address_mem"))
206                 (const_string "yes")
207                 (const_string "no")))
209 ;; Does this instruction use update addressing?
210 ;; This is used for load and store insns.  See the comments for "indexed".
211 (define_attr "update" "no,yes"
212   (if_then_else (ior (match_operand 0 "update_address_mem")
213                      (match_operand 1 "update_address_mem"))
214                 (const_string "yes")
215                 (const_string "no")))
217 ;; Is this instruction using operands[2] as shift amount, and can that be a
218 ;; register?
219 ;; This is used for shift insns.
220 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
222 ;; Is this instruction using a shift amount from a register?
223 ;; This is used for shift insns.
224 (define_attr "var_shift" "no,yes"
225   (if_then_else (and (eq_attr "type" "shift")
226                      (eq_attr "maybe_var_shift" "yes"))
227                 (if_then_else (match_operand 2 "gpc_reg_operand")
228                               (const_string "yes")
229                               (const_string "no"))
230                 (const_string "no")))
232 ;; Is copying of this instruction disallowed?
233 (define_attr "cannot_copy" "no,yes" (const_string "no"))
235 ;; Define floating point instruction sub-types for use with Xfpu.md
236 (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"))
238 ;; Length (in bytes).
239 ; '(pc)' in the following doesn't include the instruction itself; it is
240 ; calculated as if the instruction had zero size.
241 (define_attr "length" ""
242   (if_then_else (eq_attr "type" "branch")
243                 (if_then_else (and (ge (minus (match_dup 0) (pc))
244                                        (const_int -32768))
245                                    (lt (minus (match_dup 0) (pc))
246                                        (const_int 32764)))
247                               (const_int 4)
248                               (const_int 8))
249                 (const_int 4)))
251 ;; Processor type -- this attribute must exactly match the processor_type
252 ;; enumeration in rs6000-opts.h.
253 (define_attr "cpu"
254   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
255    ppc750,ppc7400,ppc7450,
256    ppc403,ppc405,ppc440,ppc476,
257    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
258    power4,power5,power6,power7,power8,power9,
259    rs64a,mpccore,cell,ppca2,titan"
260   (const (symbol_ref "rs6000_cpu_attr")))
263 ;; If this instruction is microcoded on the CELL processor
264 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
265 (define_attr "cell_micro" "not,conditional,always"
266   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
267                           (eq_attr "dot" "yes"))
268                      (and (eq_attr "type" "load")
269                           (eq_attr "sign_extend" "yes"))
270                      (and (eq_attr "type" "shift")
271                           (eq_attr "var_shift" "yes")))
272                 (const_string "always")
273                 (const_string "not")))
275 (automata_option "ndfa")
277 (include "rs64.md")
278 (include "mpc.md")
279 (include "40x.md")
280 (include "440.md")
281 (include "476.md")
282 (include "601.md")
283 (include "603.md")
284 (include "6xx.md")
285 (include "7xx.md")
286 (include "7450.md")
287 (include "8540.md")
288 (include "e300c2c3.md")
289 (include "e500mc.md")
290 (include "e500mc64.md")
291 (include "e5500.md")
292 (include "e6500.md")
293 (include "power4.md")
294 (include "power5.md")
295 (include "power6.md")
296 (include "power7.md")
297 (include "power8.md")
298 (include "power9.md")
299 (include "cell.md")
300 (include "xfpu.md")
301 (include "a2.md")
302 (include "titan.md")
304 (include "predicates.md")
305 (include "constraints.md")
307 (include "darwin.md")
310 ;; Mode iterators
312 ; This mode iterator allows :GPR to be used to indicate the allowable size
313 ; of whole values in GPRs.
314 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
316 ; Any supported integer mode.
317 (define_mode_iterator INT [QI HI SI DI TI PTI])
319 ; Any supported integer mode that fits in one register.
320 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
322 ; Integer modes supported in VSX registers with ISA 3.0 instructions
323 (define_mode_iterator INT_ISA3 [QI HI SI DI])
325 ; Everything we can extend QImode to.
326 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
328 ; Everything we can extend HImode to.
329 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
331 ; Everything we can extend SImode to.
332 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
334 ; QImode or HImode for small integer moves and small atomic ops
335 (define_mode_iterator QHI [QI HI])
337 ; QImode, HImode, SImode for fused ops only for GPR loads
338 (define_mode_iterator QHSI [QI HI SI])
340 ; HImode or SImode for sign extended fusion ops
341 (define_mode_iterator HSI [HI SI])
343 ; SImode or DImode, even if DImode doesn't fit in GPRs.
344 (define_mode_iterator SDI [SI DI])
346 ; Types that can be fused with an ADDIS instruction to load or store a GPR
347 ; register that has reg+offset addressing.
348 (define_mode_iterator GPR_FUSION [QI
349                                   HI
350                                   SI
351                                   (DI   "TARGET_POWERPC64")
352                                   SF
353                                   (DF   "TARGET_POWERPC64")])
355 ; Types that can be fused with an ADDIS instruction to load or store a FPR
356 ; register that has reg+offset addressing.
357 (define_mode_iterator FPR_FUSION [DI SF DF])
359 ; The size of a pointer.  Also, the size of the value that a record-condition
360 ; (one with a '.') will compare; and the size used for arithmetic carries.
361 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
363 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
364 ; PTImode is GPR only)
365 (define_mode_iterator TI2 [TI PTI])
367 ; Any hardware-supported floating-point mode
368 (define_mode_iterator FP [
369   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
370   (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
371   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
372   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
373   (KF "TARGET_FLOAT128_TYPE")
374   (DD "TARGET_DFP")
375   (TD "TARGET_DFP")])
377 ; Any fma capable floating-point mode.
378 (define_mode_iterator FMA_F [
379   (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
380   (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
381        || VECTOR_UNIT_VSX_P (DFmode)")
382   (V2SF "TARGET_PAIRED_FLOAT")
383   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
384   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
385   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
386   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
387   ])
389 ; Floating point move iterators to combine binary and decimal moves
390 (define_mode_iterator FMOVE32 [SF SD])
391 (define_mode_iterator FMOVE64 [DF DD])
392 (define_mode_iterator FMOVE64X [DI DF DD])
393 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
394                                 (IF "FLOAT128_IBM_P (IFmode)")
395                                 (TD "TARGET_HARD_FLOAT")])
397 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
398                                     (IF "FLOAT128_2REG_P (IFmode)")
399                                     (TD "TARGET_HARD_FLOAT")])
401 ; Iterators for 128 bit types for direct move
402 (define_mode_iterator FMOVE128_GPR [TI
403                                     V16QI
404                                     V8HI
405                                     V4SI
406                                     V4SF
407                                     V2DI
408                                     V2DF
409                                     V1TI
410                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
411                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
413 ; Iterator for 128-bit VSX types for pack/unpack
414 (define_mode_iterator FMOVE128_VSX [V1TI KF])
416 ; Whether a floating point move is ok, don't allow SD without hardware FP
417 (define_mode_attr fmove_ok [(SF "")
418                             (DF "")
419                             (SD "TARGET_HARD_FLOAT")
420                             (DD "")])
422 ; Convert REAL_VALUE to the appropriate bits
423 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
424                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
425                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
426                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
428 ; Whether 0.0 has an all-zero bit pattern
429 (define_mode_attr zero_fp [(SF "j")
430                            (DF "j")
431                            (TF "j")
432                            (IF "j")
433                            (KF "j")
434                            (SD "wn")
435                            (DD "wn")
436                            (TD "wn")])
438 ; Definitions for 64-bit VSX
439 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
441 ; Definitions for 64-bit direct move
442 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
444 ; Definitions for 64-bit use of altivec registers
445 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
447 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
448 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
450 ; These modes do not fit in integer registers in 32-bit mode.
451 (define_mode_iterator DIFD [DI DF DD])
453 ; Iterator for reciprocal estimate instructions
454 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
456 ; Iterator for just SF/DF
457 (define_mode_iterator SFDF [SF DF])
459 ; Like SFDF, but a different name to match conditional move where the
460 ; comparison operands may be a different mode than the input operands.
461 (define_mode_iterator SFDF2 [SF DF])
463 ; Iterator for 128-bit floating point that uses the IBM double-double format
464 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
465                               (TF "FLOAT128_IBM_P (TFmode)")])
467 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
468 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
469                                (TF "FLOAT128_IEEE_P (TFmode)")])
471 ; Iterator for 128-bit floating point
472 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
473                                 (IF "TARGET_FLOAT128_TYPE")
474                                 (TF "TARGET_LONG_DOUBLE_128")])
476 ; Iterator for signbit on 64-bit machines with direct move
477 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
478                                (TF "FLOAT128_VECTOR_P (TFmode)")])
480 ; Iterator for ISA 3.0 supported floating point types
481 (define_mode_iterator FP_ISA3 [SF DF])
483 ; SF/DF suffix for traditional floating instructions
484 (define_mode_attr Ftrad         [(SF "s") (DF "")])
486 ; SF/DF suffix for VSX instructions
487 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
489 ; SF/DF constraint for arithmetic on traditional floating point registers
490 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
492 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
493 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
494 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
495 ; format.
496 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
498 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
499 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
500 ; instructions added in ISA 2.07 (power8)
501 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
503 ; SF/DF constraint for arithmetic on altivec registers
504 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
506 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
507 (define_mode_attr Fs            [(SF "s")  (DF "d")])
509 ; FRE/FRES support
510 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
511 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
513 ; Conditional returns.
514 (define_code_iterator any_return [return simple_return])
515 (define_code_attr return_pred [(return "direct_return ()")
516                                (simple_return "1")])
517 (define_code_attr return_str [(return "") (simple_return "simple_")])
519 ; Logical operators.
520 (define_code_iterator iorxor            [ior xor])
521 (define_code_iterator and_ior_xor       [and ior xor])
523 ; Signed/unsigned variants of ops.
524 (define_code_iterator any_extend        [sign_extend zero_extend])
525 (define_code_iterator any_fix           [fix unsigned_fix])
526 (define_code_iterator any_float         [float unsigned_float])
528 (define_code_attr u  [(sign_extend      "")
529                       (zero_extend      "u")
530                       (fix              "")
531                       (unsigned_fix     "u")])
533 (define_code_attr su [(sign_extend      "s")
534                       (zero_extend      "u")
535                       (fix              "s")
536                       (unsigned_fix     "s")
537                       (float            "s")
538                       (unsigned_float   "u")])
540 (define_code_attr az [(sign_extend      "a")
541                       (zero_extend      "z")
542                       (fix              "a")
543                       (unsigned_fix     "z")
544                       (float            "a")
545                       (unsigned_float   "z")])
547 (define_code_attr uns [(fix             "")
548                        (unsigned_fix    "uns")
549                        (float           "")
550                        (unsigned_float  "uns")])
552 ; Various instructions that come in SI and DI forms.
553 ; A generic w/d attribute, for things like cmpw/cmpd.
554 (define_mode_attr wd [(QI    "b")
555                       (HI    "h")
556                       (SI    "w")
557                       (DI    "d")
558                       (V16QI "b")
559                       (V8HI  "h")
560                       (V4SI  "w")
561                       (V2DI  "d")
562                       (V1TI  "q")
563                       (TI    "q")])
565 ;; How many bits in this mode?
566 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
568 ; DImode bits
569 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
571 ;; ISEL/ISEL64 target selection
572 (define_mode_attr sel [(SI "") (DI "64")])
574 ;; Bitmask for shift instructions
575 (define_mode_attr hH [(SI "h") (DI "H")])
577 ;; A mode twice the size of the given mode
578 (define_mode_attr dmode [(SI "di") (DI "ti")])
579 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
581 ;; Suffix for reload patterns
582 (define_mode_attr ptrsize [(SI "32bit")
583                            (DI "64bit")])
585 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
586                             (DI "TARGET_64BIT")])
588 (define_mode_attr mptrsize [(SI "si")
589                             (DI "di")])
591 (define_mode_attr ptrload [(SI "lwz")
592                            (DI "ld")])
594 (define_mode_attr ptrm [(SI "m")
595                         (DI "Y")])
597 (define_mode_attr rreg [(SF   "f")
598                         (DF   "ws")
599                         (TF   "f")
600                         (TD   "f")
601                         (V4SF "wf")
602                         (V2DF "wd")])
604 (define_mode_attr rreg2 [(SF   "f")
605                          (DF   "d")])
607 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
608                                  (DF "TARGET_FCFID")])
610 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
611                                 (DF "TARGET_DOUBLE_FLOAT")])
613 ;; Mode iterator for logical operations on 128-bit types
614 (define_mode_iterator BOOL_128          [TI
615                                          PTI
616                                          (V16QI "TARGET_ALTIVEC")
617                                          (V8HI  "TARGET_ALTIVEC")
618                                          (V4SI  "TARGET_ALTIVEC")
619                                          (V4SF  "TARGET_ALTIVEC")
620                                          (V2DI  "TARGET_ALTIVEC")
621                                          (V2DF  "TARGET_ALTIVEC")
622                                          (V1TI  "TARGET_ALTIVEC")])
624 ;; For the GPRs we use 3 constraints for register outputs, two that are the
625 ;; same as the output register, and a third where the output register is an
626 ;; early clobber, so we don't have to deal with register overlaps.  For the
627 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
628 ;; either.
630 ;; Mode attribute for boolean operation register constraints for output
631 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
632                                          (PTI   "&r,r,r")
633                                          (V16QI "wa,v,&?r,?r,?r")
634                                          (V8HI  "wa,v,&?r,?r,?r")
635                                          (V4SI  "wa,v,&?r,?r,?r")
636                                          (V4SF  "wa,v,&?r,?r,?r")
637                                          (V2DI  "wa,v,&?r,?r,?r")
638                                          (V2DF  "wa,v,&?r,?r,?r")
639                                          (V1TI  "wa,v,&?r,?r,?r")])
641 ;; Mode attribute for boolean operation register constraints for operand1
642 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
643                                          (PTI   "r,0,r")
644                                          (V16QI "wa,v,r,0,r")
645                                          (V8HI  "wa,v,r,0,r")
646                                          (V4SI  "wa,v,r,0,r")
647                                          (V4SF  "wa,v,r,0,r")
648                                          (V2DI  "wa,v,r,0,r")
649                                          (V2DF  "wa,v,r,0,r")
650                                          (V1TI  "wa,v,r,0,r")])
652 ;; Mode attribute for boolean operation register constraints for operand2
653 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
654                                          (PTI   "r,r,0")
655                                          (V16QI "wa,v,r,r,0")
656                                          (V8HI  "wa,v,r,r,0")
657                                          (V4SI  "wa,v,r,r,0")
658                                          (V4SF  "wa,v,r,r,0")
659                                          (V2DI  "wa,v,r,r,0")
660                                          (V2DF  "wa,v,r,r,0")
661                                          (V1TI  "wa,v,r,r,0")])
663 ;; Mode attribute for boolean operation register constraints for operand1
664 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
665 ;; is used for operand1 or operand2
666 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
667                                          (PTI   "r,0,0")
668                                          (V16QI "wa,v,r,0,0")
669                                          (V8HI  "wa,v,r,0,0")
670                                          (V4SI  "wa,v,r,0,0")
671                                          (V4SF  "wa,v,r,0,0")
672                                          (V2DI  "wa,v,r,0,0")
673                                          (V2DF  "wa,v,r,0,0")
674                                          (V1TI  "wa,v,r,0,0")])
676 ;; Reload iterator for creating the function to allocate a base register to
677 ;; supplement addressing modes.
678 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
679                               SF SD SI DF DD DI TI PTI KF IF TF])
681 ;; Iterate over smin, smax
682 (define_code_iterator fp_minmax [smin smax])
684 (define_code_attr     minmax    [(smin "min")
685                                  (smax "max")])
687 (define_code_attr     SMINMAX   [(smin "SMIN")
688                                  (smax "SMAX")])
690 ;; Iterator to optimize the following cases:
691 ;;      D-form load to FPR register & move to Altivec register
692 ;;      Move Altivec register to FPR register and store
693 (define_mode_iterator ALTIVEC_DFORM [DF
694                                      (SF "TARGET_P8_VECTOR")
695                                      (DI "TARGET_POWERPC64")])
698 ;; Start with fixed-point load and store insns.  Here we put only the more
699 ;; complex forms.  Basic data transfer is done later.
701 (define_insn "zero_extendqi<mode>2"
702   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
703         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
704   ""
705   "@
706    lbz%U1%X1 %0,%1
707    rlwinm %0,%1,0,0xff
708    lxsibzx %x0,%y1
709    vextractub %0,%1,7"
710   [(set_attr "type" "load,shift,fpload,vecperm")])
712 (define_insn_and_split "*zero_extendqi<mode>2_dot"
713   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
714         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
715                     (const_int 0)))
716    (clobber (match_scratch:EXTQI 0 "=r,r"))]
717   ""
718   "@
719    andi. %0,%1,0xff
720    #"
721   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
722   [(set (match_dup 0)
723         (zero_extend:EXTQI (match_dup 1)))
724    (set (match_dup 2)
725         (compare:CC (match_dup 0)
726                     (const_int 0)))]
727   ""
728   [(set_attr "type" "logical")
729    (set_attr "dot" "yes")
730    (set_attr "length" "4,8")])
732 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
733   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
734         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
735                     (const_int 0)))
736    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
737         (zero_extend:EXTQI (match_dup 1)))]
738   ""
739   "@
740    andi. %0,%1,0xff
741    #"
742   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
743   [(set (match_dup 0)
744         (zero_extend:EXTQI (match_dup 1)))
745    (set (match_dup 2)
746         (compare:CC (match_dup 0)
747                     (const_int 0)))]
748   ""
749   [(set_attr "type" "logical")
750    (set_attr "dot" "yes")
751    (set_attr "length" "4,8")])
754 (define_insn "zero_extendhi<mode>2"
755   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
756         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
757   ""
758   "@
759    lhz%U1%X1 %0,%1
760    rlwinm %0,%1,0,0xffff
761    lxsihzx %x0,%y1
762    vextractuh %0,%1,6"
763   [(set_attr "type" "load,shift,fpload,vecperm")])
765 (define_insn_and_split "*zero_extendhi<mode>2_dot"
766   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
767         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
768                     (const_int 0)))
769    (clobber (match_scratch:EXTHI 0 "=r,r"))]
770   ""
771   "@
772    andi. %0,%1,0xffff
773    #"
774   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
775   [(set (match_dup 0)
776         (zero_extend:EXTHI (match_dup 1)))
777    (set (match_dup 2)
778         (compare:CC (match_dup 0)
779                     (const_int 0)))]
780   ""
781   [(set_attr "type" "logical")
782    (set_attr "dot" "yes")
783    (set_attr "length" "4,8")])
785 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
786   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
787         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
788                     (const_int 0)))
789    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
790         (zero_extend:EXTHI (match_dup 1)))]
791   ""
792   "@
793    andi. %0,%1,0xffff
794    #"
795   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
796   [(set (match_dup 0)
797         (zero_extend:EXTHI (match_dup 1)))
798    (set (match_dup 2)
799         (compare:CC (match_dup 0)
800                     (const_int 0)))]
801   ""
802   [(set_attr "type" "logical")
803    (set_attr "dot" "yes")
804    (set_attr "length" "4,8")])
807 (define_insn "zero_extendsi<mode>2"
808   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
809         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
810   ""
811   "@
812    lwz%U1%X1 %0,%1
813    rldicl %0,%1,0,32
814    lfiwzx %0,%y1
815    lxsiwzx %x0,%y1
816    mtvsrwz %x0,%1
817    mfvsrwz %0,%x1
818    xxextractuw %x0,%x1,4"
819   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
821 (define_insn_and_split "*zero_extendsi<mode>2_dot"
822   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
823         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
824                     (const_int 0)))
825    (clobber (match_scratch:EXTSI 0 "=r,r"))]
826   ""
827   "@
828    rldicl. %0,%1,0,32
829    #"
830   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
831   [(set (match_dup 0)
832         (zero_extend:DI (match_dup 1)))
833    (set (match_dup 2)
834         (compare:CC (match_dup 0)
835                     (const_int 0)))]
836   ""
837   [(set_attr "type" "shift")
838    (set_attr "dot" "yes")
839    (set_attr "length" "4,8")])
841 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
842   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
843         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
844                     (const_int 0)))
845    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
846         (zero_extend:EXTSI (match_dup 1)))]
847   ""
848   "@
849    rldicl. %0,%1,0,32
850    #"
851   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
852   [(set (match_dup 0)
853         (zero_extend:EXTSI (match_dup 1)))
854    (set (match_dup 2)
855         (compare:CC (match_dup 0)
856                     (const_int 0)))]
857   ""
858   [(set_attr "type" "shift")
859    (set_attr "dot" "yes")
860    (set_attr "length" "4,8")])
863 (define_insn "extendqi<mode>2"
864   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
865         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
866   ""
867   "@
868    extsb %0,%1
869    vextsb2d %0,%1"
870   [(set_attr "type" "exts,vecperm")])
872 (define_insn_and_split "*extendqi<mode>2_dot"
873   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
874         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
875                     (const_int 0)))
876    (clobber (match_scratch:EXTQI 0 "=r,r"))]
877   ""
878   "@
879    extsb. %0,%1
880    #"
881   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
882   [(set (match_dup 0)
883         (sign_extend:EXTQI (match_dup 1)))
884    (set (match_dup 2)
885         (compare:CC (match_dup 0)
886                     (const_int 0)))]
887   ""
888   [(set_attr "type" "exts")
889    (set_attr "dot" "yes")
890    (set_attr "length" "4,8")])
892 (define_insn_and_split "*extendqi<mode>2_dot2"
893   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
894         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
895                     (const_int 0)))
896    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
897         (sign_extend:EXTQI (match_dup 1)))]
898   ""
899   "@
900    extsb. %0,%1
901    #"
902   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
903   [(set (match_dup 0)
904         (sign_extend:EXTQI (match_dup 1)))
905    (set (match_dup 2)
906         (compare:CC (match_dup 0)
907                     (const_int 0)))]
908   ""
909   [(set_attr "type" "exts")
910    (set_attr "dot" "yes")
911    (set_attr "length" "4,8")])
914 (define_expand "extendhi<mode>2"
915   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
916         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
917   ""
918   "")
920 (define_insn "*extendhi<mode>2"
921   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
922         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
923   ""
924   "@
925    lha%U1%X1 %0,%1
926    extsh %0,%1
927    #
928    vextsh2d %0,%1"
929   [(set_attr "type" "load,exts,fpload,vecperm")
930    (set_attr "sign_extend" "yes")
931    (set_attr "length" "4,4,8,4")])
933 (define_split
934   [(set (match_operand:EXTHI 0 "altivec_register_operand")
935         (sign_extend:EXTHI
936          (match_operand:HI 1 "indexed_or_indirect_operand")))]
937   "TARGET_P9_VECTOR && reload_completed"
938   [(set (match_dup 2)
939         (match_dup 1))
940    (set (match_dup 0)
941         (sign_extend:EXTHI (match_dup 2)))]
943   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
946 (define_insn_and_split "*extendhi<mode>2_dot"
947   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
948         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
949                     (const_int 0)))
950    (clobber (match_scratch:EXTHI 0 "=r,r"))]
951   ""
952   "@
953    extsh. %0,%1
954    #"
955   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
956   [(set (match_dup 0)
957         (sign_extend:EXTHI (match_dup 1)))
958    (set (match_dup 2)
959         (compare:CC (match_dup 0)
960                     (const_int 0)))]
961   ""
962   [(set_attr "type" "exts")
963    (set_attr "dot" "yes")
964    (set_attr "length" "4,8")])
966 (define_insn_and_split "*extendhi<mode>2_dot2"
967   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
968         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
969                     (const_int 0)))
970    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
971         (sign_extend:EXTHI (match_dup 1)))]
972   ""
973   "@
974    extsh. %0,%1
975    #"
976   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
977   [(set (match_dup 0)
978         (sign_extend:EXTHI (match_dup 1)))
979    (set (match_dup 2)
980         (compare:CC (match_dup 0)
981                     (const_int 0)))]
982   ""
983   [(set_attr "type" "exts")
984    (set_attr "dot" "yes")
985    (set_attr "length" "4,8")])
988 (define_insn "extendsi<mode>2"
989   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK,wH")
990         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))]
991   ""
992   "@
993    lwa%U1%X1 %0,%1
994    extsw %0,%1
995    lfiwax %0,%y1
996    lxsiwax %x0,%y1
997    mtvsrwa %x0,%1
998    vextsw2d %0,%1
999    #"
1000   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm")
1001    (set_attr "sign_extend" "yes")
1002    (set_attr "length" "4,4,4,4,4,4,8")])
1004 (define_split
1005   [(set (match_operand:DI 0 "altivec_register_operand")
1006         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1007   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1008   [(const_int 0)]
1010   rtx dest = operands[0];
1011   rtx src = operands[1];
1012   int dest_regno = REGNO (dest);
1013   int src_regno = REGNO (src);
1014   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1015   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1017   if (VECTOR_ELT_ORDER_BIG)
1018     {
1019       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1020       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1021     }
1022   else
1023     {
1024       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1025       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1026     }
1027   DONE;
1030 (define_insn_and_split "*extendsi<mode>2_dot"
1031   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1032         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1033                     (const_int 0)))
1034    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1035   ""
1036   "@
1037    extsw. %0,%1
1038    #"
1039   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1040   [(set (match_dup 0)
1041         (sign_extend:EXTSI (match_dup 1)))
1042    (set (match_dup 2)
1043         (compare:CC (match_dup 0)
1044                     (const_int 0)))]
1045   ""
1046   [(set_attr "type" "exts")
1047    (set_attr "dot" "yes")
1048    (set_attr "length" "4,8")])
1050 (define_insn_and_split "*extendsi<mode>2_dot2"
1051   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1052         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1053                     (const_int 0)))
1054    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1055         (sign_extend:EXTSI (match_dup 1)))]
1056   ""
1057   "@
1058    extsw. %0,%1
1059    #"
1060   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1061   [(set (match_dup 0)
1062         (sign_extend:EXTSI (match_dup 1)))
1063    (set (match_dup 2)
1064         (compare:CC (match_dup 0)
1065                     (const_int 0)))]
1066   ""
1067   [(set_attr "type" "exts")
1068    (set_attr "dot" "yes")
1069    (set_attr "length" "4,8")])
1071 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1073 (define_insn "*macchwc"
1074   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1075         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1076                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1077                                        (const_int 16))
1078                                       (sign_extend:SI
1079                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1080                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1081                     (const_int 0)))
1082    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1083         (plus:SI (mult:SI (ashiftrt:SI
1084                            (match_dup 2)
1085                            (const_int 16))
1086                           (sign_extend:SI
1087                            (match_dup 1)))
1088                  (match_dup 4)))]
1089   "TARGET_MULHW"
1090   "macchw. %0,%1,%2"
1091   [(set_attr "type" "halfmul")])
1093 (define_insn "*macchw"
1094   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1095         (plus:SI (mult:SI (ashiftrt:SI
1096                            (match_operand:SI 2 "gpc_reg_operand" "r")
1097                            (const_int 16))
1098                           (sign_extend:SI
1099                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1100                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1101   "TARGET_MULHW"
1102   "macchw %0,%1,%2"
1103   [(set_attr "type" "halfmul")])
1105 (define_insn "*macchwuc"
1106   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1107         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1108                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1109                                        (const_int 16))
1110                                       (zero_extend:SI
1111                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1112                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1113                     (const_int 0)))
1114    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1115         (plus:SI (mult:SI (lshiftrt:SI
1116                            (match_dup 2)
1117                            (const_int 16))
1118                           (zero_extend:SI
1119                            (match_dup 1)))
1120                  (match_dup 4)))]
1121   "TARGET_MULHW"
1122   "macchwu. %0,%1,%2"
1123   [(set_attr "type" "halfmul")])
1125 (define_insn "*macchwu"
1126   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1127         (plus:SI (mult:SI (lshiftrt:SI
1128                            (match_operand:SI 2 "gpc_reg_operand" "r")
1129                            (const_int 16))
1130                           (zero_extend:SI
1131                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1132                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1133   "TARGET_MULHW"
1134   "macchwu %0,%1,%2"
1135   [(set_attr "type" "halfmul")])
1137 (define_insn "*machhwc"
1138   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1139         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1140                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1141                                        (const_int 16))
1142                                       (ashiftrt:SI
1143                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1144                                        (const_int 16)))
1145                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1146                     (const_int 0)))
1147    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1148         (plus:SI (mult:SI (ashiftrt:SI
1149                            (match_dup 1)
1150                            (const_int 16))
1151                           (ashiftrt:SI
1152                            (match_dup 2)
1153                            (const_int 16)))
1154                  (match_dup 4)))]
1155   "TARGET_MULHW"
1156   "machhw. %0,%1,%2"
1157   [(set_attr "type" "halfmul")])
1159 (define_insn "*machhw"
1160   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1161         (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 3 "gpc_reg_operand" "0")))]
1168   "TARGET_MULHW"
1169   "machhw %0,%1,%2"
1170   [(set_attr "type" "halfmul")])
1172 (define_insn "*machhwuc"
1173   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1174         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1175                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1176                                        (const_int 16))
1177                                       (lshiftrt:SI
1178                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1179                                        (const_int 16)))
1180                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1181                     (const_int 0)))
1182    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1183         (plus:SI (mult:SI (lshiftrt:SI
1184                            (match_dup 1)
1185                            (const_int 16))
1186                           (lshiftrt:SI
1187                            (match_dup 2)
1188                            (const_int 16)))
1189                  (match_dup 4)))]
1190   "TARGET_MULHW"
1191   "machhwu. %0,%1,%2"
1192   [(set_attr "type" "halfmul")])
1194 (define_insn "*machhwu"
1195   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1196         (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 3 "gpc_reg_operand" "0")))]
1203   "TARGET_MULHW"
1204   "machhwu %0,%1,%2"
1205   [(set_attr "type" "halfmul")])
1207 (define_insn "*maclhwc"
1208   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1209         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1210                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1211                                       (sign_extend:SI
1212                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1213                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1214                     (const_int 0)))
1215    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1216         (plus:SI (mult:SI (sign_extend:SI
1217                            (match_dup 1))
1218                           (sign_extend:SI
1219                            (match_dup 2)))
1220                  (match_dup 4)))]
1221   "TARGET_MULHW"
1222   "maclhw. %0,%1,%2"
1223   [(set_attr "type" "halfmul")])
1225 (define_insn "*maclhw"
1226   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1227         (plus:SI (mult:SI (sign_extend:SI
1228                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1229                           (sign_extend:SI
1230                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1231                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1232   "TARGET_MULHW"
1233   "maclhw %0,%1,%2"
1234   [(set_attr "type" "halfmul")])
1236 (define_insn "*maclhwuc"
1237   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1238         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1239                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1240                                       (zero_extend:SI
1241                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1242                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1243                     (const_int 0)))
1244    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245         (plus:SI (mult:SI (zero_extend:SI
1246                            (match_dup 1))
1247                           (zero_extend:SI
1248                            (match_dup 2)))
1249                  (match_dup 4)))]
1250   "TARGET_MULHW"
1251   "maclhwu. %0,%1,%2"
1252   [(set_attr "type" "halfmul")])
1254 (define_insn "*maclhwu"
1255   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256         (plus:SI (mult:SI (zero_extend:SI
1257                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1258                           (zero_extend:SI
1259                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1260                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1261   "TARGET_MULHW"
1262   "maclhwu %0,%1,%2"
1263   [(set_attr "type" "halfmul")])
1265 (define_insn "*nmacchwc"
1266   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1267         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1268                               (mult:SI (ashiftrt:SI
1269                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1270                                         (const_int 16))
1271                                        (sign_extend:SI
1272                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1273                     (const_int 0)))
1274    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1275         (minus:SI (match_dup 4)
1276                   (mult:SI (ashiftrt:SI
1277                             (match_dup 2)
1278                             (const_int 16))
1279                            (sign_extend:SI
1280                             (match_dup 1)))))]
1281   "TARGET_MULHW"
1282   "nmacchw. %0,%1,%2"
1283   [(set_attr "type" "halfmul")])
1285 (define_insn "*nmacchw"
1286   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1287         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1288                   (mult:SI (ashiftrt:SI
1289                             (match_operand:SI 2 "gpc_reg_operand" "r")
1290                             (const_int 16))
1291                            (sign_extend:SI
1292                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1293   "TARGET_MULHW"
1294   "nmacchw %0,%1,%2"
1295   [(set_attr "type" "halfmul")])
1297 (define_insn "*nmachhwc"
1298   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1299         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1300                               (mult:SI (ashiftrt:SI
1301                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1302                                         (const_int 16))
1303                                        (ashiftrt:SI
1304                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1305                                         (const_int 16))))
1306                     (const_int 0)))
1307    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1308         (minus:SI (match_dup 4)
1309                   (mult:SI (ashiftrt:SI
1310                             (match_dup 1)
1311                             (const_int 16))
1312                            (ashiftrt:SI
1313                             (match_dup 2)
1314                             (const_int 16)))))]
1315   "TARGET_MULHW"
1316   "nmachhw. %0,%1,%2"
1317   [(set_attr "type" "halfmul")])
1319 (define_insn "*nmachhw"
1320   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1321         (minus:SI (match_operand:SI 3 "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   "TARGET_MULHW"
1329   "nmachhw %0,%1,%2"
1330   [(set_attr "type" "halfmul")])
1332 (define_insn "*nmaclhwc"
1333   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1334         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1335                               (mult:SI (sign_extend:SI
1336                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1337                                        (sign_extend:SI
1338                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1339                     (const_int 0)))
1340    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341         (minus:SI (match_dup 4)
1342                   (mult:SI (sign_extend:SI
1343                             (match_dup 1))
1344                            (sign_extend:SI
1345                             (match_dup 2)))))]
1346   "TARGET_MULHW"
1347   "nmaclhw. %0,%1,%2"
1348   [(set_attr "type" "halfmul")])
1350 (define_insn "*nmaclhw"
1351   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1352         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1353                   (mult:SI (sign_extend:SI
1354                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1355                            (sign_extend:SI
1356                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1357   "TARGET_MULHW"
1358   "nmaclhw %0,%1,%2"
1359   [(set_attr "type" "halfmul")])
1361 (define_insn "*mulchwc"
1362   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1363         (compare:CC (mult:SI (ashiftrt:SI
1364                               (match_operand:SI 2 "gpc_reg_operand" "r")
1365                               (const_int 16))
1366                              (sign_extend:SI
1367                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1368                     (const_int 0)))
1369    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1370         (mult:SI (ashiftrt:SI
1371                   (match_dup 2)
1372                   (const_int 16))
1373                  (sign_extend:SI
1374                   (match_dup 1))))]
1375   "TARGET_MULHW"
1376   "mulchw. %0,%1,%2"
1377   [(set_attr "type" "halfmul")])
1379 (define_insn "*mulchw"
1380   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1381         (mult:SI (ashiftrt:SI
1382                   (match_operand:SI 2 "gpc_reg_operand" "r")
1383                   (const_int 16))
1384                  (sign_extend:SI
1385                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1386   "TARGET_MULHW"
1387   "mulchw %0,%1,%2"
1388   [(set_attr "type" "halfmul")])
1390 (define_insn "*mulchwuc"
1391   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1392         (compare:CC (mult:SI (lshiftrt:SI
1393                               (match_operand:SI 2 "gpc_reg_operand" "r")
1394                               (const_int 16))
1395                              (zero_extend:SI
1396                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1397                     (const_int 0)))
1398    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399         (mult:SI (lshiftrt:SI
1400                   (match_dup 2)
1401                   (const_int 16))
1402                  (zero_extend:SI
1403                   (match_dup 1))))]
1404   "TARGET_MULHW"
1405   "mulchwu. %0,%1,%2"
1406   [(set_attr "type" "halfmul")])
1408 (define_insn "*mulchwu"
1409   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1410         (mult:SI (lshiftrt:SI
1411                   (match_operand:SI 2 "gpc_reg_operand" "r")
1412                   (const_int 16))
1413                  (zero_extend:SI
1414                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1415   "TARGET_MULHW"
1416   "mulchwu %0,%1,%2"
1417   [(set_attr "type" "halfmul")])
1419 (define_insn "*mulhhwc"
1420   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1421         (compare:CC (mult:SI (ashiftrt:SI
1422                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1423                               (const_int 16))
1424                              (ashiftrt:SI
1425                               (match_operand:SI 2 "gpc_reg_operand" "r")
1426                               (const_int 16)))
1427                     (const_int 0)))
1428    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1429         (mult:SI (ashiftrt:SI
1430                   (match_dup 1)
1431                   (const_int 16))
1432                  (ashiftrt:SI
1433                   (match_dup 2)
1434                   (const_int 16))))]
1435   "TARGET_MULHW"
1436   "mulhhw. %0,%1,%2"
1437   [(set_attr "type" "halfmul")])
1439 (define_insn "*mulhhw"
1440   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1441         (mult:SI (ashiftrt:SI
1442                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1443                   (const_int 16))
1444                  (ashiftrt:SI
1445                   (match_operand:SI 2 "gpc_reg_operand" "r")
1446                   (const_int 16))))]
1447   "TARGET_MULHW"
1448   "mulhhw %0,%1,%2"
1449   [(set_attr "type" "halfmul")])
1451 (define_insn "*mulhhwuc"
1452   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1453         (compare:CC (mult:SI (lshiftrt:SI
1454                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1455                               (const_int 16))
1456                              (lshiftrt:SI
1457                               (match_operand:SI 2 "gpc_reg_operand" "r")
1458                               (const_int 16)))
1459                     (const_int 0)))
1460    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1461         (mult:SI (lshiftrt:SI
1462                   (match_dup 1)
1463                   (const_int 16))
1464                  (lshiftrt:SI
1465                   (match_dup 2)
1466                   (const_int 16))))]
1467   "TARGET_MULHW"
1468   "mulhhwu. %0,%1,%2"
1469   [(set_attr "type" "halfmul")])
1471 (define_insn "*mulhhwu"
1472   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1473         (mult:SI (lshiftrt:SI
1474                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1475                   (const_int 16))
1476                  (lshiftrt:SI
1477                   (match_operand:SI 2 "gpc_reg_operand" "r")
1478                   (const_int 16))))]
1479   "TARGET_MULHW"
1480   "mulhhwu %0,%1,%2"
1481   [(set_attr "type" "halfmul")])
1483 (define_insn "*mullhwc"
1484   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1485         (compare:CC (mult:SI (sign_extend:SI
1486                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1487                              (sign_extend:SI
1488                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1489                     (const_int 0)))
1490    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491         (mult:SI (sign_extend:SI
1492                   (match_dup 1))
1493                  (sign_extend:SI
1494                   (match_dup 2))))]
1495   "TARGET_MULHW"
1496   "mullhw. %0,%1,%2"
1497   [(set_attr "type" "halfmul")])
1499 (define_insn "*mullhw"
1500   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1501         (mult:SI (sign_extend:SI
1502                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1503                  (sign_extend:SI
1504                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1505   "TARGET_MULHW"
1506   "mullhw %0,%1,%2"
1507   [(set_attr "type" "halfmul")])
1509 (define_insn "*mullhwuc"
1510   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1511         (compare:CC (mult:SI (zero_extend:SI
1512                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1513                              (zero_extend:SI
1514                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1515                     (const_int 0)))
1516    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517         (mult:SI (zero_extend:SI
1518                   (match_dup 1))
1519                  (zero_extend:SI
1520                   (match_dup 2))))]
1521   "TARGET_MULHW"
1522   "mullhwu. %0,%1,%2"
1523   [(set_attr "type" "halfmul")])
1525 (define_insn "*mullhwu"
1526   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1527         (mult:SI (zero_extend:SI
1528                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1529                  (zero_extend:SI
1530                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1531   "TARGET_MULHW"
1532   "mullhwu %0,%1,%2"
1533   [(set_attr "type" "halfmul")])
1535 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1536 (define_insn "dlmzb"
1537   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1538         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1539                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1540                    UNSPEC_DLMZB_CR))
1541    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1542         (unspec:SI [(match_dup 1)
1543                     (match_dup 2)]
1544                    UNSPEC_DLMZB))]
1545   "TARGET_DLMZB"
1546   "dlmzb. %0,%1,%2")
1548 (define_expand "strlensi"
1549   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1550         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1551                     (match_operand:QI 2 "const_int_operand" "")
1552                     (match_operand 3 "const_int_operand" "")]
1553                    UNSPEC_DLMZB_STRLEN))
1554    (clobber (match_scratch:CC 4 "=x"))]
1555   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1557   rtx result = operands[0];
1558   rtx src = operands[1];
1559   rtx search_char = operands[2];
1560   rtx align = operands[3];
1561   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1562   rtx loop_label, end_label, mem, cr0, cond;
1563   if (search_char != const0_rtx
1564       || GET_CODE (align) != CONST_INT
1565       || INTVAL (align) < 8)
1566         FAIL;
1567   word1 = gen_reg_rtx (SImode);
1568   word2 = gen_reg_rtx (SImode);
1569   scratch_dlmzb = gen_reg_rtx (SImode);
1570   scratch_string = gen_reg_rtx (Pmode);
1571   loop_label = gen_label_rtx ();
1572   end_label = gen_label_rtx ();
1573   addr = force_reg (Pmode, XEXP (src, 0));
1574   emit_move_insn (scratch_string, addr);
1575   emit_label (loop_label);
1576   mem = change_address (src, SImode, scratch_string);
1577   emit_move_insn (word1, mem);
1578   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1579   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1580   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1581   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1582   emit_jump_insn (gen_rtx_SET (pc_rtx,
1583                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1584                                                      cond,
1585                                                      gen_rtx_LABEL_REF
1586                                                        (VOIDmode,
1587                                                         end_label),
1588                                                      pc_rtx)));
1589   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1590   emit_jump_insn (gen_rtx_SET (pc_rtx,
1591                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1592   emit_barrier ();
1593   emit_label (end_label);
1594   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1595   emit_insn (gen_subsi3 (result, scratch_string, addr));
1596   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1597   DONE;
1600 ;; Fixed-point arithmetic insns.
1602 (define_expand "add<mode>3"
1603   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1604         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1605                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1606   ""
1608   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1609     {
1610       rtx lo0 = gen_lowpart (SImode, operands[0]);
1611       rtx lo1 = gen_lowpart (SImode, operands[1]);
1612       rtx lo2 = gen_lowpart (SImode, operands[2]);
1613       rtx hi0 = gen_highpart (SImode, operands[0]);
1614       rtx hi1 = gen_highpart (SImode, operands[1]);
1615       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1617       if (!reg_or_short_operand (lo2, SImode))
1618         lo2 = force_reg (SImode, lo2);
1619       if (!adde_operand (hi2, SImode))
1620         hi2 = force_reg (SImode, hi2);
1622       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1623       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1624       DONE;
1625     }
1627   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1628     {
1629       rtx tmp = ((!can_create_pseudo_p ()
1630                   || rtx_equal_p (operands[0], operands[1]))
1631                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1633       /* Adding a constant to r0 is not a valid insn, so use a different
1634          strategy in that case.  */
1635       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1636         {
1637           if (operands[0] == operands[1])
1638             FAIL;
1639           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1640           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1641           DONE;
1642         }
1644       HOST_WIDE_INT val = INTVAL (operands[2]);
1645       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1646       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1648       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1649         FAIL;
1651       /* The ordering here is important for the prolog expander.
1652          When space is allocated from the stack, adding 'low' first may
1653          produce a temporary deallocation (which would be bad).  */
1654       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1655       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1656       DONE;
1657     }
1660 (define_insn "*add<mode>3"
1661   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1662         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1663                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1664   ""
1665   "@
1666    add %0,%1,%2
1667    addi %0,%1,%2
1668    addis %0,%1,%v2"
1669   [(set_attr "type" "add")])
1671 (define_insn "addsi3_high"
1672   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1673         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1674                  (high:SI (match_operand 2 "" ""))))]
1675   "TARGET_MACHO && !TARGET_64BIT"
1676   "addis %0,%1,ha16(%2)"
1677   [(set_attr "type" "add")])
1679 (define_insn_and_split "*add<mode>3_dot"
1680   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1681         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1682                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1683                     (const_int 0)))
1684    (clobber (match_scratch:GPR 0 "=r,r"))]
1685   "<MODE>mode == Pmode"
1686   "@
1687    add. %0,%1,%2
1688    #"
1689   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1690   [(set (match_dup 0)
1691         (plus:GPR (match_dup 1)
1692                  (match_dup 2)))
1693    (set (match_dup 3)
1694         (compare:CC (match_dup 0)
1695                     (const_int 0)))]
1696   ""
1697   [(set_attr "type" "add")
1698    (set_attr "dot" "yes")
1699    (set_attr "length" "4,8")])
1701 (define_insn_and_split "*add<mode>3_dot2"
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    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1707         (plus:GPR (match_dup 1)
1708                   (match_dup 2)))]
1709   "<MODE>mode == Pmode"
1710   "@
1711    add. %0,%1,%2
1712    #"
1713   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1714   [(set (match_dup 0)
1715         (plus:GPR (match_dup 1)
1716                   (match_dup 2)))
1717    (set (match_dup 3)
1718         (compare:CC (match_dup 0)
1719                     (const_int 0)))]
1720   ""
1721   [(set_attr "type" "add")
1722    (set_attr "dot" "yes")
1723    (set_attr "length" "4,8")])
1725 (define_insn_and_split "*add<mode>3_imm_dot"
1726   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1727         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1728                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1729                     (const_int 0)))
1730    (clobber (match_scratch:GPR 0 "=r,r"))
1731    (clobber (reg:GPR CA_REGNO))]
1732   "<MODE>mode == Pmode"
1733   "@
1734    addic. %0,%1,%2
1735    #"
1736   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1737   [(set (match_dup 0)
1738         (plus:GPR (match_dup 1)
1739                   (match_dup 2)))
1740    (set (match_dup 3)
1741         (compare:CC (match_dup 0)
1742                     (const_int 0)))]
1743   ""
1744   [(set_attr "type" "add")
1745    (set_attr "dot" "yes")
1746    (set_attr "length" "4,8")])
1748 (define_insn_and_split "*add<mode>3_imm_dot2"
1749   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1750         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1751                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1752                     (const_int 0)))
1753    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1754         (plus:GPR (match_dup 1)
1755                   (match_dup 2)))
1756    (clobber (reg:GPR CA_REGNO))]
1757   "<MODE>mode == Pmode"
1758   "@
1759    addic. %0,%1,%2
1760    #"
1761   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1762   [(set (match_dup 0)
1763         (plus:GPR (match_dup 1)
1764                   (match_dup 2)))
1765    (set (match_dup 3)
1766         (compare:CC (match_dup 0)
1767                     (const_int 0)))]
1768   ""
1769   [(set_attr "type" "add")
1770    (set_attr "dot" "yes")
1771    (set_attr "length" "4,8")])
1773 ;; Split an add that we can't do in one insn into two insns, each of which
1774 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1775 ;; add should be last in case the result gets used in an address.
1777 (define_split
1778   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1779         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1780                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1781   ""
1782   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1783    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1785   HOST_WIDE_INT val = INTVAL (operands[2]);
1786   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1787   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1789   operands[4] = GEN_INT (low);
1790   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1791     operands[3] = GEN_INT (rest);
1792   else if (can_create_pseudo_p ())
1793     {
1794       operands[3] = gen_reg_rtx (DImode);
1795       emit_move_insn (operands[3], operands[2]);
1796       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1797       DONE;
1798     }
1799   else
1800     FAIL;
1804 (define_insn "add<mode>3_carry"
1805   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1806         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1807                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1808    (set (reg:P CA_REGNO)
1809         (ltu:P (plus:P (match_dup 1)
1810                        (match_dup 2))
1811                (match_dup 1)))]
1812   ""
1813   "add%I2c %0,%1,%2"
1814   [(set_attr "type" "add")])
1816 (define_insn "*add<mode>3_imm_carry_pos"
1817   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1818         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1819                 (match_operand:P 2 "short_cint_operand" "n")))
1820    (set (reg:P CA_REGNO)
1821         (geu:P (match_dup 1)
1822                (match_operand:P 3 "const_int_operand" "n")))]
1823   "INTVAL (operands[2]) > 0
1824    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1825   "addic %0,%1,%2"
1826   [(set_attr "type" "add")])
1828 (define_insn "*add<mode>3_imm_carry_0"
1829   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1830         (match_operand:P 1 "gpc_reg_operand" "r"))
1831    (set (reg:P CA_REGNO)
1832         (const_int 0))]
1833   ""
1834   "addic %0,%1,0"
1835   [(set_attr "type" "add")])
1837 (define_insn "*add<mode>3_imm_carry_m1"
1838   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1839         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1840                 (const_int -1)))
1841    (set (reg:P CA_REGNO)
1842         (ne:P (match_dup 1)
1843               (const_int 0)))]
1844   ""
1845   "addic %0,%1,-1"
1846   [(set_attr "type" "add")])
1848 (define_insn "*add<mode>3_imm_carry_neg"
1849   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1850         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1851                 (match_operand:P 2 "short_cint_operand" "n")))
1852    (set (reg:P CA_REGNO)
1853         (gtu:P (match_dup 1)
1854                (match_operand:P 3 "const_int_operand" "n")))]
1855   "INTVAL (operands[2]) < 0
1856    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1857   "addic %0,%1,%2"
1858   [(set_attr "type" "add")])
1861 (define_expand "add<mode>3_carry_in"
1862   [(parallel [
1863      (set (match_operand:GPR 0 "gpc_reg_operand")
1864           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1865                               (match_operand:GPR 2 "adde_operand"))
1866                     (reg:GPR CA_REGNO)))
1867      (clobber (reg:GPR CA_REGNO))])]
1868   ""
1870   if (operands[2] == const0_rtx)
1871     {
1872       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1873       DONE;
1874     }
1875   if (operands[2] == constm1_rtx)
1876     {
1877       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1878       DONE;
1879     }
1882 (define_insn "*add<mode>3_carry_in_internal"
1883   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1884         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1885                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1886                   (reg:GPR CA_REGNO)))
1887    (clobber (reg:GPR CA_REGNO))]
1888   ""
1889   "adde %0,%1,%2"
1890   [(set_attr "type" "add")])
1892 (define_insn "add<mode>3_carry_in_0"
1893   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1894         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1895                   (reg:GPR CA_REGNO)))
1896    (clobber (reg:GPR CA_REGNO))]
1897   ""
1898   "addze %0,%1"
1899   [(set_attr "type" "add")])
1901 (define_insn "add<mode>3_carry_in_m1"
1902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904                             (reg:GPR CA_REGNO))
1905                   (const_int -1)))
1906    (clobber (reg:GPR CA_REGNO))]
1907   ""
1908   "addme %0,%1"
1909   [(set_attr "type" "add")])
1912 (define_expand "one_cmpl<mode>2"
1913   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1914         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1915   ""
1917   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1918     {
1919       rs6000_split_logical (operands, NOT, false, false, false);
1920       DONE;
1921     }
1924 (define_insn "*one_cmpl<mode>2"
1925   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1926         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1927   ""
1928   "not %0,%1")
1930 (define_insn_and_split "*one_cmpl<mode>2_dot"
1931   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1932         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1933                     (const_int 0)))
1934    (clobber (match_scratch:GPR 0 "=r,r"))]
1935   "<MODE>mode == Pmode"
1936   "@
1937    not. %0,%1
1938    #"
1939   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1940   [(set (match_dup 0)
1941         (not:GPR (match_dup 1)))
1942    (set (match_dup 2)
1943         (compare:CC (match_dup 0)
1944                     (const_int 0)))]
1945   ""
1946   [(set_attr "type" "logical")
1947    (set_attr "dot" "yes")
1948    (set_attr "length" "4,8")])
1950 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1951   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1952         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1953                     (const_int 0)))
1954    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1955         (not:GPR (match_dup 1)))]
1956   "<MODE>mode == Pmode"
1957   "@
1958    not. %0,%1
1959    #"
1960   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1961   [(set (match_dup 0)
1962         (not:GPR (match_dup 1)))
1963    (set (match_dup 2)
1964         (compare:CC (match_dup 0)
1965                     (const_int 0)))]
1966   ""
1967   [(set_attr "type" "logical")
1968    (set_attr "dot" "yes")
1969    (set_attr "length" "4,8")])
1972 (define_expand "sub<mode>3"
1973   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1974         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1975                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1976   ""
1978   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1979     {
1980       rtx lo0 = gen_lowpart (SImode, operands[0]);
1981       rtx lo1 = gen_lowpart (SImode, operands[1]);
1982       rtx lo2 = gen_lowpart (SImode, operands[2]);
1983       rtx hi0 = gen_highpart (SImode, operands[0]);
1984       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1985       rtx hi2 = gen_highpart (SImode, operands[2]);
1987       if (!reg_or_short_operand (lo1, SImode))
1988         lo1 = force_reg (SImode, lo1);
1989       if (!adde_operand (hi1, SImode))
1990         hi1 = force_reg (SImode, hi1);
1992       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1993       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1994       DONE;
1995     }
1997   if (short_cint_operand (operands[1], <MODE>mode))
1998     {
1999       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2000       DONE;
2001     }
2004 (define_insn "*subf<mode>3"
2005   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2006         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2007                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2008   ""
2009   "subf %0,%1,%2"
2010   [(set_attr "type" "add")])
2012 (define_insn_and_split "*subf<mode>3_dot"
2013   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2014         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2015                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2016                     (const_int 0)))
2017    (clobber (match_scratch:GPR 0 "=r,r"))]
2018   "<MODE>mode == Pmode"
2019   "@
2020    subf. %0,%1,%2
2021    #"
2022   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2023   [(set (match_dup 0)
2024         (minus:GPR (match_dup 2)
2025                    (match_dup 1)))
2026    (set (match_dup 3)
2027         (compare:CC (match_dup 0)
2028                     (const_int 0)))]
2029   ""
2030   [(set_attr "type" "add")
2031    (set_attr "dot" "yes")
2032    (set_attr "length" "4,8")])
2034 (define_insn_and_split "*subf<mode>3_dot2"
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    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2040         (minus:GPR (match_dup 2)
2041                    (match_dup 1)))]
2042   "<MODE>mode == Pmode"
2043   "@
2044    subf. %0,%1,%2
2045    #"
2046   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2047   [(set (match_dup 0)
2048         (minus:GPR (match_dup 2)
2049                    (match_dup 1)))
2050    (set (match_dup 3)
2051         (compare:CC (match_dup 0)
2052                     (const_int 0)))]
2053   ""
2054   [(set_attr "type" "add")
2055    (set_attr "dot" "yes")
2056    (set_attr "length" "4,8")])
2058 (define_insn "subf<mode>3_imm"
2059   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2060         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2061                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2062    (clobber (reg:GPR CA_REGNO))]
2063   ""
2064   "subfic %0,%1,%2"
2065   [(set_attr "type" "add")])
2067 (define_insn_and_split "subf<mode>3_carry_dot2"
2068   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2069         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2070                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2071                     (const_int 0)))
2072    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2073         (minus:P (match_dup 2)
2074                    (match_dup 1)))
2075    (set (reg:P CA_REGNO)
2076         (leu:P (match_dup 1)
2077                (match_dup 2)))]
2078   "<MODE>mode == Pmode"
2079   "@
2080    subfc. %0,%1,%2
2081    #"
2082   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2083   [(parallel [(set (match_dup 0)
2084                    (minus:P (match_dup 2)
2085                             (match_dup 1)))
2086               (set (reg:P CA_REGNO)
2087                    (leu:P (match_dup 1)
2088                           (match_dup 2)))])
2089    (set (match_dup 3)
2090         (compare:CC (match_dup 0)
2091                     (const_int 0)))]
2092   ""
2093   [(set_attr "type" "add")
2094    (set_attr "dot" "yes")
2095    (set_attr "length" "4,8")])
2097 (define_insn "subf<mode>3_carry"
2098   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2099         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2100                  (match_operand:P 1 "gpc_reg_operand" "r")))
2101    (set (reg:P CA_REGNO)
2102         (leu:P (match_dup 1)
2103                (match_dup 2)))]
2104   ""
2105   "subf%I2c %0,%1,%2"
2106   [(set_attr "type" "add")])
2108 (define_insn "*subf<mode>3_imm_carry_0"
2109   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2110         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2111    (set (reg:P CA_REGNO)
2112         (eq:P (match_dup 1)
2113               (const_int 0)))]
2114   ""
2115   "subfic %0,%1,0"
2116   [(set_attr "type" "add")])
2118 (define_insn "*subf<mode>3_imm_carry_m1"
2119   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2120         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2121    (set (reg:P CA_REGNO)
2122         (const_int 1))]
2123   ""
2124   "subfic %0,%1,-1"
2125   [(set_attr "type" "add")])
2128 (define_expand "subf<mode>3_carry_in"
2129   [(parallel [
2130      (set (match_operand:GPR 0 "gpc_reg_operand")
2131           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2132                               (reg:GPR CA_REGNO))
2133                     (match_operand:GPR 2 "adde_operand")))
2134      (clobber (reg:GPR CA_REGNO))])]
2135   ""
2137   if (operands[2] == const0_rtx)
2138     {
2139       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2140       DONE;
2141     }
2142   if (operands[2] == constm1_rtx)
2143     {
2144       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2145       DONE;
2146     }
2149 (define_insn "*subf<mode>3_carry_in_internal"
2150   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2151         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2152                             (reg:GPR CA_REGNO))
2153                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2154    (clobber (reg:GPR CA_REGNO))]
2155   ""
2156   "subfe %0,%1,%2"
2157   [(set_attr "type" "add")])
2159 (define_insn "subf<mode>3_carry_in_0"
2160   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2161         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2162                   (reg:GPR CA_REGNO)))
2163    (clobber (reg:GPR CA_REGNO))]
2164   ""
2165   "subfze %0,%1"
2166   [(set_attr "type" "add")])
2168 (define_insn "subf<mode>3_carry_in_m1"
2169   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2171                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2172                   (const_int -2)))
2173    (clobber (reg:GPR CA_REGNO))]
2174   ""
2175   "subfme %0,%1"
2176   [(set_attr "type" "add")])
2178 (define_insn "subf<mode>3_carry_in_xx"
2179   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180         (plus:GPR (reg:GPR CA_REGNO)
2181                   (const_int -1)))
2182    (clobber (reg:GPR CA_REGNO))]
2183   ""
2184   "subfe %0,%0,%0"
2185   [(set_attr "type" "add")])
2188 (define_insn "neg<mode>2"
2189   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2190         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2191   ""
2192   "neg %0,%1"
2193   [(set_attr "type" "add")])
2195 (define_insn_and_split "*neg<mode>2_dot"
2196   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2197         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2198                     (const_int 0)))
2199    (clobber (match_scratch:GPR 0 "=r,r"))]
2200   "<MODE>mode == Pmode"
2201   "@
2202    neg. %0,%1
2203    #"
2204   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2205   [(set (match_dup 0)
2206         (neg:GPR (match_dup 1)))
2207    (set (match_dup 2)
2208         (compare:CC (match_dup 0)
2209                     (const_int 0)))]
2210   ""
2211   [(set_attr "type" "add")
2212    (set_attr "dot" "yes")
2213    (set_attr "length" "4,8")])
2215 (define_insn_and_split "*neg<mode>2_dot2"
2216   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2217         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2218                     (const_int 0)))
2219    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2220         (neg:GPR (match_dup 1)))]
2221   "<MODE>mode == Pmode"
2222   "@
2223    neg. %0,%1
2224    #"
2225   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2226   [(set (match_dup 0)
2227         (neg:GPR (match_dup 1)))
2228    (set (match_dup 2)
2229         (compare:CC (match_dup 0)
2230                     (const_int 0)))]
2231   ""
2232   [(set_attr "type" "add")
2233    (set_attr "dot" "yes")
2234    (set_attr "length" "4,8")])
2237 (define_insn "clz<mode>2"
2238   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2239         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2240   ""
2241   "cntlz<wd> %0,%1"
2242   [(set_attr "type" "cntlz")])
2244 (define_expand "ctz<mode>2"
2245    [(set (match_operand:GPR 0 "gpc_reg_operand")
2246          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2247   ""
2249   if (TARGET_CTZ)
2250     {
2251       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2252       DONE;
2253     }
2255   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2256   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2257   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2259   if (TARGET_POPCNTD)
2260     {
2261       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2262       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2263       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2264       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2265     }
2266   else
2267     {
2268       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2269       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2270       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2271       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2272     }
2274   DONE;
2277 (define_insn "ctz<mode>2_hw"
2278   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2279         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2280   "TARGET_CTZ"
2281   "cnttz<wd> %0,%1"
2282   [(set_attr "type" "cntlz")])
2284 (define_expand "ffs<mode>2"
2285   [(set (match_operand:GPR 0 "gpc_reg_operand")
2286         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2287   ""
2289   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2290   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2291   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2292   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2293   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2294   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2295   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2296   DONE;
2300 (define_expand "popcount<mode>2"
2301   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2302         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2303   "TARGET_POPCNTB || TARGET_POPCNTD"
2305   rs6000_emit_popcount (operands[0], operands[1]);
2306   DONE;
2309 (define_insn "popcntb<mode>2"
2310   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2311         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2312                     UNSPEC_POPCNTB))]
2313   "TARGET_POPCNTB"
2314   "popcntb %0,%1"
2315   [(set_attr "type" "popcnt")])
2317 (define_insn "popcntd<mode>2"
2318   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2319         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2320   "TARGET_POPCNTD"
2321   "popcnt<wd> %0,%1"
2322   [(set_attr "type" "popcnt")])
2325 (define_expand "parity<mode>2"
2326   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2327         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2328   "TARGET_POPCNTB"
2330   rs6000_emit_parity (operands[0], operands[1]);
2331   DONE;
2334 (define_insn "parity<mode>2_cmpb"
2335   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2336         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2337   "TARGET_CMPB && TARGET_POPCNTB"
2338   "prty<wd> %0,%1"
2339   [(set_attr "type" "popcnt")])
2341 (define_insn "cmpb<mode>3"
2342   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2343         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2344                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2345   "TARGET_CMPB"
2346   "cmpb %0,%1,%2"
2347   [(set_attr "type" "cmp")])
2349 ;; Since the hardware zeros the upper part of the register, save generating the
2350 ;; AND immediate if we are converting to unsigned
2351 (define_insn "*bswap<mode>2_extenddi"
2352   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2353         (zero_extend:DI
2354          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2355   "TARGET_POWERPC64"
2356   "l<wd>brx %0,%y1"
2357   [(set_attr "length" "4")
2358    (set_attr "type" "load")])
2360 (define_insn "*bswaphi2_extendsi"
2361   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2362         (zero_extend:SI
2363          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2364   ""
2365   "lhbrx %0,%y1"
2366   [(set_attr "length" "4")
2367    (set_attr "type" "load")])
2369 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2370 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2371 ;; load with byte swap, which can be slower than doing it in the registers.  It
2372 ;; also prevents certain failures with the RELOAD register allocator.
2374 (define_expand "bswap<mode>2"
2375   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2376    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2377   ""
2379   rtx dest = operands[0];
2380   rtx src = operands[1];
2382   if (!REG_P (dest) && !REG_P (src))
2383     src = force_reg (<MODE>mode, src);
2385   if (MEM_P (src))
2386     emit_insn (gen_bswap<mode>2_load (dest, src));
2387   else if (MEM_P (dest))
2388     emit_insn (gen_bswap<mode>2_store (dest, src));
2389   else
2390     emit_insn (gen_bswap<mode>2_reg (dest, src));
2391   DONE;
2394 (define_insn "bswap<mode>2_load"
2395   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2396         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2397   ""
2398   "l<wd>brx %0,%y1"
2399   [(set_attr "type" "load")])
2401 (define_insn "bswap<mode>2_store"
2402   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2403         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2404   ""
2405   "st<wd>brx %1,%y0"
2406   [(set_attr "type" "store")])
2408 (define_insn_and_split "bswaphi2_reg"
2409   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2410         (bswap:HI
2411          (match_operand:HI 1 "gpc_reg_operand" "r")))
2412    (clobber (match_scratch:SI 2 "=&r"))]
2413   ""
2414   "#"
2415   "reload_completed"
2416   [(set (match_dup 3)
2417         (and:SI (lshiftrt:SI (match_dup 4)
2418                              (const_int 8))
2419                 (const_int 255)))
2420    (set (match_dup 2)
2421         (and:SI (ashift:SI (match_dup 4)
2422                            (const_int 8))
2423                 (const_int 65280)))             ;; 0xff00
2424    (set (match_dup 3)
2425         (ior:SI (match_dup 3)
2426                 (match_dup 2)))]
2428   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2429   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2431   [(set_attr "length" "12")
2432    (set_attr "type" "*")])
2434 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2435 ;; zero_extract insns do not change for -mlittle.
2436 (define_insn_and_split "bswapsi2_reg"
2437   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2438         (bswap:SI
2439          (match_operand:SI 1 "gpc_reg_operand" "r")))]
2440   ""
2441   "#"
2442   "reload_completed"
2443   [(set (match_dup 0)                                   ; DABC
2444         (rotate:SI (match_dup 1)
2445                    (const_int 24)))
2446    (set (match_dup 0)                                   ; DCBC
2447         (ior:SI (and:SI (ashift:SI (match_dup 1)
2448                                    (const_int 8))
2449                         (const_int 16711680))
2450                 (and:SI (match_dup 0)
2451                         (const_int -16711681))))
2452    (set (match_dup 0)                                   ; DCBA
2453         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2454                                      (const_int 24))
2455                         (const_int 255))
2456                 (and:SI (match_dup 0)
2457                         (const_int -256))))]
2458   "")
2460 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2461 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2462 ;; complex code.
2464 (define_expand "bswapdi2"
2465   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2466                    (bswap:DI
2467                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2468               (clobber (match_scratch:DI 2 ""))
2469               (clobber (match_scratch:DI 3 ""))])]
2470   ""
2472   rtx dest = operands[0];
2473   rtx src = operands[1];
2475   if (!REG_P (dest) && !REG_P (src))
2476     operands[1] = src = force_reg (DImode, src);
2478   if (TARGET_POWERPC64 && TARGET_LDBRX)
2479     {
2480       if (MEM_P (src))
2481         emit_insn (gen_bswapdi2_load (dest, src));
2482       else if (MEM_P (dest))
2483         emit_insn (gen_bswapdi2_store (dest, src));
2484       else
2485         emit_insn (gen_bswapdi2_reg (dest, src));
2486       DONE;
2487     }
2489   if (!TARGET_POWERPC64)
2490     {
2491       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2492          that uses 64-bit registers needs the same scratch registers as 64-bit
2493          mode.  */
2494       emit_insn (gen_bswapdi2_32bit (dest, src));
2495       DONE;
2496     }
2499 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2500 (define_insn "bswapdi2_load"
2501   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2502         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2503   "TARGET_POWERPC64 && TARGET_LDBRX"
2504   "ldbrx %0,%y1"
2505   [(set_attr "type" "load")])
2507 (define_insn "bswapdi2_store"
2508   [(set (match_operand:DI 0 "memory_operand" "=Z")
2509         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2510   "TARGET_POWERPC64 && TARGET_LDBRX"
2511   "stdbrx %1,%y0"
2512   [(set_attr "type" "store")])
2514 (define_insn "bswapdi2_reg"
2515   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2516         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2517    (clobber (match_scratch:DI 2 "=&r"))
2518    (clobber (match_scratch:DI 3 "=&r"))]
2519   "TARGET_POWERPC64 && TARGET_LDBRX"
2520   "#"
2521   [(set_attr "length" "36")])
2523 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2524 (define_insn "*bswapdi2_64bit"
2525   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2526         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2527    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2528    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2529   "TARGET_POWERPC64 && !TARGET_LDBRX
2530    && (REG_P (operands[0]) || REG_P (operands[1]))
2531    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2532    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2533   "#"
2534   [(set_attr "length" "16,12,36")])
2536 (define_split
2537   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2538         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2539    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2540    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2541   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2542   [(const_int 0)]
2543   "
2545   rtx dest   = operands[0];
2546   rtx src    = operands[1];
2547   rtx op2    = operands[2];
2548   rtx op3    = operands[3];
2549   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2550                                     BYTES_BIG_ENDIAN ? 4 : 0);
2551   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2552                                      BYTES_BIG_ENDIAN ? 4 : 0);
2553   rtx addr1;
2554   rtx addr2;
2555   rtx word1;
2556   rtx word2;
2558   addr1 = XEXP (src, 0);
2559   if (GET_CODE (addr1) == PLUS)
2560     {
2561       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2562       if (TARGET_AVOID_XFORM)
2563         {
2564           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2565           addr2 = op2;
2566         }
2567       else
2568         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2569     }
2570   else if (TARGET_AVOID_XFORM)
2571     {
2572       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2573       addr2 = op2;
2574     }
2575   else
2576     {
2577       emit_move_insn (op2, GEN_INT (4));
2578       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2579     }
2581   word1 = change_address (src, SImode, addr1);
2582   word2 = change_address (src, SImode, addr2);
2584   if (BYTES_BIG_ENDIAN)
2585     {
2586       emit_insn (gen_bswapsi2 (op3_32, word2));
2587       emit_insn (gen_bswapsi2 (dest_32, word1));
2588     }
2589   else
2590     {
2591       emit_insn (gen_bswapsi2 (op3_32, word1));
2592       emit_insn (gen_bswapsi2 (dest_32, word2));
2593     }
2595   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2596   emit_insn (gen_iordi3 (dest, dest, op3));
2597   DONE;
2600 (define_split
2601   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2602         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2603    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2604    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2605   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2606   [(const_int 0)]
2607   "
2609   rtx dest   = operands[0];
2610   rtx src    = operands[1];
2611   rtx op2    = operands[2];
2612   rtx op3    = operands[3];
2613   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2614                                     BYTES_BIG_ENDIAN ? 4 : 0);
2615   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2616                                     BYTES_BIG_ENDIAN ? 4 : 0);
2617   rtx addr1;
2618   rtx addr2;
2619   rtx word1;
2620   rtx word2;
2622   addr1 = XEXP (dest, 0);
2623   if (GET_CODE (addr1) == PLUS)
2624     {
2625       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2626       if (TARGET_AVOID_XFORM)
2627         {
2628           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2629           addr2 = op2;
2630         }
2631       else
2632         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2633     }
2634   else if (TARGET_AVOID_XFORM)
2635     {
2636       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2637       addr2 = op2;
2638     }
2639   else
2640     {
2641       emit_move_insn (op2, GEN_INT (4));
2642       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2643     }
2645   word1 = change_address (dest, SImode, addr1);
2646   word2 = change_address (dest, SImode, addr2);
2648   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2650   if (BYTES_BIG_ENDIAN)
2651     {
2652       emit_insn (gen_bswapsi2 (word1, src_si));
2653       emit_insn (gen_bswapsi2 (word2, op3_si));
2654     }
2655   else
2656     {
2657       emit_insn (gen_bswapsi2 (word2, src_si));
2658       emit_insn (gen_bswapsi2 (word1, op3_si));
2659     }
2660   DONE;
2663 (define_split
2664   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2665         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2666    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2667    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2668   "TARGET_POWERPC64 && reload_completed"
2669   [(const_int 0)]
2670   "
2672   rtx dest    = operands[0];
2673   rtx src     = operands[1];
2674   rtx op2     = operands[2];
2675   rtx op3     = operands[3];
2676   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2677   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2678   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2679   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2680   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2682   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2683   emit_insn (gen_bswapsi2 (dest_si, src_si));
2684   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2685   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2686   emit_insn (gen_iordi3 (dest, dest, op3));
2687   DONE;
2690 (define_insn "bswapdi2_32bit"
2691   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2692         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2693    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2694   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2695   "#"
2696   [(set_attr "length" "16,12,36")])
2698 (define_split
2699   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2700         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2701    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2702   "!TARGET_POWERPC64 && reload_completed"
2703   [(const_int 0)]
2704   "
2706   rtx dest  = operands[0];
2707   rtx src   = operands[1];
2708   rtx op2   = operands[2];
2709   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2710   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2711   rtx addr1;
2712   rtx addr2;
2713   rtx word1;
2714   rtx word2;
2716   addr1 = XEXP (src, 0);
2717   if (GET_CODE (addr1) == PLUS)
2718     {
2719       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2720       if (TARGET_AVOID_XFORM
2721           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2722         {
2723           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2724           addr2 = op2;
2725         }
2726       else
2727         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2728     }
2729   else if (TARGET_AVOID_XFORM
2730            || REGNO (addr1) == REGNO (dest2))
2731     {
2732       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2733       addr2 = op2;
2734     }
2735   else
2736     {
2737       emit_move_insn (op2, GEN_INT (4));
2738       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2739     }
2741   word1 = change_address (src, SImode, addr1);
2742   word2 = change_address (src, SImode, addr2);
2744   emit_insn (gen_bswapsi2 (dest2, word1));
2745   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2746      thus allowing us to omit an early clobber on the output.  */
2747   emit_insn (gen_bswapsi2 (dest1, word2));
2748   DONE;
2751 (define_split
2752   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2753         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2754    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2755   "!TARGET_POWERPC64 && reload_completed"
2756   [(const_int 0)]
2757   "
2759   rtx dest = operands[0];
2760   rtx src  = operands[1];
2761   rtx op2  = operands[2];
2762   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2763   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2764   rtx addr1;
2765   rtx addr2;
2766   rtx word1;
2767   rtx word2;
2769   addr1 = XEXP (dest, 0);
2770   if (GET_CODE (addr1) == PLUS)
2771     {
2772       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2773       if (TARGET_AVOID_XFORM)
2774         {
2775           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2776           addr2 = op2;
2777         }
2778       else
2779         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2780     }
2781   else if (TARGET_AVOID_XFORM)
2782     {
2783       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2784       addr2 = op2;
2785     }
2786   else
2787     {
2788       emit_move_insn (op2, GEN_INT (4));
2789       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2790     }
2792   word1 = change_address (dest, SImode, addr1);
2793   word2 = change_address (dest, SImode, addr2);
2795   emit_insn (gen_bswapsi2 (word2, src1));
2796   emit_insn (gen_bswapsi2 (word1, src2));
2797   DONE;
2800 (define_split
2801   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2802         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2803    (clobber (match_operand:SI 2 "" ""))]
2804   "!TARGET_POWERPC64 && reload_completed"
2805   [(const_int 0)]
2806   "
2808   rtx dest  = operands[0];
2809   rtx src   = operands[1];
2810   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2811   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2812   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2813   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2815   emit_insn (gen_bswapsi2 (dest1, src2));
2816   emit_insn (gen_bswapsi2 (dest2, src1));
2817   DONE;
2821 (define_insn "mul<mode>3"
2822   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2823         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2824                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2825   ""
2826   "@
2827    mull<wd> %0,%1,%2
2828    mulli %0,%1,%2"
2829    [(set_attr "type" "mul")
2830     (set (attr "size")
2831       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2832                 (const_string "8")
2833              (match_operand:GPR 2 "short_cint_operand" "")
2834                 (const_string "16")]
2835         (const_string "<bits>")))])
2837 (define_insn_and_split "*mul<mode>3_dot"
2838   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2839         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2840                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2841                     (const_int 0)))
2842    (clobber (match_scratch:GPR 0 "=r,r"))]
2843   "<MODE>mode == Pmode"
2844   "@
2845    mull<wd>. %0,%1,%2
2846    #"
2847   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2848   [(set (match_dup 0)
2849         (mult:GPR (match_dup 1)
2850                   (match_dup 2)))
2851    (set (match_dup 3)
2852         (compare:CC (match_dup 0)
2853                     (const_int 0)))]
2854   ""
2855   [(set_attr "type" "mul")
2856    (set_attr "size" "<bits>")
2857    (set_attr "dot" "yes")
2858    (set_attr "length" "4,8")])
2860 (define_insn_and_split "*mul<mode>3_dot2"
2861   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2862         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2863                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2864                     (const_int 0)))
2865    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2866         (mult:GPR (match_dup 1)
2867                   (match_dup 2)))]
2868   "<MODE>mode == Pmode"
2869   "@
2870    mull<wd>. %0,%1,%2
2871    #"
2872   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2873   [(set (match_dup 0)
2874         (mult:GPR (match_dup 1)
2875                   (match_dup 2)))
2876    (set (match_dup 3)
2877         (compare:CC (match_dup 0)
2878                     (const_int 0)))]
2879   ""
2880   [(set_attr "type" "mul")
2881    (set_attr "size" "<bits>")
2882    (set_attr "dot" "yes")
2883    (set_attr "length" "4,8")])
2886 (define_expand "<su>mul<mode>3_highpart"
2887   [(set (match_operand:GPR 0 "gpc_reg_operand")
2888         (subreg:GPR
2889           (mult:<DMODE> (any_extend:<DMODE>
2890                           (match_operand:GPR 1 "gpc_reg_operand"))
2891                         (any_extend:<DMODE>
2892                           (match_operand:GPR 2 "gpc_reg_operand")))
2893          0))]
2894   ""
2896   if (<MODE>mode == SImode && TARGET_POWERPC64)
2897     {
2898       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2899                                              operands[2]));
2900       DONE;
2901     }
2903   if (!WORDS_BIG_ENDIAN)
2904     {
2905       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2906                                                  operands[2]));
2907       DONE;
2908     }
2911 (define_insn "*<su>mul<mode>3_highpart"
2912   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2913         (subreg:GPR
2914           (mult:<DMODE> (any_extend:<DMODE>
2915                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2916                         (any_extend:<DMODE>
2917                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2918          0))]
2919   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2920   "mulh<wd><u> %0,%1,%2"
2921   [(set_attr "type" "mul")
2922    (set_attr "size" "<bits>")])
2924 (define_insn "<su>mulsi3_highpart_le"
2925   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2926         (subreg:SI
2927           (mult:DI (any_extend:DI
2928                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2929                    (any_extend:DI
2930                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2931          4))]
2932   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2933   "mulhw<u> %0,%1,%2"
2934   [(set_attr "type" "mul")])
2936 (define_insn "<su>muldi3_highpart_le"
2937   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2938         (subreg:DI
2939           (mult:TI (any_extend:TI
2940                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2941                    (any_extend:TI
2942                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2943          8))]
2944   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2945   "mulhd<u> %0,%1,%2"
2946   [(set_attr "type" "mul")
2947    (set_attr "size" "64")])
2949 (define_insn "<su>mulsi3_highpart_64"
2950   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2951         (truncate:SI
2952           (lshiftrt:DI
2953             (mult:DI (any_extend:DI
2954                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2955                      (any_extend:DI
2956                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2957             (const_int 32))))]
2958   "TARGET_POWERPC64"
2959   "mulhw<u> %0,%1,%2"
2960   [(set_attr "type" "mul")])
2962 (define_expand "<u>mul<mode><dmode>3"
2963   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2964         (mult:<DMODE> (any_extend:<DMODE>
2965                         (match_operand:GPR 1 "gpc_reg_operand"))
2966                       (any_extend:<DMODE>
2967                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2968   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2970   rtx l = gen_reg_rtx (<MODE>mode);
2971   rtx h = gen_reg_rtx (<MODE>mode);
2972   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2973   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2974   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2975   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2976   DONE;
2979 (define_insn "*maddld4"
2980   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2981         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2982                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2983                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2984   "TARGET_MADDLD"
2985   "maddld %0,%1,%2,%3"
2986   [(set_attr "type" "mul")])
2988 (define_insn "udiv<mode>3"
2989   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2990         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2991                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2992   ""
2993   "div<wd>u %0,%1,%2"
2994   [(set_attr "type" "div")
2995    (set_attr "size" "<bits>")])
2998 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2999 ;; modulus.  If it isn't a power of two, force operands into register and do
3000 ;; a normal divide.
3001 (define_expand "div<mode>3"
3002   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3003         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3004                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3005   ""
3007   if (CONST_INT_P (operands[2])
3008       && INTVAL (operands[2]) > 0
3009       && exact_log2 (INTVAL (operands[2])) >= 0)
3010     {
3011       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3012       DONE;
3013     }
3015   operands[2] = force_reg (<MODE>mode, operands[2]);
3018 (define_insn "*div<mode>3"
3019   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3020         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3021                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3022   ""
3023   "div<wd> %0,%1,%2"
3024   [(set_attr "type" "div")
3025    (set_attr "size" "<bits>")])
3027 (define_insn "div<mode>3_sra"
3028   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3029         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3030                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3031    (clobber (reg:GPR CA_REGNO))]
3032   ""
3033   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3034   [(set_attr "type" "two")
3035    (set_attr "length" "8")])
3037 (define_insn_and_split "*div<mode>3_sra_dot"
3038   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3039         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3040                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3041                     (const_int 0)))
3042    (clobber (match_scratch:GPR 0 "=r,r"))
3043    (clobber (reg:GPR CA_REGNO))]
3044   "<MODE>mode == Pmode"
3045   "@
3046    sra<wd>i %0,%1,%p2\;addze. %0,%0
3047    #"
3048   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3049   [(parallel [(set (match_dup 0)
3050                    (div:GPR (match_dup 1)
3051                             (match_dup 2)))
3052               (clobber (reg:GPR CA_REGNO))])
3053    (set (match_dup 3)
3054         (compare:CC (match_dup 0)
3055                     (const_int 0)))]
3056   ""
3057   [(set_attr "type" "two")
3058    (set_attr "length" "8,12")
3059    (set_attr "cell_micro" "not")])
3061 (define_insn_and_split "*div<mode>3_sra_dot2"
3062   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3063         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3064                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3065                     (const_int 0)))
3066    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3067         (div:GPR (match_dup 1)
3068                  (match_dup 2)))
3069    (clobber (reg:GPR CA_REGNO))]
3070   "<MODE>mode == Pmode"
3071   "@
3072    sra<wd>i %0,%1,%p2\;addze. %0,%0
3073    #"
3074   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3075   [(parallel [(set (match_dup 0)
3076                    (div:GPR (match_dup 1)
3077                             (match_dup 2)))
3078               (clobber (reg:GPR CA_REGNO))])
3079    (set (match_dup 3)
3080         (compare:CC (match_dup 0)
3081                     (const_int 0)))]
3082   ""
3083   [(set_attr "type" "two")
3084    (set_attr "length" "8,12")
3085    (set_attr "cell_micro" "not")])
3087 (define_expand "mod<mode>3"
3088   [(set (match_operand:GPR 0 "gpc_reg_operand")
3089         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3090                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3091   ""
3093   int i;
3094   rtx temp1;
3095   rtx temp2;
3097   if (GET_CODE (operands[2]) != CONST_INT
3098       || INTVAL (operands[2]) <= 0
3099       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3100     {
3101       if (!TARGET_MODULO)
3102         FAIL;
3104       operands[2] = force_reg (<MODE>mode, operands[2]);
3105     }
3106   else
3107     {
3108       temp1 = gen_reg_rtx (<MODE>mode);
3109       temp2 = gen_reg_rtx (<MODE>mode);
3111       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3112       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3113       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3114       DONE;
3115     }
3118 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3119 ;; mod, prefer putting the result of mod into a different register
3120 (define_insn "*mod<mode>3"
3121   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3122         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3123                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3124   "TARGET_MODULO"
3125   "mods<wd> %0,%1,%2"
3126   [(set_attr "type" "div")
3127    (set_attr "size" "<bits>")])
3130 (define_insn "umod<mode>3"
3131   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3132         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3133                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3134   "TARGET_MODULO"
3135   "modu<wd> %0,%1,%2"
3136   [(set_attr "type" "div")
3137    (set_attr "size" "<bits>")])
3139 ;; On machines with modulo support, do a combined div/mod the old fashioned
3140 ;; method, since the multiply/subtract is faster than doing the mod instruction
3141 ;; after a divide.
3143 (define_peephole2
3144   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3145         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3146                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3147    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3148         (mod:GPR (match_dup 1)
3149                  (match_dup 2)))]
3150   "TARGET_MODULO
3151    && ! reg_mentioned_p (operands[0], operands[1])
3152    && ! reg_mentioned_p (operands[0], operands[2])
3153    && ! reg_mentioned_p (operands[3], operands[1])
3154    && ! reg_mentioned_p (operands[3], operands[2])"
3155   [(set (match_dup 0)
3156         (div:GPR (match_dup 1)
3157                  (match_dup 2)))
3158    (set (match_dup 3)
3159         (mult:GPR (match_dup 0)
3160                   (match_dup 2)))
3161    (set (match_dup 3)
3162         (minus:GPR (match_dup 1)
3163                    (match_dup 3)))])
3165 (define_peephole2
3166   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3167         (udiv: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         (umod: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         (udiv: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)))])
3188 ;; Logical instructions
3189 ;; The logical instructions are mostly combined by using match_operator,
3190 ;; but the plain AND insns are somewhat different because there is no
3191 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3192 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3194 (define_expand "and<mode>3"
3195   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3196         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3197                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3198   ""
3200   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3201     {
3202       rs6000_split_logical (operands, AND, false, false, false);
3203       DONE;
3204     }
3206   if (CONST_INT_P (operands[2]))
3207     {
3208       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3209         {
3210           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3211           DONE;
3212         }
3214       if (logical_const_operand (operands[2], <MODE>mode))
3215         {
3216           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3217           DONE;
3218         }
3220       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3221         {
3222           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3223           DONE;
3224         }
3226       operands[2] = force_reg (<MODE>mode, operands[2]);
3227     }
3231 (define_insn "and<mode>3_imm"
3232   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3233         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3234                  (match_operand:GPR 2 "logical_const_operand" "n")))
3235    (clobber (match_scratch:CC 3 "=x"))]
3236   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3237   "andi%e2. %0,%1,%u2"
3238   [(set_attr "type" "logical")
3239    (set_attr "dot" "yes")])
3241 (define_insn_and_split "*and<mode>3_imm_dot"
3242   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3243         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3244                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3245                     (const_int 0)))
3246    (clobber (match_scratch:GPR 0 "=r,r"))
3247    (clobber (match_scratch:CC 4 "=X,x"))]
3248   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3249    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3250   "@
3251    andi%e2. %0,%1,%u2
3252    #"
3253   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3254   [(parallel [(set (match_dup 0)
3255                    (and:GPR (match_dup 1)
3256                             (match_dup 2)))
3257               (clobber (match_dup 4))])
3258    (set (match_dup 3)
3259         (compare:CC (match_dup 0)
3260                     (const_int 0)))]
3261   ""
3262   [(set_attr "type" "logical")
3263    (set_attr "dot" "yes")
3264    (set_attr "length" "4,8")])
3266 (define_insn_and_split "*and<mode>3_imm_dot2"
3267   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3268         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3269                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3270                     (const_int 0)))
3271    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3272         (and:GPR (match_dup 1)
3273                  (match_dup 2)))
3274    (clobber (match_scratch:CC 4 "=X,x"))]
3275   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3276    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3277   "@
3278    andi%e2. %0,%1,%u2
3279    #"
3280   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3281   [(parallel [(set (match_dup 0)
3282                    (and:GPR (match_dup 1)
3283                             (match_dup 2)))
3284               (clobber (match_dup 4))])
3285    (set (match_dup 3)
3286         (compare:CC (match_dup 0)
3287                     (const_int 0)))]
3288   ""
3289   [(set_attr "type" "logical")
3290    (set_attr "dot" "yes")
3291    (set_attr "length" "4,8")])
3293 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3294   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3295         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3296                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3297                     (const_int 0)))
3298    (clobber (match_scratch:GPR 0 "=r,r"))]
3299   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3300    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3301   "@
3302    andi%e2. %0,%1,%u2
3303    #"
3304   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3305   [(set (match_dup 0)
3306         (and:GPR (match_dup 1)
3307                  (match_dup 2)))
3308    (set (match_dup 3)
3309         (compare:CC (match_dup 0)
3310                     (const_int 0)))]
3311   ""
3312   [(set_attr "type" "logical")
3313    (set_attr "dot" "yes")
3314    (set_attr "length" "4,8")])
3316 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3317   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3318         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3319                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3320                     (const_int 0)))
3321    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3322         (and:GPR (match_dup 1)
3323                  (match_dup 2)))]
3324   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3325    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3326   "@
3327    andi%e2. %0,%1,%u2
3328    #"
3329   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3330   [(set (match_dup 0)
3331         (and:GPR (match_dup 1)
3332                  (match_dup 2)))
3333    (set (match_dup 3)
3334         (compare:CC (match_dup 0)
3335                     (const_int 0)))]
3336   ""
3337   [(set_attr "type" "logical")
3338    (set_attr "dot" "yes")
3339    (set_attr "length" "4,8")])
3341 (define_insn "*and<mode>3_imm_dot_shifted"
3342   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3343         (compare:CC
3344           (and:GPR
3345             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3346                           (match_operand:SI 4 "const_int_operand" "n"))
3347             (match_operand:GPR 2 "const_int_operand" "n"))
3348           (const_int 0)))
3349    (clobber (match_scratch:GPR 0 "=r"))]
3350   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3351                                    << INTVAL (operands[4])),
3352                           DImode)
3353    && (<MODE>mode == Pmode
3354        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3356   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3357   return "andi%e2. %0,%1,%u2";
3359   [(set_attr "type" "logical")
3360    (set_attr "dot" "yes")])
3363 (define_insn "and<mode>3_mask"
3364   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3365         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3366                  (match_operand:GPR 2 "const_int_operand" "n")))]
3367   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3369   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3371   [(set_attr "type" "shift")])
3373 (define_insn_and_split "*and<mode>3_mask_dot"
3374   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3375         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3376                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3377                     (const_int 0)))
3378    (clobber (match_scratch:GPR 0 "=r,r"))]
3379   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3380    && !logical_const_operand (operands[2], <MODE>mode)
3381    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3383   if (which_alternative == 0)
3384     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3385   else
3386     return "#";
3388   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3389   [(set (match_dup 0)
3390         (and:GPR (match_dup 1)
3391                  (match_dup 2)))
3392    (set (match_dup 3)
3393         (compare:CC (match_dup 0)
3394                     (const_int 0)))]
3395   ""
3396   [(set_attr "type" "shift")
3397    (set_attr "dot" "yes")
3398    (set_attr "length" "4,8")])
3400 (define_insn_and_split "*and<mode>3_mask_dot2"
3401   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3402         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3403                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3404                     (const_int 0)))
3405    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3406         (and:GPR (match_dup 1)
3407                  (match_dup 2)))]
3408   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3409    && !logical_const_operand (operands[2], <MODE>mode)
3410    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3412   if (which_alternative == 0)
3413     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3414   else
3415     return "#";
3417   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3418   [(set (match_dup 0)
3419         (and:GPR (match_dup 1)
3420                  (match_dup 2)))
3421    (set (match_dup 3)
3422         (compare:CC (match_dup 0)
3423                     (const_int 0)))]
3424   ""
3425   [(set_attr "type" "shift")
3426    (set_attr "dot" "yes")
3427    (set_attr "length" "4,8")])
3430 (define_insn_and_split "*and<mode>3_2insn"
3431   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3432         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3433                  (match_operand:GPR 2 "const_int_operand" "n")))]
3434   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3435    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3436         || logical_const_operand (operands[2], <MODE>mode))"
3437   "#"
3438   "&& 1"
3439   [(pc)]
3441   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3442   DONE;
3444   [(set_attr "type" "shift")
3445    (set_attr "length" "8")])
3447 (define_insn_and_split "*and<mode>3_2insn_dot"
3448   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3449         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3450                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3451                     (const_int 0)))
3452    (clobber (match_scratch:GPR 0 "=r,r"))]
3453   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3454    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3455    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3456         || logical_const_operand (operands[2], <MODE>mode))"
3457   "#"
3458   "&& reload_completed"
3459   [(pc)]
3461   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3462   DONE;
3464   [(set_attr "type" "shift")
3465    (set_attr "dot" "yes")
3466    (set_attr "length" "8,12")])
3468 (define_insn_and_split "*and<mode>3_2insn_dot2"
3469   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3470         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3471                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3472                     (const_int 0)))
3473    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3474         (and:GPR (match_dup 1)
3475                  (match_dup 2)))]
3476   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3477    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3478    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3479         || logical_const_operand (operands[2], <MODE>mode))"
3480   "#"
3481   "&& reload_completed"
3482   [(pc)]
3484   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3485   DONE;
3487   [(set_attr "type" "shift")
3488    (set_attr "dot" "yes")
3489    (set_attr "length" "8,12")])
3492 (define_expand "<code><mode>3"
3493   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3494         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3495                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3496   ""
3498   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3499     {
3500       rs6000_split_logical (operands, <CODE>, false, false, false);
3501       DONE;
3502     }
3504   if (non_logical_cint_operand (operands[2], <MODE>mode))
3505     {
3506       rtx tmp = ((!can_create_pseudo_p ()
3507                   || rtx_equal_p (operands[0], operands[1]))
3508                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3510       HOST_WIDE_INT value = INTVAL (operands[2]);
3511       HOST_WIDE_INT lo = value & 0xffff;
3512       HOST_WIDE_INT hi = value - lo;
3514       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3515       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3516       DONE;
3517     }
3519   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3520     operands[2] = force_reg (<MODE>mode, operands[2]);
3523 (define_split
3524   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3525         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3526                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3527   ""
3528   [(set (match_dup 3)
3529         (iorxor:GPR (match_dup 1)
3530                     (match_dup 4)))
3531    (set (match_dup 0)
3532         (iorxor:GPR (match_dup 3)
3533                     (match_dup 5)))]
3535   operands[3] = ((!can_create_pseudo_p ()
3536                   || rtx_equal_p (operands[0], operands[1]))
3537                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3539   HOST_WIDE_INT value = INTVAL (operands[2]);
3540   HOST_WIDE_INT lo = value & 0xffff;
3541   HOST_WIDE_INT hi = value - lo;
3543   operands[4] = GEN_INT (hi);
3544   operands[5] = GEN_INT (lo);
3547 (define_insn "*bool<mode>3_imm"
3548   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3549         (match_operator:GPR 3 "boolean_or_operator"
3550          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3551           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3552   ""
3553   "%q3i%e2 %0,%1,%u2"
3554   [(set_attr "type" "logical")])
3556 (define_insn "*bool<mode>3"
3557   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3558         (match_operator:GPR 3 "boolean_operator"
3559          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3560           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3561   ""
3562   "%q3 %0,%1,%2"
3563   [(set_attr "type" "logical")])
3565 (define_insn_and_split "*bool<mode>3_dot"
3566   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3567         (compare:CC (match_operator:GPR 3 "boolean_operator"
3568          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3569           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3570          (const_int 0)))
3571    (clobber (match_scratch:GPR 0 "=r,r"))]
3572   "<MODE>mode == Pmode"
3573   "@
3574    %q3. %0,%1,%2
3575    #"
3576   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3577   [(set (match_dup 0)
3578         (match_dup 3))
3579    (set (match_dup 4)
3580         (compare:CC (match_dup 0)
3581                     (const_int 0)))]
3582   ""
3583   [(set_attr "type" "logical")
3584    (set_attr "dot" "yes")
3585    (set_attr "length" "4,8")])
3587 (define_insn_and_split "*bool<mode>3_dot2"
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    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3594         (match_dup 3))]
3595   "<MODE>mode == Pmode"
3596   "@
3597    %q3. %0,%1,%2
3598    #"
3599   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3600   [(set (match_dup 0)
3601         (match_dup 3))
3602    (set (match_dup 4)
3603         (compare:CC (match_dup 0)
3604                     (const_int 0)))]
3605   ""
3606   [(set_attr "type" "logical")
3607    (set_attr "dot" "yes")
3608    (set_attr "length" "4,8")])
3611 (define_insn "*boolc<mode>3"
3612   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3613         (match_operator:GPR 3 "boolean_operator"
3614          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3615           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3616   ""
3617   "%q3 %0,%1,%2"
3618   [(set_attr "type" "logical")])
3620 (define_insn_and_split "*boolc<mode>3_dot"
3621   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3622         (compare:CC (match_operator:GPR 3 "boolean_operator"
3623          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3624           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3625          (const_int 0)))
3626    (clobber (match_scratch:GPR 0 "=r,r"))]
3627   "<MODE>mode == Pmode"
3628   "@
3629    %q3. %0,%1,%2
3630    #"
3631   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3632   [(set (match_dup 0)
3633         (match_dup 3))
3634    (set (match_dup 4)
3635         (compare:CC (match_dup 0)
3636                     (const_int 0)))]
3637   ""
3638   [(set_attr "type" "logical")
3639    (set_attr "dot" "yes")
3640    (set_attr "length" "4,8")])
3642 (define_insn_and_split "*boolc<mode>3_dot2"
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    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3649         (match_dup 3))]
3650   "<MODE>mode == Pmode"
3651   "@
3652    %q3. %0,%1,%2
3653    #"
3654   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3655   [(set (match_dup 0)
3656         (match_dup 3))
3657    (set (match_dup 4)
3658         (compare:CC (match_dup 0)
3659                     (const_int 0)))]
3660   ""
3661   [(set_attr "type" "logical")
3662    (set_attr "dot" "yes")
3663    (set_attr "length" "4,8")])
3666 (define_insn "*boolcc<mode>3"
3667   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3668         (match_operator:GPR 3 "boolean_operator"
3669          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3670           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3671   ""
3672   "%q3 %0,%1,%2"
3673   [(set_attr "type" "logical")])
3675 (define_insn_and_split "*boolcc<mode>3_dot"
3676   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3677         (compare:CC (match_operator:GPR 3 "boolean_operator"
3678          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3679           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3680          (const_int 0)))
3681    (clobber (match_scratch:GPR 0 "=r,r"))]
3682   "<MODE>mode == Pmode"
3683   "@
3684    %q3. %0,%1,%2
3685    #"
3686   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3687   [(set (match_dup 0)
3688         (match_dup 3))
3689    (set (match_dup 4)
3690         (compare:CC (match_dup 0)
3691                     (const_int 0)))]
3692   ""
3693   [(set_attr "type" "logical")
3694    (set_attr "dot" "yes")
3695    (set_attr "length" "4,8")])
3697 (define_insn_and_split "*boolcc<mode>3_dot2"
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    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3704         (match_dup 3))]
3705   "<MODE>mode == Pmode"
3706   "@
3707    %q3. %0,%1,%2
3708    #"
3709   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3710   [(set (match_dup 0)
3711         (match_dup 3))
3712    (set (match_dup 4)
3713         (compare:CC (match_dup 0)
3714                     (const_int 0)))]
3715   ""
3716   [(set_attr "type" "logical")
3717    (set_attr "dot" "yes")
3718    (set_attr "length" "4,8")])
3721 ;; TODO: Should have dots of this as well.
3722 (define_insn "*eqv<mode>3"
3723   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3724         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3725                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3726   ""
3727   "eqv %0,%1,%2"
3728   [(set_attr "type" "logical")])
3730 ;; Rotate-and-mask and insert.
3732 (define_insn "*rotl<mode>3_mask"
3733   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3734         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3735                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3736                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3737                  (match_operand:GPR 3 "const_int_operand" "n")))]
3738   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3740   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3742   [(set_attr "type" "shift")
3743    (set_attr "maybe_var_shift" "yes")])
3745 (define_insn_and_split "*rotl<mode>3_mask_dot"
3746   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3747         (compare:CC
3748           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3749                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3750                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3751                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3752           (const_int 0)))
3753    (clobber (match_scratch:GPR 0 "=r,r"))]
3754   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3755    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3757   if (which_alternative == 0)
3758     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3759   else
3760     return "#";
3762   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3763   [(set (match_dup 0)
3764         (and:GPR (match_dup 4)
3765                  (match_dup 3)))
3766    (set (match_dup 5)
3767         (compare:CC (match_dup 0)
3768                     (const_int 0)))]
3769   ""
3770   [(set_attr "type" "shift")
3771    (set_attr "maybe_var_shift" "yes")
3772    (set_attr "dot" "yes")
3773    (set_attr "length" "4,8")])
3775 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3776   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3777         (compare:CC
3778           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3779                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3780                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3781                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3782           (const_int 0)))
3783    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3784         (and:GPR (match_dup 4)
3785                  (match_dup 3)))]
3786   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3787    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3789   if (which_alternative == 0)
3790     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3791   else
3792     return "#";
3794   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3795   [(set (match_dup 0)
3796         (and:GPR (match_dup 4)
3797                  (match_dup 3)))
3798    (set (match_dup 5)
3799         (compare:CC (match_dup 0)
3800                     (const_int 0)))]
3801   ""
3802   [(set_attr "type" "shift")
3803    (set_attr "maybe_var_shift" "yes")
3804    (set_attr "dot" "yes")
3805    (set_attr "length" "4,8")])
3807 ; Special case for less-than-0.  We can do it with just one machine
3808 ; instruction, but the generic optimizers do not realise it is cheap.
3809 (define_insn "*lt0_disi"
3810   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3811         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3812                (const_int 0)))]
3813   "TARGET_POWERPC64"
3814   "rlwinm %0,%1,1,31,31"
3815   [(set_attr "type" "shift")])
3819 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3820 ; both are an AND so are the same precedence).
3821 (define_insn "*rotl<mode>3_insert"
3822   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3823         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3824                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3825                             (match_operand:SI 2 "const_int_operand" "n")])
3826                           (match_operand:GPR 3 "const_int_operand" "n"))
3827                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3828                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3829   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3830    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3832   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3834   [(set_attr "type" "insert")])
3835 ; FIXME: this needs an attr "size", so that the scheduler can see the
3836 ; difference between rlwimi and rldimi.  We also might want dot forms,
3837 ; but not for rlwimi on POWER4 and similar processors.
3839 (define_insn "*rotl<mode>3_insert_2"
3840   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3841         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3842                           (match_operand:GPR 6 "const_int_operand" "n"))
3843                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3844                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3845                             (match_operand:SI 2 "const_int_operand" "n")])
3846                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3847   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3848    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3850   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3852   [(set_attr "type" "insert")])
3854 ; There are also some forms without one of the ANDs.
3855 (define_insn "*rotl<mode>3_insert_3"
3856   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3857         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3858                           (match_operand:GPR 4 "const_int_operand" "n"))
3859                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3860                              (match_operand:SI 2 "const_int_operand" "n"))))]
3861   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3863   if (<MODE>mode == SImode)
3864     return "rlwimi %0,%1,%h2,0,31-%h2";
3865   else
3866     return "rldimi %0,%1,%H2,0";
3868   [(set_attr "type" "insert")])
3870 (define_insn "*rotl<mode>3_insert_4"
3871   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3872         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3873                           (match_operand:GPR 4 "const_int_operand" "n"))
3874                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3875                                (match_operand:SI 2 "const_int_operand" "n"))))]
3876   "<MODE>mode == SImode &&
3877    GET_MODE_PRECISION (<MODE>mode)
3878    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3880   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3881                          - INTVAL (operands[2]));
3882   if (<MODE>mode == SImode)
3883     return "rlwimi %0,%1,%h2,32-%h2,31";
3884   else
3885     return "rldimi %0,%1,%H2,64-%H2";
3887   [(set_attr "type" "insert")])
3889 (define_insn "*rotlsi3_insert_5"
3890   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3891         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3892                         (match_operand:SI 2 "const_int_operand" "n,n"))
3893                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3894                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3895   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3896    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3897    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3898   "@
3899    rlwimi %0,%3,0,%4
3900    rlwimi %0,%1,0,%2"
3901   [(set_attr "type" "insert")])
3903 (define_insn "*rotldi3_insert_6"
3904   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3905         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3906                         (match_operand:DI 2 "const_int_operand" "n"))
3907                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3908                         (match_operand:DI 4 "const_int_operand" "n"))))]
3909   "exact_log2 (-UINTVAL (operands[2])) > 0
3910    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3912   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3913   return "rldimi %0,%3,0,%5";
3915   [(set_attr "type" "insert")
3916    (set_attr "size" "64")])
3918 (define_insn "*rotldi3_insert_7"
3919   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3920         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3921                         (match_operand:DI 4 "const_int_operand" "n"))
3922                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3923                         (match_operand:DI 2 "const_int_operand" "n"))))]
3924   "exact_log2 (-UINTVAL (operands[2])) > 0
3925    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3927   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3928   return "rldimi %0,%3,0,%5";
3930   [(set_attr "type" "insert")
3931    (set_attr "size" "64")])
3934 ; This handles the important case of multiple-precision shifts.  There is
3935 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3936 (define_split
3937   [(set (match_operand:GPR 0 "gpc_reg_operand")
3938         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3939                              (match_operand:SI 3 "const_int_operand"))
3940                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3941                                (match_operand:SI 4 "const_int_operand"))))]
3942   "can_create_pseudo_p ()
3943    && INTVAL (operands[3]) + INTVAL (operands[4])
3944       >= GET_MODE_PRECISION (<MODE>mode)"
3945   [(set (match_dup 5)
3946         (lshiftrt:GPR (match_dup 2)
3947                       (match_dup 4)))
3948    (set (match_dup 0)
3949         (ior:GPR (and:GPR (match_dup 5)
3950                           (match_dup 6))
3951                  (ashift:GPR (match_dup 1)
3952                              (match_dup 3))))]
3954   unsigned HOST_WIDE_INT mask = 1;
3955   mask = (mask << INTVAL (operands[3])) - 1;
3956   operands[5] = gen_reg_rtx (<MODE>mode);
3957   operands[6] = GEN_INT (mask);
3960 (define_split
3961   [(set (match_operand:GPR 0 "gpc_reg_operand")
3962         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3963                                (match_operand:SI 4 "const_int_operand"))
3964                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3965                              (match_operand:SI 3 "const_int_operand"))))]
3966   "can_create_pseudo_p ()
3967    && INTVAL (operands[3]) + INTVAL (operands[4])
3968       >= GET_MODE_PRECISION (<MODE>mode)"
3969   [(set (match_dup 5)
3970         (lshiftrt:GPR (match_dup 2)
3971                       (match_dup 4)))
3972    (set (match_dup 0)
3973         (ior:GPR (and:GPR (match_dup 5)
3974                           (match_dup 6))
3975                  (ashift:GPR (match_dup 1)
3976                              (match_dup 3))))]
3978   unsigned HOST_WIDE_INT mask = 1;
3979   mask = (mask << INTVAL (operands[3])) - 1;
3980   operands[5] = gen_reg_rtx (<MODE>mode);
3981   operands[6] = GEN_INT (mask);
3985 ; Another important case is setting some bits to 1; we can do that with
3986 ; an insert instruction, in many cases.
3987 (define_insn_and_split "*ior<mode>_mask"
3988   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3989         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3990                  (match_operand:GPR 2 "const_int_operand" "n")))
3991    (clobber (match_scratch:GPR 3 "=r"))]
3992   "!logical_const_operand (operands[2], <MODE>mode)
3993    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3994   "#"
3995   "&& 1"
3996   [(set (match_dup 3)
3997         (const_int -1))
3998    (set (match_dup 0)
3999         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4000                                       (match_dup 4))
4001                           (match_dup 2))
4002                  (and:GPR (match_dup 1)
4003                           (match_dup 5))))]
4005   int nb, ne;
4006   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4007   if (GET_CODE (operands[3]) == SCRATCH)
4008     operands[3] = gen_reg_rtx (<MODE>mode);
4009   operands[4] = GEN_INT (ne);
4010   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4012   [(set_attr "type" "two")
4013    (set_attr "length" "8")])
4016 ;; Now the simple shifts.
4018 (define_insn "rotl<mode>3"
4019   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4020         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4021                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4022   ""
4023   "rotl<wd>%I2 %0,%1,%<hH>2"
4024   [(set_attr "type" "shift")
4025    (set_attr "maybe_var_shift" "yes")])
4027 (define_insn "*rotlsi3_64"
4028   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4029         (zero_extend:DI
4030             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4031                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4032   "TARGET_POWERPC64"
4033   "rotlw%I2 %0,%1,%h2"
4034   [(set_attr "type" "shift")
4035    (set_attr "maybe_var_shift" "yes")])
4037 (define_insn_and_split "*rotl<mode>3_dot"
4038   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4039         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4040                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4041                     (const_int 0)))
4042    (clobber (match_scratch:GPR 0 "=r,r"))]
4043   "<MODE>mode == Pmode"
4044   "@
4045    rotl<wd>%I2. %0,%1,%<hH>2
4046    #"
4047   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4048   [(set (match_dup 0)
4049         (rotate:GPR (match_dup 1)
4050                     (match_dup 2)))
4051    (set (match_dup 3)
4052         (compare:CC (match_dup 0)
4053                     (const_int 0)))]
4054   ""
4055   [(set_attr "type" "shift")
4056    (set_attr "maybe_var_shift" "yes")
4057    (set_attr "dot" "yes")
4058    (set_attr "length" "4,8")])
4060 (define_insn_and_split "*rotl<mode>3_dot2"
4061   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4062         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4063                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4064                     (const_int 0)))
4065    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4066         (rotate:GPR (match_dup 1)
4067                     (match_dup 2)))]
4068   "<MODE>mode == Pmode"
4069   "@
4070    rotl<wd>%I2. %0,%1,%<hH>2
4071    #"
4072   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4073   [(set (match_dup 0)
4074         (rotate:GPR (match_dup 1)
4075                     (match_dup 2)))
4076    (set (match_dup 3)
4077         (compare:CC (match_dup 0)
4078                     (const_int 0)))]
4079   ""
4080   [(set_attr "type" "shift")
4081    (set_attr "maybe_var_shift" "yes")
4082    (set_attr "dot" "yes")
4083    (set_attr "length" "4,8")])
4086 (define_insn "ashl<mode>3"
4087   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4088         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4089                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4090   ""
4091   "sl<wd>%I2 %0,%1,%<hH>2"
4092   [(set_attr "type" "shift")
4093    (set_attr "maybe_var_shift" "yes")])
4095 (define_insn "*ashlsi3_64"
4096   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4097         (zero_extend:DI
4098             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4099                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4100   "TARGET_POWERPC64"
4101   "slw%I2 %0,%1,%h2"
4102   [(set_attr "type" "shift")
4103    (set_attr "maybe_var_shift" "yes")])
4105 (define_insn_and_split "*ashl<mode>3_dot"
4106   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4107         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4108                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4109                     (const_int 0)))
4110    (clobber (match_scratch:GPR 0 "=r,r"))]
4111   "<MODE>mode == Pmode"
4112   "@
4113    sl<wd>%I2. %0,%1,%<hH>2
4114    #"
4115   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4116   [(set (match_dup 0)
4117         (ashift:GPR (match_dup 1)
4118                     (match_dup 2)))
4119    (set (match_dup 3)
4120         (compare:CC (match_dup 0)
4121                     (const_int 0)))]
4122   ""
4123   [(set_attr "type" "shift")
4124    (set_attr "maybe_var_shift" "yes")
4125    (set_attr "dot" "yes")
4126    (set_attr "length" "4,8")])
4128 (define_insn_and_split "*ashl<mode>3_dot2"
4129   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4130         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4131                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4132                     (const_int 0)))
4133    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4134         (ashift:GPR (match_dup 1)
4135                     (match_dup 2)))]
4136   "<MODE>mode == Pmode"
4137   "@
4138    sl<wd>%I2. %0,%1,%<hH>2
4139    #"
4140   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4141   [(set (match_dup 0)
4142         (ashift:GPR (match_dup 1)
4143                     (match_dup 2)))
4144    (set (match_dup 3)
4145         (compare:CC (match_dup 0)
4146                     (const_int 0)))]
4147   ""
4148   [(set_attr "type" "shift")
4149    (set_attr "maybe_var_shift" "yes")
4150    (set_attr "dot" "yes")
4151    (set_attr "length" "4,8")])
4153 ;; Pretend we have a memory form of extswsli until register allocation is done
4154 ;; so that we use LWZ to load the value from memory, instead of LWA.
4155 (define_insn_and_split "ashdi3_extswsli"
4156   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4157         (ashift:DI
4158          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4159          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4160   "TARGET_EXTSWSLI"
4161   "@
4162    extswsli %0,%1,%2
4163    #"
4164   "&& reload_completed && MEM_P (operands[1])"
4165   [(set (match_dup 3)
4166         (match_dup 1))
4167    (set (match_dup 0)
4168         (ashift:DI (sign_extend:DI (match_dup 3))
4169                    (match_dup 2)))]
4171   operands[3] = gen_lowpart (SImode, operands[0]);
4173   [(set_attr "type" "shift")
4174    (set_attr "maybe_var_shift" "no")])
4177 (define_insn_and_split "ashdi3_extswsli_dot"
4178   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4179         (compare:CC
4180          (ashift:DI
4181           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4182           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4183          (const_int 0)))
4184    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4185   "TARGET_EXTSWSLI"
4186   "@
4187    extswsli. %0,%1,%2
4188    #
4189    #
4190    #"
4191   "&& reload_completed
4192    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4193        || memory_operand (operands[1], SImode))"
4194   [(pc)]
4196   rtx dest = operands[0];
4197   rtx src = operands[1];
4198   rtx shift = operands[2];
4199   rtx cr = operands[3];
4200   rtx src2;
4202   if (!MEM_P (src))
4203     src2 = src;
4204   else
4205     {
4206       src2 = gen_lowpart (SImode, dest);
4207       emit_move_insn (src2, src);
4208     }
4210   if (REGNO (cr) == CR0_REGNO)
4211     {
4212       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4213       DONE;
4214     }
4216   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4217   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4218   DONE;
4220   [(set_attr "type" "shift")
4221    (set_attr "maybe_var_shift" "no")
4222    (set_attr "dot" "yes")
4223    (set_attr "length" "4,8,8,12")])
4225 (define_insn_and_split "ashdi3_extswsli_dot2"
4226   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4227         (compare:CC
4228          (ashift:DI
4229           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4230           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4231          (const_int 0)))
4232    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4233         (ashift:DI (sign_extend:DI (match_dup 1))
4234                    (match_dup 2)))]
4235   "TARGET_EXTSWSLI"
4236   "@
4237    extswsli. %0,%1,%2
4238    #
4239    #
4240    #"
4241   "&& reload_completed
4242    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4243        || memory_operand (operands[1], SImode))"
4244   [(pc)]
4246   rtx dest = operands[0];
4247   rtx src = operands[1];
4248   rtx shift = operands[2];
4249   rtx cr = operands[3];
4250   rtx src2;
4252   if (!MEM_P (src))
4253     src2 = src;
4254   else
4255     {
4256       src2 = gen_lowpart (SImode, dest);
4257       emit_move_insn (src2, src);
4258     }
4260   if (REGNO (cr) == CR0_REGNO)
4261     {
4262       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4263       DONE;
4264     }
4266   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4267   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4268   DONE;
4270   [(set_attr "type" "shift")
4271    (set_attr "maybe_var_shift" "no")
4272    (set_attr "dot" "yes")
4273    (set_attr "length" "4,8,8,12")])
4275 (define_insn "lshr<mode>3"
4276   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4277         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4278                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4279   ""
4280   "sr<wd>%I2 %0,%1,%<hH>2"
4281   [(set_attr "type" "shift")
4282    (set_attr "maybe_var_shift" "yes")])
4284 (define_insn "*lshrsi3_64"
4285   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4286         (zero_extend:DI
4287             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4288                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4289   "TARGET_POWERPC64"
4290   "srw%I2 %0,%1,%h2"
4291   [(set_attr "type" "shift")
4292    (set_attr "maybe_var_shift" "yes")])
4294 (define_insn_and_split "*lshr<mode>3_dot"
4295   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4296         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4297                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4298                     (const_int 0)))
4299    (clobber (match_scratch:GPR 0 "=r,r"))]
4300   "<MODE>mode == Pmode"
4301   "@
4302    sr<wd>%I2. %0,%1,%<hH>2
4303    #"
4304   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4305   [(set (match_dup 0)
4306         (lshiftrt:GPR (match_dup 1)
4307                       (match_dup 2)))
4308    (set (match_dup 3)
4309         (compare:CC (match_dup 0)
4310                     (const_int 0)))]
4311   ""
4312   [(set_attr "type" "shift")
4313    (set_attr "maybe_var_shift" "yes")
4314    (set_attr "dot" "yes")
4315    (set_attr "length" "4,8")])
4317 (define_insn_and_split "*lshr<mode>3_dot2"
4318   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4319         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4320                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4321                     (const_int 0)))
4322    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4323         (lshiftrt:GPR (match_dup 1)
4324                       (match_dup 2)))]
4325   "<MODE>mode == Pmode"
4326   "@
4327    sr<wd>%I2. %0,%1,%<hH>2
4328    #"
4329   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4330   [(set (match_dup 0)
4331         (lshiftrt:GPR (match_dup 1)
4332                       (match_dup 2)))
4333    (set (match_dup 3)
4334         (compare:CC (match_dup 0)
4335                     (const_int 0)))]
4336   ""
4337   [(set_attr "type" "shift")
4338    (set_attr "maybe_var_shift" "yes")
4339    (set_attr "dot" "yes")
4340    (set_attr "length" "4,8")])
4343 (define_insn "ashr<mode>3"
4344   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4345         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4346                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4347    (clobber (reg:GPR CA_REGNO))]
4348   ""
4349   "sra<wd>%I2 %0,%1,%<hH>2"
4350   [(set_attr "type" "shift")
4351    (set_attr "maybe_var_shift" "yes")])
4353 (define_insn "*ashrsi3_64"
4354   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4355         (sign_extend:DI
4356             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4357                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4358    (clobber (reg:SI CA_REGNO))]
4359   "TARGET_POWERPC64"
4360   "sraw%I2 %0,%1,%h2"
4361   [(set_attr "type" "shift")
4362    (set_attr "maybe_var_shift" "yes")])
4364 (define_insn_and_split "*ashr<mode>3_dot"
4365   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4366         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4367                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4368                     (const_int 0)))
4369    (clobber (match_scratch:GPR 0 "=r,r"))
4370    (clobber (reg:GPR CA_REGNO))]
4371   "<MODE>mode == Pmode"
4372   "@
4373    sra<wd>%I2. %0,%1,%<hH>2
4374    #"
4375   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4376   [(parallel [(set (match_dup 0)
4377                    (ashiftrt:GPR (match_dup 1)
4378                                  (match_dup 2)))
4379               (clobber (reg:GPR CA_REGNO))])
4380    (set (match_dup 3)
4381         (compare:CC (match_dup 0)
4382                     (const_int 0)))]
4383   ""
4384   [(set_attr "type" "shift")
4385    (set_attr "maybe_var_shift" "yes")
4386    (set_attr "dot" "yes")
4387    (set_attr "length" "4,8")])
4389 (define_insn_and_split "*ashr<mode>3_dot2"
4390   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4391         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4392                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4393                     (const_int 0)))
4394    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4395         (ashiftrt:GPR (match_dup 1)
4396                       (match_dup 2)))
4397    (clobber (reg:GPR CA_REGNO))]
4398   "<MODE>mode == Pmode"
4399   "@
4400    sra<wd>%I2. %0,%1,%<hH>2
4401    #"
4402   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4403   [(parallel [(set (match_dup 0)
4404                    (ashiftrt:GPR (match_dup 1)
4405                                  (match_dup 2)))
4406               (clobber (reg:GPR CA_REGNO))])
4407    (set (match_dup 3)
4408         (compare:CC (match_dup 0)
4409                     (const_int 0)))]
4410   ""
4411   [(set_attr "type" "shift")
4412    (set_attr "maybe_var_shift" "yes")
4413    (set_attr "dot" "yes")
4414    (set_attr "length" "4,8")])
4416 ;; Builtins to replace a division to generate FRE reciprocal estimate
4417 ;; instructions and the necessary fixup instructions
4418 (define_expand "recip<mode>3"
4419   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4420    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4421    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4422   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4424    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4425    DONE;
4428 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4429 ;; hardware division.  This is only done before register allocation and with
4430 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4431 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4432 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4433 (define_split
4434   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4435         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4436                     (match_operand 2 "gpc_reg_operand" "")))]
4437   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4438    && can_create_pseudo_p () && flag_finite_math_only
4439    && !flag_trapping_math && flag_reciprocal_math"
4440   [(const_int 0)]
4442   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4443   DONE;
4446 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4447 ;; appropriate fixup.
4448 (define_expand "rsqrt<mode>2"
4449   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4450    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4451   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4453   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4454   DONE;
4457 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4458 ;; modes here, and also add in conditional vsx/power8-vector support to access
4459 ;; values in the traditional Altivec registers if the appropriate
4460 ;; -mupper-regs-{df,sf} option is enabled.
4462 (define_expand "abs<mode>2"
4463   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4464         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4465   "TARGET_<MODE>_INSN"
4466   "")
4468 (define_insn "*abs<mode>2_fpr"
4469   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4470         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4471   "TARGET_<MODE>_FPR"
4472   "@
4473    fabs %0,%1
4474    xsabsdp %x0,%x1"
4475   [(set_attr "type" "fpsimple")
4476    (set_attr "fp_type" "fp_addsub_<Fs>")])
4478 (define_insn "*nabs<mode>2_fpr"
4479   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4480         (neg:SFDF
4481          (abs:SFDF
4482           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4483   "TARGET_<MODE>_FPR"
4484   "@
4485    fnabs %0,%1
4486    xsnabsdp %x0,%x1"
4487   [(set_attr "type" "fpsimple")
4488    (set_attr "fp_type" "fp_addsub_<Fs>")])
4490 (define_expand "neg<mode>2"
4491   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4492         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4493   "TARGET_<MODE>_INSN"
4494   "")
4496 (define_insn "*neg<mode>2_fpr"
4497   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4498         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4499   "TARGET_<MODE>_FPR"
4500   "@
4501    fneg %0,%1
4502    xsnegdp %x0,%x1"
4503   [(set_attr "type" "fpsimple")
4504    (set_attr "fp_type" "fp_addsub_<Fs>")])
4506 (define_expand "add<mode>3"
4507   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4508         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4509                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4510   "TARGET_<MODE>_INSN"
4511   "")
4513 (define_insn "*add<mode>3_fpr"
4514   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4515         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4516                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4517   "TARGET_<MODE>_FPR"
4518   "@
4519    fadd<Ftrad> %0,%1,%2
4520    xsadd<Fvsx> %x0,%x1,%x2"
4521   [(set_attr "type" "fp")
4522    (set_attr "fp_type" "fp_addsub_<Fs>")])
4524 (define_expand "sub<mode>3"
4525   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4526         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4527                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4528   "TARGET_<MODE>_INSN"
4529   "")
4531 (define_insn "*sub<mode>3_fpr"
4532   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4533         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4534                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4535   "TARGET_<MODE>_FPR"
4536   "@
4537    fsub<Ftrad> %0,%1,%2
4538    xssub<Fvsx> %x0,%x1,%x2"
4539   [(set_attr "type" "fp")
4540    (set_attr "fp_type" "fp_addsub_<Fs>")])
4542 (define_expand "mul<mode>3"
4543   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4544         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4545                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4546   "TARGET_<MODE>_INSN"
4547   "")
4549 (define_insn "*mul<mode>3_fpr"
4550   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4551         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4552                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4553   "TARGET_<MODE>_FPR"
4554   "@
4555    fmul<Ftrad> %0,%1,%2
4556    xsmul<Fvsx> %x0,%x1,%x2"
4557   [(set_attr "type" "dmul")
4558    (set_attr "fp_type" "fp_mul_<Fs>")])
4560 (define_expand "div<mode>3"
4561   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4562         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4563                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4564   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4566   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4567       && can_create_pseudo_p () && flag_finite_math_only
4568       && !flag_trapping_math && flag_reciprocal_math)
4569     {
4570       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4571       DONE;
4572     }
4575 (define_insn "*div<mode>3_fpr"
4576   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4577         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4578                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4579   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4580   "@
4581    fdiv<Ftrad> %0,%1,%2
4582    xsdiv<Fvsx> %x0,%x1,%x2"
4583   [(set_attr "type" "<Fs>div")
4584    (set_attr "fp_type" "fp_div_<Fs>")])
4586 (define_insn "*sqrt<mode>2_internal"
4587   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4588         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4589   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4590    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4591   "@
4592    fsqrt<Ftrad> %0,%1
4593    xssqrt<Fvsx> %x0,%x1"
4594   [(set_attr "type" "<Fs>sqrt")
4595    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4597 (define_expand "sqrt<mode>2"
4598   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4599         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4600   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4601    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4603   if (<MODE>mode == SFmode
4604       && TARGET_RECIP_PRECISION
4605       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4606       && !optimize_function_for_size_p (cfun)
4607       && flag_finite_math_only && !flag_trapping_math
4608       && flag_unsafe_math_optimizations)
4609     {
4610       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4611       DONE;
4612     }
4615 ;; Floating point reciprocal approximation
4616 (define_insn "fre<Fs>"
4617   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4618         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4619                      UNSPEC_FRES))]
4620   "TARGET_<FFRE>"
4621   "@
4622    fre<Ftrad> %0,%1
4623    xsre<Fvsx> %x0,%x1"
4624   [(set_attr "type" "fp")])
4626 (define_insn "*rsqrt<mode>2"
4627   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4628         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4629                      UNSPEC_RSQRT))]
4630   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4631   "@
4632    frsqrte<Ftrad> %0,%1
4633    xsrsqrte<Fvsx> %x0,%x1"
4634   [(set_attr "type" "fp")])
4636 ;; Floating point comparisons
4637 (define_insn "*cmp<mode>_fpr"
4638   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4639         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4640                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4641   "TARGET_<MODE>_FPR"
4642   "@
4643    fcmpu %0,%1,%2
4644    xscmpudp %0,%x1,%x2"
4645   [(set_attr "type" "fpcompare")])
4647 ;; Floating point conversions
4648 (define_expand "extendsfdf2"
4649   [(set (match_operand:DF 0 "gpc_reg_operand")
4650         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4651   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4653   if (HONOR_SNANS (SFmode))
4654     operands[1] = force_reg (SFmode, operands[1]);
4657 (define_insn_and_split "*extendsfdf2_fpr"
4658   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4659         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4660   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4661   "@
4662    #
4663    fmr %0,%1
4664    lfs%U1%X1 %0,%1
4665    #
4666    xscpsgndp %x0,%x1,%x1
4667    lxsspx %x0,%y1
4668    lxssp %0,%1"
4669   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4670   [(const_int 0)]
4672   emit_note (NOTE_INSN_DELETED);
4673   DONE;
4675   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4677 (define_insn "*extendsfdf2_snan"
4678   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4679         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4680   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4681   "@
4682    frsp %0,%1
4683    xsrsp %x0,%x1"
4684   [(set_attr "type" "fp")])
4686 (define_expand "truncdfsf2"
4687   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4688         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4689   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4690   "")
4692 (define_insn "*truncdfsf2_fpr"
4693   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4694         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4695   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4696   "@
4697    frsp %0,%1
4698    xsrsp %x0,%x1"
4699   [(set_attr "type" "fp")])
4701 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4702 ;; builtins.c and optabs.c that are not correct for IBM long double
4703 ;; when little-endian.
4704 (define_expand "signbit<mode>2"
4705   [(set (match_dup 2)
4706         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4707    (set (match_dup 3)
4708         (subreg:DI (match_dup 2) 0))
4709    (set (match_dup 4)
4710         (match_dup 5))
4711    (set (match_operand:SI 0 "gpc_reg_operand" "")
4712         (match_dup 6))]
4713   "TARGET_HARD_FLOAT
4714    && (!FLOAT128_IEEE_P (<MODE>mode)
4715        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4717   if (FLOAT128_IEEE_P (<MODE>mode))
4718     {
4719       if (<MODE>mode == KFmode)
4720         emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4721       else if (<MODE>mode == TFmode)
4722         emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4723       else
4724         gcc_unreachable ();
4725       DONE;
4726     }
4727   operands[2] = gen_reg_rtx (DFmode);
4728   operands[3] = gen_reg_rtx (DImode);
4729   if (TARGET_POWERPC64)
4730     {
4731       operands[4] = gen_reg_rtx (DImode);
4732       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4733       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4734                                     WORDS_BIG_ENDIAN ? 4 : 0);
4735     }
4736   else
4737     {
4738       operands[4] = gen_reg_rtx (SImode);
4739       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4740                                     WORDS_BIG_ENDIAN ? 0 : 4);
4741       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4742     }
4745 (define_expand "copysign<mode>3"
4746   [(set (match_dup 3)
4747         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4748    (set (match_dup 4)
4749         (neg:SFDF (abs:SFDF (match_dup 1))))
4750    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4751         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4752                                (match_dup 5))
4753                          (match_dup 3)
4754                          (match_dup 4)))]
4755   "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4756    && ((TARGET_PPC_GFXOPT
4757         && !HONOR_NANS (<MODE>mode)
4758         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4759        || TARGET_CMPB
4760        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4762   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4763     {
4764       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4765                                              operands[2]));
4766       DONE;
4767     }
4769    operands[3] = gen_reg_rtx (<MODE>mode);
4770    operands[4] = gen_reg_rtx (<MODE>mode);
4771    operands[5] = CONST0_RTX (<MODE>mode);
4772   })
4774 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4775 ;; and load.
4776 (define_insn_and_split "signbit<mode>2_dm"
4777   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4778         (unspec:SI
4779          [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4780          UNSPEC_SIGNBIT))]
4781   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4782   "#"
4783   "&& reload_completed"
4784   [(const_int 0)]
4786   rs6000_split_signbit (operands[0], operands[1]);
4787   DONE;
4789  [(set_attr "length" "8,8,4")
4790   (set_attr "type" "mftgpr,load,integer")])
4792 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4793   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4794         (any_extend:DI
4795          (unspec:SI
4796           [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4797           UNSPEC_SIGNBIT)))]
4798   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4799   "#"
4800   "&& reload_completed"
4801   [(const_int 0)]
4803   rs6000_split_signbit (operands[0], operands[1]);
4804   DONE;
4806  [(set_attr "length" "8,8,4")
4807   (set_attr "type" "mftgpr,load,integer")])
4809 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4810 ;; point types, which makes normal SUBREG's problematical. Instead use a
4811 ;; special pattern to avoid using a normal movdi.
4812 (define_insn "signbit<mode>2_dm2"
4813   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4814         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4815                     (const_int 0)]
4816                    UNSPEC_SIGNBIT))]
4817   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4818   "mfvsrd %0,%x1"
4819  [(set_attr "type" "mftgpr")])
4822 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4823 ;; compiler from optimizing -0.0
4824 (define_insn "copysign<mode>3_fcpsgn"
4825   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4826         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4827                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4828                      UNSPEC_COPYSIGN))]
4829   "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4830   "@
4831    fcpsgn %0,%2,%1
4832    xscpsgndp %x0,%x2,%x1"
4833   [(set_attr "type" "fpsimple")])
4835 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4836 ;; fsel instruction and some auxiliary computations.  Then we just have a
4837 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4838 ;; combine.
4839 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4840 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4841 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4842 ;; define_splits to make them if made by combine.  On VSX machines we have the
4843 ;; min/max instructions.
4845 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4846 ;; to allow either DF/SF to use only traditional registers.
4848 (define_expand "s<minmax><mode>3"
4849   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4850         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4851                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4852   "TARGET_MINMAX_<MODE>"
4854   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4855   DONE;
4858 (define_insn "*s<minmax><mode>3_vsx"
4859   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4860         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4861                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4862   "TARGET_VSX && TARGET_<MODE>_FPR"
4864   return (TARGET_P9_MINMAX
4865           ? "xs<minmax>cdp %x0,%x1,%x2"
4866           : "xs<minmax>dp %x0,%x1,%x2");
4868   [(set_attr "type" "fp")])
4870 ;; The conditional move instructions allow us to perform max and min operations
4871 ;; even when we don't have the appropriate max/min instruction using the FSEL
4872 ;; instruction.
4874 (define_insn_and_split "*s<minmax><mode>3_fpr"
4875   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4876         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4877                         (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4878   "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4879   "#"
4880   "&& 1"
4881   [(const_int 0)]
4883   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4884   DONE;
4887 (define_expand "mov<mode>cc"
4888    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4889          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4890                            (match_operand:GPR 2 "gpc_reg_operand" "")
4891                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4892   "TARGET_ISEL<sel>"
4893   "
4895   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4896     DONE;
4897   else
4898     FAIL;
4901 ;; We use the BASE_REGS for the isel input operands because, if rA is
4902 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4903 ;; because we may switch the operands and rB may end up being rA.
4905 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4906 ;; leave out the mode in operand 4 and use one pattern, but reload can
4907 ;; change the mode underneath our feet and then gets confused trying
4908 ;; to reload the value.
4909 (define_insn "isel_signed_<mode>"
4910   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4911         (if_then_else:GPR
4912          (match_operator 1 "scc_comparison_operator"
4913                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4914                           (const_int 0)])
4915          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4916          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4917   "TARGET_ISEL<sel>"
4918   "*
4919 { return output_isel (operands); }"
4920   [(set_attr "type" "isel")
4921    (set_attr "length" "4")])
4923 (define_insn "isel_unsigned_<mode>"
4924   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4925         (if_then_else:GPR
4926          (match_operator 1 "scc_comparison_operator"
4927                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4928                           (const_int 0)])
4929          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4930          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4931   "TARGET_ISEL<sel>"
4932   "*
4933 { return output_isel (operands); }"
4934   [(set_attr "type" "isel")
4935    (set_attr "length" "4")])
4937 ;; These patterns can be useful for combine; they let combine know that
4938 ;; isel can handle reversed comparisons so long as the operands are
4939 ;; registers.
4941 (define_insn "*isel_reversed_signed_<mode>"
4942   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4943         (if_then_else:GPR
4944          (match_operator 1 "scc_rev_comparison_operator"
4945                          [(match_operand:CC 4 "cc_reg_operand" "y")
4946                           (const_int 0)])
4947          (match_operand:GPR 2 "gpc_reg_operand" "b")
4948          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4949   "TARGET_ISEL<sel>"
4950   "*
4951 { return output_isel (operands); }"
4952   [(set_attr "type" "isel")
4953    (set_attr "length" "4")])
4955 (define_insn "*isel_reversed_unsigned_<mode>"
4956   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4957         (if_then_else:GPR
4958          (match_operator 1 "scc_rev_comparison_operator"
4959                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4960                           (const_int 0)])
4961          (match_operand:GPR 2 "gpc_reg_operand" "b")
4962          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4963   "TARGET_ISEL<sel>"
4964   "*
4965 { return output_isel (operands); }"
4966   [(set_attr "type" "isel")
4967    (set_attr "length" "4")])
4969 ;; Floating point conditional move
4970 (define_expand "mov<mode>cc"
4971    [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4972          (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4973                             (match_operand:SFDF 2 "gpc_reg_operand" "")
4974                             (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4975   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4976   "
4978   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4979     DONE;
4980   else
4981     FAIL;
4984 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4985   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
4986         (if_then_else:SFDF
4987          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
4988              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4989          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
4990          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
4991   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4992   "fsel %0,%1,%2,%3"
4993   [(set_attr "type" "fp")])
4995 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4996   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4997         (if_then_else:SFDF
4998          (match_operator:CCFP 1 "fpmask_comparison_operator"
4999                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5000                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5001          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5002          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5003    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5004   "TARGET_P9_MINMAX"
5005   "#"
5006   ""
5007   [(set (match_dup 6)
5008         (if_then_else:V2DI (match_dup 1)
5009                            (match_dup 7)
5010                            (match_dup 8)))
5011    (set (match_dup 0)
5012         (if_then_else:SFDF (ne (match_dup 6)
5013                                (match_dup 8))
5014                            (match_dup 4)
5015                            (match_dup 5)))]
5017   if (GET_CODE (operands[6]) == SCRATCH)
5018     operands[6] = gen_reg_rtx (V2DImode);
5020   operands[7] = CONSTM1_RTX (V2DImode);
5021   operands[8] = CONST0_RTX (V2DImode);
5023  [(set_attr "length" "8")
5024   (set_attr "type" "vecperm")])
5026 ;; Handle inverting the fpmask comparisons.
5027 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5028   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5029         (if_then_else:SFDF
5030          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5031                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5032                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5033          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5034          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5035    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5036   "TARGET_P9_MINMAX"
5037   "#"
5038   "&& 1"
5039   [(set (match_dup 6)
5040         (if_then_else:V2DI (match_dup 9)
5041                            (match_dup 7)
5042                            (match_dup 8)))
5043    (set (match_dup 0)
5044         (if_then_else:SFDF (ne (match_dup 6)
5045                                (match_dup 8))
5046                            (match_dup 5)
5047                            (match_dup 4)))]
5049   rtx op1 = operands[1];
5050   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5052   if (GET_CODE (operands[6]) == SCRATCH)
5053     operands[6] = gen_reg_rtx (V2DImode);
5055   operands[7] = CONSTM1_RTX (V2DImode);
5056   operands[8] = CONST0_RTX (V2DImode);
5058   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5060  [(set_attr "length" "8")
5061   (set_attr "type" "vecperm")])
5063 (define_insn "*fpmask<mode>"
5064   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5065         (if_then_else:V2DI
5066          (match_operator:CCFP 1 "fpmask_comparison_operator"
5067                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5068                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5069          (match_operand:V2DI 4 "all_ones_constant" "")
5070          (match_operand:V2DI 5 "zero_constant" "")))]
5071   "TARGET_P9_MINMAX"
5072   "xscmp%V1dp %x0,%x2,%x3"
5073   [(set_attr "type" "fpcompare")])
5075 (define_insn "*xxsel<mode>"
5076   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5077         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5078                                (match_operand:V2DI 2 "zero_constant" ""))
5079                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5080                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5081   "TARGET_P9_MINMAX"
5082   "xxsel %x0,%x4,%x3,%x1"
5083   [(set_attr "type" "vecmove")])
5086 ;; Conversions to and from floating-point.
5088 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5089 ; don't want to support putting SImode in FPR registers.
5090 (define_insn "lfiwax"
5091   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5092         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5093                    UNSPEC_LFIWAX))]
5094   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5095   "@
5096    lfiwax %0,%y1
5097    lxsiwax %x0,%y1
5098    mtvsrwa %x0,%1
5099    vextsw2d %0,%1"
5100   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5102 ; This split must be run before register allocation because it allocates the
5103 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5104 ; it earlier to allow for the combiner to merge insns together where it might
5105 ; not be needed and also in case the insns are deleted as dead code.
5107 (define_insn_and_split "floatsi<mode>2_lfiwax"
5108   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5109         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5110    (clobber (match_scratch:DI 2 "=wi"))]
5111   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5112    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5113   "#"
5114   ""
5115   [(pc)]
5116   "
5118   rtx dest = operands[0];
5119   rtx src = operands[1];
5120   rtx tmp;
5122   if (!MEM_P (src) && TARGET_POWERPC64
5123       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5124     tmp = convert_to_mode (DImode, src, false);
5125   else
5126     {
5127       tmp = operands[2];
5128       if (GET_CODE (tmp) == SCRATCH)
5129         tmp = gen_reg_rtx (DImode);
5130       if (MEM_P (src))
5131         {
5132           src = rs6000_address_for_fpconvert (src);
5133           emit_insn (gen_lfiwax (tmp, src));
5134         }
5135       else
5136         {
5137           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5138           emit_move_insn (stack, src);
5139           emit_insn (gen_lfiwax (tmp, stack));
5140         }
5141     }
5142   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5143   DONE;
5145   [(set_attr "length" "12")
5146    (set_attr "type" "fpload")])
5148 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5149   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5150         (float:SFDF
5151          (sign_extend:DI
5152           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5153    (clobber (match_scratch:DI 2 "=wi"))]
5154   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5155   "#"
5156   ""
5157   [(pc)]
5158   "
5160   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5161   if (GET_CODE (operands[2]) == SCRATCH)
5162     operands[2] = gen_reg_rtx (DImode);
5163   if (TARGET_P8_VECTOR)
5164     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5165   else
5166     emit_insn (gen_lfiwax (operands[2], operands[1]));
5167   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5168   DONE;
5170   [(set_attr "length" "8")
5171    (set_attr "type" "fpload")])
5173 (define_insn "lfiwzx"
5174   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5175         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5176                    UNSPEC_LFIWZX))]
5177   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5178   "@
5179    lfiwzx %0,%y1
5180    lxsiwzx %x0,%y1
5181    mtvsrwz %x0,%1
5182    xxextractuw %x0,%x1,4"
5183   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5185 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5186   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5187         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5188    (clobber (match_scratch:DI 2 "=wi"))]
5189   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5190   "#"
5191   ""
5192   [(pc)]
5193   "
5195   rtx dest = operands[0];
5196   rtx src = operands[1];
5197   rtx tmp;
5199   if (!MEM_P (src) && TARGET_POWERPC64
5200       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5201     tmp = convert_to_mode (DImode, src, true);
5202   else
5203     {
5204       tmp = operands[2];
5205       if (GET_CODE (tmp) == SCRATCH)
5206         tmp = gen_reg_rtx (DImode);
5207       if (MEM_P (src))
5208         {
5209           src = rs6000_address_for_fpconvert (src);
5210           emit_insn (gen_lfiwzx (tmp, src));
5211         }
5212       else
5213         {
5214           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5215           emit_move_insn (stack, src);
5216           emit_insn (gen_lfiwzx (tmp, stack));
5217         }
5218     }
5219   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5220   DONE;
5222   [(set_attr "length" "12")
5223    (set_attr "type" "fpload")])
5225 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5226   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5227         (unsigned_float:SFDF
5228          (zero_extend:DI
5229           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5230    (clobber (match_scratch:DI 2 "=wi"))]
5231   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5232   "#"
5233   ""
5234   [(pc)]
5235   "
5237   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5238   if (GET_CODE (operands[2]) == SCRATCH)
5239     operands[2] = gen_reg_rtx (DImode);
5240   if (TARGET_P8_VECTOR)
5241     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5242   else
5243     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5244   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5245   DONE;
5247   [(set_attr "length" "8")
5248    (set_attr "type" "fpload")])
5250 ; For each of these conversions, there is a define_expand, a define_insn
5251 ; with a '#' template, and a define_split (with C code).  The idea is
5252 ; to allow constant folding with the template of the define_insn,
5253 ; then to have the insns split later (between sched1 and final).
5255 (define_expand "floatsidf2"
5256   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5257                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5258               (use (match_dup 2))
5259               (use (match_dup 3))
5260               (clobber (match_dup 4))
5261               (clobber (match_dup 5))
5262               (clobber (match_dup 6))])]
5263   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5264   "
5266   if (TARGET_LFIWAX && TARGET_FCFID)
5267     {
5268       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5269       DONE;
5270     }
5271   else if (TARGET_FCFID)
5272     {
5273       rtx dreg = operands[1];
5274       if (!REG_P (dreg))
5275         dreg = force_reg (SImode, dreg);
5276       dreg = convert_to_mode (DImode, dreg, false);
5277       emit_insn (gen_floatdidf2 (operands[0], dreg));
5278       DONE;
5279     }
5281   if (!REG_P (operands[1]))
5282     operands[1] = force_reg (SImode, operands[1]);
5283   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5284   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5285   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5286   operands[5] = gen_reg_rtx (DFmode);
5287   operands[6] = gen_reg_rtx (SImode);
5290 (define_insn_and_split "*floatsidf2_internal"
5291   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5292         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5293    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5294    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5295    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5296    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5297    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5298   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5299   "#"
5300   ""
5301   [(pc)]
5302   "
5304   rtx lowword, highword;
5305   gcc_assert (MEM_P (operands[4]));
5306   highword = adjust_address (operands[4], SImode, 0);
5307   lowword = adjust_address (operands[4], SImode, 4);
5308   if (! WORDS_BIG_ENDIAN)
5309     std::swap (lowword, highword);
5311   emit_insn (gen_xorsi3 (operands[6], operands[1],
5312                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5313   emit_move_insn (lowword, operands[6]);
5314   emit_move_insn (highword, operands[2]);
5315   emit_move_insn (operands[5], operands[4]);
5316   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5317   DONE;
5319   [(set_attr "length" "24")
5320    (set_attr "type" "fp")])
5322 ;; If we don't have a direct conversion to single precision, don't enable this
5323 ;; conversion for 32-bit without fast math, because we don't have the insn to
5324 ;; generate the fixup swizzle to avoid double rounding problems.
5325 (define_expand "floatunssisf2"
5326   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5327         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5328   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5329    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5330        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5331            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5332   "
5334   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5335     {
5336       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5337       DONE;
5338     }
5339   else
5340     {
5341       rtx dreg = operands[1];
5342       if (!REG_P (dreg))
5343         dreg = force_reg (SImode, dreg);
5344       dreg = convert_to_mode (DImode, dreg, true);
5345       emit_insn (gen_floatdisf2 (operands[0], dreg));
5346       DONE;
5347     }
5350 (define_expand "floatunssidf2"
5351   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5352                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5353               (use (match_dup 2))
5354               (use (match_dup 3))
5355               (clobber (match_dup 4))
5356               (clobber (match_dup 5))])]
5357   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5358   "
5360   if (TARGET_LFIWZX && TARGET_FCFID)
5361     {
5362       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5363       DONE;
5364     }
5365   else if (TARGET_FCFID)
5366     {
5367       rtx dreg = operands[1];
5368       if (!REG_P (dreg))
5369         dreg = force_reg (SImode, dreg);
5370       dreg = convert_to_mode (DImode, dreg, true);
5371       emit_insn (gen_floatdidf2 (operands[0], dreg));
5372       DONE;
5373     }
5375   if (!REG_P (operands[1]))
5376     operands[1] = force_reg (SImode, operands[1]);
5377   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5378   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5379   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5380   operands[5] = gen_reg_rtx (DFmode);
5383 (define_insn_and_split "*floatunssidf2_internal"
5384   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5385         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5386    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5387    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5388    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5389    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5390   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5391    && !(TARGET_FCFID && TARGET_POWERPC64)"
5392   "#"
5393   ""
5394   [(pc)]
5395   "
5397   rtx lowword, highword;
5398   gcc_assert (MEM_P (operands[4]));
5399   highword = adjust_address (operands[4], SImode, 0);
5400   lowword = adjust_address (operands[4], SImode, 4);
5401   if (! WORDS_BIG_ENDIAN)
5402     std::swap (lowword, highword);
5404   emit_move_insn (lowword, operands[1]);
5405   emit_move_insn (highword, operands[2]);
5406   emit_move_insn (operands[5], operands[4]);
5407   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5408   DONE;
5410   [(set_attr "length" "20")
5411    (set_attr "type" "fp")])
5413 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5414 ;; vector registers.  These insns favor doing the sign/zero extension in
5415 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5416 ;; extension and then a direct move.
5418 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5419   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5420                    (float:FP_ISA3
5421                     (match_operand:QHI 1 "input_operand")))
5422               (clobber (match_scratch:DI 2))
5423               (clobber (match_scratch:DI 3))
5424               (clobber (match_scratch:<QHI:MODE> 4))])]
5425   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5427   if (MEM_P (operands[1]))
5428     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5431 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5432   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5433         (float:FP_ISA3
5434          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5435    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5436    (clobber (match_scratch:DI 3 "=X,r,X"))
5437    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5438   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5439   "#"
5440   "&& reload_completed"
5441   [(const_int 0)]
5443   rtx result = operands[0];
5444   rtx input = operands[1];
5445   rtx di = operands[2];
5447   if (!MEM_P (input))
5448     {
5449       rtx tmp = operands[3];
5450       if (altivec_register_operand (input, <QHI:MODE>mode))
5451         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5452       else if (GET_CODE (tmp) == SCRATCH)
5453         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5454       else
5455         {
5456           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5457           emit_move_insn (di, tmp);
5458         }
5459     }
5460   else
5461     {
5462       rtx tmp = operands[4];
5463       emit_move_insn (tmp, input);
5464       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5465     }
5467   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5468   DONE;
5471 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5472   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5473                    (unsigned_float:FP_ISA3
5474                     (match_operand:QHI 1 "input_operand" "")))
5475               (clobber (match_scratch:DI 2 ""))
5476               (clobber (match_scratch:DI 3 ""))])]
5477   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5479   if (MEM_P (operands[1]))
5480     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5483 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5484   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5485         (unsigned_float:FP_ISA3
5486          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5487    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5488    (clobber (match_scratch:DI 3 "=X,r,X"))]
5489   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5490   "#"
5491   "&& reload_completed"
5492   [(const_int 0)]
5494   rtx result = operands[0];
5495   rtx input = operands[1];
5496   rtx di = operands[2];
5498   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5499     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5500   else
5501     {
5502       rtx tmp = operands[3];
5503       if (GET_CODE (tmp) == SCRATCH)
5504         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5505       else
5506         {
5507           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5508           emit_move_insn (di, tmp);
5509         }
5510     }
5512   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5513   DONE;
5516 (define_expand "fix_trunc<mode>si2"
5517   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5518         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5519   "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5520   "
5522   if (!TARGET_P8_VECTOR)
5523     {
5524       rtx src = force_reg (<MODE>mode, operands[1]);
5526       if (TARGET_STFIWX)
5527         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5528       else
5529         {
5530           rtx tmp = gen_reg_rtx (DImode);
5531           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5532           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5533                                                       tmp, stack));
5534         }
5535       DONE;
5536     }
5539 ; Like the convert to float patterns, this insn must be split before
5540 ; register allocation so that it can allocate the memory slot if it
5541 ; needed
5542 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5543   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5544         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5545    (clobber (match_scratch:DI 2 "=d"))]
5546   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5547    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5548    && TARGET_STFIWX && can_create_pseudo_p ()
5549    && !TARGET_P8_VECTOR"
5550   "#"
5551   ""
5552   [(pc)]
5554   rtx dest = operands[0];
5555   rtx src = operands[1];
5556   rtx tmp = operands[2];
5558   if (GET_CODE (tmp) == SCRATCH)
5559     tmp = gen_reg_rtx (DImode);
5561   emit_insn (gen_fctiwz_<mode> (tmp, src));
5562   if (MEM_P (dest))
5563     {
5564       dest = rs6000_address_for_fpconvert (dest);
5565       emit_insn (gen_stfiwx (dest, tmp));
5566       DONE;
5567     }
5568   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5569     {
5570       dest = gen_lowpart (DImode, dest);
5571       emit_move_insn (dest, tmp);
5572       DONE;
5573     }
5574   else
5575     {
5576       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5577       emit_insn (gen_stfiwx (stack, tmp));
5578       emit_move_insn (dest, stack);
5579       DONE;
5580     }
5582   [(set_attr "length" "12")
5583    (set_attr "type" "fp")])
5585 (define_insn_and_split "fix_trunc<mode>si2_internal"
5586   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5587         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5588    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5589    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5590   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5591   "#"
5592   ""
5593   [(pc)]
5594   "
5596   rtx lowword;
5597   gcc_assert (MEM_P (operands[3]));
5598   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5600   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5601   emit_move_insn (operands[3], operands[2]);
5602   emit_move_insn (operands[0], lowword);
5603   DONE;
5605   [(set_attr "length" "16")
5606    (set_attr "type" "fp")])
5608 (define_expand "fix_trunc<mode>di2"
5609   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5610         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5611   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5612   "")
5614 (define_insn "*fix_trunc<mode>di2_fctidz"
5615   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5616         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5617   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5618   "@
5619    fctidz %0,%1
5620    xscvdpsxds %x0,%x1"
5621   [(set_attr "type" "fp")])
5623 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5624   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5625                    (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5626               (clobber (match_scratch:DI 2))])]
5627   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5629   if (MEM_P (operands[0]))
5630     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5633 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5634   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5635         (fix:QHI
5636          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5637    (clobber (match_scratch:DI 2 "=X,wi"))]
5638   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5639   "#"
5640   "&& reload_completed"
5641   [(const_int 0)]
5643   rtx dest = operands[0];
5644   rtx src = operands[1];
5646   if (vsx_register_operand (dest, <QHI:MODE>mode))
5647     {
5648       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5649       emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5650     }
5651   else
5652     {
5653       rtx tmp = operands[2];
5654       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5656       emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5657       emit_move_insn (dest, tmp2);
5658     }
5659   DONE;
5662 (define_expand "fixuns_trunc<mode>si2"
5663   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5664         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5665   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5666   "
5668   if (!TARGET_P8_VECTOR)
5669     {
5670       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5671       DONE;
5672     }
5675 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5676   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5677         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5678    (clobber (match_scratch:DI 2 "=d"))]
5679   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5680    && TARGET_STFIWX && can_create_pseudo_p ()
5681    && !TARGET_P8_VECTOR"
5682   "#"
5683   ""
5684   [(pc)]
5686   rtx dest = operands[0];
5687   rtx src = operands[1];
5688   rtx tmp = operands[2];
5690   if (GET_CODE (tmp) == SCRATCH)
5691     tmp = gen_reg_rtx (DImode);
5693   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5694   if (MEM_P (dest))
5695     {
5696       dest = rs6000_address_for_fpconvert (dest);
5697       emit_insn (gen_stfiwx (dest, tmp));
5698       DONE;
5699     }
5700   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5701     {
5702       dest = gen_lowpart (DImode, dest);
5703       emit_move_insn (dest, tmp);
5704       DONE;
5705     }
5706   else
5707     {
5708       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5709       emit_insn (gen_stfiwx (stack, tmp));
5710       emit_move_insn (dest, stack);
5711       DONE;
5712     }
5714   [(set_attr "length" "12")
5715    (set_attr "type" "fp")])
5717 (define_insn "fixuns_trunc<mode>di2"
5718   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5719         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5720   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5721   "@
5722    fctiduz %0,%1
5723    xscvdpuxds %x0,%x1"
5724   [(set_attr "type" "fp")])
5726 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5727   [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5728                    (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5729               (clobber (match_scratch:DI 2))])]
5730   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5732   if (MEM_P (operands[0]))
5733     operands[0] = rs6000_address_for_fpconvert (operands[0]);
5736 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5737   [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5738         (unsigned_fix:QHI
5739          (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5740    (clobber (match_scratch:DI 2 "=X,wi"))]
5741   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5742   "#"
5743   "&& reload_completed"
5744   [(const_int 0)]
5746   rtx dest = operands[0];
5747   rtx src = operands[1];
5749   if (vsx_register_operand (dest, <QHI:MODE>mode))
5750     {
5751       rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5752       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5753     }
5754   else
5755     {
5756       rtx tmp = operands[2];
5757       rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5759       emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5760       emit_move_insn (dest, tmp2);
5761     }
5762   DONE;
5765 ;; If -mvsx-small-integer, we can represent the FIX operation directly.  On
5766 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5767 ;; to another location, since SImode is not allowed in vector registers.
5768 (define_insn "*fctiw<u>z_<mode>_smallint"
5769   [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5770         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5771   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5772   "@
5773    fctiw<u>z %0,%1
5774    xscvdp<su>xws %x0,%x1"
5775   [(set_attr "type" "fp")])
5777 ;; Combiner pattern to prevent moving the result of converting a floating point
5778 ;; value to 32-bit integer to GPR in order to save it.
5779 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5780   [(set (match_operand:SI 0 "memory_operand" "=Z")
5781         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5782    (clobber (match_scratch:SI 2 "=wa"))]
5783   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5784   "#"
5785   "&& reload_completed"
5786   [(set (match_dup 2)
5787         (any_fix:SI (match_dup 1)))
5788    (set (match_dup 0)
5789         (match_dup 2))])
5791 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5792 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5793 ;; because the first makes it clear that operand 0 is not live
5794 ;; before the instruction.
5795 (define_insn "fctiwz_<mode>"
5796   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5797         (unspec:DI [(fix:SI
5798                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5799                    UNSPEC_FCTIWZ))]
5800   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5801   "@
5802    fctiwz %0,%1
5803    xscvdpsxws %x0,%x1"
5804   [(set_attr "type" "fp")])
5806 (define_insn "fctiwuz_<mode>"
5807   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5808         (unspec:DI [(unsigned_fix:SI
5809                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5810                    UNSPEC_FCTIWUZ))]
5811   "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5812   "@
5813    fctiwuz %0,%1
5814    xscvdpuxws %x0,%x1"
5815   [(set_attr "type" "fp")])
5817 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5818 ;; since the friz instruction does not truncate the value if the floating
5819 ;; point value is < LONG_MIN or > LONG_MAX.
5820 (define_insn "*friz"
5821   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5822         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5823   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5824    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5825   "@
5826    friz %0,%1
5827    xsrdpiz %x0,%x1"
5828   [(set_attr "type" "fp")])
5830 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5831 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5832 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5833 ;; extend it, store it back on the stack from the GPR, load it back into the
5834 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5835 ;; disable using store and load to sign/zero extend the value.
5836 (define_insn_and_split "*round32<mode>2_fprs"
5837   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5838         (float:SFDF
5839          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5840    (clobber (match_scratch:DI 2 "=d"))
5841    (clobber (match_scratch:DI 3 "=d"))]
5842   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5843    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5844    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5845   "#"
5846   ""
5847   [(pc)]
5849   rtx dest = operands[0];
5850   rtx src = operands[1];
5851   rtx tmp1 = operands[2];
5852   rtx tmp2 = operands[3];
5853   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5855   if (GET_CODE (tmp1) == SCRATCH)
5856     tmp1 = gen_reg_rtx (DImode);
5857   if (GET_CODE (tmp2) == SCRATCH)
5858     tmp2 = gen_reg_rtx (DImode);
5860   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5861   emit_insn (gen_stfiwx (stack, tmp1));
5862   emit_insn (gen_lfiwax (tmp2, stack));
5863   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5864   DONE;
5866   [(set_attr "type" "fpload")
5867    (set_attr "length" "16")])
5869 (define_insn_and_split "*roundu32<mode>2_fprs"
5870   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5871         (unsigned_float:SFDF
5872          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5873    (clobber (match_scratch:DI 2 "=d"))
5874    (clobber (match_scratch:DI 3 "=d"))]
5875   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5876    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5877    && can_create_pseudo_p ()"
5878   "#"
5879   ""
5880   [(pc)]
5882   rtx dest = operands[0];
5883   rtx src = operands[1];
5884   rtx tmp1 = operands[2];
5885   rtx tmp2 = operands[3];
5886   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5888   if (GET_CODE (tmp1) == SCRATCH)
5889     tmp1 = gen_reg_rtx (DImode);
5890   if (GET_CODE (tmp2) == SCRATCH)
5891     tmp2 = gen_reg_rtx (DImode);
5893   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5894   emit_insn (gen_stfiwx (stack, tmp1));
5895   emit_insn (gen_lfiwzx (tmp2, stack));
5896   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5897   DONE;
5899   [(set_attr "type" "fpload")
5900    (set_attr "length" "16")])
5902 ;; No VSX equivalent to fctid
5903 (define_insn "lrint<mode>di2"
5904   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5905         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5906                    UNSPEC_FCTID))]
5907   "TARGET_<MODE>_FPR && TARGET_FPRND"
5908   "fctid %0,%1"
5909   [(set_attr "type" "fp")])
5911 (define_insn "btrunc<mode>2"
5912   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5913         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5914                      UNSPEC_FRIZ))]
5915   "TARGET_<MODE>_FPR && TARGET_FPRND"
5916   "@
5917    friz %0,%1
5918    xsrdpiz %x0,%x1"
5919   [(set_attr "type" "fp")
5920    (set_attr "fp_type" "fp_addsub_<Fs>")])
5922 (define_insn "ceil<mode>2"
5923   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5924         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5925                      UNSPEC_FRIP))]
5926   "TARGET_<MODE>_FPR && TARGET_FPRND"
5927   "@
5928    frip %0,%1
5929    xsrdpip %x0,%x1"
5930   [(set_attr "type" "fp")
5931    (set_attr "fp_type" "fp_addsub_<Fs>")])
5933 (define_insn "floor<mode>2"
5934   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5935         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5936                      UNSPEC_FRIM))]
5937   "TARGET_<MODE>_FPR && TARGET_FPRND"
5938   "@
5939    frim %0,%1
5940    xsrdpim %x0,%x1"
5941   [(set_attr "type" "fp")
5942    (set_attr "fp_type" "fp_addsub_<Fs>")])
5944 ;; No VSX equivalent to frin
5945 (define_insn "round<mode>2"
5946   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5947         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5948                      UNSPEC_FRIN))]
5949   "TARGET_<MODE>_FPR && TARGET_FPRND"
5950   "frin %0,%1"
5951   [(set_attr "type" "fp")
5952    (set_attr "fp_type" "fp_addsub_<Fs>")])
5954 (define_insn "*xsrdpi<mode>2"
5955   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5956         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5957                      UNSPEC_XSRDPI))]
5958   "TARGET_<MODE>_FPR && TARGET_VSX"
5959   "xsrdpi %x0,%x1"
5960   [(set_attr "type" "fp")
5961    (set_attr "fp_type" "fp_addsub_<Fs>")])
5963 (define_expand "lround<mode>di2"
5964   [(set (match_dup 2)
5965         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5966                      UNSPEC_XSRDPI))
5967    (set (match_operand:DI 0 "gpc_reg_operand" "")
5968         (unspec:DI [(match_dup 2)]
5969                    UNSPEC_FCTID))]
5970   "TARGET_<MODE>_FPR && TARGET_VSX"
5972   operands[2] = gen_reg_rtx (<MODE>mode);
5975 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5976 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5977 ; is only generated for Power8 or later.
5978 (define_insn "stfiwx"
5979   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5980         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5981                    UNSPEC_STFIWX))]
5982   "TARGET_PPC_GFXOPT"
5983   "@
5984    stfiwx %1,%y0
5985    stxsiwx %x1,%y0"
5986   [(set_attr "type" "fpstore")])
5988 ;; If we don't have a direct conversion to single precision, don't enable this
5989 ;; conversion for 32-bit without fast math, because we don't have the insn to
5990 ;; generate the fixup swizzle to avoid double rounding problems.
5991 (define_expand "floatsisf2"
5992   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5993         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5994   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5995    && ((TARGET_FCFIDS && TARGET_LFIWAX)
5996        || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5997            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5998   "
6000   if (TARGET_FCFIDS && TARGET_LFIWAX)
6001     {
6002       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6003       DONE;
6004     }
6005   else if (TARGET_FCFID && TARGET_LFIWAX)
6006     {
6007       rtx dfreg = gen_reg_rtx (DFmode);
6008       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6009       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6010       DONE;
6011     }
6012   else
6013     {
6014       rtx dreg = operands[1];
6015       if (!REG_P (dreg))
6016         dreg = force_reg (SImode, dreg);
6017       dreg = convert_to_mode (DImode, dreg, false);
6018       emit_insn (gen_floatdisf2 (operands[0], dreg));
6019       DONE;
6020     }
6023 (define_insn "floatdidf2"
6024   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6025         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6026   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6027   "@
6028    fcfid %0,%1
6029    xscvsxddp %x0,%x1"
6030   [(set_attr "type" "fp")])
6032 ; Allow the combiner to merge source memory operands to the conversion so that
6033 ; the optimizer/register allocator doesn't try to load the value too early in a
6034 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6035 ; hit.  We will split after reload to avoid the trip through the GPRs
6037 (define_insn_and_split "*floatdidf2_mem"
6038   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6039         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6040    (clobber (match_scratch:DI 2 "=d,wi"))]
6041   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6042   "#"
6043   "&& reload_completed"
6044   [(set (match_dup 2) (match_dup 1))
6045    (set (match_dup 0) (float:DF (match_dup 2)))]
6046   ""
6047   [(set_attr "length" "8")
6048    (set_attr "type" "fpload")])
6050 (define_expand "floatunsdidf2"
6051   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6052         (unsigned_float:DF
6053          (match_operand:DI 1 "gpc_reg_operand" "")))]
6054   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6055   "")
6057 (define_insn "*floatunsdidf2_fcfidu"
6058   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6059         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6060   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6061   "@
6062    fcfidu %0,%1
6063    xscvuxddp %x0,%x1"
6064   [(set_attr "type" "fp")
6065    (set_attr "length" "4")])
6067 (define_insn_and_split "*floatunsdidf2_mem"
6068   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6069         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6070    (clobber (match_scratch:DI 2 "=d,wi"))]
6071   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6072   "#"
6073   "&& reload_completed"
6074   [(set (match_dup 2) (match_dup 1))
6075    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6076   ""
6077   [(set_attr "length" "8")
6078    (set_attr "type" "fpload")])
6080 (define_expand "floatdisf2"
6081   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6082         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6083   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6084    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6085   "
6087   if (!TARGET_FCFIDS)
6088     {
6089       rtx val = operands[1];
6090       if (!flag_unsafe_math_optimizations)
6091         {
6092           rtx label = gen_label_rtx ();
6093           val = gen_reg_rtx (DImode);
6094           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6095           emit_label (label);
6096         }
6097       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6098       DONE;
6099     }
6102 (define_insn "floatdisf2_fcfids"
6103   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6104         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6105   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6106    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6107   "@
6108    fcfids %0,%1
6109    xscvsxdsp %x0,%x1"
6110   [(set_attr "type" "fp")])
6112 (define_insn_and_split "*floatdisf2_mem"
6113   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6114         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6115    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6116   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6117    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6118   "#"
6119   "&& reload_completed"
6120   [(pc)]
6121   "
6123   emit_move_insn (operands[2], operands[1]);
6124   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6125   DONE;
6127   [(set_attr "length" "8")])
6129 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6130 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6131 ;; from double rounding.
6132 ;; Instead of creating a new cpu type for two FP operations, just use fp
6133 (define_insn_and_split "floatdisf2_internal1"
6134   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6135         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6136    (clobber (match_scratch:DF 2 "=d"))]
6137   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6138   "#"
6139   "&& reload_completed"
6140   [(set (match_dup 2)
6141         (float:DF (match_dup 1)))
6142    (set (match_dup 0)
6143         (float_truncate:SF (match_dup 2)))]
6144   ""
6145   [(set_attr "length" "8")
6146    (set_attr "type" "fp")])
6148 ;; Twiddles bits to avoid double rounding.
6149 ;; Bits that might be truncated when converting to DFmode are replaced
6150 ;; by a bit that won't be lost at that stage, but is below the SFmode
6151 ;; rounding position.
6152 (define_expand "floatdisf2_internal2"
6153   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6154                                               (const_int 53)))
6155               (clobber (reg:DI CA_REGNO))])
6156    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6157                                            (const_int 2047)))
6158    (set (match_dup 3) (plus:DI (match_dup 3)
6159                                (const_int 1)))
6160    (set (match_dup 0) (plus:DI (match_dup 0)
6161                                (const_int 2047)))
6162    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6163                                      (const_int 2)))
6164    (set (match_dup 0) (ior:DI (match_dup 0)
6165                               (match_dup 1)))
6166    (set (match_dup 0) (and:DI (match_dup 0)
6167                               (const_int -2048)))
6168    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6169                            (label_ref (match_operand:DI 2 "" ""))
6170                            (pc)))
6171    (set (match_dup 0) (match_dup 1))]
6172   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6173    && !TARGET_FCFIDS"
6174   "
6176   operands[3] = gen_reg_rtx (DImode);
6177   operands[4] = gen_reg_rtx (CCUNSmode);
6180 (define_expand "floatunsdisf2"
6181   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6182         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6183   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6184    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6185   "")
6187 (define_insn "floatunsdisf2_fcfidus"
6188   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6189         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6190   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6191    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6192   "@
6193    fcfidus %0,%1
6194    xscvuxdsp %x0,%x1"
6195   [(set_attr "type" "fp")])
6197 (define_insn_and_split "*floatunsdisf2_mem"
6198   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6199         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6200    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6201   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6202    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6203   "#"
6204   "&& reload_completed"
6205   [(pc)]
6206   "
6208   emit_move_insn (operands[2], operands[1]);
6209   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6210   DONE;
6212   [(set_attr "length" "8")
6213    (set_attr "type" "fpload")])
6215 ;; Define the TImode operations that can be done in a small number
6216 ;; of instructions.  The & constraints are to prevent the register
6217 ;; allocator from allocating registers that overlap with the inputs
6218 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6219 ;; also allow for the output being the same as one of the inputs.
6221 (define_expand "addti3"
6222   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6223         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6224                  (match_operand:TI 2 "reg_or_short_operand" "")))]
6225   "TARGET_64BIT"
6227   rtx lo0 = gen_lowpart (DImode, operands[0]);
6228   rtx lo1 = gen_lowpart (DImode, operands[1]);
6229   rtx lo2 = gen_lowpart (DImode, operands[2]);
6230   rtx hi0 = gen_highpart (DImode, operands[0]);
6231   rtx hi1 = gen_highpart (DImode, operands[1]);
6232   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6234   if (!reg_or_short_operand (lo2, DImode))
6235     lo2 = force_reg (DImode, lo2);
6236   if (!adde_operand (hi2, DImode))
6237     hi2 = force_reg (DImode, hi2);
6239   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6240   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6241   DONE;
6244 (define_expand "subti3"
6245   [(set (match_operand:TI 0 "gpc_reg_operand" "")
6246         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6247                   (match_operand:TI 2 "gpc_reg_operand" "")))]
6248   "TARGET_64BIT"
6250   rtx lo0 = gen_lowpart (DImode, operands[0]);
6251   rtx lo1 = gen_lowpart (DImode, operands[1]);
6252   rtx lo2 = gen_lowpart (DImode, operands[2]);
6253   rtx hi0 = gen_highpart (DImode, operands[0]);
6254   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6255   rtx hi2 = gen_highpart (DImode, operands[2]);
6257   if (!reg_or_short_operand (lo1, DImode))
6258     lo1 = force_reg (DImode, lo1);
6259   if (!adde_operand (hi1, DImode))
6260     hi1 = force_reg (DImode, hi1);
6262   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6263   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6264   DONE;
6267 ;; 128-bit logical operations expanders
6269 (define_expand "and<mode>3"
6270   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6271         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6272                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6273   ""
6274   "")
6276 (define_expand "ior<mode>3"
6277   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6278         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6279                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6280   ""
6281   "")
6283 (define_expand "xor<mode>3"
6284   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6285         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6286                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6287   ""
6288   "")
6290 (define_expand "one_cmpl<mode>2"
6291   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6292         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6293   ""
6294   "")
6296 (define_expand "nor<mode>3"
6297   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6298         (and:BOOL_128
6299          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6300          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6301   ""
6302   "")
6304 (define_expand "andc<mode>3"
6305   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6306         (and:BOOL_128
6307          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6308          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6309   ""
6310   "")
6312 ;; Power8 vector logical instructions.
6313 (define_expand "eqv<mode>3"
6314   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6315         (not:BOOL_128
6316          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6317                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6318   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6319   "")
6321 ;; Rewrite nand into canonical form
6322 (define_expand "nand<mode>3"
6323   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6324         (ior:BOOL_128
6325          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6326          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6327   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6328   "")
6330 ;; The canonical form is to have the negated element first, so we need to
6331 ;; reverse arguments.
6332 (define_expand "orc<mode>3"
6333   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6334         (ior:BOOL_128
6335          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6336          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6337   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6338   "")
6340 ;; 128-bit logical operations insns and split operations
6341 (define_insn_and_split "*and<mode>3_internal"
6342   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6343         (and:BOOL_128
6344          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6345          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6346   ""
6348   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6349     return "xxland %x0,%x1,%x2";
6351   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6352     return "vand %0,%1,%2";
6354   return "#";
6356   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6357   [(const_int 0)]
6359   rs6000_split_logical (operands, AND, false, false, false);
6360   DONE;
6362   [(set (attr "type")
6363       (if_then_else
6364         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6365         (const_string "veclogical")
6366         (const_string "integer")))
6367    (set (attr "length")
6368       (if_then_else
6369         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6370         (const_string "4")
6371         (if_then_else
6372          (match_test "TARGET_POWERPC64")
6373          (const_string "8")
6374          (const_string "16"))))])
6376 ;; 128-bit IOR/XOR
6377 (define_insn_and_split "*bool<mode>3_internal"
6378   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6379         (match_operator:BOOL_128 3 "boolean_or_operator"
6380          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6381           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6382   ""
6384   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6385     return "xxl%q3 %x0,%x1,%x2";
6387   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6388     return "v%q3 %0,%1,%2";
6390   return "#";
6392   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6393   [(const_int 0)]
6395   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6396   DONE;
6398   [(set (attr "type")
6399       (if_then_else
6400         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6401         (const_string "veclogical")
6402         (const_string "integer")))
6403    (set (attr "length")
6404       (if_then_else
6405         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6406         (const_string "4")
6407         (if_then_else
6408          (match_test "TARGET_POWERPC64")
6409          (const_string "8")
6410          (const_string "16"))))])
6412 ;; 128-bit ANDC/ORC
6413 (define_insn_and_split "*boolc<mode>3_internal1"
6414   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6415         (match_operator:BOOL_128 3 "boolean_operator"
6416          [(not:BOOL_128
6417            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6418           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6419   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6421   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6422     return "xxl%q3 %x0,%x1,%x2";
6424   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6425     return "v%q3 %0,%1,%2";
6427   return "#";
6429   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6430    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6431   [(const_int 0)]
6433   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6434   DONE;
6436   [(set (attr "type")
6437       (if_then_else
6438         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6439         (const_string "veclogical")
6440         (const_string "integer")))
6441    (set (attr "length")
6442       (if_then_else
6443         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6444         (const_string "4")
6445         (if_then_else
6446          (match_test "TARGET_POWERPC64")
6447          (const_string "8")
6448          (const_string "16"))))])
6450 (define_insn_and_split "*boolc<mode>3_internal2"
6451   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6452         (match_operator:TI2 3 "boolean_operator"
6453          [(not:TI2
6454            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6455           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6456   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6457   "#"
6458   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6459   [(const_int 0)]
6461   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6462   DONE;
6464   [(set_attr "type" "integer")
6465    (set (attr "length")
6466         (if_then_else
6467          (match_test "TARGET_POWERPC64")
6468          (const_string "8")
6469          (const_string "16")))])
6471 ;; 128-bit NAND/NOR
6472 (define_insn_and_split "*boolcc<mode>3_internal1"
6473   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6474         (match_operator:BOOL_128 3 "boolean_operator"
6475          [(not:BOOL_128
6476            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6477           (not:BOOL_128
6478            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6479   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6481   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6482     return "xxl%q3 %x0,%x1,%x2";
6484   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6485     return "v%q3 %0,%1,%2";
6487   return "#";
6489   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6490    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6491   [(const_int 0)]
6493   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6494   DONE;
6496   [(set (attr "type")
6497       (if_then_else
6498         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6499         (const_string "veclogical")
6500         (const_string "integer")))
6501    (set (attr "length")
6502       (if_then_else
6503         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6504         (const_string "4")
6505         (if_then_else
6506          (match_test "TARGET_POWERPC64")
6507          (const_string "8")
6508          (const_string "16"))))])
6510 (define_insn_and_split "*boolcc<mode>3_internal2"
6511   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6512         (match_operator:TI2 3 "boolean_operator"
6513          [(not:TI2
6514            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6515           (not:TI2
6516            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6517   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6518   "#"
6519   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6520   [(const_int 0)]
6522   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6523   DONE;
6525   [(set_attr "type" "integer")
6526    (set (attr "length")
6527         (if_then_else
6528          (match_test "TARGET_POWERPC64")
6529          (const_string "8")
6530          (const_string "16")))])
6533 ;; 128-bit EQV
6534 (define_insn_and_split "*eqv<mode>3_internal1"
6535   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6536         (not:BOOL_128
6537          (xor:BOOL_128
6538           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6539           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6540   "TARGET_P8_VECTOR"
6542   if (vsx_register_operand (operands[0], <MODE>mode))
6543     return "xxleqv %x0,%x1,%x2";
6545   return "#";
6547   "TARGET_P8_VECTOR && reload_completed
6548    && int_reg_operand (operands[0], <MODE>mode)"
6549   [(const_int 0)]
6551   rs6000_split_logical (operands, XOR, true, false, false);
6552   DONE;
6554   [(set (attr "type")
6555       (if_then_else
6556         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6557         (const_string "veclogical")
6558         (const_string "integer")))
6559    (set (attr "length")
6560       (if_then_else
6561         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6562         (const_string "4")
6563         (if_then_else
6564          (match_test "TARGET_POWERPC64")
6565          (const_string "8")
6566          (const_string "16"))))])
6568 (define_insn_and_split "*eqv<mode>3_internal2"
6569   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6570         (not:TI2
6571          (xor:TI2
6572           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6573           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6574   "!TARGET_P8_VECTOR"
6575   "#"
6576   "reload_completed && !TARGET_P8_VECTOR"
6577   [(const_int 0)]
6579   rs6000_split_logical (operands, XOR, true, false, false);
6580   DONE;
6582   [(set_attr "type" "integer")
6583    (set (attr "length")
6584         (if_then_else
6585          (match_test "TARGET_POWERPC64")
6586          (const_string "8")
6587          (const_string "16")))])
6589 ;; 128-bit one's complement
6590 (define_insn_and_split "*one_cmpl<mode>3_internal"
6591   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6592         (not:BOOL_128
6593           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6594   ""
6596   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6597     return "xxlnor %x0,%x1,%x1";
6599   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6600     return "vnor %0,%1,%1";
6602   return "#";
6604   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6605   [(const_int 0)]
6607   rs6000_split_logical (operands, NOT, false, false, false);
6608   DONE;
6610   [(set (attr "type")
6611       (if_then_else
6612         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6613         (const_string "veclogical")
6614         (const_string "integer")))
6615    (set (attr "length")
6616       (if_then_else
6617         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6618         (const_string "4")
6619         (if_then_else
6620          (match_test "TARGET_POWERPC64")
6621          (const_string "8")
6622          (const_string "16"))))])
6625 ;; Now define ways of moving data around.
6627 ;; Set up a register with a value from the GOT table
6629 (define_expand "movsi_got"
6630   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6631         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6632                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6633   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6634   "
6636   if (GET_CODE (operands[1]) == CONST)
6637     {
6638       rtx offset = const0_rtx;
6639       HOST_WIDE_INT value;
6641       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6642       value = INTVAL (offset);
6643       if (value != 0)
6644         {
6645           rtx tmp = (!can_create_pseudo_p ()
6646                      ? operands[0]
6647                      : gen_reg_rtx (Pmode));
6648           emit_insn (gen_movsi_got (tmp, operands[1]));
6649           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6650           DONE;
6651         }
6652     }
6654   operands[2] = rs6000_got_register (operands[1]);
6657 (define_insn "*movsi_got_internal"
6658   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6659         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6660                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6661                    UNSPEC_MOVSI_GOT))]
6662   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6663   "lwz %0,%a1@got(%2)"
6664   [(set_attr "type" "load")])
6666 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6667 ;; didn't get allocated to a hard register.
6668 (define_split
6669   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6670         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6671                     (match_operand:SI 2 "memory_operand" "")]
6672                    UNSPEC_MOVSI_GOT))]
6673   "DEFAULT_ABI == ABI_V4
6674     && flag_pic == 1
6675     && reload_completed"
6676   [(set (match_dup 0) (match_dup 2))
6677    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6678                                  UNSPEC_MOVSI_GOT))]
6679   "")
6681 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6682 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6683 ;; and this is even supposed to be faster, but it is simpler not to get
6684 ;; integers in the TOC.
6685 (define_insn "movsi_low"
6686   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6687         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6688                            (match_operand 2 "" ""))))]
6689   "TARGET_MACHO && ! TARGET_64BIT"
6690   "lwz %0,lo16(%2)(%1)"
6691   [(set_attr "type" "load")
6692    (set_attr "length" "4")])
6694 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6695 ;;              STW          STFIWX       STXSIWX      LI           LIS
6696 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6697 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6698 ;;              MF%1         MT%0         MT%0         NOP
6699 (define_insn "*movsi_internal1"
6700   [(set (match_operand:SI 0 "nonimmediate_operand"
6701                 "=r,         r,           r,           ?*wI,        ?*wH,
6702                  m,          ?Z,          ?Z,          r,           r,
6703                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6704                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6705                  r,          *c*l,        *h,          *h")
6707         (match_operand:SI 1 "input_operand"
6708                 "r,          U,           m,           Z,           Z,
6709                  r,          wI,          wH,          I,           L,
6710                  n,          wIwH,        O,           wM,          wB,
6711                  O,          wM,          wS,          r,           wIwH,
6712                  *h,         r,           r,           0"))]
6714   "!TARGET_SINGLE_FPU &&
6715    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6716   "@
6717    mr %0,%1
6718    la %0,%a1
6719    lwz%U1%X1 %0,%1
6720    lfiwzx %0,%y1
6721    lxsiwzx %x0,%y1
6722    stw%U0%X0 %1,%0
6723    stfiwx %1,%y0
6724    stxsiwx %x1,%y0
6725    li %0,%1
6726    lis %0,%v1
6727    #
6728    xxlor %x0,%x1,%x1
6729    xxspltib %x0,0
6730    xxspltib %x0,255
6731    vspltisw %0,%1
6732    xxlxor %x0,%x0,%x0
6733    xxlorc %x0,%x0,%x0
6734    #
6735    mtvsrwz %x0,%1
6736    mfvsrwz %0,%x1
6737    mf%1 %0
6738    mt%0 %1
6739    mt%0 %1
6740    nop"
6741   [(set_attr "type"
6742                 "*,          *,           load,        fpload,      fpload,
6743                  store,      fpstore,     fpstore,     *,           *,
6744                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6745                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6746                  *,           *,           *,           *")
6748    (set_attr "length"
6749                 "4,          4,           4,           4,           4,
6750                  4,          4,           4,           4,           4,
6751                  8,          4,           4,           4,           4,
6752                  4,          4,           8,           4,           4,
6753                  4,          4,           4,           4")])
6755 (define_insn "*movsi_internal1_single"
6756   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6757         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6758   "TARGET_SINGLE_FPU &&
6759    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6760   "@
6761    mr %0,%1
6762    la %0,%a1
6763    lwz%U1%X1 %0,%1
6764    stw%U0%X0 %1,%0
6765    li %0,%1
6766    lis %0,%v1
6767    #
6768    mf%1 %0
6769    mt%0 %1
6770    mt%0 %1
6771    nop
6772    stfs%U0%X0 %1,%0
6773    lfs%U1%X1 %0,%1"
6774   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6775    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6777 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6778 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6780 ;; Because SF values are actually stored as DF values within the vector
6781 ;; registers, we need to convert the value to the vector SF format when
6782 ;; we need to use the bits in a union or similar cases.  We only need
6783 ;; to do this transformation when the value is a vector register.  Loads,
6784 ;; stores, and transfers within GPRs are assumed to be safe.
6786 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6787 ;; no alternatives, because the call is created as part of secondary_reload,
6788 ;; and operand #2's register class is used to allocate the temporary register.
6789 ;; This function is called before reload, and it creates the temporary as
6790 ;; needed.
6792 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6793 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  MTVSRWZ
6794 ;;              VSX->VSX
6796 (define_insn_and_split "movsi_from_sf"
6797   [(set (match_operand:SI 0 "nonimmediate_operand"
6798                 "=r,         r,           ?*wI,        ?*wH,     m,
6799                  m,          wY,          Z,           r,        wIwH,
6800                  ?wK")
6802         (unspec:SI [(match_operand:SF 1 "input_operand"
6803                 "r,          m,           Z,           Z,        r,
6804                  f,          wb,          wu,          wIwH,     r,
6805                  wK")]
6806                     UNSPEC_SI_FROM_SF))
6808    (clobber (match_scratch:V4SF 2
6809                 "=X,         X,           X,           X,        X,
6810                  X,          X,           X,           wa,       X,
6811                  wa"))]
6813   "TARGET_NO_SF_SUBREG
6814    && (register_operand (operands[0], SImode)
6815        || register_operand (operands[1], SFmode))"
6816   "@
6817    mr %0,%1
6818    lwz%U1%X1 %0,%1
6819    lfiwzx %0,%y1
6820    lxsiwzx %x0,%y1
6821    stw%U0%X0 %1,%0
6822    stfs%U0%X0 %1,%0
6823    stxssp %1,%0
6824    stxsspx %x1,%y0
6825    #
6826    mtvsrwz %x0,%1
6827    #"
6828   "&& reload_completed
6829    && register_operand (operands[0], SImode)
6830    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6831   [(const_int 0)]
6833   rtx op0 = operands[0];
6834   rtx op1 = operands[1];
6835   rtx op2 = operands[2];
6836   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6838   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6840   if (int_reg_operand (op0, SImode))
6841     {
6842       emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6843       emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6844     }
6845   else
6846     {
6847       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6848       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6849       emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6850     }
6852   DONE;
6854   [(set_attr "type"
6855                 "*,          load,        fpload,      fpload,   store,
6856                  fpstore,    fpstore,     fpstore,     mftgpr,   mffgpr,
6857                  veclogical")
6859    (set_attr "length"
6860                 "4,          4,           4,           4,        4,
6861                  4,          4,           4,           12,       4,
6862                  8")])
6864 ;; movsi_from_sf with zero extension
6866 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6867 ;;              MTVSRWZ      VSX->VSX
6869 (define_insn_and_split "*movdi_from_sf_zero_ext"
6870   [(set (match_operand:DI 0 "gpc_reg_operand"
6871                 "=r,         r,           ?*wI,        ?*wH,     r,
6872                 wIwH,        ?wK")
6874         (zero_extend:DI
6875          (unspec:SI [(match_operand:SF 1 "input_operand"
6876                 "r,          m,           Z,           Z,        wIwH,
6877                  r,          wK")]
6878                     UNSPEC_SI_FROM_SF)))
6880    (clobber (match_scratch:V4SF 2
6881                 "=X,         X,           X,           X,        wa,
6882                  X,          wa"))]
6884   "TARGET_DIRECT_MOVE_64BIT
6885    && (register_operand (operands[0], DImode)
6886        || register_operand (operands[1], SImode))"
6887   "@
6888    rldicl %0,%1,0,32
6889    lwz%U1%X1 %0,%1
6890    lfiwzx %0,%y1
6891    lxsiwzx %x0,%y1
6892    #
6893    mtvsrwz %x0,%1
6894    #"
6895   "&& reload_completed
6896    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6897   [(const_int 0)]
6899   rtx op0 = operands[0];
6900   rtx op1 = operands[1];
6901   rtx op2 = operands[2];
6903   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6905   if (int_reg_operand (op0, DImode))
6906     {
6907       emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6908       emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6909     }
6910   else
6911     {
6912       rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6913       rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6914       rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6915       emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6916     }
6918   DONE;
6920   [(set_attr "type"
6921                 "*,          load,        fpload,      fpload,  mftgpr,
6922                  mffgpr,     veclogical")
6924    (set_attr "length"
6925                 "4,          4,           4,           4,        12,
6926                  4,          8")])
6928 ;; Split a load of a large constant into the appropriate two-insn
6929 ;; sequence.
6931 (define_split
6932   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6933         (match_operand:SI 1 "const_int_operand" ""))]
6934   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6935    && (INTVAL (operands[1]) & 0xffff) != 0"
6936   [(set (match_dup 0)
6937         (match_dup 2))
6938    (set (match_dup 0)
6939         (ior:SI (match_dup 0)
6940                 (match_dup 3)))]
6941   "
6943   if (rs6000_emit_set_const (operands[0], operands[1]))
6944     DONE;
6945   else
6946     FAIL;
6949 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6950 (define_split
6951   [(set (match_operand:DI 0 "altivec_register_operand")
6952         (match_operand:DI 1 "xxspltib_constant_split"))]
6953   "TARGET_P9_VECTOR && reload_completed"
6954   [(const_int 0)]
6956   rtx op0 = operands[0];
6957   rtx op1 = operands[1];
6958   int r = REGNO (op0);
6959   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6961   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6962   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6963   DONE;
6966 (define_insn "*mov<mode>_internal2"
6967   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6968         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6969                     (const_int 0)))
6970    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6971   ""
6972   "@
6973    cmp<wd>i %2,%0,0
6974    mr. %0,%1
6975    #"
6976   [(set_attr "type" "cmp,logical,cmp")
6977    (set_attr "dot" "yes")
6978    (set_attr "length" "4,4,8")])
6980 (define_split
6981   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6982         (compare:CC (match_operand:P 1 "gpc_reg_operand")
6983                     (const_int 0)))
6984    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6985   "reload_completed"
6986   [(set (match_dup 0) (match_dup 1))
6987    (set (match_dup 2)
6988         (compare:CC (match_dup 0)
6989                     (const_int 0)))]
6990   "")
6992 (define_expand "mov<mode>"
6993   [(set (match_operand:INT 0 "general_operand" "")
6994         (match_operand:INT 1 "any_operand" ""))]
6995   ""
6996   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6998 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
6999 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7000 ;;              MTVSRWZ     MF%1       MT%1       NOP
7001 (define_insn "*mov<mode>_internal"
7002   [(set (match_operand:QHI 0 "nonimmediate_operand"
7003                 "=r,        r,         ?*wJwK,    m,         Z,         r,
7004                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
7005                  ?*wJwK,    r,         *c*l,      *h")
7007         (match_operand:QHI 1 "input_operand"
7008                 "r,         m,         Z,         r,         wJwK,      i,
7009                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
7010                  r,         *h,        r,         0"))]
7012   "gpc_reg_operand (operands[0], <MODE>mode)
7013    || gpc_reg_operand (operands[1], <MODE>mode)"
7014   "@
7015    mr %0,%1
7016    l<wd>z%U1%X1 %0,%1
7017    lxsi<wd>zx %x0,%y1
7018    st<wd>%U0%X0 %1,%0
7019    stxsi<wd>x %x1,%y0
7020    li %0,%1
7021    xxlor %x0,%x1,%x1
7022    xxspltib %x0,0
7023    xxspltib %x0,255
7024    vspltis<wd> %0,%1
7025    #
7026    mfvsrwz %0,%x1
7027    mtvsrwz %x0,%1
7028    mf%1 %0
7029    mt%0 %1
7030    nop"
7031   [(set_attr "type"
7032                 "*,         load,      fpload,    store,     fpstore,   *,
7033                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7034                  mffgpr,    mfjmpr,    mtjmpr,    *")
7036    (set_attr "length"
7037                 "4,         4,         4,         4,         4,         4,
7038                  4,         4,         4,         4,         8,         4,
7039                  4,         4,         4,         4")])
7042 ;; Here is how to move condition codes around.  When we store CC data in
7043 ;; an integer register or memory, we store just the high-order 4 bits.
7044 ;; This lets us not shift in the most common case of CR0.
7045 (define_expand "movcc"
7046   [(set (match_operand:CC 0 "nonimmediate_operand" "")
7047         (match_operand:CC 1 "nonimmediate_operand" ""))]
7048   ""
7049   "")
7051 (define_insn "*movcc_internal1"
7052   [(set (match_operand:CC 0 "nonimmediate_operand"
7053                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7054         (match_operand:CC 1 "general_operand"
7055                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7056   "register_operand (operands[0], CCmode)
7057    || register_operand (operands[1], CCmode)"
7058   "@
7059    mcrf %0,%1
7060    mtcrf 128,%1
7061    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7062    crxor %0,%0,%0
7063    mfcr %0%Q1
7064    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7065    mr %0,%1
7066    li %0,%1
7067    mf%1 %0
7068    mt%0 %1
7069    lwz%U1%X1 %0,%1
7070    stw%U0%X0 %1,%0"
7071   [(set (attr "type")
7072      (cond [(eq_attr "alternative" "0,3")
7073                 (const_string "cr_logical")
7074             (eq_attr "alternative" "1,2")
7075                 (const_string "mtcr")
7076             (eq_attr "alternative" "6,7")
7077                 (const_string "integer")
7078             (eq_attr "alternative" "8")
7079                 (const_string "mfjmpr")
7080             (eq_attr "alternative" "9")
7081                 (const_string "mtjmpr")
7082             (eq_attr "alternative" "10")
7083                 (const_string "load")
7084             (eq_attr "alternative" "11")
7085                 (const_string "store")
7086             (match_test "TARGET_MFCRF")
7087                 (const_string "mfcrf")
7088            ]
7089         (const_string "mfcr")))
7090    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7092 ;; For floating-point, we normally deal with the floating-point registers
7093 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7094 ;; can produce floating-point values in fixed-point registers.  Unless the
7095 ;; value is a simple constant or already in memory, we deal with this by
7096 ;; allocating memory and copying the value explicitly via that memory location.
7098 ;; Move 32-bit binary/decimal floating point
7099 (define_expand "mov<mode>"
7100   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7101         (match_operand:FMOVE32 1 "any_operand" ""))]
7102   "<fmove_ok>"
7103   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7105 (define_split
7106   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7107         (match_operand:FMOVE32 1 "const_double_operand" ""))]
7108   "reload_completed
7109    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7110        || (GET_CODE (operands[0]) == SUBREG
7111            && GET_CODE (SUBREG_REG (operands[0])) == REG
7112            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7113   [(set (match_dup 2) (match_dup 3))]
7114   "
7116   long l;
7118   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7120   if (! TARGET_POWERPC64)
7121     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7122   else
7123     operands[2] = gen_lowpart (SImode, operands[0]);
7125   operands[3] = gen_int_mode (l, SImode);
7128 ;; Originally, we tried to keep movsf and movsd common, but the differences
7129 ;; addressing was making it rather difficult to hide with mode attributes.  In
7130 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7131 ;; before the VSX stores meant that the register allocator would tend to do a
7132 ;; direct move to the GPR (which involves conversion from scalar to
7133 ;; vector/memory formats) to save values in the traditional Altivec registers,
7134 ;; while SDmode had problems on power6 if the GPR store was not first due to
7135 ;; the power6 not having an integer store operation.
7137 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7138 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7139 ;;      MR           MT<x>      MF<x>       NOP
7141 (define_insn "movsf_hardfloat"
7142   [(set (match_operand:SF 0 "nonimmediate_operand"
7143          "=!r,       f,         wb,         wu,        m,         wY,
7144           Z,         m,         ww,         !r,        f,         ww,
7145           !r,        *c*l,      !r,         *h")
7146         (match_operand:SF 1 "input_operand"
7147          "m,         m,         wY,         Z,         f,         wb,
7148           wu,        r,         j,          j,         f,         ww,
7149           r,         r,         *h,         0"))]
7150   "(register_operand (operands[0], SFmode)
7151    || register_operand (operands[1], SFmode))
7152    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7153    && (TARGET_ALLOW_SF_SUBREG
7154        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7155   "@
7156    lwz%U1%X1 %0,%1
7157    lfs%U1%X1 %0,%1
7158    lxssp %0,%1
7159    lxsspx %x0,%y1
7160    stfs%U0%X0 %1,%0
7161    stxssp %1,%0
7162    stxsspx %x1,%y0
7163    stw%U0%X0 %1,%0
7164    xxlxor %x0,%x0,%x0
7165    li %0,0
7166    fmr %0,%1
7167    xscpsgndp %x0,%x1,%x1
7168    mr %0,%1
7169    mt%0 %1
7170    mf%1 %0
7171    nop"
7172   [(set_attr "type"
7173         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7174          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7175          *,          mtjmpr,    mfjmpr,     *")])
7177 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7178 ;;      FMR          MR         MT%0       MF%1       NOP
7179 (define_insn "movsd_hardfloat"
7180   [(set (match_operand:SD 0 "nonimmediate_operand"
7181          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7182           f,         !r,        *c*l,      !r,        *h")
7183         (match_operand:SD 1 "input_operand"
7184          "m,         Z,         r,         wx,        r,         wh,
7185           f,         r,         r,         *h,        0"))]
7186   "(register_operand (operands[0], SDmode)
7187    || register_operand (operands[1], SDmode))
7188    && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7189   "@
7190    lwz%U1%X1 %0,%1
7191    lfiwzx %0,%y1
7192    stw%U0%X0 %1,%0
7193    stfiwx %1,%y0
7194    mtvsrwz %x0,%1
7195    mfvsrwz %0,%x1
7196    fmr %0,%1
7197    mr %0,%1
7198    mt%0 %1
7199    mf%1 %0
7200    nop"
7201   [(set_attr "type"
7202         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7203          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7205 (define_insn "*mov<mode>_softfloat"
7206   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7207         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7208   "(gpc_reg_operand (operands[0], <MODE>mode)
7209    || gpc_reg_operand (operands[1], <MODE>mode))
7210    && TARGET_SOFT_FLOAT"
7211   "@
7212    mr %0,%1
7213    mt%0 %1
7214    mf%1 %0
7215    lwz%U1%X1 %0,%1
7216    stw%U0%X0 %1,%0
7217    li %0,%1
7218    lis %0,%v1
7219    #
7220    #
7221    nop"
7222   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7223    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7225 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7226 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7228 ;; Because SF values are actually stored as DF values within the vector
7229 ;; registers, we need to convert the value to the vector SF format when
7230 ;; we need to use the bits in a union or similar cases.  We only need
7231 ;; to do this transformation when the value is a vector register.  Loads,
7232 ;; stores, and transfers within GPRs are assumed to be safe.
7234 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7235 ;; no alternatives, because the call is created as part of secondary_reload,
7236 ;; and operand #2's register class is used to allocate the temporary register.
7237 ;; This function is called before reload, and it creates the temporary as
7238 ;; needed.
7240 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7241 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7242 (define_insn_and_split "movsf_from_si"
7243   [(set (match_operand:SF 0 "nonimmediate_operand"
7244             "=!r,       f,         wb,        wu,        m,         Z,
7245              Z,         wy,        ?r,        !r")
7247         (unspec:SF [(match_operand:SI 1 "input_operand" 
7248             "m,         m,         wY,        Z,         r,         f,
7249              wu,        r,         wy,        r")]
7250                    UNSPEC_SF_FROM_SI))
7252    (clobber (match_scratch:DI 2
7253             "=X,        X,         X,         X,         X,         X,
7254              X,         r,         X,         X"))]
7256   "TARGET_NO_SF_SUBREG
7257    && (register_operand (operands[0], SFmode)
7258        || register_operand (operands[1], SImode))"
7259   "@
7260    lwz%U1%X1 %0,%1
7261    lfs%U1%X1 %0,%1
7262    lxssp %0,%1
7263    lxsspx %x0,%y1
7264    stw%U0%X0 %1,%0
7265    stfiwx %1,%y0
7266    stxsiwx %x1,%y0
7267    #
7268    mfvsrwz %0,%x1
7269    mr %0,%1"
7271   "&& reload_completed
7272    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7273    && int_reg_operand_not_pseudo (operands[1], SImode)"
7274   [(const_int 0)]
7276   rtx op0 = operands[0];
7277   rtx op1 = operands[1];
7278   rtx op2 = operands[2];
7279   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7281   /* Move SF value to upper 32-bits for xscvspdpn.  */
7282   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7283   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7284   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7285   DONE;
7287   [(set_attr "length"
7288             "4,          4,         4,         4,         4,         4,
7289              4,          12,        4,         4")
7290    (set_attr "type"
7291             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7292              fpstore,    vecfloat,  mffgpr,    *")])
7295 ;; Move 64-bit binary/decimal floating point
7296 (define_expand "mov<mode>"
7297   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7298         (match_operand:FMOVE64 1 "any_operand" ""))]
7299   ""
7300   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7302 (define_split
7303   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7304         (match_operand:FMOVE64 1 "const_int_operand" ""))]
7305   "! TARGET_POWERPC64 && reload_completed
7306    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7307        || (GET_CODE (operands[0]) == SUBREG
7308            && GET_CODE (SUBREG_REG (operands[0])) == REG
7309            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7310   [(set (match_dup 2) (match_dup 4))
7311    (set (match_dup 3) (match_dup 1))]
7312   "
7314   int endian = (WORDS_BIG_ENDIAN == 0);
7315   HOST_WIDE_INT value = INTVAL (operands[1]);
7317   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7318   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7319   operands[4] = GEN_INT (value >> 32);
7320   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7323 (define_split
7324   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7325         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7326   "! TARGET_POWERPC64 && reload_completed
7327    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7328        || (GET_CODE (operands[0]) == SUBREG
7329            && GET_CODE (SUBREG_REG (operands[0])) == REG
7330            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7331   [(set (match_dup 2) (match_dup 4))
7332    (set (match_dup 3) (match_dup 5))]
7333   "
7335   int endian = (WORDS_BIG_ENDIAN == 0);
7336   long l[2];
7338   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7340   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7341   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7342   operands[4] = gen_int_mode (l[endian], SImode);
7343   operands[5] = gen_int_mode (l[1 - endian], SImode);
7346 (define_split
7347   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7348         (match_operand:FMOVE64 1 "const_double_operand" ""))]
7349   "TARGET_POWERPC64 && reload_completed
7350    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7351        || (GET_CODE (operands[0]) == SUBREG
7352            && GET_CODE (SUBREG_REG (operands[0])) == REG
7353            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7354   [(set (match_dup 2) (match_dup 3))]
7355   "
7357   int endian = (WORDS_BIG_ENDIAN == 0);
7358   long l[2];
7359   HOST_WIDE_INT val;
7361   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7363   operands[2] = gen_lowpart (DImode, operands[0]);
7364   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7365   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7366          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7368   operands[3] = gen_int_mode (val, DImode);
7371 ;; Don't have reload use general registers to load a constant.  It is
7372 ;; less efficient than loading the constant into an FP register, since
7373 ;; it will probably be used there.
7375 ;; The move constraints are ordered to prefer floating point registers before
7376 ;; general purpose registers to avoid doing a store and a load to get the value
7377 ;; into a floating point register when it is needed for a floating point
7378 ;; operation.  Prefer traditional floating point registers over VSX registers,
7379 ;; since the D-form version of the memory instructions does not need a GPR for
7380 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7381 ;; registers.
7383 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7384 ;; except for 0.0 which can be created on VSX with an xor instruction.
7386 (define_insn "*mov<mode>_hardfloat32"
7387   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7388         (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7389   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 
7390    && (gpc_reg_operand (operands[0], <MODE>mode)
7391        || gpc_reg_operand (operands[1], <MODE>mode))"
7392   "@
7393    stfd%U0%X0 %1,%0
7394    lfd%U1%X1 %0,%1
7395    fmr %0,%1
7396    lxsd %0,%1
7397    stxsd %1,%0
7398    lxsd%U1x %x0,%y1
7399    stxsd%U0x %x1,%y0
7400    xxlor %x0,%x1,%x1
7401    xxlxor %x0,%x0,%x0
7402    #
7403    #
7404    #
7405    #"
7406   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7407    (set_attr "size" "64")
7408    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7410 (define_insn "*mov<mode>_softfloat32"
7411   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7412         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7413   "! TARGET_POWERPC64 
7414    && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7415    && (gpc_reg_operand (operands[0], <MODE>mode)
7416        || gpc_reg_operand (operands[1], <MODE>mode))"
7417   "#"
7418   [(set_attr "type" "store,load,two,*,*,*")
7419    (set_attr "length" "8,8,8,8,12,16")])
7421 ; ld/std require word-aligned displacements -> 'Y' constraint.
7422 ; List Y->r and r->Y before r->r for reload.
7423 (define_insn "*mov<mode>_hardfloat64"
7424   [(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>")
7425         (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"))]
7426   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7427    && (gpc_reg_operand (operands[0], <MODE>mode)
7428        || gpc_reg_operand (operands[1], <MODE>mode))"
7429   "@
7430    stfd%U0%X0 %1,%0
7431    lfd%U1%X1 %0,%1
7432    fmr %0,%1
7433    lxsd %0,%1
7434    stxsd %1,%0
7435    lxsd%U1x %x0,%y1
7436    stxsd%U0x %x1,%y0
7437    xxlor %x0,%x1,%x1
7438    xxlxor %x0,%x0,%x0
7439    li %0,0
7440    std%U0%X0 %1,%0
7441    ld%U1%X1 %0,%1
7442    mr %0,%1
7443    mt%0 %1
7444    mf%1 %0
7445    nop
7446    mftgpr %0,%1
7447    mffgpr %0,%1
7448    mfvsrd %0,%x1
7449    mtvsrd %x0,%1"
7450   [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7451    (set_attr "size" "64")
7452    (set_attr "length" "4")])
7454 (define_insn "*mov<mode>_softfloat64"
7455   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7456         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7457   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7458    && (gpc_reg_operand (operands[0], <MODE>mode)
7459        || gpc_reg_operand (operands[1], <MODE>mode))"
7460   "@
7461    std%U0%X0 %1,%0
7462    ld%U1%X1 %0,%1
7463    mr %0,%1
7464    mt%0 %1
7465    mf%1 %0
7466    #
7467    #
7468    #
7469    nop"
7470   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7471    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7473 (define_expand "mov<mode>"
7474   [(set (match_operand:FMOVE128 0 "general_operand" "")
7475         (match_operand:FMOVE128 1 "any_operand" ""))]
7476   ""
7477   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7479 ;; It's important to list Y->r and r->Y before r->r because otherwise
7480 ;; reload, given m->r, will try to pick r->r and reload it, which
7481 ;; doesn't make progress.
7483 ;; We can't split little endian direct moves of TDmode, because the words are
7484 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7485 ;; problematical.  Don't allow direct move for this case.
7487 (define_insn_and_split "*mov<mode>_64bit_dm"
7488   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7489         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7490   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7491    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7492    && (gpc_reg_operand (operands[0], <MODE>mode)
7493        || gpc_reg_operand (operands[1], <MODE>mode))"
7494   "#"
7495   "&& reload_completed"
7496   [(pc)]
7497 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7498   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7500 (define_insn_and_split "*movtd_64bit_nodm"
7501   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7502         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7503   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7504    && (gpc_reg_operand (operands[0], TDmode)
7505        || gpc_reg_operand (operands[1], TDmode))"
7506   "#"
7507   "&& reload_completed"
7508   [(pc)]
7509 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7510   [(set_attr "length" "8,8,8,12,12,8")])
7512 (define_insn_and_split "*mov<mode>_32bit"
7513   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7514         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7515   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7516    && (FLOAT128_2REG_P (<MODE>mode)
7517        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7518        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7519    && (gpc_reg_operand (operands[0], <MODE>mode)
7520        || gpc_reg_operand (operands[1], <MODE>mode))"
7521   "#"
7522   "&& reload_completed"
7523   [(pc)]
7524 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7525   [(set_attr "length" "8,8,8,8,20,20,16")])
7527 (define_insn_and_split "*mov<mode>_softfloat"
7528   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7529         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7530   "TARGET_SOFT_FLOAT
7531    && (gpc_reg_operand (operands[0], <MODE>mode)
7532        || gpc_reg_operand (operands[1], <MODE>mode))"
7533   "#"
7534   "&& reload_completed"
7535   [(pc)]
7536 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7537   [(set_attr "length" "20,20,16")])
7539 (define_expand "extenddf<mode>2"
7540   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7541         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7542   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7544   if (FLOAT128_IEEE_P (<MODE>mode))
7545     rs6000_expand_float128_convert (operands[0], operands[1], false);
7546   else if (TARGET_VSX)
7547     {
7548       if (<MODE>mode == TFmode)
7549         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7550       else if (<MODE>mode == IFmode)
7551         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7552       else
7553         gcc_unreachable ();
7554     }
7555    else
7556     {
7557       rtx zero = gen_reg_rtx (DFmode);
7558       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7560       if (<MODE>mode == TFmode)
7561         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7562       else if (<MODE>mode == IFmode)
7563         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7564       else
7565         gcc_unreachable ();
7566     }
7567   DONE;
7570 ;; Allow memory operands for the source to be created by the combiner.
7571 (define_insn_and_split "extenddf<mode>2_fprs"
7572   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7573         (float_extend:IBM128
7574          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7575    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7576   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7577    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7578   "#"
7579   "&& reload_completed"
7580   [(set (match_dup 3) (match_dup 1))
7581    (set (match_dup 4) (match_dup 2))]
7583   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7584   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7586   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7587   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7590 (define_insn_and_split "extenddf<mode>2_vsx"
7591   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7592         (float_extend:IBM128
7593          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7594   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7595   "#"
7596   "&& reload_completed"
7597   [(set (match_dup 2) (match_dup 1))
7598    (set (match_dup 3) (match_dup 4))]
7600   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7601   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7603   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7604   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7605   operands[4] = CONST0_RTX (DFmode);
7608 (define_expand "extendsf<mode>2"
7609   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7610         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7611   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7613   if (FLOAT128_IEEE_P (<MODE>mode))
7614     rs6000_expand_float128_convert (operands[0], operands[1], false);
7615   else
7616     {
7617       rtx tmp = gen_reg_rtx (DFmode);
7618       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7619       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7620     }
7621   DONE;
7624 (define_expand "trunc<mode>df2"
7625   [(set (match_operand:DF 0 "gpc_reg_operand" "")
7626         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7627   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7629   if (FLOAT128_IEEE_P (<MODE>mode))
7630     {
7631       rs6000_expand_float128_convert (operands[0], operands[1], false);
7632       DONE;
7633     }
7636 (define_insn_and_split "trunc<mode>df2_internal1"
7637   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7638         (float_truncate:DF
7639          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7640   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7641    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7642   "@
7643    #
7644    fmr %0,%1"
7645   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7646   [(const_int 0)]
7648   emit_note (NOTE_INSN_DELETED);
7649   DONE;
7651   [(set_attr "type" "fpsimple")])
7653 (define_insn "trunc<mode>df2_internal2"
7654   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7655         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7656   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7657    && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7658   "fadd %0,%1,%L1"
7659   [(set_attr "type" "fp")
7660    (set_attr "fp_type" "fp_addsub_d")])
7662 (define_expand "trunc<mode>sf2"
7663   [(set (match_operand:SF 0 "gpc_reg_operand" "")
7664         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7665   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7667   if (FLOAT128_IEEE_P (<MODE>mode))
7668     rs6000_expand_float128_convert (operands[0], operands[1], false);
7669   else if (<MODE>mode == TFmode)
7670     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7671   else if (<MODE>mode == IFmode)
7672     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7673   else
7674     gcc_unreachable ();
7675   DONE;
7678 (define_insn_and_split "trunc<mode>sf2_fprs"
7679   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7680         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7681    (clobber (match_scratch:DF 2 "=d"))]
7682   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 
7683    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7684   "#"
7685   "&& reload_completed"
7686   [(set (match_dup 2)
7687         (float_truncate:DF (match_dup 1)))
7688    (set (match_dup 0)
7689         (float_truncate:SF (match_dup 2)))]
7690   "")
7692 (define_expand "floatsi<mode>2"
7693   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7694                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7695               (clobber (match_scratch:DI 2))])]
7696   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7698   rtx op0 = operands[0];
7699   rtx op1 = operands[1];
7701   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7702     ;
7703   else if (FLOAT128_IEEE_P (<MODE>mode))
7704     {
7705       rs6000_expand_float128_convert (op0, op1, false);
7706       DONE;
7707     }
7708   else
7709     {
7710       rtx tmp = gen_reg_rtx (DFmode);
7711       expand_float (tmp, op1, false);
7712       if (<MODE>mode == TFmode)
7713         emit_insn (gen_extenddftf2 (op0, tmp));
7714       else if (<MODE>mode == IFmode)
7715         emit_insn (gen_extenddfif2 (op0, tmp));
7716       else
7717         gcc_unreachable ();
7718       DONE;
7719     }
7722 ; fadd, but rounding towards zero.
7723 ; This is probably not the optimal code sequence.
7724 (define_insn "fix_trunc_helper<mode>"
7725   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7726         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7727                    UNSPEC_FIX_TRUNC_TF))
7728    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7729   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7730   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7731   [(set_attr "type" "fp")
7732    (set_attr "length" "20")])
7734 (define_expand "fix_trunc<mode>si2"
7735   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7736         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7737   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7739   rtx op0 = operands[0];
7740   rtx op1 = operands[1];
7742   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7743     ;
7744   else
7745     {
7746       if (FLOAT128_IEEE_P (<MODE>mode))
7747         rs6000_expand_float128_convert (op0, op1, false);
7748       else if (<MODE>mode == TFmode)
7749         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7750       else if (<MODE>mode == IFmode)
7751         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7752       else
7753         gcc_unreachable ();
7754       DONE;
7755     }
7758 (define_expand "fix_trunc<mode>si2_fprs"
7759   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7760                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7761               (clobber (match_dup 2))
7762               (clobber (match_dup 3))
7763               (clobber (match_dup 4))
7764               (clobber (match_dup 5))])]
7765   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7767   operands[2] = gen_reg_rtx (DFmode);
7768   operands[3] = gen_reg_rtx (DFmode);
7769   operands[4] = gen_reg_rtx (DImode);
7770   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7773 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7774   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7775         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7776    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7777    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7778    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7779    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7780   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7781   "#"
7782   ""
7783   [(pc)]
7785   rtx lowword;
7786   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7787                                          operands[3]));
7789   gcc_assert (MEM_P (operands[5]));
7790   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7792   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7793   emit_move_insn (operands[5], operands[4]);
7794   emit_move_insn (operands[0], lowword);
7795   DONE;
7798 (define_expand "fix_trunc<mode>di2"
7799   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7800         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7801   "TARGET_FLOAT128_TYPE"
7803   if (!TARGET_FLOAT128_HW)
7804     {
7805       rs6000_expand_float128_convert (operands[0], operands[1], false);
7806       DONE;
7807     }
7810 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7811   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7812         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7813   "TARGET_FLOAT128_TYPE"
7815   rs6000_expand_float128_convert (operands[0], operands[1], true);
7816   DONE;
7819 (define_expand "floatdi<mode>2"
7820   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7821         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7822   "TARGET_FLOAT128_TYPE"
7824   if (!TARGET_FLOAT128_HW)
7825     {
7826       rs6000_expand_float128_convert (operands[0], operands[1], false);
7827       DONE;
7828     }
7831 (define_expand "floatunsdi<IEEE128:mode>2"
7832   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7833         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7834   "TARGET_FLOAT128_TYPE"
7836   if (!TARGET_FLOAT128_HW)
7837     {
7838       rs6000_expand_float128_convert (operands[0], operands[1], true);
7839       DONE;
7840     }
7843 (define_expand "floatuns<IEEE128:mode>2"
7844   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7845         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7846   "TARGET_FLOAT128_TYPE"
7848   rtx op0 = operands[0];
7849   rtx op1 = operands[1];
7851   if (TARGET_FLOAT128_HW)
7852     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7853   else
7854     rs6000_expand_float128_convert (op0, op1, true);
7855   DONE;
7858 (define_expand "neg<mode>2"
7859   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7860         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7861   "FLOAT128_IEEE_P (<MODE>mode)
7862    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7863   "
7865   if (FLOAT128_IEEE_P (<MODE>mode))
7866     {
7867       if (TARGET_FLOAT128_HW)
7868         {
7869           if (<MODE>mode == TFmode)
7870             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7871           else if (<MODE>mode == KFmode)
7872             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7873           else
7874             gcc_unreachable ();
7875         }
7876       else if (TARGET_FLOAT128_TYPE)
7877         {
7878           if (<MODE>mode == TFmode)
7879             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7880           else if (<MODE>mode == KFmode)
7881             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7882           else
7883             gcc_unreachable ();
7884         }
7885       else
7886         {
7887           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7888           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7889                                                 <MODE>mode, 1,
7890                                                 operands[1], <MODE>mode);
7892           if (target && !rtx_equal_p (target, operands[0]))
7893             emit_move_insn (operands[0], target);
7894         }
7895       DONE;
7896     }
7899 (define_insn "neg<mode>2_internal"
7900   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7901         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7902   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7903   "*
7905   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7906     return \"fneg %L0,%L1\;fneg %0,%1\";
7907   else
7908     return \"fneg %0,%1\;fneg %L0,%L1\";
7910   [(set_attr "type" "fpsimple")
7911    (set_attr "length" "8")])
7913 (define_expand "abs<mode>2"
7914   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7915         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7916   "FLOAT128_IEEE_P (<MODE>mode)
7917    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7918   "
7920   rtx label;
7922   if (FLOAT128_IEEE_P (<MODE>mode))
7923     {
7924       if (TARGET_FLOAT128_HW)
7925         {
7926           if (<MODE>mode == TFmode)
7927             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7928           else if (<MODE>mode == KFmode)
7929             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7930           else
7931             FAIL;
7932           DONE;
7933         }
7934       else if (TARGET_FLOAT128_TYPE)
7935         {
7936           if (<MODE>mode == TFmode)
7937             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7938           else if (<MODE>mode == KFmode)
7939             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7940           else
7941             FAIL;
7942           DONE;
7943         }
7944       else
7945         FAIL;
7946     }
7948   label = gen_label_rtx ();
7949   if (<MODE>mode == TFmode)
7950     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7951   else if (<MODE>mode == TFmode)
7952     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7953   else
7954     FAIL;
7955   emit_label (label);
7956   DONE;
7959 (define_expand "abs<mode>2_internal"
7960   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7961         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7962    (set (match_dup 3) (match_dup 5))
7963    (set (match_dup 5) (abs:DF (match_dup 5)))
7964    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7965    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7966                            (label_ref (match_operand 2 "" ""))
7967                            (pc)))
7968    (set (match_dup 6) (neg:DF (match_dup 6)))]
7969   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7970   "
7972   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7973   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7974   operands[3] = gen_reg_rtx (DFmode);
7975   operands[4] = gen_reg_rtx (CCFPmode);
7976   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7977   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7981 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7982 ;; register
7984 (define_expand "ieee_128bit_negative_zero"
7985   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7986   "TARGET_FLOAT128_TYPE"
7988   rtvec v = rtvec_alloc (16);
7989   int i, high;
7991   for (i = 0; i < 16; i++)
7992     RTVEC_ELT (v, i) = const0_rtx;
7994   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7995   RTVEC_ELT (v, high) = GEN_INT (0x80);
7997   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7998   DONE;
8001 ;; IEEE 128-bit negate
8003 ;; We have 2 insns here for negate and absolute value.  The first uses
8004 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8005 ;; insns, and second insn after the first split pass loads up the bit to
8006 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8007 ;; neg/abs to create the constant just once.
8009 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8010   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8011         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8012    (clobber (match_scratch:V16QI 2 "=v"))]
8013   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8014   "#"
8015   "&& 1"
8016   [(parallel [(set (match_dup 0)
8017                    (neg:IEEE128 (match_dup 1)))
8018               (use (match_dup 2))])]
8020   if (GET_CODE (operands[2]) == SCRATCH)
8021     operands[2] = gen_reg_rtx (V16QImode);
8023   operands[3] = gen_reg_rtx (V16QImode);
8024   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8026   [(set_attr "length" "8")
8027    (set_attr "type" "vecsimple")])
8029 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8030   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8031         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8032    (use (match_operand:V16QI 2 "register_operand" "v"))]
8033   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8034   "xxlxor %x0,%x1,%x2"
8035   [(set_attr "type" "veclogical")])
8037 ;; IEEE 128-bit absolute value
8038 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8039   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8040         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8041    (clobber (match_scratch:V16QI 2 "=v"))]
8042   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8043   "#"
8044   "&& 1"
8045   [(parallel [(set (match_dup 0)
8046                    (abs:IEEE128 (match_dup 1)))
8047               (use (match_dup 2))])]
8049   if (GET_CODE (operands[2]) == SCRATCH)
8050     operands[2] = gen_reg_rtx (V16QImode);
8052   operands[3] = gen_reg_rtx (V16QImode);
8053   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8055   [(set_attr "length" "8")
8056    (set_attr "type" "vecsimple")])
8058 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8059   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8060         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8061    (use (match_operand:V16QI 2 "register_operand" "v"))]
8062   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8063   "xxlandc %x0,%x1,%x2"
8064   [(set_attr "type" "veclogical")])
8066 ;; IEEE 128-bit negative absolute value
8067 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8068   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8069         (neg:IEEE128
8070          (abs:IEEE128
8071           (match_operand:IEEE128 1 "register_operand" "wa"))))
8072    (clobber (match_scratch:V16QI 2 "=v"))]
8073   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8074    && FLOAT128_IEEE_P (<MODE>mode)"
8075   "#"
8076   "&& 1"
8077   [(parallel [(set (match_dup 0)
8078                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8079               (use (match_dup 2))])]
8081   if (GET_CODE (operands[2]) == SCRATCH)
8082     operands[2] = gen_reg_rtx (V16QImode);
8084   operands[3] = gen_reg_rtx (V16QImode);
8085   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8087   [(set_attr "length" "8")
8088    (set_attr "type" "vecsimple")])
8090 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8091   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8092         (neg:IEEE128
8093          (abs:IEEE128
8094           (match_operand:IEEE128 1 "register_operand" "wa"))))
8095    (use (match_operand:V16QI 2 "register_operand" "v"))]
8096   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8097   "xxlor %x0,%x1,%x2"
8098   [(set_attr "type" "veclogical")])
8100 ;; Float128 conversion functions.  These expand to library function calls.
8101 ;; We use expand to convert from IBM double double to IEEE 128-bit
8102 ;; and trunc for the opposite.
8103 (define_expand "extendiftf2"
8104   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8105         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8106   "TARGET_FLOAT128_TYPE"
8108   rs6000_expand_float128_convert (operands[0], operands[1], false);
8109   DONE;
8112 (define_expand "extendifkf2"
8113   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8114         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8115   "TARGET_FLOAT128_TYPE"
8117   rs6000_expand_float128_convert (operands[0], operands[1], false);
8118   DONE;
8121 (define_expand "extendtfkf2"
8122   [(set (match_operand:KF 0 "gpc_reg_operand" "")
8123         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8124   "TARGET_FLOAT128_TYPE"
8126   rs6000_expand_float128_convert (operands[0], operands[1], false);
8127   DONE;
8130 (define_expand "trunciftf2"
8131   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8132         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8133   "TARGET_FLOAT128_TYPE"
8135   rs6000_expand_float128_convert (operands[0], operands[1], false);
8136   DONE;
8139 (define_expand "truncifkf2"
8140   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8141         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8142   "TARGET_FLOAT128_TYPE"
8144   rs6000_expand_float128_convert (operands[0], operands[1], false);
8145   DONE;
8148 (define_expand "trunckftf2"
8149   [(set (match_operand:TF 0 "gpc_reg_operand" "")
8150         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8151   "TARGET_FLOAT128_TYPE"
8153   rs6000_expand_float128_convert (operands[0], operands[1], false);
8154   DONE;
8157 (define_expand "trunctfif2"
8158   [(set (match_operand:IF 0 "gpc_reg_operand" "")
8159         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8160   "TARGET_FLOAT128_TYPE"
8162   rs6000_expand_float128_convert (operands[0], operands[1], false);
8163   DONE;
8167 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8168 ;; must have 3 arguments, and scratch register constraint must be a single
8169 ;; constraint.
8171 ;; Reload patterns to support gpr load/store with misaligned mem.
8172 ;; and multiple gpr load/store at offset >= 0xfffc
8173 (define_expand "reload_<mode>_store"
8174   [(parallel [(match_operand 0 "memory_operand" "=m")
8175               (match_operand 1 "gpc_reg_operand" "r")
8176               (match_operand:GPR 2 "register_operand" "=&b")])]
8177   ""
8179   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8180   DONE;
8183 (define_expand "reload_<mode>_load"
8184   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8185               (match_operand 1 "memory_operand" "m")
8186               (match_operand:GPR 2 "register_operand" "=b")])]
8187   ""
8189   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8190   DONE;
8194 ;; Reload patterns for various types using the vector registers.  We may need
8195 ;; an additional base register to convert the reg+offset addressing to reg+reg
8196 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8197 ;; index register for gpr registers.
8198 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8199   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8200               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8201               (match_operand:P 2 "register_operand" "=b")])]
8202   "<P:tptrsize>"
8204   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8205   DONE;
8208 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8209   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8210               (match_operand:RELOAD 1 "memory_operand" "m")
8211               (match_operand:P 2 "register_operand" "=b")])]
8212   "<P:tptrsize>"
8214   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8215   DONE;
8219 ;; Reload sometimes tries to move the address to a GPR, and can generate
8220 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8221 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8223 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8224   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8225         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8226                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8227                (const_int -16)))]
8228   "TARGET_ALTIVEC && reload_completed"
8229   "#"
8230   "&& reload_completed"
8231   [(set (match_dup 0)
8232         (plus:P (match_dup 1)
8233                 (match_dup 2)))
8234    (set (match_dup 0)
8235         (and:P (match_dup 0)
8236                (const_int -16)))])
8238 ;; Power8 merge instructions to allow direct move to/from floating point
8239 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8240 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8241 ;; value, since it is allocated in reload and not all of the flow information
8242 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8243 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8244 ;; schedule other instructions between the two instructions.
8246 (define_insn "p8_fmrgow_<mode>"
8247   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8248         (unspec:FMOVE64X [
8249                 (match_operand:DF 1 "register_operand" "d")
8250                 (match_operand:DF 2 "register_operand" "d")]
8251                          UNSPEC_P8V_FMRGOW))]
8252   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8253   "fmrgow %0,%1,%2"
8254   [(set_attr "type" "fpsimple")])
8256 (define_insn "p8_mtvsrwz"
8257   [(set (match_operand:DF 0 "register_operand" "=d")
8258         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8259                    UNSPEC_P8V_MTVSRWZ))]
8260   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8261   "mtvsrwz %x0,%1"
8262   [(set_attr "type" "mftgpr")])
8264 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8265   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8266         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8267                          UNSPEC_P8V_RELOAD_FROM_GPR))
8268    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8269   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8270   "#"
8271   "&& reload_completed"
8272   [(const_int 0)]
8274   rtx dest = operands[0];
8275   rtx src = operands[1];
8276   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8277   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8278   rtx gpr_hi_reg = gen_highpart (SImode, src);
8279   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8281   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8282   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8283   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8284   DONE;
8286   [(set_attr "length" "12")
8287    (set_attr "type" "three")])
8289 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8290 (define_insn "p8_mtvsrd_df"
8291   [(set (match_operand:DF 0 "register_operand" "=wa")
8292         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8293                    UNSPEC_P8V_MTVSRD))]
8294   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8295   "mtvsrd %x0,%1"
8296   [(set_attr "type" "mftgpr")])
8298 (define_insn "p8_xxpermdi_<mode>"
8299   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8300         (unspec:FMOVE128_GPR [
8301                 (match_operand:DF 1 "register_operand" "wa")
8302                 (match_operand:DF 2 "register_operand" "wa")]
8303                 UNSPEC_P8V_XXPERMDI))]
8304   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8305   "xxpermdi %x0,%x1,%x2,0"
8306   [(set_attr "type" "vecperm")])
8308 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8309   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8310         (unspec:FMOVE128_GPR
8311          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8312          UNSPEC_P8V_RELOAD_FROM_GPR))
8313    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8314   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8315   "#"
8316   "&& reload_completed"
8317   [(const_int 0)]
8319   rtx dest = operands[0];
8320   rtx src = operands[1];
8321   /* You might think that we could use op0 as one temp and a DF clobber
8322      as op2, but you'd be wrong.  Secondary reload move patterns don't
8323      check for overlap of the clobber and the destination.  */
8324   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8325   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8326   rtx gpr_hi_reg = gen_highpart (DImode, src);
8327   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8329   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8330   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8331   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8332   DONE;
8334   [(set_attr "length" "12")
8335    (set_attr "type" "three")])
8337 (define_split
8338   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8339         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8340   "reload_completed
8341    && (int_reg_operand (operands[0], <MODE>mode)
8342        || int_reg_operand (operands[1], <MODE>mode))
8343    && (!TARGET_DIRECT_MOVE_128
8344        || (!vsx_register_operand (operands[0], <MODE>mode)
8345            && !vsx_register_operand (operands[1], <MODE>mode)))"
8346   [(pc)]
8347 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8349 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8350 ;; type is stored internally as double precision in the VSX registers, we have
8351 ;; to convert it from the vector format.
8352 (define_insn "p8_mtvsrd_sf"
8353   [(set (match_operand:SF 0 "register_operand" "=wa")
8354         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8355                    UNSPEC_P8V_MTVSRD))]
8356   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8357   "mtvsrd %x0,%1"
8358   [(set_attr "type" "mftgpr")])
8360 (define_insn_and_split "reload_vsx_from_gprsf"
8361   [(set (match_operand:SF 0 "register_operand" "=wa")
8362         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8363                    UNSPEC_P8V_RELOAD_FROM_GPR))
8364    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8365   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8366   "#"
8367   "&& reload_completed"
8368   [(const_int 0)]
8370   rtx op0 = operands[0];
8371   rtx op1 = operands[1];
8372   rtx op2 = operands[2];
8373   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8375   /* Move SF value to upper 32-bits for xscvspdpn.  */
8376   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8377   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8378   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8379   DONE;
8381   [(set_attr "length" "8")
8382    (set_attr "type" "two")])
8384 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8385 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8386 ;; and then doing a move of that.
8387 (define_insn "p8_mfvsrd_3_<mode>"
8388   [(set (match_operand:DF 0 "register_operand" "=r")
8389         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8390                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8391   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8392   "mfvsrd %0,%x1"
8393   [(set_attr "type" "mftgpr")])
8395 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8396   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8397         (unspec:FMOVE128_GPR
8398          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8399          UNSPEC_P8V_RELOAD_FROM_VSX))
8400    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8401   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8402   "#"
8403   "&& reload_completed"
8404   [(const_int 0)]
8406   rtx dest = operands[0];
8407   rtx src = operands[1];
8408   rtx tmp = operands[2];
8409   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8410   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8412   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8413   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8414   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8415   DONE;
8417   [(set_attr "length" "12")
8418    (set_attr "type" "three")])
8420 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8421 ;; type is stored internally as double precision, we have to convert it to the
8422 ;; vector format.
8424 (define_insn_and_split "reload_gpr_from_vsxsf"
8425   [(set (match_operand:SF 0 "register_operand" "=r")
8426         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8427                    UNSPEC_P8V_RELOAD_FROM_VSX))
8428    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8429   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8430   "#"
8431   "&& reload_completed"
8432   [(const_int 0)]
8434   rtx op0 = operands[0];
8435   rtx op1 = operands[1];
8436   rtx op2 = operands[2];
8437   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8439   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8440   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8441   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8442   DONE;
8444   [(set_attr "length" "12")
8445    (set_attr "type" "three")])
8447 (define_insn "p8_mfvsrd_4_disf"
8448   [(set (match_operand:DI 0 "register_operand" "=r")
8449         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8450                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8451   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8452   "mfvsrd %0,%x1"
8453   [(set_attr "type" "mftgpr")])
8456 ;; Next come the multi-word integer load and store and the load and store
8457 ;; multiple insns.
8459 ;; List r->r after r->Y, otherwise reload will try to reload a
8460 ;; non-offsettable address by using r->r which won't make progress.
8461 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8462 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8464 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8465 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8466 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8467 ;;        AVX const  
8469 (define_insn "*movdi_internal32"
8470   [(set (match_operand:DI 0 "nonimmediate_operand"
8471          "=Y,        r,         r,         ^m,        ^d,         ^d,
8472           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8473           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8474           *wv")
8476         (match_operand:DI 1 "input_operand"
8477           "r,        Y,         r,         d,         m,          d,
8478            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8479            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8480            wB"))]
8482   "! TARGET_POWERPC64
8483    && (gpc_reg_operand (operands[0], DImode)
8484        || gpc_reg_operand (operands[1], DImode))"
8485   "@
8486    #
8487    #
8488    #
8489    stfd%U0%X0 %1,%0
8490    lfd%U1%X1 %0,%1
8491    fmr %0,%1
8492    #
8493    stxsd %1,%0
8494    stxsdx %x1,%y0
8495    lxsd %0,%1
8496    lxsdx %x0,%y1
8497    xxlor %x0,%x1,%x1
8498    xxspltib %x0,0
8499    xxspltib %x0,255
8500    vspltisw %0,%1
8501    xxlxor %x0,%x0,%x0
8502    xxlorc %x0,%x0,%x0
8503    #
8504    #"
8505   [(set_attr "type"
8506                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8507                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8508                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8509                 vecsimple")
8510    (set_attr "size" "64")])
8512 (define_split
8513   [(set (match_operand:DI 0 "gpc_reg_operand" "")
8514         (match_operand:DI 1 "const_int_operand" ""))]
8515   "! TARGET_POWERPC64 && reload_completed
8516    && gpr_or_gpr_p (operands[0], operands[1])
8517    && !direct_move_p (operands[0], operands[1])"
8518   [(set (match_dup 2) (match_dup 4))
8519    (set (match_dup 3) (match_dup 1))]
8520   "
8522   HOST_WIDE_INT value = INTVAL (operands[1]);
8523   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8524                                        DImode);
8525   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8526                                        DImode);
8527   operands[4] = GEN_INT (value >> 32);
8528   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8531 (define_split
8532   [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
8533         (match_operand:DIFD 1 "input_operand" ""))]
8534   "reload_completed && !TARGET_POWERPC64
8535    && gpr_or_gpr_p (operands[0], operands[1])
8536    && !direct_move_p (operands[0], operands[1])"
8537   [(pc)]
8538 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8540 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8541 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8542 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8543 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8544 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8545 (define_insn "*movdi_internal64"
8546   [(set (match_operand:DI 0 "nonimmediate_operand"
8547                "=Y,        r,         r,         r,         r,          r,
8548                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8549                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8550                 *wi,       *wv,       *wv,       r,         *h,         *h,
8551                 ?*r,       ?*wg,      ?*r,       ?*wj")
8553         (match_operand:DI 1 "input_operand"
8554                 "r,        Y,         r,         I,         L,          nF,
8555                  d,        m,         d,         wb,        wv,         wY,
8556                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8557                  wM,       wS,        wB,        *h,        r,          0,
8558                  wg,       r,         wj,        r"))]
8560   "TARGET_POWERPC64
8561    && (gpc_reg_operand (operands[0], DImode)
8562        || gpc_reg_operand (operands[1], DImode))"
8563   "@
8564    std%U0%X0 %1,%0
8565    ld%U1%X1 %0,%1
8566    mr %0,%1
8567    li %0,%1
8568    lis %0,%v1
8569    #
8570    stfd%U0%X0 %1,%0
8571    lfd%U1%X1 %0,%1
8572    fmr %0,%1
8573    stxsd %1,%0
8574    stxsdx %x1,%y0
8575    lxsd %0,%1
8576    lxsdx %x0,%y1
8577    xxlor %x0,%x1,%x1
8578    xxspltib %x0,0
8579    xxspltib %x0,255
8580    #
8581    xxlxor %x0,%x0,%x0
8582    xxlorc %x0,%x0,%x0
8583    #
8584    #
8585    mf%1 %0
8586    mt%0 %1
8587    nop
8588    mftgpr %0,%1
8589    mffgpr %0,%1
8590    mfvsrd %0,%x1
8591    mtvsrd %x0,%1"
8592   [(set_attr "type"
8593                "store,      load,       *,         *,         *,         *,
8594                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8595                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8596                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8597                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8599    (set_attr "size" "64")
8600    (set_attr "length"
8601                "4,         4,         4,         4,         4,          20,
8602                 4,         4,         4,         4,         4,          4,
8603                 4,         4,         4,         4,         4,          8,
8604                 8,         4,         4,         4,         4,          4,
8605                 4,         4,         4,         4")])
8607 ; Some DImode loads are best done as a load of -1 followed by a mask
8608 ; instruction.
8609 (define_split
8610   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8611         (match_operand:DI 1 "const_int_operand"))]
8612   "TARGET_POWERPC64
8613    && num_insns_constant (operands[1], DImode) > 1
8614    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8615    && rs6000_is_valid_and_mask (operands[1], DImode)"
8616   [(set (match_dup 0)
8617         (const_int -1))
8618    (set (match_dup 0)
8619         (and:DI (match_dup 0)
8620                 (match_dup 1)))]
8621   "")
8623 ;; Split a load of a large constant into the appropriate five-instruction
8624 ;; sequence.  Handle anything in a constant number of insns.
8625 ;; When non-easy constants can go in the TOC, this should use
8626 ;; easy_fp_constant predicate.
8627 (define_split
8628   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8629         (match_operand:DI 1 "const_int_operand" ""))]
8630   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8631   [(set (match_dup 0) (match_dup 2))
8632    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8633   "
8635   if (rs6000_emit_set_const (operands[0], operands[1]))
8636     DONE;
8637   else
8638     FAIL;
8641 (define_split
8642   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8643         (match_operand:DI 1 "const_scalar_int_operand" ""))]
8644   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8645   [(set (match_dup 0) (match_dup 2))
8646    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8647   "
8649   if (rs6000_emit_set_const (operands[0], operands[1]))
8650     DONE;
8651   else
8652     FAIL;
8655 (define_split
8656   [(set (match_operand:DI 0 "altivec_register_operand" "")
8657         (match_operand:DI 1 "s5bit_cint_operand" ""))]
8658   "TARGET_VSX && reload_completed"
8659   [(const_int 0)]
8661   rtx op0 = operands[0];
8662   rtx op1 = operands[1];
8663   int r = REGNO (op0);
8664   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8666   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8667   if (op1 != const0_rtx && op1 != constm1_rtx)
8668     {
8669       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8670       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8671     }
8672   DONE;
8675 ;; Split integer constants that can be loaded with XXSPLTIB and a
8676 ;; sign extend operation.
8677 (define_split
8678   [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8679         (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8680   "TARGET_P9_VECTOR && reload_completed"
8681   [(const_int 0)]
8683   rtx op0 = operands[0];
8684   rtx op1 = operands[1];
8685   int r = REGNO (op0);
8686   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8688   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8689   if (<MODE>mode == DImode)
8690     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8691   else if (<MODE>mode == SImode)
8692     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8693   else if (<MODE>mode == HImode)
8694     {
8695       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8696       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8697     }
8698   DONE;
8702 ;; TImode/PTImode is similar, except that we usually want to compute the
8703 ;; address into a register and use lsi/stsi (the exception is during reload).
8705 (define_insn "*mov<mode>_string"
8706   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8707         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8708   "! TARGET_POWERPC64
8709    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8710    && (gpc_reg_operand (operands[0], <MODE>mode)
8711        || gpc_reg_operand (operands[1], <MODE>mode))"
8712   "*
8714   switch (which_alternative)
8715     {
8716     default:
8717       gcc_unreachable ();
8718     case 0:
8719       if (TARGET_STRING)
8720         return \"stswi %1,%P0,16\";
8721       /* FALLTHRU */
8722     case 1:
8723       return \"#\";
8724     case 2:
8725       /* If the address is not used in the output, we can use lsi.  Otherwise,
8726          fall through to generating four loads.  */
8727       if (TARGET_STRING
8728           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8729         return \"lswi %0,%P1,16\";
8730       /* fall through */
8731     case 3:
8732     case 4:
8733     case 5:
8734       return \"#\";
8735     }
8737   [(set_attr "type" "store,store,load,load,*,*")
8738    (set_attr "update" "yes")
8739    (set_attr "indexed" "yes")
8740    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8741                                           (const_string "always")
8742                                           (const_string "conditional")))])
8744 (define_insn "*mov<mode>_ppc64"
8745   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8746         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8747   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8748    && (gpc_reg_operand (operands[0], <MODE>mode)
8749        || gpc_reg_operand (operands[1], <MODE>mode)))"
8751   return rs6000_output_move_128bit (operands);
8753   [(set_attr "type" "store,store,load,load,*,*")
8754    (set_attr "length" "8")])
8756 (define_split
8757   [(set (match_operand:TI2 0 "int_reg_operand" "")
8758         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8759   "TARGET_POWERPC64
8760    && (VECTOR_MEM_NONE_P (<MODE>mode)
8761        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8762   [(set (match_dup 2) (match_dup 4))
8763    (set (match_dup 3) (match_dup 5))]
8764   "
8766   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8767                                        <MODE>mode);
8768   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8769                                        <MODE>mode);
8770   if (CONST_WIDE_INT_P (operands[1]))
8771     {
8772       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8773       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8774     }
8775   else if (CONST_INT_P (operands[1]))
8776     {
8777       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8778       operands[5] = operands[1];
8779     }
8780   else
8781     FAIL;
8784 (define_split
8785   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8786         (match_operand:TI2 1 "input_operand" ""))]
8787   "reload_completed
8788    && gpr_or_gpr_p (operands[0], operands[1])
8789    && !direct_move_p (operands[0], operands[1])
8790    && !quad_load_store_p (operands[0], operands[1])"
8791   [(pc)]
8792 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8794 (define_expand "load_multiple"
8795   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8796                           (match_operand:SI 1 "" ""))
8797                      (use (match_operand:SI 2 "" ""))])]
8798   "TARGET_STRING && !TARGET_POWERPC64"
8799   "
8801   int regno;
8802   int count;
8803   rtx op1;
8804   int i;
8806   /* Support only loading a constant number of fixed-point registers from
8807      memory and only bother with this if more than two; the machine
8808      doesn't support more than eight.  */
8809   if (GET_CODE (operands[2]) != CONST_INT
8810       || INTVAL (operands[2]) <= 2
8811       || INTVAL (operands[2]) > 8
8812       || GET_CODE (operands[1]) != MEM
8813       || GET_CODE (operands[0]) != REG
8814       || REGNO (operands[0]) >= 32)
8815     FAIL;
8817   count = INTVAL (operands[2]);
8818   regno = REGNO (operands[0]);
8820   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8821   op1 = replace_equiv_address (operands[1],
8822                                force_reg (SImode, XEXP (operands[1], 0)));
8824   for (i = 0; i < count; i++)
8825     XVECEXP (operands[3], 0, i)
8826       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8827                      adjust_address_nv (op1, SImode, i * 4));
8830 (define_insn "*ldmsi8"
8831   [(match_parallel 0 "load_multiple_operation"
8832     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8833           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8834      (set (match_operand:SI 3 "gpc_reg_operand" "")
8835           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8836      (set (match_operand:SI 4 "gpc_reg_operand" "")
8837           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8838      (set (match_operand:SI 5 "gpc_reg_operand" "")
8839           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8840      (set (match_operand:SI 6 "gpc_reg_operand" "")
8841           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8842      (set (match_operand:SI 7 "gpc_reg_operand" "")
8843           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8844      (set (match_operand:SI 8 "gpc_reg_operand" "")
8845           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8846      (set (match_operand:SI 9 "gpc_reg_operand" "")
8847           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8848   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8849   "*
8850 { return rs6000_output_load_multiple (operands); }"
8851   [(set_attr "type" "load")
8852    (set_attr "update" "yes")
8853    (set_attr "indexed" "yes")
8854    (set_attr "length" "32")])
8856 (define_insn "*ldmsi7"
8857   [(match_parallel 0 "load_multiple_operation"
8858     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8859           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8860      (set (match_operand:SI 3 "gpc_reg_operand" "")
8861           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8862      (set (match_operand:SI 4 "gpc_reg_operand" "")
8863           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8864      (set (match_operand:SI 5 "gpc_reg_operand" "")
8865           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8866      (set (match_operand:SI 6 "gpc_reg_operand" "")
8867           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8868      (set (match_operand:SI 7 "gpc_reg_operand" "")
8869           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8870      (set (match_operand:SI 8 "gpc_reg_operand" "")
8871           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8872   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8873   "*
8874 { return rs6000_output_load_multiple (operands); }"
8875   [(set_attr "type" "load")
8876    (set_attr "update" "yes")
8877    (set_attr "indexed" "yes")
8878    (set_attr "length" "32")])
8880 (define_insn "*ldmsi6"
8881   [(match_parallel 0 "load_multiple_operation"
8882     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8883           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8884      (set (match_operand:SI 3 "gpc_reg_operand" "")
8885           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8886      (set (match_operand:SI 4 "gpc_reg_operand" "")
8887           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8888      (set (match_operand:SI 5 "gpc_reg_operand" "")
8889           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8890      (set (match_operand:SI 6 "gpc_reg_operand" "")
8891           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8892      (set (match_operand:SI 7 "gpc_reg_operand" "")
8893           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8894   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8895   "*
8896 { return rs6000_output_load_multiple (operands); }"
8897   [(set_attr "type" "load")
8898    (set_attr "update" "yes")
8899    (set_attr "indexed" "yes")
8900    (set_attr "length" "32")])
8902 (define_insn "*ldmsi5"
8903   [(match_parallel 0 "load_multiple_operation"
8904     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8905           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8906      (set (match_operand:SI 3 "gpc_reg_operand" "")
8907           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8908      (set (match_operand:SI 4 "gpc_reg_operand" "")
8909           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8910      (set (match_operand:SI 5 "gpc_reg_operand" "")
8911           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8912      (set (match_operand:SI 6 "gpc_reg_operand" "")
8913           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8914   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
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 "*ldmsi4"
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   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8933   "*
8934 { return rs6000_output_load_multiple (operands); }"
8935   [(set_attr "type" "load")
8936    (set_attr "update" "yes")
8937    (set_attr "indexed" "yes")
8938    (set_attr "length" "32")])
8940 (define_insn "*ldmsi3"
8941   [(match_parallel 0 "load_multiple_operation"
8942     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8943           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8944      (set (match_operand:SI 3 "gpc_reg_operand" "")
8945           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8946      (set (match_operand:SI 4 "gpc_reg_operand" "")
8947           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8948   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8949   "*
8950 { return rs6000_output_load_multiple (operands); }"
8951   [(set_attr "type" "load")
8952    (set_attr "update" "yes")
8953    (set_attr "indexed" "yes")
8954    (set_attr "length" "32")])
8956 (define_expand "store_multiple"
8957   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8958                           (match_operand:SI 1 "" ""))
8959                      (clobber (scratch:SI))
8960                      (use (match_operand:SI 2 "" ""))])]
8961   "TARGET_STRING && !TARGET_POWERPC64"
8962   "
8964   int regno;
8965   int count;
8966   rtx to;
8967   rtx op0;
8968   int i;
8970   /* Support only storing a constant number of fixed-point registers to
8971      memory and only bother with this if more than two; the machine
8972      doesn't support more than eight.  */
8973   if (GET_CODE (operands[2]) != CONST_INT
8974       || INTVAL (operands[2]) <= 2
8975       || INTVAL (operands[2]) > 8
8976       || GET_CODE (operands[0]) != MEM
8977       || GET_CODE (operands[1]) != REG
8978       || REGNO (operands[1]) >= 32)
8979     FAIL;
8981   count = INTVAL (operands[2]);
8982   regno = REGNO (operands[1]);
8984   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8985   to = force_reg (SImode, XEXP (operands[0], 0));
8986   op0 = replace_equiv_address (operands[0], to);
8988   XVECEXP (operands[3], 0, 0)
8989     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8990   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8991                                                  gen_rtx_SCRATCH (SImode));
8993   for (i = 1; i < count; i++)
8994     XVECEXP (operands[3], 0, i + 1)
8995       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8996                      gen_rtx_REG (SImode, regno + i));
8999 (define_insn "*stmsi8"
9000   [(match_parallel 0 "store_multiple_operation"
9001     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9002           (match_operand:SI 2 "gpc_reg_operand" "r"))
9003      (clobber (match_scratch:SI 3 "=X"))
9004      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9005           (match_operand:SI 4 "gpc_reg_operand" "r"))
9006      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9007           (match_operand:SI 5 "gpc_reg_operand" "r"))
9008      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9009           (match_operand:SI 6 "gpc_reg_operand" "r"))
9010      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9011           (match_operand:SI 7 "gpc_reg_operand" "r"))
9012      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9013           (match_operand:SI 8 "gpc_reg_operand" "r"))
9014      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9015           (match_operand:SI 9 "gpc_reg_operand" "r"))
9016      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9017           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9018   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9019   "stswi %2,%1,%O0"
9020   [(set_attr "type" "store")
9021    (set_attr "update" "yes")
9022    (set_attr "indexed" "yes")
9023    (set_attr "cell_micro" "always")])
9025 (define_insn "*stmsi7"
9026   [(match_parallel 0 "store_multiple_operation"
9027     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9028           (match_operand:SI 2 "gpc_reg_operand" "r"))
9029      (clobber (match_scratch:SI 3 "=X"))
9030      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9031           (match_operand:SI 4 "gpc_reg_operand" "r"))
9032      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9033           (match_operand:SI 5 "gpc_reg_operand" "r"))
9034      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9035           (match_operand:SI 6 "gpc_reg_operand" "r"))
9036      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9037           (match_operand:SI 7 "gpc_reg_operand" "r"))
9038      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9039           (match_operand:SI 8 "gpc_reg_operand" "r"))
9040      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9041           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9042   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9043   "stswi %2,%1,%O0"
9044   [(set_attr "type" "store")
9045    (set_attr "update" "yes")
9046    (set_attr "indexed" "yes")
9047    (set_attr "cell_micro" "always")])
9049 (define_insn "*stmsi6"
9050   [(match_parallel 0 "store_multiple_operation"
9051     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9052           (match_operand:SI 2 "gpc_reg_operand" "r"))
9053      (clobber (match_scratch:SI 3 "=X"))
9054      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9055           (match_operand:SI 4 "gpc_reg_operand" "r"))
9056      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9057           (match_operand:SI 5 "gpc_reg_operand" "r"))
9058      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9059           (match_operand:SI 6 "gpc_reg_operand" "r"))
9060      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9061           (match_operand:SI 7 "gpc_reg_operand" "r"))
9062      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9063           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9064   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9065   "stswi %2,%1,%O0"
9066   [(set_attr "type" "store")
9067    (set_attr "update" "yes")
9068    (set_attr "indexed" "yes")
9069    (set_attr "cell_micro" "always")])
9071 (define_insn "*stmsi5"
9072   [(match_parallel 0 "store_multiple_operation"
9073     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9074           (match_operand:SI 2 "gpc_reg_operand" "r"))
9075      (clobber (match_scratch:SI 3 "=X"))
9076      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9077           (match_operand:SI 4 "gpc_reg_operand" "r"))
9078      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9079           (match_operand:SI 5 "gpc_reg_operand" "r"))
9080      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9081           (match_operand:SI 6 "gpc_reg_operand" "r"))
9082      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9083           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9084   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
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 "*stmsi4"
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   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9103   "stswi %2,%1,%O0"
9104   [(set_attr "type" "store")
9105    (set_attr "update" "yes")
9106    (set_attr "indexed" "yes")
9107    (set_attr "cell_micro" "always")])
9109 (define_insn "*stmsi3"
9110   [(match_parallel 0 "store_multiple_operation"
9111     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9112           (match_operand:SI 2 "gpc_reg_operand" "r"))
9113      (clobber (match_scratch:SI 3 "=X"))
9114      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9115           (match_operand:SI 4 "gpc_reg_operand" "r"))
9116      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9117           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9118   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9119   "stswi %2,%1,%O0"
9120   [(set_attr "type" "store")
9121    (set_attr "update" "yes")
9122    (set_attr "indexed" "yes")
9123    (set_attr "cell_micro" "always")])
9125 (define_expand "setmemsi"
9126   [(parallel [(set (match_operand:BLK 0 "" "")
9127                    (match_operand 2 "const_int_operand" ""))
9128               (use (match_operand:SI 1 "" ""))
9129               (use (match_operand:SI 3 "" ""))])]
9130   ""
9131   "
9133   /* If value to set is not zero, use the library routine.  */
9134   if (operands[2] != const0_rtx)
9135     FAIL;
9137   if (expand_block_clear (operands))
9138     DONE;
9139   else
9140     FAIL;
9143 ;; String compare N insn.
9144 ;; Argument 0 is the target (result)
9145 ;; Argument 1 is the destination
9146 ;; Argument 2 is the source
9147 ;; Argument 3 is the length
9148 ;; Argument 4 is the alignment
9150 (define_expand "cmpstrnsi"
9151   [(parallel [(set (match_operand:SI 0)
9152                (compare:SI (match_operand:BLK 1)
9153                            (match_operand:BLK 2)))
9154               (use (match_operand:SI 3))
9155               (use (match_operand:SI 4))])]
9156   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9158   if (optimize_insn_for_size_p ())
9159     FAIL;
9161   if (expand_strn_compare (operands, 0))
9162     DONE;
9163   else  
9164     FAIL;
9167 ;; String compare insn.
9168 ;; Argument 0 is the target (result)
9169 ;; Argument 1 is the destination
9170 ;; Argument 2 is the source
9171 ;; Argument 3 is the alignment
9173 (define_expand "cmpstrsi"
9174   [(parallel [(set (match_operand:SI 0)
9175                (compare:SI (match_operand:BLK 1)
9176                            (match_operand:BLK 2)))
9177               (use (match_operand:SI 3))])]
9178   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9180   if (optimize_insn_for_size_p ())
9181     FAIL;
9183   if (expand_strn_compare (operands, 1))
9184     DONE;
9185   else  
9186     FAIL;
9189 ;; Block compare insn.
9190 ;; Argument 0 is the target (result)
9191 ;; Argument 1 is the destination
9192 ;; Argument 2 is the source
9193 ;; Argument 3 is the length
9194 ;; Argument 4 is the alignment
9196 (define_expand "cmpmemsi"
9197   [(parallel [(set (match_operand:SI 0)
9198                (compare:SI (match_operand:BLK 1)
9199                            (match_operand:BLK 2)))
9200               (use (match_operand:SI 3))
9201               (use (match_operand:SI 4))])]
9202   "TARGET_POPCNTD"
9204   if (expand_block_compare (operands))
9205     DONE;
9206   else
9207     FAIL;
9210 ;; String/block move insn.
9211 ;; Argument 0 is the destination
9212 ;; Argument 1 is the source
9213 ;; Argument 2 is the length
9214 ;; Argument 3 is the alignment
9216 (define_expand "movmemsi"
9217   [(parallel [(set (match_operand:BLK 0 "" "")
9218                    (match_operand:BLK 1 "" ""))
9219               (use (match_operand:SI 2 "" ""))
9220               (use (match_operand:SI 3 "" ""))])]
9221   ""
9222   "
9224   if (expand_block_move (operands))
9225     DONE;
9226   else
9227     FAIL;
9230 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
9231 ;; register allocator doesn't have a clue about allocating 8 word registers.
9232 ;; rD/rS = r5 is preferred, efficient form.
9233 (define_expand "movmemsi_8reg"
9234   [(parallel [(set (match_operand 0 "" "")
9235                    (match_operand 1 "" ""))
9236               (use (match_operand 2 "" ""))
9237               (use (match_operand 3 "" ""))
9238               (clobber (reg:SI  5))
9239               (clobber (reg:SI  6))
9240               (clobber (reg:SI  7))
9241               (clobber (reg:SI  8))
9242               (clobber (reg:SI  9))
9243               (clobber (reg:SI 10))
9244               (clobber (reg:SI 11))
9245               (clobber (reg:SI 12))
9246               (clobber (match_scratch:SI 4 ""))])]
9247   "TARGET_STRING"
9248   "")
9250 (define_insn ""
9251   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9252         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9253    (use (match_operand:SI 2 "immediate_operand" "i"))
9254    (use (match_operand:SI 3 "immediate_operand" "i"))
9255    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9256    (clobber (reg:SI  6))
9257    (clobber (reg:SI  7))
9258    (clobber (reg:SI  8))
9259    (clobber (reg:SI  9))
9260    (clobber (reg:SI 10))
9261    (clobber (reg:SI 11))
9262    (clobber (reg:SI 12))
9263    (clobber (match_scratch:SI 5 "=X"))]
9264   "TARGET_STRING
9265    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9266        || INTVAL (operands[2]) == 0)
9267    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9268    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9269    && REGNO (operands[4]) == 5"
9270   "lswi %4,%1,%2\;stswi %4,%0,%2"
9271   [(set_attr "type" "store")
9272    (set_attr "update" "yes")
9273    (set_attr "indexed" "yes")
9274    (set_attr "cell_micro" "always")
9275    (set_attr "length" "8")])
9277 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
9278 ;; register allocator doesn't have a clue about allocating 6 word registers.
9279 ;; rD/rS = r5 is preferred, efficient form.
9280 (define_expand "movmemsi_6reg"
9281   [(parallel [(set (match_operand 0 "" "")
9282                    (match_operand 1 "" ""))
9283               (use (match_operand 2 "" ""))
9284               (use (match_operand 3 "" ""))
9285               (clobber (reg:SI  5))
9286               (clobber (reg:SI  6))
9287               (clobber (reg:SI  7))
9288               (clobber (reg:SI  8))
9289               (clobber (reg:SI  9))
9290               (clobber (reg:SI 10))
9291               (clobber (match_scratch:SI 4 ""))])]
9292   "TARGET_STRING"
9293   "")
9295 (define_insn ""
9296   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9297         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9298    (use (match_operand:SI 2 "immediate_operand" "i"))
9299    (use (match_operand:SI 3 "immediate_operand" "i"))
9300    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9301    (clobber (reg:SI  6))
9302    (clobber (reg:SI  7))
9303    (clobber (reg:SI  8))
9304    (clobber (reg:SI  9))
9305    (clobber (reg:SI 10))
9306    (clobber (match_scratch:SI 5 "=X"))]
9307   "TARGET_STRING
9308    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9309    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9310    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9311    && REGNO (operands[4]) == 5"
9312   "lswi %4,%1,%2\;stswi %4,%0,%2"
9313   [(set_attr "type" "store")
9314    (set_attr "update" "yes")
9315    (set_attr "indexed" "yes")
9316    (set_attr "cell_micro" "always")
9317    (set_attr "length" "8")])
9319 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9320 ;; problems with TImode.
9321 ;; rD/rS = r5 is preferred, efficient form.
9322 (define_expand "movmemsi_4reg"
9323   [(parallel [(set (match_operand 0 "" "")
9324                    (match_operand 1 "" ""))
9325               (use (match_operand 2 "" ""))
9326               (use (match_operand 3 "" ""))
9327               (clobber (reg:SI 5))
9328               (clobber (reg:SI 6))
9329               (clobber (reg:SI 7))
9330               (clobber (reg:SI 8))
9331               (clobber (match_scratch:SI 4 ""))])]
9332   "TARGET_STRING"
9333   "")
9335 (define_insn ""
9336   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9337         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9338    (use (match_operand:SI 2 "immediate_operand" "i"))
9339    (use (match_operand:SI 3 "immediate_operand" "i"))
9340    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9341    (clobber (reg:SI 6))
9342    (clobber (reg:SI 7))
9343    (clobber (reg:SI 8))
9344    (clobber (match_scratch:SI 5 "=X"))]
9345   "TARGET_STRING
9346    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9347    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9348    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9349    && REGNO (operands[4]) == 5"
9350   "lswi %4,%1,%2\;stswi %4,%0,%2"
9351   [(set_attr "type" "store")
9352    (set_attr "update" "yes")
9353    (set_attr "indexed" "yes")
9354    (set_attr "cell_micro" "always")
9355    (set_attr "length" "8")])
9357 ;; Move up to 8 bytes at a time.
9358 (define_expand "movmemsi_2reg"
9359   [(parallel [(set (match_operand 0 "" "")
9360                    (match_operand 1 "" ""))
9361               (use (match_operand 2 "" ""))
9362               (use (match_operand 3 "" ""))
9363               (clobber (match_scratch:DI 4 ""))
9364               (clobber (match_scratch:SI 5 ""))])]
9365   "TARGET_STRING && ! TARGET_POWERPC64"
9366   "")
9368 (define_insn ""
9369   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9370         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9371    (use (match_operand:SI 2 "immediate_operand" "i"))
9372    (use (match_operand:SI 3 "immediate_operand" "i"))
9373    (clobber (match_scratch:DI 4 "=&r"))
9374    (clobber (match_scratch:SI 5 "=X"))]
9375   "TARGET_STRING && ! TARGET_POWERPC64
9376    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9377   "lswi %4,%1,%2\;stswi %4,%0,%2"
9378   [(set_attr "type" "store")
9379    (set_attr "update" "yes")
9380    (set_attr "indexed" "yes")
9381    (set_attr "cell_micro" "always")
9382    (set_attr "length" "8")])
9384 ;; Move up to 4 bytes at a time.
9385 (define_expand "movmemsi_1reg"
9386   [(parallel [(set (match_operand 0 "" "")
9387                    (match_operand 1 "" ""))
9388               (use (match_operand 2 "" ""))
9389               (use (match_operand 3 "" ""))
9390               (clobber (match_scratch:SI 4 ""))
9391               (clobber (match_scratch:SI 5 ""))])]
9392   "TARGET_STRING"
9393   "")
9395 (define_insn ""
9396   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9397         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9398    (use (match_operand:SI 2 "immediate_operand" "i"))
9399    (use (match_operand:SI 3 "immediate_operand" "i"))
9400    (clobber (match_scratch:SI 4 "=&r"))
9401    (clobber (match_scratch:SI 5 "=X"))]
9402   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9403   "lswi %4,%1,%2\;stswi %4,%0,%2"
9404   [(set_attr "type" "store")
9405    (set_attr "update" "yes")
9406    (set_attr "indexed" "yes")
9407    (set_attr "cell_micro" "always")
9408    (set_attr "length" "8")])
9410 ;; Define insns that do load or store with update.  Some of these we can
9411 ;; get by using pre-decrement or pre-increment, but the hardware can also
9412 ;; do cases where the increment is not the size of the object.
9414 ;; In all these cases, we use operands 0 and 1 for the register being
9415 ;; incremented because those are the operands that local-alloc will
9416 ;; tie and these are the pair most likely to be tieable (and the ones
9417 ;; that will benefit the most).
9419 (define_insn "*movdi_update1"
9420   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9421         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9422                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9423    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9424         (plus:DI (match_dup 1) (match_dup 2)))]
9425   "TARGET_POWERPC64 && TARGET_UPDATE
9426    && (!avoiding_indexed_address_p (DImode)
9427        || !gpc_reg_operand (operands[2], DImode))"
9428   "@
9429    ldux %3,%0,%2
9430    ldu %3,%2(%0)"
9431   [(set_attr "type" "load")
9432    (set_attr "update" "yes")
9433    (set_attr "indexed" "yes,no")])
9435 (define_insn "movdi_<mode>_update"
9436   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9437                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9438         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9439    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9440         (plus:P (match_dup 1) (match_dup 2)))]
9441   "TARGET_POWERPC64 && TARGET_UPDATE
9442    && (!avoiding_indexed_address_p (Pmode)
9443        || !gpc_reg_operand (operands[2], Pmode)
9444        || (REG_P (operands[0])
9445            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9446   "@
9447    stdux %3,%0,%2
9448    stdu %3,%2(%0)"
9449   [(set_attr "type" "store")
9450    (set_attr "update" "yes")
9451    (set_attr "indexed" "yes,no")])
9453 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9454 ;; needed for stack allocation, even if the user passes -mno-update.
9455 (define_insn "movdi_<mode>_update_stack"
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"
9462   "@
9463    stdux %3,%0,%2
9464    stdu %3,%2(%0)"
9465   [(set_attr "type" "store")
9466    (set_attr "update" "yes")
9467    (set_attr "indexed" "yes,no")])
9469 (define_insn "*movsi_update1"
9470   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9471         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9472                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9473    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9474         (plus:SI (match_dup 1) (match_dup 2)))]
9475   "TARGET_UPDATE
9476    && (!avoiding_indexed_address_p (SImode)
9477        || !gpc_reg_operand (operands[2], SImode))"
9478   "@
9479    lwzux %3,%0,%2
9480    lwzu %3,%2(%0)"
9481   [(set_attr "type" "load")
9482    (set_attr "update" "yes")
9483    (set_attr "indexed" "yes,no")])
9485 (define_insn "*movsi_update2"
9486   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9487         (sign_extend:DI
9488          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9489                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
9490    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9491         (plus:DI (match_dup 1) (match_dup 2)))]
9492   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9493   "lwaux %3,%0,%2"
9494   [(set_attr "type" "load")
9495    (set_attr "sign_extend" "yes")
9496    (set_attr "update" "yes")
9497    (set_attr "indexed" "yes")])
9499 (define_insn "movsi_update"
9500   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9501                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9502         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9503    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9504         (plus:SI (match_dup 1) (match_dup 2)))]
9505   "TARGET_UPDATE
9506    && (!avoiding_indexed_address_p (SImode)
9507        || !gpc_reg_operand (operands[2], SImode)
9508        || (REG_P (operands[0])
9509            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9510   "@
9511    stwux %3,%0,%2
9512    stwu %3,%2(%0)"
9513   [(set_attr "type" "store")
9514    (set_attr "update" "yes")
9515    (set_attr "indexed" "yes,no")])
9517 ;; This is an unconditional pattern; needed for stack allocation, even
9518 ;; if the user passes -mno-update.
9519 (define_insn "movsi_update_stack"
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   ""
9526   "@
9527    stwux %3,%0,%2
9528    stwu %3,%2(%0)"
9529   [(set_attr "type" "store")
9530    (set_attr "update" "yes")
9531    (set_attr "indexed" "yes,no")])
9533 (define_insn "*movhi_update1"
9534   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9535         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9536                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9537    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9538         (plus:SI (match_dup 1) (match_dup 2)))]
9539   "TARGET_UPDATE
9540    && (!avoiding_indexed_address_p (SImode)
9541        || !gpc_reg_operand (operands[2], SImode))"
9542   "@
9543    lhzux %3,%0,%2
9544    lhzu %3,%2(%0)"
9545   [(set_attr "type" "load")
9546    (set_attr "update" "yes")
9547    (set_attr "indexed" "yes,no")])
9549 (define_insn "*movhi_update2"
9550   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9551         (zero_extend:SI
9552          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9553                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9554    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9555         (plus:SI (match_dup 1) (match_dup 2)))]
9556   "TARGET_UPDATE
9557    && (!avoiding_indexed_address_p (SImode)
9558        || !gpc_reg_operand (operands[2], SImode))"
9559   "@
9560    lhzux %3,%0,%2
9561    lhzu %3,%2(%0)"
9562   [(set_attr "type" "load")
9563    (set_attr "update" "yes")
9564    (set_attr "indexed" "yes,no")])
9566 (define_insn "*movhi_update3"
9567   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9568         (sign_extend:SI
9569          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9570                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9571    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9572         (plus:SI (match_dup 1) (match_dup 2)))]
9573   "TARGET_UPDATE
9574    && !(avoiding_indexed_address_p (SImode)
9575         && gpc_reg_operand (operands[2], SImode))"
9576   "@
9577    lhaux %3,%0,%2
9578    lhau %3,%2(%0)"
9579   [(set_attr "type" "load")
9580    (set_attr "sign_extend" "yes")
9581    (set_attr "update" "yes")
9582    (set_attr "indexed" "yes,no")])
9584 (define_insn "*movhi_update4"
9585   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9586                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9587         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9588    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9589         (plus:SI (match_dup 1) (match_dup 2)))]
9590   "TARGET_UPDATE
9591    && (!avoiding_indexed_address_p (SImode)
9592        || !gpc_reg_operand (operands[2], SImode))"
9593   "@
9594    sthux %3,%0,%2
9595    sthu %3,%2(%0)"
9596   [(set_attr "type" "store")
9597    (set_attr "update" "yes")
9598    (set_attr "indexed" "yes,no")])
9600 (define_insn "*movqi_update1"
9601   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9602         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9603                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9604    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9605         (plus:SI (match_dup 1) (match_dup 2)))]
9606   "TARGET_UPDATE
9607    && (!avoiding_indexed_address_p (SImode)
9608        || !gpc_reg_operand (operands[2], SImode))"
9609   "@
9610    lbzux %3,%0,%2
9611    lbzu %3,%2(%0)"
9612   [(set_attr "type" "load")
9613    (set_attr "update" "yes")
9614    (set_attr "indexed" "yes,no")])
9616 (define_insn "*movqi_update2"
9617   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9618         (zero_extend:SI
9619          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9620                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9621    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9622         (plus:SI (match_dup 1) (match_dup 2)))]
9623   "TARGET_UPDATE
9624    && (!avoiding_indexed_address_p (SImode)
9625        || !gpc_reg_operand (operands[2], SImode))"
9626   "@
9627    lbzux %3,%0,%2
9628    lbzu %3,%2(%0)"
9629   [(set_attr "type" "load")
9630    (set_attr "update" "yes")
9631    (set_attr "indexed" "yes,no")])
9633 (define_insn "*movqi_update3"
9634   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9635                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9636         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9637    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9638         (plus:SI (match_dup 1) (match_dup 2)))]
9639   "TARGET_UPDATE
9640    && (!avoiding_indexed_address_p (SImode)
9641        || !gpc_reg_operand (operands[2], SImode))"
9642   "@
9643    stbux %3,%0,%2
9644    stbu %3,%2(%0)"
9645   [(set_attr "type" "store")
9646    (set_attr "update" "yes")
9647    (set_attr "indexed" "yes,no")])
9649 (define_insn "*movsf_update1"
9650   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9651         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9652                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9653    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9654         (plus:SI (match_dup 1) (match_dup 2)))]
9655   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9656    && (!avoiding_indexed_address_p (SImode)
9657        || !gpc_reg_operand (operands[2], SImode))"
9658   "@
9659    lfsux %3,%0,%2
9660    lfsu %3,%2(%0)"
9661   [(set_attr "type" "fpload")
9662    (set_attr "update" "yes")
9663    (set_attr "indexed" "yes,no")])
9665 (define_insn "*movsf_update2"
9666   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9667                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9668         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9669    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9670         (plus:SI (match_dup 1) (match_dup 2)))]
9671   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9672    && (!avoiding_indexed_address_p (SImode)
9673        || !gpc_reg_operand (operands[2], SImode))"
9674   "@
9675    stfsux %3,%0,%2
9676    stfsu %3,%2(%0)"
9677   [(set_attr "type" "fpstore")
9678    (set_attr "update" "yes")
9679    (set_attr "indexed" "yes,no")])
9681 (define_insn "*movsf_update3"
9682   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9683         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9684                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9685    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9686         (plus:SI (match_dup 1) (match_dup 2)))]
9687   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9688    && (!avoiding_indexed_address_p (SImode)
9689        || !gpc_reg_operand (operands[2], SImode))"
9690   "@
9691    lwzux %3,%0,%2
9692    lwzu %3,%2(%0)"
9693   [(set_attr "type" "load")
9694    (set_attr "update" "yes")
9695    (set_attr "indexed" "yes,no")])
9697 (define_insn "*movsf_update4"
9698   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9699                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9700         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9701    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9702         (plus:SI (match_dup 1) (match_dup 2)))]
9703   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9704    && (!avoiding_indexed_address_p (SImode)
9705        || !gpc_reg_operand (operands[2], SImode))"
9706   "@
9707    stwux %3,%0,%2
9708    stwu %3,%2(%0)"
9709   [(set_attr "type" "store")
9710    (set_attr "update" "yes")
9711    (set_attr "indexed" "yes,no")])
9713 (define_insn "*movdf_update1"
9714   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9715         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9716                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9717    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9718         (plus:SI (match_dup 1) (match_dup 2)))]
9719   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9720    && (!avoiding_indexed_address_p (SImode)
9721        || !gpc_reg_operand (operands[2], SImode))"
9722   "@
9723    lfdux %3,%0,%2
9724    lfdu %3,%2(%0)"
9725   [(set_attr "type" "fpload")
9726    (set_attr "update" "yes")
9727    (set_attr "indexed" "yes,no")
9728    (set_attr "size" "64")])
9730 (define_insn "*movdf_update2"
9731   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9732                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9733         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9734    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9735         (plus:SI (match_dup 1) (match_dup 2)))]
9736   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9737    && (!avoiding_indexed_address_p (SImode)
9738        || !gpc_reg_operand (operands[2], SImode))"
9739   "@
9740    stfdux %3,%0,%2
9741    stfdu %3,%2(%0)"
9742   [(set_attr "type" "fpstore")
9743    (set_attr "update" "yes")
9744    (set_attr "indexed" "yes,no")])
9747 ;; After inserting conditional returns we can sometimes have
9748 ;; unnecessary register moves.  Unfortunately we cannot have a
9749 ;; modeless peephole here, because some single SImode sets have early
9750 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9751 ;; sequences, using get_attr_length here will smash the operands
9752 ;; array.  Neither is there an early_cobbler_p predicate.
9753 ;; Also this optimization interferes with scalars going into
9754 ;; altivec registers (the code does reloading through the FPRs).
9755 (define_peephole2
9756   [(set (match_operand:DF 0 "gpc_reg_operand" "")
9757         (match_operand:DF 1 "any_operand" ""))
9758    (set (match_operand:DF 2 "gpc_reg_operand" "")
9759         (match_dup 0))]
9760   "!TARGET_VSX
9761    && peep2_reg_dead_p (2, operands[0])"
9762   [(set (match_dup 2) (match_dup 1))])
9764 (define_peephole2
9765   [(set (match_operand:SF 0 "gpc_reg_operand" "")
9766         (match_operand:SF 1 "any_operand" ""))
9767    (set (match_operand:SF 2 "gpc_reg_operand" "")
9768         (match_dup 0))]
9769   "!TARGET_P8_VECTOR
9770    && peep2_reg_dead_p (2, operands[0])"
9771   [(set (match_dup 2) (match_dup 1))])
9774 ;; TLS support.
9776 ;; Mode attributes for different ABIs.
9777 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9778 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9779 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9780 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9782 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9783   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9784         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9785               (match_operand 4 "" "g")))
9786    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9787                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9788                    UNSPEC_TLSGD)
9789    (clobber (reg:SI LR_REGNO))]
9790   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9792   if (TARGET_CMODEL != CMODEL_SMALL)
9793     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9794            "bl %z3\;nop";
9795   else
9796     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9798   "&& TARGET_TLS_MARKERS"
9799   [(set (match_dup 0)
9800         (unspec:TLSmode [(match_dup 1)
9801                          (match_dup 2)]
9802                         UNSPEC_TLSGD))
9803    (parallel [(set (match_dup 0)
9804                    (call (mem:TLSmode (match_dup 3))
9805                          (match_dup 4)))
9806               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9807               (clobber (reg:SI LR_REGNO))])]
9808   ""
9809   [(set_attr "type" "two")
9810    (set (attr "length")
9811      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9812                    (const_int 16)
9813                    (const_int 12)))])
9815 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9816   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9817         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9818               (match_operand 4 "" "g")))
9819    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9820                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9821                    UNSPEC_TLSGD)
9822    (clobber (reg:SI LR_REGNO))]
9823   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9825   if (flag_pic)
9826     {
9827       if (TARGET_SECURE_PLT && flag_pic == 2)
9828         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9829       else
9830         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9831     }
9832   else
9833     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9835   "&& TARGET_TLS_MARKERS"
9836   [(set (match_dup 0)
9837         (unspec:TLSmode [(match_dup 1)
9838                          (match_dup 2)]
9839                         UNSPEC_TLSGD))
9840    (parallel [(set (match_dup 0)
9841                    (call (mem:TLSmode (match_dup 3))
9842                          (match_dup 4)))
9843               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9844               (clobber (reg:SI LR_REGNO))])]
9845   ""
9846   [(set_attr "type" "two")
9847    (set_attr "length" "8")])
9849 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9850   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9851         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9852                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9853                         UNSPEC_TLSGD))]
9854   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9855   "addi %0,%1,%2@got@tlsgd"
9856   "&& TARGET_CMODEL != CMODEL_SMALL"
9857   [(set (match_dup 3)
9858         (high:TLSmode
9859             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9860    (set (match_dup 0)
9861         (lo_sum:TLSmode (match_dup 3)
9862             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9863   "
9865   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9867   [(set (attr "length")
9868      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9869                    (const_int 8)
9870                    (const_int 4)))])
9872 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9873   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9874      (high:TLSmode
9875        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9876                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9877                        UNSPEC_TLSGD)))]
9878   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9879   "addis %0,%1,%2@got@tlsgd@ha"
9880   [(set_attr "length" "4")])
9882 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9883   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9884      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9885        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9886                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9887                        UNSPEC_TLSGD)))]
9888   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9889   "addi %0,%1,%2@got@tlsgd@l"
9890   [(set_attr "length" "4")])
9892 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9893   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9894         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9895               (match_operand 2 "" "g")))
9896    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9897                    UNSPEC_TLSGD)
9898    (clobber (reg:SI LR_REGNO))]
9899   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9900    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9901   "bl %z1(%3@tlsgd)\;nop"
9902   [(set_attr "type" "branch")
9903    (set_attr "length" "8")])
9905 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9906   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9907         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9908               (match_operand 2 "" "g")))
9909    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9910                    UNSPEC_TLSGD)
9911    (clobber (reg:SI LR_REGNO))]
9912   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9914   if (flag_pic)
9915     {
9916       if (TARGET_SECURE_PLT && flag_pic == 2)
9917         return "bl %z1+32768(%3@tlsgd)@plt";
9918       return "bl %z1(%3@tlsgd)@plt";
9919     }
9920   return "bl %z1(%3@tlsgd)";
9922   [(set_attr "type" "branch")
9923    (set_attr "length" "4")])
9925 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9926   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9927         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9928               (match_operand 3 "" "g")))
9929    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9930                    UNSPEC_TLSLD)
9931    (clobber (reg:SI LR_REGNO))]
9932   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9934   if (TARGET_CMODEL != CMODEL_SMALL)
9935     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9936            "bl %z2\;nop";
9937   else
9938     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9940   "&& TARGET_TLS_MARKERS"
9941   [(set (match_dup 0)
9942         (unspec:TLSmode [(match_dup 1)]
9943                         UNSPEC_TLSLD))
9944    (parallel [(set (match_dup 0)
9945                    (call (mem:TLSmode (match_dup 2))
9946                          (match_dup 3)))
9947               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9948               (clobber (reg:SI LR_REGNO))])]
9949   ""
9950   [(set_attr "type" "two")
9951    (set (attr "length")
9952      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9953                    (const_int 16)
9954                    (const_int 12)))])
9956 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9957   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9958         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9959               (match_operand 3 "" "g")))
9960    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9961                    UNSPEC_TLSLD)
9962    (clobber (reg:SI LR_REGNO))]
9963   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9965   if (flag_pic)
9966     {
9967       if (TARGET_SECURE_PLT && flag_pic == 2)
9968         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9969       else
9970         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9971     }
9972   else
9973     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9975   "&& TARGET_TLS_MARKERS"
9976   [(set (match_dup 0)
9977         (unspec:TLSmode [(match_dup 1)]
9978                         UNSPEC_TLSLD))
9979    (parallel [(set (match_dup 0)
9980                    (call (mem:TLSmode (match_dup 2))
9981                          (match_dup 3)))
9982               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9983               (clobber (reg:SI LR_REGNO))])]
9984   ""
9985   [(set_attr "length" "8")])
9987 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9988   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9989         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9990                         UNSPEC_TLSLD))]
9991   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9992   "addi %0,%1,%&@got@tlsld"
9993   "&& TARGET_CMODEL != CMODEL_SMALL"
9994   [(set (match_dup 2)
9995         (high:TLSmode
9996             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9997    (set (match_dup 0)
9998         (lo_sum:TLSmode (match_dup 2)
9999             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10000   "
10002   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10004   [(set (attr "length")
10005      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10006                    (const_int 8)
10007                    (const_int 4)))])
10009 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10010   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10011      (high:TLSmode
10012        (unspec:TLSmode [(const_int 0)
10013                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10014                        UNSPEC_TLSLD)))]
10015   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10016   "addis %0,%1,%&@got@tlsld@ha"
10017   [(set_attr "length" "4")])
10019 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10020   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10021      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10022        (unspec:TLSmode [(const_int 0)
10023                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10024                        UNSPEC_TLSLD)))]
10025   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10026   "addi %0,%1,%&@got@tlsld@l"
10027   [(set_attr "length" "4")])
10029 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10030   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10031         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10032               (match_operand 2 "" "g")))
10033    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10034    (clobber (reg:SI LR_REGNO))]
10035   "HAVE_AS_TLS && TARGET_TLS_MARKERS
10036    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10037   "bl %z1(%&@tlsld)\;nop"
10038   [(set_attr "type" "branch")
10039    (set_attr "length" "8")])
10041 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10042   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10043         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10044               (match_operand 2 "" "g")))
10045    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10046    (clobber (reg:SI LR_REGNO))]
10047   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10049   if (flag_pic)
10050     {
10051       if (TARGET_SECURE_PLT && flag_pic == 2)
10052         return "bl %z1+32768(%&@tlsld)@plt";
10053       return "bl %z1(%&@tlsld)@plt";
10054     }
10055   return "bl %z1(%&@tlsld)";
10057   [(set_attr "type" "branch")
10058    (set_attr "length" "4")])
10060 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10061   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10062         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10063                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10064                         UNSPEC_TLSDTPREL))]
10065   "HAVE_AS_TLS"
10066   "addi %0,%1,%2@dtprel")
10068 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10069   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10070         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10071                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10072                         UNSPEC_TLSDTPRELHA))]
10073   "HAVE_AS_TLS"
10074   "addis %0,%1,%2@dtprel@ha")
10076 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10077   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10078         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10079                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10080                         UNSPEC_TLSDTPRELLO))]
10081   "HAVE_AS_TLS"
10082   "addi %0,%1,%2@dtprel@l")
10084 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10085   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10086         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10087                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10088                         UNSPEC_TLSGOTDTPREL))]
10089   "HAVE_AS_TLS"
10090   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10091   "&& TARGET_CMODEL != CMODEL_SMALL"
10092   [(set (match_dup 3)
10093         (high:TLSmode
10094             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10095    (set (match_dup 0)
10096         (lo_sum:TLSmode (match_dup 3)
10097             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10098   "
10100   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10102   [(set (attr "length")
10103      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10104                    (const_int 8)
10105                    (const_int 4)))])
10107 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10108   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10109      (high:TLSmode
10110        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10111                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10112                        UNSPEC_TLSGOTDTPREL)))]
10113   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10114   "addis %0,%1,%2@got@dtprel@ha"
10115   [(set_attr "length" "4")])
10117 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10118   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10119      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10120          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10121                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10122                          UNSPEC_TLSGOTDTPREL)))]
10123   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10124   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10125   [(set_attr "length" "4")])
10127 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10128   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10129         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10130                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10131                         UNSPEC_TLSTPREL))]
10132   "HAVE_AS_TLS"
10133   "addi %0,%1,%2@tprel")
10135 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10136   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10137         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10138                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10139                         UNSPEC_TLSTPRELHA))]
10140   "HAVE_AS_TLS"
10141   "addis %0,%1,%2@tprel@ha")
10143 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10144   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10145         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10146                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10147                         UNSPEC_TLSTPRELLO))]
10148   "HAVE_AS_TLS"
10149   "addi %0,%1,%2@tprel@l")
10151 ;; "b" output constraint here and on tls_tls input to support linker tls
10152 ;; optimization.  The linker may edit the instructions emitted by a
10153 ;; tls_got_tprel/tls_tls pair to addis,addi.
10154 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10155   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10156         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10157                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10158                         UNSPEC_TLSGOTTPREL))]
10159   "HAVE_AS_TLS"
10160   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10161   "&& TARGET_CMODEL != CMODEL_SMALL"
10162   [(set (match_dup 3)
10163         (high:TLSmode
10164             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10165    (set (match_dup 0)
10166         (lo_sum:TLSmode (match_dup 3)
10167             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10168   "
10170   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10172   [(set (attr "length")
10173      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10174                    (const_int 8)
10175                    (const_int 4)))])
10177 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10178   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10179      (high:TLSmode
10180        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10181                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10182                        UNSPEC_TLSGOTTPREL)))]
10183   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10184   "addis %0,%1,%2@got@tprel@ha"
10185   [(set_attr "length" "4")])
10187 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10188   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10189      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10190          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10191                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10192                          UNSPEC_TLSGOTTPREL)))]
10193   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10194   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10195   [(set_attr "length" "4")])
10197 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10198   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10199         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10200                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10201                         UNSPEC_TLSTLS))]
10202   "TARGET_ELF && HAVE_AS_TLS"
10203   "add %0,%1,%2@tls")
10205 (define_expand "tls_get_tpointer"
10206   [(set (match_operand:SI 0 "gpc_reg_operand" "")
10207         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10208   "TARGET_XCOFF && HAVE_AS_TLS"
10209   "
10211   emit_insn (gen_tls_get_tpointer_internal ());
10212   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10213   DONE;
10216 (define_insn "tls_get_tpointer_internal"
10217   [(set (reg:SI 3)
10218         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10219    (clobber (reg:SI LR_REGNO))]
10220   "TARGET_XCOFF && HAVE_AS_TLS"
10221   "bla __get_tpointer")
10223 (define_expand "tls_get_addr<mode>"
10224   [(set (match_operand:P 0 "gpc_reg_operand" "")
10225         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10226                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10227   "TARGET_XCOFF && HAVE_AS_TLS"
10228   "
10230   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10231   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10232   emit_insn (gen_tls_get_addr_internal<mode> ());
10233   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10234   DONE;
10237 (define_insn "tls_get_addr_internal<mode>"
10238   [(set (reg:P 3)
10239         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10240    (clobber (reg:P 0))
10241    (clobber (reg:P 4))
10242    (clobber (reg:P 5))
10243    (clobber (reg:P 11))
10244    (clobber (reg:CC CR0_REGNO))
10245    (clobber (reg:P LR_REGNO))]
10246   "TARGET_XCOFF && HAVE_AS_TLS"
10247   "bla __tls_get_addr")
10249 ;; Next come insns related to the calling sequence.
10251 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10252 ;; We move the back-chain and decrement the stack pointer.
10254 (define_expand "allocate_stack"
10255   [(set (match_operand 0 "gpc_reg_operand" "")
10256         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10257    (set (reg 1)
10258         (minus (reg 1) (match_dup 1)))]
10259   ""
10260   "
10261 { rtx chain = gen_reg_rtx (Pmode);
10262   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10263   rtx neg_op0;
10264   rtx insn, par, set, mem;
10266   emit_move_insn (chain, stack_bot);
10268   /* Check stack bounds if necessary.  */
10269   if (crtl->limit_stack)
10270     {
10271       rtx available;
10272       available = expand_binop (Pmode, sub_optab,
10273                                 stack_pointer_rtx, stack_limit_rtx,
10274                                 NULL_RTX, 1, OPTAB_WIDEN);
10275       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10276     }
10278   if (GET_CODE (operands[1]) != CONST_INT
10279       || INTVAL (operands[1]) < -32767
10280       || INTVAL (operands[1]) > 32768)
10281     {
10282       neg_op0 = gen_reg_rtx (Pmode);
10283       if (TARGET_32BIT)
10284         emit_insn (gen_negsi2 (neg_op0, operands[1]));
10285       else
10286         emit_insn (gen_negdi2 (neg_op0, operands[1]));
10287     }
10288   else
10289     neg_op0 = GEN_INT (- INTVAL (operands[1]));
10291   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10292                                        : gen_movdi_di_update_stack))
10293                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10294                          chain));
10295   /* Since we didn't use gen_frame_mem to generate the MEM, grab
10296      it now and set the alias set/attributes. The above gen_*_update
10297      calls will generate a PARALLEL with the MEM set being the first
10298      operation. */
10299   par = PATTERN (insn);
10300   gcc_assert (GET_CODE (par) == PARALLEL);
10301   set = XVECEXP (par, 0, 0);
10302   gcc_assert (GET_CODE (set) == SET);
10303   mem = SET_DEST (set);
10304   gcc_assert (MEM_P (mem));
10305   MEM_NOTRAP_P (mem) = 1;
10306   set_mem_alias_set (mem, get_frame_alias_set ());
10308   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10309   DONE;
10312 ;; These patterns say how to save and restore the stack pointer.  We need not
10313 ;; save the stack pointer at function level since we are careful to
10314 ;; preserve the backchain.  At block level, we have to restore the backchain
10315 ;; when we restore the stack pointer.
10317 ;; For nonlocal gotos, we must save both the stack pointer and its
10318 ;; backchain and restore both.  Note that in the nonlocal case, the
10319 ;; save area is a memory location.
10321 (define_expand "save_stack_function"
10322   [(match_operand 0 "any_operand" "")
10323    (match_operand 1 "any_operand" "")]
10324   ""
10325   "DONE;")
10327 (define_expand "restore_stack_function"
10328   [(match_operand 0 "any_operand" "")
10329    (match_operand 1 "any_operand" "")]
10330   ""
10331   "DONE;")
10333 ;; Adjust stack pointer (op0) to a new value (op1).
10334 ;; First copy old stack backchain to new location, and ensure that the
10335 ;; scheduler won't reorder the sp assignment before the backchain write.
10336 (define_expand "restore_stack_block"
10337   [(set (match_dup 2) (match_dup 3))
10338    (set (match_dup 4) (match_dup 2))
10339    (match_dup 5)
10340    (set (match_operand 0 "register_operand" "")
10341         (match_operand 1 "register_operand" ""))]
10342   ""
10343   "
10345   rtvec p;
10347   operands[1] = force_reg (Pmode, operands[1]);
10348   operands[2] = gen_reg_rtx (Pmode);
10349   operands[3] = gen_frame_mem (Pmode, operands[0]);
10350   operands[4] = gen_frame_mem (Pmode, operands[1]);
10351   p = rtvec_alloc (1);
10352   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10353                                   const0_rtx);
10354   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10357 (define_expand "save_stack_nonlocal"
10358   [(set (match_dup 3) (match_dup 4))
10359    (set (match_operand 0 "memory_operand" "") (match_dup 3))
10360    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10361   ""
10362   "
10364   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10366   /* Copy the backchain to the first word, sp to the second.  */
10367   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10368   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10369   operands[3] = gen_reg_rtx (Pmode);
10370   operands[4] = gen_frame_mem (Pmode, operands[1]);
10373 (define_expand "restore_stack_nonlocal"
10374   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10375    (set (match_dup 3) (match_dup 4))
10376    (set (match_dup 5) (match_dup 2))
10377    (match_dup 6)
10378    (set (match_operand 0 "register_operand" "") (match_dup 3))]
10379   ""
10380   "
10382   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10383   rtvec p;
10385   /* Restore the backchain from the first word, sp from the second.  */
10386   operands[2] = gen_reg_rtx (Pmode);
10387   operands[3] = gen_reg_rtx (Pmode);
10388   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10389   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10390   operands[5] = gen_frame_mem (Pmode, operands[3]);
10391   p = rtvec_alloc (1);
10392   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10393                                   const0_rtx);
10394   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10397 ;; TOC register handling.
10399 ;; Code to initialize the TOC register...
10401 (define_insn "load_toc_aix_si"
10402   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10403                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10404               (use (reg:SI 2))])]
10405   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10406   "*
10408   char buf[30];
10409   extern int need_toc_init;
10410   need_toc_init = 1;
10411   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10412   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10413   operands[2] = gen_rtx_REG (Pmode, 2);
10414   return \"lwz %0,%1(%2)\";
10416   [(set_attr "type" "load")
10417    (set_attr "update" "no")
10418    (set_attr "indexed" "no")])
10420 (define_insn "load_toc_aix_di"
10421   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10422                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10423               (use (reg:DI 2))])]
10424   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10425   "*
10427   char buf[30];
10428   extern int need_toc_init;
10429   need_toc_init = 1;
10430   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10431                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10432   if (TARGET_ELF)
10433     strcat (buf, \"@toc\");
10434   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10435   operands[2] = gen_rtx_REG (Pmode, 2);
10436   return \"ld %0,%1(%2)\";
10438   [(set_attr "type" "load")
10439    (set_attr "update" "no")
10440    (set_attr "indexed" "no")])
10442 (define_insn "load_toc_v4_pic_si"
10443   [(set (reg:SI LR_REGNO)
10444         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10445   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10446   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10447   [(set_attr "type" "branch")
10448    (set_attr "length" "4")])
10450 (define_expand "load_toc_v4_PIC_1"
10451   [(parallel [(set (reg:SI LR_REGNO)
10452                    (match_operand:SI 0 "immediate_operand" "s"))
10453               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10454   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10455    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10456   "")
10458 (define_insn "load_toc_v4_PIC_1_normal"
10459   [(set (reg:SI LR_REGNO)
10460         (match_operand:SI 0 "immediate_operand" "s"))
10461    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10462   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10463    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10464   "bcl 20,31,%0\\n%0:"
10465   [(set_attr "type" "branch")
10466    (set_attr "length" "4")
10467    (set_attr "cannot_copy" "yes")])
10469 (define_insn "load_toc_v4_PIC_1_476"
10470   [(set (reg:SI LR_REGNO)
10471         (match_operand:SI 0 "immediate_operand" "s"))
10472    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10473   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10474    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10475   "*
10477   char name[32];
10478   static char templ[32];
10480   get_ppc476_thunk_name (name);
10481   sprintf (templ, \"bl %s\\n%%0:\", name);
10482   return templ;
10484   [(set_attr "type" "branch")
10485    (set_attr "length" "4")
10486    (set_attr "cannot_copy" "yes")])
10488 (define_expand "load_toc_v4_PIC_1b"
10489   [(parallel [(set (reg:SI LR_REGNO)
10490                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10491                                (label_ref (match_operand 1 "" ""))]
10492                            UNSPEC_TOCPTR))
10493               (match_dup 1)])]
10494   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10495   "")
10497 (define_insn "load_toc_v4_PIC_1b_normal"
10498   [(set (reg:SI LR_REGNO)
10499         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10500                     (label_ref (match_operand 1 "" ""))]
10501                 UNSPEC_TOCPTR))
10502    (match_dup 1)]
10503   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10504   "bcl 20,31,$+8\;.long %0-$"
10505   [(set_attr "type" "branch")
10506    (set_attr "length" "8")])
10508 (define_insn "load_toc_v4_PIC_1b_476"
10509   [(set (reg:SI LR_REGNO)
10510         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10511                     (label_ref (match_operand 1 "" ""))]
10512                 UNSPEC_TOCPTR))
10513    (match_dup 1)]
10514   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10515   "*
10517   char name[32];
10518   static char templ[32];
10520   get_ppc476_thunk_name (name);
10521   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10522   return templ;
10524   [(set_attr "type" "branch")
10525    (set_attr "length" "16")])
10527 (define_insn "load_toc_v4_PIC_2"
10528   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10529         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10530                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10531                              (match_operand:SI 3 "immediate_operand" "s")))))]
10532   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10533   "lwz %0,%2-%3(%1)"
10534   [(set_attr "type" "load")])
10536 (define_insn "load_toc_v4_PIC_3b"
10537   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10538         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10539                  (high:SI
10540                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10541                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10542   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10543   "addis %0,%1,%2-%3@ha")
10545 (define_insn "load_toc_v4_PIC_3c"
10546   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10547         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10548                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10549                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10550   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10551   "addi %0,%1,%2-%3@l")
10553 ;; If the TOC is shared over a translation unit, as happens with all
10554 ;; the kinds of PIC that we support, we need to restore the TOC
10555 ;; pointer only when jumping over units of translation.
10556 ;; On Darwin, we need to reload the picbase.
10558 (define_expand "builtin_setjmp_receiver"
10559   [(use (label_ref (match_operand 0 "" "")))]
10560   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10561    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10562    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10563   "
10565 #if TARGET_MACHO
10566   if (DEFAULT_ABI == ABI_DARWIN)
10567     {
10568       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10569       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10570       rtx tmplabrtx;
10571       char tmplab[20];
10573       crtl->uses_pic_offset_table = 1;
10574       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10575                                   CODE_LABEL_NUMBER (operands[0]));
10576       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10578       emit_insn (gen_load_macho_picbase (tmplabrtx));
10579       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10580       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10581     }
10582   else
10583 #endif
10584     rs6000_emit_load_toc_table (FALSE);
10585   DONE;
10588 ;; Largetoc support
10589 (define_insn "*largetoc_high"
10590   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10591         (high:DI
10592           (unspec [(match_operand:DI 1 "" "")
10593                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10594                   UNSPEC_TOCREL)))]
10595    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10596    "addis %0,%2,%1@toc@ha")
10598 (define_insn "*largetoc_high_aix<mode>"
10599   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10600         (high:P
10601           (unspec [(match_operand:P 1 "" "")
10602                    (match_operand:P 2 "gpc_reg_operand" "b")]
10603                   UNSPEC_TOCREL)))]
10604    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10605    "addis %0,%1@u(%2)")
10607 (define_insn "*largetoc_high_plus"
10608   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10609         (high:DI
10610           (plus:DI
10611             (unspec [(match_operand:DI 1 "" "")
10612                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10613                     UNSPEC_TOCREL)
10614             (match_operand:DI 3 "add_cint_operand" "n"))))]
10615    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10616    "addis %0,%2,%1+%3@toc@ha")
10618 (define_insn "*largetoc_high_plus_aix<mode>"
10619   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10620         (high:P
10621           (plus:P
10622             (unspec [(match_operand:P 1 "" "")
10623                      (match_operand:P 2 "gpc_reg_operand" "b")]
10624                     UNSPEC_TOCREL)
10625             (match_operand:P 3 "add_cint_operand" "n"))))]
10626    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10627    "addis %0,%1+%3@u(%2)")
10629 (define_insn "*largetoc_low"
10630   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10631         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10632                    (match_operand:DI 2 "" "")))]
10633    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10634    "addi %0,%1,%2@l")
10636 (define_insn "*largetoc_low_aix<mode>"
10637   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10638         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10639                    (match_operand:P 2 "" "")))]
10640    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10641    "la %0,%2@l(%1)")
10643 (define_insn_and_split "*tocref<mode>"
10644   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10645         (match_operand:P 1 "small_toc_ref" "R"))]
10646    "TARGET_TOC"
10647    "la %0,%a1"
10648    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10649   [(set (match_dup 0) (high:P (match_dup 1)))
10650    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10652 ;; Elf specific ways of loading addresses for non-PIC code.
10653 ;; The output of this could be r0, but we make a very strong
10654 ;; preference for a base register because it will usually
10655 ;; be needed there.
10656 (define_insn "elf_high"
10657   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10658         (high:SI (match_operand 1 "" "")))]
10659   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10660   "lis %0,%1@ha")
10662 (define_insn "elf_low"
10663   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10664         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10665                    (match_operand 2 "" "")))]
10666    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10667    "la %0,%2@l(%1)")
10669 ;; Call and call_value insns
10670 (define_expand "call"
10671   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10672                     (match_operand 1 "" ""))
10673               (use (match_operand 2 "" ""))
10674               (clobber (reg:SI LR_REGNO))])]
10675   ""
10676   "
10678 #if TARGET_MACHO
10679   if (MACHOPIC_INDIRECT)
10680     operands[0] = machopic_indirect_call_target (operands[0]);
10681 #endif
10683   gcc_assert (GET_CODE (operands[0]) == MEM);
10684   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10686   operands[0] = XEXP (operands[0], 0);
10688   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10689     {
10690       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10691       DONE;
10692     }
10694   if (GET_CODE (operands[0]) != SYMBOL_REF
10695       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10696     {
10697       if (INTVAL (operands[2]) & CALL_LONG)
10698         operands[0] = rs6000_longcall_ref (operands[0]);
10700       switch (DEFAULT_ABI)
10701         {
10702         case ABI_V4:
10703         case ABI_DARWIN:
10704           operands[0] = force_reg (Pmode, operands[0]);
10705           break;
10707         default:
10708           gcc_unreachable ();
10709         }
10710     }
10713 (define_expand "call_value"
10714   [(parallel [(set (match_operand 0 "" "")
10715                    (call (mem:SI (match_operand 1 "address_operand" ""))
10716                          (match_operand 2 "" "")))
10717               (use (match_operand 3 "" ""))
10718               (clobber (reg:SI LR_REGNO))])]
10719   ""
10720   "
10722 #if TARGET_MACHO
10723   if (MACHOPIC_INDIRECT)
10724     operands[1] = machopic_indirect_call_target (operands[1]);
10725 #endif
10727   gcc_assert (GET_CODE (operands[1]) == MEM);
10728   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10730   operands[1] = XEXP (operands[1], 0);
10732   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10733     {
10734       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10735       DONE;
10736     }
10738   if (GET_CODE (operands[1]) != SYMBOL_REF
10739       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10740     {
10741       if (INTVAL (operands[3]) & CALL_LONG)
10742         operands[1] = rs6000_longcall_ref (operands[1]);
10744       switch (DEFAULT_ABI)
10745         {
10746         case ABI_V4:
10747         case ABI_DARWIN:
10748           operands[1] = force_reg (Pmode, operands[1]);
10749           break;
10751         default:
10752           gcc_unreachable ();
10753         }
10754     }
10757 ;; Call to function in current module.  No TOC pointer reload needed.
10758 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10759 ;; either the function was not prototyped, or it was prototyped as a
10760 ;; variable argument function.  It is > 0 if FP registers were passed
10761 ;; and < 0 if they were not.
10763 (define_insn "*call_local32"
10764   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10765          (match_operand 1 "" "g,g"))
10766    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10767    (clobber (reg:SI LR_REGNO))]
10768   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10769   "*
10771   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10772     output_asm_insn (\"crxor 6,6,6\", operands);
10774   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10775     output_asm_insn (\"creqv 6,6,6\", operands);
10777   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10779   [(set_attr "type" "branch")
10780    (set_attr "length" "4,8")])
10782 (define_insn "*call_local64"
10783   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10784          (match_operand 1 "" "g,g"))
10785    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10786    (clobber (reg:SI LR_REGNO))]
10787   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10788   "*
10790   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10791     output_asm_insn (\"crxor 6,6,6\", operands);
10793   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10794     output_asm_insn (\"creqv 6,6,6\", operands);
10796   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10798   [(set_attr "type" "branch")
10799    (set_attr "length" "4,8")])
10801 (define_insn "*call_value_local32"
10802   [(set (match_operand 0 "" "")
10803         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10804               (match_operand 2 "" "g,g")))
10805    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10806    (clobber (reg:SI LR_REGNO))]
10807   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10808   "*
10810   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10811     output_asm_insn (\"crxor 6,6,6\", operands);
10813   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10814     output_asm_insn (\"creqv 6,6,6\", operands);
10816   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10818   [(set_attr "type" "branch")
10819    (set_attr "length" "4,8")])
10822 (define_insn "*call_value_local64"
10823   [(set (match_operand 0 "" "")
10824         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10825               (match_operand 2 "" "g,g")))
10826    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10827    (clobber (reg:SI LR_REGNO))]
10828   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10829   "*
10831   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10832     output_asm_insn (\"crxor 6,6,6\", operands);
10834   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10835     output_asm_insn (\"creqv 6,6,6\", operands);
10837   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10839   [(set_attr "type" "branch")
10840    (set_attr "length" "4,8")])
10843 ;; A function pointer under System V is just a normal pointer
10844 ;; operands[0] is the function pointer
10845 ;; operands[1] is the stack size to clean up
10846 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10847 ;; which indicates how to set cr1
10849 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10850   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10851          (match_operand 1 "" "g,g,g,g"))
10852    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10853    (clobber (reg:SI LR_REGNO))]
10854   "DEFAULT_ABI == ABI_V4
10855    || DEFAULT_ABI == ABI_DARWIN"
10857   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10858     output_asm_insn ("crxor 6,6,6", operands);
10860   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10861     output_asm_insn ("creqv 6,6,6", operands);
10863   return "b%T0l";
10865   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10866    (set_attr "length" "4,4,8,8")])
10868 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10869   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10870          (match_operand 1 "" "g,g"))
10871    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10872    (clobber (reg:SI LR_REGNO))]
10873   "(DEFAULT_ABI == ABI_DARWIN
10874    || (DEFAULT_ABI == ABI_V4
10875        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10877   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10878     output_asm_insn ("crxor 6,6,6", operands);
10880   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10881     output_asm_insn ("creqv 6,6,6", operands);
10883 #if TARGET_MACHO
10884   return output_call(insn, operands, 0, 2);
10885 #else
10886   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10887     {
10888       gcc_assert (!TARGET_SECURE_PLT);
10889       return "bl %z0@plt";
10890     }
10891   else
10892     return "bl %z0";
10893 #endif
10895   "DEFAULT_ABI == ABI_V4
10896    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10897    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10898   [(parallel [(call (mem:SI (match_dup 0))
10899                     (match_dup 1))
10900               (use (match_dup 2))
10901               (use (match_dup 3))
10902               (clobber (reg:SI LR_REGNO))])]
10904   operands[3] = pic_offset_table_rtx;
10906   [(set_attr "type" "branch,branch")
10907    (set_attr "length" "4,8")])
10909 (define_insn "*call_nonlocal_sysv_secure<mode>"
10910   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10911          (match_operand 1 "" "g,g"))
10912    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10913    (use (match_operand:SI 3 "register_operand" "r,r"))
10914    (clobber (reg:SI LR_REGNO))]
10915   "(DEFAULT_ABI == ABI_V4
10916     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10917     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10919   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10920     output_asm_insn ("crxor 6,6,6", operands);
10922   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10923     output_asm_insn ("creqv 6,6,6", operands);
10925   if (flag_pic == 2)
10926     /* The magic 32768 offset here and in the other sysv call insns
10927        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10928        See sysv4.h:toc_section.  */
10929     return "bl %z0+32768@plt";
10930   else
10931     return "bl %z0@plt";
10933   [(set_attr "type" "branch,branch")
10934    (set_attr "length" "4,8")])
10936 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10937   [(set (match_operand 0 "" "")
10938         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10939               (match_operand 2 "" "g,g,g,g")))
10940    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10941    (clobber (reg:SI LR_REGNO))]
10942   "DEFAULT_ABI == ABI_V4
10943    || DEFAULT_ABI == ABI_DARWIN"
10945   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10946     output_asm_insn ("crxor 6,6,6", operands);
10948   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10949     output_asm_insn ("creqv 6,6,6", operands);
10951   return "b%T1l";
10953   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10954    (set_attr "length" "4,4,8,8")])
10956 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10957   [(set (match_operand 0 "" "")
10958         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10959               (match_operand 2 "" "g,g")))
10960    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10961    (clobber (reg:SI LR_REGNO))]
10962   "(DEFAULT_ABI == ABI_DARWIN
10963    || (DEFAULT_ABI == ABI_V4
10964        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10966   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10967     output_asm_insn ("crxor 6,6,6", operands);
10969   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10970     output_asm_insn ("creqv 6,6,6", operands);
10972 #if TARGET_MACHO
10973   return output_call(insn, operands, 1, 3);
10974 #else
10975   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10976     {
10977       gcc_assert (!TARGET_SECURE_PLT);
10978       return "bl %z1@plt";
10979     }
10980   else
10981     return "bl %z1";
10982 #endif
10984   "DEFAULT_ABI == ABI_V4
10985    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10986    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10987   [(parallel [(set (match_dup 0)
10988                    (call (mem:SI (match_dup 1))
10989                          (match_dup 2)))
10990               (use (match_dup 3))
10991               (use (match_dup 4))
10992               (clobber (reg:SI LR_REGNO))])]
10994   operands[4] = pic_offset_table_rtx;
10996   [(set_attr "type" "branch,branch")
10997    (set_attr "length" "4,8")])
10999 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11000   [(set (match_operand 0 "" "")
11001         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11002               (match_operand 2 "" "g,g")))
11003    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11004    (use (match_operand:SI 4 "register_operand" "r,r"))
11005    (clobber (reg:SI LR_REGNO))]
11006   "(DEFAULT_ABI == ABI_V4
11007     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11008     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11010   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11011     output_asm_insn ("crxor 6,6,6", operands);
11013   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11014     output_asm_insn ("creqv 6,6,6", operands);
11016   if (flag_pic == 2)
11017     return "bl %z1+32768@plt";
11018   else
11019     return "bl %z1@plt";
11021   [(set_attr "type" "branch,branch")
11022    (set_attr "length" "4,8")])
11025 ;; Call to AIX abi function in the same module.
11027 (define_insn "*call_local_aix<mode>"
11028   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11029          (match_operand 1 "" "g"))
11030    (clobber (reg:P LR_REGNO))]
11031   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11032   "bl %z0"
11033   [(set_attr "type" "branch")
11034    (set_attr "length" "4")])
11036 (define_insn "*call_value_local_aix<mode>"
11037   [(set (match_operand 0 "" "")
11038         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11039               (match_operand 2 "" "g")))
11040    (clobber (reg:P LR_REGNO))]
11041   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11042   "bl %z1"
11043   [(set_attr "type" "branch")
11044    (set_attr "length" "4")])
11046 ;; Call to AIX abi function which may be in another module.
11047 ;; Restore the TOC pointer (r2) after the call.
11049 (define_insn "*call_nonlocal_aix<mode>"
11050   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11051          (match_operand 1 "" "g"))
11052    (clobber (reg:P LR_REGNO))]
11053   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11054   "bl %z0\;nop"
11055   [(set_attr "type" "branch")
11056    (set_attr "length" "8")])
11058 (define_insn "*call_value_nonlocal_aix<mode>"
11059   [(set (match_operand 0 "" "")
11060         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11061               (match_operand 2 "" "g")))
11062    (clobber (reg:P LR_REGNO))]
11063   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11064   "bl %z1\;nop"
11065   [(set_attr "type" "branch")
11066    (set_attr "length" "8")])
11068 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11069 ;; Operand0 is the addresss of the function to call
11070 ;; Operand2 is the location in the function descriptor to load r2 from
11071 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11073 (define_insn "*call_indirect_aix<mode>"
11074   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11075          (match_operand 1 "" "g,g"))
11076    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11077    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11078    (clobber (reg:P LR_REGNO))]
11079   "DEFAULT_ABI == ABI_AIX"
11080   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11081   [(set_attr "type" "jmpreg")
11082    (set_attr "length" "12")])
11084 (define_insn "*call_value_indirect_aix<mode>"
11085   [(set (match_operand 0 "" "")
11086         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11087               (match_operand 2 "" "g,g")))
11088    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11089    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11090    (clobber (reg:P LR_REGNO))]
11091   "DEFAULT_ABI == ABI_AIX"
11092   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11093   [(set_attr "type" "jmpreg")
11094    (set_attr "length" "12")])
11096 ;; Call to indirect functions with the ELFv2 ABI.
11097 ;; Operand0 is the addresss of the function to call
11098 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11100 (define_insn "*call_indirect_elfv2<mode>"
11101   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11102          (match_operand 1 "" "g,g"))
11103    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11104    (clobber (reg:P LR_REGNO))]
11105   "DEFAULT_ABI == ABI_ELFv2"
11106   "b%T0l\;<ptrload> 2,%2(1)"
11107   [(set_attr "type" "jmpreg")
11108    (set_attr "length" "8")])
11110 (define_insn "*call_value_indirect_elfv2<mode>"
11111   [(set (match_operand 0 "" "")
11112         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11113               (match_operand 2 "" "g,g")))
11114    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11115    (clobber (reg:P LR_REGNO))]
11116   "DEFAULT_ABI == ABI_ELFv2"
11117   "b%T1l\;<ptrload> 2,%3(1)"
11118   [(set_attr "type" "jmpreg")
11119    (set_attr "length" "8")])
11122 ;; Call subroutine returning any type.
11123 (define_expand "untyped_call"
11124   [(parallel [(call (match_operand 0 "" "")
11125                     (const_int 0))
11126               (match_operand 1 "" "")
11127               (match_operand 2 "" "")])]
11128   ""
11129   "
11131   int i;
11133   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11135   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11136     {
11137       rtx set = XVECEXP (operands[2], 0, i);
11138       emit_move_insn (SET_DEST (set), SET_SRC (set));
11139     }
11141   /* The optimizer does not know that the call sets the function value
11142      registers we stored in the result block.  We avoid problems by
11143      claiming that all hard registers are used and clobbered at this
11144      point.  */
11145   emit_insn (gen_blockage ());
11147   DONE;
11150 ;; sibling call patterns
11151 (define_expand "sibcall"
11152   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11153                     (match_operand 1 "" ""))
11154               (use (match_operand 2 "" ""))
11155               (simple_return)])]
11156   ""
11157   "
11159 #if TARGET_MACHO
11160   if (MACHOPIC_INDIRECT)
11161     operands[0] = machopic_indirect_call_target (operands[0]);
11162 #endif
11164   gcc_assert (GET_CODE (operands[0]) == MEM);
11165   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11167   operands[0] = XEXP (operands[0], 0);
11169   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11170     {
11171       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11172       DONE;
11173     }
11176 (define_expand "sibcall_value"
11177   [(parallel [(set (match_operand 0 "register_operand" "")
11178                 (call (mem:SI (match_operand 1 "address_operand" ""))
11179                       (match_operand 2 "" "")))
11180               (use (match_operand 3 "" ""))
11181               (simple_return)])]
11182   ""
11183   "
11185 #if TARGET_MACHO
11186   if (MACHOPIC_INDIRECT)
11187     operands[1] = machopic_indirect_call_target (operands[1]);
11188 #endif
11190   gcc_assert (GET_CODE (operands[1]) == MEM);
11191   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11193   operands[1] = XEXP (operands[1], 0);
11195   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11196     {
11197       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11198       DONE;
11199     }
11202 (define_insn "*sibcall_local32"
11203   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11204          (match_operand 1 "" "g,g"))
11205    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11206    (simple_return)]
11207   "(INTVAL (operands[2]) & CALL_LONG) == 0"
11208   "*
11210   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11211     output_asm_insn (\"crxor 6,6,6\", operands);
11213   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11214     output_asm_insn (\"creqv 6,6,6\", operands);
11216   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11218   [(set_attr "type" "branch")
11219    (set_attr "length" "4,8")])
11221 (define_insn "*sibcall_local64"
11222   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11223          (match_operand 1 "" "g,g"))
11224    (use (match_operand:SI 2 "immediate_operand" "O,n"))
11225    (simple_return)]
11226   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11227   "*
11229   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11230     output_asm_insn (\"crxor 6,6,6\", operands);
11232   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11233     output_asm_insn (\"creqv 6,6,6\", operands);
11235   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11237   [(set_attr "type" "branch")
11238    (set_attr "length" "4,8")])
11240 (define_insn "*sibcall_value_local32"
11241   [(set (match_operand 0 "" "")
11242         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11243               (match_operand 2 "" "g,g")))
11244    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11245    (simple_return)]
11246   "(INTVAL (operands[3]) & CALL_LONG) == 0"
11247   "*
11249   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11250     output_asm_insn (\"crxor 6,6,6\", operands);
11252   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11253     output_asm_insn (\"creqv 6,6,6\", operands);
11255   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11257   [(set_attr "type" "branch")
11258    (set_attr "length" "4,8")])
11260 (define_insn "*sibcall_value_local64"
11261   [(set (match_operand 0 "" "")
11262         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11263               (match_operand 2 "" "g,g")))
11264    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11265    (simple_return)]
11266   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11267   "*
11269   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11270     output_asm_insn (\"crxor 6,6,6\", operands);
11272   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11273     output_asm_insn (\"creqv 6,6,6\", operands);
11275   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11277   [(set_attr "type" "branch")
11278    (set_attr "length" "4,8")])
11280 (define_insn "*sibcall_nonlocal_sysv<mode>"
11281   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11282          (match_operand 1 "" ""))
11283    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11284    (simple_return)]
11285   "(DEFAULT_ABI == ABI_DARWIN
11286     || DEFAULT_ABI == ABI_V4)
11287    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11288   "*
11290   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11291     output_asm_insn (\"crxor 6,6,6\", operands);
11293   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11294     output_asm_insn (\"creqv 6,6,6\", operands);
11296   if (which_alternative >= 2)
11297     return \"b%T0\";
11298   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11299     {
11300       gcc_assert (!TARGET_SECURE_PLT);
11301       return \"b %z0@plt\";
11302     }
11303   else
11304     return \"b %z0\";
11306   [(set_attr "type" "branch")
11307    (set_attr "length" "4,8,4,8")])
11309 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11310   [(set (match_operand 0 "" "")
11311         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11312               (match_operand 2 "" "")))
11313    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11314    (simple_return)]
11315   "(DEFAULT_ABI == ABI_DARWIN
11316     || DEFAULT_ABI == ABI_V4)
11317    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11318   "*
11320   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11321     output_asm_insn (\"crxor 6,6,6\", operands);
11323   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11324     output_asm_insn (\"creqv 6,6,6\", operands);
11326   if (which_alternative >= 2)
11327     return \"b%T1\";
11328   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11329     {
11330       gcc_assert (!TARGET_SECURE_PLT);
11331       return \"b %z1@plt\";
11332     }
11333   else
11334     return \"b %z1\";
11336   [(set_attr "type" "branch")
11337    (set_attr "length" "4,8,4,8")])
11339 ;; AIX ABI sibling call patterns.
11341 (define_insn "*sibcall_aix<mode>"
11342   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11343          (match_operand 1 "" "g,g"))
11344    (simple_return)]
11345   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11346   "@
11347    b %z0
11348    b%T0"
11349   [(set_attr "type" "branch")
11350    (set_attr "length" "4")])
11352 (define_insn "*sibcall_value_aix<mode>"
11353   [(set (match_operand 0 "" "")
11354         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11355               (match_operand 2 "" "g,g")))
11356    (simple_return)]
11357   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11358   "@
11359    b %z1
11360    b%T1"
11361   [(set_attr "type" "branch")
11362    (set_attr "length" "4")])
11364 (define_expand "sibcall_epilogue"
11365   [(use (const_int 0))]
11366   ""
11368   if (!TARGET_SCHED_PROLOG)
11369     emit_insn (gen_blockage ());
11370   rs6000_emit_epilogue (TRUE);
11371   DONE;
11374 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11375 ;; all of memory.  This blocks insns from being moved across this point.
11377 (define_insn "blockage"
11378   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11379   ""
11380   "")
11382 (define_expand "probe_stack_address"
11383   [(use (match_operand 0 "address_operand"))]
11384   ""
11386   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11387   MEM_VOLATILE_P (operands[0]) = 1;
11389   if (TARGET_64BIT)
11390     emit_insn (gen_probe_stack_di (operands[0]));
11391   else
11392     emit_insn (gen_probe_stack_si (operands[0]));
11393   DONE;
11396 (define_insn "probe_stack_<mode>"
11397   [(set (match_operand:P 0 "memory_operand" "=m")
11398         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11399   ""
11401   operands[1] = gen_rtx_REG (Pmode, 0);
11402   return "st<wd>%U0%X0 %1,%0";
11404   [(set_attr "type" "store")
11405    (set (attr "update")
11406         (if_then_else (match_operand 0 "update_address_mem")
11407                       (const_string "yes")
11408                       (const_string "no")))
11409    (set (attr "indexed")
11410         (if_then_else (match_operand 0 "indexed_address_mem")
11411                       (const_string "yes")
11412                       (const_string "no")))
11413    (set_attr "length" "4")])
11415 (define_insn "probe_stack_range<P:mode>"
11416   [(set (match_operand:P 0 "register_operand" "=r")
11417         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11418                             (match_operand:P 2 "register_operand" "r")]
11419                            UNSPECV_PROBE_STACK_RANGE))]
11420   ""
11421   "* return output_probe_stack_range (operands[0], operands[2]);"
11422   [(set_attr "type" "three")])
11424 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11425 ;; signed & unsigned, and one type of branch.
11427 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11428 ;; insns, and branches.
11430 (define_expand "cbranch<mode>4"
11431   [(use (match_operator 0 "comparison_operator"
11432          [(match_operand:GPR 1 "gpc_reg_operand" "")
11433           (match_operand:GPR 2 "reg_or_short_operand" "")]))
11434    (use (match_operand 3 ""))]
11435   ""
11436   "
11438   /* Take care of the possibility that operands[2] might be negative but
11439      this might be a logical operation.  That insn doesn't exist.  */
11440   if (GET_CODE (operands[2]) == CONST_INT
11441       && INTVAL (operands[2]) < 0)
11442     {
11443       operands[2] = force_reg (<MODE>mode, operands[2]);
11444       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11445                                     GET_MODE (operands[0]),
11446                                     operands[1], operands[2]);
11447    }
11449   rs6000_emit_cbranch (<MODE>mode, operands);
11450   DONE;
11453 (define_expand "cbranch<mode>4"
11454   [(use (match_operator 0 "comparison_operator"
11455          [(match_operand:FP 1 "gpc_reg_operand" "")
11456           (match_operand:FP 2 "gpc_reg_operand" "")]))
11457    (use (match_operand 3 ""))]
11458   ""
11459   "
11461   rs6000_emit_cbranch (<MODE>mode, operands);
11462   DONE;
11465 (define_expand "cstore<mode>4_signed"
11466   [(use (match_operator 1 "signed_comparison_operator"
11467          [(match_operand:P 2 "gpc_reg_operand")
11468           (match_operand:P 3 "gpc_reg_operand")]))
11469    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11470   ""
11472   enum rtx_code cond_code = GET_CODE (operands[1]);
11474   rtx op0 = operands[0];
11475   rtx op1 = operands[2];
11476   rtx op2 = operands[3];
11478   if (cond_code == GE || cond_code == LT)
11479     {
11480       cond_code = swap_condition (cond_code);
11481       std::swap (op1, op2);
11482     }
11484   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11485   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11486   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11488   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11489   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11490   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11492   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11494   if (cond_code == LE)
11495     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11496   else
11497     {
11498       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11499       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11500       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11501     }
11503   DONE;
11506 (define_expand "cstore<mode>4_unsigned"
11507   [(use (match_operator 1 "unsigned_comparison_operator"
11508          [(match_operand:P 2 "gpc_reg_operand")
11509           (match_operand:P 3 "reg_or_short_operand")]))
11510    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11511   ""
11513   enum rtx_code cond_code = GET_CODE (operands[1]);
11515   rtx op0 = operands[0];
11516   rtx op1 = operands[2];
11517   rtx op2 = operands[3];
11519   if (cond_code == GEU || cond_code == LTU)
11520     {
11521       cond_code = swap_condition (cond_code);
11522       std::swap (op1, op2);
11523     }
11525   if (!gpc_reg_operand (op1, <MODE>mode))
11526     op1 = force_reg (<MODE>mode, op1);
11527   if (!reg_or_short_operand (op2, <MODE>mode))
11528     op2 = force_reg (<MODE>mode, op2);
11530   rtx tmp = gen_reg_rtx (<MODE>mode);
11531   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11533   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11534   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11536   if (cond_code == LEU)
11537     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11538   else
11539     emit_insn (gen_neg<mode>2 (op0, tmp2));
11541   DONE;
11544 (define_expand "cstore_si_as_di"
11545   [(use (match_operator 1 "unsigned_comparison_operator"
11546          [(match_operand:SI 2 "gpc_reg_operand")
11547           (match_operand:SI 3 "reg_or_short_operand")]))
11548    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11549   ""
11551   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11552   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11554   operands[2] = force_reg (SImode, operands[2]);
11555   operands[3] = force_reg (SImode, operands[3]);
11556   rtx op1 = gen_reg_rtx (DImode);
11557   rtx op2 = gen_reg_rtx (DImode);
11558   convert_move (op1, operands[2], uns_flag);
11559   convert_move (op2, operands[3], uns_flag);
11561   if (cond_code == GT || cond_code == LE)
11562     {
11563       cond_code = swap_condition (cond_code);
11564       std::swap (op1, op2);
11565     }
11567   rtx tmp = gen_reg_rtx (DImode);
11568   rtx tmp2 = gen_reg_rtx (DImode);
11569   emit_insn (gen_subdi3 (tmp, op1, op2));
11570   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11572   rtx tmp3;
11573   switch (cond_code)
11574     {
11575     default:
11576       gcc_unreachable ();
11577     case LT:
11578       tmp3 = tmp2;
11579       break;
11580     case GE:
11581       tmp3 = gen_reg_rtx (DImode);
11582       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11583       break;
11584     }
11586   convert_move (operands[0], tmp3, 1);
11588   DONE;
11591 (define_expand "cstore<mode>4_signed_imm"
11592   [(use (match_operator 1 "signed_comparison_operator"
11593          [(match_operand:GPR 2 "gpc_reg_operand")
11594           (match_operand:GPR 3 "immediate_operand")]))
11595    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11596   ""
11598   bool invert = false;
11600   enum rtx_code cond_code = GET_CODE (operands[1]);
11602   rtx op0 = operands[0];
11603   rtx op1 = operands[2];
11604   HOST_WIDE_INT val = INTVAL (operands[3]);
11606   if (cond_code == GE || cond_code == GT)
11607     {
11608       cond_code = reverse_condition (cond_code);
11609       invert = true;
11610     }
11612   if (cond_code == LE)
11613     val++;
11615   rtx tmp = gen_reg_rtx (<MODE>mode);
11616   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11617   rtx x = gen_reg_rtx (<MODE>mode);
11618   if (val < 0)
11619     emit_insn (gen_and<mode>3 (x, op1, tmp));
11620   else
11621     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11623   if (invert)
11624     {
11625       rtx tmp = gen_reg_rtx (<MODE>mode);
11626       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11627       x = tmp;
11628     }
11630   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11631   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11633   DONE;
11636 (define_expand "cstore<mode>4_unsigned_imm"
11637   [(use (match_operator 1 "unsigned_comparison_operator"
11638          [(match_operand:GPR 2 "gpc_reg_operand")
11639           (match_operand:GPR 3 "immediate_operand")]))
11640    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11641   ""
11643   bool invert = false;
11645   enum rtx_code cond_code = GET_CODE (operands[1]);
11647   rtx op0 = operands[0];
11648   rtx op1 = operands[2];
11649   HOST_WIDE_INT val = INTVAL (operands[3]);
11651   if (cond_code == GEU || cond_code == GTU)
11652     {
11653       cond_code = reverse_condition (cond_code);
11654       invert = true;
11655     }
11657   if (cond_code == LEU)
11658     val++;
11660   rtx tmp = gen_reg_rtx (<MODE>mode);
11661   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11662   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11663   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11664   rtx x = gen_reg_rtx (<MODE>mode);
11665   if (val < 0)
11666     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11667   else
11668     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11670   if (invert)
11671     {
11672       rtx tmp = gen_reg_rtx (<MODE>mode);
11673       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11674       x = tmp;
11675     }
11677   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11678   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11680   DONE;
11683 (define_expand "cstore<mode>4"
11684   [(use (match_operator 1 "comparison_operator"
11685          [(match_operand:GPR 2 "gpc_reg_operand")
11686           (match_operand:GPR 3 "reg_or_short_operand")]))
11687    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11688   ""
11690   /* Use ISEL if the user asked for it.  */
11691   if (TARGET_ISEL)
11692     rs6000_emit_sISEL (<MODE>mode, operands);
11694   /* Expanding EQ and NE directly to some machine instructions does not help
11695      but does hurt combine.  So don't.  */
11696   else if (GET_CODE (operands[1]) == EQ)
11697     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11698   else if (<MODE>mode == Pmode
11699            && GET_CODE (operands[1]) == NE)
11700     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11701   else if (GET_CODE (operands[1]) == NE)
11702     {
11703       rtx tmp = gen_reg_rtx (<MODE>mode);
11704       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11705       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11706     }
11708   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11709      etc. combinations magically work out just right.  */
11710   else if (<MODE>mode == Pmode
11711            && unsigned_comparison_operator (operands[1], VOIDmode))
11712     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11713                                            operands[2], operands[3]));
11715   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11716   else if (<MODE>mode == SImode && Pmode == DImode)
11717     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11718                                     operands[2], operands[3]));
11720   /* For signed comparisons against a constant, we can do some simple
11721      bit-twiddling.  */
11722   else if (signed_comparison_operator (operands[1], VOIDmode)
11723            && CONST_INT_P (operands[3]))
11724     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11725                                              operands[2], operands[3]));
11727   /* And similarly for unsigned comparisons.  */
11728   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11729            && CONST_INT_P (operands[3]))
11730     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11731                                                operands[2], operands[3]));
11733   /* We also do not want to use mfcr for signed comparisons.  */
11734   else if (<MODE>mode == Pmode
11735            && signed_comparison_operator (operands[1], VOIDmode))
11736     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11737                                          operands[2], operands[3]));
11739   /* Everything else, use the mfcr brute force.  */
11740   else
11741     rs6000_emit_sCOND (<MODE>mode, operands);
11743   DONE;
11746 (define_expand "cstore<mode>4"
11747   [(use (match_operator 1 "comparison_operator"
11748          [(match_operand:FP 2 "gpc_reg_operand")
11749           (match_operand:FP 3 "gpc_reg_operand")]))
11750    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11751   ""
11753   rs6000_emit_sCOND (<MODE>mode, operands);
11754   DONE;
11758 (define_expand "stack_protect_set"
11759   [(match_operand 0 "memory_operand")
11760    (match_operand 1 "memory_operand")]
11761   ""
11763   if (rs6000_stack_protector_guard == SSP_TLS)
11764     {
11765       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11766       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11767       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11768       operands[1] = gen_rtx_MEM (Pmode, addr);
11769     }
11771   if (TARGET_64BIT)
11772     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11773   else
11774     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11776   DONE;
11779 (define_insn "stack_protect_setsi"
11780   [(set (match_operand:SI 0 "memory_operand" "=m")
11781         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11782    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11783   "TARGET_32BIT"
11784   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11785   [(set_attr "type" "three")
11786    (set_attr "length" "12")])
11788 (define_insn "stack_protect_setdi"
11789   [(set (match_operand:DI 0 "memory_operand" "=Y")
11790         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11791    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11792   "TARGET_64BIT"
11793   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11794   [(set_attr "type" "three")
11795    (set_attr "length" "12")])
11797 (define_expand "stack_protect_test"
11798   [(match_operand 0 "memory_operand")
11799    (match_operand 1 "memory_operand")
11800    (match_operand 2 "")]
11801   ""
11803   rtx guard = operands[1];
11805   if (rs6000_stack_protector_guard == SSP_TLS)
11806     {
11807       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11808       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11809       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11810       guard = gen_rtx_MEM (Pmode, addr);
11811     }
11813   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11814   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11815   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11816   emit_jump_insn (jump);
11818   DONE;
11821 (define_insn "stack_protect_testsi"
11822   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11823         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11824                       (match_operand:SI 2 "memory_operand" "m,m")]
11825                      UNSPEC_SP_TEST))
11826    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11827    (clobber (match_scratch:SI 3 "=&r,&r"))]
11828   "TARGET_32BIT"
11829   "@
11830    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11831    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11832   [(set_attr "length" "16,20")])
11834 (define_insn "stack_protect_testdi"
11835   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11836         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11837                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11838                      UNSPEC_SP_TEST))
11839    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11840    (clobber (match_scratch:DI 3 "=&r,&r"))]
11841   "TARGET_64BIT"
11842   "@
11843    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11844    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11845   [(set_attr "length" "16,20")])
11848 ;; Here are the actual compare insns.
11849 (define_insn "*cmp<mode>_signed"
11850   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11851         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11852                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11853   ""
11854   "cmp<wd>%I2 %0,%1,%2"
11855   [(set_attr "type" "cmp")])
11857 (define_insn "*cmp<mode>_unsigned"
11858   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11859         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11860                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11861   ""
11862   "cmpl<wd>%I2 %0,%1,%2"
11863   [(set_attr "type" "cmp")])
11865 ;; If we are comparing a register for equality with a large constant,
11866 ;; we can do this with an XOR followed by a compare.  But this is profitable
11867 ;; only if the large constant is only used for the comparison (and in this
11868 ;; case we already have a register to reuse as scratch).
11870 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11871 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11873 (define_peephole2
11874   [(set (match_operand:SI 0 "register_operand")
11875         (match_operand:SI 1 "logical_const_operand" ""))
11876    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11877                        [(match_dup 0)
11878                         (match_operand:SI 2 "logical_const_operand" "")]))
11879    (set (match_operand:CC 4 "cc_reg_operand" "")
11880         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11881                     (match_dup 0)))
11882    (set (pc)
11883         (if_then_else (match_operator 6 "equality_operator"
11884                        [(match_dup 4) (const_int 0)])
11885                       (match_operand 7 "" "")
11886                       (match_operand 8 "" "")))]
11887   "peep2_reg_dead_p (3, operands[0])
11888    && peep2_reg_dead_p (4, operands[4])
11889    && REGNO (operands[0]) != REGNO (operands[5])"
11890  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11891   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11892   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11895   /* Get the constant we are comparing against, and see what it looks like
11896      when sign-extended from 16 to 32 bits.  Then see what constant we could
11897      XOR with SEXTC to get the sign-extended value.  */
11898   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11899                                               SImode,
11900                                               operands[1], operands[2]);
11901   HOST_WIDE_INT c = INTVAL (cnst);
11902   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11903   HOST_WIDE_INT xorv = c ^ sextc;
11905   operands[9] = GEN_INT (xorv);
11906   operands[10] = GEN_INT (sextc);
11909 ;; The following two insns don't exist as single insns, but if we provide
11910 ;; them, we can swap an add and compare, which will enable us to overlap more
11911 ;; of the required delay between a compare and branch.  We generate code for
11912 ;; them by splitting.
11914 (define_insn ""
11915   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11916         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11917                     (match_operand:SI 2 "short_cint_operand" "i")))
11918    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11919         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11920   ""
11921   "#"
11922   [(set_attr "length" "8")])
11924 (define_insn ""
11925   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11926         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11927                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11928    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11929         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11930   ""
11931   "#"
11932   [(set_attr "length" "8")])
11934 (define_split
11935   [(set (match_operand:CC 3 "cc_reg_operand" "")
11936         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11937                     (match_operand:SI 2 "short_cint_operand" "")))
11938    (set (match_operand:SI 0 "gpc_reg_operand" "")
11939         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11940   ""
11941   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11942    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11944 (define_split
11945   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11946         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11947                        (match_operand:SI 2 "u_short_cint_operand" "")))
11948    (set (match_operand:SI 0 "gpc_reg_operand" "")
11949         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11950   ""
11951   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11952    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11954 ;; Only need to compare second words if first words equal
11955 (define_insn "*cmp<mode>_internal1"
11956   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11957         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11958                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11959   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11960    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11961   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11962   [(set_attr "type" "fpcompare")
11963    (set_attr "length" "12")])
11965 (define_insn_and_split "*cmp<mode>_internal2"
11966   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11967         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11968                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11969     (clobber (match_scratch:DF 3 "=d"))
11970     (clobber (match_scratch:DF 4 "=d"))
11971     (clobber (match_scratch:DF 5 "=d"))
11972     (clobber (match_scratch:DF 6 "=d"))
11973     (clobber (match_scratch:DF 7 "=d"))
11974     (clobber (match_scratch:DF 8 "=d"))
11975     (clobber (match_scratch:DF 9 "=d"))
11976     (clobber (match_scratch:DF 10 "=d"))
11977     (clobber (match_scratch:GPR 11 "=b"))]
11978   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11979    && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11980   "#"
11981   "&& reload_completed"
11982   [(set (match_dup 3) (match_dup 14))
11983    (set (match_dup 4) (match_dup 15))
11984    (set (match_dup 9) (abs:DF (match_dup 5)))
11985    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11986    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11987                            (label_ref (match_dup 12))
11988                            (pc)))
11989    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11990    (set (pc) (label_ref (match_dup 13)))
11991    (match_dup 12)
11992    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11993    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11994    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11995    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11996    (match_dup 13)]
11998   REAL_VALUE_TYPE rv;
11999   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12000   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12002   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12003   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12004   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12005   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12006   operands[12] = gen_label_rtx ();
12007   operands[13] = gen_label_rtx ();
12008   real_inf (&rv);
12009   operands[14] = force_const_mem (DFmode,
12010                                   const_double_from_real_value (rv, DFmode));
12011   operands[15] = force_const_mem (DFmode,
12012                                   const_double_from_real_value (dconst0,
12013                                                                 DFmode));
12014   if (TARGET_TOC)
12015     {
12016       rtx tocref;
12017       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12018       operands[14] = gen_const_mem (DFmode, tocref);
12019       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12020       operands[15] = gen_const_mem (DFmode, tocref);
12021       set_mem_alias_set (operands[14], get_TOC_alias_set ());
12022       set_mem_alias_set (operands[15], get_TOC_alias_set ());
12023     }
12026 ;; Now we have the scc insns.  We can do some combinations because of the
12027 ;; way the machine works.
12029 ;; Note that this is probably faster if we can put an insn between the
12030 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
12031 ;; cases the insns below which don't use an intermediate CR field will
12032 ;; be used instead.
12033 (define_insn ""
12034   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12035         (match_operator:SI 1 "scc_comparison_operator"
12036                            [(match_operand 2 "cc_reg_operand" "y")
12037                             (const_int 0)]))]
12038   ""
12039   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12040   [(set (attr "type")
12041      (cond [(match_test "TARGET_MFCRF")
12042                 (const_string "mfcrf")
12043            ]
12044         (const_string "mfcr")))
12045    (set_attr "length" "8")])
12047 ;; Same as above, but get the OV/ORDERED bit.
12048 (define_insn "move_from_CR_ov_bit"
12049   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12050         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12051                    UNSPEC_MV_CR_OV))]
12052   "TARGET_ISEL"
12053   "mfcr %0\;rlwinm %0,%0,%t1,1"
12054   [(set_attr "type" "mfcr")
12055    (set_attr "length" "8")])
12057 (define_insn ""
12058   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12059         (match_operator:DI 1 "scc_comparison_operator"
12060                            [(match_operand 2 "cc_reg_operand" "y")
12061                             (const_int 0)]))]
12062   "TARGET_POWERPC64"
12063   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12064   [(set (attr "type")
12065      (cond [(match_test "TARGET_MFCRF")
12066                 (const_string "mfcrf")
12067            ]
12068         (const_string "mfcr")))
12069    (set_attr "length" "8")])
12071 (define_insn ""
12072   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12073         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12074                                        [(match_operand 2 "cc_reg_operand" "y,y")
12075                                         (const_int 0)])
12076                     (const_int 0)))
12077    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12078         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12079   "TARGET_32BIT"
12080   "@
12081    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12082    #"
12083   [(set_attr "type" "shift")
12084    (set_attr "dot" "yes")
12085    (set_attr "length" "8,16")])
12087 (define_split
12088   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12089         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12090                                        [(match_operand 2 "cc_reg_operand" "")
12091                                         (const_int 0)])
12092                     (const_int 0)))
12093    (set (match_operand:SI 3 "gpc_reg_operand" "")
12094         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12095   "TARGET_32BIT && reload_completed"
12096   [(set (match_dup 3)
12097         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12098    (set (match_dup 0)
12099         (compare:CC (match_dup 3)
12100                     (const_int 0)))]
12101   "")
12103 (define_insn ""
12104   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12105         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12106                                       [(match_operand 2 "cc_reg_operand" "y")
12107                                        (const_int 0)])
12108                    (match_operand:SI 3 "const_int_operand" "n")))]
12109   ""
12110   "*
12112   int is_bit = ccr_bit (operands[1], 1);
12113   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12114   int count;
12116   if (is_bit >= put_bit)
12117     count = is_bit - put_bit;
12118   else
12119     count = 32 - (put_bit - is_bit);
12121   operands[4] = GEN_INT (count);
12122   operands[5] = GEN_INT (put_bit);
12124   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12126   [(set (attr "type")
12127      (cond [(match_test "TARGET_MFCRF")
12128                 (const_string "mfcrf")
12129            ]
12130         (const_string "mfcr")))
12131    (set_attr "length" "8")])
12133 (define_insn ""
12134   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12135         (compare:CC
12136          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12137                                        [(match_operand 2 "cc_reg_operand" "y,y")
12138                                         (const_int 0)])
12139                     (match_operand:SI 3 "const_int_operand" "n,n"))
12140          (const_int 0)))
12141    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12142         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12143                    (match_dup 3)))]
12144   ""
12145   "*
12147   int is_bit = ccr_bit (operands[1], 1);
12148   int put_bit = 31 - (INTVAL (operands[3]) & 31);
12149   int count;
12151   /* Force split for non-cc0 compare.  */
12152   if (which_alternative == 1)
12153      return \"#\";
12155   if (is_bit >= put_bit)
12156     count = is_bit - put_bit;
12157   else
12158     count = 32 - (put_bit - is_bit);
12160   operands[5] = GEN_INT (count);
12161   operands[6] = GEN_INT (put_bit);
12163   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12165   [(set_attr "type" "shift")
12166    (set_attr "dot" "yes")
12167    (set_attr "length" "8,16")])
12169 (define_split
12170   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
12171         (compare:CC
12172          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12173                                        [(match_operand 2 "cc_reg_operand")
12174                                         (const_int 0)])
12175                     (match_operand:SI 3 "const_int_operand"))
12176          (const_int 0)))
12177    (set (match_operand:SI 4 "gpc_reg_operand")
12178         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12179                    (match_dup 3)))]
12180   "reload_completed"
12181   [(set (match_dup 4)
12182         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12183                    (match_dup 3)))
12184    (set (match_dup 0)
12185         (compare:CC (match_dup 4)
12186                     (const_int 0)))]
12187   "")
12190 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12191                               (DI "rKJI")])
12193 (define_insn_and_split "eq<mode>3"
12194   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12195         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12196                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12197    (clobber (match_scratch:GPR 3 "=r"))
12198    (clobber (match_scratch:GPR 4 "=r"))]
12199   ""
12200   "#"
12201   ""
12202   [(set (match_dup 4)
12203         (clz:GPR (match_dup 3)))
12204    (set (match_dup 0)
12205         (lshiftrt:GPR (match_dup 4)
12206                       (match_dup 5)))]
12208   operands[3] = rs6000_emit_eqne (<MODE>mode,
12209                                   operands[1], operands[2], operands[3]);
12211   if (GET_CODE (operands[4]) == SCRATCH)
12212     operands[4] = gen_reg_rtx (<MODE>mode);
12214   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12216   [(set (attr "length")
12217         (if_then_else (match_test "operands[2] == const0_rtx")
12218                       (const_string "8")
12219                       (const_string "12")))])
12221 (define_insn_and_split "ne<mode>3"
12222   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12223         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12224               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12225    (clobber (match_scratch:P 3 "=r"))
12226    (clobber (match_scratch:P 4 "=r"))
12227    (clobber (reg:P CA_REGNO))]
12228   "!TARGET_ISEL"
12229   "#"
12230   ""
12231   [(parallel [(set (match_dup 4)
12232                    (plus:P (match_dup 3)
12233                            (const_int -1)))
12234               (set (reg:P CA_REGNO)
12235                    (ne:P (match_dup 3)
12236                          (const_int 0)))])
12237    (parallel [(set (match_dup 0)
12238                    (plus:P (plus:P (not:P (match_dup 4))
12239                                    (reg:P CA_REGNO))
12240                            (match_dup 3)))
12241               (clobber (reg:P CA_REGNO))])]
12243   operands[3] = rs6000_emit_eqne (<MODE>mode,
12244                                   operands[1], operands[2], operands[3]);
12246   if (GET_CODE (operands[4]) == SCRATCH)
12247     operands[4] = gen_reg_rtx (<MODE>mode);
12249   [(set (attr "length")
12250         (if_then_else (match_test "operands[2] == const0_rtx")
12251                       (const_string "8")
12252                       (const_string "12")))])
12254 (define_insn_and_split "*neg_eq_<mode>"
12255   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12256         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12257                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12258    (clobber (match_scratch:P 3 "=r"))
12259    (clobber (match_scratch:P 4 "=r"))
12260    (clobber (reg:P CA_REGNO))]
12261   ""
12262   "#"
12263   ""
12264   [(parallel [(set (match_dup 4)
12265                    (plus:P (match_dup 3)
12266                            (const_int -1)))
12267               (set (reg:P CA_REGNO)
12268                    (ne:P (match_dup 3)
12269                          (const_int 0)))])
12270    (parallel [(set (match_dup 0)
12271                    (plus:P (reg:P CA_REGNO)
12272                            (const_int -1)))
12273               (clobber (reg:P CA_REGNO))])]
12275   operands[3] = rs6000_emit_eqne (<MODE>mode,
12276                                   operands[1], operands[2], operands[3]);
12278   if (GET_CODE (operands[4]) == SCRATCH)
12279     operands[4] = gen_reg_rtx (<MODE>mode);
12281   [(set (attr "length")
12282         (if_then_else (match_test "operands[2] == const0_rtx")
12283                       (const_string "8")
12284                       (const_string "12")))])
12286 (define_insn_and_split "*neg_ne_<mode>"
12287   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12288         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12289                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12290    (clobber (match_scratch:P 3 "=r"))
12291    (clobber (match_scratch:P 4 "=r"))
12292    (clobber (reg:P CA_REGNO))]
12293   ""
12294   "#"
12295   ""
12296   [(parallel [(set (match_dup 4)
12297                    (neg:P (match_dup 3)))
12298               (set (reg:P CA_REGNO)
12299                    (eq:P (match_dup 3)
12300                          (const_int 0)))])
12301    (parallel [(set (match_dup 0)
12302                    (plus:P (reg:P CA_REGNO)
12303                            (const_int -1)))
12304               (clobber (reg:P CA_REGNO))])]
12306   operands[3] = rs6000_emit_eqne (<MODE>mode,
12307                                   operands[1], operands[2], operands[3]);
12309   if (GET_CODE (operands[4]) == SCRATCH)
12310     operands[4] = gen_reg_rtx (<MODE>mode);
12312   [(set (attr "length")
12313         (if_then_else (match_test "operands[2] == const0_rtx")
12314                       (const_string "8")
12315                       (const_string "12")))])
12317 (define_insn_and_split "*plus_eq_<mode>"
12318   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12319         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12320                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12321                 (match_operand:P 3 "gpc_reg_operand" "r")))
12322    (clobber (match_scratch:P 4 "=r"))
12323    (clobber (match_scratch:P 5 "=r"))
12324    (clobber (reg:P CA_REGNO))]
12325   ""
12326   "#"
12327   ""
12328   [(parallel [(set (match_dup 5)
12329                    (neg:P (match_dup 4)))
12330               (set (reg:P CA_REGNO)
12331                    (eq:P (match_dup 4)
12332                          (const_int 0)))])
12333    (parallel [(set (match_dup 0)
12334                    (plus:P (match_dup 3)
12335                            (reg:P CA_REGNO)))
12336               (clobber (reg:P CA_REGNO))])]
12338   operands[4] = rs6000_emit_eqne (<MODE>mode,
12339                                   operands[1], operands[2], operands[4]);
12341   if (GET_CODE (operands[5]) == SCRATCH)
12342     operands[5] = gen_reg_rtx (<MODE>mode);
12344   [(set (attr "length")
12345         (if_then_else (match_test "operands[2] == const0_rtx")
12346                       (const_string "8")
12347                       (const_string "12")))])
12349 (define_insn_and_split "*plus_ne_<mode>"
12350   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12351         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12352                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12353                 (match_operand:P 3 "gpc_reg_operand" "r")))
12354    (clobber (match_scratch:P 4 "=r"))
12355    (clobber (match_scratch:P 5 "=r"))
12356    (clobber (reg:P CA_REGNO))]
12357   ""
12358   "#"
12359   ""
12360   [(parallel [(set (match_dup 5)
12361                    (plus:P (match_dup 4)
12362                            (const_int -1)))
12363               (set (reg:P CA_REGNO)
12364                    (ne:P (match_dup 4)
12365                          (const_int 0)))])
12366    (parallel [(set (match_dup 0)
12367                    (plus:P (match_dup 3)
12368                            (reg:P CA_REGNO)))
12369               (clobber (reg:P CA_REGNO))])]
12371   operands[4] = rs6000_emit_eqne (<MODE>mode,
12372                                   operands[1], operands[2], operands[4]);
12374   if (GET_CODE (operands[5]) == SCRATCH)
12375     operands[5] = gen_reg_rtx (<MODE>mode);
12377   [(set (attr "length")
12378         (if_then_else (match_test "operands[2] == const0_rtx")
12379                       (const_string "8")
12380                       (const_string "12")))])
12382 (define_insn_and_split "*minus_eq_<mode>"
12383   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12384         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12385                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12386                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12387    (clobber (match_scratch:P 4 "=r"))
12388    (clobber (match_scratch:P 5 "=r"))
12389    (clobber (reg:P CA_REGNO))]
12390   ""
12391   "#"
12392   ""
12393   [(parallel [(set (match_dup 5)
12394                    (plus:P (match_dup 4)
12395                            (const_int -1)))
12396               (set (reg:P CA_REGNO)
12397                    (ne:P (match_dup 4)
12398                          (const_int 0)))])
12399    (parallel [(set (match_dup 0)
12400                    (plus:P (plus:P (match_dup 3)
12401                                    (reg:P CA_REGNO))
12402                            (const_int -1)))
12403               (clobber (reg:P CA_REGNO))])]
12405   operands[4] = rs6000_emit_eqne (<MODE>mode,
12406                                   operands[1], operands[2], operands[4]);
12408   if (GET_CODE (operands[5]) == SCRATCH)
12409     operands[5] = gen_reg_rtx (<MODE>mode);
12411   [(set (attr "length")
12412         (if_then_else (match_test "operands[2] == const0_rtx")
12413                       (const_string "8")
12414                       (const_string "12")))])
12416 (define_insn_and_split "*minus_ne_<mode>"
12417   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12418         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12419                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12420                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12421    (clobber (match_scratch:P 4 "=r"))
12422    (clobber (match_scratch:P 5 "=r"))
12423    (clobber (reg:P CA_REGNO))]
12424   ""
12425   "#"
12426   ""
12427   [(parallel [(set (match_dup 5)
12428                    (neg:P (match_dup 4)))
12429               (set (reg:P CA_REGNO)
12430                    (eq:P (match_dup 4)
12431                          (const_int 0)))])
12432    (parallel [(set (match_dup 0)
12433                    (plus:P (plus:P (match_dup 3)
12434                                    (reg:P CA_REGNO))
12435                            (const_int -1)))
12436               (clobber (reg:P CA_REGNO))])]
12438   operands[4] = rs6000_emit_eqne (<MODE>mode,
12439                                   operands[1], operands[2], operands[4]);
12441   if (GET_CODE (operands[5]) == SCRATCH)
12442     operands[5] = gen_reg_rtx (<MODE>mode);
12444   [(set (attr "length")
12445         (if_then_else (match_test "operands[2] == const0_rtx")
12446                       (const_string "8")
12447                       (const_string "12")))])
12449 (define_insn_and_split "*eqsi3_ext<mode>"
12450   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12451         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12452                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12453    (clobber (match_scratch:SI 3 "=r"))
12454    (clobber (match_scratch:SI 4 "=r"))]
12455   ""
12456   "#"
12457   ""
12458   [(set (match_dup 4)
12459         (clz:SI (match_dup 3)))
12460    (set (match_dup 0)
12461         (zero_extend:EXTSI
12462           (lshiftrt:SI (match_dup 4)
12463                        (const_int 5))))]
12465   operands[3] = rs6000_emit_eqne (SImode,
12466                                   operands[1], operands[2], operands[3]);
12468   if (GET_CODE (operands[4]) == SCRATCH)
12469     operands[4] = gen_reg_rtx (SImode);
12471   [(set (attr "length")
12472         (if_then_else (match_test "operands[2] == const0_rtx")
12473                       (const_string "8")
12474                       (const_string "12")))])
12476 (define_insn_and_split "*nesi3_ext<mode>"
12477   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12478         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12479                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12480    (clobber (match_scratch:SI 3 "=r"))
12481    (clobber (match_scratch:SI 4 "=r"))
12482    (clobber (match_scratch:EXTSI 5 "=r"))]
12483   ""
12484   "#"
12485   ""
12486   [(set (match_dup 4)
12487         (clz:SI (match_dup 3)))
12488    (set (match_dup 5)
12489         (zero_extend:EXTSI
12490           (lshiftrt:SI (match_dup 4)
12491                        (const_int 5))))
12492    (set (match_dup 0)
12493         (xor:EXTSI (match_dup 5)
12494                    (const_int 1)))]
12496   operands[3] = rs6000_emit_eqne (SImode,
12497                                   operands[1], operands[2], operands[3]);
12499   if (GET_CODE (operands[4]) == SCRATCH)
12500     operands[4] = gen_reg_rtx (SImode);
12501   if (GET_CODE (operands[5]) == SCRATCH)
12502     operands[5] = gen_reg_rtx (<MODE>mode);
12504   [(set (attr "length")
12505         (if_then_else (match_test "operands[2] == const0_rtx")
12506                       (const_string "12")
12507                       (const_string "16")))])
12509 ;; Define both directions of branch and return.  If we need a reload
12510 ;; register, we'd rather use CR0 since it is much easier to copy a
12511 ;; register CC value to there.
12513 (define_insn ""
12514   [(set (pc)
12515         (if_then_else (match_operator 1 "branch_comparison_operator"
12516                                       [(match_operand 2
12517                                                       "cc_reg_operand" "y")
12518                                        (const_int 0)])
12519                       (label_ref (match_operand 0 "" ""))
12520                       (pc)))]
12521   ""
12522   "*
12524   return output_cbranch (operands[1], \"%l0\", 0, insn);
12526   [(set_attr "type" "branch")])
12528 (define_insn ""
12529   [(set (pc)
12530         (if_then_else (match_operator 0 "branch_comparison_operator"
12531                                       [(match_operand 1
12532                                                       "cc_reg_operand" "y")
12533                                        (const_int 0)])
12534                       (any_return)
12535                       (pc)))]
12536   "<return_pred>"
12537   "*
12539   return output_cbranch (operands[0], NULL, 0, insn);
12541   [(set_attr "type" "jmpreg")
12542    (set_attr "length" "4")])
12544 (define_insn ""
12545   [(set (pc)
12546         (if_then_else (match_operator 1 "branch_comparison_operator"
12547                                       [(match_operand 2
12548                                                       "cc_reg_operand" "y")
12549                                        (const_int 0)])
12550                       (pc)
12551                       (label_ref (match_operand 0 "" ""))))]
12552   ""
12553   "*
12555   return output_cbranch (operands[1], \"%l0\", 1, insn);
12557   [(set_attr "type" "branch")])
12559 (define_insn ""
12560   [(set (pc)
12561         (if_then_else (match_operator 0 "branch_comparison_operator"
12562                                       [(match_operand 1
12563                                                       "cc_reg_operand" "y")
12564                                        (const_int 0)])
12565                       (pc)
12566                       (any_return)))]
12567   "<return_pred>"
12568   "*
12570   return output_cbranch (operands[0], NULL, 1, insn);
12572   [(set_attr "type" "jmpreg")
12573    (set_attr "length" "4")])
12575 ;; Logic on condition register values.
12577 ; This pattern matches things like
12578 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12579 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12580 ;                                  (const_int 1)))
12581 ; which are generated by the branch logic.
12582 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12584 (define_insn "*cceq_ior_compare"
12585   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12586         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12587                         [(match_operator:SI 2
12588                                       "branch_positive_comparison_operator"
12589                                       [(match_operand 3
12590                                                       "cc_reg_operand" "y,y")
12591                                        (const_int 0)])
12592                          (match_operator:SI 4
12593                                       "branch_positive_comparison_operator"
12594                                       [(match_operand 5
12595                                                       "cc_reg_operand" "0,y")
12596                                        (const_int 0)])])
12597                       (const_int 1)))]
12598   ""
12599   "cr%q1 %E0,%j2,%j4"
12600   [(set_attr "type" "cr_logical,delayed_cr")])
12602 ; Why is the constant -1 here, but 1 in the previous pattern?
12603 ; Because ~1 has all but the low bit set.
12604 (define_insn ""
12605   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12606         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12607                         [(not:SI (match_operator:SI 2
12608                                       "branch_positive_comparison_operator"
12609                                       [(match_operand 3
12610                                                       "cc_reg_operand" "y,y")
12611                                        (const_int 0)]))
12612                          (match_operator:SI 4
12613                                 "branch_positive_comparison_operator"
12614                                 [(match_operand 5
12615                                                 "cc_reg_operand" "0,y")
12616                                  (const_int 0)])])
12617                       (const_int -1)))]
12618   ""
12619   "cr%q1 %E0,%j2,%j4"
12620   [(set_attr "type" "cr_logical,delayed_cr")])
12622 (define_insn "*cceq_rev_compare"
12623   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12624         (compare:CCEQ (match_operator:SI 1
12625                                       "branch_positive_comparison_operator"
12626                                       [(match_operand 2
12627                                                       "cc_reg_operand" "0,y")
12628                                        (const_int 0)])
12629                       (const_int 0)))]
12630   ""
12631   "crnot %E0,%j1"
12632   [(set_attr "type" "cr_logical,delayed_cr")])
12634 ;; If we are comparing the result of two comparisons, this can be done
12635 ;; using creqv or crxor.
12637 (define_insn_and_split ""
12638   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12639         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12640                               [(match_operand 2 "cc_reg_operand" "y")
12641                                (const_int 0)])
12642                       (match_operator 3 "branch_comparison_operator"
12643                               [(match_operand 4 "cc_reg_operand" "y")
12644                                (const_int 0)])))]
12645   ""
12646   "#"
12647   ""
12648   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12649                                     (match_dup 5)))]
12650   "
12652   int positive_1, positive_2;
12654   positive_1 = branch_positive_comparison_operator (operands[1],
12655                                                     GET_MODE (operands[1]));
12656   positive_2 = branch_positive_comparison_operator (operands[3],
12657                                                     GET_MODE (operands[3]));
12659   if (! positive_1)
12660     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12661                                                             GET_CODE (operands[1])),
12662                                   SImode,
12663                                   operands[2], const0_rtx);
12664   else if (GET_MODE (operands[1]) != SImode)
12665     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12666                                   operands[2], const0_rtx);
12668   if (! positive_2)
12669     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12670                                                             GET_CODE (operands[3])),
12671                                   SImode,
12672                                   operands[4], const0_rtx);
12673   else if (GET_MODE (operands[3]) != SImode)
12674     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12675                                   operands[4], const0_rtx);
12677   if (positive_1 == positive_2)
12678     {
12679       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12680       operands[5] = constm1_rtx;
12681     }
12682   else
12683     {
12684       operands[5] = const1_rtx;
12685     }
12688 ;; Unconditional branch and return.
12690 (define_insn "jump"
12691   [(set (pc)
12692         (label_ref (match_operand 0 "" "")))]
12693   ""
12694   "b %l0"
12695   [(set_attr "type" "branch")])
12697 (define_insn "<return_str>return"
12698   [(any_return)]
12699   "<return_pred>"
12700   "blr"
12701   [(set_attr "type" "jmpreg")])
12703 (define_expand "indirect_jump"
12704   [(set (pc) (match_operand 0 "register_operand" ""))])
12706 (define_insn "*indirect_jump<mode>"
12707   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12708   ""
12709   "@
12710    bctr
12711    blr"
12712   [(set_attr "type" "jmpreg")])
12714 ;; Table jump for switch statements:
12715 (define_expand "tablejump"
12716   [(use (match_operand 0 "" ""))
12717    (use (label_ref (match_operand 1 "" "")))]
12718   ""
12719   "
12721   if (TARGET_32BIT)
12722     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12723   else
12724     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12725   DONE;
12728 (define_expand "tablejumpsi"
12729   [(set (match_dup 3)
12730         (plus:SI (match_operand:SI 0 "" "")
12731                  (match_dup 2)))
12732    (parallel [(set (pc) (match_dup 3))
12733               (use (label_ref (match_operand 1 "" "")))])]
12734   "TARGET_32BIT"
12735   "
12736 { operands[0] = force_reg (SImode, operands[0]);
12737   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12738   operands[3] = gen_reg_rtx (SImode);
12741 (define_expand "tablejumpdi"
12742   [(set (match_dup 4)
12743         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12744    (set (match_dup 3)
12745         (plus:DI (match_dup 4)
12746                  (match_dup 2)))
12747    (parallel [(set (pc) (match_dup 3))
12748               (use (label_ref (match_operand 1 "" "")))])]
12749   "TARGET_64BIT"
12750   "
12751 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12752   operands[3] = gen_reg_rtx (DImode);
12753   operands[4] = gen_reg_rtx (DImode);
12756 (define_insn "*tablejump<mode>_internal1"
12757   [(set (pc)
12758         (match_operand:P 0 "register_operand" "c,*l"))
12759    (use (label_ref (match_operand 1 "" "")))]
12760   ""
12761   "@
12762    bctr
12763    blr"
12764   [(set_attr "type" "jmpreg")])
12766 (define_insn "nop"
12767   [(unspec [(const_int 0)] UNSPEC_NOP)]
12768   ""
12769   "nop")
12771 (define_insn "group_ending_nop"
12772   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12773   ""
12774   "*
12776   if (rs6000_cpu_attr == CPU_POWER6)
12777     return \"ori 1,1,0\";
12778   return \"ori 2,2,0\";
12781 ;; Define the subtract-one-and-jump insns, starting with the template
12782 ;; so loop.c knows what to generate.
12784 (define_expand "doloop_end"
12785   [(use (match_operand 0 "" ""))        ; loop pseudo
12786    (use (match_operand 1 "" ""))]       ; label
12787   ""
12788   "
12790   if (TARGET_64BIT)
12791     {
12792       if (GET_MODE (operands[0]) != DImode)
12793         FAIL;
12794       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12795     }
12796   else
12797     {
12798       if (GET_MODE (operands[0]) != SImode)
12799         FAIL;
12800       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12801     }
12802   DONE;
12805 (define_expand "ctr<mode>"
12806   [(parallel [(set (pc)
12807                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
12808                                      (const_int 1))
12809                                  (label_ref (match_operand 1 "" ""))
12810                                  (pc)))
12811               (set (match_dup 0)
12812                    (plus:P (match_dup 0)
12813                             (const_int -1)))
12814               (clobber (match_scratch:CC 2 ""))
12815               (clobber (match_scratch:P 3 ""))])]
12816   ""
12817   "")
12819 ;; We need to be able to do this for any operand, including MEM, or we
12820 ;; will cause reload to blow up since we don't allow output reloads on
12821 ;; JUMP_INSNs.
12822 ;; For the length attribute to be calculated correctly, the
12823 ;; label MUST be operand 0.
12824 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12825 ;; the ctr<mode> insns.
12827 (define_insn "ctr<mode>_internal1"
12828   [(set (pc)
12829         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12830                           (const_int 1))
12831                       (label_ref (match_operand 0 "" ""))
12832                       (pc)))
12833    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12834         (plus:P (match_dup 1)
12835                  (const_int -1)))
12836    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12837    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12838   ""
12839   "*
12841   if (which_alternative != 0)
12842     return \"#\";
12843   else if (get_attr_length (insn) == 4)
12844     return \"bdnz %l0\";
12845   else
12846     return \"bdz $+8\;b %l0\";
12848   [(set_attr "type" "branch")
12849    (set_attr "length" "*,16,20,20")])
12851 (define_insn "ctr<mode>_internal2"
12852   [(set (pc)
12853         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12854                           (const_int 1))
12855                       (pc)
12856                       (label_ref (match_operand 0 "" ""))))
12857    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12858         (plus:P (match_dup 1)
12859                  (const_int -1)))
12860    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12861    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12862   ""
12863   "*
12865   if (which_alternative != 0)
12866     return \"#\";
12867   else if (get_attr_length (insn) == 4)
12868     return \"bdz %l0\";
12869   else
12870     return \"bdnz $+8\;b %l0\";
12872   [(set_attr "type" "branch")
12873    (set_attr "length" "*,16,20,20")])
12875 ;; Similar but use EQ
12877 (define_insn "ctr<mode>_internal3"
12878   [(set (pc)
12879         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12880                           (const_int 1))
12881                       (label_ref (match_operand 0 "" ""))
12882                       (pc)))
12883    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12884         (plus:P (match_dup 1)
12885                  (const_int -1)))
12886    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12887    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12888   ""
12889   "*
12891   if (which_alternative != 0)
12892     return \"#\";
12893   else if (get_attr_length (insn) == 4)
12894     return \"bdz %l0\";
12895   else
12896     return \"bdnz $+8\;b %l0\";
12898   [(set_attr "type" "branch")
12899    (set_attr "length" "*,16,20,20")])
12901 (define_insn "ctr<mode>_internal4"
12902   [(set (pc)
12903         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12904                           (const_int 1))
12905                       (pc)
12906                       (label_ref (match_operand 0 "" ""))))
12907    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12908         (plus:P (match_dup 1)
12909                  (const_int -1)))
12910    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12911    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12912   ""
12913   "*
12915   if (which_alternative != 0)
12916     return \"#\";
12917   else if (get_attr_length (insn) == 4)
12918     return \"bdnz %l0\";
12919   else
12920     return \"bdz $+8\;b %l0\";
12922   [(set_attr "type" "branch")
12923    (set_attr "length" "*,16,20,20")])
12925 ;; Now the splitters if we could not allocate the CTR register
12927 (define_split
12928   [(set (pc)
12929         (if_then_else (match_operator 2 "comparison_operator"
12930                                       [(match_operand:P 1 "gpc_reg_operand" "")
12931                                        (const_int 1)])
12932                       (match_operand 5 "" "")
12933                       (match_operand 6 "" "")))
12934    (set (match_operand:P 0 "int_reg_operand" "")
12935         (plus:P (match_dup 1) (const_int -1)))
12936    (clobber (match_scratch:CC 3 ""))
12937    (clobber (match_scratch:P 4 ""))]
12938   "reload_completed"
12939   [(set (match_dup 3)
12940         (compare:CC (match_dup 1)
12941                     (const_int 1)))
12942    (set (match_dup 0)
12943         (plus:P (match_dup 1)
12944                 (const_int -1)))
12945    (set (pc) (if_then_else (match_dup 7)
12946                            (match_dup 5)
12947                            (match_dup 6)))]
12948   "
12949 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12950                                 operands[3], const0_rtx); }")
12952 (define_split
12953   [(set (pc)
12954         (if_then_else (match_operator 2 "comparison_operator"
12955                                       [(match_operand:P 1 "gpc_reg_operand" "")
12956                                        (const_int 1)])
12957                       (match_operand 5 "" "")
12958                       (match_operand 6 "" "")))
12959    (set (match_operand:P 0 "nonimmediate_operand" "")
12960         (plus:P (match_dup 1) (const_int -1)))
12961    (clobber (match_scratch:CC 3 ""))
12962    (clobber (match_scratch:P 4 ""))]
12963   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12964   [(set (match_dup 3)
12965         (compare:CC (match_dup 1)
12966                     (const_int 1)))
12967    (set (match_dup 4)
12968         (plus:P (match_dup 1)
12969                 (const_int -1)))
12970    (set (match_dup 0)
12971         (match_dup 4))
12972    (set (pc) (if_then_else (match_dup 7)
12973                            (match_dup 5)
12974                            (match_dup 6)))]
12975   "
12976 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12977                                 operands[3], const0_rtx); }")
12979 (define_insn "trap"
12980   [(trap_if (const_int 1) (const_int 0))]
12981   ""
12982   "trap"
12983   [(set_attr "type" "trap")])
12985 (define_expand "ctrap<mode>4"
12986   [(trap_if (match_operator 0 "ordered_comparison_operator"
12987                             [(match_operand:GPR 1 "register_operand")
12988                              (match_operand:GPR 2 "reg_or_short_operand")])
12989             (match_operand 3 "zero_constant" ""))]
12990   ""
12991   "")
12993 (define_insn ""
12994   [(trap_if (match_operator 0 "ordered_comparison_operator"
12995                             [(match_operand:GPR 1 "register_operand" "r")
12996                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12997             (const_int 0))]
12998   ""
12999   "t<wd>%V0%I2 %1,%2"
13000   [(set_attr "type" "trap")])
13002 ;; Insns related to generating the function prologue and epilogue.
13004 (define_expand "prologue"
13005   [(use (const_int 0))]
13006   ""
13008   rs6000_emit_prologue ();
13009   if (!TARGET_SCHED_PROLOG)
13010     emit_insn (gen_blockage ());
13011   DONE;
13014 (define_insn "*movesi_from_cr_one"
13015   [(match_parallel 0 "mfcr_operation"
13016                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13017                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13018                                      (match_operand 3 "immediate_operand" "n")]
13019                           UNSPEC_MOVESI_FROM_CR))])]
13020   "TARGET_MFCRF"
13021   "*
13023   int mask = 0;
13024   int i;
13025   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13026   {
13027     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13028     operands[4] = GEN_INT (mask);
13029     output_asm_insn (\"mfcr %1,%4\", operands);
13030   }
13031   return \"\";
13033   [(set_attr "type" "mfcrf")])
13035 (define_insn "movesi_from_cr"
13036   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13037         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13038                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13039                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13040                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13041                    UNSPEC_MOVESI_FROM_CR))]
13042   ""
13043   "mfcr %0"
13044   [(set_attr "type" "mfcr")])
13046 (define_insn "*crsave"
13047   [(match_parallel 0 "crsave_operation"
13048                    [(set (match_operand:SI 1 "memory_operand" "=m")
13049                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13050   ""
13051   "stw %2,%1"
13052   [(set_attr "type" "store")])
13054 (define_insn "*stmw"
13055   [(match_parallel 0 "stmw_operation"
13056                    [(set (match_operand:SI 1 "memory_operand" "=m")
13057                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13058   "TARGET_MULTIPLE"
13059   "stmw %2,%1"
13060   [(set_attr "type" "store")
13061    (set_attr "update" "yes")
13062    (set_attr "indexed" "yes")])
13064 ; The following comment applies to:
13065 ;     save_gpregs_*
13066 ;     save_fpregs_*
13067 ;     restore_gpregs*
13068 ;     return_and_restore_gpregs*
13069 ;     return_and_restore_fpregs*
13070 ;     return_and_restore_fpregs_aix*
13072 ; The out-of-line save / restore functions expects one input argument.
13073 ; Since those are not standard call_insn's, we must avoid using
13074 ; MATCH_OPERAND for that argument. That way the register rename
13075 ; optimization will not try to rename this register.
13076 ; Each pattern is repeated for each possible register number used in 
13077 ; various ABIs (r11, r1, and for some functions r12)
13079 (define_insn "*save_gpregs_<mode>_r11"
13080   [(match_parallel 0 "any_parallel_operand"
13081                    [(clobber (reg:P LR_REGNO))
13082                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13083                     (use (reg:P 11))
13084                     (set (match_operand:P 2 "memory_operand" "=m")
13085                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13086   ""
13087   "bl %1"
13088   [(set_attr "type" "branch")
13089    (set_attr "length" "4")])
13091 (define_insn "*save_gpregs_<mode>_r12"
13092   [(match_parallel 0 "any_parallel_operand"
13093                    [(clobber (reg:P LR_REGNO))
13094                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13095                     (use (reg:P 12))
13096                     (set (match_operand:P 2 "memory_operand" "=m")
13097                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13098   ""
13099   "bl %1"
13100   [(set_attr "type" "branch")
13101    (set_attr "length" "4")])
13103 (define_insn "*save_gpregs_<mode>_r1"
13104   [(match_parallel 0 "any_parallel_operand"
13105                    [(clobber (reg:P LR_REGNO))
13106                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13107                     (use (reg:P 1))
13108                     (set (match_operand:P 2 "memory_operand" "=m")
13109                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13110   ""
13111   "bl %1"
13112   [(set_attr "type" "branch")
13113    (set_attr "length" "4")])
13115 (define_insn "*save_fpregs_<mode>_r11"
13116   [(match_parallel 0 "any_parallel_operand"
13117                    [(clobber (reg:P LR_REGNO))
13118                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13119                     (use (reg:P 11))
13120                     (set (match_operand:DF 2 "memory_operand" "=m")
13121                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13122   ""
13123   "bl %1"
13124   [(set_attr "type" "branch")
13125    (set_attr "length" "4")])
13127 (define_insn "*save_fpregs_<mode>_r12"
13128   [(match_parallel 0 "any_parallel_operand"
13129                    [(clobber (reg:P LR_REGNO))
13130                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13131                     (use (reg:P 12))
13132                     (set (match_operand:DF 2 "memory_operand" "=m")
13133                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13134   ""
13135   "bl %1"
13136   [(set_attr "type" "branch")
13137    (set_attr "length" "4")])
13139 (define_insn "*save_fpregs_<mode>_r1"
13140   [(match_parallel 0 "any_parallel_operand"
13141                    [(clobber (reg:P LR_REGNO))
13142                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13143                     (use (reg:P 1))
13144                     (set (match_operand:DF 2 "memory_operand" "=m")
13145                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13146   ""
13147   "bl %1"
13148   [(set_attr "type" "branch")
13149    (set_attr "length" "4")])
13151 ; This is to explain that changes to the stack pointer should
13152 ; not be moved over loads from or stores to stack memory.
13153 (define_insn "stack_tie"
13154   [(match_parallel 0 "tie_operand"
13155                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13156   ""
13157   ""
13158   [(set_attr "length" "0")])
13160 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13161 ; stay behind all restores from the stack, it cannot be reordered to before
13162 ; one.  See PR77687.  This insn is an add or mr, and a stack_tie on the
13163 ; operands of that.
13164 (define_insn "stack_restore_tie"
13165   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13166         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13167                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13168    (set (mem:BLK (match_dup 0)) (const_int 0))
13169    (set (mem:BLK (match_dup 1)) (const_int 0))]
13170   "TARGET_32BIT"
13171   "@
13172    mr %0,%1
13173    add%I2 %0,%1,%2"
13174   [(set_attr "type" "*,add")])
13176 (define_expand "epilogue"
13177   [(use (const_int 0))]
13178   ""
13180   if (!TARGET_SCHED_PROLOG)
13181     emit_insn (gen_blockage ());
13182   rs6000_emit_epilogue (FALSE);
13183   DONE;
13186 ; On some processors, doing the mtcrf one CC register at a time is
13187 ; faster (like on the 604e).  On others, doing them all at once is
13188 ; faster; for instance, on the 601 and 750.
13190 (define_expand "movsi_to_cr_one"
13191   [(set (match_operand:CC 0 "cc_reg_operand" "")
13192         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13193                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13194   ""
13195   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13197 (define_insn "*movsi_to_cr"
13198   [(match_parallel 0 "mtcrf_operation"
13199                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13200                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13201                                      (match_operand 3 "immediate_operand" "n")]
13202                                     UNSPEC_MOVESI_TO_CR))])]
13203  ""
13204  "*
13206   int mask = 0;
13207   int i;
13208   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13209     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13210   operands[4] = GEN_INT (mask);
13211   return \"mtcrf %4,%2\";
13213   [(set_attr "type" "mtcr")])
13215 (define_insn "*mtcrfsi"
13216   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13217         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13218                     (match_operand 2 "immediate_operand" "n")]
13219                    UNSPEC_MOVESI_TO_CR))]
13220   "GET_CODE (operands[0]) == REG
13221    && CR_REGNO_P (REGNO (operands[0]))
13222    && GET_CODE (operands[2]) == CONST_INT
13223    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13224   "mtcrf %R0,%1"
13225   [(set_attr "type" "mtcr")])
13227 ; The load-multiple instructions have similar properties.
13228 ; Note that "load_multiple" is a name known to the machine-independent
13229 ; code that actually corresponds to the PowerPC load-string.
13231 (define_insn "*lmw"
13232   [(match_parallel 0 "lmw_operation"
13233                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13234                          (match_operand:SI 2 "memory_operand" "m"))])]
13235   "TARGET_MULTIPLE"
13236   "lmw %1,%2"
13237   [(set_attr "type" "load")
13238    (set_attr "update" "yes")
13239    (set_attr "indexed" "yes")
13240    (set_attr "cell_micro" "always")])
13242 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13243 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13245 ; The following comment applies to:
13246 ;     save_gpregs_*
13247 ;     save_fpregs_*
13248 ;     restore_gpregs*
13249 ;     return_and_restore_gpregs*
13250 ;     return_and_restore_fpregs*
13251 ;     return_and_restore_fpregs_aix*
13253 ; The out-of-line save / restore functions expects one input argument.
13254 ; Since those are not standard call_insn's, we must avoid using
13255 ; MATCH_OPERAND for that argument. That way the register rename
13256 ; optimization will not try to rename this register.
13257 ; Each pattern is repeated for each possible register number used in 
13258 ; various ABIs (r11, r1, and for some functions r12)
13260 (define_insn "*restore_gpregs_<mode>_r11"
13261  [(match_parallel 0 "any_parallel_operand"
13262                   [(clobber (reg:P LR_REGNO))
13263                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13264                    (use (reg:P 11))
13265                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13266                         (match_operand:P 3 "memory_operand" "m"))])]
13267  ""
13268  "bl %1"
13269  [(set_attr "type" "branch")
13270   (set_attr "length" "4")])
13272 (define_insn "*restore_gpregs_<mode>_r12"
13273  [(match_parallel 0 "any_parallel_operand"
13274                   [(clobber (reg:P LR_REGNO))
13275                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13276                    (use (reg:P 12))
13277                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13278                         (match_operand:P 3 "memory_operand" "m"))])]
13279  ""
13280  "bl %1"
13281  [(set_attr "type" "branch")
13282   (set_attr "length" "4")])
13284 (define_insn "*restore_gpregs_<mode>_r1"
13285  [(match_parallel 0 "any_parallel_operand"
13286                   [(clobber (reg:P LR_REGNO))
13287                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13288                    (use (reg:P 1))
13289                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13290                         (match_operand:P 3 "memory_operand" "m"))])]
13291  ""
13292  "bl %1"
13293  [(set_attr "type" "branch")
13294   (set_attr "length" "4")])
13296 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13297  [(match_parallel 0 "any_parallel_operand"
13298                   [(return)
13299                    (clobber (reg:P LR_REGNO))
13300                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13301                    (use (reg:P 11))
13302                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13303                         (match_operand:P 3 "memory_operand" "m"))])]
13304  ""
13305  "b %1"
13306  [(set_attr "type" "branch")
13307   (set_attr "length" "4")])
13309 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13310  [(match_parallel 0 "any_parallel_operand"
13311                   [(return)
13312                    (clobber (reg:P LR_REGNO))
13313                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13314                    (use (reg:P 12))
13315                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13316                         (match_operand:P 3 "memory_operand" "m"))])]
13317  ""
13318  "b %1"
13319  [(set_attr "type" "branch")
13320   (set_attr "length" "4")])
13322 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13323  [(match_parallel 0 "any_parallel_operand"
13324                   [(return)
13325                    (clobber (reg:P LR_REGNO))
13326                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13327                    (use (reg:P 1))
13328                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13329                         (match_operand:P 3 "memory_operand" "m"))])]
13330  ""
13331  "b %1"
13332  [(set_attr "type" "branch")
13333   (set_attr "length" "4")])
13335 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13336  [(match_parallel 0 "any_parallel_operand"
13337                   [(return)
13338                    (clobber (reg:P LR_REGNO))
13339                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13340                    (use (reg:P 11))
13341                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13342                         (match_operand:DF 3 "memory_operand" "m"))])]
13343  ""
13344  "b %1"
13345  [(set_attr "type" "branch")
13346   (set_attr "length" "4")])
13348 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13349  [(match_parallel 0 "any_parallel_operand"
13350                   [(return)
13351                    (clobber (reg:P LR_REGNO))
13352                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13353                    (use (reg:P 12))
13354                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13355                         (match_operand:DF 3 "memory_operand" "m"))])]
13356  ""
13357  "b %1"
13358  [(set_attr "type" "branch")
13359   (set_attr "length" "4")])
13361 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13362  [(match_parallel 0 "any_parallel_operand"
13363                   [(return)
13364                    (clobber (reg:P LR_REGNO))
13365                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13366                    (use (reg:P 1))
13367                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13368                         (match_operand:DF 3 "memory_operand" "m"))])]
13369  ""
13370  "b %1"
13371  [(set_attr "type" "branch")
13372   (set_attr "length" "4")])
13374 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13375  [(match_parallel 0 "any_parallel_operand"
13376                   [(return)
13377                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13378                    (use (reg:P 11))
13379                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13380                         (match_operand:DF 3 "memory_operand" "m"))])]
13381  ""
13382  "b %1"
13383  [(set_attr "type" "branch")
13384   (set_attr "length" "4")])
13386 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13387  [(match_parallel 0 "any_parallel_operand"
13388                   [(return)
13389                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13390                    (use (reg:P 1))
13391                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13392                         (match_operand:DF 3 "memory_operand" "m"))])]
13393  ""
13394  "b %1"
13395  [(set_attr "type" "branch")
13396   (set_attr "length" "4")])
13398 ; This is used in compiling the unwind routines.
13399 (define_expand "eh_return"
13400   [(use (match_operand 0 "general_operand" ""))]
13401   ""
13402   "
13404   if (TARGET_32BIT)
13405     emit_insn (gen_eh_set_lr_si (operands[0]));
13406   else
13407     emit_insn (gen_eh_set_lr_di (operands[0]));
13408   DONE;
13411 ; We can't expand this before we know where the link register is stored.
13412 (define_insn "eh_set_lr_<mode>"
13413   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13414                     UNSPECV_EH_RR)
13415    (clobber (match_scratch:P 1 "=&b"))]
13416   ""
13417   "#")
13419 (define_split
13420   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13421    (clobber (match_scratch 1 ""))]
13422   "reload_completed"
13423   [(const_int 0)]
13424   "
13426   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13427   DONE;
13430 (define_insn "prefetch"
13431   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13432              (match_operand:SI 1 "const_int_operand" "n")
13433              (match_operand:SI 2 "const_int_operand" "n"))]
13434   ""
13435   "*
13437   if (GET_CODE (operands[0]) == REG)
13438     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13439   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13441   [(set_attr "type" "load")])
13443 ;; Handle -fsplit-stack.
13445 (define_expand "split_stack_prologue"
13446   [(const_int 0)]
13447   ""
13449   rs6000_expand_split_stack_prologue ();
13450   DONE;
13453 (define_expand "load_split_stack_limit"
13454   [(set (match_operand 0)
13455         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13456   ""
13458   emit_insn (gen_rtx_SET (operands[0],
13459                           gen_rtx_UNSPEC (Pmode,
13460                                           gen_rtvec (1, const0_rtx),
13461                                           UNSPEC_STACK_CHECK)));
13462   DONE;
13465 (define_insn "load_split_stack_limit_di"
13466   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13467         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13468   "TARGET_64BIT"
13469   "ld %0,-0x7040(13)"
13470   [(set_attr "type" "load")
13471    (set_attr "update" "no")
13472    (set_attr "indexed" "no")])
13474 (define_insn "load_split_stack_limit_si"
13475   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13476         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13477   "!TARGET_64BIT"
13478   "lwz %0,-0x7020(2)"
13479   [(set_attr "type" "load")
13480    (set_attr "update" "no")
13481    (set_attr "indexed" "no")])
13483 ;; A return instruction which the middle-end doesn't see.
13484 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13485 ;; after the call to __morestack.
13486 (define_insn "split_stack_return"
13487   [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13488   ""
13489   "blr"
13490   [(set_attr "type" "jmpreg")])
13492 ;; If there are operand 0 bytes available on the stack, jump to
13493 ;; operand 1.
13494 (define_expand "split_stack_space_check"
13495   [(set (match_dup 2)
13496         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13497    (set (match_dup 3)
13498         (minus (reg STACK_POINTER_REGNUM)
13499                (match_operand 0)))
13500    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13501    (set (pc) (if_then_else
13502               (geu (match_dup 4) (const_int 0))
13503               (label_ref (match_operand 1))
13504               (pc)))]
13505   ""
13507   rs6000_split_stack_space_check (operands[0], operands[1]);
13508   DONE;
13511 (define_insn "bpermd_<mode>"
13512   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13513         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13514                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13515   "TARGET_POPCNTD"
13516   "bpermd %0,%1,%2"
13517   [(set_attr "type" "popcnt")])
13520 ;; Builtin fma support.  Handle 
13521 ;; Note that the conditions for expansion are in the FMA_F iterator.
13523 (define_expand "fma<mode>4"
13524   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13525         (fma:FMA_F
13526           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13527           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13528           (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13529   ""
13530   "")
13532 (define_insn "*fma<mode>4_fpr"
13533   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13534         (fma:SFDF
13535           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13536           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13537           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13538   "TARGET_<MODE>_FPR"
13539   "@
13540    fmadd<Ftrad> %0,%1,%2,%3
13541    xsmadda<Fvsx> %x0,%x1,%x2
13542    xsmaddm<Fvsx> %x0,%x1,%x3"
13543   [(set_attr "type" "fp")
13544    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13546 ; Altivec only has fma and nfms.
13547 (define_expand "fms<mode>4"
13548   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13549         (fma:FMA_F
13550           (match_operand:FMA_F 1 "gpc_reg_operand" "")
13551           (match_operand:FMA_F 2 "gpc_reg_operand" "")
13552           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13553   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13554   "")
13556 (define_insn "*fms<mode>4_fpr"
13557   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13558         (fma:SFDF
13559          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13560          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13561          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13562   "TARGET_<MODE>_FPR"
13563   "@
13564    fmsub<Ftrad> %0,%1,%2,%3
13565    xsmsuba<Fvsx> %x0,%x1,%x2
13566    xsmsubm<Fvsx> %x0,%x1,%x3"
13567   [(set_attr "type" "fp")
13568    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13570 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13571 (define_expand "fnma<mode>4"
13572   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13573         (neg:FMA_F
13574           (fma:FMA_F
13575             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13576             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13577             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13578   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13579   "")
13581 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13582 (define_expand "fnms<mode>4"
13583   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13584         (neg:FMA_F
13585           (fma:FMA_F
13586             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13587             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13588             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13589   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13590   "")
13592 ; Not an official optab name, but used from builtins.
13593 (define_expand "nfma<mode>4"
13594   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13595         (neg:FMA_F
13596           (fma:FMA_F
13597             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13598             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13599             (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13600   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13601   "")
13603 (define_insn "*nfma<mode>4_fpr"
13604   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13605         (neg:SFDF
13606          (fma:SFDF
13607           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13608           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13609           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13610   "TARGET_<MODE>_FPR"
13611   "@
13612    fnmadd<Ftrad> %0,%1,%2,%3
13613    xsnmadda<Fvsx> %x0,%x1,%x2
13614    xsnmaddm<Fvsx> %x0,%x1,%x3"
13615   [(set_attr "type" "fp")
13616    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13618 ; Not an official optab name, but used from builtins.
13619 (define_expand "nfms<mode>4"
13620   [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13621         (neg:FMA_F
13622           (fma:FMA_F
13623             (match_operand:FMA_F 1 "gpc_reg_operand" "")
13624             (match_operand:FMA_F 2 "gpc_reg_operand" "")
13625             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13626   ""
13627   "")
13629 (define_insn "*nfmssf4_fpr"
13630   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13631         (neg:SFDF
13632          (fma:SFDF
13633           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13634           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13635           (neg:SFDF
13636            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13637   "TARGET_<MODE>_FPR"
13638   "@
13639    fnmsub<Ftrad> %0,%1,%2,%3
13640    xsnmsuba<Fvsx> %x0,%x1,%x2
13641    xsnmsubm<Fvsx> %x0,%x1,%x3"
13642   [(set_attr "type" "fp")
13643    (set_attr "fp_type" "fp_maddsub_<Fs>")])
13646 (define_expand "rs6000_get_timebase"
13647   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13648   ""
13650   if (TARGET_POWERPC64)
13651     emit_insn (gen_rs6000_mftb_di (operands[0]));
13652   else
13653     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13654   DONE;
13657 (define_insn "rs6000_get_timebase_ppc32"
13658   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13659         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13660    (clobber (match_scratch:SI 1 "=r"))
13661    (clobber (match_scratch:CC 2 "=y"))]
13662   "!TARGET_POWERPC64"
13664   if (WORDS_BIG_ENDIAN)
13665     if (TARGET_MFCRF)
13666       {
13667         return "mfspr %0,269\;"
13668                "mfspr %L0,268\;"
13669                "mfspr %1,269\;"
13670                "cmpw %2,%0,%1\;"
13671                "bne- %2,$-16";
13672       }
13673     else
13674       {
13675         return "mftbu %0\;"
13676                "mftb %L0\;"
13677                "mftbu %1\;"
13678                "cmpw %2,%0,%1\;"
13679                "bne- %2,$-16";
13680       }
13681   else
13682     if (TARGET_MFCRF)
13683       {
13684         return "mfspr %L0,269\;"
13685                "mfspr %0,268\;"
13686                "mfspr %1,269\;"
13687                "cmpw %2,%L0,%1\;"
13688                "bne- %2,$-16";
13689       }
13690     else
13691       {
13692         return "mftbu %L0\;"
13693                "mftb %0\;"
13694                "mftbu %1\;"
13695                "cmpw %2,%L0,%1\;"
13696                "bne- %2,$-16";
13697       }
13699   [(set_attr "length" "20")])
13701 (define_insn "rs6000_mftb_<mode>"
13702   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13703         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13704   ""
13706   if (TARGET_MFCRF)
13707     return "mfspr %0,268";
13708   else
13709     return "mftb %0";
13713 (define_insn "rs6000_mffs"
13714   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13715         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13716   "TARGET_HARD_FLOAT"
13717   "mffs %0")
13719 (define_insn "rs6000_mtfsf"
13720   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13721                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13722                     UNSPECV_MTFSF)]
13723   "TARGET_HARD_FLOAT"
13724   "mtfsf %0,%1")
13727 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13728 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13729 ;; register that is being loaded.  The fused ops must be physically adjacent.
13731 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13732 ;; before register allocation, and is meant to reduce the lifetime for the
13733 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13734 ;; to use the register that is being load.  The peephole2 then gathers any
13735 ;; other fused possibilities that it can find after register allocation.  If
13736 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13738 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13739 ;; before register allocation, so that we can avoid allocating a temporary base
13740 ;; register that won't be used, and that we try to load into base registers,
13741 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13742 ;; (addis followed by load) even on power8.
13744 (define_split
13745   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13746         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13747   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13748   [(parallel [(set (match_dup 0) (match_dup 2))
13749               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13750               (use (match_dup 3))
13751               (clobber (scratch:DI))])]
13753   operands[2] = fusion_wrap_memory_address (operands[1]);
13754   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13757 (define_insn "*toc_fusionload_<mode>"
13758   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13759         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13760    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13761    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13762    (clobber (match_scratch:DI 3 "=X,&b"))]
13763   "TARGET_TOC_FUSION_INT"
13765   if (base_reg_operand (operands[0], <MODE>mode))
13766     return emit_fusion_gpr_load (operands[0], operands[1]);
13768   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13770   [(set_attr "type" "load")
13771    (set_attr "length" "8")])
13773 (define_insn "*toc_fusionload_di"
13774   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13775         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13776    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13777    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13778    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13779   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13780    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13782   if (base_reg_operand (operands[0], DImode))
13783     return emit_fusion_gpr_load (operands[0], operands[1]);
13785   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13787   [(set_attr "type" "load")
13788    (set_attr "length" "8")])
13791 ;; Find cases where the addis that feeds into a load instruction is either used
13792 ;; once or is the same as the target register, and replace it with the fusion
13793 ;; insn
13795 (define_peephole2
13796   [(set (match_operand:P 0 "base_reg_operand" "")
13797         (match_operand:P 1 "fusion_gpr_addis" ""))
13798    (set (match_operand:INT1 2 "base_reg_operand" "")
13799         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13800   "TARGET_P8_FUSION
13801    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13802                          operands[3])"
13803   [(const_int 0)]
13805   expand_fusion_gpr_load (operands);
13806   DONE;
13809 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13810 ;; reload)
13812 (define_insn "fusion_gpr_load_<mode>"
13813   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13814         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13815                      UNSPEC_FUSION_GPR))]
13816   "TARGET_P8_FUSION"
13818   return emit_fusion_gpr_load (operands[0], operands[1]);
13820   [(set_attr "type" "load")
13821    (set_attr "length" "8")])
13824 ;; ISA 3.0 (power9) fusion support
13825 ;; Merge addis with floating load/store to FPRs (or GPRs).
13826 (define_peephole2
13827   [(set (match_operand:P 0 "base_reg_operand" "")
13828         (match_operand:P 1 "fusion_gpr_addis" ""))
13829    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13830         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13831   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13832    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13833   [(const_int 0)]
13835   expand_fusion_p9_load (operands);
13836   DONE;
13839 (define_peephole2
13840   [(set (match_operand:P 0 "base_reg_operand" "")
13841         (match_operand:P 1 "fusion_gpr_addis" ""))
13842    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13843         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13844   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13845    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13846    && !rtx_equal_p (operands[0], operands[3])"
13847   [(const_int 0)]
13849   expand_fusion_p9_store (operands);
13850   DONE;
13853 (define_peephole2
13854   [(set (match_operand:SDI 0 "int_reg_operand" "")
13855         (match_operand:SDI 1 "upper16_cint_operand" ""))
13856    (set (match_dup 0)
13857         (ior:SDI (match_dup 0)
13858                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
13859   "TARGET_P9_FUSION"
13860   [(set (match_dup 0)
13861         (unspec:SDI [(match_dup 1)
13862                      (match_dup 2)] UNSPEC_FUSION_P9))])
13864 (define_peephole2
13865   [(set (match_operand:SDI 0 "int_reg_operand" "")
13866         (match_operand:SDI 1 "upper16_cint_operand" ""))
13867    (set (match_operand:SDI 2 "int_reg_operand" "")
13868         (ior:SDI (match_dup 0)
13869                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
13870   "TARGET_P9_FUSION
13871    && !rtx_equal_p (operands[0], operands[2])
13872    && peep2_reg_dead_p (2, operands[0])"
13873   [(set (match_dup 2)
13874         (unspec:SDI [(match_dup 1)
13875                      (match_dup 3)] UNSPEC_FUSION_P9))])
13877 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13878 ;; reload).  Because we want to eventually have secondary_reload generate
13879 ;; these, they have to have a single alternative that gives the register
13880 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13881 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13882   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13883         (unspec:GPR_FUSION
13884          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13885          UNSPEC_FUSION_P9))
13886    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13887   "TARGET_P9_FUSION"
13889   /* This insn is a secondary reload insn, which cannot have alternatives.
13890      If we are not loading up register 0, use the power8 fusion instead.  */
13891   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13892     return emit_fusion_gpr_load (operands[0], operands[1]);
13894   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13896   [(set_attr "type" "load")
13897    (set_attr "length" "8")])
13899 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13900   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13901         (unspec:GPR_FUSION
13902          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13903          UNSPEC_FUSION_P9))
13904    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13905   "TARGET_P9_FUSION"
13907   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13909   [(set_attr "type" "store")
13910    (set_attr "length" "8")])
13912 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13913   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13914         (unspec:FPR_FUSION
13915          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13916          UNSPEC_FUSION_P9))
13917    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13918   "TARGET_P9_FUSION"
13920   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13922   [(set_attr "type" "fpload")
13923    (set_attr "length" "8")])
13925 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13926   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13927         (unspec:FPR_FUSION
13928          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13929          UNSPEC_FUSION_P9))
13930    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13931   "TARGET_P9_FUSION"
13933   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13935   [(set_attr "type" "fpstore")
13936    (set_attr "length" "8")])
13938 (define_insn "*fusion_p9_<mode>_constant"
13939   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13940         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13941                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13942                     UNSPEC_FUSION_P9))] 
13943   "TARGET_P9_FUSION"
13945   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13946   return "ori %0,%0,%2";
13948   [(set_attr "type" "two")
13949    (set_attr "length" "8")])
13952 ;; Optimize cases where we want to do a D-form load (register+offset) on
13953 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13954 ;; has generated:
13955 ;;      LFD 0,32(3)
13956 ;;      XXLOR 32,0,0
13958 ;; and we change this to:
13959 ;;      LI 0,32
13960 ;;      LXSDX 32,3,9
13962 (define_peephole2
13963   [(match_scratch:P 0 "b")
13964    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13965         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13966    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13967         (match_dup 1))]
13968   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13969   [(set (match_dup 0)
13970         (match_dup 4))
13971    (set (match_dup 3)
13972         (match_dup 5))]
13974   rtx tmp_reg = operands[0];
13975   rtx mem = operands[2];
13976   rtx addr = XEXP (mem, 0);
13977   rtx add_op0, add_op1, new_addr;
13979   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13980   add_op0 = XEXP (addr, 0);
13981   add_op1 = XEXP (addr, 1);
13982   gcc_assert (REG_P (add_op0));
13983   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13985   operands[4] = add_op1;
13986   operands[5] = change_address (mem, <MODE>mode, new_addr);
13989 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13990 ;; Altivec register, and the register allocator has generated:
13991 ;;      XXLOR 0,32,32
13992 ;;      STFD 0,32(3)
13994 ;; and we change this to:
13995 ;;      LI 0,32
13996 ;;      STXSDX 32,3,9
13998 (define_peephole2
13999   [(match_scratch:P 0 "b")
14000    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14001         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14002    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14003         (match_dup 1))]
14004   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14005   [(set (match_dup 0)
14006         (match_dup 4))
14007    (set (match_dup 5)
14008         (match_dup 2))]
14010   rtx tmp_reg = operands[0];
14011   rtx mem = operands[3];
14012   rtx addr = XEXP (mem, 0);
14013   rtx add_op0, add_op1, new_addr;
14015   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14016   add_op0 = XEXP (addr, 0);
14017   add_op1 = XEXP (addr, 1);
14018   gcc_assert (REG_P (add_op0));
14019   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14021   operands[4] = add_op1;
14022   operands[5] = change_address (mem, <MODE>mode, new_addr);
14024    
14026 ;; Miscellaneous ISA 2.06 (power7) instructions
14027 (define_insn "addg6s"
14028   [(set (match_operand:SI 0 "register_operand" "=r")
14029         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14030                     (match_operand:SI 2 "register_operand" "r")]
14031                    UNSPEC_ADDG6S))]
14032   "TARGET_POPCNTD"
14033   "addg6s %0,%1,%2"
14034   [(set_attr "type" "integer")
14035    (set_attr "length" "4")])
14037 (define_insn "cdtbcd"
14038   [(set (match_operand:SI 0 "register_operand" "=r")
14039         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14040                    UNSPEC_CDTBCD))]
14041   "TARGET_POPCNTD"
14042   "cdtbcd %0,%1"
14043   [(set_attr "type" "integer")
14044    (set_attr "length" "4")])
14046 (define_insn "cbcdtd"
14047   [(set (match_operand:SI 0 "register_operand" "=r")
14048         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14049                    UNSPEC_CBCDTD))]
14050   "TARGET_POPCNTD"
14051   "cbcdtd %0,%1"
14052   [(set_attr "type" "integer")
14053    (set_attr "length" "4")])
14055 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14056                                         UNSPEC_DIVEO
14057                                         UNSPEC_DIVEU
14058                                         UNSPEC_DIVEUO])
14060 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
14061                              (UNSPEC_DIVEO      "eo")
14062                              (UNSPEC_DIVEU      "eu")
14063                              (UNSPEC_DIVEUO     "euo")])
14065 (define_insn "div<div_extend>_<mode>"
14066   [(set (match_operand:GPR 0 "register_operand" "=r")
14067         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14068                      (match_operand:GPR 2 "register_operand" "r")]
14069                     UNSPEC_DIV_EXTEND))]
14070   "TARGET_POPCNTD"
14071   "div<wd><div_extend> %0,%1,%2"
14072   [(set_attr "type" "div")
14073    (set_attr "size" "<bits>")])
14076 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14078 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14079 (define_mode_attr FP128_64 [(TF "DF")
14080                             (IF "DF")
14081                             (TD "DI")
14082                             (KF "DI")])
14084 (define_expand "unpack<mode>"
14085   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14086         (unspec:<FP128_64>
14087          [(match_operand:FMOVE128 1 "register_operand" "")
14088           (match_operand:QI 2 "const_0_to_1_operand" "")]
14089          UNSPEC_UNPACK_128BIT))]
14090   "FLOAT128_2REG_P (<MODE>mode)"
14091   "")
14093 (define_insn_and_split "unpack<mode>_dm"
14094   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14095         (unspec:<FP128_64>
14096          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14097           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14098          UNSPEC_UNPACK_128BIT))]
14099   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14100   "#"
14101   "&& reload_completed"
14102   [(set (match_dup 0) (match_dup 3))]
14104   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14106   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14107     {
14108       emit_note (NOTE_INSN_DELETED);
14109       DONE;
14110     }
14112   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14114   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14115    (set_attr "length" "4")])
14117 (define_insn_and_split "unpack<mode>_nodm"
14118   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14119         (unspec:<FP128_64>
14120          [(match_operand:FMOVE128 1 "register_operand" "d,d")
14121           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14122          UNSPEC_UNPACK_128BIT))]
14123   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14124   "#"
14125   "&& reload_completed"
14126   [(set (match_dup 0) (match_dup 3))]
14128   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14130   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14131     {
14132       emit_note (NOTE_INSN_DELETED);
14133       DONE;
14134     }
14136   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14138   [(set_attr "type" "fp,fpstore")
14139    (set_attr "length" "4")])
14141 (define_insn_and_split "pack<mode>"
14142   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14143         (unspec:FMOVE128
14144          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14145           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14146          UNSPEC_PACK_128BIT))]
14147   "FLOAT128_2REG_P (<MODE>mode)"
14148   "@
14149    fmr %L0,%2
14150    #"
14151   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14152   [(set (match_dup 3) (match_dup 1))
14153    (set (match_dup 4) (match_dup 2))]
14155   unsigned dest_hi = REGNO (operands[0]);
14156   unsigned dest_lo = dest_hi + 1;
14158   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14159   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14161   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14162   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14164   [(set_attr "type" "fpsimple,fp")
14165    (set_attr "length" "4,8")])
14167 (define_insn "unpack<mode>"
14168   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14169         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14170                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14171          UNSPEC_UNPACK_128BIT))]
14172   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14174   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14175     return ASM_COMMENT_START " xxpermdi to same register";
14177   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14178   return "xxpermdi %x0,%x1,%x1,%3";
14180   [(set_attr "type" "vecperm")])
14182 (define_insn "pack<mode>"
14183   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14184         (unspec:FMOVE128_VSX
14185          [(match_operand:DI 1 "register_operand" "wa")
14186           (match_operand:DI 2 "register_operand" "wa")]
14187          UNSPEC_PACK_128BIT))]
14188   "TARGET_VSX"
14189   "xxpermdi %x0,%x1,%x2,0"
14190   [(set_attr "type" "vecperm")])
14194 ;; ISA 2.08 IEEE 128-bit floating point support.
14196 (define_insn "add<mode>3"
14197   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14198         (plus:IEEE128
14199          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14200          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14201   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14202   "xsaddqp %0,%1,%2"
14203   [(set_attr "type" "vecfloat")
14204    (set_attr "size" "128")])
14206 (define_insn "sub<mode>3"
14207   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14208         (minus:IEEE128
14209          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14210          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14211   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14212   "xssubqp %0,%1,%2"
14213   [(set_attr "type" "vecfloat")
14214    (set_attr "size" "128")])
14216 (define_insn "mul<mode>3"
14217   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14218         (mult:IEEE128
14219          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14220          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14221   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14222   "xsmulqp %0,%1,%2"
14223   [(set_attr "type" "vecfloat")
14224    (set_attr "size" "128")])
14226 (define_insn "div<mode>3"
14227   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14228         (div:IEEE128
14229          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14230          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14231   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14232   "xsdivqp %0,%1,%2"
14233   [(set_attr "type" "vecdiv")
14234    (set_attr "size" "128")])
14236 (define_insn "sqrt<mode>2"
14237   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14238         (sqrt:IEEE128
14239          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14240   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14241    "xssqrtqp %0,%1"
14242   [(set_attr "type" "vecdiv")
14243    (set_attr "size" "128")])
14245 (define_expand "copysign<mode>3"
14246   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14247    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14248    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14249   "FLOAT128_IEEE_P (<MODE>mode)"
14251   if (TARGET_FLOAT128_HW)
14252     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14253                                          operands[2]));
14254   else
14255     {
14256       rtx tmp = gen_reg_rtx (<MODE>mode);
14257       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14258                                            operands[2], tmp));
14259     }
14260   DONE;
14263 (define_insn "copysign<mode>3_hard"
14264   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14265         (unspec:IEEE128
14266          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14267           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14268          UNSPEC_COPYSIGN))]
14269   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14270    "xscpsgnqp %0,%2,%1"
14271   [(set_attr "type" "vecmove")
14272    (set_attr "size" "128")])
14274 (define_insn "copysign<mode>3_soft"
14275   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14276         (unspec:IEEE128
14277          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14278           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14279           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14280          UNSPEC_COPYSIGN))]
14281   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14282    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14283   [(set_attr "type" "veccomplex")
14284    (set_attr "length" "8")])
14286 (define_insn "neg<mode>2_hw"
14287   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14288         (neg:IEEE128
14289          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14290   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14291   "xsnegqp %0,%1"
14292   [(set_attr "type" "vecmove")
14293    (set_attr "size" "128")])
14296 (define_insn "abs<mode>2_hw"
14297   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298         (abs:IEEE128
14299          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14300   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14301   "xsabsqp %0,%1"
14302   [(set_attr "type" "vecmove")
14303    (set_attr "size" "128")])
14306 (define_insn "*nabs<mode>2_hw"
14307   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14308         (neg:IEEE128
14309          (abs:IEEE128
14310           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14311   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14312   "xsnabsqp %0,%1"
14313   [(set_attr "type" "vecmove")
14314    (set_attr "size" "128")])
14316 ;; Initially don't worry about doing fusion
14317 (define_insn "*fma<mode>4_hw"
14318   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14319         (fma:IEEE128
14320          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14321          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14322          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14323   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14324   "xsmaddqp %0,%1,%2"
14325   [(set_attr "type" "vecfloat")
14326    (set_attr "size" "128")])
14328 (define_insn "*fms<mode>4_hw"
14329   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14330         (fma:IEEE128
14331          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14332          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14333          (neg:IEEE128
14334           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14335   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14336   "xsmsubqp %0,%1,%2"
14337   [(set_attr "type" "vecfloat")
14338    (set_attr "size" "128")])
14340 (define_insn "*nfma<mode>4_hw"
14341   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14342         (neg:IEEE128
14343          (fma:IEEE128
14344           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14345           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14346           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14347   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14348   "xsnmaddqp %0,%1,%2"
14349   [(set_attr "type" "vecfloat")
14350    (set_attr "size" "128")])
14352 (define_insn "*nfms<mode>4_hw"
14353   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14354         (neg:IEEE128
14355          (fma:IEEE128
14356           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14357           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14358           (neg:IEEE128
14359            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14360   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14361   "xsnmsubqp %0,%1,%2"
14362   [(set_attr "type" "vecfloat")
14363    (set_attr "size" "128")])
14365 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14366   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14367         (float_extend:IEEE128
14368          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14369   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14370   "xscvdpqp %0,%1"
14371   [(set_attr "type" "vecfloat")
14372    (set_attr "size" "128")])
14374 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14375 ;; point is a simple copy.
14376 (define_insn_and_split "extendkftf2"
14377   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14378         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14379   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14380   "@
14381    #
14382    xxlor %x0,%x1,%x1"
14383   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14384   [(const_int 0)]
14386   emit_note (NOTE_INSN_DELETED);
14387   DONE;
14389   [(set_attr "type" "*,veclogical")
14390    (set_attr "length" "0,4")])
14392 (define_insn_and_split "trunctfkf2"
14393   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14394         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14395   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14396   "@
14397    #
14398    xxlor %x0,%x1,%x1"
14399   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14400   [(const_int 0)]
14402   emit_note (NOTE_INSN_DELETED);
14403   DONE;
14405   [(set_attr "type" "*,veclogical")
14406    (set_attr "length" "0,4")])
14408 (define_insn "trunc<mode>df2_hw"
14409   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14410         (float_truncate:DF
14411          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14412   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14413   "xscvqpdp %0,%1"
14414   [(set_attr "type" "vecfloat")
14415    (set_attr "size" "128")])
14417 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14418 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14419 ;; conversion
14420 (define_insn_and_split "trunc<mode>sf2_hw"
14421   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14422         (float_truncate:SF
14423          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14424    (clobber (match_scratch:DF 2 "=v"))]
14425   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14426   "#"
14427   "&& 1"
14428   [(set (match_dup 2)
14429         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14430    (set (match_dup 0)
14431         (float_truncate:SF (match_dup 2)))]
14433   if (GET_CODE (operands[2]) == SCRATCH)
14434     operands[2] = gen_reg_rtx (DFmode);
14436   [(set_attr "type" "vecfloat")
14437    (set_attr "length" "8")])
14439 ;; Conversion between IEEE 128-bit and integer types
14440 (define_insn "fix_<mode>di2_hw"
14441   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14442         (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14443   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14444   "xscvqpsdz %0,%1"
14445   [(set_attr "type" "vecfloat")
14446    (set_attr "size" "128")])
14448 (define_insn "fixuns_<mode>di2_hw"
14449   [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14450         (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14451   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14452   "xscvqpudz %0,%1"
14453   [(set_attr "type" "vecfloat")
14454    (set_attr "size" "128")])
14456 (define_insn "fix_<mode>si2_hw"
14457   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14458         (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14459   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14460   "xscvqpswz %0,%1"
14461   [(set_attr "type" "vecfloat")
14462    (set_attr "size" "128")])
14464 (define_insn "fixuns_<mode>si2_hw"
14465   [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14466         (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14467   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14468   "xscvqpuwz %0,%1"
14469   [(set_attr "type" "vecfloat")
14470    (set_attr "size" "128")])
14472 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14473 ;; floating point value to 32-bit integer to GPR in order to save it.
14474 (define_insn_and_split "*fix<uns>_<mode>_mem"
14475   [(set (match_operand:SI 0 "memory_operand" "=Z")
14476         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14477    (clobber (match_scratch:SI 2 "=v"))]
14478   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14479   "#"
14480   "&& reload_completed"
14481   [(set (match_dup 2)
14482         (any_fix:SI (match_dup 1)))
14483    (set (match_dup 0)
14484         (match_dup 2))])
14486 (define_insn "float_<mode>di2_hw"
14487   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14488         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14489   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14490   "xscvsdqp %0,%1"
14491   [(set_attr "type" "vecfloat")
14492    (set_attr "size" "128")])
14494 (define_insn_and_split "float_<mode>si2_hw"
14495   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14496         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14497    (clobber (match_scratch:DI 2 "=v"))]
14498   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14499   "#"
14500   "&& 1"
14501   [(set (match_dup 2)
14502         (sign_extend:DI (match_dup 1)))
14503    (set (match_dup 0)
14504         (float:IEEE128 (match_dup 2)))]
14506   if (GET_CODE (operands[2]) == SCRATCH)
14507     operands[2] = gen_reg_rtx (DImode);
14510 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14511   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14512         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14513    (clobber (match_scratch:DI 2 "=X,r,X"))]
14514   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14515   "#"
14516   "&& reload_completed"
14517   [(const_int 0)]
14519   rtx dest = operands[0];
14520   rtx src = operands[1];
14521   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14523   if (altivec_register_operand (src, <QHI:MODE>mode))
14524     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14525   else if (int_reg_operand (src, <QHI:MODE>mode))
14526     {
14527       rtx ext_di = operands[2];
14528       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14529       emit_move_insn (dest_di, ext_di);
14530     }
14531   else if (MEM_P (src))
14532     {
14533       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14534       emit_move_insn (dest_qhi, src);
14535       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14536     }
14537   else
14538     gcc_unreachable ();
14540   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14541   DONE;
14543   [(set_attr "length" "8,12,12")
14544    (set_attr "type" "vecfloat")
14545    (set_attr "size" "128")])
14547 (define_insn "floatuns_<mode>di2_hw"
14548   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14549         (unsigned_float:IEEE128
14550          (match_operand:DI 1 "altivec_register_operand" "v")))]
14551   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14552   "xscvudqp %0,%1"
14553   [(set_attr "type" "vecfloat")
14554    (set_attr "size" "128")])
14556 (define_insn_and_split "floatuns_<mode>si2_hw"
14557   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14558         (unsigned_float:IEEE128
14559          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14560    (clobber (match_scratch:DI 2 "=v"))]
14561   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14562   "#"
14563   "&& 1"
14564   [(set (match_dup 2)
14565         (zero_extend:DI (match_dup 1)))
14566    (set (match_dup 0)
14567         (float:IEEE128 (match_dup 2)))]
14569   if (GET_CODE (operands[2]) == SCRATCH)
14570     operands[2] = gen_reg_rtx (DImode);
14573 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14574   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14575         (unsigned_float:IEEE128
14576          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14577    (clobber (match_scratch:DI 2 "=X,r,X"))]
14578   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14579   "#"
14580   "&& reload_completed"
14581   [(const_int 0)]
14583   rtx dest = operands[0];
14584   rtx src = operands[1];
14585   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14587   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14588     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14589   else if (int_reg_operand (src, <QHI:MODE>mode))
14590     {
14591       rtx ext_di = operands[2];
14592       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14593       emit_move_insn (dest_di, ext_di);
14594     }
14595   else
14596     gcc_unreachable ();
14598   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14599   DONE;
14601   [(set_attr "length" "8,12,8")
14602    (set_attr "type" "vecfloat")
14603    (set_attr "size" "128")])
14605 ;; IEEE 128-bit instructions with round to odd semantics
14606 (define_insn "*trunc<mode>df2_odd"
14607   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14608         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14609                    UNSPEC_ROUND_TO_ODD))]
14610   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14611   "xscvqpdpo %0,%1"
14612   [(set_attr "type" "vecfloat")
14613    (set_attr "size" "128")])
14615 ;; IEEE 128-bit comparisons
14616 (define_insn "*cmp<mode>_hw"
14617   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14618         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14619                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14620   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14621    "xscmpuqp %0,%1,%2"
14622   [(set_attr "type" "veccmp")
14623    (set_attr "size" "128")])
14627 (include "sync.md")
14628 (include "vector.md")
14629 (include "vsx.md")
14630 (include "altivec.md")
14631 (include "dfp.md")
14632 (include "paired.md")
14633 (include "crypto.md")
14634 (include "htm.md")