rs6000.md (mov<mode>_softfloat, FMOVE32): Reformat alternatives and attributes so...
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobb249a1f1ca7206114b02263efb8c05b85f878d44
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2018 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (FRAME_POINTER_REGNUM        111)
54    (TFHAR_REGNO                 112)
55    (TFIAR_REGNO                 113)
56    (TEXASR_REGNO                114)
57   ])
60 ;; UNSPEC usage
63 (define_c_enum "unspec"
64   [UNSPEC_FRSP                  ; frsp for POWER machines
65    UNSPEC_PROBE_STACK           ; probe stack memory reference
66    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
67    UNSPEC_TOC                   ; address of the TOC (more-or-less)
68    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
69    UNSPEC_MOVSI_GOT
70    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
71    UNSPEC_FCTIWZ
72    UNSPEC_FRIM
73    UNSPEC_FRIN
74    UNSPEC_FRIP
75    UNSPEC_FRIZ
76    UNSPEC_XSRDPI
77    UNSPEC_LD_MPIC               ; load_macho_picbase
78    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
79    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
80    UNSPEC_TLSGD
81    UNSPEC_TLSLD
82    UNSPEC_MOVESI_FROM_CR
83    UNSPEC_MOVESI_TO_CR
84    UNSPEC_TLSDTPREL
85    UNSPEC_TLSDTPRELHA
86    UNSPEC_TLSDTPRELLO
87    UNSPEC_TLSGOTDTPREL
88    UNSPEC_TLSTPREL
89    UNSPEC_TLSTPRELHA
90    UNSPEC_TLSTPRELLO
91    UNSPEC_TLSGOTTPREL
92    UNSPEC_TLSTLS
93    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
94    UNSPEC_STFIWX
95    UNSPEC_POPCNTB
96    UNSPEC_FRES
97    UNSPEC_SP_SET
98    UNSPEC_SP_TEST
99    UNSPEC_SYNC
100    UNSPEC_LWSYNC
101    UNSPEC_SYNC_OP
102    UNSPEC_ATOMIC
103    UNSPEC_CMPXCHG
104    UNSPEC_XCHG
105    UNSPEC_AND
106    UNSPEC_DLMZB
107    UNSPEC_DLMZB_CR
108    UNSPEC_DLMZB_STRLEN
109    UNSPEC_RSQRT
110    UNSPEC_TOCREL
111    UNSPEC_MACHOPIC_OFFSET
112    UNSPEC_BPERM
113    UNSPEC_COPYSIGN
114    UNSPEC_PARITY
115    UNSPEC_CMPB
116    UNSPEC_FCTIW
117    UNSPEC_FCTID
118    UNSPEC_LFIWAX
119    UNSPEC_LFIWZX
120    UNSPEC_FCTIWUZ
121    UNSPEC_NOP
122    UNSPEC_GRP_END_NOP
123    UNSPEC_P8V_FMRGOW
124    UNSPEC_P8V_MTVSRWZ
125    UNSPEC_P8V_RELOAD_FROM_GPR
126    UNSPEC_P8V_MTVSRD
127    UNSPEC_P8V_XXPERMDI
128    UNSPEC_P8V_RELOAD_FROM_VSX
129    UNSPEC_ADDG6S
130    UNSPEC_CDTBCD
131    UNSPEC_CBCDTD
132    UNSPEC_DIVE
133    UNSPEC_DIVEU
134    UNSPEC_UNPACK_128BIT
135    UNSPEC_PACK_128BIT
136    UNSPEC_LSQ
137    UNSPEC_FUSION_GPR
138    UNSPEC_STACK_CHECK
139    UNSPEC_FUSION_P9
140    UNSPEC_FUSION_ADDIS
141    UNSPEC_ADD_ROUND_TO_ODD
142    UNSPEC_SUB_ROUND_TO_ODD
143    UNSPEC_MUL_ROUND_TO_ODD
144    UNSPEC_DIV_ROUND_TO_ODD
145    UNSPEC_FMA_ROUND_TO_ODD
146    UNSPEC_SQRT_ROUND_TO_ODD
147    UNSPEC_TRUNC_ROUND_TO_ODD
148    UNSPEC_SIGNBIT
149    UNSPEC_SF_FROM_SI
150    UNSPEC_SI_FROM_SF
151   ])
154 ;; UNSPEC_VOLATILE usage
157 (define_c_enum "unspecv"
158   [UNSPECV_BLOCK
159    UNSPECV_LL                   ; load-locked
160    UNSPECV_SC                   ; store-conditional
161    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
162    UNSPECV_EH_RR                ; eh_reg_restore
163    UNSPECV_ISYNC                ; isync instruction
164    UNSPECV_MFTB                 ; move from time base
165    UNSPECV_NLGR                 ; non-local goto receiver
166    UNSPECV_MFFS                 ; Move from FPSCR
167    UNSPECV_MTFSF                ; Move to FPSCR Fields
168    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
169    UNSPECV_SPEC_BARRIER         ; Speculation barrier
170   ])
173 ;; Define an insn type attribute.  This is used in function unit delay
174 ;; computations.
175 (define_attr "type"
176   "integer,two,three,
177    add,logical,shift,insert,
178    mul,halfmul,div,
179    exts,cntlz,popcnt,isel,
180    load,store,fpload,fpstore,vecload,vecstore,
181    cmp,
182    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183    cr_logical,mfcr,mfcrf,mtcr,
184    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
185    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
186    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
187    veclogical,veccmpfx,vecexts,vecmove,
188    htm,htmsimple,dfp"
189   (const_string "integer"))
191 ;; What data size does this instruction work on?
192 ;; This is used for insert, mul and others as necessary.
193 (define_attr "size" "8,16,32,64,128" (const_string "32"))
195 ;; What is the insn_cost for this insn?  The target hook can still override
196 ;; this.  For optimizing for size the "length" attribute is used instead.
197 (define_attr "cost" "" (const_int 0))
199 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
200 ;; This is used for add, logical, shift, exts, mul.
201 (define_attr "dot" "no,yes" (const_string "no"))
203 ;; Does this instruction sign-extend its result?
204 ;; This is used for load insns.
205 (define_attr "sign_extend" "no,yes" (const_string "no"))
207 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
208 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
210 ;; Does this instruction use indexed (that is, reg+reg) addressing?
211 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
212 ;; it is automatically set based on that.  If a load or store instruction
213 ;; has fewer than two operands it needs to set this attribute manually
214 ;; or the compiler will crash.
215 (define_attr "indexed" "no,yes"
216   (if_then_else (ior (match_operand 0 "indexed_address_mem")
217                      (match_operand 1 "indexed_address_mem"))
218                 (const_string "yes")
219                 (const_string "no")))
221 ;; Does this instruction use update addressing?
222 ;; This is used for load and store insns.  See the comments for "indexed".
223 (define_attr "update" "no,yes"
224   (if_then_else (ior (match_operand 0 "update_address_mem")
225                      (match_operand 1 "update_address_mem"))
226                 (const_string "yes")
227                 (const_string "no")))
229 ;; Is this instruction using operands[2] as shift amount, and can that be a
230 ;; register?
231 ;; This is used for shift insns.
232 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
234 ;; Is this instruction using a shift amount from a register?
235 ;; This is used for shift insns.
236 (define_attr "var_shift" "no,yes"
237   (if_then_else (and (eq_attr "type" "shift")
238                      (eq_attr "maybe_var_shift" "yes"))
239                 (if_then_else (match_operand 2 "gpc_reg_operand")
240                               (const_string "yes")
241                               (const_string "no"))
242                 (const_string "no")))
244 ;; Is copying of this instruction disallowed?
245 (define_attr "cannot_copy" "no,yes" (const_string "no"))
247 ;; Length (in bytes).
248 ; '(pc)' in the following doesn't include the instruction itself; it is
249 ; calculated as if the instruction had zero size.
250 (define_attr "length" ""
251   (if_then_else (eq_attr "type" "branch")
252                 (if_then_else (and (ge (minus (match_dup 0) (pc))
253                                        (const_int -32768))
254                                    (lt (minus (match_dup 0) (pc))
255                                        (const_int 32764)))
256                               (const_int 4)
257                               (const_int 8))
258                 (const_int 4)))
260 ;; Processor type -- this attribute must exactly match the processor_type
261 ;; enumeration in rs6000-opts.h.
262 (define_attr "cpu"
263   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
264    ppc750,ppc7400,ppc7450,
265    ppc403,ppc405,ppc440,ppc476,
266    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
267    power4,power5,power6,power7,power8,power9,
268    rs64a,mpccore,cell,ppca2,titan"
269   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
272 ;; If this instruction is microcoded on the CELL processor
273 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
274 (define_attr "cell_micro" "not,conditional,always"
275   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
276                           (eq_attr "dot" "yes"))
277                      (and (eq_attr "type" "load")
278                           (eq_attr "sign_extend" "yes"))
279                      (and (eq_attr "type" "shift")
280                           (eq_attr "var_shift" "yes")))
281                 (const_string "always")
282                 (const_string "not")))
284 (automata_option "ndfa")
286 (include "rs64.md")
287 (include "mpc.md")
288 (include "40x.md")
289 (include "440.md")
290 (include "476.md")
291 (include "601.md")
292 (include "603.md")
293 (include "6xx.md")
294 (include "7xx.md")
295 (include "7450.md")
296 (include "8540.md")
297 (include "e300c2c3.md")
298 (include "e500mc.md")
299 (include "e500mc64.md")
300 (include "e5500.md")
301 (include "e6500.md")
302 (include "power4.md")
303 (include "power5.md")
304 (include "power6.md")
305 (include "power7.md")
306 (include "power8.md")
307 (include "power9.md")
308 (include "cell.md")
309 (include "a2.md")
310 (include "titan.md")
312 (include "predicates.md")
313 (include "constraints.md")
315 (include "darwin.md")
318 ;; Mode iterators
320 ; This mode iterator allows :GPR to be used to indicate the allowable size
321 ; of whole values in GPRs.
322 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
324 ; And again, for patterns that need two (potentially) different integer modes.
325 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
327 ; Any supported integer mode.
328 (define_mode_iterator INT [QI HI SI DI TI PTI])
330 ; Any supported integer mode that fits in one register.
331 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
333 ; Integer modes supported in VSX registers with ISA 3.0 instructions
334 (define_mode_iterator INT_ISA3 [QI HI SI DI])
336 ; Everything we can extend QImode to.
337 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
339 ; Everything we can extend HImode to.
340 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
342 ; Everything we can extend SImode to.
343 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
345 ; QImode or HImode for small integer moves and small atomic ops
346 (define_mode_iterator QHI [QI HI])
348 ; QImode, HImode, SImode for fused ops only for GPR loads
349 (define_mode_iterator QHSI [QI HI SI])
351 ; HImode or SImode for sign extended fusion ops
352 (define_mode_iterator HSI [HI SI])
354 ; SImode or DImode, even if DImode doesn't fit in GPRs.
355 (define_mode_iterator SDI [SI DI])
357 ; Types that can be fused with an ADDIS instruction to load or store a GPR
358 ; register that has reg+offset addressing.
359 (define_mode_iterator GPR_FUSION [QI
360                                   HI
361                                   SI
362                                   (DI   "TARGET_POWERPC64")
363                                   SF
364                                   (DF   "TARGET_POWERPC64")])
366 ; Types that can be fused with an ADDIS instruction to load or store a FPR
367 ; register that has reg+offset addressing.
368 (define_mode_iterator FPR_FUSION [DI SF DF])
370 ; The size of a pointer.  Also, the size of the value that a record-condition
371 ; (one with a '.') will compare; and the size used for arithmetic carries.
372 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
374 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
375 ; PTImode is GPR only)
376 (define_mode_iterator TI2 [TI PTI])
378 ; Any hardware-supported floating-point mode
379 (define_mode_iterator FP [
380   (SF "TARGET_HARD_FLOAT")
381   (DF "TARGET_HARD_FLOAT")
382   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
383   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
384   (KF "TARGET_FLOAT128_TYPE")
385   (DD "TARGET_DFP")
386   (TD "TARGET_DFP")])
388 ; Any fma capable floating-point mode.
389 (define_mode_iterator FMA_F [
390   (SF "TARGET_HARD_FLOAT")
391   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
392   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
393   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
394   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
395   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
396   ])
398 ; Floating point move iterators to combine binary and decimal moves
399 (define_mode_iterator FMOVE32 [SF SD])
400 (define_mode_iterator FMOVE64 [DF DD])
401 (define_mode_iterator FMOVE64X [DI DF DD])
402 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
403                                 (IF "FLOAT128_IBM_P (IFmode)")
404                                 (TD "TARGET_HARD_FLOAT")])
406 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
407                                     (IF "FLOAT128_2REG_P (IFmode)")
408                                     (TD "TARGET_HARD_FLOAT")])
410 ; Iterators for 128 bit types for direct move
411 (define_mode_iterator FMOVE128_GPR [TI
412                                     V16QI
413                                     V8HI
414                                     V4SI
415                                     V4SF
416                                     V2DI
417                                     V2DF
418                                     V1TI
419                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
420                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
422 ; Iterator for 128-bit VSX types for pack/unpack
423 (define_mode_iterator FMOVE128_VSX [V1TI KF])
425 ; Whether a floating point move is ok, don't allow SD without hardware FP
426 (define_mode_attr fmove_ok [(SF "")
427                             (DF "")
428                             (SD "TARGET_HARD_FLOAT")
429                             (DD "")])
431 ; Convert REAL_VALUE to the appropriate bits
432 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
433                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
434                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
435                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
437 ; Whether 0.0 has an all-zero bit pattern
438 (define_mode_attr zero_fp [(SF "j")
439                            (DF "j")
440                            (TF "j")
441                            (IF "j")
442                            (KF "j")
443                            (SD "wn")
444                            (DD "wn")
445                            (TD "wn")])
447 ; Definitions for 64-bit VSX
448 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
450 ; Definitions for 64-bit direct move
451 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
453 ; Definitions for 64-bit use of altivec registers
454 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
456 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
457 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
459 ; These modes do not fit in integer registers in 32-bit mode.
460 (define_mode_iterator DIFD [DI DF DD])
462 ; Iterator for reciprocal estimate instructions
463 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
465 ; Iterator for just SF/DF
466 (define_mode_iterator SFDF [SF DF])
468 ; Like SFDF, but a different name to match conditional move where the
469 ; comparison operands may be a different mode than the input operands.
470 (define_mode_iterator SFDF2 [SF DF])
472 ; Iterator for 128-bit floating point that uses the IBM double-double format
473 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
474                               (TF "FLOAT128_IBM_P (TFmode)")])
476 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
477 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
478                                (TF "FLOAT128_IEEE_P (TFmode)")])
480 ; Iterator for 128-bit floating point
481 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
482                                 (IF "TARGET_FLOAT128_TYPE")
483                                 (TF "TARGET_LONG_DOUBLE_128")])
485 ; Iterator for signbit on 64-bit machines with direct move
486 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
487                                (TF "FLOAT128_VECTOR_P (TFmode)")])
489 ; Iterator for ISA 3.0 supported floating point types
490 (define_mode_iterator FP_ISA3 [SF DF])
492 ; SF/DF suffix for traditional floating instructions
493 (define_mode_attr Ftrad         [(SF "s") (DF "")])
495 ; SF/DF suffix for VSX instructions
496 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
498 ; SF/DF constraint for arithmetic on traditional floating point registers
499 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
501 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
502 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
503 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
504 ; format.
505 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
507 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
508 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
509 ; instructions added in ISA 2.07 (power8)
510 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
512 ; SF/DF constraint for arithmetic on altivec registers
513 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
515 ; s/d suffix for things like sdiv/ddiv
516 (define_mode_attr Fs            [(SF "s")  (DF "d")])
518 ; FRE/FRES support
519 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
520 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
522 ; Conditional returns.
523 (define_code_iterator any_return [return simple_return])
524 (define_code_attr return_pred [(return "direct_return ()")
525                                (simple_return "1")])
526 (define_code_attr return_str [(return "") (simple_return "simple_")])
528 ; Logical operators.
529 (define_code_iterator iorxor            [ior xor])
530 (define_code_iterator and_ior_xor       [and ior xor])
532 ; Signed/unsigned variants of ops.
533 (define_code_iterator any_extend        [sign_extend zero_extend])
534 (define_code_iterator any_fix           [fix unsigned_fix])
535 (define_code_iterator any_float         [float unsigned_float])
537 (define_code_attr u  [(sign_extend      "")
538                       (zero_extend      "u")
539                       (fix              "")
540                       (unsigned_fix     "u")])
542 (define_code_attr su [(sign_extend      "s")
543                       (zero_extend      "u")
544                       (fix              "s")
545                       (unsigned_fix     "u")
546                       (float            "s")
547                       (unsigned_float   "u")])
549 (define_code_attr az [(sign_extend      "a")
550                       (zero_extend      "z")
551                       (fix              "a")
552                       (unsigned_fix     "z")
553                       (float            "a")
554                       (unsigned_float   "z")])
556 (define_code_attr uns [(fix             "")
557                        (unsigned_fix    "uns")
558                        (float           "")
559                        (unsigned_float  "uns")])
561 ; Various instructions that come in SI and DI forms.
562 ; A generic w/d attribute, for things like cmpw/cmpd.
563 (define_mode_attr wd [(QI    "b")
564                       (HI    "h")
565                       (SI    "w")
566                       (DI    "d")
567                       (V16QI "b")
568                       (V8HI  "h")
569                       (V4SI  "w")
570                       (V2DI  "d")
571                       (V1TI  "q")
572                       (TI    "q")])
574 ;; How many bits in this mode?
575 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
577 ; DImode bits
578 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
580 ;; Bitmask for shift instructions
581 (define_mode_attr hH [(SI "h") (DI "H")])
583 ;; A mode twice the size of the given mode
584 (define_mode_attr dmode [(SI "di") (DI "ti")])
585 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
587 ;; Suffix for reload patterns
588 (define_mode_attr ptrsize [(SI "32bit")
589                            (DI "64bit")])
591 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
592                             (DI "TARGET_64BIT")])
594 (define_mode_attr mptrsize [(SI "si")
595                             (DI "di")])
597 (define_mode_attr ptrload [(SI "lwz")
598                            (DI "ld")])
600 (define_mode_attr ptrm [(SI "m")
601                         (DI "Y")])
603 (define_mode_attr rreg [(SF   "f")
604                         (DF   "ws")
605                         (TF   "f")
606                         (TD   "f")
607                         (V4SF "wf")
608                         (V2DF "wd")])
610 (define_mode_attr rreg2 [(SF   "f")
611                          (DF   "d")])
613 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
614                                  (DF "TARGET_FCFID")])
616 ;; Mode iterator for logical operations on 128-bit types
617 (define_mode_iterator BOOL_128          [TI
618                                          PTI
619                                          (V16QI "TARGET_ALTIVEC")
620                                          (V8HI  "TARGET_ALTIVEC")
621                                          (V4SI  "TARGET_ALTIVEC")
622                                          (V4SF  "TARGET_ALTIVEC")
623                                          (V2DI  "TARGET_ALTIVEC")
624                                          (V2DF  "TARGET_ALTIVEC")
625                                          (V1TI  "TARGET_ALTIVEC")])
627 ;; For the GPRs we use 3 constraints for register outputs, two that are the
628 ;; same as the output register, and a third where the output register is an
629 ;; early clobber, so we don't have to deal with register overlaps.  For the
630 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
631 ;; either.
633 ;; Mode attribute for boolean operation register constraints for output
634 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
635                                          (PTI   "&r,r,r")
636                                          (V16QI "wa,v,&?r,?r,?r")
637                                          (V8HI  "wa,v,&?r,?r,?r")
638                                          (V4SI  "wa,v,&?r,?r,?r")
639                                          (V4SF  "wa,v,&?r,?r,?r")
640                                          (V2DI  "wa,v,&?r,?r,?r")
641                                          (V2DF  "wa,v,&?r,?r,?r")
642                                          (V1TI  "wa,v,&?r,?r,?r")])
644 ;; Mode attribute for boolean operation register constraints for operand1
645 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
646                                          (PTI   "r,0,r")
647                                          (V16QI "wa,v,r,0,r")
648                                          (V8HI  "wa,v,r,0,r")
649                                          (V4SI  "wa,v,r,0,r")
650                                          (V4SF  "wa,v,r,0,r")
651                                          (V2DI  "wa,v,r,0,r")
652                                          (V2DF  "wa,v,r,0,r")
653                                          (V1TI  "wa,v,r,0,r")])
655 ;; Mode attribute for boolean operation register constraints for operand2
656 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
657                                          (PTI   "r,r,0")
658                                          (V16QI "wa,v,r,r,0")
659                                          (V8HI  "wa,v,r,r,0")
660                                          (V4SI  "wa,v,r,r,0")
661                                          (V4SF  "wa,v,r,r,0")
662                                          (V2DI  "wa,v,r,r,0")
663                                          (V2DF  "wa,v,r,r,0")
664                                          (V1TI  "wa,v,r,r,0")])
666 ;; Mode attribute for boolean operation register constraints for operand1
667 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
668 ;; is used for operand1 or operand2
669 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
670                                          (PTI   "r,0,0")
671                                          (V16QI "wa,v,r,0,0")
672                                          (V8HI  "wa,v,r,0,0")
673                                          (V4SI  "wa,v,r,0,0")
674                                          (V4SF  "wa,v,r,0,0")
675                                          (V2DI  "wa,v,r,0,0")
676                                          (V2DF  "wa,v,r,0,0")
677                                          (V1TI  "wa,v,r,0,0")])
679 ;; Reload iterator for creating the function to allocate a base register to
680 ;; supplement addressing modes.
681 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
682                               SF SD SI DF DD DI TI PTI KF IF TF])
684 ;; Iterate over smin, smax
685 (define_code_iterator fp_minmax [smin smax])
687 (define_code_attr     minmax    [(smin "min")
688                                  (smax "max")])
690 (define_code_attr     SMINMAX   [(smin "SMIN")
691                                  (smax "SMAX")])
693 ;; Iterator to optimize the following cases:
694 ;;      D-form load to FPR register & move to Altivec register
695 ;;      Move Altivec register to FPR register and store
696 (define_mode_iterator ALTIVEC_DFORM [DF
697                                      (SF "TARGET_P8_VECTOR")
698                                      (DI "TARGET_POWERPC64")])
701 ;; Start with fixed-point load and store insns.  Here we put only the more
702 ;; complex forms.  Basic data transfer is done later.
704 (define_insn "zero_extendqi<mode>2"
705   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
706         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
707   ""
708   "@
709    lbz%U1%X1 %0,%1
710    rlwinm %0,%1,0,0xff
711    lxsibzx %x0,%y1
712    vextractub %0,%1,7"
713   [(set_attr "type" "load,shift,fpload,vecperm")])
715 (define_insn_and_split "*zero_extendqi<mode>2_dot"
716   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
717         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
718                     (const_int 0)))
719    (clobber (match_scratch:EXTQI 0 "=r,r"))]
720   ""
721   "@
722    andi. %0,%1,0xff
723    #"
724   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
725   [(set (match_dup 0)
726         (zero_extend:EXTQI (match_dup 1)))
727    (set (match_dup 2)
728         (compare:CC (match_dup 0)
729                     (const_int 0)))]
730   ""
731   [(set_attr "type" "logical")
732    (set_attr "dot" "yes")
733    (set_attr "length" "4,8")])
735 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
736   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
737         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
738                     (const_int 0)))
739    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
740         (zero_extend:EXTQI (match_dup 1)))]
741   ""
742   "@
743    andi. %0,%1,0xff
744    #"
745   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
746   [(set (match_dup 0)
747         (zero_extend:EXTQI (match_dup 1)))
748    (set (match_dup 2)
749         (compare:CC (match_dup 0)
750                     (const_int 0)))]
751   ""
752   [(set_attr "type" "logical")
753    (set_attr "dot" "yes")
754    (set_attr "length" "4,8")])
757 (define_insn "zero_extendhi<mode>2"
758   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
759         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
760   ""
761   "@
762    lhz%U1%X1 %0,%1
763    rlwinm %0,%1,0,0xffff
764    lxsihzx %x0,%y1
765    vextractuh %0,%1,6"
766   [(set_attr "type" "load,shift,fpload,vecperm")])
768 (define_insn_and_split "*zero_extendhi<mode>2_dot"
769   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
770         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
771                     (const_int 0)))
772    (clobber (match_scratch:EXTHI 0 "=r,r"))]
773   ""
774   "@
775    andi. %0,%1,0xffff
776    #"
777   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
778   [(set (match_dup 0)
779         (zero_extend:EXTHI (match_dup 1)))
780    (set (match_dup 2)
781         (compare:CC (match_dup 0)
782                     (const_int 0)))]
783   ""
784   [(set_attr "type" "logical")
785    (set_attr "dot" "yes")
786    (set_attr "length" "4,8")])
788 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
789   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
790         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
791                     (const_int 0)))
792    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
793         (zero_extend:EXTHI (match_dup 1)))]
794   ""
795   "@
796    andi. %0,%1,0xffff
797    #"
798   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
799   [(set (match_dup 0)
800         (zero_extend:EXTHI (match_dup 1)))
801    (set (match_dup 2)
802         (compare:CC (match_dup 0)
803                     (const_int 0)))]
804   ""
805   [(set_attr "type" "logical")
806    (set_attr "dot" "yes")
807    (set_attr "length" "4,8")])
810 (define_insn "zero_extendsi<mode>2"
811   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
812         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
813   ""
814   "@
815    lwz%U1%X1 %0,%1
816    rldicl %0,%1,0,32
817    lfiwzx %0,%y1
818    lxsiwzx %x0,%y1
819    mtvsrwz %x0,%1
820    mfvsrwz %0,%x1
821    xxextractuw %x0,%x1,4"
822   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
824 (define_insn_and_split "*zero_extendsi<mode>2_dot"
825   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
826         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
827                     (const_int 0)))
828    (clobber (match_scratch:EXTSI 0 "=r,r"))]
829   ""
830   "@
831    rldicl. %0,%1,0,32
832    #"
833   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
834   [(set (match_dup 0)
835         (zero_extend:DI (match_dup 1)))
836    (set (match_dup 2)
837         (compare:CC (match_dup 0)
838                     (const_int 0)))]
839   ""
840   [(set_attr "type" "shift")
841    (set_attr "dot" "yes")
842    (set_attr "length" "4,8")])
844 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
845   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
846         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
847                     (const_int 0)))
848    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
849         (zero_extend:EXTSI (match_dup 1)))]
850   ""
851   "@
852    rldicl. %0,%1,0,32
853    #"
854   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
855   [(set (match_dup 0)
856         (zero_extend:EXTSI (match_dup 1)))
857    (set (match_dup 2)
858         (compare:CC (match_dup 0)
859                     (const_int 0)))]
860   ""
861   [(set_attr "type" "shift")
862    (set_attr "dot" "yes")
863    (set_attr "length" "4,8")])
866 (define_insn "extendqi<mode>2"
867   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
868         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
869   ""
870   "@
871    extsb %0,%1
872    vextsb2d %0,%1"
873   [(set_attr "type" "exts,vecperm")])
875 (define_insn_and_split "*extendqi<mode>2_dot"
876   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
877         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
878                     (const_int 0)))
879    (clobber (match_scratch:EXTQI 0 "=r,r"))]
880   ""
881   "@
882    extsb. %0,%1
883    #"
884   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
885   [(set (match_dup 0)
886         (sign_extend:EXTQI (match_dup 1)))
887    (set (match_dup 2)
888         (compare:CC (match_dup 0)
889                     (const_int 0)))]
890   ""
891   [(set_attr "type" "exts")
892    (set_attr "dot" "yes")
893    (set_attr "length" "4,8")])
895 (define_insn_and_split "*extendqi<mode>2_dot2"
896   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
897         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
898                     (const_int 0)))
899    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
900         (sign_extend:EXTQI (match_dup 1)))]
901   ""
902   "@
903    extsb. %0,%1
904    #"
905   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
906   [(set (match_dup 0)
907         (sign_extend:EXTQI (match_dup 1)))
908    (set (match_dup 2)
909         (compare:CC (match_dup 0)
910                     (const_int 0)))]
911   ""
912   [(set_attr "type" "exts")
913    (set_attr "dot" "yes")
914    (set_attr "length" "4,8")])
917 (define_expand "extendhi<mode>2"
918   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
919         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
920   ""
921   "")
923 (define_insn "*extendhi<mode>2"
924   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
925         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
926   ""
927   "@
928    lha%U1%X1 %0,%1
929    extsh %0,%1
930    #
931    vextsh2d %0,%1"
932   [(set_attr "type" "load,exts,fpload,vecperm")
933    (set_attr "sign_extend" "yes")
934    (set_attr "length" "4,4,8,4")])
936 (define_split
937   [(set (match_operand:EXTHI 0 "altivec_register_operand")
938         (sign_extend:EXTHI
939          (match_operand:HI 1 "indexed_or_indirect_operand")))]
940   "TARGET_P9_VECTOR && reload_completed"
941   [(set (match_dup 2)
942         (match_dup 1))
943    (set (match_dup 0)
944         (sign_extend:EXTHI (match_dup 2)))]
946   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
949 (define_insn_and_split "*extendhi<mode>2_dot"
950   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
951         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
952                     (const_int 0)))
953    (clobber (match_scratch:EXTHI 0 "=r,r"))]
954   ""
955   "@
956    extsh. %0,%1
957    #"
958   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
959   [(set (match_dup 0)
960         (sign_extend:EXTHI (match_dup 1)))
961    (set (match_dup 2)
962         (compare:CC (match_dup 0)
963                     (const_int 0)))]
964   ""
965   [(set_attr "type" "exts")
966    (set_attr "dot" "yes")
967    (set_attr "length" "4,8")])
969 (define_insn_and_split "*extendhi<mode>2_dot2"
970   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
971         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
972                     (const_int 0)))
973    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
974         (sign_extend:EXTHI (match_dup 1)))]
975   ""
976   "@
977    extsh. %0,%1
978    #"
979   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
980   [(set (match_dup 0)
981         (sign_extend:EXTHI (match_dup 1)))
982    (set (match_dup 2)
983         (compare:CC (match_dup 0)
984                     (const_int 0)))]
985   ""
986   [(set_attr "type" "exts")
987    (set_attr "dot" "yes")
988    (set_attr "length" "4,8")])
991 (define_insn "extendsi<mode>2"
992   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
993                      "=r, r,   wl,    wu,    wj,    wK,     wH,    wr")
995         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
996                      "Y,  r,   Z,     Z,     r,     wK,     wH,    ?wIwH")))]
997   ""
998   "@
999    lwa%U1%X1 %0,%1
1000    extsw %0,%1
1001    lfiwax %0,%y1
1002    lxsiwax %x0,%y1
1003    mtvsrwa %x0,%1
1004    vextsw2d %0,%1
1005    #
1006    #"
1007   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1008    (set_attr "sign_extend" "yes")
1009    (set_attr "length" "4,4,4,4,4,4,8,8")])
1011 (define_split
1012   [(set (match_operand:EXTSI 0 "int_reg_operand")
1013         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1014   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1015   [(set (match_dup 2)
1016         (match_dup 1))
1017    (set (match_dup 0)
1018         (sign_extend:DI (match_dup 2)))]
1020   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1023 (define_split
1024   [(set (match_operand:DI 0 "altivec_register_operand")
1025         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1026   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1027   [(const_int 0)]
1029   rtx dest = operands[0];
1030   rtx src = operands[1];
1031   int dest_regno = REGNO (dest);
1032   int src_regno = REGNO (src);
1033   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1034   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1036   if (BYTES_BIG_ENDIAN)
1037     {
1038       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1039       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1040     }
1041   else
1042     {
1043       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1044       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1045     }
1046   DONE;
1049 (define_insn_and_split "*extendsi<mode>2_dot"
1050   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1051         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1052                     (const_int 0)))
1053    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1054   ""
1055   "@
1056    extsw. %0,%1
1057    #"
1058   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1059   [(set (match_dup 0)
1060         (sign_extend:EXTSI (match_dup 1)))
1061    (set (match_dup 2)
1062         (compare:CC (match_dup 0)
1063                     (const_int 0)))]
1064   ""
1065   [(set_attr "type" "exts")
1066    (set_attr "dot" "yes")
1067    (set_attr "length" "4,8")])
1069 (define_insn_and_split "*extendsi<mode>2_dot2"
1070   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1071         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1072                     (const_int 0)))
1073    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1074         (sign_extend:EXTSI (match_dup 1)))]
1075   ""
1076   "@
1077    extsw. %0,%1
1078    #"
1079   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1080   [(set (match_dup 0)
1081         (sign_extend:EXTSI (match_dup 1)))
1082    (set (match_dup 2)
1083         (compare:CC (match_dup 0)
1084                     (const_int 0)))]
1085   ""
1086   [(set_attr "type" "exts")
1087    (set_attr "dot" "yes")
1088    (set_attr "length" "4,8")])
1090 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1092 (define_insn "*macchwc"
1093   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1094         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1095                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1096                                        (const_int 16))
1097                                       (sign_extend:SI
1098                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1099                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1100                     (const_int 0)))
1101    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1102         (plus:SI (mult:SI (ashiftrt:SI
1103                            (match_dup 2)
1104                            (const_int 16))
1105                           (sign_extend:SI
1106                            (match_dup 1)))
1107                  (match_dup 4)))]
1108   "TARGET_MULHW"
1109   "macchw. %0,%1,%2"
1110   [(set_attr "type" "halfmul")])
1112 (define_insn "*macchw"
1113   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1114         (plus:SI (mult:SI (ashiftrt:SI
1115                            (match_operand:SI 2 "gpc_reg_operand" "r")
1116                            (const_int 16))
1117                           (sign_extend:SI
1118                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1119                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1120   "TARGET_MULHW"
1121   "macchw %0,%1,%2"
1122   [(set_attr "type" "halfmul")])
1124 (define_insn "*macchwuc"
1125   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1126         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1127                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1128                                        (const_int 16))
1129                                       (zero_extend:SI
1130                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1131                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1132                     (const_int 0)))
1133    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1134         (plus:SI (mult:SI (lshiftrt:SI
1135                            (match_dup 2)
1136                            (const_int 16))
1137                           (zero_extend:SI
1138                            (match_dup 1)))
1139                  (match_dup 4)))]
1140   "TARGET_MULHW"
1141   "macchwu. %0,%1,%2"
1142   [(set_attr "type" "halfmul")])
1144 (define_insn "*macchwu"
1145   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1146         (plus:SI (mult:SI (lshiftrt:SI
1147                            (match_operand:SI 2 "gpc_reg_operand" "r")
1148                            (const_int 16))
1149                           (zero_extend:SI
1150                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1151                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1152   "TARGET_MULHW"
1153   "macchwu %0,%1,%2"
1154   [(set_attr "type" "halfmul")])
1156 (define_insn "*machhwc"
1157   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1158         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1159                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1160                                        (const_int 16))
1161                                       (ashiftrt:SI
1162                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1163                                        (const_int 16)))
1164                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1165                     (const_int 0)))
1166    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1167         (plus:SI (mult:SI (ashiftrt:SI
1168                            (match_dup 1)
1169                            (const_int 16))
1170                           (ashiftrt:SI
1171                            (match_dup 2)
1172                            (const_int 16)))
1173                  (match_dup 4)))]
1174   "TARGET_MULHW"
1175   "machhw. %0,%1,%2"
1176   [(set_attr "type" "halfmul")])
1178 (define_insn "*machhw"
1179   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1180         (plus:SI (mult:SI (ashiftrt:SI
1181                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1182                            (const_int 16))
1183                           (ashiftrt:SI
1184                            (match_operand:SI 2 "gpc_reg_operand" "r")
1185                            (const_int 16)))
1186                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1187   "TARGET_MULHW"
1188   "machhw %0,%1,%2"
1189   [(set_attr "type" "halfmul")])
1191 (define_insn "*machhwuc"
1192   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1193         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1194                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1195                                        (const_int 16))
1196                                       (lshiftrt:SI
1197                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1198                                        (const_int 16)))
1199                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1200                     (const_int 0)))
1201    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202         (plus:SI (mult:SI (lshiftrt:SI
1203                            (match_dup 1)
1204                            (const_int 16))
1205                           (lshiftrt:SI
1206                            (match_dup 2)
1207                            (const_int 16)))
1208                  (match_dup 4)))]
1209   "TARGET_MULHW"
1210   "machhwu. %0,%1,%2"
1211   [(set_attr "type" "halfmul")])
1213 (define_insn "*machhwu"
1214   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1215         (plus:SI (mult:SI (lshiftrt:SI
1216                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1217                            (const_int 16))
1218                           (lshiftrt:SI
1219                            (match_operand:SI 2 "gpc_reg_operand" "r")
1220                            (const_int 16)))
1221                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1222   "TARGET_MULHW"
1223   "machhwu %0,%1,%2"
1224   [(set_attr "type" "halfmul")])
1226 (define_insn "*maclhwc"
1227   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1228         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1229                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1230                                       (sign_extend:SI
1231                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1232                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1233                     (const_int 0)))
1234    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235         (plus:SI (mult:SI (sign_extend:SI
1236                            (match_dup 1))
1237                           (sign_extend:SI
1238                            (match_dup 2)))
1239                  (match_dup 4)))]
1240   "TARGET_MULHW"
1241   "maclhw. %0,%1,%2"
1242   [(set_attr "type" "halfmul")])
1244 (define_insn "*maclhw"
1245   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246         (plus:SI (mult:SI (sign_extend:SI
1247                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1248                           (sign_extend:SI
1249                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1250                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1251   "TARGET_MULHW"
1252   "maclhw %0,%1,%2"
1253   [(set_attr "type" "halfmul")])
1255 (define_insn "*maclhwuc"
1256   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1257         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1258                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1259                                       (zero_extend:SI
1260                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1261                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1262                     (const_int 0)))
1263    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264         (plus:SI (mult:SI (zero_extend:SI
1265                            (match_dup 1))
1266                           (zero_extend:SI
1267                            (match_dup 2)))
1268                  (match_dup 4)))]
1269   "TARGET_MULHW"
1270   "maclhwu. %0,%1,%2"
1271   [(set_attr "type" "halfmul")])
1273 (define_insn "*maclhwu"
1274   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1275         (plus:SI (mult:SI (zero_extend:SI
1276                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1277                           (zero_extend:SI
1278                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1279                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1280   "TARGET_MULHW"
1281   "maclhwu %0,%1,%2"
1282   [(set_attr "type" "halfmul")])
1284 (define_insn "*nmacchwc"
1285   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1286         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1287                               (mult:SI (ashiftrt:SI
1288                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1289                                         (const_int 16))
1290                                        (sign_extend:SI
1291                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1292                     (const_int 0)))
1293    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1294         (minus:SI (match_dup 4)
1295                   (mult:SI (ashiftrt:SI
1296                             (match_dup 2)
1297                             (const_int 16))
1298                            (sign_extend:SI
1299                             (match_dup 1)))))]
1300   "TARGET_MULHW"
1301   "nmacchw. %0,%1,%2"
1302   [(set_attr "type" "halfmul")])
1304 (define_insn "*nmacchw"
1305   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1306         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1307                   (mult:SI (ashiftrt:SI
1308                             (match_operand:SI 2 "gpc_reg_operand" "r")
1309                             (const_int 16))
1310                            (sign_extend:SI
1311                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1312   "TARGET_MULHW"
1313   "nmacchw %0,%1,%2"
1314   [(set_attr "type" "halfmul")])
1316 (define_insn "*nmachhwc"
1317   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1318         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1319                               (mult:SI (ashiftrt:SI
1320                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1321                                         (const_int 16))
1322                                        (ashiftrt:SI
1323                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1324                                         (const_int 16))))
1325                     (const_int 0)))
1326    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1327         (minus:SI (match_dup 4)
1328                   (mult:SI (ashiftrt:SI
1329                             (match_dup 1)
1330                             (const_int 16))
1331                            (ashiftrt:SI
1332                             (match_dup 2)
1333                             (const_int 16)))))]
1334   "TARGET_MULHW"
1335   "nmachhw. %0,%1,%2"
1336   [(set_attr "type" "halfmul")])
1338 (define_insn "*nmachhw"
1339   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1340         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1341                   (mult:SI (ashiftrt:SI
1342                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1343                             (const_int 16))
1344                            (ashiftrt:SI
1345                             (match_operand:SI 2 "gpc_reg_operand" "r")
1346                             (const_int 16)))))]
1347   "TARGET_MULHW"
1348   "nmachhw %0,%1,%2"
1349   [(set_attr "type" "halfmul")])
1351 (define_insn "*nmaclhwc"
1352   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1354                               (mult:SI (sign_extend:SI
1355                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1356                                        (sign_extend:SI
1357                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1358                     (const_int 0)))
1359    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1360         (minus:SI (match_dup 4)
1361                   (mult:SI (sign_extend:SI
1362                             (match_dup 1))
1363                            (sign_extend:SI
1364                             (match_dup 2)))))]
1365   "TARGET_MULHW"
1366   "nmaclhw. %0,%1,%2"
1367   [(set_attr "type" "halfmul")])
1369 (define_insn "*nmaclhw"
1370   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1372                   (mult:SI (sign_extend:SI
1373                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1374                            (sign_extend:SI
1375                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1376   "TARGET_MULHW"
1377   "nmaclhw %0,%1,%2"
1378   [(set_attr "type" "halfmul")])
1380 (define_insn "*mulchwc"
1381   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1382         (compare:CC (mult:SI (ashiftrt:SI
1383                               (match_operand:SI 2 "gpc_reg_operand" "r")
1384                               (const_int 16))
1385                              (sign_extend:SI
1386                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1387                     (const_int 0)))
1388    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389         (mult:SI (ashiftrt:SI
1390                   (match_dup 2)
1391                   (const_int 16))
1392                  (sign_extend:SI
1393                   (match_dup 1))))]
1394   "TARGET_MULHW"
1395   "mulchw. %0,%1,%2"
1396   [(set_attr "type" "halfmul")])
1398 (define_insn "*mulchw"
1399   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400         (mult:SI (ashiftrt:SI
1401                   (match_operand:SI 2 "gpc_reg_operand" "r")
1402                   (const_int 16))
1403                  (sign_extend:SI
1404                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1405   "TARGET_MULHW"
1406   "mulchw %0,%1,%2"
1407   [(set_attr "type" "halfmul")])
1409 (define_insn "*mulchwuc"
1410   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1411         (compare:CC (mult:SI (lshiftrt:SI
1412                               (match_operand:SI 2 "gpc_reg_operand" "r")
1413                               (const_int 16))
1414                              (zero_extend:SI
1415                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1416                     (const_int 0)))
1417    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1418         (mult:SI (lshiftrt:SI
1419                   (match_dup 2)
1420                   (const_int 16))
1421                  (zero_extend:SI
1422                   (match_dup 1))))]
1423   "TARGET_MULHW"
1424   "mulchwu. %0,%1,%2"
1425   [(set_attr "type" "halfmul")])
1427 (define_insn "*mulchwu"
1428   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1429         (mult:SI (lshiftrt:SI
1430                   (match_operand:SI 2 "gpc_reg_operand" "r")
1431                   (const_int 16))
1432                  (zero_extend:SI
1433                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1434   "TARGET_MULHW"
1435   "mulchwu %0,%1,%2"
1436   [(set_attr "type" "halfmul")])
1438 (define_insn "*mulhhwc"
1439   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1440         (compare:CC (mult:SI (ashiftrt:SI
1441                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1442                               (const_int 16))
1443                              (ashiftrt:SI
1444                               (match_operand:SI 2 "gpc_reg_operand" "r")
1445                               (const_int 16)))
1446                     (const_int 0)))
1447    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1448         (mult:SI (ashiftrt:SI
1449                   (match_dup 1)
1450                   (const_int 16))
1451                  (ashiftrt:SI
1452                   (match_dup 2)
1453                   (const_int 16))))]
1454   "TARGET_MULHW"
1455   "mulhhw. %0,%1,%2"
1456   [(set_attr "type" "halfmul")])
1458 (define_insn "*mulhhw"
1459   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1460         (mult:SI (ashiftrt:SI
1461                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1462                   (const_int 16))
1463                  (ashiftrt:SI
1464                   (match_operand:SI 2 "gpc_reg_operand" "r")
1465                   (const_int 16))))]
1466   "TARGET_MULHW"
1467   "mulhhw %0,%1,%2"
1468   [(set_attr "type" "halfmul")])
1470 (define_insn "*mulhhwuc"
1471   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1472         (compare:CC (mult:SI (lshiftrt:SI
1473                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1474                               (const_int 16))
1475                              (lshiftrt:SI
1476                               (match_operand:SI 2 "gpc_reg_operand" "r")
1477                               (const_int 16)))
1478                     (const_int 0)))
1479    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1480         (mult:SI (lshiftrt:SI
1481                   (match_dup 1)
1482                   (const_int 16))
1483                  (lshiftrt:SI
1484                   (match_dup 2)
1485                   (const_int 16))))]
1486   "TARGET_MULHW"
1487   "mulhhwu. %0,%1,%2"
1488   [(set_attr "type" "halfmul")])
1490 (define_insn "*mulhhwu"
1491   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1492         (mult:SI (lshiftrt:SI
1493                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1494                   (const_int 16))
1495                  (lshiftrt:SI
1496                   (match_operand:SI 2 "gpc_reg_operand" "r")
1497                   (const_int 16))))]
1498   "TARGET_MULHW"
1499   "mulhhwu %0,%1,%2"
1500   [(set_attr "type" "halfmul")])
1502 (define_insn "*mullhwc"
1503   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1504         (compare:CC (mult:SI (sign_extend:SI
1505                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1506                              (sign_extend:SI
1507                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1508                     (const_int 0)))
1509    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1510         (mult:SI (sign_extend:SI
1511                   (match_dup 1))
1512                  (sign_extend:SI
1513                   (match_dup 2))))]
1514   "TARGET_MULHW"
1515   "mullhw. %0,%1,%2"
1516   [(set_attr "type" "halfmul")])
1518 (define_insn "*mullhw"
1519   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1520         (mult:SI (sign_extend:SI
1521                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1522                  (sign_extend:SI
1523                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1524   "TARGET_MULHW"
1525   "mullhw %0,%1,%2"
1526   [(set_attr "type" "halfmul")])
1528 (define_insn "*mullhwuc"
1529   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1530         (compare:CC (mult:SI (zero_extend:SI
1531                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1532                              (zero_extend:SI
1533                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1534                     (const_int 0)))
1535    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1536         (mult:SI (zero_extend:SI
1537                   (match_dup 1))
1538                  (zero_extend:SI
1539                   (match_dup 2))))]
1540   "TARGET_MULHW"
1541   "mullhwu. %0,%1,%2"
1542   [(set_attr "type" "halfmul")])
1544 (define_insn "*mullhwu"
1545   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1546         (mult:SI (zero_extend:SI
1547                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1548                  (zero_extend:SI
1549                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1550   "TARGET_MULHW"
1551   "mullhwu %0,%1,%2"
1552   [(set_attr "type" "halfmul")])
1554 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1555 (define_insn "dlmzb"
1556   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1557         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1558                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1559                    UNSPEC_DLMZB_CR))
1560    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1561         (unspec:SI [(match_dup 1)
1562                     (match_dup 2)]
1563                    UNSPEC_DLMZB))]
1564   "TARGET_DLMZB"
1565   "dlmzb. %0,%1,%2")
1567 (define_expand "strlensi"
1568   [(set (match_operand:SI 0 "gpc_reg_operand")
1569         (unspec:SI [(match_operand:BLK 1 "general_operand")
1570                     (match_operand:QI 2 "const_int_operand")
1571                     (match_operand 3 "const_int_operand")]
1572                    UNSPEC_DLMZB_STRLEN))
1573    (clobber (match_scratch:CC 4))]
1574   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1576   rtx result = operands[0];
1577   rtx src = operands[1];
1578   rtx search_char = operands[2];
1579   rtx align = operands[3];
1580   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1581   rtx loop_label, end_label, mem, cr0, cond;
1582   if (search_char != const0_rtx
1583       || GET_CODE (align) != CONST_INT
1584       || INTVAL (align) < 8)
1585         FAIL;
1586   word1 = gen_reg_rtx (SImode);
1587   word2 = gen_reg_rtx (SImode);
1588   scratch_dlmzb = gen_reg_rtx (SImode);
1589   scratch_string = gen_reg_rtx (Pmode);
1590   loop_label = gen_label_rtx ();
1591   end_label = gen_label_rtx ();
1592   addr = force_reg (Pmode, XEXP (src, 0));
1593   emit_move_insn (scratch_string, addr);
1594   emit_label (loop_label);
1595   mem = change_address (src, SImode, scratch_string);
1596   emit_move_insn (word1, mem);
1597   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1598   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1599   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1600   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1601   emit_jump_insn (gen_rtx_SET (pc_rtx,
1602                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1603                                                      cond,
1604                                                      gen_rtx_LABEL_REF
1605                                                        (VOIDmode,
1606                                                         end_label),
1607                                                      pc_rtx)));
1608   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1609   emit_jump_insn (gen_rtx_SET (pc_rtx,
1610                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1611   emit_barrier ();
1612   emit_label (end_label);
1613   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1614   emit_insn (gen_subsi3 (result, scratch_string, addr));
1615   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1616   DONE;
1619 ;; Fixed-point arithmetic insns.
1621 (define_expand "add<mode>3"
1622   [(set (match_operand:SDI 0 "gpc_reg_operand")
1623         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1624                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1625   ""
1627   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1628     {
1629       rtx lo0 = gen_lowpart (SImode, operands[0]);
1630       rtx lo1 = gen_lowpart (SImode, operands[1]);
1631       rtx lo2 = gen_lowpart (SImode, operands[2]);
1632       rtx hi0 = gen_highpart (SImode, operands[0]);
1633       rtx hi1 = gen_highpart (SImode, operands[1]);
1634       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1636       if (!reg_or_short_operand (lo2, SImode))
1637         lo2 = force_reg (SImode, lo2);
1638       if (!adde_operand (hi2, SImode))
1639         hi2 = force_reg (SImode, hi2);
1641       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1642       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1643       DONE;
1644     }
1646   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1647     {
1648       rtx tmp = ((!can_create_pseudo_p ()
1649                   || rtx_equal_p (operands[0], operands[1]))
1650                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1652       /* Adding a constant to r0 is not a valid insn, so use a different
1653          strategy in that case.  */
1654       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1655         {
1656           if (operands[0] == operands[1])
1657             FAIL;
1658           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1659           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1660           DONE;
1661         }
1663       HOST_WIDE_INT val = INTVAL (operands[2]);
1664       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1665       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1667       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1668         FAIL;
1670       /* The ordering here is important for the prolog expander.
1671          When space is allocated from the stack, adding 'low' first may
1672          produce a temporary deallocation (which would be bad).  */
1673       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1674       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1675       DONE;
1676     }
1679 (define_insn "*add<mode>3"
1680   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1681         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1682                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1683   ""
1684   "@
1685    add %0,%1,%2
1686    addi %0,%1,%2
1687    addis %0,%1,%v2"
1688   [(set_attr "type" "add")])
1690 (define_insn "addsi3_high"
1691   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1692         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1693                  (high:SI (match_operand 2 "" ""))))]
1694   "TARGET_MACHO && !TARGET_64BIT"
1695   "addis %0,%1,ha16(%2)"
1696   [(set_attr "type" "add")])
1698 (define_insn_and_split "*add<mode>3_dot"
1699   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1700         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1701                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1702                     (const_int 0)))
1703    (clobber (match_scratch:GPR 0 "=r,r"))]
1704   "<MODE>mode == Pmode"
1705   "@
1706    add. %0,%1,%2
1707    #"
1708   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1709   [(set (match_dup 0)
1710         (plus:GPR (match_dup 1)
1711                  (match_dup 2)))
1712    (set (match_dup 3)
1713         (compare:CC (match_dup 0)
1714                     (const_int 0)))]
1715   ""
1716   [(set_attr "type" "add")
1717    (set_attr "dot" "yes")
1718    (set_attr "length" "4,8")])
1720 (define_insn_and_split "*add<mode>3_dot2"
1721   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1722         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1723                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1724                     (const_int 0)))
1725    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1726         (plus:GPR (match_dup 1)
1727                   (match_dup 2)))]
1728   "<MODE>mode == Pmode"
1729   "@
1730    add. %0,%1,%2
1731    #"
1732   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1733   [(set (match_dup 0)
1734         (plus:GPR (match_dup 1)
1735                   (match_dup 2)))
1736    (set (match_dup 3)
1737         (compare:CC (match_dup 0)
1738                     (const_int 0)))]
1739   ""
1740   [(set_attr "type" "add")
1741    (set_attr "dot" "yes")
1742    (set_attr "length" "4,8")])
1744 (define_insn_and_split "*add<mode>3_imm_dot"
1745   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1746         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1747                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1748                     (const_int 0)))
1749    (clobber (match_scratch:GPR 0 "=r,r"))
1750    (clobber (reg:GPR CA_REGNO))]
1751   "<MODE>mode == Pmode"
1752   "@
1753    addic. %0,%1,%2
1754    #"
1755   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1756   [(set (match_dup 0)
1757         (plus:GPR (match_dup 1)
1758                   (match_dup 2)))
1759    (set (match_dup 3)
1760         (compare:CC (match_dup 0)
1761                     (const_int 0)))]
1762   ""
1763   [(set_attr "type" "add")
1764    (set_attr "dot" "yes")
1765    (set_attr "length" "4,8")])
1767 (define_insn_and_split "*add<mode>3_imm_dot2"
1768   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1769         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1770                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1771                     (const_int 0)))
1772    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1773         (plus:GPR (match_dup 1)
1774                   (match_dup 2)))
1775    (clobber (reg:GPR CA_REGNO))]
1776   "<MODE>mode == Pmode"
1777   "@
1778    addic. %0,%1,%2
1779    #"
1780   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1781   [(set (match_dup 0)
1782         (plus:GPR (match_dup 1)
1783                   (match_dup 2)))
1784    (set (match_dup 3)
1785         (compare:CC (match_dup 0)
1786                     (const_int 0)))]
1787   ""
1788   [(set_attr "type" "add")
1789    (set_attr "dot" "yes")
1790    (set_attr "length" "4,8")])
1792 ;; Split an add that we can't do in one insn into two insns, each of which
1793 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1794 ;; add should be last in case the result gets used in an address.
1796 (define_split
1797   [(set (match_operand:GPR 0 "gpc_reg_operand")
1798         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1799                   (match_operand:GPR 2 "non_add_cint_operand")))]
1800   ""
1801   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1802    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1804   HOST_WIDE_INT val = INTVAL (operands[2]);
1805   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1806   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1808   operands[4] = GEN_INT (low);
1809   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1810     operands[3] = GEN_INT (rest);
1811   else if (can_create_pseudo_p ())
1812     {
1813       operands[3] = gen_reg_rtx (DImode);
1814       emit_move_insn (operands[3], operands[2]);
1815       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1816       DONE;
1817     }
1818   else
1819     FAIL;
1823 (define_insn "add<mode>3_carry"
1824   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1825         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1826                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1827    (set (reg:P CA_REGNO)
1828         (ltu:P (plus:P (match_dup 1)
1829                        (match_dup 2))
1830                (match_dup 1)))]
1831   ""
1832   "add%I2c %0,%1,%2"
1833   [(set_attr "type" "add")])
1835 (define_insn "*add<mode>3_imm_carry_pos"
1836   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1837         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1838                 (match_operand:P 2 "short_cint_operand" "n")))
1839    (set (reg:P CA_REGNO)
1840         (geu:P (match_dup 1)
1841                (match_operand:P 3 "const_int_operand" "n")))]
1842   "INTVAL (operands[2]) > 0
1843    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1844   "addic %0,%1,%2"
1845   [(set_attr "type" "add")])
1847 (define_insn "*add<mode>3_imm_carry_0"
1848   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1849         (match_operand:P 1 "gpc_reg_operand" "r"))
1850    (set (reg:P CA_REGNO)
1851         (const_int 0))]
1852   ""
1853   "addic %0,%1,0"
1854   [(set_attr "type" "add")])
1856 (define_insn "*add<mode>3_imm_carry_m1"
1857   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1858         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1859                 (const_int -1)))
1860    (set (reg:P CA_REGNO)
1861         (ne:P (match_dup 1)
1862               (const_int 0)))]
1863   ""
1864   "addic %0,%1,-1"
1865   [(set_attr "type" "add")])
1867 (define_insn "*add<mode>3_imm_carry_neg"
1868   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1869         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1870                 (match_operand:P 2 "short_cint_operand" "n")))
1871    (set (reg:P CA_REGNO)
1872         (gtu:P (match_dup 1)
1873                (match_operand:P 3 "const_int_operand" "n")))]
1874   "INTVAL (operands[2]) < 0
1875    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1876   "addic %0,%1,%2"
1877   [(set_attr "type" "add")])
1880 (define_expand "add<mode>3_carry_in"
1881   [(parallel [
1882      (set (match_operand:GPR 0 "gpc_reg_operand")
1883           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1884                               (match_operand:GPR 2 "adde_operand"))
1885                     (reg:GPR CA_REGNO)))
1886      (clobber (reg:GPR CA_REGNO))])]
1887   ""
1889   if (operands[2] == const0_rtx)
1890     {
1891       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1892       DONE;
1893     }
1894   if (operands[2] == constm1_rtx)
1895     {
1896       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1897       DONE;
1898     }
1901 (define_insn "*add<mode>3_carry_in_internal"
1902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1905                   (reg:GPR CA_REGNO)))
1906    (clobber (reg:GPR CA_REGNO))]
1907   ""
1908   "adde %0,%1,%2"
1909   [(set_attr "type" "add")])
1911 (define_insn "*add<mode>3_carry_in_internal2"
1912   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1913         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1914                             (reg:GPR CA_REGNO))
1915                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1916    (clobber (reg:GPR CA_REGNO))]
1917   ""
1918   "adde %0,%1,%2"
1919   [(set_attr "type" "add")])
1921 (define_insn "add<mode>3_carry_in_0"
1922   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1923         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1924                   (reg:GPR CA_REGNO)))
1925    (clobber (reg:GPR CA_REGNO))]
1926   ""
1927   "addze %0,%1"
1928   [(set_attr "type" "add")])
1930 (define_insn "add<mode>3_carry_in_m1"
1931   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1932         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1933                             (reg:GPR CA_REGNO))
1934                   (const_int -1)))
1935    (clobber (reg:GPR CA_REGNO))]
1936   ""
1937   "addme %0,%1"
1938   [(set_attr "type" "add")])
1941 (define_expand "one_cmpl<mode>2"
1942   [(set (match_operand:SDI 0 "gpc_reg_operand")
1943         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1944   ""
1946   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1947     {
1948       rs6000_split_logical (operands, NOT, false, false, false);
1949       DONE;
1950     }
1953 (define_insn "*one_cmpl<mode>2"
1954   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1955         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1956   ""
1957   "not %0,%1")
1959 (define_insn_and_split "*one_cmpl<mode>2_dot"
1960   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1961         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1962                     (const_int 0)))
1963    (clobber (match_scratch:GPR 0 "=r,r"))]
1964   "<MODE>mode == Pmode"
1965   "@
1966    not. %0,%1
1967    #"
1968   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1969   [(set (match_dup 0)
1970         (not:GPR (match_dup 1)))
1971    (set (match_dup 2)
1972         (compare:CC (match_dup 0)
1973                     (const_int 0)))]
1974   ""
1975   [(set_attr "type" "logical")
1976    (set_attr "dot" "yes")
1977    (set_attr "length" "4,8")])
1979 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1980   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1981         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1982                     (const_int 0)))
1983    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1984         (not:GPR (match_dup 1)))]
1985   "<MODE>mode == Pmode"
1986   "@
1987    not. %0,%1
1988    #"
1989   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1990   [(set (match_dup 0)
1991         (not:GPR (match_dup 1)))
1992    (set (match_dup 2)
1993         (compare:CC (match_dup 0)
1994                     (const_int 0)))]
1995   ""
1996   [(set_attr "type" "logical")
1997    (set_attr "dot" "yes")
1998    (set_attr "length" "4,8")])
2001 (define_expand "sub<mode>3"
2002   [(set (match_operand:SDI 0 "gpc_reg_operand")
2003         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2004                    (match_operand:SDI 2 "gpc_reg_operand")))]
2005   ""
2007   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2008     {
2009       rtx lo0 = gen_lowpart (SImode, operands[0]);
2010       rtx lo1 = gen_lowpart (SImode, operands[1]);
2011       rtx lo2 = gen_lowpart (SImode, operands[2]);
2012       rtx hi0 = gen_highpart (SImode, operands[0]);
2013       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2014       rtx hi2 = gen_highpart (SImode, operands[2]);
2016       if (!reg_or_short_operand (lo1, SImode))
2017         lo1 = force_reg (SImode, lo1);
2018       if (!adde_operand (hi1, SImode))
2019         hi1 = force_reg (SImode, hi1);
2021       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2022       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2023       DONE;
2024     }
2026   if (short_cint_operand (operands[1], <MODE>mode))
2027     {
2028       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2029       DONE;
2030     }
2033 (define_insn "*subf<mode>3"
2034   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2035         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2036                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2037   ""
2038   "subf %0,%1,%2"
2039   [(set_attr "type" "add")])
2041 (define_insn_and_split "*subf<mode>3_dot"
2042   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2043         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2044                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2045                     (const_int 0)))
2046    (clobber (match_scratch:GPR 0 "=r,r"))]
2047   "<MODE>mode == Pmode"
2048   "@
2049    subf. %0,%1,%2
2050    #"
2051   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2052   [(set (match_dup 0)
2053         (minus:GPR (match_dup 2)
2054                    (match_dup 1)))
2055    (set (match_dup 3)
2056         (compare:CC (match_dup 0)
2057                     (const_int 0)))]
2058   ""
2059   [(set_attr "type" "add")
2060    (set_attr "dot" "yes")
2061    (set_attr "length" "4,8")])
2063 (define_insn_and_split "*subf<mode>3_dot2"
2064   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2065         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2066                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2067                     (const_int 0)))
2068    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2069         (minus:GPR (match_dup 2)
2070                    (match_dup 1)))]
2071   "<MODE>mode == Pmode"
2072   "@
2073    subf. %0,%1,%2
2074    #"
2075   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2076   [(set (match_dup 0)
2077         (minus:GPR (match_dup 2)
2078                    (match_dup 1)))
2079    (set (match_dup 3)
2080         (compare:CC (match_dup 0)
2081                     (const_int 0)))]
2082   ""
2083   [(set_attr "type" "add")
2084    (set_attr "dot" "yes")
2085    (set_attr "length" "4,8")])
2087 (define_insn "subf<mode>3_imm"
2088   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2089         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2090                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2091    (clobber (reg:GPR CA_REGNO))]
2092   ""
2093   "subfic %0,%1,%2"
2094   [(set_attr "type" "add")])
2096 (define_insn_and_split "subf<mode>3_carry_dot2"
2097   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2098         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2099                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2100                     (const_int 0)))
2101    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2102         (minus:P (match_dup 2)
2103                    (match_dup 1)))
2104    (set (reg:P CA_REGNO)
2105         (leu:P (match_dup 1)
2106                (match_dup 2)))]
2107   "<MODE>mode == Pmode"
2108   "@
2109    subfc. %0,%1,%2
2110    #"
2111   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2112   [(parallel [(set (match_dup 0)
2113                    (minus:P (match_dup 2)
2114                             (match_dup 1)))
2115               (set (reg:P CA_REGNO)
2116                    (leu:P (match_dup 1)
2117                           (match_dup 2)))])
2118    (set (match_dup 3)
2119         (compare:CC (match_dup 0)
2120                     (const_int 0)))]
2121   ""
2122   [(set_attr "type" "add")
2123    (set_attr "dot" "yes")
2124    (set_attr "length" "4,8")])
2126 (define_insn "subf<mode>3_carry"
2127   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2128         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2129                  (match_operand:P 1 "gpc_reg_operand" "r")))
2130    (set (reg:P CA_REGNO)
2131         (leu:P (match_dup 1)
2132                (match_dup 2)))]
2133   ""
2134   "subf%I2c %0,%1,%2"
2135   [(set_attr "type" "add")])
2137 (define_insn "*subf<mode>3_imm_carry_0"
2138   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2139         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2140    (set (reg:P CA_REGNO)
2141         (eq:P (match_dup 1)
2142               (const_int 0)))]
2143   ""
2144   "subfic %0,%1,0"
2145   [(set_attr "type" "add")])
2147 (define_insn "*subf<mode>3_imm_carry_m1"
2148   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2149         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2150    (set (reg:P CA_REGNO)
2151         (const_int 1))]
2152   ""
2153   "subfic %0,%1,-1"
2154   [(set_attr "type" "add")])
2157 (define_expand "subf<mode>3_carry_in"
2158   [(parallel [
2159      (set (match_operand:GPR 0 "gpc_reg_operand")
2160           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2161                               (reg:GPR CA_REGNO))
2162                     (match_operand:GPR 2 "adde_operand")))
2163      (clobber (reg:GPR CA_REGNO))])]
2164   ""
2166   if (operands[2] == const0_rtx)
2167     {
2168       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2169       DONE;
2170     }
2171   if (operands[2] == constm1_rtx)
2172     {
2173       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2174       DONE;
2175     }
2178 (define_insn "*subf<mode>3_carry_in_internal"
2179   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2181                             (reg:GPR CA_REGNO))
2182                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2183    (clobber (reg:GPR CA_REGNO))]
2184   ""
2185   "subfe %0,%1,%2"
2186   [(set_attr "type" "add")])
2188 (define_insn "subf<mode>3_carry_in_0"
2189   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2190         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2191                   (reg:GPR CA_REGNO)))
2192    (clobber (reg:GPR CA_REGNO))]
2193   ""
2194   "subfze %0,%1"
2195   [(set_attr "type" "add")])
2197 (define_insn "subf<mode>3_carry_in_m1"
2198   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2200                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2201                   (const_int -2)))
2202    (clobber (reg:GPR CA_REGNO))]
2203   ""
2204   "subfme %0,%1"
2205   [(set_attr "type" "add")])
2207 (define_insn "subf<mode>3_carry_in_xx"
2208   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2209         (plus:GPR (reg:GPR CA_REGNO)
2210                   (const_int -1)))
2211    (clobber (reg:GPR CA_REGNO))]
2212   ""
2213   "subfe %0,%0,%0"
2214   [(set_attr "type" "add")])
2217 (define_insn "neg<mode>2"
2218   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2219         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2220   ""
2221   "neg %0,%1"
2222   [(set_attr "type" "add")])
2224 (define_insn_and_split "*neg<mode>2_dot"
2225   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2226         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2227                     (const_int 0)))
2228    (clobber (match_scratch:GPR 0 "=r,r"))]
2229   "<MODE>mode == Pmode"
2230   "@
2231    neg. %0,%1
2232    #"
2233   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2234   [(set (match_dup 0)
2235         (neg:GPR (match_dup 1)))
2236    (set (match_dup 2)
2237         (compare:CC (match_dup 0)
2238                     (const_int 0)))]
2239   ""
2240   [(set_attr "type" "add")
2241    (set_attr "dot" "yes")
2242    (set_attr "length" "4,8")])
2244 (define_insn_and_split "*neg<mode>2_dot2"
2245   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2246         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2247                     (const_int 0)))
2248    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2249         (neg:GPR (match_dup 1)))]
2250   "<MODE>mode == Pmode"
2251   "@
2252    neg. %0,%1
2253    #"
2254   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2255   [(set (match_dup 0)
2256         (neg:GPR (match_dup 1)))
2257    (set (match_dup 2)
2258         (compare:CC (match_dup 0)
2259                     (const_int 0)))]
2260   ""
2261   [(set_attr "type" "add")
2262    (set_attr "dot" "yes")
2263    (set_attr "length" "4,8")])
2266 (define_insn "clz<mode>2"
2267   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2268         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2269   ""
2270   "cntlz<wd> %0,%1"
2271   [(set_attr "type" "cntlz")])
2273 (define_expand "ctz<mode>2"
2274    [(set (match_operand:GPR 0 "gpc_reg_operand")
2275          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2276   ""
2278   if (TARGET_CTZ)
2279     {
2280       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2281       DONE;
2282     }
2284   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2285   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2286   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2288   if (TARGET_POPCNTD)
2289     {
2290       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2291       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2292       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2293       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2294     }
2295   else
2296     {
2297       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2298       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2299       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2300       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2301     }
2303   DONE;
2306 (define_insn "ctz<mode>2_hw"
2307   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2308         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2309   "TARGET_CTZ"
2310   "cnttz<wd> %0,%1"
2311   [(set_attr "type" "cntlz")])
2313 (define_expand "ffs<mode>2"
2314   [(set (match_operand:GPR 0 "gpc_reg_operand")
2315         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2316   ""
2318   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2319   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2320   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2321   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2322   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2323   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2324   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2325   DONE;
2329 (define_expand "popcount<mode>2"
2330   [(set (match_operand:GPR 0 "gpc_reg_operand")
2331         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2332   "TARGET_POPCNTB || TARGET_POPCNTD"
2334   rs6000_emit_popcount (operands[0], operands[1]);
2335   DONE;
2338 (define_insn "popcntb<mode>2"
2339   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2340         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2341                     UNSPEC_POPCNTB))]
2342   "TARGET_POPCNTB"
2343   "popcntb %0,%1"
2344   [(set_attr "type" "popcnt")])
2346 (define_insn "popcntd<mode>2"
2347   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2348         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2349   "TARGET_POPCNTD"
2350   "popcnt<wd> %0,%1"
2351   [(set_attr "type" "popcnt")])
2354 (define_expand "parity<mode>2"
2355   [(set (match_operand:GPR 0 "gpc_reg_operand")
2356         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2357   "TARGET_POPCNTB"
2359   rs6000_emit_parity (operands[0], operands[1]);
2360   DONE;
2363 (define_insn "parity<mode>2_cmpb"
2364   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2365         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2366   "TARGET_CMPB && TARGET_POPCNTB"
2367   "prty<wd> %0,%1"
2368   [(set_attr "type" "popcnt")])
2370 (define_insn "cmpb<mode>3"
2371   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2372         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2373                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2374   "TARGET_CMPB"
2375   "cmpb %0,%1,%2"
2376   [(set_attr "type" "cmp")])
2378 ;; Since the hardware zeros the upper part of the register, save generating the
2379 ;; AND immediate if we are converting to unsigned
2380 (define_insn "*bswap<mode>2_extenddi"
2381   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2382         (zero_extend:DI
2383          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2384   "TARGET_POWERPC64"
2385   "l<wd>brx %0,%y1"
2386   [(set_attr "length" "4")
2387    (set_attr "type" "load")])
2389 (define_insn "*bswaphi2_extendsi"
2390   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2391         (zero_extend:SI
2392          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2393   ""
2394   "lhbrx %0,%y1"
2395   [(set_attr "length" "4")
2396    (set_attr "type" "load")])
2398 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2399 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2400 ;; load with byte swap, which can be slower than doing it in the registers.  It
2401 ;; also prevents certain failures with the RELOAD register allocator.
2403 (define_expand "bswap<mode>2"
2404   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2405    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2406   ""
2408   rtx dest = operands[0];
2409   rtx src = operands[1];
2411   if (!REG_P (dest) && !REG_P (src))
2412     src = force_reg (<MODE>mode, src);
2414   if (MEM_P (src))
2415     emit_insn (gen_bswap<mode>2_load (dest, src));
2416   else if (MEM_P (dest))
2417     emit_insn (gen_bswap<mode>2_store (dest, src));
2418   else
2419     emit_insn (gen_bswap<mode>2_reg (dest, src));
2420   DONE;
2423 (define_insn "bswap<mode>2_load"
2424   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2425         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2426   ""
2427   "l<wd>brx %0,%y1"
2428   [(set_attr "type" "load")])
2430 (define_insn "bswap<mode>2_store"
2431   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2432         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2433   ""
2434   "st<wd>brx %1,%y0"
2435   [(set_attr "type" "store")])
2437 (define_insn_and_split "bswaphi2_reg"
2438   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2439         (bswap:HI
2440          (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2441    (clobber (match_scratch:SI 2 "=&r,X"))]
2442   ""
2443   "@
2444    #
2445    xxbrh %x0,%x1"
2446   "reload_completed && int_reg_operand (operands[0], HImode)"
2447   [(set (match_dup 3)
2448         (and:SI (lshiftrt:SI (match_dup 4)
2449                              (const_int 8))
2450                 (const_int 255)))
2451    (set (match_dup 2)
2452         (and:SI (ashift:SI (match_dup 4)
2453                            (const_int 8))
2454                 (const_int 65280)))             ;; 0xff00
2455    (set (match_dup 3)
2456         (ior:SI (match_dup 3)
2457                 (match_dup 2)))]
2459   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2460   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2462   [(set_attr "length" "12,4")
2463    (set_attr "type" "*,vecperm")])
2465 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2466 ;; zero_extract insns do not change for -mlittle.
2467 (define_insn_and_split "bswapsi2_reg"
2468   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2469         (bswap:SI
2470          (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2471   ""
2472   "@
2473    #
2474    xxbrw %x0,%x1"
2475   "reload_completed && int_reg_operand (operands[0], SImode)"
2476   [(set (match_dup 0)                                   ; DABC
2477         (rotate:SI (match_dup 1)
2478                    (const_int 24)))
2479    (set (match_dup 0)                                   ; DCBC
2480         (ior:SI (and:SI (ashift:SI (match_dup 1)
2481                                    (const_int 8))
2482                         (const_int 16711680))
2483                 (and:SI (match_dup 0)
2484                         (const_int -16711681))))
2485    (set (match_dup 0)                                   ; DCBA
2486         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2487                                      (const_int 24))
2488                         (const_int 255))
2489                 (and:SI (match_dup 0)
2490                         (const_int -256))))]
2491   ""
2492   [(set_attr "length" "12,4")
2493    (set_attr "type" "*,vecperm")])
2495 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2496 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2497 ;; complex code.
2499 (define_expand "bswapdi2"
2500   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2501                    (bswap:DI
2502                     (match_operand:DI 1 "reg_or_mem_operand")))
2503               (clobber (match_scratch:DI 2))
2504               (clobber (match_scratch:DI 3))])]
2505   ""
2507   rtx dest = operands[0];
2508   rtx src = operands[1];
2510   if (!REG_P (dest) && !REG_P (src))
2511     operands[1] = src = force_reg (DImode, src);
2513   if (TARGET_POWERPC64 && TARGET_LDBRX)
2514     {
2515       if (MEM_P (src))
2516         emit_insn (gen_bswapdi2_load (dest, src));
2517       else if (MEM_P (dest))
2518         emit_insn (gen_bswapdi2_store (dest, src));
2519       else if (TARGET_P9_VECTOR)
2520         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2521       else
2522         emit_insn (gen_bswapdi2_reg (dest, src));
2523       DONE;
2524     }
2526   if (!TARGET_POWERPC64)
2527     {
2528       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2529          that uses 64-bit registers needs the same scratch registers as 64-bit
2530          mode.  */
2531       emit_insn (gen_bswapdi2_32bit (dest, src));
2532       DONE;
2533     }
2536 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2537 (define_insn "bswapdi2_load"
2538   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2539         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2540   "TARGET_POWERPC64 && TARGET_LDBRX"
2541   "ldbrx %0,%y1"
2542   [(set_attr "type" "load")])
2544 (define_insn "bswapdi2_store"
2545   [(set (match_operand:DI 0 "memory_operand" "=Z")
2546         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2547   "TARGET_POWERPC64 && TARGET_LDBRX"
2548   "stdbrx %1,%y0"
2549   [(set_attr "type" "store")])
2551 (define_insn "bswapdi2_xxbrd"
2552   [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2553         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2554   "TARGET_P9_VECTOR"
2555   "xxbrd %x0,%x1"
2556   [(set_attr "type" "vecperm")])
2558 (define_insn "bswapdi2_reg"
2559   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2560         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2561    (clobber (match_scratch:DI 2 "=&r"))
2562    (clobber (match_scratch:DI 3 "=&r"))]
2563   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2564   "#"
2565   [(set_attr "length" "36")])
2567 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2568 (define_insn "*bswapdi2_64bit"
2569   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2570         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2571    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2572    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2573   "TARGET_POWERPC64 && !TARGET_LDBRX
2574    && (REG_P (operands[0]) || REG_P (operands[1]))
2575    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2576    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2577   "#"
2578   [(set_attr "length" "16,12,36")])
2580 (define_split
2581   [(set (match_operand:DI 0 "gpc_reg_operand")
2582         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2583    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2584    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2585   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2586   [(const_int 0)]
2588   rtx dest   = operands[0];
2589   rtx src    = operands[1];
2590   rtx op2    = operands[2];
2591   rtx op3    = operands[3];
2592   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2593                                     BYTES_BIG_ENDIAN ? 4 : 0);
2594   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2595                                      BYTES_BIG_ENDIAN ? 4 : 0);
2596   rtx addr1;
2597   rtx addr2;
2598   rtx word1;
2599   rtx word2;
2601   addr1 = XEXP (src, 0);
2602   if (GET_CODE (addr1) == PLUS)
2603     {
2604       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2605       if (TARGET_AVOID_XFORM)
2606         {
2607           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2608           addr2 = op2;
2609         }
2610       else
2611         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2612     }
2613   else if (TARGET_AVOID_XFORM)
2614     {
2615       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2616       addr2 = op2;
2617     }
2618   else
2619     {
2620       emit_move_insn (op2, GEN_INT (4));
2621       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2622     }
2624   word1 = change_address (src, SImode, addr1);
2625   word2 = change_address (src, SImode, addr2);
2627   if (BYTES_BIG_ENDIAN)
2628     {
2629       emit_insn (gen_bswapsi2 (op3_32, word2));
2630       emit_insn (gen_bswapsi2 (dest_32, word1));
2631     }
2632   else
2633     {
2634       emit_insn (gen_bswapsi2 (op3_32, word1));
2635       emit_insn (gen_bswapsi2 (dest_32, word2));
2636     }
2638   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2639   emit_insn (gen_iordi3 (dest, dest, op3));
2640   DONE;
2643 (define_split
2644   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2645         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2646    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2647    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2648   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2649   [(const_int 0)]
2651   rtx dest   = operands[0];
2652   rtx src    = operands[1];
2653   rtx op2    = operands[2];
2654   rtx op3    = operands[3];
2655   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2656                                     BYTES_BIG_ENDIAN ? 4 : 0);
2657   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2658                                     BYTES_BIG_ENDIAN ? 4 : 0);
2659   rtx addr1;
2660   rtx addr2;
2661   rtx word1;
2662   rtx word2;
2664   addr1 = XEXP (dest, 0);
2665   if (GET_CODE (addr1) == PLUS)
2666     {
2667       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2668       if (TARGET_AVOID_XFORM)
2669         {
2670           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2671           addr2 = op2;
2672         }
2673       else
2674         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2675     }
2676   else if (TARGET_AVOID_XFORM)
2677     {
2678       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2679       addr2 = op2;
2680     }
2681   else
2682     {
2683       emit_move_insn (op2, GEN_INT (4));
2684       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2685     }
2687   word1 = change_address (dest, SImode, addr1);
2688   word2 = change_address (dest, SImode, addr2);
2690   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2692   if (BYTES_BIG_ENDIAN)
2693     {
2694       emit_insn (gen_bswapsi2 (word1, src_si));
2695       emit_insn (gen_bswapsi2 (word2, op3_si));
2696     }
2697   else
2698     {
2699       emit_insn (gen_bswapsi2 (word2, src_si));
2700       emit_insn (gen_bswapsi2 (word1, op3_si));
2701     }
2702   DONE;
2705 (define_split
2706   [(set (match_operand:DI 0 "gpc_reg_operand")
2707         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2708    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2709    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2710   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2711   [(const_int 0)]
2713   rtx dest    = operands[0];
2714   rtx src     = operands[1];
2715   rtx op2     = operands[2];
2716   rtx op3     = operands[3];
2717   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2718   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2719   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2720   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2721   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2723   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2724   emit_insn (gen_bswapsi2 (dest_si, src_si));
2725   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2726   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2727   emit_insn (gen_iordi3 (dest, dest, op3));
2728   DONE;
2731 (define_insn "bswapdi2_32bit"
2732   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2733         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2734    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2735   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2736   "#"
2737   [(set_attr "length" "16,12,36")])
2739 (define_split
2740   [(set (match_operand:DI 0 "gpc_reg_operand")
2741         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2742    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2743   "!TARGET_POWERPC64 && reload_completed"
2744   [(const_int 0)]
2746   rtx dest  = operands[0];
2747   rtx src   = operands[1];
2748   rtx op2   = operands[2];
2749   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2750   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2751   rtx addr1;
2752   rtx addr2;
2753   rtx word1;
2754   rtx word2;
2756   addr1 = XEXP (src, 0);
2757   if (GET_CODE (addr1) == PLUS)
2758     {
2759       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2760       if (TARGET_AVOID_XFORM
2761           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2762         {
2763           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2764           addr2 = op2;
2765         }
2766       else
2767         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2768     }
2769   else if (TARGET_AVOID_XFORM
2770            || REGNO (addr1) == REGNO (dest2))
2771     {
2772       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2773       addr2 = op2;
2774     }
2775   else
2776     {
2777       emit_move_insn (op2, GEN_INT (4));
2778       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2779     }
2781   word1 = change_address (src, SImode, addr1);
2782   word2 = change_address (src, SImode, addr2);
2784   emit_insn (gen_bswapsi2 (dest2, word1));
2785   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2786      thus allowing us to omit an early clobber on the output.  */
2787   emit_insn (gen_bswapsi2 (dest1, word2));
2788   DONE;
2791 (define_split
2792   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2793         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2794    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2795   "!TARGET_POWERPC64 && reload_completed"
2796   [(const_int 0)]
2798   rtx dest = operands[0];
2799   rtx src  = operands[1];
2800   rtx op2  = operands[2];
2801   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2802   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2803   rtx addr1;
2804   rtx addr2;
2805   rtx word1;
2806   rtx word2;
2808   addr1 = XEXP (dest, 0);
2809   if (GET_CODE (addr1) == PLUS)
2810     {
2811       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2812       if (TARGET_AVOID_XFORM)
2813         {
2814           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2815           addr2 = op2;
2816         }
2817       else
2818         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2819     }
2820   else if (TARGET_AVOID_XFORM)
2821     {
2822       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2823       addr2 = op2;
2824     }
2825   else
2826     {
2827       emit_move_insn (op2, GEN_INT (4));
2828       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2829     }
2831   word1 = change_address (dest, SImode, addr1);
2832   word2 = change_address (dest, SImode, addr2);
2834   emit_insn (gen_bswapsi2 (word2, src1));
2835   emit_insn (gen_bswapsi2 (word1, src2));
2836   DONE;
2839 (define_split
2840   [(set (match_operand:DI 0 "gpc_reg_operand")
2841         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2842    (clobber (match_operand:SI 2 ""))]
2843   "!TARGET_POWERPC64 && reload_completed"
2844   [(const_int 0)]
2846   rtx dest  = operands[0];
2847   rtx src   = operands[1];
2848   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2849   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2850   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2851   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2853   emit_insn (gen_bswapsi2 (dest1, src2));
2854   emit_insn (gen_bswapsi2 (dest2, src1));
2855   DONE;
2859 (define_insn "mul<mode>3"
2860   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2861         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2862                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2863   ""
2864   "@
2865    mull<wd> %0,%1,%2
2866    mulli %0,%1,%2"
2867    [(set_attr "type" "mul")
2868     (set (attr "size")
2869       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2870                 (const_string "8")
2871              (match_operand:GPR 2 "short_cint_operand")
2872                 (const_string "16")]
2873         (const_string "<bits>")))])
2875 (define_insn_and_split "*mul<mode>3_dot"
2876   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2877         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2878                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2879                     (const_int 0)))
2880    (clobber (match_scratch:GPR 0 "=r,r"))]
2881   "<MODE>mode == Pmode"
2882   "@
2883    mull<wd>. %0,%1,%2
2884    #"
2885   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2886   [(set (match_dup 0)
2887         (mult:GPR (match_dup 1)
2888                   (match_dup 2)))
2889    (set (match_dup 3)
2890         (compare:CC (match_dup 0)
2891                     (const_int 0)))]
2892   ""
2893   [(set_attr "type" "mul")
2894    (set_attr "size" "<bits>")
2895    (set_attr "dot" "yes")
2896    (set_attr "length" "4,8")])
2898 (define_insn_and_split "*mul<mode>3_dot2"
2899   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2900         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2901                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2902                     (const_int 0)))
2903    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2904         (mult:GPR (match_dup 1)
2905                   (match_dup 2)))]
2906   "<MODE>mode == Pmode"
2907   "@
2908    mull<wd>. %0,%1,%2
2909    #"
2910   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2911   [(set (match_dup 0)
2912         (mult:GPR (match_dup 1)
2913                   (match_dup 2)))
2914    (set (match_dup 3)
2915         (compare:CC (match_dup 0)
2916                     (const_int 0)))]
2917   ""
2918   [(set_attr "type" "mul")
2919    (set_attr "size" "<bits>")
2920    (set_attr "dot" "yes")
2921    (set_attr "length" "4,8")])
2924 (define_expand "<su>mul<mode>3_highpart"
2925   [(set (match_operand:GPR 0 "gpc_reg_operand")
2926         (subreg:GPR
2927           (mult:<DMODE> (any_extend:<DMODE>
2928                           (match_operand:GPR 1 "gpc_reg_operand"))
2929                         (any_extend:<DMODE>
2930                           (match_operand:GPR 2 "gpc_reg_operand")))
2931          0))]
2932   ""
2934   if (<MODE>mode == SImode && TARGET_POWERPC64)
2935     {
2936       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2937                                              operands[2]));
2938       DONE;
2939     }
2941   if (!WORDS_BIG_ENDIAN)
2942     {
2943       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2944                                                  operands[2]));
2945       DONE;
2946     }
2949 (define_insn "*<su>mul<mode>3_highpart"
2950   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2951         (subreg:GPR
2952           (mult:<DMODE> (any_extend:<DMODE>
2953                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2954                         (any_extend:<DMODE>
2955                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2956          0))]
2957   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2958   "mulh<wd><u> %0,%1,%2"
2959   [(set_attr "type" "mul")
2960    (set_attr "size" "<bits>")])
2962 (define_insn "<su>mulsi3_highpart_le"
2963   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2964         (subreg:SI
2965           (mult:DI (any_extend:DI
2966                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2967                    (any_extend:DI
2968                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2969          4))]
2970   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2971   "mulhw<u> %0,%1,%2"
2972   [(set_attr "type" "mul")])
2974 (define_insn "<su>muldi3_highpart_le"
2975   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2976         (subreg:DI
2977           (mult:TI (any_extend:TI
2978                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2979                    (any_extend:TI
2980                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2981          8))]
2982   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2983   "mulhd<u> %0,%1,%2"
2984   [(set_attr "type" "mul")
2985    (set_attr "size" "64")])
2987 (define_insn "<su>mulsi3_highpart_64"
2988   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2989         (truncate:SI
2990           (lshiftrt:DI
2991             (mult:DI (any_extend:DI
2992                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2993                      (any_extend:DI
2994                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2995             (const_int 32))))]
2996   "TARGET_POWERPC64"
2997   "mulhw<u> %0,%1,%2"
2998   [(set_attr "type" "mul")])
3000 (define_expand "<u>mul<mode><dmode>3"
3001   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3002         (mult:<DMODE> (any_extend:<DMODE>
3003                         (match_operand:GPR 1 "gpc_reg_operand"))
3004                       (any_extend:<DMODE>
3005                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3006   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3008   rtx l = gen_reg_rtx (<MODE>mode);
3009   rtx h = gen_reg_rtx (<MODE>mode);
3010   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3011   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3012   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3013   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3014   DONE;
3017 (define_insn "*maddld4"
3018   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3019         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3020                           (match_operand:DI 2 "gpc_reg_operand" "r"))
3021                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
3022   "TARGET_MADDLD"
3023   "maddld %0,%1,%2,%3"
3024   [(set_attr "type" "mul")])
3026 (define_insn "udiv<mode>3"
3027   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3028         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3029                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3030   ""
3031   "div<wd>u %0,%1,%2"
3032   [(set_attr "type" "div")
3033    (set_attr "size" "<bits>")])
3036 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3037 ;; modulus.  If it isn't a power of two, force operands into register and do
3038 ;; a normal divide.
3039 (define_expand "div<mode>3"
3040   [(set (match_operand:GPR 0 "gpc_reg_operand")
3041         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3042                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3043   ""
3045   if (CONST_INT_P (operands[2])
3046       && INTVAL (operands[2]) > 0
3047       && exact_log2 (INTVAL (operands[2])) >= 0)
3048     {
3049       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3050       DONE;
3051     }
3053   operands[2] = force_reg (<MODE>mode, operands[2]);
3056 (define_insn "*div<mode>3"
3057   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3058         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3059                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3060   ""
3061   "div<wd> %0,%1,%2"
3062   [(set_attr "type" "div")
3063    (set_attr "size" "<bits>")])
3065 (define_insn "div<mode>3_sra"
3066   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3069    (clobber (reg:GPR CA_REGNO))]
3070   ""
3071   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3072   [(set_attr "type" "two")
3073    (set_attr "length" "8")])
3075 (define_insn_and_split "*div<mode>3_sra_dot"
3076   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3077         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3078                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3079                     (const_int 0)))
3080    (clobber (match_scratch:GPR 0 "=r,r"))
3081    (clobber (reg:GPR CA_REGNO))]
3082   "<MODE>mode == Pmode"
3083   "@
3084    sra<wd>i %0,%1,%p2\;addze. %0,%0
3085    #"
3086   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3087   [(parallel [(set (match_dup 0)
3088                    (div:GPR (match_dup 1)
3089                             (match_dup 2)))
3090               (clobber (reg:GPR CA_REGNO))])
3091    (set (match_dup 3)
3092         (compare:CC (match_dup 0)
3093                     (const_int 0)))]
3094   ""
3095   [(set_attr "type" "two")
3096    (set_attr "length" "8,12")
3097    (set_attr "cell_micro" "not")])
3099 (define_insn_and_split "*div<mode>3_sra_dot2"
3100   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3101         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3102                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3103                     (const_int 0)))
3104    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3105         (div:GPR (match_dup 1)
3106                  (match_dup 2)))
3107    (clobber (reg:GPR CA_REGNO))]
3108   "<MODE>mode == Pmode"
3109   "@
3110    sra<wd>i %0,%1,%p2\;addze. %0,%0
3111    #"
3112   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3113   [(parallel [(set (match_dup 0)
3114                    (div:GPR (match_dup 1)
3115                             (match_dup 2)))
3116               (clobber (reg:GPR CA_REGNO))])
3117    (set (match_dup 3)
3118         (compare:CC (match_dup 0)
3119                     (const_int 0)))]
3120   ""
3121   [(set_attr "type" "two")
3122    (set_attr "length" "8,12")
3123    (set_attr "cell_micro" "not")])
3125 (define_expand "mod<mode>3"
3126   [(set (match_operand:GPR 0 "gpc_reg_operand")
3127         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3128                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3129   ""
3131   int i;
3132   rtx temp1;
3133   rtx temp2;
3135   if (GET_CODE (operands[2]) != CONST_INT
3136       || INTVAL (operands[2]) <= 0
3137       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3138     {
3139       if (!TARGET_MODULO)
3140         FAIL;
3142       operands[2] = force_reg (<MODE>mode, operands[2]);
3143     }
3144   else
3145     {
3146       temp1 = gen_reg_rtx (<MODE>mode);
3147       temp2 = gen_reg_rtx (<MODE>mode);
3149       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3150       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3151       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3152       DONE;
3153     }
3156 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3157 ;; mod, prefer putting the result of mod into a different register
3158 (define_insn "*mod<mode>3"
3159   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3160         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3161                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3162   "TARGET_MODULO"
3163   "mods<wd> %0,%1,%2"
3164   [(set_attr "type" "div")
3165    (set_attr "size" "<bits>")])
3168 (define_insn "umod<mode>3"
3169   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3170         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3171                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3172   "TARGET_MODULO"
3173   "modu<wd> %0,%1,%2"
3174   [(set_attr "type" "div")
3175    (set_attr "size" "<bits>")])
3177 ;; On machines with modulo support, do a combined div/mod the old fashioned
3178 ;; method, since the multiply/subtract is faster than doing the mod instruction
3179 ;; after a divide.
3181 (define_peephole2
3182   [(set (match_operand:GPR 0 "gpc_reg_operand")
3183         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3184                  (match_operand:GPR 2 "gpc_reg_operand")))
3185    (set (match_operand:GPR 3 "gpc_reg_operand")
3186         (mod:GPR (match_dup 1)
3187                  (match_dup 2)))]
3188   "TARGET_MODULO
3189    && ! reg_mentioned_p (operands[0], operands[1])
3190    && ! reg_mentioned_p (operands[0], operands[2])
3191    && ! reg_mentioned_p (operands[3], operands[1])
3192    && ! reg_mentioned_p (operands[3], operands[2])"
3193   [(set (match_dup 0)
3194         (div:GPR (match_dup 1)
3195                  (match_dup 2)))
3196    (set (match_dup 3)
3197         (mult:GPR (match_dup 0)
3198                   (match_dup 2)))
3199    (set (match_dup 3)
3200         (minus:GPR (match_dup 1)
3201                    (match_dup 3)))])
3203 (define_peephole2
3204   [(set (match_operand:GPR 0 "gpc_reg_operand")
3205         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3206                   (match_operand:GPR 2 "gpc_reg_operand")))
3207    (set (match_operand:GPR 3 "gpc_reg_operand")
3208         (umod:GPR (match_dup 1)
3209                   (match_dup 2)))]
3210   "TARGET_MODULO
3211    && ! reg_mentioned_p (operands[0], operands[1])
3212    && ! reg_mentioned_p (operands[0], operands[2])
3213    && ! reg_mentioned_p (operands[3], operands[1])
3214    && ! reg_mentioned_p (operands[3], operands[2])"
3215   [(set (match_dup 0)
3216         (udiv:GPR (match_dup 1)
3217                   (match_dup 2)))
3218    (set (match_dup 3)
3219         (mult:GPR (match_dup 0)
3220                   (match_dup 2)))
3221    (set (match_dup 3)
3222         (minus:GPR (match_dup 1)
3223                    (match_dup 3)))])
3226 ;; Logical instructions
3227 ;; The logical instructions are mostly combined by using match_operator,
3228 ;; but the plain AND insns are somewhat different because there is no
3229 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3230 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3232 (define_expand "and<mode>3"
3233   [(set (match_operand:SDI 0 "gpc_reg_operand")
3234         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3235                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3236   ""
3238   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3239     {
3240       rs6000_split_logical (operands, AND, false, false, false);
3241       DONE;
3242     }
3244   if (CONST_INT_P (operands[2]))
3245     {
3246       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3247         {
3248           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3249           DONE;
3250         }
3252       if (logical_const_operand (operands[2], <MODE>mode))
3253         {
3254           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3255           DONE;
3256         }
3258       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3259         {
3260           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3261           DONE;
3262         }
3264       operands[2] = force_reg (<MODE>mode, operands[2]);
3265     }
3269 (define_insn "and<mode>3_imm"
3270   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3271         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3272                  (match_operand:GPR 2 "logical_const_operand" "n")))
3273    (clobber (match_scratch:CC 3 "=x"))]
3274   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3275   "andi%e2. %0,%1,%u2"
3276   [(set_attr "type" "logical")
3277    (set_attr "dot" "yes")])
3279 (define_insn_and_split "*and<mode>3_imm_dot"
3280   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3281         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3282                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3283                     (const_int 0)))
3284    (clobber (match_scratch:GPR 0 "=r,r"))
3285    (clobber (match_scratch:CC 4 "=X,x"))]
3286   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3287    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3288   "@
3289    andi%e2. %0,%1,%u2
3290    #"
3291   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3292   [(parallel [(set (match_dup 0)
3293                    (and:GPR (match_dup 1)
3294                             (match_dup 2)))
3295               (clobber (match_dup 4))])
3296    (set (match_dup 3)
3297         (compare:CC (match_dup 0)
3298                     (const_int 0)))]
3299   ""
3300   [(set_attr "type" "logical")
3301    (set_attr "dot" "yes")
3302    (set_attr "length" "4,8")])
3304 (define_insn_and_split "*and<mode>3_imm_dot2"
3305   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3306         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3307                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3308                     (const_int 0)))
3309    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3310         (and:GPR (match_dup 1)
3311                  (match_dup 2)))
3312    (clobber (match_scratch:CC 4 "=X,x"))]
3313   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3314    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3315   "@
3316    andi%e2. %0,%1,%u2
3317    #"
3318   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319   [(parallel [(set (match_dup 0)
3320                    (and:GPR (match_dup 1)
3321                             (match_dup 2)))
3322               (clobber (match_dup 4))])
3323    (set (match_dup 3)
3324         (compare:CC (match_dup 0)
3325                     (const_int 0)))]
3326   ""
3327   [(set_attr "type" "logical")
3328    (set_attr "dot" "yes")
3329    (set_attr "length" "4,8")])
3331 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3332   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3333         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3335                     (const_int 0)))
3336    (clobber (match_scratch:GPR 0 "=r,r"))]
3337   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3338    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3339   "@
3340    andi%e2. %0,%1,%u2
3341    #"
3342   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3343   [(set (match_dup 0)
3344         (and:GPR (match_dup 1)
3345                  (match_dup 2)))
3346    (set (match_dup 3)
3347         (compare:CC (match_dup 0)
3348                     (const_int 0)))]
3349   ""
3350   [(set_attr "type" "logical")
3351    (set_attr "dot" "yes")
3352    (set_attr "length" "4,8")])
3354 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3355   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3356         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3357                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3358                     (const_int 0)))
3359    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3360         (and:GPR (match_dup 1)
3361                  (match_dup 2)))]
3362   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3363    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3364   "@
3365    andi%e2. %0,%1,%u2
3366    #"
3367   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3368   [(set (match_dup 0)
3369         (and:GPR (match_dup 1)
3370                  (match_dup 2)))
3371    (set (match_dup 3)
3372         (compare:CC (match_dup 0)
3373                     (const_int 0)))]
3374   ""
3375   [(set_attr "type" "logical")
3376    (set_attr "dot" "yes")
3377    (set_attr "length" "4,8")])
3379 (define_insn "*and<mode>3_imm_dot_shifted"
3380   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3381         (compare:CC
3382           (and:GPR
3383             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3384                           (match_operand:SI 4 "const_int_operand" "n"))
3385             (match_operand:GPR 2 "const_int_operand" "n"))
3386           (const_int 0)))
3387    (clobber (match_scratch:GPR 0 "=r"))]
3388   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3389                                    << INTVAL (operands[4])),
3390                           DImode)
3391    && (<MODE>mode == Pmode
3392        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3394   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3395   return "andi%e2. %0,%1,%u2";
3397   [(set_attr "type" "logical")
3398    (set_attr "dot" "yes")])
3401 (define_insn "and<mode>3_mask"
3402   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3403         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3404                  (match_operand:GPR 2 "const_int_operand" "n")))]
3405   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3407   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3409   [(set_attr "type" "shift")])
3411 (define_insn_and_split "*and<mode>3_mask_dot"
3412   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3413         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3414                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3415                     (const_int 0)))
3416    (clobber (match_scratch:GPR 0 "=r,r"))]
3417   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3418    && !logical_const_operand (operands[2], <MODE>mode)
3419    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3421   if (which_alternative == 0)
3422     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3423   else
3424     return "#";
3426   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3427   [(set (match_dup 0)
3428         (and:GPR (match_dup 1)
3429                  (match_dup 2)))
3430    (set (match_dup 3)
3431         (compare:CC (match_dup 0)
3432                     (const_int 0)))]
3433   ""
3434   [(set_attr "type" "shift")
3435    (set_attr "dot" "yes")
3436    (set_attr "length" "4,8")])
3438 (define_insn_and_split "*and<mode>3_mask_dot2"
3439   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3440         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3441                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3442                     (const_int 0)))
3443    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3444         (and:GPR (match_dup 1)
3445                  (match_dup 2)))]
3446   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3447    && !logical_const_operand (operands[2], <MODE>mode)
3448    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3450   if (which_alternative == 0)
3451     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3452   else
3453     return "#";
3455   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3456   [(set (match_dup 0)
3457         (and:GPR (match_dup 1)
3458                  (match_dup 2)))
3459    (set (match_dup 3)
3460         (compare:CC (match_dup 0)
3461                     (const_int 0)))]
3462   ""
3463   [(set_attr "type" "shift")
3464    (set_attr "dot" "yes")
3465    (set_attr "length" "4,8")])
3468 (define_insn_and_split "*and<mode>3_2insn"
3469   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3470         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3471                  (match_operand:GPR 2 "const_int_operand" "n")))]
3472   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3473    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3474         || logical_const_operand (operands[2], <MODE>mode))"
3475   "#"
3476   "&& 1"
3477   [(pc)]
3479   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3480   DONE;
3482   [(set_attr "type" "shift")
3483    (set_attr "length" "8")])
3485 (define_insn_and_split "*and<mode>3_2insn_dot"
3486   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3487         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3488                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3489                     (const_int 0)))
3490    (clobber (match_scratch:GPR 0 "=r,r"))]
3491   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3492    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3493    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3494         || logical_const_operand (operands[2], <MODE>mode))"
3495   "#"
3496   "&& reload_completed"
3497   [(pc)]
3499   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3500   DONE;
3502   [(set_attr "type" "shift")
3503    (set_attr "dot" "yes")
3504    (set_attr "length" "8,12")])
3506 (define_insn_and_split "*and<mode>3_2insn_dot2"
3507   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3508         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3509                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3510                     (const_int 0)))
3511    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3512         (and:GPR (match_dup 1)
3513                  (match_dup 2)))]
3514   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3516    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3517         || logical_const_operand (operands[2], <MODE>mode))"
3518   "#"
3519   "&& reload_completed"
3520   [(pc)]
3522   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3523   DONE;
3525   [(set_attr "type" "shift")
3526    (set_attr "dot" "yes")
3527    (set_attr "length" "8,12")])
3530 (define_expand "<code><mode>3"
3531   [(set (match_operand:SDI 0 "gpc_reg_operand")
3532         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3533                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3534   ""
3536   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3537     {
3538       rs6000_split_logical (operands, <CODE>, false, false, false);
3539       DONE;
3540     }
3542   if (non_logical_cint_operand (operands[2], <MODE>mode))
3543     {
3544       rtx tmp = ((!can_create_pseudo_p ()
3545                   || rtx_equal_p (operands[0], operands[1]))
3546                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3548       HOST_WIDE_INT value = INTVAL (operands[2]);
3549       HOST_WIDE_INT lo = value & 0xffff;
3550       HOST_WIDE_INT hi = value - lo;
3552       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3553       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3554       DONE;
3555     }
3557   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3558     operands[2] = force_reg (<MODE>mode, operands[2]);
3561 (define_split
3562   [(set (match_operand:GPR 0 "gpc_reg_operand")
3563         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3564                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3565   ""
3566   [(set (match_dup 3)
3567         (iorxor:GPR (match_dup 1)
3568                     (match_dup 4)))
3569    (set (match_dup 0)
3570         (iorxor:GPR (match_dup 3)
3571                     (match_dup 5)))]
3573   operands[3] = ((!can_create_pseudo_p ()
3574                   || rtx_equal_p (operands[0], operands[1]))
3575                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3577   HOST_WIDE_INT value = INTVAL (operands[2]);
3578   HOST_WIDE_INT lo = value & 0xffff;
3579   HOST_WIDE_INT hi = value - lo;
3581   operands[4] = GEN_INT (hi);
3582   operands[5] = GEN_INT (lo);
3585 (define_insn "*bool<mode>3_imm"
3586   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3587         (match_operator:GPR 3 "boolean_or_operator"
3588          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3589           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3590   ""
3591   "%q3i%e2 %0,%1,%u2"
3592   [(set_attr "type" "logical")])
3594 (define_insn "*bool<mode>3"
3595   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3596         (match_operator:GPR 3 "boolean_operator"
3597          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3598           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3599   ""
3600   "%q3 %0,%1,%2"
3601   [(set_attr "type" "logical")])
3603 (define_insn_and_split "*bool<mode>3_dot"
3604   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3605         (compare:CC (match_operator:GPR 3 "boolean_operator"
3606          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3607           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3608          (const_int 0)))
3609    (clobber (match_scratch:GPR 0 "=r,r"))]
3610   "<MODE>mode == Pmode"
3611   "@
3612    %q3. %0,%1,%2
3613    #"
3614   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3615   [(set (match_dup 0)
3616         (match_dup 3))
3617    (set (match_dup 4)
3618         (compare:CC (match_dup 0)
3619                     (const_int 0)))]
3620   ""
3621   [(set_attr "type" "logical")
3622    (set_attr "dot" "yes")
3623    (set_attr "length" "4,8")])
3625 (define_insn_and_split "*bool<mode>3_dot2"
3626   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3627         (compare:CC (match_operator:GPR 3 "boolean_operator"
3628          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3629           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3630          (const_int 0)))
3631    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3632         (match_dup 3))]
3633   "<MODE>mode == Pmode"
3634   "@
3635    %q3. %0,%1,%2
3636    #"
3637   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3638   [(set (match_dup 0)
3639         (match_dup 3))
3640    (set (match_dup 4)
3641         (compare:CC (match_dup 0)
3642                     (const_int 0)))]
3643   ""
3644   [(set_attr "type" "logical")
3645    (set_attr "dot" "yes")
3646    (set_attr "length" "4,8")])
3649 (define_insn "*boolc<mode>3"
3650   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3651         (match_operator:GPR 3 "boolean_operator"
3652          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3653           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3654   ""
3655   "%q3 %0,%1,%2"
3656   [(set_attr "type" "logical")])
3658 (define_insn_and_split "*boolc<mode>3_dot"
3659   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3660         (compare:CC (match_operator:GPR 3 "boolean_operator"
3661          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3662           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3663          (const_int 0)))
3664    (clobber (match_scratch:GPR 0 "=r,r"))]
3665   "<MODE>mode == Pmode"
3666   "@
3667    %q3. %0,%1,%2
3668    #"
3669   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3670   [(set (match_dup 0)
3671         (match_dup 3))
3672    (set (match_dup 4)
3673         (compare:CC (match_dup 0)
3674                     (const_int 0)))]
3675   ""
3676   [(set_attr "type" "logical")
3677    (set_attr "dot" "yes")
3678    (set_attr "length" "4,8")])
3680 (define_insn_and_split "*boolc<mode>3_dot2"
3681   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3682         (compare:CC (match_operator:GPR 3 "boolean_operator"
3683          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3684           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3685          (const_int 0)))
3686    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3687         (match_dup 3))]
3688   "<MODE>mode == Pmode"
3689   "@
3690    %q3. %0,%1,%2
3691    #"
3692   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3693   [(set (match_dup 0)
3694         (match_dup 3))
3695    (set (match_dup 4)
3696         (compare:CC (match_dup 0)
3697                     (const_int 0)))]
3698   ""
3699   [(set_attr "type" "logical")
3700    (set_attr "dot" "yes")
3701    (set_attr "length" "4,8")])
3704 (define_insn "*boolcc<mode>3"
3705   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3706         (match_operator:GPR 3 "boolean_operator"
3707          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3708           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3709   ""
3710   "%q3 %0,%1,%2"
3711   [(set_attr "type" "logical")])
3713 (define_insn_and_split "*boolcc<mode>3_dot"
3714   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3715         (compare:CC (match_operator:GPR 3 "boolean_operator"
3716          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3717           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3718          (const_int 0)))
3719    (clobber (match_scratch:GPR 0 "=r,r"))]
3720   "<MODE>mode == Pmode"
3721   "@
3722    %q3. %0,%1,%2
3723    #"
3724   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3725   [(set (match_dup 0)
3726         (match_dup 3))
3727    (set (match_dup 4)
3728         (compare:CC (match_dup 0)
3729                     (const_int 0)))]
3730   ""
3731   [(set_attr "type" "logical")
3732    (set_attr "dot" "yes")
3733    (set_attr "length" "4,8")])
3735 (define_insn_and_split "*boolcc<mode>3_dot2"
3736   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3737         (compare:CC (match_operator:GPR 3 "boolean_operator"
3738          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3739           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3740          (const_int 0)))
3741    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3742         (match_dup 3))]
3743   "<MODE>mode == Pmode"
3744   "@
3745    %q3. %0,%1,%2
3746    #"
3747   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3748   [(set (match_dup 0)
3749         (match_dup 3))
3750    (set (match_dup 4)
3751         (compare:CC (match_dup 0)
3752                     (const_int 0)))]
3753   ""
3754   [(set_attr "type" "logical")
3755    (set_attr "dot" "yes")
3756    (set_attr "length" "4,8")])
3759 ;; TODO: Should have dots of this as well.
3760 (define_insn "*eqv<mode>3"
3761   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3763                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3764   ""
3765   "eqv %0,%1,%2"
3766   [(set_attr "type" "logical")])
3768 ;; Rotate-and-mask and insert.
3770 (define_insn "*rotl<mode>3_mask"
3771   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3772         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3773                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3774                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3775                  (match_operand:GPR 3 "const_int_operand" "n")))]
3776   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3778   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3780   [(set_attr "type" "shift")
3781    (set_attr "maybe_var_shift" "yes")])
3783 (define_insn_and_split "*rotl<mode>3_mask_dot"
3784   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3785         (compare:CC
3786           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3787                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3788                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3789                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3790           (const_int 0)))
3791    (clobber (match_scratch:GPR 0 "=r,r"))]
3792   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3793    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3795   if (which_alternative == 0)
3796     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3797   else
3798     return "#";
3800   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3801   [(set (match_dup 0)
3802         (and:GPR (match_dup 4)
3803                  (match_dup 3)))
3804    (set (match_dup 5)
3805         (compare:CC (match_dup 0)
3806                     (const_int 0)))]
3807   ""
3808   [(set_attr "type" "shift")
3809    (set_attr "maybe_var_shift" "yes")
3810    (set_attr "dot" "yes")
3811    (set_attr "length" "4,8")])
3813 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3814   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3815         (compare:CC
3816           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3817                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3818                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3819                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3820           (const_int 0)))
3821    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3822         (and:GPR (match_dup 4)
3823                  (match_dup 3)))]
3824   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3825    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3827   if (which_alternative == 0)
3828     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3829   else
3830     return "#";
3832   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3833   [(set (match_dup 0)
3834         (and:GPR (match_dup 4)
3835                  (match_dup 3)))
3836    (set (match_dup 5)
3837         (compare:CC (match_dup 0)
3838                     (const_int 0)))]
3839   ""
3840   [(set_attr "type" "shift")
3841    (set_attr "maybe_var_shift" "yes")
3842    (set_attr "dot" "yes")
3843    (set_attr "length" "4,8")])
3845 ; Special case for less-than-0.  We can do it with just one machine
3846 ; instruction, but the generic optimizers do not realise it is cheap.
3847 (define_insn "*lt0_<mode>di"
3848   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3849         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3850                 (const_int 0)))]
3851   "TARGET_POWERPC64"
3852   "srdi %0,%1,63"
3853   [(set_attr "type" "shift")])
3855 (define_insn "*lt0_<mode>si"
3856   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3857         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3858                 (const_int 0)))]
3859   ""
3860   "rlwinm %0,%1,1,31,31"
3861   [(set_attr "type" "shift")])
3865 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3866 ; both are an AND so are the same precedence).
3867 (define_insn "*rotl<mode>3_insert"
3868   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871                             (match_operand:SI 2 "const_int_operand" "n")])
3872                           (match_operand:GPR 3 "const_int_operand" "n"))
3873                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3874                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3875   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3876    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3878   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3880   [(set_attr "type" "insert")])
3881 ; FIXME: this needs an attr "size", so that the scheduler can see the
3882 ; difference between rlwimi and rldimi.  We also might want dot forms,
3883 ; but not for rlwimi on POWER4 and similar processors.
3885 (define_insn "*rotl<mode>3_insert_2"
3886   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3887         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3888                           (match_operand:GPR 6 "const_int_operand" "n"))
3889                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3890                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3891                             (match_operand:SI 2 "const_int_operand" "n")])
3892                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3893   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3894    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3896   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3898   [(set_attr "type" "insert")])
3900 ; There are also some forms without one of the ANDs.
3901 (define_insn "*rotl<mode>3_insert_3"
3902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3903         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3904                           (match_operand:GPR 4 "const_int_operand" "n"))
3905                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3906                              (match_operand:SI 2 "const_int_operand" "n"))))]
3907   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3909   if (<MODE>mode == SImode)
3910     return "rlwimi %0,%1,%h2,0,31-%h2";
3911   else
3912     return "rldimi %0,%1,%H2,0";
3914   [(set_attr "type" "insert")])
3916 (define_insn "*rotl<mode>3_insert_4"
3917   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3918         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3919                           (match_operand:GPR 4 "const_int_operand" "n"))
3920                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3921                                (match_operand:SI 2 "const_int_operand" "n"))))]
3922   "<MODE>mode == SImode &&
3923    GET_MODE_PRECISION (<MODE>mode)
3924    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3926   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3927                          - INTVAL (operands[2]));
3928   if (<MODE>mode == SImode)
3929     return "rlwimi %0,%1,%h2,32-%h2,31";
3930   else
3931     return "rldimi %0,%1,%H2,64-%H2";
3933   [(set_attr "type" "insert")])
3935 (define_insn "*rotlsi3_insert_5"
3936   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3937         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3938                         (match_operand:SI 2 "const_int_operand" "n,n"))
3939                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3940                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
3941   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3942    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3943    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3944   "@
3945    rlwimi %0,%3,0,%4
3946    rlwimi %0,%1,0,%2"
3947   [(set_attr "type" "insert")])
3949 (define_insn "*rotldi3_insert_6"
3950   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3951         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3952                         (match_operand:DI 2 "const_int_operand" "n"))
3953                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3954                         (match_operand:DI 4 "const_int_operand" "n"))))]
3955   "exact_log2 (-UINTVAL (operands[2])) > 0
3956    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3958   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3959   return "rldimi %0,%3,0,%5";
3961   [(set_attr "type" "insert")
3962    (set_attr "size" "64")])
3964 (define_insn "*rotldi3_insert_7"
3965   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3966         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3967                         (match_operand:DI 4 "const_int_operand" "n"))
3968                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3969                         (match_operand:DI 2 "const_int_operand" "n"))))]
3970   "exact_log2 (-UINTVAL (operands[2])) > 0
3971    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3973   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3974   return "rldimi %0,%3,0,%5";
3976   [(set_attr "type" "insert")
3977    (set_attr "size" "64")])
3980 ; This handles the important case of multiple-precision shifts.  There is
3981 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3982 (define_split
3983   [(set (match_operand:GPR 0 "gpc_reg_operand")
3984         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3985                              (match_operand:SI 3 "const_int_operand"))
3986                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3987                                (match_operand:SI 4 "const_int_operand"))))]
3988   "can_create_pseudo_p ()
3989    && INTVAL (operands[3]) + INTVAL (operands[4])
3990       >= GET_MODE_PRECISION (<MODE>mode)"
3991   [(set (match_dup 5)
3992         (lshiftrt:GPR (match_dup 2)
3993                       (match_dup 4)))
3994    (set (match_dup 0)
3995         (ior:GPR (and:GPR (match_dup 5)
3996                           (match_dup 6))
3997                  (ashift:GPR (match_dup 1)
3998                              (match_dup 3))))]
4000   unsigned HOST_WIDE_INT mask = 1;
4001   mask = (mask << INTVAL (operands[3])) - 1;
4002   operands[5] = gen_reg_rtx (<MODE>mode);
4003   operands[6] = GEN_INT (mask);
4006 (define_split
4007   [(set (match_operand:GPR 0 "gpc_reg_operand")
4008         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4009                                (match_operand:SI 4 "const_int_operand"))
4010                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4011                              (match_operand:SI 3 "const_int_operand"))))]
4012   "can_create_pseudo_p ()
4013    && INTVAL (operands[3]) + INTVAL (operands[4])
4014       >= GET_MODE_PRECISION (<MODE>mode)"
4015   [(set (match_dup 5)
4016         (lshiftrt:GPR (match_dup 2)
4017                       (match_dup 4)))
4018    (set (match_dup 0)
4019         (ior:GPR (and:GPR (match_dup 5)
4020                           (match_dup 6))
4021                  (ashift:GPR (match_dup 1)
4022                              (match_dup 3))))]
4024   unsigned HOST_WIDE_INT mask = 1;
4025   mask = (mask << INTVAL (operands[3])) - 1;
4026   operands[5] = gen_reg_rtx (<MODE>mode);
4027   operands[6] = GEN_INT (mask);
4031 ; Another important case is setting some bits to 1; we can do that with
4032 ; an insert instruction, in many cases.
4033 (define_insn_and_split "*ior<mode>_mask"
4034   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4035         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4036                  (match_operand:GPR 2 "const_int_operand" "n")))
4037    (clobber (match_scratch:GPR 3 "=r"))]
4038   "!logical_const_operand (operands[2], <MODE>mode)
4039    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4040   "#"
4041   "&& 1"
4042   [(set (match_dup 3)
4043         (const_int -1))
4044    (set (match_dup 0)
4045         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4046                                       (match_dup 4))
4047                           (match_dup 2))
4048                  (and:GPR (match_dup 1)
4049                           (match_dup 5))))]
4051   int nb, ne;
4052   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4053   if (GET_CODE (operands[3]) == SCRATCH)
4054     operands[3] = gen_reg_rtx (<MODE>mode);
4055   operands[4] = GEN_INT (ne);
4056   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4058   [(set_attr "type" "two")
4059    (set_attr "length" "8")])
4062 ;; Now the simple shifts.
4064 (define_insn "rotl<mode>3"
4065   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4066         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4067                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4068   ""
4069   "rotl<wd>%I2 %0,%1,%<hH>2"
4070   [(set_attr "type" "shift")
4071    (set_attr "maybe_var_shift" "yes")])
4073 (define_insn "*rotlsi3_64"
4074   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4075         (zero_extend:DI
4076             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4077                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4078   "TARGET_POWERPC64"
4079   "rotlw%I2 %0,%1,%h2"
4080   [(set_attr "type" "shift")
4081    (set_attr "maybe_var_shift" "yes")])
4083 (define_insn_and_split "*rotl<mode>3_dot"
4084   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4085         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4086                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4087                     (const_int 0)))
4088    (clobber (match_scratch:GPR 0 "=r,r"))]
4089   "<MODE>mode == Pmode"
4090   "@
4091    rotl<wd>%I2. %0,%1,%<hH>2
4092    #"
4093   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4094   [(set (match_dup 0)
4095         (rotate:GPR (match_dup 1)
4096                     (match_dup 2)))
4097    (set (match_dup 3)
4098         (compare:CC (match_dup 0)
4099                     (const_int 0)))]
4100   ""
4101   [(set_attr "type" "shift")
4102    (set_attr "maybe_var_shift" "yes")
4103    (set_attr "dot" "yes")
4104    (set_attr "length" "4,8")])
4106 (define_insn_and_split "*rotl<mode>3_dot2"
4107   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4108         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4109                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4110                     (const_int 0)))
4111    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4112         (rotate:GPR (match_dup 1)
4113                     (match_dup 2)))]
4114   "<MODE>mode == Pmode"
4115   "@
4116    rotl<wd>%I2. %0,%1,%<hH>2
4117    #"
4118   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4119   [(set (match_dup 0)
4120         (rotate:GPR (match_dup 1)
4121                     (match_dup 2)))
4122    (set (match_dup 3)
4123         (compare:CC (match_dup 0)
4124                     (const_int 0)))]
4125   ""
4126   [(set_attr "type" "shift")
4127    (set_attr "maybe_var_shift" "yes")
4128    (set_attr "dot" "yes")
4129    (set_attr "length" "4,8")])
4132 (define_insn "ashl<mode>3"
4133   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4134         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4135                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4136   ""
4137   "sl<wd>%I2 %0,%1,%<hH>2"
4138   [(set_attr "type" "shift")
4139    (set_attr "maybe_var_shift" "yes")])
4141 (define_insn "*ashlsi3_64"
4142   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4143         (zero_extend:DI
4144             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4145                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4146   "TARGET_POWERPC64"
4147   "slw%I2 %0,%1,%h2"
4148   [(set_attr "type" "shift")
4149    (set_attr "maybe_var_shift" "yes")])
4151 (define_insn_and_split "*ashl<mode>3_dot"
4152   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4153         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4154                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4155                     (const_int 0)))
4156    (clobber (match_scratch:GPR 0 "=r,r"))]
4157   "<MODE>mode == Pmode"
4158   "@
4159    sl<wd>%I2. %0,%1,%<hH>2
4160    #"
4161   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4162   [(set (match_dup 0)
4163         (ashift:GPR (match_dup 1)
4164                     (match_dup 2)))
4165    (set (match_dup 3)
4166         (compare:CC (match_dup 0)
4167                     (const_int 0)))]
4168   ""
4169   [(set_attr "type" "shift")
4170    (set_attr "maybe_var_shift" "yes")
4171    (set_attr "dot" "yes")
4172    (set_attr "length" "4,8")])
4174 (define_insn_and_split "*ashl<mode>3_dot2"
4175   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4176         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4177                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4178                     (const_int 0)))
4179    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4180         (ashift:GPR (match_dup 1)
4181                     (match_dup 2)))]
4182   "<MODE>mode == Pmode"
4183   "@
4184    sl<wd>%I2. %0,%1,%<hH>2
4185    #"
4186   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4187   [(set (match_dup 0)
4188         (ashift:GPR (match_dup 1)
4189                     (match_dup 2)))
4190    (set (match_dup 3)
4191         (compare:CC (match_dup 0)
4192                     (const_int 0)))]
4193   ""
4194   [(set_attr "type" "shift")
4195    (set_attr "maybe_var_shift" "yes")
4196    (set_attr "dot" "yes")
4197    (set_attr "length" "4,8")])
4199 ;; Pretend we have a memory form of extswsli until register allocation is done
4200 ;; so that we use LWZ to load the value from memory, instead of LWA.
4201 (define_insn_and_split "ashdi3_extswsli"
4202   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4203         (ashift:DI
4204          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4205          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4206   "TARGET_EXTSWSLI"
4207   "@
4208    extswsli %0,%1,%2
4209    #"
4210   "&& reload_completed && MEM_P (operands[1])"
4211   [(set (match_dup 3)
4212         (match_dup 1))
4213    (set (match_dup 0)
4214         (ashift:DI (sign_extend:DI (match_dup 3))
4215                    (match_dup 2)))]
4217   operands[3] = gen_lowpart (SImode, operands[0]);
4219   [(set_attr "type" "shift")
4220    (set_attr "maybe_var_shift" "no")])
4223 (define_insn_and_split "ashdi3_extswsli_dot"
4224   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4225         (compare:CC
4226          (ashift:DI
4227           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4228           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4229          (const_int 0)))
4230    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4231   "TARGET_EXTSWSLI"
4232   "@
4233    extswsli. %0,%1,%2
4234    #
4235    #
4236    #"
4237   "&& reload_completed
4238    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4239        || memory_operand (operands[1], SImode))"
4240   [(pc)]
4242   rtx dest = operands[0];
4243   rtx src = operands[1];
4244   rtx shift = operands[2];
4245   rtx cr = operands[3];
4246   rtx src2;
4248   if (!MEM_P (src))
4249     src2 = src;
4250   else
4251     {
4252       src2 = gen_lowpart (SImode, dest);
4253       emit_move_insn (src2, src);
4254     }
4256   if (REGNO (cr) == CR0_REGNO)
4257     {
4258       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4259       DONE;
4260     }
4262   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4263   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4264   DONE;
4266   [(set_attr "type" "shift")
4267    (set_attr "maybe_var_shift" "no")
4268    (set_attr "dot" "yes")
4269    (set_attr "length" "4,8,8,12")])
4271 (define_insn_and_split "ashdi3_extswsli_dot2"
4272   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4273         (compare:CC
4274          (ashift:DI
4275           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4276           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4277          (const_int 0)))
4278    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4279         (ashift:DI (sign_extend:DI (match_dup 1))
4280                    (match_dup 2)))]
4281   "TARGET_EXTSWSLI"
4282   "@
4283    extswsli. %0,%1,%2
4284    #
4285    #
4286    #"
4287   "&& reload_completed
4288    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4289        || memory_operand (operands[1], SImode))"
4290   [(pc)]
4292   rtx dest = operands[0];
4293   rtx src = operands[1];
4294   rtx shift = operands[2];
4295   rtx cr = operands[3];
4296   rtx src2;
4298   if (!MEM_P (src))
4299     src2 = src;
4300   else
4301     {
4302       src2 = gen_lowpart (SImode, dest);
4303       emit_move_insn (src2, src);
4304     }
4306   if (REGNO (cr) == CR0_REGNO)
4307     {
4308       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4309       DONE;
4310     }
4312   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4313   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4314   DONE;
4316   [(set_attr "type" "shift")
4317    (set_attr "maybe_var_shift" "no")
4318    (set_attr "dot" "yes")
4319    (set_attr "length" "4,8,8,12")])
4321 (define_insn "lshr<mode>3"
4322   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4323         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4324                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4325   ""
4326   "sr<wd>%I2 %0,%1,%<hH>2"
4327   [(set_attr "type" "shift")
4328    (set_attr "maybe_var_shift" "yes")])
4330 (define_insn "*lshrsi3_64"
4331   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4332         (zero_extend:DI
4333             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4334                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4335   "TARGET_POWERPC64"
4336   "srw%I2 %0,%1,%h2"
4337   [(set_attr "type" "shift")
4338    (set_attr "maybe_var_shift" "yes")])
4340 (define_insn_and_split "*lshr<mode>3_dot"
4341   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4342         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4343                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4344                     (const_int 0)))
4345    (clobber (match_scratch:GPR 0 "=r,r"))]
4346   "<MODE>mode == Pmode"
4347   "@
4348    sr<wd>%I2. %0,%1,%<hH>2
4349    #"
4350   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4351   [(set (match_dup 0)
4352         (lshiftrt:GPR (match_dup 1)
4353                       (match_dup 2)))
4354    (set (match_dup 3)
4355         (compare:CC (match_dup 0)
4356                     (const_int 0)))]
4357   ""
4358   [(set_attr "type" "shift")
4359    (set_attr "maybe_var_shift" "yes")
4360    (set_attr "dot" "yes")
4361    (set_attr "length" "4,8")])
4363 (define_insn_and_split "*lshr<mode>3_dot2"
4364   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4365         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4366                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4367                     (const_int 0)))
4368    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4369         (lshiftrt:GPR (match_dup 1)
4370                       (match_dup 2)))]
4371   "<MODE>mode == Pmode"
4372   "@
4373    sr<wd>%I2. %0,%1,%<hH>2
4374    #"
4375   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4376   [(set (match_dup 0)
4377         (lshiftrt:GPR (match_dup 1)
4378                       (match_dup 2)))
4379    (set (match_dup 3)
4380         (compare:CC (match_dup 0)
4381                     (const_int 0)))]
4382   ""
4383   [(set_attr "type" "shift")
4384    (set_attr "maybe_var_shift" "yes")
4385    (set_attr "dot" "yes")
4386    (set_attr "length" "4,8")])
4389 (define_insn "ashr<mode>3"
4390   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4391         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4392                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4393    (clobber (reg:GPR CA_REGNO))]
4394   ""
4395   "sra<wd>%I2 %0,%1,%<hH>2"
4396   [(set_attr "type" "shift")
4397    (set_attr "maybe_var_shift" "yes")])
4399 (define_insn "*ashrsi3_64"
4400   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4401         (sign_extend:DI
4402             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4403                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4404    (clobber (reg:SI CA_REGNO))]
4405   "TARGET_POWERPC64"
4406   "sraw%I2 %0,%1,%h2"
4407   [(set_attr "type" "shift")
4408    (set_attr "maybe_var_shift" "yes")])
4410 (define_insn_and_split "*ashr<mode>3_dot"
4411   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4412         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4413                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4414                     (const_int 0)))
4415    (clobber (match_scratch:GPR 0 "=r,r"))
4416    (clobber (reg:GPR CA_REGNO))]
4417   "<MODE>mode == Pmode"
4418   "@
4419    sra<wd>%I2. %0,%1,%<hH>2
4420    #"
4421   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4422   [(parallel [(set (match_dup 0)
4423                    (ashiftrt:GPR (match_dup 1)
4424                                  (match_dup 2)))
4425               (clobber (reg:GPR CA_REGNO))])
4426    (set (match_dup 3)
4427         (compare:CC (match_dup 0)
4428                     (const_int 0)))]
4429   ""
4430   [(set_attr "type" "shift")
4431    (set_attr "maybe_var_shift" "yes")
4432    (set_attr "dot" "yes")
4433    (set_attr "length" "4,8")])
4435 (define_insn_and_split "*ashr<mode>3_dot2"
4436   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4437         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4438                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4439                     (const_int 0)))
4440    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4441         (ashiftrt:GPR (match_dup 1)
4442                       (match_dup 2)))
4443    (clobber (reg:GPR CA_REGNO))]
4444   "<MODE>mode == Pmode"
4445   "@
4446    sra<wd>%I2. %0,%1,%<hH>2
4447    #"
4448   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4449   [(parallel [(set (match_dup 0)
4450                    (ashiftrt:GPR (match_dup 1)
4451                                  (match_dup 2)))
4452               (clobber (reg:GPR CA_REGNO))])
4453    (set (match_dup 3)
4454         (compare:CC (match_dup 0)
4455                     (const_int 0)))]
4456   ""
4457   [(set_attr "type" "shift")
4458    (set_attr "maybe_var_shift" "yes")
4459    (set_attr "dot" "yes")
4460    (set_attr "length" "4,8")])
4462 ;; Builtins to replace a division to generate FRE reciprocal estimate
4463 ;; instructions and the necessary fixup instructions
4464 (define_expand "recip<mode>3"
4465   [(match_operand:RECIPF 0 "gpc_reg_operand")
4466    (match_operand:RECIPF 1 "gpc_reg_operand")
4467    (match_operand:RECIPF 2 "gpc_reg_operand")]
4468   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4470    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4471    DONE;
4474 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4475 ;; hardware division.  This is only done before register allocation and with
4476 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4477 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4478 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4479 (define_split
4480   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4481         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4482                     (match_operand 2 "gpc_reg_operand")))]
4483   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4484    && can_create_pseudo_p () && flag_finite_math_only
4485    && !flag_trapping_math && flag_reciprocal_math"
4486   [(const_int 0)]
4488   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4489   DONE;
4492 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4493 ;; appropriate fixup.
4494 (define_expand "rsqrt<mode>2"
4495   [(match_operand:RECIPF 0 "gpc_reg_operand")
4496    (match_operand:RECIPF 1 "gpc_reg_operand")]
4497   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4499   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4500   DONE;
4503 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4504 ;; modes here, and also add in conditional vsx/power8-vector support to access
4505 ;; values in the traditional Altivec registers if the appropriate
4506 ;; -mupper-regs-{df,sf} option is enabled.
4508 (define_expand "abs<mode>2"
4509   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4510         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4511   "TARGET_HARD_FLOAT"
4512   "")
4514 (define_insn "*abs<mode>2_fpr"
4515   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4516         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4517   "TARGET_HARD_FLOAT"
4518   "@
4519    fabs %0,%1
4520    xsabsdp %x0,%x1"
4521   [(set_attr "type" "fpsimple")])
4523 (define_insn "*nabs<mode>2_fpr"
4524   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4525         (neg:SFDF
4526          (abs:SFDF
4527           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4528   "TARGET_HARD_FLOAT"
4529   "@
4530    fnabs %0,%1
4531    xsnabsdp %x0,%x1"
4532   [(set_attr "type" "fpsimple")])
4534 (define_expand "neg<mode>2"
4535   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4536         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4537   "TARGET_HARD_FLOAT"
4538   "")
4540 (define_insn "*neg<mode>2_fpr"
4541   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4542         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4543   "TARGET_HARD_FLOAT"
4544   "@
4545    fneg %0,%1
4546    xsnegdp %x0,%x1"
4547   [(set_attr "type" "fpsimple")])
4549 (define_expand "add<mode>3"
4550   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4551         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4552                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4553   "TARGET_HARD_FLOAT"
4554   "")
4556 (define_insn "*add<mode>3_fpr"
4557   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4558         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4559                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4560   "TARGET_HARD_FLOAT"
4561   "@
4562    fadd<Ftrad> %0,%1,%2
4563    xsadd<Fvsx> %x0,%x1,%x2"
4564   [(set_attr "type" "fp")])
4566 (define_expand "sub<mode>3"
4567   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4568         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4569                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4570   "TARGET_HARD_FLOAT"
4571   "")
4573 (define_insn "*sub<mode>3_fpr"
4574   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4575         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4576                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4577   "TARGET_HARD_FLOAT"
4578   "@
4579    fsub<Ftrad> %0,%1,%2
4580    xssub<Fvsx> %x0,%x1,%x2"
4581   [(set_attr "type" "fp")])
4583 (define_expand "mul<mode>3"
4584   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4585         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4586                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4587   "TARGET_HARD_FLOAT"
4588   "")
4590 (define_insn "*mul<mode>3_fpr"
4591   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4592         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4593                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4594   "TARGET_HARD_FLOAT"
4595   "@
4596    fmul<Ftrad> %0,%1,%2
4597    xsmul<Fvsx> %x0,%x1,%x2"
4598   [(set_attr "type" "dmul")])
4600 (define_expand "div<mode>3"
4601   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4602         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4603                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4604   "TARGET_HARD_FLOAT"
4606   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4607       && can_create_pseudo_p () && flag_finite_math_only
4608       && !flag_trapping_math && flag_reciprocal_math)
4609     {
4610       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4611       DONE;
4612     }
4615 (define_insn "*div<mode>3_fpr"
4616   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4617         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4618                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4619   "TARGET_HARD_FLOAT"
4620   "@
4621    fdiv<Ftrad> %0,%1,%2
4622    xsdiv<Fvsx> %x0,%x1,%x2"
4623   [(set_attr "type" "<Fs>div")])
4625 (define_insn "*sqrt<mode>2_internal"
4626   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4627         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4628   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4629   "@
4630    fsqrt<Ftrad> %0,%1
4631    xssqrt<Fvsx> %x0,%x1"
4632   [(set_attr "type" "<Fs>sqrt")])
4634 (define_expand "sqrt<mode>2"
4635   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4636         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4637   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4639   if (<MODE>mode == SFmode
4640       && TARGET_RECIP_PRECISION
4641       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4642       && !optimize_function_for_size_p (cfun)
4643       && flag_finite_math_only && !flag_trapping_math
4644       && flag_unsafe_math_optimizations)
4645     {
4646       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4647       DONE;
4648     }
4651 ;; Floating point reciprocal approximation
4652 (define_insn "fre<Fs>"
4653   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4654         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4655                      UNSPEC_FRES))]
4656   "TARGET_<FFRE>"
4657   "@
4658    fre<Ftrad> %0,%1
4659    xsre<Fvsx> %x0,%x1"
4660   [(set_attr "type" "fp")])
4662 (define_insn "*rsqrt<mode>2"
4663   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4664         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4665                      UNSPEC_RSQRT))]
4666   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4667   "@
4668    frsqrte<Ftrad> %0,%1
4669    xsrsqrte<Fvsx> %x0,%x1"
4670   [(set_attr "type" "fp")])
4672 ;; Floating point comparisons
4673 (define_insn "*cmp<mode>_fpr"
4674   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4675         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4676                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4677   "TARGET_HARD_FLOAT"
4678   "@
4679    fcmpu %0,%1,%2
4680    xscmpudp %0,%x1,%x2"
4681   [(set_attr "type" "fpcompare")])
4683 ;; Floating point conversions
4684 (define_expand "extendsfdf2"
4685   [(set (match_operand:DF 0 "gpc_reg_operand")
4686         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4687   "TARGET_HARD_FLOAT"
4689   if (HONOR_SNANS (SFmode))
4690     operands[1] = force_reg (SFmode, operands[1]);
4693 (define_insn_and_split "*extendsfdf2_fpr"
4694   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4695         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4696   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4697   "@
4698    #
4699    fmr %0,%1
4700    lfs%U1%X1 %0,%1
4701    #
4702    xscpsgndp %x0,%x1,%x1
4703    lxsspx %x0,%y1
4704    lxssp %0,%1"
4705   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4706   [(const_int 0)]
4708   emit_note (NOTE_INSN_DELETED);
4709   DONE;
4711   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4713 (define_insn "*extendsfdf2_snan"
4714   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4715         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4716   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4717   "@
4718    frsp %0,%1
4719    xsrsp %x0,%x1"
4720   [(set_attr "type" "fp")])
4722 (define_expand "truncdfsf2"
4723   [(set (match_operand:SF 0 "gpc_reg_operand")
4724         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4725   "TARGET_HARD_FLOAT"
4726   "")
4728 (define_insn "*truncdfsf2_fpr"
4729   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4730         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4731   "TARGET_HARD_FLOAT"
4732   "@
4733    frsp %0,%1
4734    xsrsp %x0,%x1"
4735   [(set_attr "type" "fp")])
4737 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4738 ;; builtins.c and optabs.c that are not correct for IBM long double
4739 ;; when little-endian.
4740 (define_expand "signbit<mode>2"
4741   [(set (match_dup 2)
4742         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4743    (set (match_dup 3)
4744         (subreg:DI (match_dup 2) 0))
4745    (set (match_dup 4)
4746         (match_dup 5))
4747    (set (match_operand:SI 0 "gpc_reg_operand")
4748         (match_dup 6))]
4749   "TARGET_HARD_FLOAT
4750    && (!FLOAT128_IEEE_P (<MODE>mode)
4751        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4753   if (FLOAT128_IEEE_P (<MODE>mode))
4754     {
4755       rtx dest = operands[0];
4756       rtx src = operands[1];
4757       rtx tmp = gen_reg_rtx (DImode);
4758       rtx dest_di = gen_lowpart (DImode, dest);
4760       if (<MODE>mode == KFmode)
4761         emit_insn (gen_signbitkf2_dm (tmp, src));
4762       else if (<MODE>mode == TFmode)
4763         emit_insn (gen_signbittf2_dm (tmp, src));
4764       else
4765         gcc_unreachable ();
4767       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4768       DONE;
4769     }
4770   operands[2] = gen_reg_rtx (DFmode);
4771   operands[3] = gen_reg_rtx (DImode);
4772   if (TARGET_POWERPC64)
4773     {
4774       operands[4] = gen_reg_rtx (DImode);
4775       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4776       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4777                                     WORDS_BIG_ENDIAN ? 4 : 0);
4778     }
4779   else
4780     {
4781       operands[4] = gen_reg_rtx (SImode);
4782       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4783                                     WORDS_BIG_ENDIAN ? 0 : 4);
4784       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4785     }
4788 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4789 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4790 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4791 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4793 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4794 ;; split allows the post reload phases to eliminate the move, and do the shift
4795 ;; directly with the register that contains the signbit.
4796 (define_insn_and_split "signbit<mode>2_dm"
4797   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4798         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4799                    UNSPEC_SIGNBIT))]
4800   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4801   "@
4802    mfvsrd %0,%x1
4803    #"
4804   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4805   [(set (match_dup 0)
4806         (match_dup 2))]
4808   operands[2] = gen_highpart (DImode, operands[1]);
4810  [(set_attr "type" "mftgpr,*")])
4812 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4813 ;; register and then doing a direct move if the value comes from memory.  On
4814 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4815 (define_insn_and_split "*signbit<mode>2_dm_mem"
4816   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4817         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4818                    UNSPEC_SIGNBIT))]
4819   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4820   "#"
4821   "&& 1"
4822   [(set (match_dup 0)
4823         (match_dup 2))]
4825   rtx dest = operands[0];
4826   rtx src = operands[1];
4827   rtx addr = XEXP (src, 0);
4829   if (WORDS_BIG_ENDIAN)
4830     operands[2] = adjust_address (src, DImode, 0);
4832   else if (REG_P (addr) || SUBREG_P (addr))
4833     operands[2] = adjust_address (src, DImode, 8);
4835   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4836            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4837     operands[2] = adjust_address (src, DImode, 8);
4839   else
4840     {
4841       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4842       emit_insn (gen_rtx_SET (tmp, addr));
4843       operands[2] = change_address (src, DImode,
4844                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4845     }
4848 (define_expand "copysign<mode>3"
4849   [(set (match_dup 3)
4850         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4851    (set (match_dup 4)
4852         (neg:SFDF (abs:SFDF (match_dup 1))))
4853    (set (match_operand:SFDF 0 "gpc_reg_operand")
4854         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4855                                (match_dup 5))
4856                          (match_dup 3)
4857                          (match_dup 4)))]
4858   "TARGET_HARD_FLOAT
4859    && ((TARGET_PPC_GFXOPT
4860         && !HONOR_NANS (<MODE>mode)
4861         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4862        || TARGET_CMPB
4863        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4865   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4866     {
4867       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4868                                              operands[2]));
4869       DONE;
4870     }
4872    operands[3] = gen_reg_rtx (<MODE>mode);
4873    operands[4] = gen_reg_rtx (<MODE>mode);
4874    operands[5] = CONST0_RTX (<MODE>mode);
4875   })
4877 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4878 ;; compiler from optimizing -0.0
4879 (define_insn "copysign<mode>3_fcpsgn"
4880   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4881         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4882                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4883                      UNSPEC_COPYSIGN))]
4884   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4885   "@
4886    fcpsgn %0,%2,%1
4887    xscpsgndp %x0,%x2,%x1"
4888   [(set_attr "type" "fpsimple")])
4890 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4891 ;; fsel instruction and some auxiliary computations.  Then we just have a
4892 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4893 ;; combine.
4894 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4895 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4896 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4897 ;; define_splits to make them if made by combine.  On VSX machines we have the
4898 ;; min/max instructions.
4900 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4901 ;; to allow either DF/SF to use only traditional registers.
4903 (define_expand "s<minmax><mode>3"
4904   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4905         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4906                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4907   "TARGET_MINMAX"
4909   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4910   DONE;
4913 (define_insn "*s<minmax><mode>3_vsx"
4914   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4915         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4916                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4917   "TARGET_VSX && TARGET_HARD_FLOAT"
4919   return (TARGET_P9_MINMAX
4920           ? "xs<minmax>cdp %x0,%x1,%x2"
4921           : "xs<minmax>dp %x0,%x1,%x2");
4923   [(set_attr "type" "fp")])
4925 ;; The conditional move instructions allow us to perform max and min operations
4926 ;; even when we don't have the appropriate max/min instruction using the FSEL
4927 ;; instruction.
4929 (define_insn_and_split "*s<minmax><mode>3_fpr"
4930   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4931         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4932                         (match_operand:SFDF 2 "gpc_reg_operand")))]
4933   "!TARGET_VSX && TARGET_MINMAX"
4934   "#"
4935   "&& 1"
4936   [(const_int 0)]
4938   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4939   DONE;
4942 (define_expand "mov<mode>cc"
4943    [(set (match_operand:GPR 0 "gpc_reg_operand")
4944          (if_then_else:GPR (match_operand 1 "comparison_operator")
4945                            (match_operand:GPR 2 "gpc_reg_operand")
4946                            (match_operand:GPR 3 "gpc_reg_operand")))]
4947   "TARGET_ISEL"
4949   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4950     DONE;
4951   else
4952     FAIL;
4955 ;; We use the BASE_REGS for the isel input operands because, if rA is
4956 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4957 ;; because we may switch the operands and rB may end up being rA.
4959 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4960 ;; leave out the mode in operand 4 and use one pattern, but reload can
4961 ;; change the mode underneath our feet and then gets confused trying
4962 ;; to reload the value.
4963 (define_insn "isel_signed_<mode>"
4964   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4965         (if_then_else:GPR
4966          (match_operator 1 "scc_comparison_operator"
4967                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4968                           (const_int 0)])
4969          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4970          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4971   "TARGET_ISEL"
4972   "isel %0,%2,%3,%j1"
4973   [(set_attr "type" "isel")])
4975 (define_insn "isel_unsigned_<mode>"
4976   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4977         (if_then_else:GPR
4978          (match_operator 1 "scc_comparison_operator"
4979                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4980                           (const_int 0)])
4981          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4982          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4983   "TARGET_ISEL"
4984   "isel %0,%2,%3,%j1"
4985   [(set_attr "type" "isel")])
4987 ;; These patterns can be useful for combine; they let combine know that
4988 ;; isel can handle reversed comparisons so long as the operands are
4989 ;; registers.
4991 (define_insn "*isel_reversed_signed_<mode>"
4992   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4993         (if_then_else:GPR
4994          (match_operator 1 "scc_rev_comparison_operator"
4995                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4996                           (const_int 0)])
4997          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
4998          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
4999   "TARGET_ISEL"
5001   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5002   return "isel %0,%3,%2,%j1";
5004   [(set_attr "type" "isel")])
5006 (define_insn "*isel_reversed_unsigned_<mode>"
5007   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5008         (if_then_else:GPR
5009          (match_operator 1 "scc_rev_comparison_operator"
5010                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5011                           (const_int 0)])
5012          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5013          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5014   "TARGET_ISEL"
5016   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5017   return "isel %0,%3,%2,%j1";
5019   [(set_attr "type" "isel")])
5021 ;; Floating point conditional move
5022 (define_expand "mov<mode>cc"
5023    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5024          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5025                             (match_operand:SFDF 2 "gpc_reg_operand")
5026                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5027   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5029   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5030     DONE;
5031   else
5032     FAIL;
5035 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5036   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5037         (if_then_else:SFDF
5038          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5039              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5040          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5041          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5042   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5043   "fsel %0,%1,%2,%3"
5044   [(set_attr "type" "fp")])
5046 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5047   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5048         (if_then_else:SFDF
5049          (match_operator:CCFP 1 "fpmask_comparison_operator"
5050                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5051                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5052          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5053          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5054    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5055   "TARGET_P9_MINMAX"
5056   "#"
5057   ""
5058   [(set (match_dup 6)
5059         (if_then_else:V2DI (match_dup 1)
5060                            (match_dup 7)
5061                            (match_dup 8)))
5062    (set (match_dup 0)
5063         (if_then_else:SFDF (ne (match_dup 6)
5064                                (match_dup 8))
5065                            (match_dup 4)
5066                            (match_dup 5)))]
5068   if (GET_CODE (operands[6]) == SCRATCH)
5069     operands[6] = gen_reg_rtx (V2DImode);
5071   operands[7] = CONSTM1_RTX (V2DImode);
5072   operands[8] = CONST0_RTX (V2DImode);
5074  [(set_attr "length" "8")
5075   (set_attr "type" "vecperm")])
5077 ;; Handle inverting the fpmask comparisons.
5078 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5079   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5080         (if_then_else:SFDF
5081          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5082                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5083                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5084          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5085          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5086    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5087   "TARGET_P9_MINMAX"
5088   "#"
5089   "&& 1"
5090   [(set (match_dup 6)
5091         (if_then_else:V2DI (match_dup 9)
5092                            (match_dup 7)
5093                            (match_dup 8)))
5094    (set (match_dup 0)
5095         (if_then_else:SFDF (ne (match_dup 6)
5096                                (match_dup 8))
5097                            (match_dup 5)
5098                            (match_dup 4)))]
5100   rtx op1 = operands[1];
5101   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5103   if (GET_CODE (operands[6]) == SCRATCH)
5104     operands[6] = gen_reg_rtx (V2DImode);
5106   operands[7] = CONSTM1_RTX (V2DImode);
5107   operands[8] = CONST0_RTX (V2DImode);
5109   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5111  [(set_attr "length" "8")
5112   (set_attr "type" "vecperm")])
5114 (define_insn "*fpmask<mode>"
5115   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5116         (if_then_else:V2DI
5117          (match_operator:CCFP 1 "fpmask_comparison_operator"
5118                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5119                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5120          (match_operand:V2DI 4 "all_ones_constant" "")
5121          (match_operand:V2DI 5 "zero_constant" "")))]
5122   "TARGET_P9_MINMAX"
5123   "xscmp%V1dp %x0,%x2,%x3"
5124   [(set_attr "type" "fpcompare")])
5126 (define_insn "*xxsel<mode>"
5127   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5128         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5129                                (match_operand:V2DI 2 "zero_constant" ""))
5130                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5131                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5132   "TARGET_P9_MINMAX"
5133   "xxsel %x0,%x4,%x3,%x1"
5134   [(set_attr "type" "vecmove")])
5137 ;; Conversions to and from floating-point.
5139 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5140 ; don't want to support putting SImode in FPR registers.
5141 (define_insn "lfiwax"
5142   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5143         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5144                    UNSPEC_LFIWAX))]
5145   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5146   "@
5147    lfiwax %0,%y1
5148    lxsiwax %x0,%y1
5149    mtvsrwa %x0,%1
5150    vextsw2d %0,%1"
5151   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5153 ; This split must be run before register allocation because it allocates the
5154 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5155 ; it earlier to allow for the combiner to merge insns together where it might
5156 ; not be needed and also in case the insns are deleted as dead code.
5158 (define_insn_and_split "floatsi<mode>2_lfiwax"
5159   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5160         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5161    (clobber (match_scratch:DI 2 "=wi"))]
5162   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5163    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5164   "#"
5165   ""
5166   [(pc)]
5168   rtx dest = operands[0];
5169   rtx src = operands[1];
5170   rtx tmp;
5172   if (!MEM_P (src) && TARGET_POWERPC64
5173       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5174     tmp = convert_to_mode (DImode, src, false);
5175   else
5176     {
5177       tmp = operands[2];
5178       if (GET_CODE (tmp) == SCRATCH)
5179         tmp = gen_reg_rtx (DImode);
5180       if (MEM_P (src))
5181         {
5182           src = rs6000_address_for_fpconvert (src);
5183           emit_insn (gen_lfiwax (tmp, src));
5184         }
5185       else
5186         {
5187           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5188           emit_move_insn (stack, src);
5189           emit_insn (gen_lfiwax (tmp, stack));
5190         }
5191     }
5192   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5193   DONE;
5195   [(set_attr "length" "12")
5196    (set_attr "type" "fpload")])
5198 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5199   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5200         (float:SFDF
5201          (sign_extend:DI
5202           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5203    (clobber (match_scratch:DI 2 "=wi"))]
5204   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5205   "#"
5206   ""
5207   [(pc)]
5209   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5210   if (GET_CODE (operands[2]) == SCRATCH)
5211     operands[2] = gen_reg_rtx (DImode);
5212   if (TARGET_P8_VECTOR)
5213     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5214   else
5215     emit_insn (gen_lfiwax (operands[2], operands[1]));
5216   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5217   DONE;
5219   [(set_attr "length" "8")
5220    (set_attr "type" "fpload")])
5222 (define_insn "lfiwzx"
5223   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5224         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5225                    UNSPEC_LFIWZX))]
5226   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5227   "@
5228    lfiwzx %0,%y1
5229    lxsiwzx %x0,%y1
5230    mtvsrwz %x0,%1
5231    xxextractuw %x0,%x1,4"
5232   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5234 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5235   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5236         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5237    (clobber (match_scratch:DI 2 "=wi"))]
5238   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5239   "#"
5240   ""
5241   [(pc)]
5243   rtx dest = operands[0];
5244   rtx src = operands[1];
5245   rtx tmp;
5247   if (!MEM_P (src) && TARGET_POWERPC64
5248       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5249     tmp = convert_to_mode (DImode, src, true);
5250   else
5251     {
5252       tmp = operands[2];
5253       if (GET_CODE (tmp) == SCRATCH)
5254         tmp = gen_reg_rtx (DImode);
5255       if (MEM_P (src))
5256         {
5257           src = rs6000_address_for_fpconvert (src);
5258           emit_insn (gen_lfiwzx (tmp, src));
5259         }
5260       else
5261         {
5262           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5263           emit_move_insn (stack, src);
5264           emit_insn (gen_lfiwzx (tmp, stack));
5265         }
5266     }
5267   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5268   DONE;
5270   [(set_attr "length" "12")
5271    (set_attr "type" "fpload")])
5273 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5274   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5275         (unsigned_float:SFDF
5276          (zero_extend:DI
5277           (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5278    (clobber (match_scratch:DI 2 "=wi"))]
5279   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5280   "#"
5281   ""
5282   [(pc)]
5284   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5285   if (GET_CODE (operands[2]) == SCRATCH)
5286     operands[2] = gen_reg_rtx (DImode);
5287   if (TARGET_P8_VECTOR)
5288     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5289   else
5290     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5291   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5292   DONE;
5294   [(set_attr "length" "8")
5295    (set_attr "type" "fpload")])
5297 ; For each of these conversions, there is a define_expand, a define_insn
5298 ; with a '#' template, and a define_split (with C code).  The idea is
5299 ; to allow constant folding with the template of the define_insn,
5300 ; then to have the insns split later (between sched1 and final).
5302 (define_expand "floatsidf2"
5303   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5304                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5305               (use (match_dup 2))
5306               (use (match_dup 3))
5307               (clobber (match_dup 4))
5308               (clobber (match_dup 5))
5309               (clobber (match_dup 6))])]
5310   "TARGET_HARD_FLOAT"
5312   if (TARGET_LFIWAX && TARGET_FCFID)
5313     {
5314       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5315       DONE;
5316     }
5317   else if (TARGET_FCFID)
5318     {
5319       rtx dreg = operands[1];
5320       if (!REG_P (dreg))
5321         dreg = force_reg (SImode, dreg);
5322       dreg = convert_to_mode (DImode, dreg, false);
5323       emit_insn (gen_floatdidf2 (operands[0], dreg));
5324       DONE;
5325     }
5327   if (!REG_P (operands[1]))
5328     operands[1] = force_reg (SImode, operands[1]);
5329   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5330   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5331   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5332   operands[5] = gen_reg_rtx (DFmode);
5333   operands[6] = gen_reg_rtx (SImode);
5336 (define_insn_and_split "*floatsidf2_internal"
5337   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5338         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5339    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5340    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5341    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5342    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5343    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5344   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5345   "#"
5346   ""
5347   [(pc)]
5349   rtx lowword, highword;
5350   gcc_assert (MEM_P (operands[4]));
5351   highword = adjust_address (operands[4], SImode, 0);
5352   lowword = adjust_address (operands[4], SImode, 4);
5353   if (! WORDS_BIG_ENDIAN)
5354     std::swap (lowword, highword);
5356   emit_insn (gen_xorsi3 (operands[6], operands[1],
5357                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5358   emit_move_insn (lowword, operands[6]);
5359   emit_move_insn (highword, operands[2]);
5360   emit_move_insn (operands[5], operands[4]);
5361   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5362   DONE;
5364   [(set_attr "length" "24")
5365    (set_attr "type" "fp")])
5367 ;; If we don't have a direct conversion to single precision, don't enable this
5368 ;; conversion for 32-bit without fast math, because we don't have the insn to
5369 ;; generate the fixup swizzle to avoid double rounding problems.
5370 (define_expand "floatunssisf2"
5371   [(set (match_operand:SF 0 "gpc_reg_operand")
5372         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5373   "TARGET_HARD_FLOAT
5374    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5375        || (TARGET_FCFID
5376            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5378   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5379     {
5380       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5381       DONE;
5382     }
5383   else
5384     {
5385       rtx dreg = operands[1];
5386       if (!REG_P (dreg))
5387         dreg = force_reg (SImode, dreg);
5388       dreg = convert_to_mode (DImode, dreg, true);
5389       emit_insn (gen_floatdisf2 (operands[0], dreg));
5390       DONE;
5391     }
5394 (define_expand "floatunssidf2"
5395   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5396                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5397               (use (match_dup 2))
5398               (use (match_dup 3))
5399               (clobber (match_dup 4))
5400               (clobber (match_dup 5))])]
5401   "TARGET_HARD_FLOAT"
5403   if (TARGET_LFIWZX && TARGET_FCFID)
5404     {
5405       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5406       DONE;
5407     }
5408   else if (TARGET_FCFID)
5409     {
5410       rtx dreg = operands[1];
5411       if (!REG_P (dreg))
5412         dreg = force_reg (SImode, dreg);
5413       dreg = convert_to_mode (DImode, dreg, true);
5414       emit_insn (gen_floatdidf2 (operands[0], dreg));
5415       DONE;
5416     }
5418   if (!REG_P (operands[1]))
5419     operands[1] = force_reg (SImode, operands[1]);
5420   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5421   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5422   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5423   operands[5] = gen_reg_rtx (DFmode);
5426 (define_insn_and_split "*floatunssidf2_internal"
5427   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5428         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5429    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5430    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5431    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5432    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5433   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5434    && !(TARGET_FCFID && TARGET_POWERPC64)"
5435   "#"
5436   ""
5437   [(pc)]
5439   rtx lowword, highword;
5440   gcc_assert (MEM_P (operands[4]));
5441   highword = adjust_address (operands[4], SImode, 0);
5442   lowword = adjust_address (operands[4], SImode, 4);
5443   if (! WORDS_BIG_ENDIAN)
5444     std::swap (lowword, highword);
5446   emit_move_insn (lowword, operands[1]);
5447   emit_move_insn (highword, operands[2]);
5448   emit_move_insn (operands[5], operands[4]);
5449   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5450   DONE;
5452   [(set_attr "length" "20")
5453    (set_attr "type" "fp")])
5455 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5456 ;; vector registers.  These insns favor doing the sign/zero extension in
5457 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5458 ;; extension and then a direct move.
5460 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5461   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5462                    (float:FP_ISA3
5463                     (match_operand:QHI 1 "input_operand")))
5464               (clobber (match_scratch:DI 2))
5465               (clobber (match_scratch:DI 3))
5466               (clobber (match_scratch:<QHI:MODE> 4))])]
5467   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5469   if (MEM_P (operands[1]))
5470     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5473 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5474   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5475         (float:FP_ISA3
5476          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5477    (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5478    (clobber (match_scratch:DI 3 "=X,r,X"))
5479    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5480   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5481   "#"
5482   "&& reload_completed"
5483   [(const_int 0)]
5485   rtx result = operands[0];
5486   rtx input = operands[1];
5487   rtx di = operands[2];
5489   if (!MEM_P (input))
5490     {
5491       rtx tmp = operands[3];
5492       if (altivec_register_operand (input, <QHI:MODE>mode))
5493         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5494       else if (GET_CODE (tmp) == SCRATCH)
5495         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5496       else
5497         {
5498           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5499           emit_move_insn (di, tmp);
5500         }
5501     }
5502   else
5503     {
5504       rtx tmp = operands[4];
5505       emit_move_insn (tmp, input);
5506       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5507     }
5509   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5510   DONE;
5513 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5514   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5515                    (unsigned_float:FP_ISA3
5516                     (match_operand:QHI 1 "input_operand")))
5517               (clobber (match_scratch:DI 2))
5518               (clobber (match_scratch:DI 3))])]
5519   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5521   if (MEM_P (operands[1]))
5522     operands[1] = rs6000_address_for_fpconvert (operands[1]);
5525 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5526   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5527         (unsigned_float:FP_ISA3
5528          (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5529    (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5530    (clobber (match_scratch:DI 3 "=X,r,X"))]
5531   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5532   "#"
5533   "&& reload_completed"
5534   [(const_int 0)]
5536   rtx result = operands[0];
5537   rtx input = operands[1];
5538   rtx di = operands[2];
5540   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5541     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5542   else
5543     {
5544       rtx tmp = operands[3];
5545       if (GET_CODE (tmp) == SCRATCH)
5546         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5547       else
5548         {
5549           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5550           emit_move_insn (di, tmp);
5551         }
5552     }
5554   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5555   DONE;
5558 (define_expand "fix_trunc<mode>si2"
5559   [(set (match_operand:SI 0 "gpc_reg_operand")
5560         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5561   "TARGET_HARD_FLOAT"
5563   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5564     {
5565       rtx src = force_reg (<MODE>mode, operands[1]);
5567       if (TARGET_STFIWX)
5568         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5569       else
5570         {
5571           rtx tmp = gen_reg_rtx (DImode);
5572           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5573           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5574                                                       tmp, stack));
5575         }
5576       DONE;
5577     }
5580 ; Like the convert to float patterns, this insn must be split before
5581 ; register allocation so that it can allocate the memory slot if it
5582 ; needed
5583 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5584   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5585         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5586    (clobber (match_scratch:DI 2 "=d"))]
5587   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5588    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5589   "#"
5590   ""
5591   [(pc)]
5593   rtx dest = operands[0];
5594   rtx src = operands[1];
5595   rtx tmp = operands[2];
5597   if (GET_CODE (tmp) == SCRATCH)
5598     tmp = gen_reg_rtx (DImode);
5600   emit_insn (gen_fctiwz_<mode> (tmp, src));
5601   if (MEM_P (dest))
5602     {
5603       dest = rs6000_address_for_fpconvert (dest);
5604       emit_insn (gen_stfiwx (dest, tmp));
5605       DONE;
5606     }
5607   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5608     {
5609       dest = gen_lowpart (DImode, dest);
5610       emit_move_insn (dest, tmp);
5611       DONE;
5612     }
5613   else
5614     {
5615       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5616       emit_insn (gen_stfiwx (stack, tmp));
5617       emit_move_insn (dest, stack);
5618       DONE;
5619     }
5621   [(set_attr "length" "12")
5622    (set_attr "type" "fp")])
5624 (define_insn_and_split "fix_trunc<mode>si2_internal"
5625   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5626         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5627    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5628    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5629   "TARGET_HARD_FLOAT
5630    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5631   "#"
5632   ""
5633   [(pc)]
5635   rtx lowword;
5636   gcc_assert (MEM_P (operands[3]));
5637   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5639   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5640   emit_move_insn (operands[3], operands[2]);
5641   emit_move_insn (operands[0], lowword);
5642   DONE;
5644   [(set_attr "length" "16")
5645    (set_attr "type" "fp")])
5647 (define_expand "fix_trunc<mode>di2"
5648   [(set (match_operand:DI 0 "gpc_reg_operand")
5649         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5650   "TARGET_HARD_FLOAT && TARGET_FCFID"
5651   "")
5653 (define_insn "*fix_trunc<mode>di2_fctidz"
5654   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5655         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5656   "TARGET_HARD_FLOAT && TARGET_FCFID"
5657   "@
5658    fctidz %0,%1
5659    xscvdpsxds %x0,%x1"
5660   [(set_attr "type" "fp")])
5662 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5663 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5664 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5665 ;; values can go in VSX registers.  Keeping the direct move part through
5666 ;; register allocation prevents the register allocator from doing a direct move
5667 ;; of the SImode value to a GPR, and then a store/load.
5668 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5669   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5670         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5671    (clobber (match_scratch:SI 2 "=X,X,wi"))]
5672   "TARGET_DIRECT_MOVE"
5673   "@
5674    fctiw<u>z %0,%1
5675    xscvdp<su>xws %x0,%x1
5676    #"
5677   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5678   [(set (match_dup 2)
5679         (any_fix:SI (match_dup 1)))
5680    (set (match_dup 3)
5681         (match_dup 2))]
5683   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5685   [(set_attr "length" "4,4,8")
5686    (set_attr "type" "fp")])
5688 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5689   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5690         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5691   "TARGET_DIRECT_MOVE"
5692   "@
5693    fctiw<u>z %0,%1
5694    xscvdp<su>xws %x0,%x1"
5695   [(set_attr "type" "fp")])
5697 ;; Keep the convert and store together through register allocation to prevent
5698 ;; the register allocator from getting clever and doing a direct move to a GPR
5699 ;; and then store for reg+offset stores.
5700 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5701   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5702         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5703    (clobber (match_scratch:SI 2 "=wa"))]
5704     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5705   "#"
5706   "&& reload_completed"
5707   [(set (match_dup 2)
5708         (any_fix:SI (match_dup 1)))
5709    (set (match_dup 0)
5710         (match_dup 3))]
5712   operands[3] = (<QHSI:MODE>mode == SImode
5713                  ? operands[2]
5714                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5717 (define_expand "fixuns_trunc<mode>si2"
5718   [(set (match_operand:SI 0 "gpc_reg_operand")
5719         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5720   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5722   if (!TARGET_P8_VECTOR)
5723     {
5724       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5725       DONE;
5726     }
5729 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5730   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5731         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5732    (clobber (match_scratch:DI 2 "=d"))]
5733   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5734    && TARGET_STFIWX && can_create_pseudo_p ()
5735    && !TARGET_P8_VECTOR"
5736   "#"
5737   ""
5738   [(pc)]
5740   rtx dest = operands[0];
5741   rtx src = operands[1];
5742   rtx tmp = operands[2];
5744   if (GET_CODE (tmp) == SCRATCH)
5745     tmp = gen_reg_rtx (DImode);
5747   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5748   if (MEM_P (dest))
5749     {
5750       dest = rs6000_address_for_fpconvert (dest);
5751       emit_insn (gen_stfiwx (dest, tmp));
5752       DONE;
5753     }
5754   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5755     {
5756       dest = gen_lowpart (DImode, dest);
5757       emit_move_insn (dest, tmp);
5758       DONE;
5759     }
5760   else
5761     {
5762       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5763       emit_insn (gen_stfiwx (stack, tmp));
5764       emit_move_insn (dest, stack);
5765       DONE;
5766     }
5768   [(set_attr "length" "12")
5769    (set_attr "type" "fp")])
5771 (define_insn "fixuns_trunc<mode>di2"
5772   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5773         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5774   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5775   "@
5776    fctiduz %0,%1
5777    xscvdpuxds %x0,%x1"
5778   [(set_attr "type" "fp")])
5780 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5781 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5782 ;; because the first makes it clear that operand 0 is not live
5783 ;; before the instruction.
5784 (define_insn "fctiwz_<mode>"
5785   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5786         (unspec:DI [(fix:SI
5787                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5788                    UNSPEC_FCTIWZ))]
5789   "TARGET_HARD_FLOAT"
5790   "@
5791    fctiwz %0,%1
5792    xscvdpsxws %x0,%x1"
5793   [(set_attr "type" "fp")])
5795 (define_insn "fctiwuz_<mode>"
5796   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5797         (unspec:DI [(unsigned_fix:SI
5798                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5799                    UNSPEC_FCTIWUZ))]
5800   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5801   "@
5802    fctiwuz %0,%1
5803    xscvdpuxws %x0,%x1"
5804   [(set_attr "type" "fp")])
5806 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5807 ;; since the friz instruction does not truncate the value if the floating
5808 ;; point value is < LONG_MIN or > LONG_MAX.
5809 (define_insn "*friz"
5810   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5811         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5812   "TARGET_HARD_FLOAT && TARGET_FPRND
5813    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5814   "@
5815    friz %0,%1
5816    xsrdpiz %x0,%x1"
5817   [(set_attr "type" "fp")])
5819 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
5820 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5821 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5822 ;; extend it, store it back on the stack from the GPR, load it back into the
5823 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5824 ;; disable using store and load to sign/zero extend the value.
5825 (define_insn_and_split "*round32<mode>2_fprs"
5826   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5827         (float:SFDF
5828          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5829    (clobber (match_scratch:DI 2 "=d"))
5830    (clobber (match_scratch:DI 3 "=d"))]
5831   "TARGET_HARD_FLOAT
5832    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5833    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5834   "#"
5835   ""
5836   [(pc)]
5838   rtx dest = operands[0];
5839   rtx src = operands[1];
5840   rtx tmp1 = operands[2];
5841   rtx tmp2 = operands[3];
5842   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5844   if (GET_CODE (tmp1) == SCRATCH)
5845     tmp1 = gen_reg_rtx (DImode);
5846   if (GET_CODE (tmp2) == SCRATCH)
5847     tmp2 = gen_reg_rtx (DImode);
5849   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5850   emit_insn (gen_stfiwx (stack, tmp1));
5851   emit_insn (gen_lfiwax (tmp2, stack));
5852   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5853   DONE;
5855   [(set_attr "type" "fpload")
5856    (set_attr "length" "16")])
5858 (define_insn_and_split "*roundu32<mode>2_fprs"
5859   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5860         (unsigned_float:SFDF
5861          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5862    (clobber (match_scratch:DI 2 "=d"))
5863    (clobber (match_scratch:DI 3 "=d"))]
5864   "TARGET_HARD_FLOAT
5865    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5866    && can_create_pseudo_p ()"
5867   "#"
5868   ""
5869   [(pc)]
5871   rtx dest = operands[0];
5872   rtx src = operands[1];
5873   rtx tmp1 = operands[2];
5874   rtx tmp2 = operands[3];
5875   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5877   if (GET_CODE (tmp1) == SCRATCH)
5878     tmp1 = gen_reg_rtx (DImode);
5879   if (GET_CODE (tmp2) == SCRATCH)
5880     tmp2 = gen_reg_rtx (DImode);
5882   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5883   emit_insn (gen_stfiwx (stack, tmp1));
5884   emit_insn (gen_lfiwzx (tmp2, stack));
5885   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5886   DONE;
5888   [(set_attr "type" "fpload")
5889    (set_attr "length" "16")])
5891 ;; No VSX equivalent to fctid
5892 (define_insn "lrint<mode>di2"
5893   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5894         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5895                    UNSPEC_FCTID))]
5896   "TARGET_HARD_FLOAT && TARGET_FPRND"
5897   "fctid %0,%1"
5898   [(set_attr "type" "fp")])
5900 (define_insn "btrunc<mode>2"
5901   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5902         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5903                      UNSPEC_FRIZ))]
5904   "TARGET_HARD_FLOAT && TARGET_FPRND"
5905   "@
5906    friz %0,%1
5907    xsrdpiz %x0,%x1"
5908   [(set_attr "type" "fp")])
5910 (define_insn "ceil<mode>2"
5911   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5912         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5913                      UNSPEC_FRIP))]
5914   "TARGET_HARD_FLOAT && TARGET_FPRND"
5915   "@
5916    frip %0,%1
5917    xsrdpip %x0,%x1"
5918   [(set_attr "type" "fp")])
5920 (define_insn "floor<mode>2"
5921   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5922         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5923                      UNSPEC_FRIM))]
5924   "TARGET_HARD_FLOAT && TARGET_FPRND"
5925   "@
5926    frim %0,%1
5927    xsrdpim %x0,%x1"
5928   [(set_attr "type" "fp")])
5930 ;; No VSX equivalent to frin
5931 (define_insn "round<mode>2"
5932   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5933         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5934                      UNSPEC_FRIN))]
5935   "TARGET_HARD_FLOAT && TARGET_FPRND"
5936   "frin %0,%1"
5937   [(set_attr "type" "fp")])
5939 (define_insn "*xsrdpi<mode>2"
5940   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5941         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5942                      UNSPEC_XSRDPI))]
5943   "TARGET_HARD_FLOAT && TARGET_VSX"
5944   "xsrdpi %x0,%x1"
5945   [(set_attr "type" "fp")])
5947 (define_expand "lround<mode>di2"
5948   [(set (match_dup 2)
5949         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
5950                      UNSPEC_XSRDPI))
5951    (set (match_operand:DI 0 "gpc_reg_operand")
5952         (unspec:DI [(match_dup 2)]
5953                    UNSPEC_FCTID))]
5954   "TARGET_HARD_FLOAT && TARGET_VSX"
5956   operands[2] = gen_reg_rtx (<MODE>mode);
5959 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5960 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5961 ; is only generated for Power8 or later.
5962 (define_insn "stfiwx"
5963   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5964         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5965                    UNSPEC_STFIWX))]
5966   "TARGET_PPC_GFXOPT"
5967   "@
5968    stfiwx %1,%y0
5969    stxsiwx %x1,%y0"
5970   [(set_attr "type" "fpstore")])
5972 ;; If we don't have a direct conversion to single precision, don't enable this
5973 ;; conversion for 32-bit without fast math, because we don't have the insn to
5974 ;; generate the fixup swizzle to avoid double rounding problems.
5975 (define_expand "floatsisf2"
5976   [(set (match_operand:SF 0 "gpc_reg_operand")
5977         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5978   "TARGET_HARD_FLOAT
5979    && ((TARGET_FCFIDS && TARGET_LFIWAX)
5980        || (TARGET_FCFID
5981            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5983   if (TARGET_FCFIDS && TARGET_LFIWAX)
5984     {
5985       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5986       DONE;
5987     }
5988   else if (TARGET_FCFID && TARGET_LFIWAX)
5989     {
5990       rtx dfreg = gen_reg_rtx (DFmode);
5991       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5992       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5993       DONE;
5994     }
5995   else
5996     {
5997       rtx dreg = operands[1];
5998       if (!REG_P (dreg))
5999         dreg = force_reg (SImode, dreg);
6000       dreg = convert_to_mode (DImode, dreg, false);
6001       emit_insn (gen_floatdisf2 (operands[0], dreg));
6002       DONE;
6003     }
6006 (define_insn "floatdidf2"
6007   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6008         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6009   "TARGET_FCFID && TARGET_HARD_FLOAT"
6010   "@
6011    fcfid %0,%1
6012    xscvsxddp %x0,%x1"
6013   [(set_attr "type" "fp")])
6015 ; Allow the combiner to merge source memory operands to the conversion so that
6016 ; the optimizer/register allocator doesn't try to load the value too early in a
6017 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6018 ; hit.  We will split after reload to avoid the trip through the GPRs
6020 (define_insn_and_split "*floatdidf2_mem"
6021   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6022         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6023    (clobber (match_scratch:DI 2 "=d,wi"))]
6024   "TARGET_HARD_FLOAT && TARGET_FCFID"
6025   "#"
6026   "&& reload_completed"
6027   [(set (match_dup 2) (match_dup 1))
6028    (set (match_dup 0) (float:DF (match_dup 2)))]
6029   ""
6030   [(set_attr "length" "8")
6031    (set_attr "type" "fpload")])
6033 (define_expand "floatunsdidf2"
6034   [(set (match_operand:DF 0 "gpc_reg_operand")
6035         (unsigned_float:DF
6036          (match_operand:DI 1 "gpc_reg_operand")))]
6037   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6038   "")
6040 (define_insn "*floatunsdidf2_fcfidu"
6041   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6042         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6043   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6044   "@
6045    fcfidu %0,%1
6046    xscvuxddp %x0,%x1"
6047   [(set_attr "type" "fp")
6048    (set_attr "length" "4")])
6050 (define_insn_and_split "*floatunsdidf2_mem"
6051   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6052         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6053    (clobber (match_scratch:DI 2 "=d,wi"))]
6054   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6055   "#"
6056   "&& reload_completed"
6057   [(set (match_dup 2) (match_dup 1))
6058    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6059   ""
6060   [(set_attr "length" "8")
6061    (set_attr "type" "fpload")])
6063 (define_expand "floatdisf2"
6064   [(set (match_operand:SF 0 "gpc_reg_operand")
6065         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6066   "TARGET_FCFID && TARGET_HARD_FLOAT
6067    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6069   if (!TARGET_FCFIDS)
6070     {
6071       rtx val = operands[1];
6072       if (!flag_unsafe_math_optimizations)
6073         {
6074           rtx label = gen_label_rtx ();
6075           val = gen_reg_rtx (DImode);
6076           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6077           emit_label (label);
6078         }
6079       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6080       DONE;
6081     }
6084 (define_insn "floatdisf2_fcfids"
6085   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6086         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6087   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6088   "@
6089    fcfids %0,%1
6090    xscvsxdsp %x0,%x1"
6091   [(set_attr "type" "fp")])
6093 (define_insn_and_split "*floatdisf2_mem"
6094   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6095         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6096    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6097   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6098   "#"
6099   "&& reload_completed"
6100   [(pc)]
6102   emit_move_insn (operands[2], operands[1]);
6103   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6104   DONE;
6106   [(set_attr "length" "8")])
6108 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6109 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6110 ;; from double rounding.
6111 ;; Instead of creating a new cpu type for two FP operations, just use fp
6112 (define_insn_and_split "floatdisf2_internal1"
6113   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6114         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6115    (clobber (match_scratch:DF 2 "=d"))]
6116   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6117   "#"
6118   "&& reload_completed"
6119   [(set (match_dup 2)
6120         (float:DF (match_dup 1)))
6121    (set (match_dup 0)
6122         (float_truncate:SF (match_dup 2)))]
6123   ""
6124   [(set_attr "length" "8")
6125    (set_attr "type" "fp")])
6127 ;; Twiddles bits to avoid double rounding.
6128 ;; Bits that might be truncated when converting to DFmode are replaced
6129 ;; by a bit that won't be lost at that stage, but is below the SFmode
6130 ;; rounding position.
6131 (define_expand "floatdisf2_internal2"
6132   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6133                                               (const_int 53)))
6134               (clobber (reg:DI CA_REGNO))])
6135    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6136                                         (const_int 2047)))
6137    (set (match_dup 3) (plus:DI (match_dup 3)
6138                                (const_int 1)))
6139    (set (match_dup 0) (plus:DI (match_dup 0)
6140                                (const_int 2047)))
6141    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6142                                      (const_int 2)))
6143    (set (match_dup 0) (ior:DI (match_dup 0)
6144                               (match_dup 1)))
6145    (set (match_dup 0) (and:DI (match_dup 0)
6146                               (const_int -2048)))
6147    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6148                            (label_ref (match_operand:DI 2 ""))
6149                            (pc)))
6150    (set (match_dup 0) (match_dup 1))]
6151   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6153   operands[3] = gen_reg_rtx (DImode);
6154   operands[4] = gen_reg_rtx (CCUNSmode);
6157 (define_expand "floatunsdisf2"
6158   [(set (match_operand:SF 0 "gpc_reg_operand")
6159         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6160   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6161   "")
6163 (define_insn "floatunsdisf2_fcfidus"
6164   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6165         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6166   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6167   "@
6168    fcfidus %0,%1
6169    xscvuxdsp %x0,%x1"
6170   [(set_attr "type" "fp")])
6172 (define_insn_and_split "*floatunsdisf2_mem"
6173   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6174         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6175    (clobber (match_scratch:DI 2 "=d,d,wi"))]
6176   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6177   "#"
6178   "&& reload_completed"
6179   [(pc)]
6181   emit_move_insn (operands[2], operands[1]);
6182   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6183   DONE;
6185   [(set_attr "length" "8")
6186    (set_attr "type" "fpload")])
6188 ;; Define the TImode operations that can be done in a small number
6189 ;; of instructions.  The & constraints are to prevent the register
6190 ;; allocator from allocating registers that overlap with the inputs
6191 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6192 ;; also allow for the output being the same as one of the inputs.
6194 (define_expand "addti3"
6195   [(set (match_operand:TI 0 "gpc_reg_operand")
6196         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6197                  (match_operand:TI 2 "reg_or_short_operand")))]
6198   "TARGET_64BIT"
6200   rtx lo0 = gen_lowpart (DImode, operands[0]);
6201   rtx lo1 = gen_lowpart (DImode, operands[1]);
6202   rtx lo2 = gen_lowpart (DImode, operands[2]);
6203   rtx hi0 = gen_highpart (DImode, operands[0]);
6204   rtx hi1 = gen_highpart (DImode, operands[1]);
6205   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6207   if (!reg_or_short_operand (lo2, DImode))
6208     lo2 = force_reg (DImode, lo2);
6209   if (!adde_operand (hi2, DImode))
6210     hi2 = force_reg (DImode, hi2);
6212   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6213   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6214   DONE;
6217 (define_expand "subti3"
6218   [(set (match_operand:TI 0 "gpc_reg_operand")
6219         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6220                   (match_operand:TI 2 "gpc_reg_operand")))]
6221   "TARGET_64BIT"
6223   rtx lo0 = gen_lowpart (DImode, operands[0]);
6224   rtx lo1 = gen_lowpart (DImode, operands[1]);
6225   rtx lo2 = gen_lowpart (DImode, operands[2]);
6226   rtx hi0 = gen_highpart (DImode, operands[0]);
6227   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6228   rtx hi2 = gen_highpart (DImode, operands[2]);
6230   if (!reg_or_short_operand (lo1, DImode))
6231     lo1 = force_reg (DImode, lo1);
6232   if (!adde_operand (hi1, DImode))
6233     hi1 = force_reg (DImode, hi1);
6235   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6236   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6237   DONE;
6240 ;; 128-bit logical operations expanders
6242 (define_expand "and<mode>3"
6243   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6244         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6245                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6246   ""
6247   "")
6249 (define_expand "ior<mode>3"
6250   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6251         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6252                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6253   ""
6254   "")
6256 (define_expand "xor<mode>3"
6257   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6258         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6259                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6260   ""
6261   "")
6263 (define_expand "one_cmpl<mode>2"
6264   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6265         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6266   ""
6267   "")
6269 (define_expand "nor<mode>3"
6270   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6271         (and:BOOL_128
6272          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6273          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6274   ""
6275   "")
6277 (define_expand "andc<mode>3"
6278   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6279         (and:BOOL_128
6280          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6281          (match_operand:BOOL_128 1 "vlogical_operand")))]
6282   ""
6283   "")
6285 ;; Power8 vector logical instructions.
6286 (define_expand "eqv<mode>3"
6287   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6288         (not:BOOL_128
6289          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6290                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6291   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6292   "")
6294 ;; Rewrite nand into canonical form
6295 (define_expand "nand<mode>3"
6296   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6297         (ior:BOOL_128
6298          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6299          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6300   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6301   "")
6303 ;; The canonical form is to have the negated element first, so we need to
6304 ;; reverse arguments.
6305 (define_expand "orc<mode>3"
6306   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6307         (ior:BOOL_128
6308          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6309          (match_operand:BOOL_128 1 "vlogical_operand")))]
6310   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6311   "")
6313 ;; 128-bit logical operations insns and split operations
6314 (define_insn_and_split "*and<mode>3_internal"
6315   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6316         (and:BOOL_128
6317          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6318          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6319   ""
6321   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6322     return "xxland %x0,%x1,%x2";
6324   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6325     return "vand %0,%1,%2";
6327   return "#";
6329   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6330   [(const_int 0)]
6332   rs6000_split_logical (operands, AND, false, false, false);
6333   DONE;
6335   [(set (attr "type")
6336       (if_then_else
6337         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6338         (const_string "veclogical")
6339         (const_string "integer")))
6340    (set (attr "length")
6341       (if_then_else
6342         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6343         (const_string "4")
6344         (if_then_else
6345          (match_test "TARGET_POWERPC64")
6346          (const_string "8")
6347          (const_string "16"))))])
6349 ;; 128-bit IOR/XOR
6350 (define_insn_and_split "*bool<mode>3_internal"
6351   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6352         (match_operator:BOOL_128 3 "boolean_or_operator"
6353          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6354           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6355   ""
6357   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6358     return "xxl%q3 %x0,%x1,%x2";
6360   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6361     return "v%q3 %0,%1,%2";
6363   return "#";
6365   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6366   [(const_int 0)]
6368   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6369   DONE;
6371   [(set (attr "type")
6372       (if_then_else
6373         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6374         (const_string "veclogical")
6375         (const_string "integer")))
6376    (set (attr "length")
6377       (if_then_else
6378         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6379         (const_string "4")
6380         (if_then_else
6381          (match_test "TARGET_POWERPC64")
6382          (const_string "8")
6383          (const_string "16"))))])
6385 ;; 128-bit ANDC/ORC
6386 (define_insn_and_split "*boolc<mode>3_internal1"
6387   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6388         (match_operator:BOOL_128 3 "boolean_operator"
6389          [(not:BOOL_128
6390            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6391           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6392   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6394   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6395     return "xxl%q3 %x0,%x1,%x2";
6397   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6398     return "v%q3 %0,%1,%2";
6400   return "#";
6402   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6403    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6404   [(const_int 0)]
6406   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6407   DONE;
6409   [(set (attr "type")
6410       (if_then_else
6411         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6412         (const_string "veclogical")
6413         (const_string "integer")))
6414    (set (attr "length")
6415       (if_then_else
6416         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6417         (const_string "4")
6418         (if_then_else
6419          (match_test "TARGET_POWERPC64")
6420          (const_string "8")
6421          (const_string "16"))))])
6423 (define_insn_and_split "*boolc<mode>3_internal2"
6424   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6425         (match_operator:TI2 3 "boolean_operator"
6426          [(not:TI2
6427            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6428           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6429   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6430   "#"
6431   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6432   [(const_int 0)]
6434   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6435   DONE;
6437   [(set_attr "type" "integer")
6438    (set (attr "length")
6439         (if_then_else
6440          (match_test "TARGET_POWERPC64")
6441          (const_string "8")
6442          (const_string "16")))])
6444 ;; 128-bit NAND/NOR
6445 (define_insn_and_split "*boolcc<mode>3_internal1"
6446   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6447         (match_operator:BOOL_128 3 "boolean_operator"
6448          [(not:BOOL_128
6449            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6450           (not:BOOL_128
6451            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6452   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6454   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6455     return "xxl%q3 %x0,%x1,%x2";
6457   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6458     return "v%q3 %0,%1,%2";
6460   return "#";
6462   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6463    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6464   [(const_int 0)]
6466   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6467   DONE;
6469   [(set (attr "type")
6470       (if_then_else
6471         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6472         (const_string "veclogical")
6473         (const_string "integer")))
6474    (set (attr "length")
6475       (if_then_else
6476         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6477         (const_string "4")
6478         (if_then_else
6479          (match_test "TARGET_POWERPC64")
6480          (const_string "8")
6481          (const_string "16"))))])
6483 (define_insn_and_split "*boolcc<mode>3_internal2"
6484   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6485         (match_operator:TI2 3 "boolean_operator"
6486          [(not:TI2
6487            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6488           (not:TI2
6489            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6490   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6491   "#"
6492   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6493   [(const_int 0)]
6495   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6496   DONE;
6498   [(set_attr "type" "integer")
6499    (set (attr "length")
6500         (if_then_else
6501          (match_test "TARGET_POWERPC64")
6502          (const_string "8")
6503          (const_string "16")))])
6506 ;; 128-bit EQV
6507 (define_insn_and_split "*eqv<mode>3_internal1"
6508   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6509         (not:BOOL_128
6510          (xor:BOOL_128
6511           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6512           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6513   "TARGET_P8_VECTOR"
6515   if (vsx_register_operand (operands[0], <MODE>mode))
6516     return "xxleqv %x0,%x1,%x2";
6518   return "#";
6520   "TARGET_P8_VECTOR && reload_completed
6521    && int_reg_operand (operands[0], <MODE>mode)"
6522   [(const_int 0)]
6524   rs6000_split_logical (operands, XOR, true, false, false);
6525   DONE;
6527   [(set (attr "type")
6528       (if_then_else
6529         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6530         (const_string "veclogical")
6531         (const_string "integer")))
6532    (set (attr "length")
6533       (if_then_else
6534         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6535         (const_string "4")
6536         (if_then_else
6537          (match_test "TARGET_POWERPC64")
6538          (const_string "8")
6539          (const_string "16"))))])
6541 (define_insn_and_split "*eqv<mode>3_internal2"
6542   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6543         (not:TI2
6544          (xor:TI2
6545           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6546           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6547   "!TARGET_P8_VECTOR"
6548   "#"
6549   "reload_completed && !TARGET_P8_VECTOR"
6550   [(const_int 0)]
6552   rs6000_split_logical (operands, XOR, true, false, false);
6553   DONE;
6555   [(set_attr "type" "integer")
6556    (set (attr "length")
6557         (if_then_else
6558          (match_test "TARGET_POWERPC64")
6559          (const_string "8")
6560          (const_string "16")))])
6562 ;; 128-bit one's complement
6563 (define_insn_and_split "*one_cmpl<mode>3_internal"
6564   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6565         (not:BOOL_128
6566           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6567   ""
6569   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6570     return "xxlnor %x0,%x1,%x1";
6572   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6573     return "vnor %0,%1,%1";
6575   return "#";
6577   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6578   [(const_int 0)]
6580   rs6000_split_logical (operands, NOT, false, false, false);
6581   DONE;
6583   [(set (attr "type")
6584       (if_then_else
6585         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6586         (const_string "veclogical")
6587         (const_string "integer")))
6588    (set (attr "length")
6589       (if_then_else
6590         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6591         (const_string "4")
6592         (if_then_else
6593          (match_test "TARGET_POWERPC64")
6594          (const_string "8")
6595          (const_string "16"))))])
6598 ;; Now define ways of moving data around.
6600 ;; Set up a register with a value from the GOT table
6602 (define_expand "movsi_got"
6603   [(set (match_operand:SI 0 "gpc_reg_operand")
6604         (unspec:SI [(match_operand:SI 1 "got_operand")
6605                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6606   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6608   if (GET_CODE (operands[1]) == CONST)
6609     {
6610       rtx offset = const0_rtx;
6611       HOST_WIDE_INT value;
6613       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6614       value = INTVAL (offset);
6615       if (value != 0)
6616         {
6617           rtx tmp = (!can_create_pseudo_p ()
6618                      ? operands[0]
6619                      : gen_reg_rtx (Pmode));
6620           emit_insn (gen_movsi_got (tmp, operands[1]));
6621           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6622           DONE;
6623         }
6624     }
6626   operands[2] = rs6000_got_register (operands[1]);
6629 (define_insn "*movsi_got_internal"
6630   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6631         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6632                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6633                    UNSPEC_MOVSI_GOT))]
6634   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6635   "lwz %0,%a1@got(%2)"
6636   [(set_attr "type" "load")])
6638 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6639 ;; didn't get allocated to a hard register.
6640 (define_split
6641   [(set (match_operand:SI 0 "gpc_reg_operand")
6642         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6643                     (match_operand:SI 2 "memory_operand")]
6644                    UNSPEC_MOVSI_GOT))]
6645   "DEFAULT_ABI == ABI_V4
6646     && flag_pic == 1
6647     && reload_completed"
6648   [(set (match_dup 0) (match_dup 2))
6649    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6650                                  UNSPEC_MOVSI_GOT))]
6651   "")
6653 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6654 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6655 ;; and this is even supposed to be faster, but it is simpler not to get
6656 ;; integers in the TOC.
6657 (define_insn "movsi_low"
6658   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6659         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6660                            (match_operand 2 "" ""))))]
6661   "TARGET_MACHO && ! TARGET_64BIT"
6662   "lwz %0,lo16(%2)(%1)"
6663   [(set_attr "type" "load")
6664    (set_attr "length" "4")])
6666 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6667 ;;              STW          STFIWX       STXSIWX      LI           LIS
6668 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6669 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6670 ;;              MF%1         MT%0         MT%0         NOP
6671 (define_insn "*movsi_internal1"
6672   [(set (match_operand:SI 0 "nonimmediate_operand"
6673                 "=r,         r,           r,           ?*wI,        ?*wH,
6674                  m,          ?Z,          ?Z,          r,           r,
6675                  r,          ?*wIwH,      ?*wJwK,      ?*wJwK,      ?*wu,
6676                  ?*wJwK,     ?*wH,        ?*wK,        ?*wIwH,      ?r,
6677                  r,          *c*l,        *h,          *h")
6679         (match_operand:SI 1 "input_operand"
6680                 "r,          U,           m,           Z,           Z,
6681                  r,          wI,          wH,          I,           L,
6682                  n,          wIwH,        O,           wM,          wB,
6683                  O,          wM,          wS,          r,           wIwH,
6684                  *h,         r,           r,           0"))]
6686   "gpc_reg_operand (operands[0], SImode)
6687    || gpc_reg_operand (operands[1], SImode)"
6688   "@
6689    mr %0,%1
6690    la %0,%a1
6691    lwz%U1%X1 %0,%1
6692    lfiwzx %0,%y1
6693    lxsiwzx %x0,%y1
6694    stw%U0%X0 %1,%0
6695    stfiwx %1,%y0
6696    stxsiwx %x1,%y0
6697    li %0,%1
6698    lis %0,%v1
6699    #
6700    xxlor %x0,%x1,%x1
6701    xxspltib %x0,0
6702    xxspltib %x0,255
6703    vspltisw %0,%1
6704    xxlxor %x0,%x0,%x0
6705    xxlorc %x0,%x0,%x0
6706    #
6707    mtvsrwz %x0,%1
6708    mfvsrwz %0,%x1
6709    mf%1 %0
6710    mt%0 %1
6711    mt%0 %1
6712    nop"
6713   [(set_attr "type"
6714                 "*,          *,           load,        fpload,      fpload,
6715                  store,      fpstore,     fpstore,     *,           *,
6716                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6717                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6718                  *,           *,           *,           *")
6720    (set_attr "length"
6721                 "4,          4,           4,           4,           4,
6722                  4,          4,           4,           4,           4,
6723                  8,          4,           4,           4,           4,
6724                  4,          4,           8,           4,           4,
6725                  4,          4,           4,           4")])
6727 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6728 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6730 ;; Because SF values are actually stored as DF values within the vector
6731 ;; registers, we need to convert the value to the vector SF format when
6732 ;; we need to use the bits in a union or similar cases.  We only need
6733 ;; to do this transformation when the value is a vector register.  Loads,
6734 ;; stores, and transfers within GPRs are assumed to be safe.
6736 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6737 ;; no alternatives, because the call is created as part of secondary_reload,
6738 ;; and operand #2's register class is used to allocate the temporary register.
6739 ;; This function is called before reload, and it creates the temporary as
6740 ;; needed.
6742 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6743 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6744 ;;              MTVSRWZ
6746 (define_insn_and_split "movsi_from_sf"
6747   [(set (match_operand:SI 0 "nonimmediate_operand"
6748                 "=r,         r,           ?*wI,        ?*wH,     m,
6749                  m,          wY,          Z,           r,        ?*wIwH,
6750                  wIwH")
6752         (unspec:SI [(match_operand:SF 1 "input_operand"
6753                 "r,          m,           Z,           Z,        r,
6754                  f,          wb,          wu,          wIwH,     wIwH,
6755                  r")]
6756                     UNSPEC_SI_FROM_SF))
6758    (clobber (match_scratch:V4SF 2
6759                 "=X,         X,           X,           X,        X,
6760                  X,          X,           X,           wIwH,     X,
6761                  X"))]
6763   "TARGET_NO_SF_SUBREG
6764    && (register_operand (operands[0], SImode)
6765        || register_operand (operands[1], SFmode))"
6766   "@
6767    mr %0,%1
6768    lwz%U1%X1 %0,%1
6769    lfiwzx %0,%y1
6770    lxsiwzx %x0,%y1
6771    stw%U0%X0 %1,%0
6772    stfs%U0%X0 %1,%0
6773    stxssp %1,%0
6774    stxsspx %x1,%y0
6775    #
6776    xscvdpspn %x0,%x1
6777    mtvsrwz %x0,%1"
6778   "&& reload_completed
6779    && int_reg_operand (operands[0], SImode)
6780    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6781   [(const_int 0)]
6783   rtx op0 = operands[0];
6784   rtx op1 = operands[1];
6785   rtx op2 = operands[2];
6786   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6787   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6789   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6790   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6791   DONE;
6793   [(set_attr "type"
6794                 "*,          load,        fpload,      fpload,   store,
6795                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
6796                  mffgpr")
6798    (set_attr "length"
6799                 "4,          4,           4,           4,        4,
6800                  4,          4,           4,           8,        4,
6801                  4")])
6803 ;; movsi_from_sf with zero extension
6805 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
6806 ;;              VSX->VSX     MTVSRWZ
6808 (define_insn_and_split "*movdi_from_sf_zero_ext"
6809   [(set (match_operand:DI 0 "gpc_reg_operand"
6810                 "=r,         r,           ?*wI,        ?*wH,     r,
6811                  ?wK,        wIwH")
6813         (zero_extend:DI
6814          (unspec:SI [(match_operand:SF 1 "input_operand"
6815                 "r,          m,           Z,           Z,        wIwH,
6816                  wIwH,       r")]
6817                     UNSPEC_SI_FROM_SF)))
6819    (clobber (match_scratch:V4SF 2
6820                 "=X,         X,           X,           X,        wa,
6821                  wIwH,       X"))]
6823   "TARGET_DIRECT_MOVE_64BIT
6824    && (register_operand (operands[0], DImode)
6825        || register_operand (operands[1], SImode))"
6826   "@
6827    rldicl %0,%1,0,32
6828    lwz%U1%X1 %0,%1
6829    lfiwzx %0,%y1
6830    lxsiwzx %x0,%y1
6831    #
6832    #
6833    mtvsrwz %x0,%1"
6834   "&& reload_completed
6835    && register_operand (operands[0], DImode)
6836    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6837   [(const_int 0)]
6839   rtx op0 = operands[0];
6840   rtx op1 = operands[1];
6841   rtx op2 = operands[2];
6842   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6844   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6845   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6846   DONE;
6848   [(set_attr "type"
6849                 "*,          load,        fpload,      fpload,   two,
6850                  two,        mffgpr")
6852    (set_attr "length"
6853                 "4,          4,           4,           4,        8,
6854                  8,          4")])
6856 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6857 ;; moving it to SImode.  We can do a SFmode store without having to do the
6858 ;; conversion explicitly.  If we are doing a register->register conversion, use
6859 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6860 ;; input will not fit in a SFmode, and the later assumes the value has already
6861 ;; been rounded.
6862 (define_insn "*movsi_from_df"
6863   [(set (match_operand:SI 0 "nonimmediate_operand"         "=wa,m,wY,Z")
6864         (unspec:SI [(float_truncate:SF
6865                      (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6866                     UNSPEC_SI_FROM_SF))]
6868   "TARGET_NO_SF_SUBREG"
6869   "@
6870    xscvdpsp %x0,%x1
6871    stfs%U0%X0 %1,%0
6872    stxssp %1,%0
6873    stxsspx %x1,%y0"
6874   [(set_attr "type"   "fp,fpstore,fpstore,fpstore")])
6876 ;; Split a load of a large constant into the appropriate two-insn
6877 ;; sequence.
6879 (define_split
6880   [(set (match_operand:SI 0 "gpc_reg_operand")
6881         (match_operand:SI 1 "const_int_operand"))]
6882   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6883    && (INTVAL (operands[1]) & 0xffff) != 0"
6884   [(set (match_dup 0)
6885         (match_dup 2))
6886    (set (match_dup 0)
6887         (ior:SI (match_dup 0)
6888                 (match_dup 3)))]
6890   if (rs6000_emit_set_const (operands[0], operands[1]))
6891     DONE;
6892   else
6893     FAIL;
6896 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6897 (define_split
6898   [(set (match_operand:DI 0 "altivec_register_operand")
6899         (match_operand:DI 1 "xxspltib_constant_split"))]
6900   "TARGET_P9_VECTOR && reload_completed"
6901   [(const_int 0)]
6903   rtx op0 = operands[0];
6904   rtx op1 = operands[1];
6905   int r = REGNO (op0);
6906   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6908   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6909   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6910   DONE;
6913 (define_insn "*mov<mode>_internal2"
6914   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6915         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6916                     (const_int 0)))
6917    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6918   ""
6919   "@
6920    cmp<wd>i %2,%0,0
6921    mr. %0,%1
6922    #"
6923   [(set_attr "type" "cmp,logical,cmp")
6924    (set_attr "dot" "yes")
6925    (set_attr "length" "4,4,8")])
6927 (define_split
6928   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6929         (compare:CC (match_operand:P 1 "gpc_reg_operand")
6930                     (const_int 0)))
6931    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6932   "reload_completed"
6933   [(set (match_dup 0) (match_dup 1))
6934    (set (match_dup 2)
6935         (compare:CC (match_dup 0)
6936                     (const_int 0)))]
6937   "")
6939 (define_expand "mov<mode>"
6940   [(set (match_operand:INT 0 "general_operand")
6941         (match_operand:INT 1 "any_operand"))]
6942   ""
6944   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
6945   DONE;
6948 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
6949 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
6950 ;;              MTVSRWZ     MF%1       MT%1       NOP
6951 (define_insn "*mov<mode>_internal"
6952   [(set (match_operand:QHI 0 "nonimmediate_operand"
6953                 "=r,        r,         ?*wJwK,    m,         Z,         r,
6954                  ?*wJwK,    ?*wJwK,    ?*wJwK,    ?*wK,      ?*wK,      r,
6955                  ?*wJwK,    r,         *c*l,      *h")
6957         (match_operand:QHI 1 "input_operand"
6958                 "r,         m,         Z,         r,         wJwK,      i,
6959                  wJwK,      O,         wM,        wB,        wS,        ?*wJwK,
6960                  r,         *h,        r,         0"))]
6962   "gpc_reg_operand (operands[0], <MODE>mode)
6963    || gpc_reg_operand (operands[1], <MODE>mode)"
6964   "@
6965    mr %0,%1
6966    l<wd>z%U1%X1 %0,%1
6967    lxsi<wd>zx %x0,%y1
6968    st<wd>%U0%X0 %1,%0
6969    stxsi<wd>x %x1,%y0
6970    li %0,%1
6971    xxlor %x0,%x1,%x1
6972    xxspltib %x0,0
6973    xxspltib %x0,255
6974    vspltis<wd> %0,%1
6975    #
6976    mfvsrwz %0,%x1
6977    mtvsrwz %x0,%1
6978    mf%1 %0
6979    mt%0 %1
6980    nop"
6981   [(set_attr "type"
6982                 "*,         load,      fpload,    store,     fpstore,   *,
6983                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
6984                  mffgpr,    mfjmpr,    mtjmpr,    *")
6986    (set_attr "length"
6987                 "4,         4,         4,         4,         4,         4,
6988                  4,         4,         4,         4,         8,         4,
6989                  4,         4,         4,         4")])
6992 ;; Here is how to move condition codes around.  When we store CC data in
6993 ;; an integer register or memory, we store just the high-order 4 bits.
6994 ;; This lets us not shift in the most common case of CR0.
6995 (define_expand "movcc"
6996   [(set (match_operand:CC 0 "nonimmediate_operand")
6997         (match_operand:CC 1 "nonimmediate_operand"))]
6998   ""
6999   "")
7001 (define_insn "*movcc_internal1"
7002   [(set (match_operand:CC 0 "nonimmediate_operand"
7003                             "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7004         (match_operand:CC 1 "general_operand"
7005                             " y,r, r,O,x,y,r,I,h,   r,m,r"))]
7006   "register_operand (operands[0], CCmode)
7007    || register_operand (operands[1], CCmode)"
7008   "@
7009    mcrf %0,%1
7010    mtcrf 128,%1
7011    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7012    crxor %0,%0,%0
7013    mfcr %0%Q1
7014    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7015    mr %0,%1
7016    li %0,%1
7017    mf%1 %0
7018    mt%0 %1
7019    lwz%U1%X1 %0,%1
7020    stw%U0%X0 %1,%0"
7021   [(set (attr "type")
7022      (cond [(eq_attr "alternative" "0,3")
7023                 (const_string "cr_logical")
7024             (eq_attr "alternative" "1,2")
7025                 (const_string "mtcr")
7026             (eq_attr "alternative" "6,7")
7027                 (const_string "integer")
7028             (eq_attr "alternative" "8")
7029                 (const_string "mfjmpr")
7030             (eq_attr "alternative" "9")
7031                 (const_string "mtjmpr")
7032             (eq_attr "alternative" "10")
7033                 (const_string "load")
7034             (eq_attr "alternative" "11")
7035                 (const_string "store")
7036             (match_test "TARGET_MFCRF")
7037                 (const_string "mfcrf")
7038            ]
7039         (const_string "mfcr")))
7040    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7042 ;; For floating-point, we normally deal with the floating-point registers
7043 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7044 ;; can produce floating-point values in fixed-point registers.  Unless the
7045 ;; value is a simple constant or already in memory, we deal with this by
7046 ;; allocating memory and copying the value explicitly via that memory location.
7048 ;; Move 32-bit binary/decimal floating point
7049 (define_expand "mov<mode>"
7050   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7051         (match_operand:FMOVE32 1 "any_operand"))]
7052   "<fmove_ok>"
7054   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7055   DONE;
7058 (define_split
7059   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7060         (match_operand:FMOVE32 1 "const_double_operand"))]
7061   "reload_completed
7062    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7063        || (GET_CODE (operands[0]) == SUBREG
7064            && GET_CODE (SUBREG_REG (operands[0])) == REG
7065            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7066   [(set (match_dup 2) (match_dup 3))]
7068   long l;
7070   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7072   if (! TARGET_POWERPC64)
7073     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7074   else
7075     operands[2] = gen_lowpart (SImode, operands[0]);
7077   operands[3] = gen_int_mode (l, SImode);
7080 ;; Originally, we tried to keep movsf and movsd common, but the differences
7081 ;; addressing was making it rather difficult to hide with mode attributes.  In
7082 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7083 ;; before the VSX stores meant that the register allocator would tend to do a
7084 ;; direct move to the GPR (which involves conversion from scalar to
7085 ;; vector/memory formats) to save values in the traditional Altivec registers,
7086 ;; while SDmode had problems on power6 if the GPR store was not first due to
7087 ;; the power6 not having an integer store operation.
7089 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7090 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7091 ;;      MR           MT<x>      MF<x>       NOP
7093 (define_insn "movsf_hardfloat"
7094   [(set (match_operand:SF 0 "nonimmediate_operand"
7095          "=!r,       f,         wb,         wu,        m,         wY,
7096           Z,         m,         ww,         !r,        f,         ww,
7097           !r,        *c*l,      !r,         *h")
7098         (match_operand:SF 1 "input_operand"
7099          "m,         m,         wY,         Z,         f,         wb,
7100           wu,        r,         j,          j,         f,         ww,
7101           r,         r,         *h,         0"))]
7102   "(register_operand (operands[0], SFmode)
7103    || register_operand (operands[1], SFmode))
7104    && TARGET_HARD_FLOAT
7105    && (TARGET_ALLOW_SF_SUBREG
7106        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7107   "@
7108    lwz%U1%X1 %0,%1
7109    lfs%U1%X1 %0,%1
7110    lxssp %0,%1
7111    lxsspx %x0,%y1
7112    stfs%U0%X0 %1,%0
7113    stxssp %1,%0
7114    stxsspx %x1,%y0
7115    stw%U0%X0 %1,%0
7116    xxlxor %x0,%x0,%x0
7117    li %0,0
7118    fmr %0,%1
7119    xscpsgndp %x0,%x1,%x1
7120    mr %0,%1
7121    mt%0 %1
7122    mf%1 %0
7123    nop"
7124   [(set_attr "type"
7125         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7126          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7127          *,          mtjmpr,    mfjmpr,     *")])
7129 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7130 ;;      FMR          MR         MT%0       MF%1       NOP
7131 (define_insn "movsd_hardfloat"
7132   [(set (match_operand:SD 0 "nonimmediate_operand"
7133          "=!r,       wz,        m,         Z,         ?wh,       ?r,
7134           f,         !r,        *c*l,      !r,        *h")
7135         (match_operand:SD 1 "input_operand"
7136          "m,         Z,         r,         wx,        r,         wh,
7137           f,         r,         r,         *h,        0"))]
7138   "(register_operand (operands[0], SDmode)
7139    || register_operand (operands[1], SDmode))
7140    && TARGET_HARD_FLOAT"
7141   "@
7142    lwz%U1%X1 %0,%1
7143    lfiwzx %0,%y1
7144    stw%U0%X0 %1,%0
7145    stfiwx %1,%y0
7146    mtvsrwz %x0,%1
7147    mfvsrwz %0,%x1
7148    fmr %0,%1
7149    mr %0,%1
7150    mt%0 %1
7151    mf%1 %0
7152    nop"
7153   [(set_attr "type"
7154         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7155          fpsimple,   *,         mtjmpr,    mfjmpr,    *")])
7157 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7158 ;;      LIS          G-const.   F/n-const  NOP
7159 (define_insn "*mov<mode>_softfloat"
7160   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7161         "=r,         cl,        r,         r,         m,         r,
7162           r,         r,         r,         *h")
7164         (match_operand:FMOVE32 1 "input_operand"
7165          "r,         r,         h,         m,         r,         I,
7166           L,         G,         Fn,        0"))]
7168   "(gpc_reg_operand (operands[0], <MODE>mode)
7169    || gpc_reg_operand (operands[1], <MODE>mode))
7170    && TARGET_SOFT_FLOAT"
7171   "@
7172    mr %0,%1
7173    mt%0 %1
7174    mf%1 %0
7175    lwz%U1%X1 %0,%1
7176    stw%U0%X0 %1,%0
7177    li %0,%1
7178    lis %0,%v1
7179    #
7180    #
7181    nop"
7182   [(set_attr "type"
7183         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7184          *,          *,         *,         *")
7186    (set_attr "length"
7187         "4,          4,         4,         4,         4,         4,
7188          4,          4,         8,         4")])
7190 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7191 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7193 ;; Because SF values are actually stored as DF values within the vector
7194 ;; registers, we need to convert the value to the vector SF format when
7195 ;; we need to use the bits in a union or similar cases.  We only need
7196 ;; to do this transformation when the value is a vector register.  Loads,
7197 ;; stores, and transfers within GPRs are assumed to be safe.
7199 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7200 ;; no alternatives, because the call is created as part of secondary_reload,
7201 ;; and operand #2's register class is used to allocate the temporary register.
7202 ;; This function is called before reload, and it creates the temporary as
7203 ;; needed.
7205 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7206 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7207 (define_insn_and_split "movsf_from_si"
7208   [(set (match_operand:SF 0 "nonimmediate_operand"
7209             "=!r,       f,         wb,        wu,        m,         Z,
7210              Z,         wy,        ?r,        !r")
7212         (unspec:SF [(match_operand:SI 1 "input_operand" 
7213             "m,         m,         wY,        Z,         r,         f,
7214              wu,        r,         wy,        r")]
7215                    UNSPEC_SF_FROM_SI))
7217    (clobber (match_scratch:DI 2
7218             "=X,        X,         X,         X,         X,         X,
7219              X,         r,         X,         X"))]
7221   "TARGET_NO_SF_SUBREG
7222    && (register_operand (operands[0], SFmode)
7223        || register_operand (operands[1], SImode))"
7224   "@
7225    lwz%U1%X1 %0,%1
7226    lfs%U1%X1 %0,%1
7227    lxssp %0,%1
7228    lxsspx %x0,%y1
7229    stw%U0%X0 %1,%0
7230    stfiwx %1,%y0
7231    stxsiwx %x1,%y0
7232    #
7233    mfvsrwz %0,%x1
7234    mr %0,%1"
7236   "&& reload_completed
7237    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7238    && int_reg_operand_not_pseudo (operands[1], SImode)"
7239   [(const_int 0)]
7241   rtx op0 = operands[0];
7242   rtx op1 = operands[1];
7243   rtx op2 = operands[2];
7244   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7246   /* Move SF value to upper 32-bits for xscvspdpn.  */
7247   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7248   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7249   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7250   DONE;
7252   [(set_attr "length"
7253             "4,          4,         4,         4,         4,         4,
7254              4,          12,        4,         4")
7255    (set_attr "type"
7256             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7257              fpstore,    vecfloat,  mffgpr,    *")])
7260 ;; Move 64-bit binary/decimal floating point
7261 (define_expand "mov<mode>"
7262   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7263         (match_operand:FMOVE64 1 "any_operand"))]
7264   ""
7266   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7267   DONE;
7270 (define_split
7271   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7272         (match_operand:FMOVE64 1 "const_int_operand"))]
7273   "! TARGET_POWERPC64 && reload_completed
7274    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7275        || (GET_CODE (operands[0]) == SUBREG
7276            && GET_CODE (SUBREG_REG (operands[0])) == REG
7277            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7278   [(set (match_dup 2) (match_dup 4))
7279    (set (match_dup 3) (match_dup 1))]
7281   int endian = (WORDS_BIG_ENDIAN == 0);
7282   HOST_WIDE_INT value = INTVAL (operands[1]);
7284   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7285   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7286   operands[4] = GEN_INT (value >> 32);
7287   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7290 (define_split
7291   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7292         (match_operand:FMOVE64 1 "const_double_operand"))]
7293   "! TARGET_POWERPC64 && reload_completed
7294    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7295        || (GET_CODE (operands[0]) == SUBREG
7296            && GET_CODE (SUBREG_REG (operands[0])) == REG
7297            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7298   [(set (match_dup 2) (match_dup 4))
7299    (set (match_dup 3) (match_dup 5))]
7301   int endian = (WORDS_BIG_ENDIAN == 0);
7302   long l[2];
7304   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7306   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7307   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7308   operands[4] = gen_int_mode (l[endian], SImode);
7309   operands[5] = gen_int_mode (l[1 - endian], SImode);
7312 (define_split
7313   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7314         (match_operand:FMOVE64 1 "const_double_operand"))]
7315   "TARGET_POWERPC64 && reload_completed
7316    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7317        || (GET_CODE (operands[0]) == SUBREG
7318            && GET_CODE (SUBREG_REG (operands[0])) == REG
7319            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7320   [(set (match_dup 2) (match_dup 3))]
7322   int endian = (WORDS_BIG_ENDIAN == 0);
7323   long l[2];
7324   HOST_WIDE_INT val;
7326   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7328   operands[2] = gen_lowpart (DImode, operands[0]);
7329   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7330   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7331          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7333   operands[3] = gen_int_mode (val, DImode);
7336 ;; Don't have reload use general registers to load a constant.  It is
7337 ;; less efficient than loading the constant into an FP register, since
7338 ;; it will probably be used there.
7340 ;; The move constraints are ordered to prefer floating point registers before
7341 ;; general purpose registers to avoid doing a store and a load to get the value
7342 ;; into a floating point register when it is needed for a floating point
7343 ;; operation.  Prefer traditional floating point registers over VSX registers,
7344 ;; since the D-form version of the memory instructions does not need a GPR for
7345 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7346 ;; registers.
7348 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7349 ;; except for 0.0 which can be created on VSX with an xor instruction.
7351 ;;           STFD         LFD         FMR         LXSD        STXSD
7352 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7353 ;;           LWZ          STW         MR
7356 (define_insn "*mov<mode>_hardfloat32"
7357   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7358             "=m,          d,          d,          <f64_p9>,   wY,
7359               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7360               Y,          r,          !r")
7362         (match_operand:FMOVE64 1 "input_operand"
7363              "d,          m,          d,          wY,         <f64_p9>,
7364               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7365               r,          Y,          r"))]
7367   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7368    && (gpc_reg_operand (operands[0], <MODE>mode)
7369        || gpc_reg_operand (operands[1], <MODE>mode))"
7370   "@
7371    stfd%U0%X0 %1,%0
7372    lfd%U1%X1 %0,%1
7373    fmr %0,%1
7374    lxsd %0,%1
7375    stxsd %1,%0
7376    lxsd%U1x %x0,%y1
7377    stxsd%U0x %x1,%y0
7378    xxlor %x0,%x1,%x1
7379    xxlxor %x0,%x0,%x0
7380    #
7381    #
7382    #
7383    #"
7384   [(set_attr "type"
7385             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7386              fpload,      fpstore,    veclogical, veclogical, two,
7387              store,       load,       two")
7389    (set_attr "size" "64")
7390    (set_attr "length"
7391             "4,           4,          4,          4,          4,
7392              4,           4,          4,          4,          8,
7393              8,           8,          8")])
7395 ;;           STW      LWZ     MR      G-const H-const F-const
7397 (define_insn "*mov<mode>_softfloat32"
7398   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7399            "=Y,       r,      r,      r,      r,      r")
7401         (match_operand:FMOVE64 1 "input_operand"
7402             "r,       Y,      r,      G,      H,      F"))]
7404   "!TARGET_POWERPC64
7405    && (gpc_reg_operand (operands[0], <MODE>mode)
7406        || gpc_reg_operand (operands[1], <MODE>mode))"
7407   "#"
7408   [(set_attr "type"
7409             "store,   load,   two,    *,      *,      *")
7411    (set_attr "length"
7412              "8,      8,      8,      8,      12,     16")])
7414 ; ld/std require word-aligned displacements -> 'Y' constraint.
7415 ; List Y->r and r->Y before r->r for reload.
7417 ;;           STFD         LFD         FMR         LXSD        STXSD
7418 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7419 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7420 ;;           NOP          MFTGPR      MFFGPR      MFVSRD      MTVSRD
7422 (define_insn "*mov<mode>_hardfloat64"
7423   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7424            "=m,           d,          d,          <f64_p9>,   wY,
7425              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7426              Y,           r,          !r,         *c*l,       !r,
7427             *h,           r,          wg,         r,          <f64_dm>")
7429         (match_operand:FMOVE64 1 "input_operand"
7430             "d,           m,          d,          wY,         <f64_p9>,
7431              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7432              r,           Y,          r,          r,          h,
7433              0,           wg,         r,          <f64_dm>,   r"))]
7435   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7436    && (gpc_reg_operand (operands[0], <MODE>mode)
7437        || gpc_reg_operand (operands[1], <MODE>mode))"
7438   "@
7439    stfd%U0%X0 %1,%0
7440    lfd%U1%X1 %0,%1
7441    fmr %0,%1
7442    lxsd %0,%1
7443    stxsd %1,%0
7444    lxsd%U1x %x0,%y1
7445    stxsd%U0x %x1,%y0
7446    xxlor %x0,%x1,%x1
7447    xxlxor %x0,%x0,%x0
7448    li %0,0
7449    std%U0%X0 %1,%0
7450    ld%U1%X1 %0,%1
7451    mr %0,%1
7452    mt%0 %1
7453    mf%1 %0
7454    nop
7455    mftgpr %0,%1
7456    mffgpr %0,%1
7457    mfvsrd %0,%x1
7458    mtvsrd %x0,%1"
7459   [(set_attr "type"
7460             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7461              fpload,      fpstore,    veclogical, veclogical, integer,
7462              store,       load,       *,          mtjmpr,     mfjmpr,
7463              *,           mftgpr,     mffgpr,     mftgpr,    mffgpr")
7465    (set_attr "size" "64")
7466    (set_attr "length" "4")])
7468 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7469 ;;           H-const  F-const  Special
7471 (define_insn "*mov<mode>_softfloat64"
7472   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7473            "=Y,       r,      r,      cl,     r,      r,
7474              r,       r,      *h")
7476         (match_operand:FMOVE64 1 "input_operand"
7477             "r,       Y,      r,      r,      h,      G,
7478              H,       F,      0"))]
7480   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7481    && (gpc_reg_operand (operands[0], <MODE>mode)
7482        || gpc_reg_operand (operands[1], <MODE>mode))"
7483   "@
7484    std%U0%X0 %1,%0
7485    ld%U1%X1 %0,%1
7486    mr %0,%1
7487    mt%0 %1
7488    mf%1 %0
7489    #
7490    #
7491    #
7492    nop"
7493   [(set_attr "type"
7494             "store,   load,   *,      mtjmpr, mfjmpr, *,
7495              *,       *,      *")
7497    (set_attr "length"
7498             "4,       4,      4,      4,      4,      8,
7499              12,      16,     4")])
7501 (define_expand "mov<mode>"
7502   [(set (match_operand:FMOVE128 0 "general_operand")
7503         (match_operand:FMOVE128 1 "any_operand"))]
7504   ""
7506   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7507   DONE;
7510 ;; It's important to list Y->r and r->Y before r->r because otherwise
7511 ;; reload, given m->r, will try to pick r->r and reload it, which
7512 ;; doesn't make progress.
7514 ;; We can't split little endian direct moves of TDmode, because the words are
7515 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7516 ;; problematical.  Don't allow direct move for this case.
7518 (define_insn_and_split "*mov<mode>_64bit_dm"
7519   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7520         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7521   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7522    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7523    && (gpc_reg_operand (operands[0], <MODE>mode)
7524        || gpc_reg_operand (operands[1], <MODE>mode))"
7525   "#"
7526   "&& reload_completed"
7527   [(pc)]
7528 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7529   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7531 (define_insn_and_split "*movtd_64bit_nodm"
7532   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7533         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7534   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7535    && (gpc_reg_operand (operands[0], TDmode)
7536        || gpc_reg_operand (operands[1], TDmode))"
7537   "#"
7538   "&& reload_completed"
7539   [(pc)]
7540 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7541   [(set_attr "length" "8,8,8,12,12,8")])
7543 (define_insn_and_split "*mov<mode>_32bit"
7544   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7545         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7546   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7547    && (FLOAT128_2REG_P (<MODE>mode)
7548        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7549        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7550    && (gpc_reg_operand (operands[0], <MODE>mode)
7551        || gpc_reg_operand (operands[1], <MODE>mode))"
7552   "#"
7553   "&& reload_completed"
7554   [(pc)]
7555 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7556   [(set_attr "length" "8,8,8,8,20,20,16")])
7558 (define_insn_and_split "*mov<mode>_softfloat"
7559   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7560         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7561   "TARGET_SOFT_FLOAT
7562    && (gpc_reg_operand (operands[0], <MODE>mode)
7563        || gpc_reg_operand (operands[1], <MODE>mode))"
7564   "#"
7565   "&& reload_completed"
7566   [(pc)]
7567 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7568   [(set_attr "length" "20,20,16")])
7570 (define_expand "extenddf<mode>2"
7571   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7572         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7573   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7575   if (FLOAT128_IEEE_P (<MODE>mode))
7576     rs6000_expand_float128_convert (operands[0], operands[1], false);
7577   else if (TARGET_VSX)
7578     {
7579       if (<MODE>mode == TFmode)
7580         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7581       else if (<MODE>mode == IFmode)
7582         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7583       else
7584         gcc_unreachable ();
7585     }
7586    else
7587     {
7588       rtx zero = gen_reg_rtx (DFmode);
7589       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7591       if (<MODE>mode == TFmode)
7592         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7593       else if (<MODE>mode == IFmode)
7594         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7595       else
7596         gcc_unreachable ();
7597     }
7598   DONE;
7601 ;; Allow memory operands for the source to be created by the combiner.
7602 (define_insn_and_split "extenddf<mode>2_fprs"
7603   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7604         (float_extend:IBM128
7605          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7606    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7607   "!TARGET_VSX && TARGET_HARD_FLOAT
7608    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7609   "#"
7610   "&& reload_completed"
7611   [(set (match_dup 3) (match_dup 1))
7612    (set (match_dup 4) (match_dup 2))]
7614   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7615   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7617   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7618   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7621 (define_insn_and_split "extenddf<mode>2_vsx"
7622   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7623         (float_extend:IBM128
7624          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7625   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7626   "#"
7627   "&& reload_completed"
7628   [(set (match_dup 2) (match_dup 1))
7629    (set (match_dup 3) (match_dup 4))]
7631   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7632   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7634   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7635   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7636   operands[4] = CONST0_RTX (DFmode);
7639 (define_expand "extendsf<mode>2"
7640   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7641         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7642   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7644   if (FLOAT128_IEEE_P (<MODE>mode))
7645     rs6000_expand_float128_convert (operands[0], operands[1], false);
7646   else
7647     {
7648       rtx tmp = gen_reg_rtx (DFmode);
7649       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7650       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7651     }
7652   DONE;
7655 (define_expand "trunc<mode>df2"
7656   [(set (match_operand:DF 0 "gpc_reg_operand")
7657         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7658   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7660   if (FLOAT128_IEEE_P (<MODE>mode))
7661     {
7662       rs6000_expand_float128_convert (operands[0], operands[1], false);
7663       DONE;
7664     }
7667 (define_insn_and_split "trunc<mode>df2_internal1"
7668   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7669         (float_truncate:DF
7670          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7671   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7672    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7673   "@
7674    #
7675    fmr %0,%1"
7676   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7677   [(const_int 0)]
7679   emit_note (NOTE_INSN_DELETED);
7680   DONE;
7682   [(set_attr "type" "fpsimple")])
7684 (define_insn "trunc<mode>df2_internal2"
7685   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7686         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7687   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7688    && TARGET_LONG_DOUBLE_128"
7689   "fadd %0,%1,%L1"
7690   [(set_attr "type" "fp")])
7692 (define_expand "trunc<mode>sf2"
7693   [(set (match_operand:SF 0 "gpc_reg_operand")
7694         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7695   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7697   if (FLOAT128_IEEE_P (<MODE>mode))
7698     rs6000_expand_float128_convert (operands[0], operands[1], false);
7699   else if (<MODE>mode == TFmode)
7700     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7701   else if (<MODE>mode == IFmode)
7702     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7703   else
7704     gcc_unreachable ();
7705   DONE;
7708 (define_insn_and_split "trunc<mode>sf2_fprs"
7709   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7710         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7711    (clobber (match_scratch:DF 2 "=d"))]
7712   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7713   "#"
7714   "&& reload_completed"
7715   [(set (match_dup 2)
7716         (float_truncate:DF (match_dup 1)))
7717    (set (match_dup 0)
7718         (float_truncate:SF (match_dup 2)))]
7719   "")
7721 (define_expand "floatsi<mode>2"
7722   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7723                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7724               (clobber (match_scratch:DI 2))])]
7725   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7727   rtx op0 = operands[0];
7728   rtx op1 = operands[1];
7730   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7731     ;
7732   else if (FLOAT128_IEEE_P (<MODE>mode))
7733     {
7734       rs6000_expand_float128_convert (op0, op1, false);
7735       DONE;
7736     }
7737   else
7738     {
7739       rtx tmp = gen_reg_rtx (DFmode);
7740       expand_float (tmp, op1, false);
7741       if (<MODE>mode == TFmode)
7742         emit_insn (gen_extenddftf2 (op0, tmp));
7743       else if (<MODE>mode == IFmode)
7744         emit_insn (gen_extenddfif2 (op0, tmp));
7745       else
7746         gcc_unreachable ();
7747       DONE;
7748     }
7751 ; fadd, but rounding towards zero.
7752 ; This is probably not the optimal code sequence.
7753 (define_insn "fix_trunc_helper<mode>"
7754   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7755         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7756                    UNSPEC_FIX_TRUNC_TF))
7757    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7758   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7759   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7760   [(set_attr "type" "fp")
7761    (set_attr "length" "20")])
7763 (define_expand "fix_trunc<mode>si2"
7764   [(set (match_operand:SI 0 "gpc_reg_operand")
7765         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7766   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7768   rtx op0 = operands[0];
7769   rtx op1 = operands[1];
7771   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7772     ;
7773   else
7774     {
7775       if (FLOAT128_IEEE_P (<MODE>mode))
7776         rs6000_expand_float128_convert (op0, op1, false);
7777       else if (<MODE>mode == TFmode)
7778         emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7779       else if (<MODE>mode == IFmode)
7780         emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7781       else
7782         gcc_unreachable ();
7783       DONE;
7784     }
7787 (define_expand "fix_trunc<mode>si2_fprs"
7788   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7789                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7790               (clobber (match_dup 2))
7791               (clobber (match_dup 3))
7792               (clobber (match_dup 4))
7793               (clobber (match_dup 5))])]
7794   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7796   operands[2] = gen_reg_rtx (DFmode);
7797   operands[3] = gen_reg_rtx (DFmode);
7798   operands[4] = gen_reg_rtx (DImode);
7799   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7802 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7803   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7804         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7805    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7806    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7807    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7808    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7809   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7810   "#"
7811   ""
7812   [(pc)]
7814   rtx lowword;
7815   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7816                                          operands[3]));
7818   gcc_assert (MEM_P (operands[5]));
7819   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7821   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7822   emit_move_insn (operands[5], operands[4]);
7823   emit_move_insn (operands[0], lowword);
7824   DONE;
7827 (define_expand "fix_trunc<mode>di2"
7828   [(set (match_operand:DI 0 "gpc_reg_operand")
7829         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7830   "TARGET_FLOAT128_TYPE"
7832   if (!TARGET_FLOAT128_HW)
7833     {
7834       rs6000_expand_float128_convert (operands[0], operands[1], false);
7835       DONE;
7836     }
7839 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7840   [(set (match_operand:SDI 0 "gpc_reg_operand")
7841         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7842   "TARGET_FLOAT128_TYPE"
7844   rs6000_expand_float128_convert (operands[0], operands[1], true);
7845   DONE;
7848 (define_expand "floatdi<mode>2"
7849   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7850         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7851   "TARGET_FLOAT128_TYPE"
7853   if (!TARGET_FLOAT128_HW)
7854     {
7855       rs6000_expand_float128_convert (operands[0], operands[1], false);
7856       DONE;
7857     }
7860 (define_expand "floatunsdi<IEEE128:mode>2"
7861   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7862         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7863   "TARGET_FLOAT128_TYPE"
7865   if (!TARGET_FLOAT128_HW)
7866     {
7867       rs6000_expand_float128_convert (operands[0], operands[1], true);
7868       DONE;
7869     }
7872 (define_expand "floatuns<IEEE128:mode>2"
7873   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7874         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
7875   "TARGET_FLOAT128_TYPE"
7877   rtx op0 = operands[0];
7878   rtx op1 = operands[1];
7880   if (TARGET_FLOAT128_HW)
7881     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7882   else
7883     rs6000_expand_float128_convert (op0, op1, true);
7884   DONE;
7887 (define_expand "neg<mode>2"
7888   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7889         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7890   "FLOAT128_IEEE_P (<MODE>mode)
7891    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7893   if (FLOAT128_IEEE_P (<MODE>mode))
7894     {
7895       if (TARGET_FLOAT128_HW)
7896         {
7897           if (<MODE>mode == TFmode)
7898             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7899           else if (<MODE>mode == KFmode)
7900             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7901           else
7902             gcc_unreachable ();
7903         }
7904       else if (TARGET_FLOAT128_TYPE)
7905         {
7906           if (<MODE>mode == TFmode)
7907             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7908           else if (<MODE>mode == KFmode)
7909             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7910           else
7911             gcc_unreachable ();
7912         }
7913       else
7914         {
7915           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7916           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7917                                                 <MODE>mode,
7918                                                 operands[1], <MODE>mode);
7920           if (target && !rtx_equal_p (target, operands[0]))
7921             emit_move_insn (operands[0], target);
7922         }
7923       DONE;
7924     }
7927 (define_insn "neg<mode>2_internal"
7928   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7929         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7930   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7932   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7933     return "fneg %L0,%L1\;fneg %0,%1";
7934   else
7935     return "fneg %0,%1\;fneg %L0,%L1";
7937   [(set_attr "type" "fpsimple")
7938    (set_attr "length" "8")])
7940 (define_expand "abs<mode>2"
7941   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7942         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7943   "FLOAT128_IEEE_P (<MODE>mode)
7944    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7946   rtx label;
7948   if (FLOAT128_IEEE_P (<MODE>mode))
7949     {
7950       if (TARGET_FLOAT128_HW)
7951         {
7952           if (<MODE>mode == TFmode)
7953             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7954           else if (<MODE>mode == KFmode)
7955             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7956           else
7957             FAIL;
7958           DONE;
7959         }
7960       else if (TARGET_FLOAT128_TYPE)
7961         {
7962           if (<MODE>mode == TFmode)
7963             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7964           else if (<MODE>mode == KFmode)
7965             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7966           else
7967             FAIL;
7968           DONE;
7969         }
7970       else
7971         FAIL;
7972     }
7974   label = gen_label_rtx ();
7975   if (<MODE>mode == TFmode)
7976     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7977   else if (<MODE>mode == TFmode)
7978     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7979   else
7980     FAIL;
7981   emit_label (label);
7982   DONE;
7985 (define_expand "abs<mode>2_internal"
7986   [(set (match_operand:IBM128 0 "gpc_reg_operand")
7987         (match_operand:IBM128 1 "gpc_reg_operand"))
7988    (set (match_dup 3) (match_dup 5))
7989    (set (match_dup 5) (abs:DF (match_dup 5)))
7990    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7991    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7992                            (label_ref (match_operand 2 ""))
7993                            (pc)))
7994    (set (match_dup 6) (neg:DF (match_dup 6)))]
7995   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7997   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7998   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7999   operands[3] = gen_reg_rtx (DFmode);
8000   operands[4] = gen_reg_rtx (CCFPmode);
8001   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8002   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8006 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8007 ;; register
8009 (define_expand "ieee_128bit_negative_zero"
8010   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8011   "TARGET_FLOAT128_TYPE"
8013   rtvec v = rtvec_alloc (16);
8014   int i, high;
8016   for (i = 0; i < 16; i++)
8017     RTVEC_ELT (v, i) = const0_rtx;
8019   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8020   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8022   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8023   DONE;
8026 ;; IEEE 128-bit negate
8028 ;; We have 2 insns here for negate and absolute value.  The first uses
8029 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8030 ;; insns, and second insn after the first split pass loads up the bit to
8031 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8032 ;; neg/abs to create the constant just once.
8034 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8035   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8036         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8037    (clobber (match_scratch:V16QI 2 "=v"))]
8038   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8039   "#"
8040   "&& 1"
8041   [(parallel [(set (match_dup 0)
8042                    (neg:IEEE128 (match_dup 1)))
8043               (use (match_dup 2))])]
8045   if (GET_CODE (operands[2]) == SCRATCH)
8046     operands[2] = gen_reg_rtx (V16QImode);
8048   operands[3] = gen_reg_rtx (V16QImode);
8049   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8051   [(set_attr "length" "8")
8052    (set_attr "type" "vecsimple")])
8054 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8055   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8056         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8057    (use (match_operand:V16QI 2 "register_operand" "v"))]
8058   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8059   "xxlxor %x0,%x1,%x2"
8060   [(set_attr "type" "veclogical")])
8062 ;; IEEE 128-bit absolute value
8063 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8064   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8065         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8066    (clobber (match_scratch:V16QI 2 "=v"))]
8067   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8068   "#"
8069   "&& 1"
8070   [(parallel [(set (match_dup 0)
8071                    (abs:IEEE128 (match_dup 1)))
8072               (use (match_dup 2))])]
8074   if (GET_CODE (operands[2]) == SCRATCH)
8075     operands[2] = gen_reg_rtx (V16QImode);
8077   operands[3] = gen_reg_rtx (V16QImode);
8078   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8080   [(set_attr "length" "8")
8081    (set_attr "type" "vecsimple")])
8083 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8084   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8085         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8086    (use (match_operand:V16QI 2 "register_operand" "v"))]
8087   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8088   "xxlandc %x0,%x1,%x2"
8089   [(set_attr "type" "veclogical")])
8091 ;; IEEE 128-bit negative absolute value
8092 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8093   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8094         (neg:IEEE128
8095          (abs:IEEE128
8096           (match_operand:IEEE128 1 "register_operand" "wa"))))
8097    (clobber (match_scratch:V16QI 2 "=v"))]
8098   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8099    && FLOAT128_IEEE_P (<MODE>mode)"
8100   "#"
8101   "&& 1"
8102   [(parallel [(set (match_dup 0)
8103                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8104               (use (match_dup 2))])]
8106   if (GET_CODE (operands[2]) == SCRATCH)
8107     operands[2] = gen_reg_rtx (V16QImode);
8109   operands[3] = gen_reg_rtx (V16QImode);
8110   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8112   [(set_attr "length" "8")
8113    (set_attr "type" "vecsimple")])
8115 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8116   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8117         (neg:IEEE128
8118          (abs:IEEE128
8119           (match_operand:IEEE128 1 "register_operand" "wa"))))
8120    (use (match_operand:V16QI 2 "register_operand" "v"))]
8121   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8122   "xxlor %x0,%x1,%x2"
8123   [(set_attr "type" "veclogical")])
8125 ;; Float128 conversion functions.  These expand to library function calls.
8126 ;; We use expand to convert from IBM double double to IEEE 128-bit
8127 ;; and trunc for the opposite.
8128 (define_expand "extendiftf2"
8129   [(set (match_operand:TF 0 "gpc_reg_operand")
8130         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8131   "TARGET_FLOAT128_TYPE"
8133   rs6000_expand_float128_convert (operands[0], operands[1], false);
8134   DONE;
8137 (define_expand "extendifkf2"
8138   [(set (match_operand:KF 0 "gpc_reg_operand")
8139         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8140   "TARGET_FLOAT128_TYPE"
8142   rs6000_expand_float128_convert (operands[0], operands[1], false);
8143   DONE;
8146 (define_expand "extendtfkf2"
8147   [(set (match_operand:KF 0 "gpc_reg_operand")
8148         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8149   "TARGET_FLOAT128_TYPE"
8151   rs6000_expand_float128_convert (operands[0], operands[1], false);
8152   DONE;
8155 (define_expand "trunciftf2"
8156   [(set (match_operand:IF 0 "gpc_reg_operand")
8157         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8158   "TARGET_FLOAT128_TYPE"
8160   rs6000_expand_float128_convert (operands[0], operands[1], false);
8161   DONE;
8164 (define_expand "truncifkf2"
8165   [(set (match_operand:IF 0 "gpc_reg_operand")
8166         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand")))]
8167   "TARGET_FLOAT128_TYPE"
8169   rs6000_expand_float128_convert (operands[0], operands[1], false);
8170   DONE;
8173 (define_expand "trunckftf2"
8174   [(set (match_operand:TF 0 "gpc_reg_operand")
8175         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8176   "TARGET_FLOAT128_TYPE"
8178   rs6000_expand_float128_convert (operands[0], operands[1], false);
8179   DONE;
8182 (define_expand "trunctfif2"
8183   [(set (match_operand:IF 0 "gpc_reg_operand")
8184         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8185   "TARGET_FLOAT128_TYPE"
8187   rs6000_expand_float128_convert (operands[0], operands[1], false);
8188   DONE;
8192 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8193 ;; must have 3 arguments, and scratch register constraint must be a single
8194 ;; constraint.
8196 ;; Reload patterns to support gpr load/store with misaligned mem.
8197 ;; and multiple gpr load/store at offset >= 0xfffc
8198 (define_expand "reload_<mode>_store"
8199   [(parallel [(match_operand 0 "memory_operand" "=m")
8200               (match_operand 1 "gpc_reg_operand" "r")
8201               (match_operand:GPR 2 "register_operand" "=&b")])]
8202   ""
8204   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8205   DONE;
8208 (define_expand "reload_<mode>_load"
8209   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8210               (match_operand 1 "memory_operand" "m")
8211               (match_operand:GPR 2 "register_operand" "=b")])]
8212   ""
8214   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8215   DONE;
8219 ;; Reload patterns for various types using the vector registers.  We may need
8220 ;; an additional base register to convert the reg+offset addressing to reg+reg
8221 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8222 ;; index register for gpr registers.
8223 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8224   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8225               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8226               (match_operand:P 2 "register_operand" "=b")])]
8227   "<P:tptrsize>"
8229   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8230   DONE;
8233 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8234   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8235               (match_operand:RELOAD 1 "memory_operand" "m")
8236               (match_operand:P 2 "register_operand" "=b")])]
8237   "<P:tptrsize>"
8239   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8240   DONE;
8244 ;; Reload sometimes tries to move the address to a GPR, and can generate
8245 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8246 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8248 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8249   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8250         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8251                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8252                (const_int -16)))]
8253   "TARGET_ALTIVEC && reload_completed"
8254   "#"
8255   "&& reload_completed"
8256   [(set (match_dup 0)
8257         (plus:P (match_dup 1)
8258                 (match_dup 2)))
8259    (set (match_dup 0)
8260         (and:P (match_dup 0)
8261                (const_int -16)))])
8263 ;; Power8 merge instructions to allow direct move to/from floating point
8264 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8265 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8266 ;; value, since it is allocated in reload and not all of the flow information
8267 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8268 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8269 ;; schedule other instructions between the two instructions.
8271 (define_insn "p8_fmrgow_<mode>"
8272   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8273         (unspec:FMOVE64X [
8274                 (match_operand:DF 1 "register_operand" "d")
8275                 (match_operand:DF 2 "register_operand" "d")]
8276                          UNSPEC_P8V_FMRGOW))]
8277   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8278   "fmrgow %0,%1,%2"
8279   [(set_attr "type" "fpsimple")])
8281 (define_insn "p8_mtvsrwz"
8282   [(set (match_operand:DF 0 "register_operand" "=d")
8283         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8284                    UNSPEC_P8V_MTVSRWZ))]
8285   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8286   "mtvsrwz %x0,%1"
8287   [(set_attr "type" "mftgpr")])
8289 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8290   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8291         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8292                          UNSPEC_P8V_RELOAD_FROM_GPR))
8293    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8294   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8295   "#"
8296   "&& reload_completed"
8297   [(const_int 0)]
8299   rtx dest = operands[0];
8300   rtx src = operands[1];
8301   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8302   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8303   rtx gpr_hi_reg = gen_highpart (SImode, src);
8304   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8306   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8307   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8308   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8309   DONE;
8311   [(set_attr "length" "12")
8312    (set_attr "type" "three")])
8314 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8315 (define_insn "p8_mtvsrd_df"
8316   [(set (match_operand:DF 0 "register_operand" "=wa")
8317         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8318                    UNSPEC_P8V_MTVSRD))]
8319   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8320   "mtvsrd %x0,%1"
8321   [(set_attr "type" "mftgpr")])
8323 (define_insn "p8_xxpermdi_<mode>"
8324   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8325         (unspec:FMOVE128_GPR [
8326                 (match_operand:DF 1 "register_operand" "wa")
8327                 (match_operand:DF 2 "register_operand" "wa")]
8328                 UNSPEC_P8V_XXPERMDI))]
8329   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8330   "xxpermdi %x0,%x1,%x2,0"
8331   [(set_attr "type" "vecperm")])
8333 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8334   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8335         (unspec:FMOVE128_GPR
8336          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8337          UNSPEC_P8V_RELOAD_FROM_GPR))
8338    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8339   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8340   "#"
8341   "&& reload_completed"
8342   [(const_int 0)]
8344   rtx dest = operands[0];
8345   rtx src = operands[1];
8346   /* You might think that we could use op0 as one temp and a DF clobber
8347      as op2, but you'd be wrong.  Secondary reload move patterns don't
8348      check for overlap of the clobber and the destination.  */
8349   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8350   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8351   rtx gpr_hi_reg = gen_highpart (DImode, src);
8352   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8354   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8355   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8356   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8357   DONE;
8359   [(set_attr "length" "12")
8360    (set_attr "type" "three")])
8362 (define_split
8363   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8364         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8365   "reload_completed
8366    && (int_reg_operand (operands[0], <MODE>mode)
8367        || int_reg_operand (operands[1], <MODE>mode))
8368    && (!TARGET_DIRECT_MOVE_128
8369        || (!vsx_register_operand (operands[0], <MODE>mode)
8370            && !vsx_register_operand (operands[1], <MODE>mode)))"
8371   [(pc)]
8372 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8374 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8375 ;; type is stored internally as double precision in the VSX registers, we have
8376 ;; to convert it from the vector format.
8377 (define_insn "p8_mtvsrd_sf"
8378   [(set (match_operand:SF 0 "register_operand" "=wa")
8379         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8380                    UNSPEC_P8V_MTVSRD))]
8381   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8382   "mtvsrd %x0,%1"
8383   [(set_attr "type" "mftgpr")])
8385 (define_insn_and_split "reload_vsx_from_gprsf"
8386   [(set (match_operand:SF 0 "register_operand" "=wa")
8387         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8388                    UNSPEC_P8V_RELOAD_FROM_GPR))
8389    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8390   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8391   "#"
8392   "&& reload_completed"
8393   [(const_int 0)]
8395   rtx op0 = operands[0];
8396   rtx op1 = operands[1];
8397   rtx op2 = operands[2];
8398   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8400   /* Move SF value to upper 32-bits for xscvspdpn.  */
8401   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8402   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8403   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8404   DONE;
8406   [(set_attr "length" "8")
8407    (set_attr "type" "two")])
8409 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8410 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8411 ;; and then doing a move of that.
8412 (define_insn "p8_mfvsrd_3_<mode>"
8413   [(set (match_operand:DF 0 "register_operand" "=r")
8414         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8415                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8416   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8417   "mfvsrd %0,%x1"
8418   [(set_attr "type" "mftgpr")])
8420 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8421   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8422         (unspec:FMOVE128_GPR
8423          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8424          UNSPEC_P8V_RELOAD_FROM_VSX))
8425    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8426   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8427   "#"
8428   "&& reload_completed"
8429   [(const_int 0)]
8431   rtx dest = operands[0];
8432   rtx src = operands[1];
8433   rtx tmp = operands[2];
8434   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8435   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8437   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8438   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8439   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8440   DONE;
8442   [(set_attr "length" "12")
8443    (set_attr "type" "three")])
8445 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8446 ;; type is stored internally as double precision, we have to convert it to the
8447 ;; vector format.
8449 (define_insn_and_split "reload_gpr_from_vsxsf"
8450   [(set (match_operand:SF 0 "register_operand" "=r")
8451         (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8452                    UNSPEC_P8V_RELOAD_FROM_VSX))
8453    (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8454   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8455   "#"
8456   "&& reload_completed"
8457   [(const_int 0)]
8459   rtx op0 = operands[0];
8460   rtx op1 = operands[1];
8461   rtx op2 = operands[2];
8462   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8463   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8465   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8466   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8467   DONE;
8469   [(set_attr "length" "8")
8470    (set_attr "type" "two")])
8473 ;; Next come the multi-word integer load and store and the load and store
8474 ;; multiple insns.
8476 ;; List r->r after r->Y, otherwise reload will try to reload a
8477 ;; non-offsettable address by using r->r which won't make progress.
8478 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8479 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8481 ;;        GPR store  GPR load   GPR move   FPR store  FPR load    FPR move
8482 ;;        GPR const  AVX store  AVX store  AVX load   AVX load    VSX move
8483 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1      P9 const
8484 ;;        AVX const  
8486 (define_insn "*movdi_internal32"
8487   [(set (match_operand:DI 0 "nonimmediate_operand"
8488          "=Y,        r,         r,         ^m,        ^d,         ^d,
8489           r,         ^wY,       $Z,        ^wb,       $wv,        ^wi,
8490           *wo,       *wo,       *wv,       *wi,       *wi,        *wv,
8491           *wv")
8493         (match_operand:DI 1 "input_operand"
8494           "r,        Y,         r,         d,         m,          d,
8495            IJKnGHF,  wb,        wv,        wY,        Z,          wi,
8496            Oj,       wM,        OjwM,      Oj,        wM,         wS,
8497            wB"))]
8499   "! TARGET_POWERPC64
8500    && (gpc_reg_operand (operands[0], DImode)
8501        || gpc_reg_operand (operands[1], DImode))"
8502   "@
8503    #
8504    #
8505    #
8506    stfd%U0%X0 %1,%0
8507    lfd%U1%X1 %0,%1
8508    fmr %0,%1
8509    #
8510    stxsd %1,%0
8511    stxsdx %x1,%y0
8512    lxsd %0,%1
8513    lxsdx %x0,%y1
8514    xxlor %x0,%x1,%x1
8515    xxspltib %x0,0
8516    xxspltib %x0,255
8517    vspltisw %0,%1
8518    xxlxor %x0,%x0,%x0
8519    xxlorc %x0,%x0,%x0
8520    #
8521    #"
8522   [(set_attr "type"
8523                "store,     load,      *,         fpstore,    fpload,     fpsimple,
8524                 *,         fpstore,   fpstore,   fpload,     fpload,     veclogical,
8525                 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8526                 vecsimple")
8527    (set_attr "size" "64")])
8529 (define_split
8530   [(set (match_operand:DI 0 "gpc_reg_operand")
8531         (match_operand:DI 1 "const_int_operand"))]
8532   "! TARGET_POWERPC64 && reload_completed
8533    && gpr_or_gpr_p (operands[0], operands[1])
8534    && !direct_move_p (operands[0], operands[1])"
8535   [(set (match_dup 2) (match_dup 4))
8536    (set (match_dup 3) (match_dup 1))]
8538   HOST_WIDE_INT value = INTVAL (operands[1]);
8539   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8540                                        DImode);
8541   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8542                                        DImode);
8543   operands[4] = GEN_INT (value >> 32);
8544   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8547 (define_split
8548   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8549         (match_operand:DIFD 1 "input_operand"))]
8550   "reload_completed && !TARGET_POWERPC64
8551    && gpr_or_gpr_p (operands[0], operands[1])
8552    && !direct_move_p (operands[0], operands[1])"
8553   [(pc)]
8554 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8556 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8557 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8558 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8559 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8560 ;;              FPR->GPR   GPR->FPR   VSX->GPR   GPR->VSX
8561 (define_insn "*movdi_internal64"
8562   [(set (match_operand:DI 0 "nonimmediate_operand"
8563                "=YZ,       r,         r,         r,         r,          r,
8564                 ^m,        ^d,        ^d,        ^wY,       $Z,         $wb,
8565                 $wv,       ^wi,       *wo,       *wo,       *wv,        *wi,
8566                 *wi,       *wv,       *wv,       r,         *h,         *h,
8567                 ?*r,       ?*wg,      ?*r,       ?*wj")
8569         (match_operand:DI 1 "input_operand"
8570                 "r,        YZ,        r,         I,         L,          nF,
8571                  d,        m,         d,         wb,        wv,         wY,
8572                  Z,        wi,        Oj,        wM,        OjwM,       Oj,
8573                  wM,       wS,        wB,        *h,        r,          0,
8574                  wg,       r,         wj,        r"))]
8576   "TARGET_POWERPC64
8577    && (gpc_reg_operand (operands[0], DImode)
8578        || gpc_reg_operand (operands[1], DImode))"
8579   "@
8580    std%U0%X0 %1,%0
8581    ld%U1%X1 %0,%1
8582    mr %0,%1
8583    li %0,%1
8584    lis %0,%v1
8585    #
8586    stfd%U0%X0 %1,%0
8587    lfd%U1%X1 %0,%1
8588    fmr %0,%1
8589    stxsd %1,%0
8590    stxsdx %x1,%y0
8591    lxsd %0,%1
8592    lxsdx %x0,%y1
8593    xxlor %x0,%x1,%x1
8594    xxspltib %x0,0
8595    xxspltib %x0,255
8596    #
8597    xxlxor %x0,%x0,%x0
8598    xxlorc %x0,%x0,%x0
8599    #
8600    #
8601    mf%1 %0
8602    mt%0 %1
8603    nop
8604    mftgpr %0,%1
8605    mffgpr %0,%1
8606    mfvsrd %0,%x1
8607    mtvsrd %x0,%1"
8608   [(set_attr "type"
8609                "store,      load,       *,         *,         *,         *,
8610                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8611                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8612                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8613                 mftgpr,     mffgpr,     mftgpr,    mffgpr")
8615    (set_attr "size" "64")
8616    (set_attr "length"
8617                "4,         4,         4,         4,         4,          20,
8618                 4,         4,         4,         4,         4,          4,
8619                 4,         4,         4,         4,         4,          8,
8620                 8,         4,         4,         4,         4,          4,
8621                 4,         4,         4,         4")])
8623 ; Some DImode loads are best done as a load of -1 followed by a mask
8624 ; instruction.
8625 (define_split
8626   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8627         (match_operand:DI 1 "const_int_operand"))]
8628   "TARGET_POWERPC64
8629    && num_insns_constant (operands[1], DImode) > 1
8630    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8631    && rs6000_is_valid_and_mask (operands[1], DImode)"
8632   [(set (match_dup 0)
8633         (const_int -1))
8634    (set (match_dup 0)
8635         (and:DI (match_dup 0)
8636                 (match_dup 1)))]
8637   "")
8639 ;; Split a load of a large constant into the appropriate five-instruction
8640 ;; sequence.  Handle anything in a constant number of insns.
8641 ;; When non-easy constants can go in the TOC, this should use
8642 ;; easy_fp_constant predicate.
8643 (define_split
8644   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8645         (match_operand:DI 1 "const_int_operand"))]
8646   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8647   [(set (match_dup 0) (match_dup 2))
8648    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8650   if (rs6000_emit_set_const (operands[0], operands[1]))
8651     DONE;
8652   else
8653     FAIL;
8656 (define_split
8657   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8658         (match_operand:DI 1 "const_scalar_int_operand"))]
8659   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8660   [(set (match_dup 0) (match_dup 2))
8661    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8663   if (rs6000_emit_set_const (operands[0], operands[1]))
8664     DONE;
8665   else
8666     FAIL;
8669 (define_split
8670   [(set (match_operand:DI 0 "altivec_register_operand")
8671         (match_operand:DI 1 "s5bit_cint_operand"))]
8672   "TARGET_VSX && reload_completed"
8673   [(const_int 0)]
8675   rtx op0 = operands[0];
8676   rtx op1 = operands[1];
8677   int r = REGNO (op0);
8678   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8680   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8681   if (op1 != const0_rtx && op1 != constm1_rtx)
8682     {
8683       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8684       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8685     }
8686   DONE;
8689 ;; Split integer constants that can be loaded with XXSPLTIB and a
8690 ;; sign extend operation.
8691 (define_split
8692   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8693         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8694   "TARGET_P9_VECTOR && reload_completed"
8695   [(const_int 0)]
8697   rtx op0 = operands[0];
8698   rtx op1 = operands[1];
8699   int r = REGNO (op0);
8700   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8702   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8703   if (<MODE>mode == DImode)
8704     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8705   else if (<MODE>mode == SImode)
8706     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8707   else if (<MODE>mode == HImode)
8708     {
8709       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8710       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8711     }
8712   DONE;
8716 ;; TImode/PTImode is similar, except that we usually want to compute the
8717 ;; address into a register and use lsi/stsi (the exception is during reload).
8719 (define_insn "*mov<mode>_string"
8720   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8721         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8722   "! TARGET_POWERPC64
8723    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8724    && (gpc_reg_operand (operands[0], <MODE>mode)
8725        || gpc_reg_operand (operands[1], <MODE>mode))"
8726   "#"
8727   [(set_attr "type" "store,store,load,load,*,*")
8728    (set_attr "update" "yes")
8729    (set_attr "indexed" "yes")
8730    (set_attr "cell_micro" "conditional")])
8732 (define_insn "*mov<mode>_ppc64"
8733   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8734         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8735   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8736    && (gpc_reg_operand (operands[0], <MODE>mode)
8737        || gpc_reg_operand (operands[1], <MODE>mode)))"
8739   return rs6000_output_move_128bit (operands);
8741   [(set_attr "type" "store,store,load,load,*,*")
8742    (set_attr "length" "8")])
8744 (define_split
8745   [(set (match_operand:TI2 0 "int_reg_operand")
8746         (match_operand:TI2 1 "const_scalar_int_operand"))]
8747   "TARGET_POWERPC64
8748    && (VECTOR_MEM_NONE_P (<MODE>mode)
8749        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8750   [(set (match_dup 2) (match_dup 4))
8751    (set (match_dup 3) (match_dup 5))]
8753   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8754                                        <MODE>mode);
8755   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8756                                        <MODE>mode);
8757   if (CONST_WIDE_INT_P (operands[1]))
8758     {
8759       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8760       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8761     }
8762   else if (CONST_INT_P (operands[1]))
8763     {
8764       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8765       operands[5] = operands[1];
8766     }
8767   else
8768     FAIL;
8771 (define_split
8772   [(set (match_operand:TI2 0 "nonimmediate_operand")
8773         (match_operand:TI2 1 "input_operand"))]
8774   "reload_completed
8775    && gpr_or_gpr_p (operands[0], operands[1])
8776    && !direct_move_p (operands[0], operands[1])
8777    && !quad_load_store_p (operands[0], operands[1])"
8778   [(pc)]
8779 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8781 (define_expand "setmemsi"
8782   [(parallel [(set (match_operand:BLK 0 "")
8783                    (match_operand 2 "const_int_operand"))
8784               (use (match_operand:SI 1 ""))
8785               (use (match_operand:SI 3 ""))])]
8786   ""
8788   /* If value to set is not zero, use the library routine.  */
8789   if (operands[2] != const0_rtx)
8790     FAIL;
8792   if (expand_block_clear (operands))
8793     DONE;
8794   else
8795     FAIL;
8798 ;; String compare N insn.
8799 ;; Argument 0 is the target (result)
8800 ;; Argument 1 is the destination
8801 ;; Argument 2 is the source
8802 ;; Argument 3 is the length
8803 ;; Argument 4 is the alignment
8805 (define_expand "cmpstrnsi"
8806   [(parallel [(set (match_operand:SI 0)
8807                (compare:SI (match_operand:BLK 1)
8808                            (match_operand:BLK 2)))
8809               (use (match_operand:SI 3))
8810               (use (match_operand:SI 4))])]
8811   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8813   if (optimize_insn_for_size_p ())
8814     FAIL;
8816   if (expand_strn_compare (operands, 0))
8817     DONE;
8818   else  
8819     FAIL;
8822 ;; String compare insn.
8823 ;; Argument 0 is the target (result)
8824 ;; Argument 1 is the destination
8825 ;; Argument 2 is the source
8826 ;; Argument 3 is the alignment
8828 (define_expand "cmpstrsi"
8829   [(parallel [(set (match_operand:SI 0)
8830                (compare:SI (match_operand:BLK 1)
8831                            (match_operand:BLK 2)))
8832               (use (match_operand:SI 3))])]
8833   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8835   if (optimize_insn_for_size_p ())
8836     FAIL;
8838   if (expand_strn_compare (operands, 1))
8839     DONE;
8840   else  
8841     FAIL;
8844 ;; Block compare insn.
8845 ;; Argument 0 is the target (result)
8846 ;; Argument 1 is the destination
8847 ;; Argument 2 is the source
8848 ;; Argument 3 is the length
8849 ;; Argument 4 is the alignment
8851 (define_expand "cmpmemsi"
8852   [(parallel [(set (match_operand:SI 0)
8853                (compare:SI (match_operand:BLK 1)
8854                            (match_operand:BLK 2)))
8855               (use (match_operand:SI 3))
8856               (use (match_operand:SI 4))])]
8857   "TARGET_POPCNTD"
8859   if (expand_block_compare (operands))
8860     DONE;
8861   else
8862     FAIL;
8865 ;; String/block move insn.
8866 ;; Argument 0 is the destination
8867 ;; Argument 1 is the source
8868 ;; Argument 2 is the length
8869 ;; Argument 3 is the alignment
8871 (define_expand "movmemsi"
8872   [(parallel [(set (match_operand:BLK 0 "")
8873                    (match_operand:BLK 1 ""))
8874               (use (match_operand:SI 2 ""))
8875               (use (match_operand:SI 3 ""))])]
8876   ""
8878   if (expand_block_move (operands))
8879     DONE;
8880   else
8881     FAIL;
8884 ;; Define insns that do load or store with update.  Some of these we can
8885 ;; get by using pre-decrement or pre-increment, but the hardware can also
8886 ;; do cases where the increment is not the size of the object.
8888 ;; In all these cases, we use operands 0 and 1 for the register being
8889 ;; incremented because those are the operands that local-alloc will
8890 ;; tie and these are the pair most likely to be tieable (and the ones
8891 ;; that will benefit the most).
8893 (define_insn "*movdi_update1"
8894   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8895         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8896                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8897    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8898         (plus:DI (match_dup 1) (match_dup 2)))]
8899   "TARGET_POWERPC64 && TARGET_UPDATE
8900    && (!avoiding_indexed_address_p (DImode)
8901        || !gpc_reg_operand (operands[2], DImode))"
8902   "@
8903    ldux %3,%0,%2
8904    ldu %3,%2(%0)"
8905   [(set_attr "type" "load")
8906    (set_attr "update" "yes")
8907    (set_attr "indexed" "yes,no")])
8909 (define_insn "movdi_<mode>_update"
8910   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8911                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8912         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8913    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8914         (plus:P (match_dup 1) (match_dup 2)))]
8915   "TARGET_POWERPC64 && TARGET_UPDATE
8916    && (!avoiding_indexed_address_p (Pmode)
8917        || !gpc_reg_operand (operands[2], Pmode)
8918        || (REG_P (operands[0])
8919            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8920   "@
8921    stdux %3,%0,%2
8922    stdu %3,%2(%0)"
8923   [(set_attr "type" "store")
8924    (set_attr "update" "yes")
8925    (set_attr "indexed" "yes,no")])
8927 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8928 ;; needed for stack allocation, even if the user passes -mno-update.
8929 (define_insn "movdi_<mode>_update_stack"
8930   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8931                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8932         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8933    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8934         (plus:P (match_dup 1) (match_dup 2)))]
8935   "TARGET_POWERPC64"
8936   "@
8937    stdux %3,%0,%2
8938    stdu %3,%2(%0)"
8939   [(set_attr "type" "store")
8940    (set_attr "update" "yes")
8941    (set_attr "indexed" "yes,no")])
8943 (define_insn "*movsi_update1"
8944   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8945         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8946                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8947    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8948         (plus:SI (match_dup 1) (match_dup 2)))]
8949   "TARGET_UPDATE
8950    && (!avoiding_indexed_address_p (SImode)
8951        || !gpc_reg_operand (operands[2], SImode))"
8952   "@
8953    lwzux %3,%0,%2
8954    lwzu %3,%2(%0)"
8955   [(set_attr "type" "load")
8956    (set_attr "update" "yes")
8957    (set_attr "indexed" "yes,no")])
8959 (define_insn "*movsi_update2"
8960   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8961         (sign_extend:DI
8962          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8963                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8964    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8965         (plus:DI (match_dup 1) (match_dup 2)))]
8966   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
8967   "lwaux %3,%0,%2"
8968   [(set_attr "type" "load")
8969    (set_attr "sign_extend" "yes")
8970    (set_attr "update" "yes")
8971    (set_attr "indexed" "yes")])
8973 (define_insn "movsi_update"
8974   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8975                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8976         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8977    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8978         (plus:SI (match_dup 1) (match_dup 2)))]
8979   "TARGET_UPDATE
8980    && (!avoiding_indexed_address_p (SImode)
8981        || !gpc_reg_operand (operands[2], SImode)
8982        || (REG_P (operands[0])
8983            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8984   "@
8985    stwux %3,%0,%2
8986    stwu %3,%2(%0)"
8987   [(set_attr "type" "store")
8988    (set_attr "update" "yes")
8989    (set_attr "indexed" "yes,no")])
8991 ;; This is an unconditional pattern; needed for stack allocation, even
8992 ;; if the user passes -mno-update.
8993 (define_insn "movsi_update_stack"
8994   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8995                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8996         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8997    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8998         (plus:SI (match_dup 1) (match_dup 2)))]
8999   ""
9000   "@
9001    stwux %3,%0,%2
9002    stwu %3,%2(%0)"
9003   [(set_attr "type" "store")
9004    (set_attr "update" "yes")
9005    (set_attr "indexed" "yes,no")])
9007 (define_insn "*movhi_update1"
9008   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9009         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9010                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9011    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9012         (plus:SI (match_dup 1) (match_dup 2)))]
9013   "TARGET_UPDATE
9014    && (!avoiding_indexed_address_p (SImode)
9015        || !gpc_reg_operand (operands[2], SImode))"
9016   "@
9017    lhzux %3,%0,%2
9018    lhzu %3,%2(%0)"
9019   [(set_attr "type" "load")
9020    (set_attr "update" "yes")
9021    (set_attr "indexed" "yes,no")])
9023 (define_insn "*movhi_update2"
9024   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9025         (zero_extend:SI
9026          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9027                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9028    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9029         (plus:SI (match_dup 1) (match_dup 2)))]
9030   "TARGET_UPDATE
9031    && (!avoiding_indexed_address_p (SImode)
9032        || !gpc_reg_operand (operands[2], SImode))"
9033   "@
9034    lhzux %3,%0,%2
9035    lhzu %3,%2(%0)"
9036   [(set_attr "type" "load")
9037    (set_attr "update" "yes")
9038    (set_attr "indexed" "yes,no")])
9040 (define_insn "*movhi_update3"
9041   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9042         (sign_extend:SI
9043          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9044                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9045    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9046         (plus:SI (match_dup 1) (match_dup 2)))]
9047   "TARGET_UPDATE
9048    && !(avoiding_indexed_address_p (SImode)
9049         && gpc_reg_operand (operands[2], SImode))"
9050   "@
9051    lhaux %3,%0,%2
9052    lhau %3,%2(%0)"
9053   [(set_attr "type" "load")
9054    (set_attr "sign_extend" "yes")
9055    (set_attr "update" "yes")
9056    (set_attr "indexed" "yes,no")])
9058 (define_insn "*movhi_update4"
9059   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9060                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9061         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9062    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9063         (plus:SI (match_dup 1) (match_dup 2)))]
9064   "TARGET_UPDATE
9065    && (!avoiding_indexed_address_p (SImode)
9066        || !gpc_reg_operand (operands[2], SImode))"
9067   "@
9068    sthux %3,%0,%2
9069    sthu %3,%2(%0)"
9070   [(set_attr "type" "store")
9071    (set_attr "update" "yes")
9072    (set_attr "indexed" "yes,no")])
9074 (define_insn "*movqi_update1"
9075   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9076         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9077                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9078    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9079         (plus:SI (match_dup 1) (match_dup 2)))]
9080   "TARGET_UPDATE
9081    && (!avoiding_indexed_address_p (SImode)
9082        || !gpc_reg_operand (operands[2], SImode))"
9083   "@
9084    lbzux %3,%0,%2
9085    lbzu %3,%2(%0)"
9086   [(set_attr "type" "load")
9087    (set_attr "update" "yes")
9088    (set_attr "indexed" "yes,no")])
9090 (define_insn "*movqi_update2"
9091   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9092         (zero_extend:SI
9093          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9094                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9095    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9096         (plus:SI (match_dup 1) (match_dup 2)))]
9097   "TARGET_UPDATE
9098    && (!avoiding_indexed_address_p (SImode)
9099        || !gpc_reg_operand (operands[2], SImode))"
9100   "@
9101    lbzux %3,%0,%2
9102    lbzu %3,%2(%0)"
9103   [(set_attr "type" "load")
9104    (set_attr "update" "yes")
9105    (set_attr "indexed" "yes,no")])
9107 (define_insn "*movqi_update3"
9108   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9109                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9110         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9111    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9112         (plus:SI (match_dup 1) (match_dup 2)))]
9113   "TARGET_UPDATE
9114    && (!avoiding_indexed_address_p (SImode)
9115        || !gpc_reg_operand (operands[2], SImode))"
9116   "@
9117    stbux %3,%0,%2
9118    stbu %3,%2(%0)"
9119   [(set_attr "type" "store")
9120    (set_attr "update" "yes")
9121    (set_attr "indexed" "yes,no")])
9123 (define_insn "*movsf_update1"
9124   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9125         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9126                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9127    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9128         (plus:SI (match_dup 1) (match_dup 2)))]
9129   "TARGET_HARD_FLOAT && TARGET_UPDATE
9130    && (!avoiding_indexed_address_p (SImode)
9131        || !gpc_reg_operand (operands[2], SImode))"
9132   "@
9133    lfsux %3,%0,%2
9134    lfsu %3,%2(%0)"
9135   [(set_attr "type" "fpload")
9136    (set_attr "update" "yes")
9137    (set_attr "indexed" "yes,no")])
9139 (define_insn "*movsf_update2"
9140   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9141                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9142         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9143    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9144         (plus:SI (match_dup 1) (match_dup 2)))]
9145   "TARGET_HARD_FLOAT && TARGET_UPDATE
9146    && (!avoiding_indexed_address_p (SImode)
9147        || !gpc_reg_operand (operands[2], SImode))"
9148   "@
9149    stfsux %3,%0,%2
9150    stfsu %3,%2(%0)"
9151   [(set_attr "type" "fpstore")
9152    (set_attr "update" "yes")
9153    (set_attr "indexed" "yes,no")])
9155 (define_insn "*movsf_update3"
9156   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9157         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9158                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9159    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9160         (plus:SI (match_dup 1) (match_dup 2)))]
9161   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9162    && (!avoiding_indexed_address_p (SImode)
9163        || !gpc_reg_operand (operands[2], SImode))"
9164   "@
9165    lwzux %3,%0,%2
9166    lwzu %3,%2(%0)"
9167   [(set_attr "type" "load")
9168    (set_attr "update" "yes")
9169    (set_attr "indexed" "yes,no")])
9171 (define_insn "*movsf_update4"
9172   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9173                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9174         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9175    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9176         (plus:SI (match_dup 1) (match_dup 2)))]
9177   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9178    && (!avoiding_indexed_address_p (SImode)
9179        || !gpc_reg_operand (operands[2], SImode))"
9180   "@
9181    stwux %3,%0,%2
9182    stwu %3,%2(%0)"
9183   [(set_attr "type" "store")
9184    (set_attr "update" "yes")
9185    (set_attr "indexed" "yes,no")])
9187 (define_insn "*movdf_update1"
9188   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9189         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9190                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9191    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9192         (plus:SI (match_dup 1) (match_dup 2)))]
9193   "TARGET_HARD_FLOAT && TARGET_UPDATE
9194    && (!avoiding_indexed_address_p (SImode)
9195        || !gpc_reg_operand (operands[2], SImode))"
9196   "@
9197    lfdux %3,%0,%2
9198    lfdu %3,%2(%0)"
9199   [(set_attr "type" "fpload")
9200    (set_attr "update" "yes")
9201    (set_attr "indexed" "yes,no")
9202    (set_attr "size" "64")])
9204 (define_insn "*movdf_update2"
9205   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9206                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9207         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9208    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9209         (plus:SI (match_dup 1) (match_dup 2)))]
9210   "TARGET_HARD_FLOAT && TARGET_UPDATE
9211    && (!avoiding_indexed_address_p (SImode)
9212        || !gpc_reg_operand (operands[2], SImode))"
9213   "@
9214    stfdux %3,%0,%2
9215    stfdu %3,%2(%0)"
9216   [(set_attr "type" "fpstore")
9217    (set_attr "update" "yes")
9218    (set_attr "indexed" "yes,no")])
9221 ;; After inserting conditional returns we can sometimes have
9222 ;; unnecessary register moves.  Unfortunately we cannot have a
9223 ;; modeless peephole here, because some single SImode sets have early
9224 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9225 ;; sequences, using get_attr_length here will smash the operands
9226 ;; array.  Neither is there an early_cobbler_p predicate.
9227 ;; Also this optimization interferes with scalars going into
9228 ;; altivec registers (the code does reloading through the FPRs).
9229 (define_peephole2
9230   [(set (match_operand:DF 0 "gpc_reg_operand")
9231         (match_operand:DF 1 "any_operand"))
9232    (set (match_operand:DF 2 "gpc_reg_operand")
9233         (match_dup 0))]
9234   "!TARGET_VSX
9235    && peep2_reg_dead_p (2, operands[0])"
9236   [(set (match_dup 2) (match_dup 1))])
9238 (define_peephole2
9239   [(set (match_operand:SF 0 "gpc_reg_operand")
9240         (match_operand:SF 1 "any_operand"))
9241    (set (match_operand:SF 2 "gpc_reg_operand")
9242         (match_dup 0))]
9243   "!TARGET_P8_VECTOR
9244    && peep2_reg_dead_p (2, operands[0])"
9245   [(set (match_dup 2) (match_dup 1))])
9248 ;; TLS support.
9250 ;; Mode attributes for different ABIs.
9251 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9252 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9253 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9254 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9256 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9257   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9258         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9259               (match_operand 4 "" "g")))
9260    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9261                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9262                    UNSPEC_TLSGD)
9263    (clobber (reg:SI LR_REGNO))]
9264   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9266   if (TARGET_CMODEL != CMODEL_SMALL)
9267     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9268            "bl %z3\;nop";
9269   else
9270     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9272   "&& TARGET_TLS_MARKERS"
9273   [(set (match_dup 0)
9274         (unspec:TLSmode [(match_dup 1)
9275                          (match_dup 2)]
9276                         UNSPEC_TLSGD))
9277    (parallel [(set (match_dup 0)
9278                    (call (mem:TLSmode (match_dup 3))
9279                          (match_dup 4)))
9280               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9281               (clobber (reg:SI LR_REGNO))])]
9282   ""
9283   [(set_attr "type" "two")
9284    (set (attr "length")
9285      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9286                    (const_int 16)
9287                    (const_int 12)))])
9289 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9290   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9291         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9292               (match_operand 4 "" "g")))
9293    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9294                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9295                    UNSPEC_TLSGD)
9296    (clobber (reg:SI LR_REGNO))]
9297   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9299   if (flag_pic)
9300     {
9301       if (TARGET_SECURE_PLT && flag_pic == 2)
9302         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9303       else
9304         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9305     }
9306   else
9307     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9309   "&& TARGET_TLS_MARKERS"
9310   [(set (match_dup 0)
9311         (unspec:TLSmode [(match_dup 1)
9312                          (match_dup 2)]
9313                         UNSPEC_TLSGD))
9314    (parallel [(set (match_dup 0)
9315                    (call (mem:TLSmode (match_dup 3))
9316                          (match_dup 4)))
9317               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9318               (clobber (reg:SI LR_REGNO))])]
9319   ""
9320   [(set_attr "type" "two")
9321    (set_attr "length" "8")])
9323 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9324   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9325         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9326                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9327                         UNSPEC_TLSGD))]
9328   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9329   "addi %0,%1,%2@got@tlsgd"
9330   "&& TARGET_CMODEL != CMODEL_SMALL"
9331   [(set (match_dup 3)
9332         (high:TLSmode
9333             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9334    (set (match_dup 0)
9335         (lo_sum:TLSmode (match_dup 3)
9336             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9338   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9340   [(set (attr "length")
9341      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9342                    (const_int 8)
9343                    (const_int 4)))])
9345 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9346   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9347      (high:TLSmode
9348        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9349                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9350                        UNSPEC_TLSGD)))]
9351   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9352   "addis %0,%1,%2@got@tlsgd@ha"
9353   [(set_attr "length" "4")])
9355 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9356   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9357      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9358        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9359                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9360                        UNSPEC_TLSGD)))]
9361   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9362   "addi %0,%1,%2@got@tlsgd@l"
9363   [(set_attr "length" "4")])
9365 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9366   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9367         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9368               (match_operand 2 "" "g")))
9369    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9370                    UNSPEC_TLSGD)
9371    (clobber (reg:SI LR_REGNO))]
9372   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9373    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9374   "bl %z1(%3@tlsgd)\;nop"
9375   [(set_attr "type" "branch")
9376    (set_attr "length" "8")])
9378 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9379   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9380         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9381               (match_operand 2 "" "g")))
9382    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9383                    UNSPEC_TLSGD)
9384    (clobber (reg:SI LR_REGNO))]
9385   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9387   if (flag_pic)
9388     {
9389       if (TARGET_SECURE_PLT && flag_pic == 2)
9390         return "bl %z1+32768(%3@tlsgd)@plt";
9391       return "bl %z1(%3@tlsgd)@plt";
9392     }
9393   return "bl %z1(%3@tlsgd)";
9395   [(set_attr "type" "branch")
9396    (set_attr "length" "4")])
9398 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9399   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9400         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9401               (match_operand 3 "" "g")))
9402    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9403                    UNSPEC_TLSLD)
9404    (clobber (reg:SI LR_REGNO))]
9405   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9407   if (TARGET_CMODEL != CMODEL_SMALL)
9408     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9409            "bl %z2\;nop";
9410   else
9411     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9413   "&& TARGET_TLS_MARKERS"
9414   [(set (match_dup 0)
9415         (unspec:TLSmode [(match_dup 1)]
9416                         UNSPEC_TLSLD))
9417    (parallel [(set (match_dup 0)
9418                    (call (mem:TLSmode (match_dup 2))
9419                          (match_dup 3)))
9420               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9421               (clobber (reg:SI LR_REGNO))])]
9422   ""
9423   [(set_attr "type" "two")
9424    (set (attr "length")
9425      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9426                    (const_int 16)
9427                    (const_int 12)))])
9429 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9430   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9431         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9432               (match_operand 3 "" "g")))
9433    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9434                    UNSPEC_TLSLD)
9435    (clobber (reg:SI LR_REGNO))]
9436   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9438   if (flag_pic)
9439     {
9440       if (TARGET_SECURE_PLT && flag_pic == 2)
9441         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9442       else
9443         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9444     }
9445   else
9446     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9448   "&& TARGET_TLS_MARKERS"
9449   [(set (match_dup 0)
9450         (unspec:TLSmode [(match_dup 1)]
9451                         UNSPEC_TLSLD))
9452    (parallel [(set (match_dup 0)
9453                    (call (mem:TLSmode (match_dup 2))
9454                          (match_dup 3)))
9455               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9456               (clobber (reg:SI LR_REGNO))])]
9457   ""
9458   [(set_attr "length" "8")])
9460 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9461   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9462         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9463                         UNSPEC_TLSLD))]
9464   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9465   "addi %0,%1,%&@got@tlsld"
9466   "&& TARGET_CMODEL != CMODEL_SMALL"
9467   [(set (match_dup 2)
9468         (high:TLSmode
9469             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9470    (set (match_dup 0)
9471         (lo_sum:TLSmode (match_dup 2)
9472             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9474   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9476   [(set (attr "length")
9477      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9478                    (const_int 8)
9479                    (const_int 4)))])
9481 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9482   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9483      (high:TLSmode
9484        (unspec:TLSmode [(const_int 0)
9485                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9486                        UNSPEC_TLSLD)))]
9487   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9488   "addis %0,%1,%&@got@tlsld@ha"
9489   [(set_attr "length" "4")])
9491 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9492   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9493      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9494        (unspec:TLSmode [(const_int 0)
9495                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9496                        UNSPEC_TLSLD)))]
9497   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9498   "addi %0,%1,%&@got@tlsld@l"
9499   [(set_attr "length" "4")])
9501 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9502   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9503         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9504               (match_operand 2 "" "g")))
9505    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9506    (clobber (reg:SI LR_REGNO))]
9507   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9508    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9509   "bl %z1(%&@tlsld)\;nop"
9510   [(set_attr "type" "branch")
9511    (set_attr "length" "8")])
9513 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9514   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9515         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9516               (match_operand 2 "" "g")))
9517    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9518    (clobber (reg:SI LR_REGNO))]
9519   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9521   if (flag_pic)
9522     {
9523       if (TARGET_SECURE_PLT && flag_pic == 2)
9524         return "bl %z1+32768(%&@tlsld)@plt";
9525       return "bl %z1(%&@tlsld)@plt";
9526     }
9527   return "bl %z1(%&@tlsld)";
9529   [(set_attr "type" "branch")
9530    (set_attr "length" "4")])
9532 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9533   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9534         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9535                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9536                         UNSPEC_TLSDTPREL))]
9537   "HAVE_AS_TLS"
9538   "addi %0,%1,%2@dtprel")
9540 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9541   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9542         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9543                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9544                         UNSPEC_TLSDTPRELHA))]
9545   "HAVE_AS_TLS"
9546   "addis %0,%1,%2@dtprel@ha")
9548 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9549   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9550         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9551                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9552                         UNSPEC_TLSDTPRELLO))]
9553   "HAVE_AS_TLS"
9554   "addi %0,%1,%2@dtprel@l")
9556 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9557   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9558         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9559                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9560                         UNSPEC_TLSGOTDTPREL))]
9561   "HAVE_AS_TLS"
9562   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9563   "&& TARGET_CMODEL != CMODEL_SMALL"
9564   [(set (match_dup 3)
9565         (high:TLSmode
9566             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9567    (set (match_dup 0)
9568         (lo_sum:TLSmode (match_dup 3)
9569             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9571   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9573   [(set (attr "length")
9574      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9575                    (const_int 8)
9576                    (const_int 4)))])
9578 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9579   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9580      (high:TLSmode
9581        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9582                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9583                        UNSPEC_TLSGOTDTPREL)))]
9584   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9585   "addis %0,%1,%2@got@dtprel@ha"
9586   [(set_attr "length" "4")])
9588 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9589   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9590      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9591          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9592                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9593                          UNSPEC_TLSGOTDTPREL)))]
9594   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9595   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9596   [(set_attr "length" "4")])
9598 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9599   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9600         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9601                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9602                         UNSPEC_TLSTPREL))]
9603   "HAVE_AS_TLS"
9604   "addi %0,%1,%2@tprel")
9606 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9607   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9608         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9609                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9610                         UNSPEC_TLSTPRELHA))]
9611   "HAVE_AS_TLS"
9612   "addis %0,%1,%2@tprel@ha")
9614 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9615   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9616         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9617                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9618                         UNSPEC_TLSTPRELLO))]
9619   "HAVE_AS_TLS"
9620   "addi %0,%1,%2@tprel@l")
9622 ;; "b" output constraint here and on tls_tls input to support linker tls
9623 ;; optimization.  The linker may edit the instructions emitted by a
9624 ;; tls_got_tprel/tls_tls pair to addis,addi.
9625 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9626   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9627         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9628                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9629                         UNSPEC_TLSGOTTPREL))]
9630   "HAVE_AS_TLS"
9631   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9632   "&& TARGET_CMODEL != CMODEL_SMALL"
9633   [(set (match_dup 3)
9634         (high:TLSmode
9635             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9636    (set (match_dup 0)
9637         (lo_sum:TLSmode (match_dup 3)
9638             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9640   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9642   [(set (attr "length")
9643      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9644                    (const_int 8)
9645                    (const_int 4)))])
9647 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9648   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9649      (high:TLSmode
9650        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9651                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9652                        UNSPEC_TLSGOTTPREL)))]
9653   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9654   "addis %0,%1,%2@got@tprel@ha"
9655   [(set_attr "length" "4")])
9657 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9658   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9659      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9660          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9661                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9662                          UNSPEC_TLSGOTTPREL)))]
9663   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9664   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9665   [(set_attr "length" "4")])
9667 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9668   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9669         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9670                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9671                         UNSPEC_TLSTLS))]
9672   "TARGET_ELF && HAVE_AS_TLS"
9673   "add %0,%1,%2@tls")
9675 (define_expand "tls_get_tpointer"
9676   [(set (match_operand:SI 0 "gpc_reg_operand")
9677         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9678   "TARGET_XCOFF && HAVE_AS_TLS"
9680   emit_insn (gen_tls_get_tpointer_internal ());
9681   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9682   DONE;
9685 (define_insn "tls_get_tpointer_internal"
9686   [(set (reg:SI 3)
9687         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9688    (clobber (reg:SI LR_REGNO))]
9689   "TARGET_XCOFF && HAVE_AS_TLS"
9690   "bla __get_tpointer")
9692 (define_expand "tls_get_addr<mode>"
9693   [(set (match_operand:P 0 "gpc_reg_operand")
9694         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9695                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9696   "TARGET_XCOFF && HAVE_AS_TLS"
9698   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9699   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9700   emit_insn (gen_tls_get_addr_internal<mode> ());
9701   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9702   DONE;
9705 (define_insn "tls_get_addr_internal<mode>"
9706   [(set (reg:P 3)
9707         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9708    (clobber (reg:P 0))
9709    (clobber (reg:P 4))
9710    (clobber (reg:P 5))
9711    (clobber (reg:P 11))
9712    (clobber (reg:CC CR0_REGNO))
9713    (clobber (reg:P LR_REGNO))]
9714   "TARGET_XCOFF && HAVE_AS_TLS"
9715   "bla __tls_get_addr")
9717 ;; Next come insns related to the calling sequence.
9719 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9720 ;; We move the back-chain and decrement the stack pointer.
9722 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9723 ;; constant alloca, using that predicate will force the generic code to put
9724 ;; the constant size into a register before calling the expander.
9726 ;; As a result the expander would not have the constant size information
9727 ;; in those cases and would have to generate less efficient code.
9729 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9730 ;; the constant size.  The value is forced into a register if necessary.
9732 (define_expand "allocate_stack"
9733   [(set (match_operand 0 "gpc_reg_operand")
9734         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9735    (set (reg 1)
9736         (minus (reg 1) (match_dup 1)))]
9737   ""
9739   rtx chain = gen_reg_rtx (Pmode);
9740   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9741   rtx neg_op0;
9742   rtx insn, par, set, mem;
9744   /* By allowing reg_or_cint_operand as the predicate we can get
9745      better code for stack-clash-protection because we do not lose
9746      size information.  But the rest of the code expects the operand
9747      to be reg_or_short_operand.  If it isn't, then force it into
9748      a register.  */
9749   rtx orig_op1 = operands[1];
9750   if (!reg_or_short_operand (operands[1], Pmode))
9751     operands[1] = force_reg (Pmode, operands[1]);
9753   emit_move_insn (chain, stack_bot);
9755   /* Check stack bounds if necessary.  */
9756   if (crtl->limit_stack)
9757     {
9758       rtx available;
9759       available = expand_binop (Pmode, sub_optab,
9760                                 stack_pointer_rtx, stack_limit_rtx,
9761                                 NULL_RTX, 1, OPTAB_WIDEN);
9762       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9763     }
9765   /* Allocate and probe if requested.
9766      This may look similar to the loop we use for prologue allocations,
9767      but it is critically different.  For the former we know the loop
9768      will iterate, but do not know that generally here.  The former
9769      uses that knowledge to rotate the loop.  Combining them would be
9770      possible with some performance cost.  */
9771   if (flag_stack_clash_protection)
9772     {
9773       rtx rounded_size, last_addr, residual;
9774       HOST_WIDE_INT probe_interval;
9775       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9776                                                 &residual, &probe_interval,
9777                                                 orig_op1);
9778       
9779       /* We do occasionally get in here with constant sizes, we might
9780          as well do a reasonable job when we obviously can.  */
9781       if (rounded_size != const0_rtx)
9782         {
9783           rtx loop_lab, end_loop;
9784           bool rotated = CONST_INT_P (rounded_size);
9785           rtx update = GEN_INT (-probe_interval);
9786           if (probe_interval > 32768)
9787             update = force_reg (Pmode, update);
9789           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9790                                                         last_addr, rotated);
9792           if (Pmode == SImode)
9793             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9794                                                stack_pointer_rtx,
9795                                                update, chain));
9796           else
9797             emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9798                                                   stack_pointer_rtx,
9799                                                   update, chain));
9800           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9801                                                       last_addr, rotated);
9802         }
9804       /* Now handle residuals.  We just have to set operands[1] correctly
9805          and let the rest of the expander run.  */
9806       operands[1] = residual;
9807     }
9809   if (!(CONST_INT_P (operands[1])
9810         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9811     {
9812       operands[1] = force_reg (Pmode, operands[1]);
9813       neg_op0 = gen_reg_rtx (Pmode);
9814       if (TARGET_32BIT)
9815         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9816       else
9817         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9818     }
9819   else
9820     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9822   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9823                                        : gen_movdi_di_update_stack))
9824                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9825                          chain));
9826   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9827      it now and set the alias set/attributes. The above gen_*_update
9828      calls will generate a PARALLEL with the MEM set being the first
9829      operation. */
9830   par = PATTERN (insn);
9831   gcc_assert (GET_CODE (par) == PARALLEL);
9832   set = XVECEXP (par, 0, 0);
9833   gcc_assert (GET_CODE (set) == SET);
9834   mem = SET_DEST (set);
9835   gcc_assert (MEM_P (mem));
9836   MEM_NOTRAP_P (mem) = 1;
9837   set_mem_alias_set (mem, get_frame_alias_set ());
9839   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9840   DONE;
9843 ;; These patterns say how to save and restore the stack pointer.  We need not
9844 ;; save the stack pointer at function level since we are careful to
9845 ;; preserve the backchain.  At block level, we have to restore the backchain
9846 ;; when we restore the stack pointer.
9848 ;; For nonlocal gotos, we must save both the stack pointer and its
9849 ;; backchain and restore both.  Note that in the nonlocal case, the
9850 ;; save area is a memory location.
9852 (define_expand "save_stack_function"
9853   [(match_operand 0 "any_operand")
9854    (match_operand 1 "any_operand")]
9855   ""
9856   "DONE;")
9858 (define_expand "restore_stack_function"
9859   [(match_operand 0 "any_operand")
9860    (match_operand 1 "any_operand")]
9861   ""
9862   "DONE;")
9864 ;; Adjust stack pointer (op0) to a new value (op1).
9865 ;; First copy old stack backchain to new location, and ensure that the
9866 ;; scheduler won't reorder the sp assignment before the backchain write.
9867 (define_expand "restore_stack_block"
9868   [(set (match_dup 2) (match_dup 3))
9869    (set (match_dup 4) (match_dup 2))
9870    (match_dup 5)
9871    (set (match_operand 0 "register_operand")
9872         (match_operand 1 "register_operand"))]
9873   ""
9875   rtvec p;
9877   operands[1] = force_reg (Pmode, operands[1]);
9878   operands[2] = gen_reg_rtx (Pmode);
9879   operands[3] = gen_frame_mem (Pmode, operands[0]);
9880   operands[4] = gen_frame_mem (Pmode, operands[1]);
9881   p = rtvec_alloc (1);
9882   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9883                                   const0_rtx);
9884   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9887 (define_expand "save_stack_nonlocal"
9888   [(set (match_dup 3) (match_dup 4))
9889    (set (match_operand 0 "memory_operand") (match_dup 3))
9890    (set (match_dup 2) (match_operand 1 "register_operand"))]
9891   ""
9893   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9895   /* Copy the backchain to the first word, sp to the second.  */
9896   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9897   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9898   operands[3] = gen_reg_rtx (Pmode);
9899   operands[4] = gen_frame_mem (Pmode, operands[1]);
9902 (define_expand "restore_stack_nonlocal"
9903   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9904    (set (match_dup 3) (match_dup 4))
9905    (set (match_dup 5) (match_dup 2))
9906    (match_dup 6)
9907    (set (match_operand 0 "register_operand") (match_dup 3))]
9908   ""
9910   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9911   rtvec p;
9913   /* Restore the backchain from the first word, sp from the second.  */
9914   operands[2] = gen_reg_rtx (Pmode);
9915   operands[3] = gen_reg_rtx (Pmode);
9916   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9917   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9918   operands[5] = gen_frame_mem (Pmode, operands[3]);
9919   p = rtvec_alloc (1);
9920   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9921                                   const0_rtx);
9922   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9925 ;; TOC register handling.
9927 ;; Code to initialize the TOC register...
9929 (define_insn "load_toc_aix_si"
9930   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9931                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9932               (use (reg:SI 2))])]
9933   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9935   char buf[30];
9936   extern int need_toc_init;
9937   need_toc_init = 1;
9938   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9939   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9940   operands[2] = gen_rtx_REG (Pmode, 2);
9941   return "lwz %0,%1(%2)";
9943   [(set_attr "type" "load")
9944    (set_attr "update" "no")
9945    (set_attr "indexed" "no")])
9947 (define_insn "load_toc_aix_di"
9948   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9949                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9950               (use (reg:DI 2))])]
9951   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9953   char buf[30];
9954   extern int need_toc_init;
9955   need_toc_init = 1;
9956   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9957                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
9958   if (TARGET_ELF)
9959     strcat (buf, "@toc");
9960   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9961   operands[2] = gen_rtx_REG (Pmode, 2);
9962   return "ld %0,%1(%2)";
9964   [(set_attr "type" "load")
9965    (set_attr "update" "no")
9966    (set_attr "indexed" "no")])
9968 (define_insn "load_toc_v4_pic_si"
9969   [(set (reg:SI LR_REGNO)
9970         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9971   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9972   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9973   [(set_attr "type" "branch")
9974    (set_attr "length" "4")])
9976 (define_expand "load_toc_v4_PIC_1"
9977   [(parallel [(set (reg:SI LR_REGNO)
9978                    (match_operand:SI 0 "immediate_operand" "s"))
9979               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9980   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9981    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9982   "")
9984 (define_insn "load_toc_v4_PIC_1_normal"
9985   [(set (reg:SI LR_REGNO)
9986         (match_operand:SI 0 "immediate_operand" "s"))
9987    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9988   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9989    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9990   "bcl 20,31,%0\n%0:"
9991   [(set_attr "type" "branch")
9992    (set_attr "length" "4")
9993    (set_attr "cannot_copy" "yes")])
9995 (define_insn "load_toc_v4_PIC_1_476"
9996   [(set (reg:SI LR_REGNO)
9997         (match_operand:SI 0 "immediate_operand" "s"))
9998    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9999   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10000    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10002   char name[32];
10003   static char templ[32];
10005   get_ppc476_thunk_name (name);
10006   sprintf (templ, "bl %s\n%%0:", name);
10007   return templ;
10009   [(set_attr "type" "branch")
10010    (set_attr "length" "4")
10011    (set_attr "cannot_copy" "yes")])
10013 (define_expand "load_toc_v4_PIC_1b"
10014   [(parallel [(set (reg:SI LR_REGNO)
10015                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10016                                (label_ref (match_operand 1 ""))]
10017                            UNSPEC_TOCPTR))
10018               (match_dup 1)])]
10019   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10020   "")
10022 (define_insn "load_toc_v4_PIC_1b_normal"
10023   [(set (reg:SI LR_REGNO)
10024         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10025                     (label_ref (match_operand 1 "" ""))]
10026                 UNSPEC_TOCPTR))
10027    (match_dup 1)]
10028   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10029   "bcl 20,31,$+8\;.long %0-$"
10030   [(set_attr "type" "branch")
10031    (set_attr "length" "8")])
10033 (define_insn "load_toc_v4_PIC_1b_476"
10034   [(set (reg:SI LR_REGNO)
10035         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10036                     (label_ref (match_operand 1 "" ""))]
10037                 UNSPEC_TOCPTR))
10038    (match_dup 1)]
10039   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10041   char name[32];
10042   static char templ[32];
10044   get_ppc476_thunk_name (name);
10045   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10046   return templ;
10048   [(set_attr "type" "branch")
10049    (set_attr "length" "16")])
10051 (define_insn "load_toc_v4_PIC_2"
10052   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10053         (mem:SI (plus:SI
10054                   (match_operand:SI 1 "gpc_reg_operand" "b")
10055                   (const
10056                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10057                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10058   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10059   "lwz %0,%2-%3(%1)"
10060   [(set_attr "type" "load")])
10062 (define_insn "load_toc_v4_PIC_3b"
10063   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10064         (plus:SI
10065           (match_operand:SI 1 "gpc_reg_operand" "b")
10066           (high:SI
10067             (const
10068               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10069                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10070   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10071   "addis %0,%1,%2-%3@ha")
10073 (define_insn "load_toc_v4_PIC_3c"
10074   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10075         (lo_sum:SI
10076           (match_operand:SI 1 "gpc_reg_operand" "b")
10077           (const
10078             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10079                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10080   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10081   "addi %0,%1,%2-%3@l")
10083 ;; If the TOC is shared over a translation unit, as happens with all
10084 ;; the kinds of PIC that we support, we need to restore the TOC
10085 ;; pointer only when jumping over units of translation.
10086 ;; On Darwin, we need to reload the picbase.
10088 (define_expand "builtin_setjmp_receiver"
10089   [(use (label_ref (match_operand 0 "")))]
10090   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10091    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10092    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10094 #if TARGET_MACHO
10095   if (DEFAULT_ABI == ABI_DARWIN)
10096     {
10097       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10098       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10099       rtx tmplabrtx;
10100       char tmplab[20];
10102       crtl->uses_pic_offset_table = 1;
10103       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10104                                   CODE_LABEL_NUMBER (operands[0]));
10105       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10107       emit_insn (gen_load_macho_picbase (tmplabrtx));
10108       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10109       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10110     }
10111   else
10112 #endif
10113     rs6000_emit_load_toc_table (FALSE);
10114   DONE;
10117 ;; Largetoc support
10118 (define_insn "*largetoc_high"
10119   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10120         (high:DI
10121           (unspec [(match_operand:DI 1 "" "")
10122                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10123                   UNSPEC_TOCREL)))]
10124    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10125    "addis %0,%2,%1@toc@ha")
10127 (define_insn "*largetoc_high_aix<mode>"
10128   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10129         (high:P
10130           (unspec [(match_operand:P 1 "" "")
10131                    (match_operand:P 2 "gpc_reg_operand" "b")]
10132                   UNSPEC_TOCREL)))]
10133    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10134    "addis %0,%1@u(%2)")
10136 (define_insn "*largetoc_high_plus"
10137   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10138         (high:DI
10139           (plus:DI
10140             (unspec [(match_operand:DI 1 "" "")
10141                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10142                     UNSPEC_TOCREL)
10143             (match_operand:DI 3 "add_cint_operand" "n"))))]
10144    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10145    "addis %0,%2,%1+%3@toc@ha")
10147 (define_insn "*largetoc_high_plus_aix<mode>"
10148   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10149         (high:P
10150           (plus:P
10151             (unspec [(match_operand:P 1 "" "")
10152                      (match_operand:P 2 "gpc_reg_operand" "b")]
10153                     UNSPEC_TOCREL)
10154             (match_operand:P 3 "add_cint_operand" "n"))))]
10155    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10156    "addis %0,%1+%3@u(%2)")
10158 (define_insn "*largetoc_low"
10159   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10160         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10161                    (match_operand:DI 2 "" "")))]
10162    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10163    "addi %0,%1,%2@l")
10165 (define_insn "*largetoc_low_aix<mode>"
10166   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10167         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10168                    (match_operand:P 2 "" "")))]
10169    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10170    "la %0,%2@l(%1)")
10172 (define_insn_and_split "*tocref<mode>"
10173   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10174         (match_operand:P 1 "small_toc_ref" "R"))]
10175    "TARGET_TOC"
10176    "la %0,%a1"
10177    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10178   [(set (match_dup 0) (high:P (match_dup 1)))
10179    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10181 ;; Elf specific ways of loading addresses for non-PIC code.
10182 ;; The output of this could be r0, but we make a very strong
10183 ;; preference for a base register because it will usually
10184 ;; be needed there.
10185 (define_insn "elf_high"
10186   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10187         (high:SI (match_operand 1 "" "")))]
10188   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10189   "lis %0,%1@ha")
10191 (define_insn "elf_low"
10192   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10193         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10194                    (match_operand 2 "" "")))]
10195    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10196    "la %0,%2@l(%1)")
10198 ;; Call and call_value insns
10199 (define_expand "call"
10200   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10201                     (match_operand 1 ""))
10202               (use (match_operand 2 ""))
10203               (clobber (reg:SI LR_REGNO))])]
10204   ""
10206 #if TARGET_MACHO
10207   if (MACHOPIC_INDIRECT)
10208     operands[0] = machopic_indirect_call_target (operands[0]);
10209 #endif
10211   gcc_assert (GET_CODE (operands[0]) == MEM);
10212   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10214   operands[0] = XEXP (operands[0], 0);
10216   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10217     {
10218       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10219       DONE;
10220     }
10222   if (GET_CODE (operands[0]) != SYMBOL_REF
10223       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10224     {
10225       if (INTVAL (operands[2]) & CALL_LONG)
10226         operands[0] = rs6000_longcall_ref (operands[0]);
10228       switch (DEFAULT_ABI)
10229         {
10230         case ABI_V4:
10231         case ABI_DARWIN:
10232           operands[0] = force_reg (Pmode, operands[0]);
10233           break;
10235         default:
10236           gcc_unreachable ();
10237         }
10238     }
10241 (define_expand "call_value"
10242   [(parallel [(set (match_operand 0 "")
10243                    (call (mem:SI (match_operand 1 "address_operand"))
10244                          (match_operand 2 "")))
10245               (use (match_operand 3 ""))
10246               (clobber (reg:SI LR_REGNO))])]
10247   ""
10249 #if TARGET_MACHO
10250   if (MACHOPIC_INDIRECT)
10251     operands[1] = machopic_indirect_call_target (operands[1]);
10252 #endif
10254   gcc_assert (GET_CODE (operands[1]) == MEM);
10255   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10257   operands[1] = XEXP (operands[1], 0);
10259   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10260     {
10261       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10262       DONE;
10263     }
10265   if (GET_CODE (operands[1]) != SYMBOL_REF
10266       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10267     {
10268       if (INTVAL (operands[3]) & CALL_LONG)
10269         operands[1] = rs6000_longcall_ref (operands[1]);
10271       switch (DEFAULT_ABI)
10272         {
10273         case ABI_V4:
10274         case ABI_DARWIN:
10275           operands[1] = force_reg (Pmode, operands[1]);
10276           break;
10278         default:
10279           gcc_unreachable ();
10280         }
10281     }
10284 ;; Call to function in current module.  No TOC pointer reload needed.
10285 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10286 ;; either the function was not prototyped, or it was prototyped as a
10287 ;; variable argument function.  It is > 0 if FP registers were passed
10288 ;; and < 0 if they were not.
10290 (define_insn "*call_local32"
10291   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10292          (match_operand 1 "" "g,g"))
10293    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10294    (clobber (reg:SI LR_REGNO))]
10295   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10297   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10298     output_asm_insn ("crxor 6,6,6", operands);
10300   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10301     output_asm_insn ("creqv 6,6,6", operands);
10303   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10305   [(set_attr "type" "branch")
10306    (set_attr "length" "4,8")])
10308 (define_insn "*call_local64"
10309   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10310          (match_operand 1 "" "g,g"))
10311    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10312    (clobber (reg:SI LR_REGNO))]
10313   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10315   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10316     output_asm_insn ("crxor 6,6,6", operands);
10318   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10319     output_asm_insn ("creqv 6,6,6", operands);
10321   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10323   [(set_attr "type" "branch")
10324    (set_attr "length" "4,8")])
10326 (define_insn "*call_value_local32"
10327   [(set (match_operand 0 "" "")
10328         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10329               (match_operand 2 "" "g,g")))
10330    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10331    (clobber (reg:SI LR_REGNO))]
10332   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10334   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10335     output_asm_insn ("crxor 6,6,6", operands);
10337   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10338     output_asm_insn ("creqv 6,6,6", operands);
10340   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10342   [(set_attr "type" "branch")
10343    (set_attr "length" "4,8")])
10346 (define_insn "*call_value_local64"
10347   [(set (match_operand 0 "" "")
10348         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10349               (match_operand 2 "" "g,g")))
10350    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10351    (clobber (reg:SI LR_REGNO))]
10352   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10354   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10355     output_asm_insn ("crxor 6,6,6", operands);
10357   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10358     output_asm_insn ("creqv 6,6,6", operands);
10360   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10362   [(set_attr "type" "branch")
10363    (set_attr "length" "4,8")])
10366 ;; A function pointer under System V is just a normal pointer
10367 ;; operands[0] is the function pointer
10368 ;; operands[1] is the stack size to clean up
10369 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10370 ;; which indicates how to set cr1
10372 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10373   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10374          (match_operand 1 "" "g,g,g,g"))
10375    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10376    (clobber (reg:SI LR_REGNO))]
10377   "DEFAULT_ABI == ABI_V4
10378    || DEFAULT_ABI == ABI_DARWIN"
10380   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10381     output_asm_insn ("crxor 6,6,6", operands);
10383   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10384     output_asm_insn ("creqv 6,6,6", operands);
10386   if (rs6000_speculate_indirect_jumps
10387       || which_alternative == 1 || which_alternative == 3)
10388     return "b%T0l";
10389   else
10390     return "crset 2\;beq%T0l-";
10392   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10393    (set (attr "length")
10394         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10395                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10396                         (const_int 0)))
10397                   (const_string "8")
10398                (and (eq (symbol_ref "which_alternative") (const_int 2))
10399                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10400                         (const_int 0)))
10401                   (const_string "8")
10402                (and (eq (symbol_ref "which_alternative") (const_int 2))
10403                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10404                         (const_int 0)))
10405                   (const_string "12")
10406                (eq (symbol_ref "which_alternative") (const_int 3))
10407                   (const_string "8")]
10408               (const_string "4")))])
10410 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10411   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10412          (match_operand 1 "" "g,g"))
10413    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10414    (clobber (reg:SI LR_REGNO))]
10415   "(DEFAULT_ABI == ABI_DARWIN
10416    || (DEFAULT_ABI == ABI_V4
10417        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10419   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10420     output_asm_insn ("crxor 6,6,6", operands);
10422   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10423     output_asm_insn ("creqv 6,6,6", operands);
10425 #if TARGET_MACHO
10426   return output_call(insn, operands, 0, 2);
10427 #else
10428   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10429     {
10430       gcc_assert (!TARGET_SECURE_PLT);
10431       return "bl %z0@plt";
10432     }
10433   else
10434     return "bl %z0";
10435 #endif
10437   "DEFAULT_ABI == ABI_V4
10438    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10439    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10440   [(parallel [(call (mem:SI (match_dup 0))
10441                     (match_dup 1))
10442               (use (match_dup 2))
10443               (use (match_dup 3))
10444               (clobber (reg:SI LR_REGNO))])]
10446   operands[3] = pic_offset_table_rtx;
10448   [(set_attr "type" "branch,branch")
10449    (set_attr "length" "4,8")])
10451 (define_insn "*call_nonlocal_sysv_secure<mode>"
10452   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10453          (match_operand 1 "" "g,g"))
10454    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10455    (use (match_operand:SI 3 "register_operand" "r,r"))
10456    (clobber (reg:SI LR_REGNO))]
10457   "(DEFAULT_ABI == ABI_V4
10458     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10459     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10461   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10462     output_asm_insn ("crxor 6,6,6", operands);
10464   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10465     output_asm_insn ("creqv 6,6,6", operands);
10467   if (flag_pic == 2)
10468     /* The magic 32768 offset here and in the other sysv call insns
10469        corresponds to the offset of r30 in .got2, as given by LCTOC1.
10470        See sysv4.h:toc_section.  */
10471     return "bl %z0+32768@plt";
10472   else
10473     return "bl %z0@plt";
10475   [(set_attr "type" "branch,branch")
10476    (set_attr "length" "4,8")])
10478 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10479   [(set (match_operand 0 "" "")
10480         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10481               (match_operand 2 "" "g,g,g,g")))
10482    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10483    (clobber (reg:SI LR_REGNO))]
10484   "DEFAULT_ABI == ABI_V4
10485    || DEFAULT_ABI == ABI_DARWIN"
10487   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10488     output_asm_insn ("crxor 6,6,6", operands);
10490   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10491     output_asm_insn ("creqv 6,6,6", operands);
10493   if (rs6000_speculate_indirect_jumps
10494       || which_alternative == 1 || which_alternative == 3)
10495     return "b%T1l";
10496   else
10497     return "crset 2\;beq%T1l-";
10499   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10500    (set (attr "length")
10501         (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10502                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10503                         (const_int 0)))
10504                   (const_string "8")
10505                (and (eq (symbol_ref "which_alternative") (const_int 2))
10506                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10507                         (const_int 0)))
10508                   (const_string "8")
10509                (and (eq (symbol_ref "which_alternative") (const_int 2))
10510                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10511                         (const_int 0)))
10512                   (const_string "12")
10513                (eq (symbol_ref "which_alternative") (const_int 3))
10514                   (const_string "8")]
10515               (const_string "4")))])
10517 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10518   [(set (match_operand 0 "" "")
10519         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10520               (match_operand 2 "" "g,g")))
10521    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10522    (clobber (reg:SI LR_REGNO))]
10523   "(DEFAULT_ABI == ABI_DARWIN
10524    || (DEFAULT_ABI == ABI_V4
10525        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10527   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10528     output_asm_insn ("crxor 6,6,6", operands);
10530   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10531     output_asm_insn ("creqv 6,6,6", operands);
10533 #if TARGET_MACHO
10534   return output_call(insn, operands, 1, 3);
10535 #else
10536   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10537     {
10538       gcc_assert (!TARGET_SECURE_PLT);
10539       return "bl %z1@plt";
10540     }
10541   else
10542     return "bl %z1";
10543 #endif
10545   "DEFAULT_ABI == ABI_V4
10546    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10547    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10548   [(parallel [(set (match_dup 0)
10549                    (call (mem:SI (match_dup 1))
10550                          (match_dup 2)))
10551               (use (match_dup 3))
10552               (use (match_dup 4))
10553               (clobber (reg:SI LR_REGNO))])]
10555   operands[4] = pic_offset_table_rtx;
10557   [(set_attr "type" "branch,branch")
10558    (set_attr "length" "4,8")])
10560 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10561   [(set (match_operand 0 "" "")
10562         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10563               (match_operand 2 "" "g,g")))
10564    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10565    (use (match_operand:SI 4 "register_operand" "r,r"))
10566    (clobber (reg:SI LR_REGNO))]
10567   "(DEFAULT_ABI == ABI_V4
10568     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10569     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10571   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10572     output_asm_insn ("crxor 6,6,6", operands);
10574   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10575     output_asm_insn ("creqv 6,6,6", operands);
10577   if (flag_pic == 2)
10578     return "bl %z1+32768@plt";
10579   else
10580     return "bl %z1@plt";
10582   [(set_attr "type" "branch,branch")
10583    (set_attr "length" "4,8")])
10586 ;; Call to AIX abi function in the same module.
10588 (define_insn "*call_local_aix<mode>"
10589   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10590          (match_operand 1 "" "g"))
10591    (clobber (reg:P LR_REGNO))]
10592   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10593   "bl %z0"
10594   [(set_attr "type" "branch")
10595    (set_attr "length" "4")])
10597 (define_insn "*call_value_local_aix<mode>"
10598   [(set (match_operand 0 "" "")
10599         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10600               (match_operand 2 "" "g")))
10601    (clobber (reg:P LR_REGNO))]
10602   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10603   "bl %z1"
10604   [(set_attr "type" "branch")
10605    (set_attr "length" "4")])
10607 ;; Call to AIX abi function which may be in another module.
10608 ;; Restore the TOC pointer (r2) after the call.
10610 (define_insn "*call_nonlocal_aix<mode>"
10611   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10612          (match_operand 1 "" "g"))
10613    (clobber (reg:P LR_REGNO))]
10614   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10615   "bl %z0\;nop"
10616   [(set_attr "type" "branch")
10617    (set_attr "length" "8")])
10619 (define_insn "*call_value_nonlocal_aix<mode>"
10620   [(set (match_operand 0 "" "")
10621         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10622               (match_operand 2 "" "g")))
10623    (clobber (reg:P LR_REGNO))]
10624   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10625   "bl %z1\;nop"
10626   [(set_attr "type" "branch")
10627    (set_attr "length" "8")])
10629 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10630 ;; Operand0 is the addresss of the function to call
10631 ;; Operand2 is the location in the function descriptor to load r2 from
10632 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10634 (define_insn "*call_indirect_aix<mode>"
10635   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10636          (match_operand 1 "" "g,g"))
10637    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10638    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10639    (clobber (reg:P LR_REGNO))]
10640   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10641   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10642   [(set_attr "type" "jmpreg")
10643    (set_attr "length" "12")])
10645 (define_insn "*call_indirect_aix<mode>_nospec"
10646   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10647          (match_operand 1 "" "g,g"))
10648    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10649    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10650    (clobber (reg:P LR_REGNO))]
10651   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10652   "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10653   [(set_attr "type" "jmpreg")
10654    (set_attr "length" "16")])
10656 (define_insn "*call_value_indirect_aix<mode>"
10657   [(set (match_operand 0 "" "")
10658         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10659               (match_operand 2 "" "g,g")))
10660    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10661    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10662    (clobber (reg:P LR_REGNO))]
10663   "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10664   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10665   [(set_attr "type" "jmpreg")
10666    (set_attr "length" "12")])
10668 (define_insn "*call_value_indirect_aix<mode>_nospec"
10669   [(set (match_operand 0 "" "")
10670         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10671               (match_operand 2 "" "g,g")))
10672    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10673    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10674    (clobber (reg:P LR_REGNO))]
10675   "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10676   "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10677   [(set_attr "type" "jmpreg")
10678    (set_attr "length" "16")])
10680 ;; Call to indirect functions with the ELFv2 ABI.
10681 ;; Operand0 is the addresss of the function to call
10682 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10684 (define_insn "*call_indirect_elfv2<mode>"
10685   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10686          (match_operand 1 "" "g,g"))
10687    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10688    (clobber (reg:P LR_REGNO))]
10689   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10690   "b%T0l\;<ptrload> 2,%2(1)"
10691   [(set_attr "type" "jmpreg")
10692    (set_attr "length" "8")])
10694 ;; Variant with deliberate misprediction.
10695 (define_insn "*call_indirect_elfv2<mode>_nospec"
10696   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10697          (match_operand 1 "" "g,g"))
10698    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10699    (clobber (reg:P LR_REGNO))]
10700   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10701   "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10702   [(set_attr "type" "jmpreg")
10703    (set_attr "length" "12")])
10705 (define_insn "*call_value_indirect_elfv2<mode>"
10706   [(set (match_operand 0 "" "")
10707         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10708               (match_operand 2 "" "g,g")))
10709    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10710    (clobber (reg:P LR_REGNO))]
10711   "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10712   "b%T1l\;<ptrload> 2,%3(1)"
10713   [(set_attr "type" "jmpreg")
10714    (set_attr "length" "8")])
10716 ; Variant with deliberate misprediction.
10717 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10718   [(set (match_operand 0 "" "")
10719         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10720               (match_operand 2 "" "g,g")))
10721    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10722    (clobber (reg:P LR_REGNO))]
10723   "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10724   "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10725   [(set_attr "type" "jmpreg")
10726    (set_attr "length" "12")])
10728 ;; Call subroutine returning any type.
10729 (define_expand "untyped_call"
10730   [(parallel [(call (match_operand 0 "")
10731                     (const_int 0))
10732               (match_operand 1 "")
10733               (match_operand 2 "")])]
10734   ""
10736   int i;
10738   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10740   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10741     {
10742       rtx set = XVECEXP (operands[2], 0, i);
10743       emit_move_insn (SET_DEST (set), SET_SRC (set));
10744     }
10746   /* The optimizer does not know that the call sets the function value
10747      registers we stored in the result block.  We avoid problems by
10748      claiming that all hard registers are used and clobbered at this
10749      point.  */
10750   emit_insn (gen_blockage ());
10752   DONE;
10755 ;; sibling call patterns
10756 (define_expand "sibcall"
10757   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10758                     (match_operand 1 ""))
10759               (use (match_operand 2 ""))
10760               (simple_return)])]
10761   ""
10763 #if TARGET_MACHO
10764   if (MACHOPIC_INDIRECT)
10765     operands[0] = machopic_indirect_call_target (operands[0]);
10766 #endif
10768   gcc_assert (GET_CODE (operands[0]) == MEM);
10769   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10771   operands[0] = XEXP (operands[0], 0);
10773   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10774     {
10775       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10776       DONE;
10777     }
10780 (define_expand "sibcall_value"
10781   [(parallel [(set (match_operand 0 "register_operand")
10782                 (call (mem:SI (match_operand 1 "address_operand"))
10783                       (match_operand 2 "")))
10784               (use (match_operand 3 ""))
10785               (simple_return)])]
10786   ""
10788 #if TARGET_MACHO
10789   if (MACHOPIC_INDIRECT)
10790     operands[1] = machopic_indirect_call_target (operands[1]);
10791 #endif
10793   gcc_assert (GET_CODE (operands[1]) == MEM);
10794   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10796   operands[1] = XEXP (operands[1], 0);
10798   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10799     {
10800       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10801       DONE;
10802     }
10805 (define_insn "*sibcall_local32"
10806   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10807          (match_operand 1 "" "g,g"))
10808    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10809    (simple_return)]
10810   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10812   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10813     output_asm_insn ("crxor 6,6,6", operands);
10815   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10816     output_asm_insn ("creqv 6,6,6", operands);
10818   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10820   [(set_attr "type" "branch")
10821    (set_attr "length" "4,8")])
10823 (define_insn "*sibcall_local64"
10824   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10825          (match_operand 1 "" "g,g"))
10826    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10827    (simple_return)]
10828   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10830   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10831     output_asm_insn ("crxor 6,6,6", operands);
10833   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10834     output_asm_insn ("creqv 6,6,6", operands);
10836   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10838   [(set_attr "type" "branch")
10839    (set_attr "length" "4,8")])
10841 (define_insn "*sibcall_value_local32"
10842   [(set (match_operand 0 "" "")
10843         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10844               (match_operand 2 "" "g,g")))
10845    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10846    (simple_return)]
10847   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10849   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10850     output_asm_insn ("crxor 6,6,6", operands);
10852   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10853     output_asm_insn ("creqv 6,6,6", operands);
10855   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10857   [(set_attr "type" "branch")
10858    (set_attr "length" "4,8")])
10860 (define_insn "*sibcall_value_local64"
10861   [(set (match_operand 0 "" "")
10862         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10863               (match_operand 2 "" "g,g")))
10864    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10865    (simple_return)]
10866   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10868   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10869     output_asm_insn ("crxor 6,6,6", operands);
10871   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10872     output_asm_insn ("creqv 6,6,6", operands);
10874   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10876   [(set_attr "type" "branch")
10877    (set_attr "length" "4,8")])
10879 (define_insn "*sibcall_nonlocal_sysv<mode>"
10880   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10881          (match_operand 1 "" ""))
10882    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10883    (simple_return)]
10884   "(DEFAULT_ABI == ABI_DARWIN
10885     || DEFAULT_ABI == ABI_V4)
10886    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10888   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10889     output_asm_insn ("crxor 6,6,6", operands);
10891   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10892     output_asm_insn ("creqv 6,6,6", operands);
10894   if (which_alternative >= 2)
10895     {
10896       if (rs6000_speculate_indirect_jumps)
10897         return "b%T0";
10898       else
10899         /* Can use CR0 since it is volatile across sibcalls.  */
10900         return "crset 2\;beq%T0-\;b $";
10901     }
10902   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10903     {
10904       gcc_assert (!TARGET_SECURE_PLT);
10905       return "b %z0@plt";
10906     }
10907   else
10908     return "b %z0";
10910   [(set_attr "type" "branch")
10911    (set (attr "length")
10912         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10913                   (const_string "8")
10914                (and (eq (symbol_ref "which_alternative") (const_int 2))
10915                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10916                         (const_int 0)))
10917                   (const_string "12")
10918                (and (eq (symbol_ref "which_alternative") (const_int 3))
10919                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10920                         (const_int 0)))
10921                   (const_string "8")
10922                (and (eq (symbol_ref "which_alternative") (const_int 3))
10923                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10924                         (const_int 0)))
10925                   (const_string "16")]
10926               (const_string "4")))])
10928 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10929   [(set (match_operand 0 "" "")
10930         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10931               (match_operand 2 "" "")))
10932    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10933    (simple_return)]
10934   "(DEFAULT_ABI == ABI_DARWIN
10935     || DEFAULT_ABI == ABI_V4)
10936    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10938   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10939     output_asm_insn ("crxor 6,6,6", operands);
10941   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10942     output_asm_insn ("creqv 6,6,6", operands);
10944   if (which_alternative >= 2)
10945     {
10946       if (rs6000_speculate_indirect_jumps)
10947         return "b%T1";
10948       else
10949         /* Can use CR0 since it is volatile across sibcalls.  */
10950         return "crset 2\;beq%T1-\;b $";
10951     }
10952   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10953     {
10954       gcc_assert (!TARGET_SECURE_PLT);
10955       return "b %z1@plt";
10956     }
10957   else
10958     return "b %z1";
10960   [(set_attr "type" "branch")
10961    (set (attr "length")
10962         (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10963                   (const_string "8")
10964                (and (eq (symbol_ref "which_alternative") (const_int 2))
10965                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10966                         (const_int 0)))
10967                   (const_string "12")
10968                (and (eq (symbol_ref "which_alternative") (const_int 3))
10969                     (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10970                         (const_int 0)))
10971                   (const_string "8")
10972                (and (eq (symbol_ref "which_alternative") (const_int 3))
10973                     (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10974                         (const_int 0)))
10975                   (const_string "16")]
10976               (const_string "4")))])
10978 ;; AIX ABI sibling call patterns.
10980 (define_insn "*sibcall_aix<mode>"
10981   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10982          (match_operand 1 "" "g,g"))
10983    (simple_return)]
10984   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10985   "@
10986    b %z0
10987    b%T0"
10988   [(set_attr "type" "branch")
10989    (set_attr "length" "4")])
10991 (define_insn "*sibcall_value_aix<mode>"
10992   [(set (match_operand 0 "" "")
10993         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10994               (match_operand 2 "" "g,g")))
10995    (simple_return)]
10996   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10997   "@
10998    b %z1
10999    b%T1"
11000   [(set_attr "type" "branch")
11001    (set_attr "length" "4")])
11003 (define_expand "sibcall_epilogue"
11004   [(use (const_int 0))]
11005   ""
11007   if (!TARGET_SCHED_PROLOG)
11008     emit_insn (gen_blockage ());
11009   rs6000_emit_epilogue (TRUE);
11010   DONE;
11013 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11014 ;; all of memory.  This blocks insns from being moved across this point.
11016 (define_insn "blockage"
11017   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11018   ""
11019   ""
11020   [(set_attr "length" "0")])
11022 (define_expand "probe_stack_address"
11023   [(use (match_operand 0 "address_operand"))]
11024   ""
11026   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11027   MEM_VOLATILE_P (operands[0]) = 1;
11029   if (TARGET_64BIT)
11030     emit_insn (gen_probe_stack_di (operands[0]));
11031   else
11032     emit_insn (gen_probe_stack_si (operands[0]));
11033   DONE;
11036 (define_insn "probe_stack_<mode>"
11037   [(set (match_operand:P 0 "memory_operand" "=m")
11038         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11039   ""
11041   operands[1] = gen_rtx_REG (Pmode, 0);
11042   return "st<wd>%U0%X0 %1,%0";
11044   [(set_attr "type" "store")
11045    (set (attr "update")
11046         (if_then_else (match_operand 0 "update_address_mem")
11047                       (const_string "yes")
11048                       (const_string "no")))
11049    (set (attr "indexed")
11050         (if_then_else (match_operand 0 "indexed_address_mem")
11051                       (const_string "yes")
11052                       (const_string "no")))
11053    (set_attr "length" "4")])
11055 (define_insn "probe_stack_range<P:mode>"
11056   [(set (match_operand:P 0 "register_operand" "=&r")
11057         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11058                             (match_operand:P 2 "register_operand" "r")
11059                             (match_operand:P 3 "register_operand" "r")]
11060                            UNSPECV_PROBE_STACK_RANGE))]
11061   ""
11062   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11063   [(set_attr "type" "three")])
11065 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11066 ;; signed & unsigned, and one type of branch.
11068 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11069 ;; insns, and branches.
11071 (define_expand "cbranch<mode>4"
11072   [(use (match_operator 0 "comparison_operator"
11073          [(match_operand:GPR 1 "gpc_reg_operand")
11074           (match_operand:GPR 2 "reg_or_short_operand")]))
11075    (use (match_operand 3))]
11076   ""
11078   /* Take care of the possibility that operands[2] might be negative but
11079      this might be a logical operation.  That insn doesn't exist.  */
11080   if (GET_CODE (operands[2]) == CONST_INT
11081       && INTVAL (operands[2]) < 0)
11082     {
11083       operands[2] = force_reg (<MODE>mode, operands[2]);
11084       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11085                                     GET_MODE (operands[0]),
11086                                     operands[1], operands[2]);
11087    }
11089   rs6000_emit_cbranch (<MODE>mode, operands);
11090   DONE;
11093 (define_expand "cbranch<mode>4"
11094   [(use (match_operator 0 "comparison_operator"
11095          [(match_operand:FP 1 "gpc_reg_operand")
11096           (match_operand:FP 2 "gpc_reg_operand")]))
11097    (use (match_operand 3))]
11098   ""
11100   rs6000_emit_cbranch (<MODE>mode, operands);
11101   DONE;
11104 (define_expand "cstore<mode>4_signed"
11105   [(use (match_operator 1 "signed_comparison_operator"
11106          [(match_operand:P 2 "gpc_reg_operand")
11107           (match_operand:P 3 "gpc_reg_operand")]))
11108    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11109   ""
11111   enum rtx_code cond_code = GET_CODE (operands[1]);
11113   rtx op0 = operands[0];
11114   rtx op1 = operands[2];
11115   rtx op2 = operands[3];
11117   if (cond_code == GE || cond_code == LT)
11118     {
11119       cond_code = swap_condition (cond_code);
11120       std::swap (op1, op2);
11121     }
11123   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11124   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11125   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11127   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11128   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11129   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11131   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11133   if (cond_code == LE)
11134     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11135   else
11136     {
11137       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11138       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11139       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11140     }
11142   DONE;
11145 (define_expand "cstore<mode>4_unsigned"
11146   [(use (match_operator 1 "unsigned_comparison_operator"
11147          [(match_operand:P 2 "gpc_reg_operand")
11148           (match_operand:P 3 "reg_or_short_operand")]))
11149    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11150   ""
11152   enum rtx_code cond_code = GET_CODE (operands[1]);
11154   rtx op0 = operands[0];
11155   rtx op1 = operands[2];
11156   rtx op2 = operands[3];
11158   if (cond_code == GEU || cond_code == LTU)
11159     {
11160       cond_code = swap_condition (cond_code);
11161       std::swap (op1, op2);
11162     }
11164   if (!gpc_reg_operand (op1, <MODE>mode))
11165     op1 = force_reg (<MODE>mode, op1);
11166   if (!reg_or_short_operand (op2, <MODE>mode))
11167     op2 = force_reg (<MODE>mode, op2);
11169   rtx tmp = gen_reg_rtx (<MODE>mode);
11170   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11172   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11173   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11175   if (cond_code == LEU)
11176     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11177   else
11178     emit_insn (gen_neg<mode>2 (op0, tmp2));
11180   DONE;
11183 (define_expand "cstore_si_as_di"
11184   [(use (match_operator 1 "unsigned_comparison_operator"
11185          [(match_operand:SI 2 "gpc_reg_operand")
11186           (match_operand:SI 3 "reg_or_short_operand")]))
11187    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11188   ""
11190   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11191   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11193   operands[2] = force_reg (SImode, operands[2]);
11194   operands[3] = force_reg (SImode, operands[3]);
11195   rtx op1 = gen_reg_rtx (DImode);
11196   rtx op2 = gen_reg_rtx (DImode);
11197   convert_move (op1, operands[2], uns_flag);
11198   convert_move (op2, operands[3], uns_flag);
11200   if (cond_code == GT || cond_code == LE)
11201     {
11202       cond_code = swap_condition (cond_code);
11203       std::swap (op1, op2);
11204     }
11206   rtx tmp = gen_reg_rtx (DImode);
11207   rtx tmp2 = gen_reg_rtx (DImode);
11208   emit_insn (gen_subdi3 (tmp, op1, op2));
11209   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11211   rtx tmp3;
11212   switch (cond_code)
11213     {
11214     default:
11215       gcc_unreachable ();
11216     case LT:
11217       tmp3 = tmp2;
11218       break;
11219     case GE:
11220       tmp3 = gen_reg_rtx (DImode);
11221       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11222       break;
11223     }
11225   convert_move (operands[0], tmp3, 1);
11227   DONE;
11230 (define_expand "cstore<mode>4_signed_imm"
11231   [(use (match_operator 1 "signed_comparison_operator"
11232          [(match_operand:GPR 2 "gpc_reg_operand")
11233           (match_operand:GPR 3 "immediate_operand")]))
11234    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11235   ""
11237   bool invert = false;
11239   enum rtx_code cond_code = GET_CODE (operands[1]);
11241   rtx op0 = operands[0];
11242   rtx op1 = operands[2];
11243   HOST_WIDE_INT val = INTVAL (operands[3]);
11245   if (cond_code == GE || cond_code == GT)
11246     {
11247       cond_code = reverse_condition (cond_code);
11248       invert = true;
11249     }
11251   if (cond_code == LE)
11252     val++;
11254   rtx tmp = gen_reg_rtx (<MODE>mode);
11255   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11256   rtx x = gen_reg_rtx (<MODE>mode);
11257   if (val < 0)
11258     emit_insn (gen_and<mode>3 (x, op1, tmp));
11259   else
11260     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11262   if (invert)
11263     {
11264       rtx tmp = gen_reg_rtx (<MODE>mode);
11265       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11266       x = tmp;
11267     }
11269   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11270   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11272   DONE;
11275 (define_expand "cstore<mode>4_unsigned_imm"
11276   [(use (match_operator 1 "unsigned_comparison_operator"
11277          [(match_operand:GPR 2 "gpc_reg_operand")
11278           (match_operand:GPR 3 "immediate_operand")]))
11279    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11280   ""
11282   bool invert = false;
11284   enum rtx_code cond_code = GET_CODE (operands[1]);
11286   rtx op0 = operands[0];
11287   rtx op1 = operands[2];
11288   HOST_WIDE_INT val = INTVAL (operands[3]);
11290   if (cond_code == GEU || cond_code == GTU)
11291     {
11292       cond_code = reverse_condition (cond_code);
11293       invert = true;
11294     }
11296   if (cond_code == LEU)
11297     val++;
11299   rtx tmp = gen_reg_rtx (<MODE>mode);
11300   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11301   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11302   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11303   rtx x = gen_reg_rtx (<MODE>mode);
11304   if (val < 0)
11305     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11306   else
11307     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11309   if (invert)
11310     {
11311       rtx tmp = gen_reg_rtx (<MODE>mode);
11312       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11313       x = tmp;
11314     }
11316   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11317   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11319   DONE;
11322 (define_expand "cstore<mode>4"
11323   [(use (match_operator 1 "comparison_operator"
11324          [(match_operand:GPR 2 "gpc_reg_operand")
11325           (match_operand:GPR 3 "reg_or_short_operand")]))
11326    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11327   ""
11329   /* Expanding EQ and NE directly to some machine instructions does not help
11330      but does hurt combine.  So don't.  */
11331   if (GET_CODE (operands[1]) == EQ)
11332     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11333   else if (<MODE>mode == Pmode
11334            && GET_CODE (operands[1]) == NE)
11335     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11336   else if (GET_CODE (operands[1]) == NE)
11337     {
11338       rtx tmp = gen_reg_rtx (<MODE>mode);
11339       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11340       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11341     }
11343   /* If ISEL is fast, expand to it.  */
11344   else if (TARGET_ISEL)
11345     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11347   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11348      etc. combinations magically work out just right.  */
11349   else if (<MODE>mode == Pmode
11350            && unsigned_comparison_operator (operands[1], VOIDmode))
11351     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11352                                            operands[2], operands[3]));
11354   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11355   else if (<MODE>mode == SImode && Pmode == DImode)
11356     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11357                                     operands[2], operands[3]));
11359   /* For signed comparisons against a constant, we can do some simple
11360      bit-twiddling.  */
11361   else if (signed_comparison_operator (operands[1], VOIDmode)
11362            && CONST_INT_P (operands[3]))
11363     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11364                                              operands[2], operands[3]));
11366   /* And similarly for unsigned comparisons.  */
11367   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11368            && CONST_INT_P (operands[3]))
11369     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11370                                                operands[2], operands[3]));
11372   /* We also do not want to use mfcr for signed comparisons.  */
11373   else if (<MODE>mode == Pmode
11374            && signed_comparison_operator (operands[1], VOIDmode))
11375     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11376                                          operands[2], operands[3]));
11378   /* Everything else, use the mfcr brute force.  */
11379   else
11380     rs6000_emit_sCOND (<MODE>mode, operands);
11382   DONE;
11385 (define_expand "cstore<mode>4"
11386   [(use (match_operator 1 "comparison_operator"
11387          [(match_operand:FP 2 "gpc_reg_operand")
11388           (match_operand:FP 3 "gpc_reg_operand")]))
11389    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11390   ""
11392   rs6000_emit_sCOND (<MODE>mode, operands);
11393   DONE;
11397 (define_expand "stack_protect_set"
11398   [(match_operand 0 "memory_operand")
11399    (match_operand 1 "memory_operand")]
11400   ""
11402   if (rs6000_stack_protector_guard == SSP_TLS)
11403     {
11404       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11405       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11406       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11407       operands[1] = gen_rtx_MEM (Pmode, addr);
11408     }
11410   if (TARGET_64BIT)
11411     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11412   else
11413     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11415   DONE;
11418 (define_insn "stack_protect_setsi"
11419   [(set (match_operand:SI 0 "memory_operand" "=m")
11420         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11421    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11422   "TARGET_32BIT"
11423   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11424   [(set_attr "type" "three")
11425    (set_attr "length" "12")])
11427 (define_insn "stack_protect_setdi"
11428   [(set (match_operand:DI 0 "memory_operand" "=Y")
11429         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11430    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11431   "TARGET_64BIT"
11432   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11433   [(set_attr "type" "three")
11434    (set_attr "length" "12")])
11436 (define_expand "stack_protect_test"
11437   [(match_operand 0 "memory_operand")
11438    (match_operand 1 "memory_operand")
11439    (match_operand 2 "")]
11440   ""
11442   rtx guard = operands[1];
11444   if (rs6000_stack_protector_guard == SSP_TLS)
11445     {
11446       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11447       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11448       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11449       guard = gen_rtx_MEM (Pmode, addr);
11450     }
11452   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11453   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11454   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11455   emit_jump_insn (jump);
11457   DONE;
11460 (define_insn "stack_protect_testsi"
11461   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11462         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11463                       (match_operand:SI 2 "memory_operand" "m,m")]
11464                      UNSPEC_SP_TEST))
11465    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11466    (clobber (match_scratch:SI 3 "=&r,&r"))]
11467   "TARGET_32BIT"
11468   "@
11469    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11470    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11471   [(set_attr "length" "16,20")])
11473 (define_insn "stack_protect_testdi"
11474   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11475         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11476                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11477                      UNSPEC_SP_TEST))
11478    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11479    (clobber (match_scratch:DI 3 "=&r,&r"))]
11480   "TARGET_64BIT"
11481   "@
11482    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11483    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11484   [(set_attr "length" "16,20")])
11487 ;; Here are the actual compare insns.
11488 (define_insn "*cmp<mode>_signed"
11489   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11490         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11491                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11492   ""
11493   "cmp<wd>%I2 %0,%1,%2"
11494   [(set_attr "type" "cmp")])
11496 (define_insn "*cmp<mode>_unsigned"
11497   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11498         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11499                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11500   ""
11501   "cmpl<wd>%I2 %0,%1,%2"
11502   [(set_attr "type" "cmp")])
11504 ;; If we are comparing a register for equality with a large constant,
11505 ;; we can do this with an XOR followed by a compare.  But this is profitable
11506 ;; only if the large constant is only used for the comparison (and in this
11507 ;; case we already have a register to reuse as scratch).
11509 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11510 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11512 (define_peephole2
11513   [(set (match_operand:SI 0 "register_operand")
11514         (match_operand:SI 1 "logical_const_operand"))
11515    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11516                        [(match_dup 0)
11517                         (match_operand:SI 2 "logical_const_operand")]))
11518    (set (match_operand:CC 4 "cc_reg_operand")
11519         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11520                     (match_dup 0)))
11521    (set (pc)
11522         (if_then_else (match_operator 6 "equality_operator"
11523                        [(match_dup 4) (const_int 0)])
11524                       (match_operand 7 "")
11525                       (match_operand 8 "")))]
11526   "peep2_reg_dead_p (3, operands[0])
11527    && peep2_reg_dead_p (4, operands[4])
11528    && REGNO (operands[0]) != REGNO (operands[5])"
11529  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11530   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11531   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11534   /* Get the constant we are comparing against, and see what it looks like
11535      when sign-extended from 16 to 32 bits.  Then see what constant we could
11536      XOR with SEXTC to get the sign-extended value.  */
11537   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11538                                               SImode,
11539                                               operands[1], operands[2]);
11540   HOST_WIDE_INT c = INTVAL (cnst);
11541   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11542   HOST_WIDE_INT xorv = c ^ sextc;
11544   operands[9] = GEN_INT (xorv);
11545   operands[10] = GEN_INT (sextc);
11548 ;; The following two insns don't exist as single insns, but if we provide
11549 ;; them, we can swap an add and compare, which will enable us to overlap more
11550 ;; of the required delay between a compare and branch.  We generate code for
11551 ;; them by splitting.
11553 (define_insn ""
11554   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11555         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11556                     (match_operand:SI 2 "short_cint_operand" "i")))
11557    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11558         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11559   ""
11560   "#"
11561   [(set_attr "length" "8")])
11563 (define_insn ""
11564   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11565         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11566                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11567    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11568         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11569   ""
11570   "#"
11571   [(set_attr "length" "8")])
11573 (define_split
11574   [(set (match_operand:CC 3 "cc_reg_operand")
11575         (compare:CC (match_operand:SI 1 "gpc_reg_operand")
11576                     (match_operand:SI 2 "short_cint_operand")))
11577    (set (match_operand:SI 0 "gpc_reg_operand")
11578         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11579   ""
11580   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11581    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11583 (define_split
11584   [(set (match_operand:CCUNS 3 "cc_reg_operand")
11585         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11586                        (match_operand:SI 2 "u_short_cint_operand")))
11587    (set (match_operand:SI 0 "gpc_reg_operand")
11588         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11589   ""
11590   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11591    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11593 ;; Only need to compare second words if first words equal
11594 (define_insn "*cmp<mode>_internal1"
11595   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11596         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11597                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11598   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11599    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11600   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11601   [(set_attr "type" "fpcompare")
11602    (set_attr "length" "12")])
11604 (define_insn_and_split "*cmp<mode>_internal2"
11605   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11606         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11607                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11608     (clobber (match_scratch:DF 3 "=d"))
11609     (clobber (match_scratch:DF 4 "=d"))
11610     (clobber (match_scratch:DF 5 "=d"))
11611     (clobber (match_scratch:DF 6 "=d"))
11612     (clobber (match_scratch:DF 7 "=d"))
11613     (clobber (match_scratch:DF 8 "=d"))
11614     (clobber (match_scratch:DF 9 "=d"))
11615     (clobber (match_scratch:DF 10 "=d"))
11616     (clobber (match_scratch:GPR 11 "=b"))]
11617   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11618    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11619   "#"
11620   "&& reload_completed"
11621   [(set (match_dup 3) (match_dup 14))
11622    (set (match_dup 4) (match_dup 15))
11623    (set (match_dup 9) (abs:DF (match_dup 5)))
11624    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11625    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11626                            (label_ref (match_dup 12))
11627                            (pc)))
11628    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11629    (set (pc) (label_ref (match_dup 13)))
11630    (match_dup 12)
11631    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11632    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11633    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11634    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11635    (match_dup 13)]
11637   REAL_VALUE_TYPE rv;
11638   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11639   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11641   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11642   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11643   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11644   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11645   operands[12] = gen_label_rtx ();
11646   operands[13] = gen_label_rtx ();
11647   real_inf (&rv);
11648   operands[14] = force_const_mem (DFmode,
11649                                   const_double_from_real_value (rv, DFmode));
11650   operands[15] = force_const_mem (DFmode,
11651                                   const_double_from_real_value (dconst0,
11652                                                                 DFmode));
11653   if (TARGET_TOC)
11654     {
11655       rtx tocref;
11656       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11657       operands[14] = gen_const_mem (DFmode, tocref);
11658       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11659       operands[15] = gen_const_mem (DFmode, tocref);
11660       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11661       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11662     }
11665 ;; Now we have the scc insns.  We can do some combinations because of the
11666 ;; way the machine works.
11668 ;; Note that this is probably faster if we can put an insn between the
11669 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11670 ;; cases the insns below which don't use an intermediate CR field will
11671 ;; be used instead.
11672 (define_insn ""
11673   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11674         (match_operator:SI 1 "scc_comparison_operator"
11675                            [(match_operand 2 "cc_reg_operand" "y")
11676                             (const_int 0)]))]
11677   ""
11678   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11679   [(set (attr "type")
11680      (cond [(match_test "TARGET_MFCRF")
11681                 (const_string "mfcrf")
11682            ]
11683         (const_string "mfcr")))
11684    (set_attr "length" "8")])
11686 (define_insn ""
11687   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11688         (match_operator:DI 1 "scc_comparison_operator"
11689                            [(match_operand 2 "cc_reg_operand" "y")
11690                             (const_int 0)]))]
11691   "TARGET_POWERPC64"
11692   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11693   [(set (attr "type")
11694      (cond [(match_test "TARGET_MFCRF")
11695                 (const_string "mfcrf")
11696            ]
11697         (const_string "mfcr")))
11698    (set_attr "length" "8")])
11700 (define_insn ""
11701   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11702         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11703                                        [(match_operand 2 "cc_reg_operand" "y,y")
11704                                         (const_int 0)])
11705                     (const_int 0)))
11706    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11707         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11708   "TARGET_32BIT"
11709   "@
11710    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11711    #"
11712   [(set_attr "type" "shift")
11713    (set_attr "dot" "yes")
11714    (set_attr "length" "8,16")])
11716 (define_split
11717   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11718         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11719                                        [(match_operand 2 "cc_reg_operand")
11720                                         (const_int 0)])
11721                     (const_int 0)))
11722    (set (match_operand:SI 3 "gpc_reg_operand")
11723         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11724   "TARGET_32BIT && reload_completed"
11725   [(set (match_dup 3)
11726         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11727    (set (match_dup 0)
11728         (compare:CC (match_dup 3)
11729                     (const_int 0)))]
11730   "")
11732 (define_insn ""
11733   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11734         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11735                                       [(match_operand 2 "cc_reg_operand" "y")
11736                                        (const_int 0)])
11737                    (match_operand:SI 3 "const_int_operand" "n")))]
11738   ""
11740   int is_bit = ccr_bit (operands[1], 1);
11741   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11742   int count;
11744   if (is_bit >= put_bit)
11745     count = is_bit - put_bit;
11746   else
11747     count = 32 - (put_bit - is_bit);
11749   operands[4] = GEN_INT (count);
11750   operands[5] = GEN_INT (put_bit);
11752   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11754   [(set (attr "type")
11755      (cond [(match_test "TARGET_MFCRF")
11756                 (const_string "mfcrf")
11757            ]
11758         (const_string "mfcr")))
11759    (set_attr "length" "8")])
11761 (define_insn ""
11762   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11763         (compare:CC
11764          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11765                                        [(match_operand 2 "cc_reg_operand" "y,y")
11766                                         (const_int 0)])
11767                     (match_operand:SI 3 "const_int_operand" "n,n"))
11768          (const_int 0)))
11769    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11770         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11771                    (match_dup 3)))]
11772   ""
11774   int is_bit = ccr_bit (operands[1], 1);
11775   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11776   int count;
11778   /* Force split for non-cc0 compare.  */
11779   if (which_alternative == 1)
11780      return "#";
11782   if (is_bit >= put_bit)
11783     count = is_bit - put_bit;
11784   else
11785     count = 32 - (put_bit - is_bit);
11787   operands[5] = GEN_INT (count);
11788   operands[6] = GEN_INT (put_bit);
11790   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11792   [(set_attr "type" "shift")
11793    (set_attr "dot" "yes")
11794    (set_attr "length" "8,16")])
11796 (define_split
11797   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11798         (compare:CC
11799          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11800                                        [(match_operand 2 "cc_reg_operand")
11801                                         (const_int 0)])
11802                     (match_operand:SI 3 "const_int_operand"))
11803          (const_int 0)))
11804    (set (match_operand:SI 4 "gpc_reg_operand")
11805         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11806                    (match_dup 3)))]
11807   "reload_completed"
11808   [(set (match_dup 4)
11809         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11810                    (match_dup 3)))
11811    (set (match_dup 0)
11812         (compare:CC (match_dup 4)
11813                     (const_int 0)))]
11814   "")
11817 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11818 (define_code_attr UNS [(eq "CC")
11819                        (ne "CC")
11820                        (lt "CC") (ltu "CCUNS")
11821                        (gt "CC") (gtu "CCUNS")
11822                        (le "CC") (leu "CCUNS")
11823                        (ge "CC") (geu "CCUNS")])
11824 (define_code_attr UNSu_ [(eq "")
11825                          (ne "")
11826                          (lt "") (ltu "u_")
11827                          (gt "") (gtu "u_")
11828                          (le "") (leu "u_")
11829                          (ge "") (geu "u_")])
11830 (define_code_attr UNSIK [(eq "I")
11831                          (ne "I")
11832                          (lt "I") (ltu "K")
11833                          (gt "I") (gtu "K")
11834                          (le "I") (leu "K")
11835                          (ge "I") (geu "K")])
11837 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11838   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11839         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11840                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11841    (clobber (match_scratch:GPR 3 "=r"))
11842    (clobber (match_scratch:GPR 4 "=r"))
11843    (clobber (match_scratch:<UNS> 5 "=y"))]
11844   "TARGET_ISEL
11845    && !(<CODE> == EQ && operands[2] == const0_rtx)
11846    && !(<CODE> == NE && operands[2] == const0_rtx
11847         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11848   "#"
11849   "&& 1"
11850   [(pc)]
11852   rtx_code code = <CODE>;
11853   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11854     {
11855       HOST_WIDE_INT val = INTVAL (operands[2]);
11856       if (code == LT && val != -0x8000)
11857         {
11858           code = LE;
11859           val--;
11860         }
11861       if (code == GT && val != 0x7fff)
11862         {
11863           code = GE;
11864           val++;
11865         }
11866       if (code == LTU && val != 0)
11867         {
11868           code = LEU;
11869           val--;
11870         }
11871       if (code == GTU && val != 0xffff)
11872         {
11873           code = GEU;
11874           val++;
11875         }
11876       operands[2] = GEN_INT (val);
11877     }
11879   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11880     operands[3] = const0_rtx;
11881   else
11882     {
11883       if (GET_CODE (operands[3]) == SCRATCH)
11884         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11885       emit_move_insn (operands[3], const0_rtx);
11886     }
11888   if (GET_CODE (operands[4]) == SCRATCH)
11889     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11890   emit_move_insn (operands[4], const1_rtx);
11892   if (GET_CODE (operands[5]) == SCRATCH)
11893     operands[5] = gen_reg_rtx (<UNS>mode);
11895   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11896   emit_insn (gen_rtx_SET (operands[5], c1));
11898   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11899   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11900   emit_move_insn (operands[0], x);
11902   DONE;
11904   [(set (attr "cost")
11905         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11906                                    || <CODE> == NE
11907                                    || <CODE> == LE || <CODE> == GE
11908                                    || <CODE> == LEU || <CODE> == GEU")
11909                       (const_string "9")
11910                       (const_string "10")))])
11912 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11913                               (DI "rKJI")])
11915 (define_expand "eq<mode>3"
11916   [(parallel [
11917      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11918           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11919                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11920      (clobber (match_scratch:GPR 3 "=r"))
11921      (clobber (match_scratch:GPR 4 "=r"))])]
11922   ""
11924   if (TARGET_ISEL && operands[2] != const0_rtx)
11925     {
11926       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11927                                            operands[2]));
11928       DONE;
11929     }
11932 (define_insn_and_split "*eq<mode>3"
11933   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11934         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11935                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11936    (clobber (match_scratch:GPR 3 "=r"))
11937    (clobber (match_scratch:GPR 4 "=r"))]
11938   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11939   "#"
11940   "&& 1"
11941   [(set (match_dup 4)
11942         (clz:GPR (match_dup 3)))
11943    (set (match_dup 0)
11944         (lshiftrt:GPR (match_dup 4)
11945                       (match_dup 5)))]
11947   operands[3] = rs6000_emit_eqne (<MODE>mode,
11948                                   operands[1], operands[2], operands[3]);
11950   if (GET_CODE (operands[4]) == SCRATCH)
11951     operands[4] = gen_reg_rtx (<MODE>mode);
11953   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11955   [(set (attr "length")
11956         (if_then_else (match_test "operands[2] == const0_rtx")
11957                       (const_string "8")
11958                       (const_string "12")))])
11960 (define_expand "ne<mode>3"
11961   [(parallel [
11962      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11963           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11964                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11965      (clobber (match_scratch:P 3 "=r"))
11966      (clobber (match_scratch:P 4 "=r"))
11967      (clobber (reg:P CA_REGNO))])]
11968   ""
11970   if (TARGET_ISEL && operands[2] != const0_rtx)
11971     {
11972       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11973                                            operands[2]));
11974       DONE;
11975     }
11978 (define_insn_and_split "*ne<mode>3"
11979   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11980         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11981               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11982    (clobber (match_scratch:P 3 "=r"))
11983    (clobber (match_scratch:P 4 "=r"))
11984    (clobber (reg:P CA_REGNO))]
11985   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11986   "#"
11987   "&& 1"
11988   [(parallel [(set (match_dup 4)
11989                    (plus:P (match_dup 3)
11990                            (const_int -1)))
11991               (set (reg:P CA_REGNO)
11992                    (ne:P (match_dup 3)
11993                          (const_int 0)))])
11994    (parallel [(set (match_dup 0)
11995                    (plus:P (plus:P (not:P (match_dup 4))
11996                                    (reg:P CA_REGNO))
11997                            (match_dup 3)))
11998               (clobber (reg:P CA_REGNO))])]
12000   operands[3] = rs6000_emit_eqne (<MODE>mode,
12001                                   operands[1], operands[2], operands[3]);
12003   if (GET_CODE (operands[4]) == SCRATCH)
12004     operands[4] = gen_reg_rtx (<MODE>mode);
12006   [(set (attr "length")
12007         (if_then_else (match_test "operands[2] == const0_rtx")
12008                       (const_string "8")
12009                       (const_string "12")))])
12011 (define_insn_and_split "*neg_eq_<mode>"
12012   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12013         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12014                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12015    (clobber (match_scratch:P 3 "=r"))
12016    (clobber (match_scratch:P 4 "=r"))
12017    (clobber (reg:P CA_REGNO))]
12018   ""
12019   "#"
12020   ""
12021   [(parallel [(set (match_dup 4)
12022                    (plus:P (match_dup 3)
12023                            (const_int -1)))
12024               (set (reg:P CA_REGNO)
12025                    (ne:P (match_dup 3)
12026                          (const_int 0)))])
12027    (parallel [(set (match_dup 0)
12028                    (plus:P (reg:P CA_REGNO)
12029                            (const_int -1)))
12030               (clobber (reg:P CA_REGNO))])]
12032   operands[3] = rs6000_emit_eqne (<MODE>mode,
12033                                   operands[1], operands[2], operands[3]);
12035   if (GET_CODE (operands[4]) == SCRATCH)
12036     operands[4] = gen_reg_rtx (<MODE>mode);
12038   [(set (attr "length")
12039         (if_then_else (match_test "operands[2] == const0_rtx")
12040                       (const_string "8")
12041                       (const_string "12")))])
12043 (define_insn_and_split "*neg_ne_<mode>"
12044   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12045         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12046                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12047    (clobber (match_scratch:P 3 "=r"))
12048    (clobber (match_scratch:P 4 "=r"))
12049    (clobber (reg:P CA_REGNO))]
12050   ""
12051   "#"
12052   ""
12053   [(parallel [(set (match_dup 4)
12054                    (neg:P (match_dup 3)))
12055               (set (reg:P CA_REGNO)
12056                    (eq:P (match_dup 3)
12057                          (const_int 0)))])
12058    (parallel [(set (match_dup 0)
12059                    (plus:P (reg:P CA_REGNO)
12060                            (const_int -1)))
12061               (clobber (reg:P CA_REGNO))])]
12063   operands[3] = rs6000_emit_eqne (<MODE>mode,
12064                                   operands[1], operands[2], operands[3]);
12066   if (GET_CODE (operands[4]) == SCRATCH)
12067     operands[4] = gen_reg_rtx (<MODE>mode);
12069   [(set (attr "length")
12070         (if_then_else (match_test "operands[2] == const0_rtx")
12071                       (const_string "8")
12072                       (const_string "12")))])
12074 (define_insn_and_split "*plus_eq_<mode>"
12075   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12076         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12077                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12078                 (match_operand:P 3 "gpc_reg_operand" "r")))
12079    (clobber (match_scratch:P 4 "=r"))
12080    (clobber (match_scratch:P 5 "=r"))
12081    (clobber (reg:P CA_REGNO))]
12082   ""
12083   "#"
12084   ""
12085   [(parallel [(set (match_dup 5)
12086                    (neg:P (match_dup 4)))
12087               (set (reg:P CA_REGNO)
12088                    (eq:P (match_dup 4)
12089                          (const_int 0)))])
12090    (parallel [(set (match_dup 0)
12091                    (plus:P (match_dup 3)
12092                            (reg:P CA_REGNO)))
12093               (clobber (reg:P CA_REGNO))])]
12095   operands[4] = rs6000_emit_eqne (<MODE>mode,
12096                                   operands[1], operands[2], operands[4]);
12098   if (GET_CODE (operands[5]) == SCRATCH)
12099     operands[5] = gen_reg_rtx (<MODE>mode);
12101   [(set (attr "length")
12102         (if_then_else (match_test "operands[2] == const0_rtx")
12103                       (const_string "8")
12104                       (const_string "12")))])
12106 (define_insn_and_split "*plus_ne_<mode>"
12107   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12108         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12109                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12110                 (match_operand:P 3 "gpc_reg_operand" "r")))
12111    (clobber (match_scratch:P 4 "=r"))
12112    (clobber (match_scratch:P 5 "=r"))
12113    (clobber (reg:P CA_REGNO))]
12114   ""
12115   "#"
12116   ""
12117   [(parallel [(set (match_dup 5)
12118                    (plus:P (match_dup 4)
12119                            (const_int -1)))
12120               (set (reg:P CA_REGNO)
12121                    (ne:P (match_dup 4)
12122                          (const_int 0)))])
12123    (parallel [(set (match_dup 0)
12124                    (plus:P (match_dup 3)
12125                            (reg:P CA_REGNO)))
12126               (clobber (reg:P CA_REGNO))])]
12128   operands[4] = rs6000_emit_eqne (<MODE>mode,
12129                                   operands[1], operands[2], operands[4]);
12131   if (GET_CODE (operands[5]) == SCRATCH)
12132     operands[5] = gen_reg_rtx (<MODE>mode);
12134   [(set (attr "length")
12135         (if_then_else (match_test "operands[2] == const0_rtx")
12136                       (const_string "8")
12137                       (const_string "12")))])
12139 (define_insn_and_split "*minus_eq_<mode>"
12140   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12141         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12142                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12143                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12144    (clobber (match_scratch:P 4 "=r"))
12145    (clobber (match_scratch:P 5 "=r"))
12146    (clobber (reg:P CA_REGNO))]
12147   ""
12148   "#"
12149   ""
12150   [(parallel [(set (match_dup 5)
12151                    (plus:P (match_dup 4)
12152                            (const_int -1)))
12153               (set (reg:P CA_REGNO)
12154                    (ne:P (match_dup 4)
12155                          (const_int 0)))])
12156    (parallel [(set (match_dup 0)
12157                    (plus:P (plus:P (match_dup 3)
12158                                    (reg:P CA_REGNO))
12159                            (const_int -1)))
12160               (clobber (reg:P CA_REGNO))])]
12162   operands[4] = rs6000_emit_eqne (<MODE>mode,
12163                                   operands[1], operands[2], operands[4]);
12165   if (GET_CODE (operands[5]) == SCRATCH)
12166     operands[5] = gen_reg_rtx (<MODE>mode);
12168   [(set (attr "length")
12169         (if_then_else (match_test "operands[2] == const0_rtx")
12170                       (const_string "8")
12171                       (const_string "12")))])
12173 (define_insn_and_split "*minus_ne_<mode>"
12174   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12175         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12176                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12177                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12178    (clobber (match_scratch:P 4 "=r"))
12179    (clobber (match_scratch:P 5 "=r"))
12180    (clobber (reg:P CA_REGNO))]
12181   ""
12182   "#"
12183   ""
12184   [(parallel [(set (match_dup 5)
12185                    (neg:P (match_dup 4)))
12186               (set (reg:P CA_REGNO)
12187                    (eq:P (match_dup 4)
12188                          (const_int 0)))])
12189    (parallel [(set (match_dup 0)
12190                    (plus:P (plus:P (match_dup 3)
12191                                    (reg:P CA_REGNO))
12192                            (const_int -1)))
12193               (clobber (reg:P CA_REGNO))])]
12195   operands[4] = rs6000_emit_eqne (<MODE>mode,
12196                                   operands[1], operands[2], operands[4]);
12198   if (GET_CODE (operands[5]) == SCRATCH)
12199     operands[5] = gen_reg_rtx (<MODE>mode);
12201   [(set (attr "length")
12202         (if_then_else (match_test "operands[2] == const0_rtx")
12203                       (const_string "8")
12204                       (const_string "12")))])
12206 (define_insn_and_split "*eqsi3_ext<mode>"
12207   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12208         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12209                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12210    (clobber (match_scratch:SI 3 "=r"))
12211    (clobber (match_scratch:SI 4 "=r"))]
12212   ""
12213   "#"
12214   ""
12215   [(set (match_dup 4)
12216         (clz:SI (match_dup 3)))
12217    (set (match_dup 0)
12218         (zero_extend:EXTSI
12219           (lshiftrt:SI (match_dup 4)
12220                        (const_int 5))))]
12222   operands[3] = rs6000_emit_eqne (SImode,
12223                                   operands[1], operands[2], operands[3]);
12225   if (GET_CODE (operands[4]) == SCRATCH)
12226     operands[4] = gen_reg_rtx (SImode);
12228   [(set (attr "length")
12229         (if_then_else (match_test "operands[2] == const0_rtx")
12230                       (const_string "8")
12231                       (const_string "12")))])
12233 (define_insn_and_split "*nesi3_ext<mode>"
12234   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12235         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12236                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12237    (clobber (match_scratch:SI 3 "=r"))
12238    (clobber (match_scratch:SI 4 "=r"))
12239    (clobber (match_scratch:EXTSI 5 "=r"))]
12240   "!TARGET_ISEL"
12241   "#"
12242   "&& 1"
12243   [(set (match_dup 4)
12244         (clz:SI (match_dup 3)))
12245    (set (match_dup 5)
12246         (zero_extend:EXTSI
12247           (lshiftrt:SI (match_dup 4)
12248                        (const_int 5))))
12249    (set (match_dup 0)
12250         (xor:EXTSI (match_dup 5)
12251                    (const_int 1)))]
12253   operands[3] = rs6000_emit_eqne (SImode,
12254                                   operands[1], operands[2], operands[3]);
12256   if (GET_CODE (operands[4]) == SCRATCH)
12257     operands[4] = gen_reg_rtx (SImode);
12258   if (GET_CODE (operands[5]) == SCRATCH)
12259     operands[5] = gen_reg_rtx (<MODE>mode);
12261   [(set (attr "length")
12262         (if_then_else (match_test "operands[2] == const0_rtx")
12263                       (const_string "12")
12264                       (const_string "16")))])
12266 ;; Define both directions of branch and return.  If we need a reload
12267 ;; register, we'd rather use CR0 since it is much easier to copy a
12268 ;; register CC value to there.
12270 (define_insn ""
12271   [(set (pc)
12272         (if_then_else (match_operator 1 "branch_comparison_operator"
12273                                       [(match_operand 2 "cc_reg_operand" "y")
12274                                        (const_int 0)])
12275                       (label_ref (match_operand 0))
12276                       (pc)))]
12277   ""
12279   return output_cbranch (operands[1], "%l0", 0, insn);
12281   [(set_attr "type" "branch")])
12283 (define_insn ""
12284   [(set (pc)
12285         (if_then_else (match_operator 0 "branch_comparison_operator"
12286                                       [(match_operand 1 "cc_reg_operand" "y")
12287                                        (const_int 0)])
12288                       (any_return)
12289                       (pc)))]
12290   "<return_pred>"
12292   return output_cbranch (operands[0], NULL, 0, insn);
12294   [(set_attr "type" "jmpreg")
12295    (set_attr "length" "4")])
12297 ;; Logic on condition register values.
12299 ; This pattern matches things like
12300 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12301 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12302 ;                                  (const_int 1)))
12303 ; which are generated by the branch logic.
12304 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12306 (define_insn "cceq_ior_compare"
12307   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12308         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12309                         [(match_operator:SI 2
12310                                       "branch_positive_comparison_operator"
12311                                       [(match_operand 3
12312                                                       "cc_reg_operand" "y,y")
12313                                        (const_int 0)])
12314                          (match_operator:SI 4
12315                                       "branch_positive_comparison_operator"
12316                                       [(match_operand 5
12317                                                       "cc_reg_operand" "0,y")
12318                                        (const_int 0)])])
12319                       (const_int 1)))]
12320   ""
12321   "cr%q1 %E0,%j2,%j4"
12322   [(set_attr "type" "cr_logical")
12323    (set_attr "cr_logical_3op" "no,yes")])
12325 ; Why is the constant -1 here, but 1 in the previous pattern?
12326 ; Because ~1 has all but the low bit set.
12327 (define_insn "cceq_ior_compare_complement"
12328   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12329         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12330                         [(not:SI (match_operator:SI 2
12331                                       "branch_positive_comparison_operator"
12332                                       [(match_operand 3
12333                                                       "cc_reg_operand" "y,y")
12334                                        (const_int 0)]))
12335                          (match_operator:SI 4
12336                                 "branch_positive_comparison_operator"
12337                                 [(match_operand 5
12338                                                 "cc_reg_operand" "0,y")
12339                                  (const_int 0)])])
12340                       (const_int -1)))]
12341   ""
12342   "cr%q1 %E0,%j2,%j4"
12343   [(set_attr "type" "cr_logical")
12344    (set_attr "cr_logical_3op" "no,yes")])
12346 (define_insn "*cceq_rev_compare"
12347   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12348         (compare:CCEQ (match_operator:SI 1
12349                                       "branch_positive_comparison_operator"
12350                                       [(match_operand 2
12351                                                       "cc_reg_operand" "0,y")
12352                                        (const_int 0)])
12353                       (const_int 0)))]
12354   ""
12355   "crnot %E0,%j1"
12356   [(set_attr "type" "cr_logical")
12357    (set_attr "cr_logical_3op" "no,yes")])
12359 ;; If we are comparing the result of two comparisons, this can be done
12360 ;; using creqv or crxor.
12362 (define_insn_and_split ""
12363   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12364         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12365                               [(match_operand 2 "cc_reg_operand" "y")
12366                                (const_int 0)])
12367                       (match_operator 3 "branch_comparison_operator"
12368                               [(match_operand 4 "cc_reg_operand" "y")
12369                                (const_int 0)])))]
12370   ""
12371   "#"
12372   ""
12373   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12374                                     (match_dup 5)))]
12376   int positive_1, positive_2;
12378   positive_1 = branch_positive_comparison_operator (operands[1],
12379                                                     GET_MODE (operands[1]));
12380   positive_2 = branch_positive_comparison_operator (operands[3],
12381                                                     GET_MODE (operands[3]));
12383   if (! positive_1)
12384     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12385                                                             GET_CODE (operands[1])),
12386                                   SImode,
12387                                   operands[2], const0_rtx);
12388   else if (GET_MODE (operands[1]) != SImode)
12389     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12390                                   operands[2], const0_rtx);
12392   if (! positive_2)
12393     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12394                                                             GET_CODE (operands[3])),
12395                                   SImode,
12396                                   operands[4], const0_rtx);
12397   else if (GET_MODE (operands[3]) != SImode)
12398     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12399                                   operands[4], const0_rtx);
12401   if (positive_1 == positive_2)
12402     {
12403       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12404       operands[5] = constm1_rtx;
12405     }
12406   else
12407     {
12408       operands[5] = const1_rtx;
12409     }
12412 ;; Unconditional branch and return.
12414 (define_insn "jump"
12415   [(set (pc)
12416         (label_ref (match_operand 0)))]
12417   ""
12418   "b %l0"
12419   [(set_attr "type" "branch")])
12421 (define_insn "<return_str>return"
12422   [(any_return)]
12423   "<return_pred>"
12424   "blr"
12425   [(set_attr "type" "jmpreg")])
12427 (define_expand "indirect_jump"
12428   [(set (pc) (match_operand 0 "register_operand"))]
12429  ""
12431   if (!rs6000_speculate_indirect_jumps) {
12432     rtx ccreg = gen_reg_rtx (CCmode);
12433     if (Pmode == DImode)
12434       emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12435     else
12436       emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12437     DONE;
12438   }
12441 (define_insn "*indirect_jump<mode>"
12442   [(set (pc)
12443         (match_operand:P 0 "register_operand" "c,*l"))]
12444   "rs6000_speculate_indirect_jumps"
12445   "b%T0"
12446   [(set_attr "type" "jmpreg")])
12448 (define_insn "indirect_jump<mode>_nospec"
12449   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12450    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12451   "!rs6000_speculate_indirect_jumps"
12452   "crset %E1\;beq%T0- %1\;b $"
12453   [(set_attr "type" "jmpreg")
12454    (set_attr "length" "12")])
12456 ;; Table jump for switch statements:
12457 (define_expand "tablejump"
12458   [(use (match_operand 0))
12459    (use (label_ref (match_operand 1)))]
12460   ""
12462   if (rs6000_speculate_indirect_jumps)
12463     {
12464       if (TARGET_32BIT)
12465         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12466       else
12467         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12468     }
12469   else
12470     {
12471       rtx ccreg = gen_reg_rtx (CCmode);
12472       rtx jump;
12473       if (TARGET_32BIT)
12474         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12475       else
12476         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12477       emit_jump_insn (jump);
12478     }
12479   DONE;
12482 (define_expand "tablejumpsi"
12483   [(set (match_dup 3)
12484         (plus:SI (match_operand:SI 0)
12485                  (match_dup 2)))
12486    (parallel [(set (pc)
12487                    (match_dup 3))
12488               (use (label_ref (match_operand 1)))])]
12489   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12491   operands[0] = force_reg (SImode, operands[0]);
12492   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12493   operands[3] = gen_reg_rtx (SImode);
12496 (define_expand "tablejumpsi_nospec"
12497   [(set (match_dup 4)
12498         (plus:SI (match_operand:SI 0)
12499                  (match_dup 3)))
12500    (parallel [(set (pc)
12501                    (match_dup 4))
12502               (use (label_ref (match_operand 1)))
12503               (clobber (match_operand 2))])]
12504   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12506   operands[0] = force_reg (SImode, operands[0]);
12507   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12508   operands[4] = gen_reg_rtx (SImode);
12511 (define_expand "tablejumpdi"
12512   [(set (match_dup 4)
12513         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12514    (set (match_dup 3)
12515         (plus:DI (match_dup 4)
12516                  (match_dup 2)))
12517    (parallel [(set (pc)
12518                    (match_dup 3))
12519               (use (label_ref (match_operand 1)))])]
12520   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12522   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12523   operands[3] = gen_reg_rtx (DImode);
12524   operands[4] = gen_reg_rtx (DImode);
12527 (define_expand "tablejumpdi_nospec"
12528   [(set (match_dup 5)
12529         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12530    (set (match_dup 4)
12531         (plus:DI (match_dup 5)
12532                  (match_dup 3)))
12533    (parallel [(set (pc)
12534                    (match_dup 4))
12535               (use (label_ref (match_operand 1)))
12536               (clobber (match_operand 2))])]
12537   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12539   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12540   operands[4] = gen_reg_rtx (DImode);
12541   operands[5] = gen_reg_rtx (DImode);
12544 (define_insn "*tablejump<mode>_internal1"
12545   [(set (pc)
12546         (match_operand:P 0 "register_operand" "c,*l"))
12547    (use (label_ref (match_operand 1)))]
12548   "rs6000_speculate_indirect_jumps"
12549   "b%T0"
12550   [(set_attr "type" "jmpreg")])
12552 (define_insn "*tablejump<mode>_internal1_nospec"
12553   [(set (pc)
12554         (match_operand:P 0 "register_operand" "c,*l"))
12555    (use (label_ref (match_operand 1)))
12556    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12557   "!rs6000_speculate_indirect_jumps"
12558   "crset %E2\;beq%T0- %2\;b $"
12559   [(set_attr "type" "jmpreg")
12560    (set_attr "length" "12")])
12562 (define_insn "nop"
12563   [(unspec [(const_int 0)] UNSPEC_NOP)]
12564   ""
12565   "nop")
12567 (define_insn "group_ending_nop"
12568   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12569   ""
12571   if (rs6000_tune == PROCESSOR_POWER6)
12572     return "ori 1,1,0";
12573   return "ori 2,2,0";
12576 (define_insn "rs6000_speculation_barrier"
12577   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12578   ""
12579   "ori 31,31,0")
12581 ;; Define the subtract-one-and-jump insns, starting with the template
12582 ;; so loop.c knows what to generate.
12584 (define_expand "doloop_end"
12585   [(use (match_operand 0))      ; loop pseudo
12586    (use (match_operand 1))]     ; label
12587   ""
12589   if (TARGET_64BIT)
12590     {
12591       if (GET_MODE (operands[0]) != DImode)
12592         FAIL;
12593       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12594     }
12595   else
12596     {
12597       if (GET_MODE (operands[0]) != SImode)
12598         FAIL;
12599       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12600     }
12601   DONE;
12604 (define_expand "ctr<mode>"
12605   [(parallel [(set (pc)
12606                    (if_then_else (ne (match_operand:P 0 "register_operand")
12607                                      (const_int 1))
12608                                  (label_ref (match_operand 1))
12609                                  (pc)))
12610               (set (match_dup 0)
12611                    (plus:P (match_dup 0)
12612                             (const_int -1)))
12613               (clobber (match_scratch:CC 2))
12614               (clobber (match_scratch:P 3))])]
12615   ""
12616   "")
12618 ;; We need to be able to do this for any operand, including MEM, or we
12619 ;; will cause reload to blow up since we don't allow output reloads on
12620 ;; JUMP_INSNs.
12621 ;; For the length attribute to be calculated correctly, the
12622 ;; label MUST be operand 0.
12623 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12624 ;; the ctr<mode> insns.
12626 (define_code_iterator eqne [eq ne])
12627 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12628 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12630 (define_insn "<bd>_<mode>"
12631   [(set (pc)
12632         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12633                           (const_int 1))
12634                       (label_ref (match_operand 0))
12635                       (pc)))
12636    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12637         (plus:P (match_dup 1)
12638                 (const_int -1)))
12639    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12640    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12641   ""
12643   if (which_alternative != 0)
12644     return "#";
12645   else if (get_attr_length (insn) == 4)
12646     return "<bd> %l0";
12647   else
12648     return "<bd_neg> $+8\;b %l0";
12650   [(set_attr "type" "branch")
12651    (set_attr "length" "*,16,20,20")])
12653 ;; Now the splitter if we could not allocate the CTR register
12654 (define_split
12655   [(set (pc)
12656         (if_then_else (match_operator 2 "comparison_operator"
12657                                       [(match_operand:P 1 "gpc_reg_operand")
12658                                        (const_int 1)])
12659                       (match_operand 5)
12660                       (match_operand 6)))
12661    (set (match_operand:P 0 "nonimmediate_operand")
12662         (plus:P (match_dup 1)
12663                 (const_int -1)))
12664    (clobber (match_scratch:CC 3))
12665    (clobber (match_scratch:P 4))]
12666   "reload_completed"
12667   [(set (pc)
12668         (if_then_else (match_dup 7)
12669                       (match_dup 5)
12670                       (match_dup 6)))]
12672   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12673                                 const0_rtx);
12674   emit_insn (gen_rtx_SET (operands[3],
12675                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12676   if (gpc_reg_operand (operands[0], <MODE>mode))
12677     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12678   else
12679     {
12680       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12681       emit_move_insn (operands[0], operands[4]);
12682     } 
12683     /* No DONE so branch comes from the pattern.  */
12686 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12687 ;; Note that in the case of long branches we have to decompose this into
12688 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12689 ;; and the CR bit, which means there is no way to conveniently invert the
12690 ;; comparison as is done with plain bdnz/bdz.
12692 (define_insn "<bd>tf_<mode>"
12693   [(set (pc)
12694         (if_then_else
12695           (and
12696              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12697                    (const_int 1))
12698              (match_operator 3 "branch_comparison_operator"
12699                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12700                        (const_int 0)]))
12701           (label_ref (match_operand 0))
12702           (pc)))
12703    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12704         (plus:P (match_dup 1)
12705                 (const_int -1)))
12706    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12707    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12708    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12709   ""
12711   if (which_alternative != 0)
12712     return "#";
12713   else if (get_attr_length (insn) == 4)
12714     {
12715       if (branch_positive_comparison_operator (operands[3],
12716                                                GET_MODE (operands[3])))
12717         return "<bd>t %j3,%l0";
12718       else
12719         return "<bd>f %j3,%l0";
12720     }
12721   else
12722     {
12723       static char seq[96];
12724       char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12725       sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12726       return seq;
12727     }
12729   [(set_attr "type" "branch")
12730    (set_attr "length" "*,16,20,20")])
12732 ;; Now the splitter if we could not allocate the CTR register
12733 (define_split
12734   [(set (pc)
12735         (if_then_else
12736           (and
12737              (match_operator 1 "comparison_operator"
12738                              [(match_operand:P 0 "gpc_reg_operand")
12739                               (const_int 1)])
12740              (match_operator 3 "branch_comparison_operator"
12741                       [(match_operand 2 "cc_reg_operand")
12742                        (const_int 0)]))
12743           (match_operand 4)
12744           (match_operand 5)))
12745    (set (match_operand:P 6 "int_reg_operand")
12746         (plus:P (match_dup 0)
12747                 (const_int -1)))
12748    (clobber (match_scratch:P 7))
12749    (clobber (match_scratch:CC 8))
12750    (clobber (match_scratch:CCEQ 9))]
12751   "reload_completed"
12752 [(pc)]
12754   rtx ctr = operands[0];
12755   rtx ctrcmp = operands[1];
12756   rtx ccin = operands[2];
12757   rtx cccmp = operands[3];
12758   rtx dst1 = operands[4];
12759   rtx dst2 = operands[5];
12760   rtx ctrout = operands[6];
12761   rtx ctrtmp = operands[7];
12762   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12763   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12764   if (!ispos)
12765     cmpcode = reverse_condition (cmpcode);
12766   /* Generate crand/crandc here.  */
12767   emit_insn (gen_rtx_SET (operands[8],
12768                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12769   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12771   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12772   if (ispos)
12773      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12774                                       operands[8], cccmp, ccin));
12775   else
12776      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12777                                                  operands[8], cccmp, ccin));
12778   if (gpc_reg_operand (operands[0], <MODE>mode))
12779      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12780   else
12781     {
12782       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12783       emit_move_insn (ctrout, ctrtmp);
12784     }
12785   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12786   emit_jump_insn (gen_rtx_SET (pc_rtx,
12787                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12788                                                      dst1, dst2)));
12789   DONE;
12793 (define_insn "trap"
12794   [(trap_if (const_int 1) (const_int 0))]
12795   ""
12796   "trap"
12797   [(set_attr "type" "trap")])
12799 (define_expand "ctrap<mode>4"
12800   [(trap_if (match_operator 0 "ordered_comparison_operator"
12801                             [(match_operand:GPR 1 "register_operand")
12802                              (match_operand:GPR 2 "reg_or_short_operand")])
12803             (match_operand 3 "zero_constant" ""))]
12804   ""
12805   "")
12807 (define_insn ""
12808   [(trap_if (match_operator 0 "ordered_comparison_operator"
12809                             [(match_operand:GPR 1 "register_operand" "r")
12810                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12811             (const_int 0))]
12812   ""
12813   "t<wd>%V0%I2 %1,%2"
12814   [(set_attr "type" "trap")])
12816 ;; Insns related to generating the function prologue and epilogue.
12818 (define_expand "prologue"
12819   [(use (const_int 0))]
12820   ""
12822   rs6000_emit_prologue ();
12823   if (!TARGET_SCHED_PROLOG)
12824     emit_insn (gen_blockage ());
12825   DONE;
12828 (define_insn "*movesi_from_cr_one"
12829   [(match_parallel 0 "mfcr_operation"
12830                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12831                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12832                                      (match_operand 3 "immediate_operand" "n")]
12833                           UNSPEC_MOVESI_FROM_CR))])]
12834   "TARGET_MFCRF"
12836   int mask = 0;
12837   int i;
12838   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12839   {
12840     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12841     operands[4] = GEN_INT (mask);
12842     output_asm_insn ("mfcr %1,%4", operands);
12843   }
12844   return "";
12846   [(set_attr "type" "mfcrf")])
12848 ;; Don't include the volatile CRs since their values are not used wrt CR save
12849 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12850 ;; prologue past an insn (early exit test) that defines a register used in the
12851 ;; prologue.
12852 (define_insn "prologue_movesi_from_cr"
12853   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12854         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12855                     (reg:CC CR4_REGNO)]
12856                    UNSPEC_MOVESI_FROM_CR))]
12857   ""
12858   "mfcr %0"
12859   [(set_attr "type" "mfcr")])
12861 (define_insn "*crsave"
12862   [(match_parallel 0 "crsave_operation"
12863                    [(set (match_operand:SI 1 "memory_operand" "=m")
12864                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12865   ""
12866   "stw %2,%1"
12867   [(set_attr "type" "store")])
12869 (define_insn "*stmw"
12870   [(match_parallel 0 "stmw_operation"
12871                    [(set (match_operand:SI 1 "memory_operand" "=m")
12872                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12873   "TARGET_MULTIPLE"
12874   "stmw %2,%1"
12875   [(set_attr "type" "store")
12876    (set_attr "update" "yes")
12877    (set_attr "indexed" "yes")])
12879 ; The following comment applies to:
12880 ;     save_gpregs_*
12881 ;     save_fpregs_*
12882 ;     restore_gpregs*
12883 ;     return_and_restore_gpregs*
12884 ;     return_and_restore_fpregs*
12885 ;     return_and_restore_fpregs_aix*
12887 ; The out-of-line save / restore functions expects one input argument.
12888 ; Since those are not standard call_insn's, we must avoid using
12889 ; MATCH_OPERAND for that argument. That way the register rename
12890 ; optimization will not try to rename this register.
12891 ; Each pattern is repeated for each possible register number used in 
12892 ; various ABIs (r11, r1, and for some functions r12)
12894 (define_insn "*save_gpregs_<mode>_r11"
12895   [(match_parallel 0 "any_parallel_operand"
12896                    [(clobber (reg:P LR_REGNO))
12897                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12898                     (use (reg:P 11))
12899                     (set (match_operand:P 2 "memory_operand" "=m")
12900                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12901   ""
12902   "bl %1"
12903   [(set_attr "type" "branch")
12904    (set_attr "length" "4")])
12906 (define_insn "*save_gpregs_<mode>_r12"
12907   [(match_parallel 0 "any_parallel_operand"
12908                    [(clobber (reg:P LR_REGNO))
12909                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12910                     (use (reg:P 12))
12911                     (set (match_operand:P 2 "memory_operand" "=m")
12912                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12913   ""
12914   "bl %1"
12915   [(set_attr "type" "branch")
12916    (set_attr "length" "4")])
12918 (define_insn "*save_gpregs_<mode>_r1"
12919   [(match_parallel 0 "any_parallel_operand"
12920                    [(clobber (reg:P LR_REGNO))
12921                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12922                     (use (reg:P 1))
12923                     (set (match_operand:P 2 "memory_operand" "=m")
12924                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12925   ""
12926   "bl %1"
12927   [(set_attr "type" "branch")
12928    (set_attr "length" "4")])
12930 (define_insn "*save_fpregs_<mode>_r11"
12931   [(match_parallel 0 "any_parallel_operand"
12932                    [(clobber (reg:P LR_REGNO))
12933                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12934                     (use (reg:P 11))
12935                     (set (match_operand:DF 2 "memory_operand" "=m")
12936                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12937   ""
12938   "bl %1"
12939   [(set_attr "type" "branch")
12940    (set_attr "length" "4")])
12942 (define_insn "*save_fpregs_<mode>_r12"
12943   [(match_parallel 0 "any_parallel_operand"
12944                    [(clobber (reg:P LR_REGNO))
12945                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12946                     (use (reg:P 12))
12947                     (set (match_operand:DF 2 "memory_operand" "=m")
12948                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12949   ""
12950   "bl %1"
12951   [(set_attr "type" "branch")
12952    (set_attr "length" "4")])
12954 (define_insn "*save_fpregs_<mode>_r1"
12955   [(match_parallel 0 "any_parallel_operand"
12956                    [(clobber (reg:P LR_REGNO))
12957                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12958                     (use (reg:P 1))
12959                     (set (match_operand:DF 2 "memory_operand" "=m")
12960                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12961   ""
12962   "bl %1"
12963   [(set_attr "type" "branch")
12964    (set_attr "length" "4")])
12966 ; This is to explain that changes to the stack pointer should
12967 ; not be moved over loads from or stores to stack memory.
12968 (define_insn "stack_tie"
12969   [(match_parallel 0 "tie_operand"
12970                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12971   ""
12972   ""
12973   [(set_attr "length" "0")])
12975 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12976 ; stay behind all restores from the stack, it cannot be reordered to before
12977 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
12978 (define_insn "stack_restore_tie"
12979   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12980         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12981                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12982    (set (mem:BLK (scratch)) (const_int 0))]
12983   "TARGET_32BIT"
12984   "@
12985    mr %0,%1
12986    add%I2 %0,%1,%2"
12987   [(set_attr "type" "*,add")])
12989 (define_expand "epilogue"
12990   [(use (const_int 0))]
12991   ""
12993   if (!TARGET_SCHED_PROLOG)
12994     emit_insn (gen_blockage ());
12995   rs6000_emit_epilogue (FALSE);
12996   DONE;
12999 ; On some processors, doing the mtcrf one CC register at a time is
13000 ; faster (like on the 604e).  On others, doing them all at once is
13001 ; faster; for instance, on the 601 and 750.
13003 (define_expand "movsi_to_cr_one"
13004   [(set (match_operand:CC 0 "cc_reg_operand")
13005         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13006                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13007   ""
13008   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13010 (define_insn "*movsi_to_cr"
13011   [(match_parallel 0 "mtcrf_operation"
13012                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13013                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13014                                      (match_operand 3 "immediate_operand" "n")]
13015                                     UNSPEC_MOVESI_TO_CR))])]
13016  ""
13018   int mask = 0;
13019   int i;
13020   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13021     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13022   operands[4] = GEN_INT (mask);
13023   return "mtcrf %4,%2";
13025   [(set_attr "type" "mtcr")])
13027 (define_insn "*mtcrfsi"
13028   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13029         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13030                     (match_operand 2 "immediate_operand" "n")]
13031                    UNSPEC_MOVESI_TO_CR))]
13032   "GET_CODE (operands[0]) == REG
13033    && CR_REGNO_P (REGNO (operands[0]))
13034    && GET_CODE (operands[2]) == CONST_INT
13035    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13036   "mtcrf %R0,%1"
13037   [(set_attr "type" "mtcr")])
13039 ; The load-multiple instructions have similar properties.
13040 ; Note that "load_multiple" is a name known to the machine-independent
13041 ; code that actually corresponds to the PowerPC load-string.
13043 (define_insn "*lmw"
13044   [(match_parallel 0 "lmw_operation"
13045                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13046                          (match_operand:SI 2 "memory_operand" "m"))])]
13047   "TARGET_MULTIPLE"
13048   "lmw %1,%2"
13049   [(set_attr "type" "load")
13050    (set_attr "update" "yes")
13051    (set_attr "indexed" "yes")
13052    (set_attr "cell_micro" "always")])
13054 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13055 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
13057 ; The following comment applies to:
13058 ;     save_gpregs_*
13059 ;     save_fpregs_*
13060 ;     restore_gpregs*
13061 ;     return_and_restore_gpregs*
13062 ;     return_and_restore_fpregs*
13063 ;     return_and_restore_fpregs_aix*
13065 ; The out-of-line save / restore functions expects one input argument.
13066 ; Since those are not standard call_insn's, we must avoid using
13067 ; MATCH_OPERAND for that argument. That way the register rename
13068 ; optimization will not try to rename this register.
13069 ; Each pattern is repeated for each possible register number used in 
13070 ; various ABIs (r11, r1, and for some functions r12)
13072 (define_insn "*restore_gpregs_<mode>_r11"
13073  [(match_parallel 0 "any_parallel_operand"
13074                   [(clobber (reg:P LR_REGNO))
13075                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13076                    (use (reg:P 11))
13077                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13078                         (match_operand:P 3 "memory_operand" "m"))])]
13079  ""
13080  "bl %1"
13081  [(set_attr "type" "branch")
13082   (set_attr "length" "4")])
13084 (define_insn "*restore_gpregs_<mode>_r12"
13085  [(match_parallel 0 "any_parallel_operand"
13086                   [(clobber (reg:P LR_REGNO))
13087                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13088                    (use (reg:P 12))
13089                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13090                         (match_operand:P 3 "memory_operand" "m"))])]
13091  ""
13092  "bl %1"
13093  [(set_attr "type" "branch")
13094   (set_attr "length" "4")])
13096 (define_insn "*restore_gpregs_<mode>_r1"
13097  [(match_parallel 0 "any_parallel_operand"
13098                   [(clobber (reg:P LR_REGNO))
13099                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13100                    (use (reg:P 1))
13101                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13102                         (match_operand:P 3 "memory_operand" "m"))])]
13103  ""
13104  "bl %1"
13105  [(set_attr "type" "branch")
13106   (set_attr "length" "4")])
13108 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13109  [(match_parallel 0 "any_parallel_operand"
13110                   [(return)
13111                    (clobber (reg:P LR_REGNO))
13112                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13113                    (use (reg:P 11))
13114                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13115                         (match_operand:P 3 "memory_operand" "m"))])]
13116  ""
13117  "b %1"
13118  [(set_attr "type" "branch")
13119   (set_attr "length" "4")])
13121 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13122  [(match_parallel 0 "any_parallel_operand"
13123                   [(return)
13124                    (clobber (reg:P LR_REGNO))
13125                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13126                    (use (reg:P 12))
13127                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13128                         (match_operand:P 3 "memory_operand" "m"))])]
13129  ""
13130  "b %1"
13131  [(set_attr "type" "branch")
13132   (set_attr "length" "4")])
13134 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13135  [(match_parallel 0 "any_parallel_operand"
13136                   [(return)
13137                    (clobber (reg:P LR_REGNO))
13138                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13139                    (use (reg:P 1))
13140                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13141                         (match_operand:P 3 "memory_operand" "m"))])]
13142  ""
13143  "b %1"
13144  [(set_attr "type" "branch")
13145   (set_attr "length" "4")])
13147 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13148  [(match_parallel 0 "any_parallel_operand"
13149                   [(return)
13150                    (clobber (reg:P LR_REGNO))
13151                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13152                    (use (reg:P 11))
13153                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13154                         (match_operand:DF 3 "memory_operand" "m"))])]
13155  ""
13156  "b %1"
13157  [(set_attr "type" "branch")
13158   (set_attr "length" "4")])
13160 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13161  [(match_parallel 0 "any_parallel_operand"
13162                   [(return)
13163                    (clobber (reg:P LR_REGNO))
13164                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13165                    (use (reg:P 12))
13166                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13167                         (match_operand:DF 3 "memory_operand" "m"))])]
13168  ""
13169  "b %1"
13170  [(set_attr "type" "branch")
13171   (set_attr "length" "4")])
13173 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13174  [(match_parallel 0 "any_parallel_operand"
13175                   [(return)
13176                    (clobber (reg:P LR_REGNO))
13177                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13178                    (use (reg:P 1))
13179                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13180                         (match_operand:DF 3 "memory_operand" "m"))])]
13181  ""
13182  "b %1"
13183  [(set_attr "type" "branch")
13184   (set_attr "length" "4")])
13186 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13187  [(match_parallel 0 "any_parallel_operand"
13188                   [(return)
13189                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13190                    (use (reg:P 11))
13191                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13192                         (match_operand:DF 3 "memory_operand" "m"))])]
13193  ""
13194  "b %1"
13195  [(set_attr "type" "branch")
13196   (set_attr "length" "4")])
13198 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13199  [(match_parallel 0 "any_parallel_operand"
13200                   [(return)
13201                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13202                    (use (reg:P 1))
13203                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13204                         (match_operand:DF 3 "memory_operand" "m"))])]
13205  ""
13206  "b %1"
13207  [(set_attr "type" "branch")
13208   (set_attr "length" "4")])
13210 ; This is used in compiling the unwind routines.
13211 (define_expand "eh_return"
13212   [(use (match_operand 0 "general_operand"))]
13213   ""
13215   if (TARGET_32BIT)
13216     emit_insn (gen_eh_set_lr_si (operands[0]));
13217   else
13218     emit_insn (gen_eh_set_lr_di (operands[0]));
13219   DONE;
13222 ; We can't expand this before we know where the link register is stored.
13223 (define_insn "eh_set_lr_<mode>"
13224   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13225                     UNSPECV_EH_RR)
13226    (clobber (match_scratch:P 1 "=&b"))]
13227   ""
13228   "#")
13230 (define_split
13231   [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13232    (clobber (match_scratch 1))]
13233   "reload_completed"
13234   [(const_int 0)]
13236   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13237   DONE;
13240 (define_insn "prefetch"
13241   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13242              (match_operand:SI 1 "const_int_operand" "n")
13243              (match_operand:SI 2 "const_int_operand" "n"))]
13244   ""
13246   /* dcbtstt, dcbtt and TM=0b10000 support starts with ISA 2.06.  */
13247   int inst_select = INTVAL (operands[2]) || !TARGET_POPCNTD;
13249   if (REG_P (operands[0]))
13250     {
13251       if (INTVAL (operands[1]) == 0)
13252         return inst_select ? "dcbt 0,%0" : "dcbtt 0,%0";
13253       else
13254         return inst_select ? "dcbtst 0,%0" : "dcbtstt 0,%0";
13255     }
13256   else
13257     {
13258       if (INTVAL (operands[1]) == 0)
13259         return inst_select ? "dcbt %a0" : "dcbtt %a0";
13260       else
13261         return inst_select ? "dcbtst %a0" : "dcbtstt %a0";
13262     }
13264   [(set_attr "type" "load")])
13266 ;; Handle -fsplit-stack.
13268 (define_expand "split_stack_prologue"
13269   [(const_int 0)]
13270   ""
13272   rs6000_expand_split_stack_prologue ();
13273   DONE;
13276 (define_expand "load_split_stack_limit"
13277   [(set (match_operand 0)
13278         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13279   ""
13281   emit_insn (gen_rtx_SET (operands[0],
13282                           gen_rtx_UNSPEC (Pmode,
13283                                           gen_rtvec (1, const0_rtx),
13284                                           UNSPEC_STACK_CHECK)));
13285   DONE;
13288 (define_insn "load_split_stack_limit_di"
13289   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13290         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13291   "TARGET_64BIT"
13292   "ld %0,-0x7040(13)"
13293   [(set_attr "type" "load")
13294    (set_attr "update" "no")
13295    (set_attr "indexed" "no")])
13297 (define_insn "load_split_stack_limit_si"
13298   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13299         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13300   "!TARGET_64BIT"
13301   "lwz %0,-0x7020(2)"
13302   [(set_attr "type" "load")
13303    (set_attr "update" "no")
13304    (set_attr "indexed" "no")])
13306 ;; A return instruction which the middle-end doesn't see.
13307 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13308 ;; after the call to __morestack.
13309 (define_insn "split_stack_return"
13310   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13311   ""
13312   "blr"
13313   [(set_attr "type" "jmpreg")])
13315 ;; If there are operand 0 bytes available on the stack, jump to
13316 ;; operand 1.
13317 (define_expand "split_stack_space_check"
13318   [(set (match_dup 2)
13319         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13320    (set (match_dup 3)
13321         (minus (reg STACK_POINTER_REGNUM)
13322                (match_operand 0)))
13323    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13324    (set (pc) (if_then_else
13325               (geu (match_dup 4) (const_int 0))
13326               (label_ref (match_operand 1))
13327               (pc)))]
13328   ""
13330   rs6000_split_stack_space_check (operands[0], operands[1]);
13331   DONE;
13334 (define_insn "bpermd_<mode>"
13335   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13336         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13337                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13338   "TARGET_POPCNTD"
13339   "bpermd %0,%1,%2"
13340   [(set_attr "type" "popcnt")])
13343 ;; Builtin fma support.  Handle 
13344 ;; Note that the conditions for expansion are in the FMA_F iterator.
13346 (define_expand "fma<mode>4"
13347   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13348         (fma:FMA_F
13349           (match_operand:FMA_F 1 "gpc_reg_operand")
13350           (match_operand:FMA_F 2 "gpc_reg_operand")
13351           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13352   ""
13353   "")
13355 (define_insn "*fma<mode>4_fpr"
13356   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13357         (fma:SFDF
13358           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13359           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13360           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13361   "TARGET_HARD_FLOAT"
13362   "@
13363    fmadd<Ftrad> %0,%1,%2,%3
13364    xsmadda<Fvsx> %x0,%x1,%x2
13365    xsmaddm<Fvsx> %x0,%x1,%x3"
13366   [(set_attr "type" "fp")])
13368 ; Altivec only has fma and nfms.
13369 (define_expand "fms<mode>4"
13370   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13371         (fma:FMA_F
13372           (match_operand:FMA_F 1 "gpc_reg_operand")
13373           (match_operand:FMA_F 2 "gpc_reg_operand")
13374           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13375   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13376   "")
13378 (define_insn "*fms<mode>4_fpr"
13379   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13380         (fma:SFDF
13381          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13382          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13383          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13384   "TARGET_HARD_FLOAT"
13385   "@
13386    fmsub<Ftrad> %0,%1,%2,%3
13387    xsmsuba<Fvsx> %x0,%x1,%x2
13388    xsmsubm<Fvsx> %x0,%x1,%x3"
13389   [(set_attr "type" "fp")])
13391 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13392 (define_expand "fnma<mode>4"
13393   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13394         (neg:FMA_F
13395           (fma:FMA_F
13396             (match_operand:FMA_F 1 "gpc_reg_operand")
13397             (match_operand:FMA_F 2 "gpc_reg_operand")
13398             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13399   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13400   "")
13402 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13403 (define_expand "fnms<mode>4"
13404   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13405         (neg:FMA_F
13406           (fma:FMA_F
13407             (match_operand:FMA_F 1 "gpc_reg_operand")
13408             (match_operand:FMA_F 2 "gpc_reg_operand")
13409             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13410   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13411   "")
13413 ; Not an official optab name, but used from builtins.
13414 (define_expand "nfma<mode>4"
13415   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13416         (neg:FMA_F
13417           (fma:FMA_F
13418             (match_operand:FMA_F 1 "gpc_reg_operand")
13419             (match_operand:FMA_F 2 "gpc_reg_operand")
13420             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13421   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13422   "")
13424 (define_insn "*nfma<mode>4_fpr"
13425   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13426         (neg:SFDF
13427          (fma:SFDF
13428           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13429           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13430           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13431   "TARGET_HARD_FLOAT"
13432   "@
13433    fnmadd<Ftrad> %0,%1,%2,%3
13434    xsnmadda<Fvsx> %x0,%x1,%x2
13435    xsnmaddm<Fvsx> %x0,%x1,%x3"
13436   [(set_attr "type" "fp")])
13438 ; Not an official optab name, but used from builtins.
13439 (define_expand "nfms<mode>4"
13440   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13441         (neg:FMA_F
13442           (fma:FMA_F
13443             (match_operand:FMA_F 1 "gpc_reg_operand")
13444             (match_operand:FMA_F 2 "gpc_reg_operand")
13445             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13446   ""
13447   "")
13449 (define_insn "*nfmssf4_fpr"
13450   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13451         (neg:SFDF
13452          (fma:SFDF
13453           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13454           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13455           (neg:SFDF
13456            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13457   "TARGET_HARD_FLOAT"
13458   "@
13459    fnmsub<Ftrad> %0,%1,%2,%3
13460    xsnmsuba<Fvsx> %x0,%x1,%x2
13461    xsnmsubm<Fvsx> %x0,%x1,%x3"
13462   [(set_attr "type" "fp")])
13465 (define_expand "rs6000_get_timebase"
13466   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13467   ""
13469   if (TARGET_POWERPC64)
13470     emit_insn (gen_rs6000_mftb_di (operands[0]));
13471   else
13472     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13473   DONE;
13476 (define_insn "rs6000_get_timebase_ppc32"
13477   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13478         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13479    (clobber (match_scratch:SI 1 "=r"))
13480    (clobber (match_scratch:CC 2 "=y"))]
13481   "!TARGET_POWERPC64"
13483   if (WORDS_BIG_ENDIAN)
13484     if (TARGET_MFCRF)
13485       {
13486         return "mfspr %0,269\;"
13487                "mfspr %L0,268\;"
13488                "mfspr %1,269\;"
13489                "cmpw %2,%0,%1\;"
13490                "bne- %2,$-16";
13491       }
13492     else
13493       {
13494         return "mftbu %0\;"
13495                "mftb %L0\;"
13496                "mftbu %1\;"
13497                "cmpw %2,%0,%1\;"
13498                "bne- %2,$-16";
13499       }
13500   else
13501     if (TARGET_MFCRF)
13502       {
13503         return "mfspr %L0,269\;"
13504                "mfspr %0,268\;"
13505                "mfspr %1,269\;"
13506                "cmpw %2,%L0,%1\;"
13507                "bne- %2,$-16";
13508       }
13509     else
13510       {
13511         return "mftbu %L0\;"
13512                "mftb %0\;"
13513                "mftbu %1\;"
13514                "cmpw %2,%L0,%1\;"
13515                "bne- %2,$-16";
13516       }
13518   [(set_attr "length" "20")])
13520 (define_insn "rs6000_mftb_<mode>"
13521   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13522         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13523   ""
13525   if (TARGET_MFCRF)
13526     return "mfspr %0,268";
13527   else
13528     return "mftb %0";
13532 (define_insn "rs6000_mffs"
13533   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13534         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13535   "TARGET_HARD_FLOAT"
13536   "mffs %0")
13538 (define_insn "rs6000_mtfsf"
13539   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13540                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13541                     UNSPECV_MTFSF)]
13542   "TARGET_HARD_FLOAT"
13543   "mtfsf %0,%1")
13546 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13547 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13548 ;; register that is being loaded.  The fused ops must be physically adjacent.
13550 ;; There are two parts to addis fusion.  The support for fused TOCs occur
13551 ;; before register allocation, and is meant to reduce the lifetime for the
13552 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
13553 ;; to use the register that is being load.  The peephole2 then gathers any
13554 ;; other fused possibilities that it can find after register allocation.  If
13555 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13557 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
13558 ;; before register allocation, so that we can avoid allocating a temporary base
13559 ;; register that won't be used, and that we try to load into base registers,
13560 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
13561 ;; (addis followed by load) even on power8.
13563 (define_split
13564   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13565         (match_operand:INT1 1 "toc_fusion_mem_raw"))]
13566   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13567   [(parallel [(set (match_dup 0) (match_dup 2))
13568               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13569               (use (match_dup 3))
13570               (clobber (scratch:DI))])]
13572   operands[2] = fusion_wrap_memory_address (operands[1]);
13573   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13576 (define_insn "*toc_fusionload_<mode>"
13577   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13578         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13579    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13580    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13581    (clobber (match_scratch:DI 3 "=X,&b"))]
13582   "TARGET_TOC_FUSION_INT"
13584   if (base_reg_operand (operands[0], <MODE>mode))
13585     return emit_fusion_gpr_load (operands[0], operands[1]);
13587   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13589   [(set_attr "type" "load")
13590    (set_attr "length" "8")])
13592 (define_insn "*toc_fusionload_di"
13593   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13594         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13595    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13596    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13597    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13598   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13599    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13601   if (base_reg_operand (operands[0], DImode))
13602     return emit_fusion_gpr_load (operands[0], operands[1]);
13604   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13606   [(set_attr "type" "load")
13607    (set_attr "length" "8")])
13610 ;; Find cases where the addis that feeds into a load instruction is either used
13611 ;; once or is the same as the target register, and replace it with the fusion
13612 ;; insn
13614 (define_peephole2
13615   [(set (match_operand:P 0 "base_reg_operand")
13616         (match_operand:P 1 "fusion_gpr_addis"))
13617    (set (match_operand:INT1 2 "base_reg_operand")
13618         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13619   "TARGET_P8_FUSION
13620    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13621                          operands[3])"
13622   [(const_int 0)]
13624   expand_fusion_gpr_load (operands);
13625   DONE;
13628 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13629 ;; reload)
13631 (define_insn "fusion_gpr_load_<mode>"
13632   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13633         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13634                      UNSPEC_FUSION_GPR))]
13635   "TARGET_P8_FUSION"
13637   return emit_fusion_gpr_load (operands[0], operands[1]);
13639   [(set_attr "type" "load")
13640    (set_attr "length" "8")])
13643 ;; ISA 3.0 (power9) fusion support
13644 ;; Merge addis with floating load/store to FPRs (or GPRs).
13645 (define_peephole2
13646   [(set (match_operand:P 0 "base_reg_operand")
13647         (match_operand:P 1 "fusion_gpr_addis"))
13648    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13649         (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13650   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13651    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13652   [(const_int 0)]
13654   expand_fusion_p9_load (operands);
13655   DONE;
13658 (define_peephole2
13659   [(set (match_operand:P 0 "base_reg_operand")
13660         (match_operand:P 1 "fusion_gpr_addis"))
13661    (set (match_operand:SFDF 2 "offsettable_mem_operand")
13662         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13663   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13664    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13665    && !rtx_equal_p (operands[0], operands[3])"
13666   [(const_int 0)]
13668   expand_fusion_p9_store (operands);
13669   DONE;
13672 (define_peephole2
13673   [(set (match_operand:SDI 0 "int_reg_operand")
13674         (match_operand:SDI 1 "upper16_cint_operand"))
13675    (set (match_dup 0)
13676         (ior:SDI (match_dup 0)
13677                  (match_operand:SDI 2 "u_short_cint_operand")))]
13678   "TARGET_P9_FUSION"
13679   [(set (match_dup 0)
13680         (unspec:SDI [(match_dup 1)
13681                      (match_dup 2)] UNSPEC_FUSION_P9))])
13683 (define_peephole2
13684   [(set (match_operand:SDI 0 "int_reg_operand")
13685         (match_operand:SDI 1 "upper16_cint_operand"))
13686    (set (match_operand:SDI 2 "int_reg_operand")
13687         (ior:SDI (match_dup 0)
13688                  (match_operand:SDI 3 "u_short_cint_operand")))]
13689   "TARGET_P9_FUSION
13690    && !rtx_equal_p (operands[0], operands[2])
13691    && peep2_reg_dead_p (2, operands[0])"
13692   [(set (match_dup 2)
13693         (unspec:SDI [(match_dup 1)
13694                      (match_dup 3)] UNSPEC_FUSION_P9))])
13696 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13697 ;; reload).  Because we want to eventually have secondary_reload generate
13698 ;; these, they have to have a single alternative that gives the register
13699 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
13700 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13701   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13702         (unspec:GPR_FUSION
13703          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13704          UNSPEC_FUSION_P9))
13705    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13706   "TARGET_P9_FUSION"
13708   /* This insn is a secondary reload insn, which cannot have alternatives.
13709      If we are not loading up register 0, use the power8 fusion instead.  */
13710   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13711     return emit_fusion_gpr_load (operands[0], operands[1]);
13713   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13715   [(set_attr "type" "load")
13716    (set_attr "length" "8")])
13718 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13719   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13720         (unspec:GPR_FUSION
13721          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13722          UNSPEC_FUSION_P9))
13723    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13724   "TARGET_P9_FUSION"
13726   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13728   [(set_attr "type" "store")
13729    (set_attr "length" "8")])
13731 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13732   [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13733         (unspec:FPR_FUSION
13734          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13735          UNSPEC_FUSION_P9))
13736    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13737   "TARGET_P9_FUSION"
13739   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13741   [(set_attr "type" "fpload")
13742    (set_attr "length" "8")])
13744 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13745   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13746         (unspec:FPR_FUSION
13747          [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13748          UNSPEC_FUSION_P9))
13749    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13750   "TARGET_P9_FUSION"
13752   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13754   [(set_attr "type" "fpstore")
13755    (set_attr "length" "8")])
13757 (define_insn "*fusion_p9_<mode>_constant"
13758   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13759         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13760                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13761                     UNSPEC_FUSION_P9))] 
13762   "TARGET_P9_FUSION"
13764   emit_fusion_addis (operands[0], operands[1]);
13765   return "ori %0,%0,%2";
13767   [(set_attr "type" "two")
13768    (set_attr "length" "8")])
13771 ;; Optimize cases where we want to do a D-form load (register+offset) on
13772 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13773 ;; has generated:
13774 ;;      LFD 0,32(3)
13775 ;;      XXLOR 32,0,0
13777 ;; and we change this to:
13778 ;;      LI 0,32
13779 ;;      LXSDX 32,3,9
13781 (define_peephole2
13782   [(match_scratch:P 0 "b")
13783    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13784         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13785    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13786         (match_dup 1))]
13787   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13788   [(set (match_dup 0)
13789         (match_dup 4))
13790    (set (match_dup 3)
13791         (match_dup 5))]
13793   rtx tmp_reg = operands[0];
13794   rtx mem = operands[2];
13795   rtx addr = XEXP (mem, 0);
13796   rtx add_op0, add_op1, new_addr;
13798   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13799   add_op0 = XEXP (addr, 0);
13800   add_op1 = XEXP (addr, 1);
13801   gcc_assert (REG_P (add_op0));
13802   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13804   operands[4] = add_op1;
13805   operands[5] = change_address (mem, <MODE>mode, new_addr);
13808 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13809 ;; Altivec register, and the register allocator has generated:
13810 ;;      XXLOR 0,32,32
13811 ;;      STFD 0,32(3)
13813 ;; and we change this to:
13814 ;;      LI 0,32
13815 ;;      STXSDX 32,3,9
13817 (define_peephole2
13818   [(match_scratch:P 0 "b")
13819    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13820         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13821    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13822         (match_dup 1))]
13823   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13824   [(set (match_dup 0)
13825         (match_dup 4))
13826    (set (match_dup 5)
13827         (match_dup 2))]
13829   rtx tmp_reg = operands[0];
13830   rtx mem = operands[3];
13831   rtx addr = XEXP (mem, 0);
13832   rtx add_op0, add_op1, new_addr;
13834   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13835   add_op0 = XEXP (addr, 0);
13836   add_op1 = XEXP (addr, 1);
13837   gcc_assert (REG_P (add_op0));
13838   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13840   operands[4] = add_op1;
13841   operands[5] = change_address (mem, <MODE>mode, new_addr);
13843    
13845 ;; Miscellaneous ISA 2.06 (power7) instructions
13846 (define_insn "addg6s"
13847   [(set (match_operand:SI 0 "register_operand" "=r")
13848         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13849                     (match_operand:SI 2 "register_operand" "r")]
13850                    UNSPEC_ADDG6S))]
13851   "TARGET_POPCNTD"
13852   "addg6s %0,%1,%2"
13853   [(set_attr "type" "integer")
13854    (set_attr "length" "4")])
13856 (define_insn "cdtbcd"
13857   [(set (match_operand:SI 0 "register_operand" "=r")
13858         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13859                    UNSPEC_CDTBCD))]
13860   "TARGET_POPCNTD"
13861   "cdtbcd %0,%1"
13862   [(set_attr "type" "integer")
13863    (set_attr "length" "4")])
13865 (define_insn "cbcdtd"
13866   [(set (match_operand:SI 0 "register_operand" "=r")
13867         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13868                    UNSPEC_CBCDTD))]
13869   "TARGET_POPCNTD"
13870   "cbcdtd %0,%1"
13871   [(set_attr "type" "integer")
13872    (set_attr "length" "4")])
13874 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13875                                         UNSPEC_DIVEU])
13877 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13878                              (UNSPEC_DIVEU      "eu")])
13880 (define_insn "div<div_extend>_<mode>"
13881   [(set (match_operand:GPR 0 "register_operand" "=r")
13882         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13883                      (match_operand:GPR 2 "register_operand" "r")]
13884                     UNSPEC_DIV_EXTEND))]
13885   "TARGET_POPCNTD"
13886   "div<wd><div_extend> %0,%1,%2"
13887   [(set_attr "type" "div")
13888    (set_attr "size" "<bits>")])
13891 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13893 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13894 (define_mode_attr FP128_64 [(TF "DF")
13895                             (IF "DF")
13896                             (TD "DI")
13897                             (KF "DI")])
13899 (define_expand "unpack<mode>"
13900   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13901         (unspec:<FP128_64>
13902          [(match_operand:FMOVE128 1 "register_operand")
13903           (match_operand:QI 2 "const_0_to_1_operand")]
13904          UNSPEC_UNPACK_128BIT))]
13905   "FLOAT128_2REG_P (<MODE>mode)"
13906   "")
13908 (define_insn_and_split "unpack<mode>_dm"
13909   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13910         (unspec:<FP128_64>
13911          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13912           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13913          UNSPEC_UNPACK_128BIT))]
13914   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13915   "#"
13916   "&& reload_completed"
13917   [(set (match_dup 0) (match_dup 3))]
13919   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13921   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13922     {
13923       emit_note (NOTE_INSN_DELETED);
13924       DONE;
13925     }
13927   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13929   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13930    (set_attr "length" "4")])
13932 (define_insn_and_split "unpack<mode>_nodm"
13933   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13934         (unspec:<FP128_64>
13935          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13936           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13937          UNSPEC_UNPACK_128BIT))]
13938   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13939   "#"
13940   "&& reload_completed"
13941   [(set (match_dup 0) (match_dup 3))]
13943   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13945   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13946     {
13947       emit_note (NOTE_INSN_DELETED);
13948       DONE;
13949     }
13951   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13953   [(set_attr "type" "fp,fpstore")
13954    (set_attr "length" "4")])
13956 (define_insn_and_split "pack<mode>"
13957   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13958         (unspec:FMOVE128
13959          [(match_operand:<FP128_64> 1 "register_operand" "d")
13960           (match_operand:<FP128_64> 2 "register_operand" "d")]
13961          UNSPEC_PACK_128BIT))]
13962   "FLOAT128_2REG_P (<MODE>mode)"
13963   "#"
13964   "&& reload_completed"
13965   [(set (match_dup 3) (match_dup 1))
13966    (set (match_dup 4) (match_dup 2))]
13968   unsigned dest_hi = REGNO (operands[0]);
13969   unsigned dest_lo = dest_hi + 1;
13971   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13972   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13974   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13975   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13977   [(set_attr "type" "fp")
13978    (set_attr "length" "8")])
13980 (define_insn "unpack<mode>"
13981   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13982         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13983                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13984          UNSPEC_UNPACK_128BIT))]
13985   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13987   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13988     return ASM_COMMENT_START " xxpermdi to same register";
13990   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13991   return "xxpermdi %x0,%x1,%x1,%3";
13993   [(set_attr "type" "vecperm")])
13995 (define_insn "pack<mode>"
13996   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13997         (unspec:FMOVE128_VSX
13998          [(match_operand:DI 1 "register_operand" "wa")
13999           (match_operand:DI 2 "register_operand" "wa")]
14000          UNSPEC_PACK_128BIT))]
14001   "TARGET_VSX"
14002   "xxpermdi %x0,%x1,%x2,0"
14003   [(set_attr "type" "vecperm")])
14007 ;; ISA 2.08 IEEE 128-bit floating point support.
14009 (define_insn "add<mode>3"
14010   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14011         (plus:IEEE128
14012          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14013          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14014   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14015   "xsaddqp %0,%1,%2"
14016   [(set_attr "type" "vecfloat")
14017    (set_attr "size" "128")])
14019 (define_insn "sub<mode>3"
14020   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14021         (minus:IEEE128
14022          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14023          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14024   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14025   "xssubqp %0,%1,%2"
14026   [(set_attr "type" "vecfloat")
14027    (set_attr "size" "128")])
14029 (define_insn "mul<mode>3"
14030   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14031         (mult:IEEE128
14032          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14033          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14034   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14035   "xsmulqp %0,%1,%2"
14036   [(set_attr "type" "qmul")
14037    (set_attr "size" "128")])
14039 (define_insn "div<mode>3"
14040   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14041         (div:IEEE128
14042          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14043          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14044   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14045   "xsdivqp %0,%1,%2"
14046   [(set_attr "type" "vecdiv")
14047    (set_attr "size" "128")])
14049 (define_insn "sqrt<mode>2"
14050   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14051         (sqrt:IEEE128
14052          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14053   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14054    "xssqrtqp %0,%1"
14055   [(set_attr "type" "vecdiv")
14056    (set_attr "size" "128")])
14058 (define_expand "copysign<mode>3"
14059   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14060    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14061    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14062   "FLOAT128_IEEE_P (<MODE>mode)"
14064   if (TARGET_FLOAT128_HW)
14065     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14066                                          operands[2]));
14067   else
14068     {
14069       rtx tmp = gen_reg_rtx (<MODE>mode);
14070       emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14071                                            operands[2], tmp));
14072     }
14073   DONE;
14076 (define_insn "copysign<mode>3_hard"
14077   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14078         (unspec:IEEE128
14079          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14080           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14081          UNSPEC_COPYSIGN))]
14082   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14083    "xscpsgnqp %0,%2,%1"
14084   [(set_attr "type" "vecmove")
14085    (set_attr "size" "128")])
14087 (define_insn "copysign<mode>3_soft"
14088   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14089         (unspec:IEEE128
14090          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14091           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14092           (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14093          UNSPEC_COPYSIGN))]
14094   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14095    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14096   [(set_attr "type" "veccomplex")
14097    (set_attr "length" "8")])
14099 (define_insn "neg<mode>2_hw"
14100   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14101         (neg:IEEE128
14102          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14103   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14104   "xsnegqp %0,%1"
14105   [(set_attr "type" "vecmove")
14106    (set_attr "size" "128")])
14109 (define_insn "abs<mode>2_hw"
14110   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14111         (abs:IEEE128
14112          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14113   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14114   "xsabsqp %0,%1"
14115   [(set_attr "type" "vecmove")
14116    (set_attr "size" "128")])
14119 (define_insn "*nabs<mode>2_hw"
14120   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14121         (neg:IEEE128
14122          (abs:IEEE128
14123           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14124   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14125   "xsnabsqp %0,%1"
14126   [(set_attr "type" "vecmove")
14127    (set_attr "size" "128")])
14129 ;; Initially don't worry about doing fusion
14130 (define_insn "fma<mode>4_hw"
14131   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14132         (fma:IEEE128
14133          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14134          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14135          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14136   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14137   "xsmaddqp %0,%1,%2"
14138   [(set_attr "type" "qmul")
14139    (set_attr "size" "128")])
14141 (define_insn "*fms<mode>4_hw"
14142   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14143         (fma:IEEE128
14144          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14145          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14146          (neg:IEEE128
14147           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14148   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14149   "xsmsubqp %0,%1,%2"
14150   [(set_attr "type" "qmul")
14151    (set_attr "size" "128")])
14153 (define_insn "*nfma<mode>4_hw"
14154   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14155         (neg:IEEE128
14156          (fma:IEEE128
14157           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14158           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14159           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14160   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14161   "xsnmaddqp %0,%1,%2"
14162   [(set_attr "type" "qmul")
14163    (set_attr "size" "128")])
14165 (define_insn "*nfms<mode>4_hw"
14166   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14167         (neg:IEEE128
14168          (fma:IEEE128
14169           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14170           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14171           (neg:IEEE128
14172            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14173   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14174   "xsnmsubqp %0,%1,%2"
14175   [(set_attr "type" "qmul")
14176    (set_attr "size" "128")])
14178 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14179   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14180         (float_extend:IEEE128
14181          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14182   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14183   "xscvdpqp %0,%1"
14184   [(set_attr "type" "vecfloat")
14185    (set_attr "size" "128")])
14187 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14188 ;; point is a simple copy.
14189 (define_insn_and_split "extendkftf2"
14190   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14191         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14192   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14193   "@
14194    #
14195    xxlor %x0,%x1,%x1"
14196   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14197   [(const_int 0)]
14199   emit_note (NOTE_INSN_DELETED);
14200   DONE;
14202   [(set_attr "type" "*,veclogical")
14203    (set_attr "length" "0,4")])
14205 (define_insn_and_split "trunctfkf2"
14206   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14207         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14208   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14209   "@
14210    #
14211    xxlor %x0,%x1,%x1"
14212   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14213   [(const_int 0)]
14215   emit_note (NOTE_INSN_DELETED);
14216   DONE;
14218   [(set_attr "type" "*,veclogical")
14219    (set_attr "length" "0,4")])
14221 (define_insn "trunc<mode>df2_hw"
14222   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14223         (float_truncate:DF
14224          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14225   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14226   "xscvqpdp %0,%1"
14227   [(set_attr "type" "vecfloat")
14228    (set_attr "size" "128")])
14230 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14231 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14232 ;; conversion
14233 (define_insn_and_split "trunc<mode>sf2_hw"
14234   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14235         (float_truncate:SF
14236          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14237    (clobber (match_scratch:DF 2 "=v"))]
14238   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14239   "#"
14240   "&& 1"
14241   [(set (match_dup 2)
14242         (unspec:DF [(match_dup 1)]
14243                    UNSPEC_TRUNC_ROUND_TO_ODD))
14244    (set (match_dup 0)
14245         (float_truncate:SF (match_dup 2)))]
14247   if (GET_CODE (operands[2]) == SCRATCH)
14248     operands[2] = gen_reg_rtx (DFmode);
14250   [(set_attr "type" "vecfloat")
14251    (set_attr "length" "8")])
14253 ;; Conversion between IEEE 128-bit and integer types
14255 ;; The fix function for DImode and SImode was declared earlier as a
14256 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14257 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14258 ;; unless we have the IEEE 128-bit hardware.
14260 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14261 ;; to provide a GPR target that used direct move and a conversion in the GPR
14262 ;; which works around QImode/HImode not being allowed in vector registers in
14263 ;; ISA 2.07 (power8).
14264 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14265   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14266         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14267   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14268   "xscvqp<su><wd>z %0,%1"
14269   [(set_attr "type" "vecfloat")
14270    (set_attr "size" "128")])
14272 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14273   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14274         (any_fix:QHI
14275          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14276   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14277   "xscvqp<su>wz %0,%1"
14278   [(set_attr "type" "vecfloat")
14279    (set_attr "size" "128")])
14281 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14282 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14283 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14284   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14285         (any_fix:QHSI
14286          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14287    (clobber (match_scratch:QHSI 2 "=v"))]
14288   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14289   "#"
14290   "&& reload_completed"
14291   [(set (match_dup 2)
14292         (any_fix:QHSI (match_dup 1)))
14293    (set (match_dup 0)
14294         (match_dup 2))])
14296 (define_insn "float_<mode>di2_hw"
14297   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14299   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14300   "xscvsdqp %0,%1"
14301   [(set_attr "type" "vecfloat")
14302    (set_attr "size" "128")])
14304 (define_insn_and_split "float_<mode>si2_hw"
14305   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14306         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14307    (clobber (match_scratch:DI 2 "=v"))]
14308   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14309   "#"
14310   "&& 1"
14311   [(set (match_dup 2)
14312         (sign_extend:DI (match_dup 1)))
14313    (set (match_dup 0)
14314         (float:IEEE128 (match_dup 2)))]
14316   if (GET_CODE (operands[2]) == SCRATCH)
14317     operands[2] = gen_reg_rtx (DImode);
14319   if (MEM_P (operands[1]))
14320     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14323 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14324   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14325         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14326    (clobber (match_scratch:DI 2 "=X,r,X"))]
14327   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14328   "#"
14329   "&& reload_completed"
14330   [(const_int 0)]
14332   rtx dest = operands[0];
14333   rtx src = operands[1];
14334   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14336   if (altivec_register_operand (src, <QHI:MODE>mode))
14337     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14338   else if (int_reg_operand (src, <QHI:MODE>mode))
14339     {
14340       rtx ext_di = operands[2];
14341       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14342       emit_move_insn (dest_di, ext_di);
14343     }
14344   else if (MEM_P (src))
14345     {
14346       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14347       emit_move_insn (dest_qhi, src);
14348       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14349     }
14350   else
14351     gcc_unreachable ();
14353   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14354   DONE;
14356   [(set_attr "length" "8,12,12")
14357    (set_attr "type" "vecfloat")
14358    (set_attr "size" "128")])
14360 (define_insn "floatuns_<mode>di2_hw"
14361   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14362         (unsigned_float:IEEE128
14363          (match_operand:DI 1 "altivec_register_operand" "v")))]
14364   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14365   "xscvudqp %0,%1"
14366   [(set_attr "type" "vecfloat")
14367    (set_attr "size" "128")])
14369 (define_insn_and_split "floatuns_<mode>si2_hw"
14370   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14371         (unsigned_float:IEEE128
14372          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14373    (clobber (match_scratch:DI 2 "=v"))]
14374   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14375   "#"
14376   "&& 1"
14377   [(set (match_dup 2)
14378         (zero_extend:DI (match_dup 1)))
14379    (set (match_dup 0)
14380         (float:IEEE128 (match_dup 2)))]
14382   if (GET_CODE (operands[2]) == SCRATCH)
14383     operands[2] = gen_reg_rtx (DImode);
14385   if (MEM_P (operands[1]))
14386     operands[1] = rs6000_address_for_fpconvert (operands[1]);
14389 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14390   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14391         (unsigned_float:IEEE128
14392          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14393    (clobber (match_scratch:DI 2 "=X,r,X"))]
14394   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14395   "#"
14396   "&& reload_completed"
14397   [(const_int 0)]
14399   rtx dest = operands[0];
14400   rtx src = operands[1];
14401   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14403   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14404     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14405   else if (int_reg_operand (src, <QHI:MODE>mode))
14406     {
14407       rtx ext_di = operands[2];
14408       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14409       emit_move_insn (dest_di, ext_di);
14410     }
14411   else
14412     gcc_unreachable ();
14414   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14415   DONE;
14417   [(set_attr "length" "8,12,8")
14418    (set_attr "type" "vecfloat")
14419    (set_attr "size" "128")])
14421 ;; IEEE 128-bit round to integer built-in functions
14422 (define_insn "floor<mode>2"
14423   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14424         (unspec:IEEE128
14425          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14426          UNSPEC_FRIM))]
14427   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14428   "xsrqpi 1,%0,%1,3"
14429   [(set_attr "type" "vecfloat")
14430    (set_attr "size" "128")])
14432 (define_insn "ceil<mode>2"
14433   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14434         (unspec:IEEE128
14435          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14436          UNSPEC_FRIP))]
14437   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14438   "xsrqpi 1,%0,%1,2"
14439   [(set_attr "type" "vecfloat")
14440    (set_attr "size" "128")])
14442 (define_insn "btrunc<mode>2"
14443   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14444         (unspec:IEEE128
14445          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14446          UNSPEC_FRIZ))]
14447   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14448   "xsrqpi 1,%0,%1,1"
14449   [(set_attr "type" "vecfloat")
14450    (set_attr "size" "128")])
14452 (define_insn "round<mode>2"
14453   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14454         (unspec:IEEE128
14455          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14456          UNSPEC_FRIN))]
14457   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14458   "xsrqpi 0,%0,%1,0"
14459   [(set_attr "type" "vecfloat")
14460    (set_attr "size" "128")])
14462 ;; IEEE 128-bit instructions with round to odd semantics
14463 (define_insn "add<mode>3_odd"
14464   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14465         (unspec:IEEE128
14466          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14467           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14468          UNSPEC_ADD_ROUND_TO_ODD))]
14469   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14470   "xsaddqpo %0,%1,%2"
14471   [(set_attr "type" "vecfloat")
14472    (set_attr "size" "128")])
14474 (define_insn "sub<mode>3_odd"
14475   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14476         (unspec:IEEE128
14477          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14478           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14479          UNSPEC_SUB_ROUND_TO_ODD))]
14480   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14481   "xssubqpo %0,%1,%2"
14482   [(set_attr "type" "vecfloat")
14483    (set_attr "size" "128")])
14485 (define_insn "mul<mode>3_odd"
14486   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14487         (unspec:IEEE128
14488          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14489           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14490          UNSPEC_MUL_ROUND_TO_ODD))]
14491   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14492   "xsmulqpo %0,%1,%2"
14493   [(set_attr "type" "qmul")
14494    (set_attr "size" "128")])
14496 (define_insn "div<mode>3_odd"
14497   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14498         (unspec:IEEE128
14499          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14500           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14501          UNSPEC_DIV_ROUND_TO_ODD))]
14502   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14503   "xsdivqpo %0,%1,%2"
14504   [(set_attr "type" "vecdiv")
14505    (set_attr "size" "128")])
14507 (define_insn "sqrt<mode>2_odd"
14508   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14509         (unspec:IEEE128
14510          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14511          UNSPEC_SQRT_ROUND_TO_ODD))]
14512   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14513    "xssqrtqpo %0,%1"
14514   [(set_attr "type" "vecdiv")
14515    (set_attr "size" "128")])
14517 (define_insn "fma<mode>4_odd"
14518   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14519         (unspec:IEEE128
14520          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14521           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14522           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14523          UNSPEC_FMA_ROUND_TO_ODD))]
14524   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14525   "xsmaddqpo %0,%1,%2"
14526   [(set_attr "type" "qmul")
14527    (set_attr "size" "128")])
14529 (define_insn "*fms<mode>4_odd"
14530   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14531         (unspec:IEEE128
14532          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14533           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14534           (neg:IEEE128
14535            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14536          UNSPEC_FMA_ROUND_TO_ODD))]
14537   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14538   "xsmsubqpo %0,%1,%2"
14539   [(set_attr "type" "qmul")
14540    (set_attr "size" "128")])
14542 (define_insn "*nfma<mode>4_odd"
14543   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14544         (neg:IEEE128
14545          (unspec:IEEE128
14546           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14547            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14548            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14549           UNSPEC_FMA_ROUND_TO_ODD)))]
14550   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14551   "xsnmaddqpo %0,%1,%2"
14552   [(set_attr "type" "qmul")
14553    (set_attr "size" "128")])
14555 (define_insn "*nfms<mode>4_odd"
14556   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14557         (neg:IEEE128
14558          (unspec:IEEE128
14559           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14560            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14561            (neg:IEEE128
14562             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14563           UNSPEC_FMA_ROUND_TO_ODD)))]
14564   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14565   "xsnmsubqpo %0,%1,%2"
14566   [(set_attr "type" "qmul")
14567    (set_attr "size" "128")])
14569 (define_insn "trunc<mode>df2_odd"
14570   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14571         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14572                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14573   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14574   "xscvqpdpo %0,%1"
14575   [(set_attr "type" "vecfloat")
14576    (set_attr "size" "128")])
14578 ;; IEEE 128-bit comparisons
14579 (define_insn "*cmp<mode>_hw"
14580   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14581         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14582                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14583   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14584    "xscmpuqp %0,%1,%2"
14585   [(set_attr "type" "veccmp")
14586    (set_attr "size" "128")])
14590 (include "sync.md")
14591 (include "vector.md")
14592 (include "vsx.md")
14593 (include "altivec.md")
14594 (include "dfp.md")
14595 (include "crypto.md")
14596 (include "htm.md")