Rename -mprefixed-addr to be -mprefixed, and document it.
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob3da7b1ed9c2a9a25afdb7bc81f530ef08b21e6d1
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2020 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    (FIRST_ALTIVEC_REGNO         64)
37    (LAST_ALTIVEC_REGNO          95)
38    (LR_REGNO                    96)
39    (CTR_REGNO                   97)
40    (CA_REGNO                    98)
41    (ARG_POINTER_REGNUM          99)
42    (CR0_REGNO                   100)
43    (CR1_REGNO                   101)
44    (CR2_REGNO                   102)
45    (CR3_REGNO                   103)
46    (CR4_REGNO                   104)
47    (CR5_REGNO                   105)
48    (CR6_REGNO                   106)
49    (CR7_REGNO                   107)
50    (MAX_CR_REGNO                107)
51    (VRSAVE_REGNO                108)
52    (VSCR_REGNO                  109)
53    (FRAME_POINTER_REGNUM        110)
54   ])
57 ;; UNSPEC usage
60 (define_c_enum "unspec"
61   [UNSPEC_PROBE_STACK           ; probe stack memory reference
62    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
63    UNSPEC_TOC                   ; address of the TOC (more-or-less)
64    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
65    UNSPEC_MOVSI_GOT
66    UNSPEC_FCTIWZ
67    UNSPEC_FRIM
68    UNSPEC_FRIN
69    UNSPEC_FRIP
70    UNSPEC_FRIZ
71    UNSPEC_XSRDPI
72    UNSPEC_LD_MPIC               ; load_macho_picbase
73    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
74    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
75    UNSPEC_TLSGD
76    UNSPEC_TLSLD
77    UNSPEC_TLS_GET_ADDR
78    UNSPEC_MOVESI_FROM_CR
79    UNSPEC_MOVESI_TO_CR
80    UNSPEC_TLSDTPREL
81    UNSPEC_TLSDTPRELHA
82    UNSPEC_TLSDTPRELLO
83    UNSPEC_TLSGOTDTPREL
84    UNSPEC_TLSTPREL
85    UNSPEC_TLSTPRELHA
86    UNSPEC_TLSTPRELLO
87    UNSPEC_TLSGOTTPREL
88    UNSPEC_TLSTLS
89    UNSPEC_TLSTLS_PCREL
90    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
91    UNSPEC_STFIWX
92    UNSPEC_POPCNTB
93    UNSPEC_FRES
94    UNSPEC_SP_SET
95    UNSPEC_SP_TEST
96    UNSPEC_SYNC
97    UNSPEC_LWSYNC
98    UNSPEC_SYNC_OP
99    UNSPEC_ATOMIC
100    UNSPEC_CMPXCHG
101    UNSPEC_XCHG
102    UNSPEC_AND
103    UNSPEC_DLMZB
104    UNSPEC_DLMZB_CR
105    UNSPEC_DLMZB_STRLEN
106    UNSPEC_RSQRT
107    UNSPEC_TOCREL
108    UNSPEC_MACHOPIC_OFFSET
109    UNSPEC_BPERM
110    UNSPEC_COPYSIGN
111    UNSPEC_PARITY
112    UNSPEC_CMPB
113    UNSPEC_FCTIW
114    UNSPEC_FCTID
115    UNSPEC_LFIWAX
116    UNSPEC_LFIWZX
117    UNSPEC_FCTIWUZ
118    UNSPEC_NOP
119    UNSPEC_GRP_END_NOP
120    UNSPEC_P8V_FMRGOW
121    UNSPEC_P8V_MTVSRWZ
122    UNSPEC_P8V_RELOAD_FROM_GPR
123    UNSPEC_P8V_MTVSRD
124    UNSPEC_P8V_XXPERMDI
125    UNSPEC_P8V_RELOAD_FROM_VSX
126    UNSPEC_ADDG6S
127    UNSPEC_CDTBCD
128    UNSPEC_CBCDTD
129    UNSPEC_DIVE
130    UNSPEC_DIVEU
131    UNSPEC_UNPACK_128BIT
132    UNSPEC_PACK_128BIT
133    UNSPEC_LSQ
134    UNSPEC_FUSION_GPR
135    UNSPEC_STACK_CHECK
136    UNSPEC_CMPRB
137    UNSPEC_CMPRB2
138    UNSPEC_CMPEQB
139    UNSPEC_ADD_ROUND_TO_ODD
140    UNSPEC_SUB_ROUND_TO_ODD
141    UNSPEC_MUL_ROUND_TO_ODD
142    UNSPEC_DIV_ROUND_TO_ODD
143    UNSPEC_FMA_ROUND_TO_ODD
144    UNSPEC_SQRT_ROUND_TO_ODD
145    UNSPEC_TRUNC_ROUND_TO_ODD
146    UNSPEC_SIGNBIT
147    UNSPEC_SF_FROM_SI
148    UNSPEC_SI_FROM_SF
149    UNSPEC_PLTSEQ
150    UNSPEC_PLT16_HA
151    UNSPEC_PLT16_LO
152    UNSPEC_PLT_PCREL
153   ])
156 ;; UNSPEC_VOLATILE usage
159 (define_c_enum "unspecv"
160   [UNSPECV_BLOCK
161    UNSPECV_LL                   ; load-locked
162    UNSPECV_SC                   ; store-conditional
163    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
164    UNSPECV_EH_RR                ; eh_reg_restore
165    UNSPECV_ISYNC                ; isync instruction
166    UNSPECV_MFTB                 ; move from time base
167    UNSPECV_DARN                 ; darn 1 (deliver a random number)
168    UNSPECV_DARN_32              ; darn 2
169    UNSPECV_DARN_RAW             ; darn 0
170    UNSPECV_NLGR                 ; non-local goto receiver
171    UNSPECV_MFFS                 ; Move from FPSCR
172    UNSPECV_MFFSL                ; Move from FPSCR light instruction version
173    UNSPECV_MFFSCRN              ; Move from FPSCR float rounding mode
174    UNSPECV_MFFSCDRN             ; Move from FPSCR decimal float rounding mode
175    UNSPECV_MTFSF                ; Move to FPSCR Fields 8 to 15
176    UNSPECV_MTFSF_HI             ; Move to FPSCR Fields 0 to 7
177    UNSPECV_MTFSB0               ; Set FPSCR Field bit to 0
178    UNSPECV_MTFSB1               ; Set FPSCR Field bit to 1
179    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
180    UNSPECV_SPEC_BARRIER         ; Speculation barrier
181   ])
183 ; The three different kinds of epilogue.
184 (define_enum "epilogue_type" [normal sibcall eh_return])
186 ;; Define an insn type attribute.  This is used in function unit delay
187 ;; computations.
188 (define_attr "type"
189   "integer,two,three,
190    add,logical,shift,insert,
191    mul,halfmul,div,
192    exts,cntlz,popcnt,isel,
193    load,store,fpload,fpstore,vecload,vecstore,
194    cmp,
195    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
196    cr_logical,mfcr,mfcrf,mtcr,
197    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
198    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
199    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
200    veclogical,veccmpfx,vecexts,vecmove,
201    htm,htmsimple,dfp"
202   (const_string "integer"))
204 ;; What data size does this instruction work on?
205 ;; This is used for insert, mul and others as necessary.
206 (define_attr "size" "8,16,32,64,128" (const_string "32"))
208 ;; What is the insn_cost for this insn?  The target hook can still override
209 ;; this.  For optimizing for size the "length" attribute is used instead.
210 (define_attr "cost" "" (const_int 0))
212 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
213 ;; This is used for add, logical, shift, exts, mul.
214 (define_attr "dot" "no,yes" (const_string "no"))
216 ;; Does this instruction sign-extend its result?
217 ;; This is used for load insns.
218 (define_attr "sign_extend" "no,yes" (const_string "no"))
220 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
221 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
223 ;; Does this instruction use indexed (that is, reg+reg) addressing?
224 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
225 ;; it is automatically set based on that.  If a load or store instruction
226 ;; has fewer than two operands it needs to set this attribute manually
227 ;; or the compiler will crash.
228 (define_attr "indexed" "no,yes"
229   (if_then_else (ior (match_operand 0 "indexed_address_mem")
230                      (match_operand 1 "indexed_address_mem"))
231                 (const_string "yes")
232                 (const_string "no")))
234 ;; Does this instruction use update addressing?
235 ;; This is used for load and store insns.  See the comments for "indexed".
236 (define_attr "update" "no,yes"
237   (if_then_else (ior (match_operand 0 "update_address_mem")
238                      (match_operand 1 "update_address_mem"))
239                 (const_string "yes")
240                 (const_string "no")))
242 ;; Is this instruction using operands[2] as shift amount, and can that be a
243 ;; register?
244 ;; This is used for shift insns.
245 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
247 ;; Is this instruction using a shift amount from a register?
248 ;; This is used for shift insns.
249 (define_attr "var_shift" "no,yes"
250   (if_then_else (and (eq_attr "type" "shift")
251                      (eq_attr "maybe_var_shift" "yes"))
252                 (if_then_else (match_operand 2 "gpc_reg_operand")
253                               (const_string "yes")
254                               (const_string "no"))
255                 (const_string "no")))
257 ;; Is copying of this instruction disallowed?
258 (define_attr "cannot_copy" "no,yes" (const_string "no"))
261 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
262 ;; before the instruction.  A prefixed instruction has a prefix instruction
263 ;; word that extends the immediate value of the instructions from 12-16 bits to
264 ;; 34 bits.  The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
265 ;; insns.  The default "length" attribute will also be adjusted by default to
266 ;; be 12 bytes.
267 (define_attr "prefixed" "no,yes"
268   (cond [(ior (match_test "!TARGET_PREFIXED")
269               (match_test "!NONJUMP_INSN_P (insn)"))
270          (const_string "no")
272          (eq_attr "type" "load,fpload,vecload")
273          (if_then_else (match_test "prefixed_load_p (insn)")
274                        (const_string "yes")
275                        (const_string "no"))
277          (eq_attr "type" "store,fpstore,vecstore")
278          (if_then_else (match_test "prefixed_store_p (insn)")
279                        (const_string "yes")
280                        (const_string "no"))
282          (eq_attr "type" "integer,add")
283          (if_then_else (match_test "prefixed_paddi_p (insn)")
284                        (const_string "yes")
285                        (const_string "no"))]
287         (const_string "no")))
289 ;; Return the number of real hardware instructions in a combined insn.  If it
290 ;; is 0, just use the length / 4.
291 (define_attr "num_insns" "" (const_int 0))
293 ;; If an insn is prefixed, return the maximum number of prefixed instructions
294 ;; in the insn.  The macro ADJUST_INSN_LENGTH uses this number to adjust the
295 ;; insn length.
296 (define_attr "max_prefixed_insns" "" (const_int 1))
298 ;; Length of the instruction (in bytes).  This length does not consider the
299 ;; length for prefixed instructions.  The macro ADJUST_INSN_LENGTH will adjust
300 ;; the length if there are prefixed instructions.
302 ;; While it might be tempting to use num_insns to calculate the length, it can
303 ;; be problematical unless all insn lengths are adjusted to use num_insns
304 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
305 ;; num_insns and recurse).
306 (define_attr "length" "" (const_int 4))
308 ;; Processor type -- this attribute must exactly match the processor_type
309 ;; enumeration in rs6000-opts.h.
310 (define_attr "cpu"
311   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
312    ppc750,ppc7400,ppc7450,
313    ppc403,ppc405,ppc440,ppc476,
314    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
315    power4,power5,power6,power7,power8,power9,future,
316    rs64a,mpccore,cell,ppca2,titan"
317   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
319 ;; The ISA we implement.
320 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
321   (const_string "any"))
323 ;; Is this alternative enabled for the current CPU/ISA/etc.?
324 (define_attr "enabled" ""
325   (cond
326     [(eq_attr "isa" "any")
327      (const_int 1)
329      (and (eq_attr "isa" "p5")
330           (match_test "TARGET_POPCNTB"))
331      (const_int 1)
333      (and (eq_attr "isa" "p6")
334           (match_test "TARGET_CMPB"))
335      (const_int 1)
337      (and (eq_attr "isa" "p7")
338           (match_test "TARGET_POPCNTD"))
339      (const_int 1)
341      (and (eq_attr "isa" "p7v")
342           (match_test "TARGET_VSX"))
343      (const_int 1)
345      (and (eq_attr "isa" "p8v")
346           (match_test "TARGET_P8_VECTOR"))
347      (const_int 1)
349      (and (eq_attr "isa" "p9v")
350           (match_test "TARGET_P9_VECTOR"))
351      (const_int 1)
353      (and (eq_attr "isa" "p9kf")
354           (match_test "TARGET_FLOAT128_TYPE"))
355      (const_int 1)
357      (and (eq_attr "isa" "p9tf")
358           (match_test "FLOAT128_VECTOR_P (TFmode)"))
359      (const_int 1)
361      (and (eq_attr "isa" "fut")
362           (match_test "TARGET_FUTURE"))
363      (const_int 1)
364     ] (const_int 0)))
366 ;; If this instruction is microcoded on the CELL processor
367 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
368 (define_attr "cell_micro" "not,conditional,always"
369   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
370                           (eq_attr "dot" "yes"))
371                      (and (eq_attr "type" "load")
372                           (eq_attr "sign_extend" "yes"))
373                      (and (eq_attr "type" "shift")
374                           (eq_attr "var_shift" "yes")))
375                 (const_string "always")
376                 (const_string "not")))
378 (automata_option "ndfa")
380 (include "rs64.md")
381 (include "mpc.md")
382 (include "40x.md")
383 (include "440.md")
384 (include "476.md")
385 (include "601.md")
386 (include "603.md")
387 (include "6xx.md")
388 (include "7xx.md")
389 (include "7450.md")
390 (include "8540.md")
391 (include "e300c2c3.md")
392 (include "e500mc.md")
393 (include "e500mc64.md")
394 (include "e5500.md")
395 (include "e6500.md")
396 (include "power4.md")
397 (include "power5.md")
398 (include "power6.md")
399 (include "power7.md")
400 (include "power8.md")
401 (include "power9.md")
402 (include "future.md")
403 (include "cell.md")
404 (include "a2.md")
405 (include "titan.md")
407 (include "predicates.md")
408 (include "constraints.md")
411 ;; Mode iterators
413 ; This mode iterator allows :GPR to be used to indicate the allowable size
414 ; of whole values in GPRs.
415 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
417 ; And again, for patterns that need two (potentially) different integer modes.
418 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
420 ; Any supported integer mode.
421 (define_mode_iterator INT [QI HI SI DI TI PTI])
423 ; Any supported integer mode that fits in one register.
424 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
426 ; Integer modes supported in VSX registers with ISA 3.0 instructions
427 (define_mode_iterator INT_ISA3 [QI HI SI DI])
429 ; Everything we can extend QImode to.
430 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
432 ; Everything we can extend HImode to.
433 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
435 ; Everything we can extend SImode to.
436 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
438 ; QImode or HImode for small integer moves and small atomic ops
439 (define_mode_iterator QHI [QI HI])
441 ; QImode, HImode, SImode for fused ops only for GPR loads
442 (define_mode_iterator QHSI [QI HI SI])
444 ; HImode or SImode for sign extended fusion ops
445 (define_mode_iterator HSI [HI SI])
447 ; SImode or DImode, even if DImode doesn't fit in GPRs.
448 (define_mode_iterator SDI [SI DI])
450 ; The size of a pointer.  Also, the size of the value that a record-condition
451 ; (one with a '.') will compare; and the size used for arithmetic carries.
452 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
454 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
455 ; PTImode is GPR only)
456 (define_mode_iterator TI2 [TI PTI])
458 ; Any hardware-supported floating-point mode
459 (define_mode_iterator FP [
460   (SF "TARGET_HARD_FLOAT")
461   (DF "TARGET_HARD_FLOAT")
462   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
463   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
464   (KF "TARGET_FLOAT128_TYPE")
465   (DD "TARGET_DFP")
466   (TD "TARGET_DFP")])
468 ; Any fma capable floating-point mode.
469 (define_mode_iterator FMA_F [
470   (SF "TARGET_HARD_FLOAT")
471   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
472   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
473   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
474   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
475   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
476   ])
478 ; Floating point move iterators to combine binary and decimal moves
479 (define_mode_iterator FMOVE32 [SF SD])
480 (define_mode_iterator FMOVE64 [DF DD])
481 (define_mode_iterator FMOVE64X [DI DF DD])
482 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
483                                 (IF "FLOAT128_IBM_P (IFmode)")
484                                 (TD "TARGET_HARD_FLOAT")])
486 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
487                                     (IF "FLOAT128_2REG_P (IFmode)")
488                                     (TD "TARGET_HARD_FLOAT")])
490 ; Iterators for 128 bit types for direct move
491 (define_mode_iterator FMOVE128_GPR [TI
492                                     V16QI
493                                     V8HI
494                                     V4SI
495                                     V4SF
496                                     V2DI
497                                     V2DF
498                                     V1TI
499                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
500                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
502 ; Iterator for 128-bit VSX types for pack/unpack
503 (define_mode_iterator FMOVE128_VSX [V1TI KF])
505 ; Iterators for converting to/from TFmode
506 (define_mode_iterator IFKF [IF KF])
508 ; Constraints for moving IF/KFmode.
509 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
511 ; Whether a floating point move is ok, don't allow SD without hardware FP
512 (define_mode_attr fmove_ok [(SF "")
513                             (DF "")
514                             (SD "TARGET_HARD_FLOAT")
515                             (DD "")])
517 ; Convert REAL_VALUE to the appropriate bits
518 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
519                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
520                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
521                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
523 ; Whether 0.0 has an all-zero bit pattern
524 (define_mode_attr zero_fp [(SF "j")
525                            (DF "j")
526                            (TF "j")
527                            (IF "j")
528                            (KF "j")
529                            (SD "wn")
530                            (DD "wn")
531                            (TD "wn")])
533 ; Definitions for 64-bit VSX
534 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
536 ; Definitions for 64-bit direct move
537 (define_mode_attr f64_dm  [(DF "wa") (DD "d")])
539 ; Definitions for 64-bit use of altivec registers
540 (define_mode_attr f64_av  [(DF "v") (DD "wn")])
542 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
543 (define_mode_attr f64_p9  [(DF "v") (DD "wn")])
545 ; These modes do not fit in integer registers in 32-bit mode.
546 (define_mode_iterator DIFD [DI DF DD])
548 ; Iterator for reciprocal estimate instructions
549 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
551 ; SFmode or DFmode.
552 (define_mode_iterator SFDF [SF DF])
554 ; And again, for when we need two FP modes in a pattern.
555 (define_mode_iterator SFDF2 [SF DF])
557 ; A generic s/d attribute, for sp/dp for example.
558 (define_mode_attr sd [(SF   "s") (DF   "d")
559                       (V4SF "s") (V2DF "d")])
561 ; "s" or nothing, for fmuls/fmul for example.
562 (define_mode_attr s [(SF "s") (DF "")])
564 ; Iterator for 128-bit floating point that uses the IBM double-double format
565 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
566                               (TF "FLOAT128_IBM_P (TFmode)")])
568 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
569 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
570                                (TF "FLOAT128_IEEE_P (TFmode)")])
572 ; Iterator for 128-bit floating point
573 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
574                                 (IF "TARGET_FLOAT128_TYPE")
575                                 (TF "TARGET_LONG_DOUBLE_128")])
577 ; Iterator for signbit on 64-bit machines with direct move
578 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
579                                (TF "FLOAT128_VECTOR_P (TFmode)")])
581 ; Iterator for ISA 3.0 supported floating point types
582 (define_mode_iterator FP_ISA3 [SF DF])
584 ; SF/DF constraint for arithmetic on traditional floating point registers
585 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
587 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
588 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
589 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
590 ; format.
591 (define_mode_attr Fv            [(SF "wa") (DF "wa") (DI "wa")])
593 ; Which isa is needed for those float instructions?
594 (define_mode_attr Fisa          [(SF "p8v")  (DF "*") (DI "*")])
596 ; FRE/FRES support
597 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
599 ; Conditional returns.
600 (define_code_iterator any_return [return simple_return])
601 (define_code_attr return_pred [(return "direct_return ()")
602                                (simple_return "1")])
603 (define_code_attr return_str [(return "") (simple_return "simple_")])
605 ; Logical operators.
606 (define_code_iterator iorxor            [ior xor])
607 (define_code_iterator and_ior_xor       [and ior xor])
609 ; Signed/unsigned variants of ops.
610 (define_code_iterator any_extend        [sign_extend zero_extend])
611 (define_code_iterator any_fix           [fix unsigned_fix])
612 (define_code_iterator any_float         [float unsigned_float])
614 (define_code_attr u  [(sign_extend      "")
615                       (zero_extend      "u")
616                       (fix              "")
617                       (unsigned_fix     "u")])
619 (define_code_attr su [(sign_extend      "s")
620                       (zero_extend      "u")
621                       (fix              "s")
622                       (unsigned_fix     "u")
623                       (float            "s")
624                       (unsigned_float   "u")])
626 (define_code_attr az [(sign_extend      "a")
627                       (zero_extend      "z")
628                       (fix              "a")
629                       (unsigned_fix     "z")
630                       (float            "a")
631                       (unsigned_float   "z")])
633 (define_code_attr uns [(fix             "")
634                        (unsigned_fix    "uns")
635                        (float           "")
636                        (unsigned_float  "uns")])
638 ; Various instructions that come in SI and DI forms.
639 ; A generic w/d attribute, for things like cmpw/cmpd.
640 (define_mode_attr wd [(QI    "b")
641                       (HI    "h")
642                       (SI    "w")
643                       (DI    "d")
644                       (V16QI "b")
645                       (V8HI  "h")
646                       (V4SI  "w")
647                       (V2DI  "d")
648                       (V1TI  "q")
649                       (TI    "q")])
651 ;; How many bits in this mode?
652 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
653                                            (SF "32") (DF "64")])
655 ; DImode bits
656 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
658 ;; Bitmask for shift instructions
659 (define_mode_attr hH [(SI "h") (DI "H")])
661 ;; A mode twice the size of the given mode
662 (define_mode_attr dmode [(SI "di") (DI "ti")])
663 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
665 ;; Suffix for reload patterns
666 (define_mode_attr ptrsize [(SI "32bit")
667                            (DI "64bit")])
669 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
670                             (DI "TARGET_64BIT")])
672 (define_mode_attr mptrsize [(SI "si")
673                             (DI "di")])
675 (define_mode_attr ptrload [(SI "lwz")
676                            (DI "ld")])
678 (define_mode_attr ptrm [(SI "m")
679                         (DI "Y")])
681 (define_mode_attr rreg [(SF   "f")
682                         (DF   "wa")
683                         (TF   "f")
684                         (TD   "f")
685                         (V4SF "wa")
686                         (V2DF "wa")])
688 (define_mode_attr rreg2 [(SF   "f")
689                          (DF   "d")])
691 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
692                                  (DF "TARGET_FCFID")])
694 ;; Mode iterator for logical operations on 128-bit types
695 (define_mode_iterator BOOL_128          [TI
696                                          PTI
697                                          (V16QI "TARGET_ALTIVEC")
698                                          (V8HI  "TARGET_ALTIVEC")
699                                          (V4SI  "TARGET_ALTIVEC")
700                                          (V4SF  "TARGET_ALTIVEC")
701                                          (V2DI  "TARGET_ALTIVEC")
702                                          (V2DF  "TARGET_ALTIVEC")
703                                          (V1TI  "TARGET_ALTIVEC")])
705 ;; For the GPRs we use 3 constraints for register outputs, two that are the
706 ;; same as the output register, and a third where the output register is an
707 ;; early clobber, so we don't have to deal with register overlaps.  For the
708 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
709 ;; either.
711 ;; Mode attribute for boolean operation register constraints for output
712 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wa,v")
713                                          (PTI   "&r,r,r")
714                                          (V16QI "wa,v,&?r,?r,?r")
715                                          (V8HI  "wa,v,&?r,?r,?r")
716                                          (V4SI  "wa,v,&?r,?r,?r")
717                                          (V4SF  "wa,v,&?r,?r,?r")
718                                          (V2DI  "wa,v,&?r,?r,?r")
719                                          (V2DF  "wa,v,&?r,?r,?r")
720                                          (V1TI  "wa,v,&?r,?r,?r")])
722 ;; Mode attribute for boolean operation register constraints for operand1
723 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wa,v")
724                                          (PTI   "r,0,r")
725                                          (V16QI "wa,v,r,0,r")
726                                          (V8HI  "wa,v,r,0,r")
727                                          (V4SI  "wa,v,r,0,r")
728                                          (V4SF  "wa,v,r,0,r")
729                                          (V2DI  "wa,v,r,0,r")
730                                          (V2DF  "wa,v,r,0,r")
731                                          (V1TI  "wa,v,r,0,r")])
733 ;; Mode attribute for boolean operation register constraints for operand2
734 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wa,v")
735                                          (PTI   "r,r,0")
736                                          (V16QI "wa,v,r,r,0")
737                                          (V8HI  "wa,v,r,r,0")
738                                          (V4SI  "wa,v,r,r,0")
739                                          (V4SF  "wa,v,r,r,0")
740                                          (V2DI  "wa,v,r,r,0")
741                                          (V2DF  "wa,v,r,r,0")
742                                          (V1TI  "wa,v,r,r,0")])
744 ;; Mode attribute for boolean operation register constraints for operand1
745 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
746 ;; is used for operand1 or operand2
747 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wa,v")
748                                          (PTI   "r,0,0")
749                                          (V16QI "wa,v,r,0,0")
750                                          (V8HI  "wa,v,r,0,0")
751                                          (V4SI  "wa,v,r,0,0")
752                                          (V4SF  "wa,v,r,0,0")
753                                          (V2DI  "wa,v,r,0,0")
754                                          (V2DF  "wa,v,r,0,0")
755                                          (V1TI  "wa,v,r,0,0")])
757 ;; Reload iterator for creating the function to allocate a base register to
758 ;; supplement addressing modes.
759 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
760                               SF SD SI DF DD DI TI PTI KF IF TF])
762 ;; Iterate over smin, smax
763 (define_code_iterator fp_minmax [smin smax])
765 (define_code_attr     minmax    [(smin "min")
766                                  (smax "max")])
768 (define_code_attr     SMINMAX   [(smin "SMIN")
769                                  (smax "SMAX")])
771 ;; Iterator to optimize the following cases:
772 ;;      D-form load to FPR register & move to Altivec register
773 ;;      Move Altivec register to FPR register and store
774 (define_mode_iterator ALTIVEC_DFORM [DF
775                                      (SF "TARGET_P8_VECTOR")
776                                      (DI "TARGET_POWERPC64")])
778 (include "darwin.md")
780 ;; Start with fixed-point load and store insns.  Here we put only the more
781 ;; complex forms.  Basic data transfer is done later.
783 (define_insn "zero_extendqi<mode>2"
784   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
785         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
786   ""
787   "@
788    lbz%U1%X1 %0,%1
789    rlwinm %0,%1,0,0xff
790    lxsibzx %x0,%y1
791    vextractub %0,%1,7"
792   [(set_attr "type" "load,shift,fpload,vecperm")
793    (set_attr "isa" "*,*,p9v,p9v")])
795 (define_insn_and_split "*zero_extendqi<mode>2_dot"
796   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
797         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
798                     (const_int 0)))
799    (clobber (match_scratch:EXTQI 0 "=r,r"))]
800   ""
801   "@
802    andi. %0,%1,0xff
803    #"
804   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
805   [(set (match_dup 0)
806         (zero_extend:EXTQI (match_dup 1)))
807    (set (match_dup 2)
808         (compare:CC (match_dup 0)
809                     (const_int 0)))]
810   ""
811   [(set_attr "type" "logical")
812    (set_attr "dot" "yes")
813    (set_attr "length" "4,8")])
815 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
816   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
817         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
818                     (const_int 0)))
819    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
820         (zero_extend:EXTQI (match_dup 1)))]
821   ""
822   "@
823    andi. %0,%1,0xff
824    #"
825   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
826   [(set (match_dup 0)
827         (zero_extend:EXTQI (match_dup 1)))
828    (set (match_dup 2)
829         (compare:CC (match_dup 0)
830                     (const_int 0)))]
831   ""
832   [(set_attr "type" "logical")
833    (set_attr "dot" "yes")
834    (set_attr "length" "4,8")])
837 (define_insn "zero_extendhi<mode>2"
838   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
839         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
840   ""
841   "@
842    lhz%U1%X1 %0,%1
843    rlwinm %0,%1,0,0xffff
844    lxsihzx %x0,%y1
845    vextractuh %0,%1,6"
846   [(set_attr "type" "load,shift,fpload,vecperm")
847    (set_attr "isa" "*,*,p9v,p9v")])
849 (define_insn_and_split "*zero_extendhi<mode>2_dot"
850   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
851         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
852                     (const_int 0)))
853    (clobber (match_scratch:EXTHI 0 "=r,r"))]
854   ""
855   "@
856    andi. %0,%1,0xffff
857    #"
858   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
859   [(set (match_dup 0)
860         (zero_extend:EXTHI (match_dup 1)))
861    (set (match_dup 2)
862         (compare:CC (match_dup 0)
863                     (const_int 0)))]
864   ""
865   [(set_attr "type" "logical")
866    (set_attr "dot" "yes")
867    (set_attr "length" "4,8")])
869 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
870   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
871         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
872                     (const_int 0)))
873    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
874         (zero_extend:EXTHI (match_dup 1)))]
875   ""
876   "@
877    andi. %0,%1,0xffff
878    #"
879   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
880   [(set (match_dup 0)
881         (zero_extend:EXTHI (match_dup 1)))
882    (set (match_dup 2)
883         (compare:CC (match_dup 0)
884                     (const_int 0)))]
885   ""
886   [(set_attr "type" "logical")
887    (set_attr "dot" "yes")
888    (set_attr "length" "4,8")])
891 (define_insn "zero_extendsi<mode>2"
892   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
893         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
894   ""
895   "@
896    lwz%U1%X1 %0,%1
897    rldicl %0,%1,0,32
898    lfiwzx %0,%y1
899    lxsiwzx %x0,%y1
900    mtvsrwz %x0,%1
901    mfvsrwz %0,%x1
902    xxextractuw %x0,%x1,4"
903   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
904    (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
906 (define_insn_and_split "*zero_extendsi<mode>2_dot"
907   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
909                     (const_int 0)))
910    (clobber (match_scratch:EXTSI 0 "=r,r"))]
911   ""
912   "@
913    rldicl. %0,%1,0,32
914    #"
915   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
916   [(set (match_dup 0)
917         (zero_extend:DI (match_dup 1)))
918    (set (match_dup 2)
919         (compare:CC (match_dup 0)
920                     (const_int 0)))]
921   ""
922   [(set_attr "type" "shift")
923    (set_attr "dot" "yes")
924    (set_attr "length" "4,8")])
926 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
927   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
928         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
929                     (const_int 0)))
930    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
931         (zero_extend:EXTSI (match_dup 1)))]
932   ""
933   "@
934    rldicl. %0,%1,0,32
935    #"
936   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
937   [(set (match_dup 0)
938         (zero_extend:EXTSI (match_dup 1)))
939    (set (match_dup 2)
940         (compare:CC (match_dup 0)
941                     (const_int 0)))]
942   ""
943   [(set_attr "type" "shift")
944    (set_attr "dot" "yes")
945    (set_attr "length" "4,8")])
948 (define_insn "extendqi<mode>2"
949   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
950         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
951   ""
952   "@
953    extsb %0,%1
954    vextsb2d %0,%1"
955   [(set_attr "type" "exts,vecperm")
956    (set_attr "isa" "*,p9v")])
958 (define_insn_and_split "*extendqi<mode>2_dot"
959   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
960         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
961                     (const_int 0)))
962    (clobber (match_scratch:EXTQI 0 "=r,r"))]
963   ""
964   "@
965    extsb. %0,%1
966    #"
967   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
968   [(set (match_dup 0)
969         (sign_extend:EXTQI (match_dup 1)))
970    (set (match_dup 2)
971         (compare:CC (match_dup 0)
972                     (const_int 0)))]
973   ""
974   [(set_attr "type" "exts")
975    (set_attr "dot" "yes")
976    (set_attr "length" "4,8")])
978 (define_insn_and_split "*extendqi<mode>2_dot2"
979   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
981                     (const_int 0)))
982    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
983         (sign_extend:EXTQI (match_dup 1)))]
984   ""
985   "@
986    extsb. %0,%1
987    #"
988   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
989   [(set (match_dup 0)
990         (sign_extend:EXTQI (match_dup 1)))
991    (set (match_dup 2)
992         (compare:CC (match_dup 0)
993                     (const_int 0)))]
994   ""
995   [(set_attr "type" "exts")
996    (set_attr "dot" "yes")
997    (set_attr "length" "4,8")])
1000 (define_expand "extendhi<mode>2"
1001   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1002         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1003   ""
1004   "")
1006 (define_insn "*extendhi<mode>2"
1007   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1008         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1009   ""
1010   "@
1011    lha%U1%X1 %0,%1
1012    extsh %0,%1
1013    #
1014    vextsh2d %0,%1"
1015   [(set_attr "type" "load,exts,fpload,vecperm")
1016    (set_attr "sign_extend" "yes")
1017    (set_attr "length" "*,*,8,*")
1018    (set_attr "isa" "*,*,p9v,p9v")])
1020 (define_split
1021   [(set (match_operand:EXTHI 0 "altivec_register_operand")
1022         (sign_extend:EXTHI
1023          (match_operand:HI 1 "indexed_or_indirect_operand")))]
1024   "TARGET_P9_VECTOR && reload_completed"
1025   [(set (match_dup 2)
1026         (match_dup 1))
1027    (set (match_dup 0)
1028         (sign_extend:EXTHI (match_dup 2)))]
1030   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1033 (define_insn_and_split "*extendhi<mode>2_dot"
1034   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1035         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1036                     (const_int 0)))
1037    (clobber (match_scratch:EXTHI 0 "=r,r"))]
1038   ""
1039   "@
1040    extsh. %0,%1
1041    #"
1042   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1043   [(set (match_dup 0)
1044         (sign_extend:EXTHI (match_dup 1)))
1045    (set (match_dup 2)
1046         (compare:CC (match_dup 0)
1047                     (const_int 0)))]
1048   ""
1049   [(set_attr "type" "exts")
1050    (set_attr "dot" "yes")
1051    (set_attr "length" "4,8")])
1053 (define_insn_and_split "*extendhi<mode>2_dot2"
1054   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1055         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1056                     (const_int 0)))
1057    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1058         (sign_extend:EXTHI (match_dup 1)))]
1059   ""
1060   "@
1061    extsh. %0,%1
1062    #"
1063   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1064   [(set (match_dup 0)
1065         (sign_extend:EXTHI (match_dup 1)))
1066    (set (match_dup 2)
1067         (compare:CC (match_dup 0)
1068                     (const_int 0)))]
1069   ""
1070   [(set_attr "type" "exts")
1071    (set_attr "dot" "yes")
1072    (set_attr "length" "4,8")])
1075 (define_insn "extendsi<mode>2"
1076   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1077                      "=r, r,   d,     wa,    wa,    v,      v,     wr")
1078         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1079                      "YZ, r,   Z,     Z,     r,     v,      v,     ?wa")))]
1080   ""
1081   "@
1082    lwa%U1%X1 %0,%1
1083    extsw %0,%1
1084    lfiwax %0,%y1
1085    lxsiwax %x0,%y1
1086    mtvsrwa %x0,%1
1087    vextsw2d %0,%1
1088    #
1089    #"
1090   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1091    (set_attr "sign_extend" "yes")
1092    (set_attr "length" "*,*,*,*,*,*,8,8")
1093    (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1095 (define_split
1096   [(set (match_operand:EXTSI 0 "int_reg_operand")
1097         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1098   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1099   [(set (match_dup 2)
1100         (match_dup 1))
1101    (set (match_dup 0)
1102         (sign_extend:DI (match_dup 2)))]
1104   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1107 (define_split
1108   [(set (match_operand:DI 0 "altivec_register_operand")
1109         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1110   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1111   [(const_int 0)]
1113   rtx dest = operands[0];
1114   rtx src = operands[1];
1115   int dest_regno = REGNO (dest);
1116   int src_regno = REGNO (src);
1117   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1118   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1120   if (BYTES_BIG_ENDIAN)
1121     {
1122       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1123       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1124     }
1125   else
1126     {
1127       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1128       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1129     }
1130   DONE;
1133 (define_insn_and_split "*extendsi<mode>2_dot"
1134   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1135         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1136                     (const_int 0)))
1137    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1138   ""
1139   "@
1140    extsw. %0,%1
1141    #"
1142   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1143   [(set (match_dup 0)
1144         (sign_extend:EXTSI (match_dup 1)))
1145    (set (match_dup 2)
1146         (compare:CC (match_dup 0)
1147                     (const_int 0)))]
1148   ""
1149   [(set_attr "type" "exts")
1150    (set_attr "dot" "yes")
1151    (set_attr "length" "4,8")])
1153 (define_insn_and_split "*extendsi<mode>2_dot2"
1154   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1155         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1156                     (const_int 0)))
1157    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1158         (sign_extend:EXTSI (match_dup 1)))]
1159   ""
1160   "@
1161    extsw. %0,%1
1162    #"
1163   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1164   [(set (match_dup 0)
1165         (sign_extend:EXTSI (match_dup 1)))
1166    (set (match_dup 2)
1167         (compare:CC (match_dup 0)
1168                     (const_int 0)))]
1169   ""
1170   [(set_attr "type" "exts")
1171    (set_attr "dot" "yes")
1172    (set_attr "length" "4,8")])
1174 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1176 (define_insn "*macchwc"
1177   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1178         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1179                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1180                                        (const_int 16))
1181                                       (sign_extend:SI
1182                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1183                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1184                     (const_int 0)))
1185    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186         (plus:SI (mult:SI (ashiftrt:SI
1187                            (match_dup 2)
1188                            (const_int 16))
1189                           (sign_extend:SI
1190                            (match_dup 1)))
1191                  (match_dup 4)))]
1192   "TARGET_MULHW"
1193   "macchw. %0,%1,%2"
1194   [(set_attr "type" "halfmul")])
1196 (define_insn "*macchw"
1197   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1198         (plus:SI (mult:SI (ashiftrt:SI
1199                            (match_operand:SI 2 "gpc_reg_operand" "r")
1200                            (const_int 16))
1201                           (sign_extend:SI
1202                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1203                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1204   "TARGET_MULHW"
1205   "macchw %0,%1,%2"
1206   [(set_attr "type" "halfmul")])
1208 (define_insn "*macchwuc"
1209   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1210         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1211                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1212                                        (const_int 16))
1213                                       (zero_extend:SI
1214                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1215                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1216                     (const_int 0)))
1217    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1218         (plus:SI (mult:SI (lshiftrt:SI
1219                            (match_dup 2)
1220                            (const_int 16))
1221                           (zero_extend:SI
1222                            (match_dup 1)))
1223                  (match_dup 4)))]
1224   "TARGET_MULHW"
1225   "macchwu. %0,%1,%2"
1226   [(set_attr "type" "halfmul")])
1228 (define_insn "*macchwu"
1229   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1230         (plus:SI (mult:SI (lshiftrt:SI
1231                            (match_operand:SI 2 "gpc_reg_operand" "r")
1232                            (const_int 16))
1233                           (zero_extend:SI
1234                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1235                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1236   "TARGET_MULHW"
1237   "macchwu %0,%1,%2"
1238   [(set_attr "type" "halfmul")])
1240 (define_insn "*machhwc"
1241   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1242         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1243                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1244                                        (const_int 16))
1245                                       (ashiftrt:SI
1246                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1247                                        (const_int 16)))
1248                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1249                     (const_int 0)))
1250    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251         (plus:SI (mult:SI (ashiftrt:SI
1252                            (match_dup 1)
1253                            (const_int 16))
1254                           (ashiftrt:SI
1255                            (match_dup 2)
1256                            (const_int 16)))
1257                  (match_dup 4)))]
1258   "TARGET_MULHW"
1259   "machhw. %0,%1,%2"
1260   [(set_attr "type" "halfmul")])
1262 (define_insn "*machhw"
1263   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264         (plus:SI (mult:SI (ashiftrt:SI
1265                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1266                            (const_int 16))
1267                           (ashiftrt:SI
1268                            (match_operand:SI 2 "gpc_reg_operand" "r")
1269                            (const_int 16)))
1270                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1271   "TARGET_MULHW"
1272   "machhw %0,%1,%2"
1273   [(set_attr "type" "halfmul")])
1275 (define_insn "*machhwuc"
1276   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1277         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1278                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1279                                        (const_int 16))
1280                                       (lshiftrt:SI
1281                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1282                                        (const_int 16)))
1283                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1284                     (const_int 0)))
1285    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1286         (plus:SI (mult:SI (lshiftrt:SI
1287                            (match_dup 1)
1288                            (const_int 16))
1289                           (lshiftrt:SI
1290                            (match_dup 2)
1291                            (const_int 16)))
1292                  (match_dup 4)))]
1293   "TARGET_MULHW"
1294   "machhwu. %0,%1,%2"
1295   [(set_attr "type" "halfmul")])
1297 (define_insn "*machhwu"
1298   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299         (plus:SI (mult:SI (lshiftrt:SI
1300                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1301                            (const_int 16))
1302                           (lshiftrt:SI
1303                            (match_operand:SI 2 "gpc_reg_operand" "r")
1304                            (const_int 16)))
1305                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1306   "TARGET_MULHW"
1307   "machhwu %0,%1,%2"
1308   [(set_attr "type" "halfmul")])
1310 (define_insn "*maclhwc"
1311   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1312         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1313                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1314                                       (sign_extend:SI
1315                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1316                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1317                     (const_int 0)))
1318    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1319         (plus:SI (mult:SI (sign_extend:SI
1320                            (match_dup 1))
1321                           (sign_extend:SI
1322                            (match_dup 2)))
1323                  (match_dup 4)))]
1324   "TARGET_MULHW"
1325   "maclhw. %0,%1,%2"
1326   [(set_attr "type" "halfmul")])
1328 (define_insn "*maclhw"
1329   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330         (plus:SI (mult:SI (sign_extend:SI
1331                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1332                           (sign_extend:SI
1333                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1334                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1335   "TARGET_MULHW"
1336   "maclhw %0,%1,%2"
1337   [(set_attr "type" "halfmul")])
1339 (define_insn "*maclhwuc"
1340   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1341         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1342                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1343                                       (zero_extend:SI
1344                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1345                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1346                     (const_int 0)))
1347    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1348         (plus:SI (mult:SI (zero_extend:SI
1349                            (match_dup 1))
1350                           (zero_extend:SI
1351                            (match_dup 2)))
1352                  (match_dup 4)))]
1353   "TARGET_MULHW"
1354   "maclhwu. %0,%1,%2"
1355   [(set_attr "type" "halfmul")])
1357 (define_insn "*maclhwu"
1358   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359         (plus:SI (mult:SI (zero_extend:SI
1360                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1361                           (zero_extend:SI
1362                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1363                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1364   "TARGET_MULHW"
1365   "maclhwu %0,%1,%2"
1366   [(set_attr "type" "halfmul")])
1368 (define_insn "*nmacchwc"
1369   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1370         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1371                               (mult:SI (ashiftrt:SI
1372                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1373                                         (const_int 16))
1374                                        (sign_extend:SI
1375                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1376                     (const_int 0)))
1377    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1378         (minus:SI (match_dup 4)
1379                   (mult:SI (ashiftrt:SI
1380                             (match_dup 2)
1381                             (const_int 16))
1382                            (sign_extend:SI
1383                             (match_dup 1)))))]
1384   "TARGET_MULHW"
1385   "nmacchw. %0,%1,%2"
1386   [(set_attr "type" "halfmul")])
1388 (define_insn "*nmacchw"
1389   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1391                   (mult:SI (ashiftrt:SI
1392                             (match_operand:SI 2 "gpc_reg_operand" "r")
1393                             (const_int 16))
1394                            (sign_extend:SI
1395                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1396   "TARGET_MULHW"
1397   "nmacchw %0,%1,%2"
1398   [(set_attr "type" "halfmul")])
1400 (define_insn "*nmachhwc"
1401   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1402         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1403                               (mult:SI (ashiftrt:SI
1404                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1405                                         (const_int 16))
1406                                        (ashiftrt:SI
1407                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1408                                         (const_int 16))))
1409                     (const_int 0)))
1410    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411         (minus:SI (match_dup 4)
1412                   (mult:SI (ashiftrt:SI
1413                             (match_dup 1)
1414                             (const_int 16))
1415                            (ashiftrt:SI
1416                             (match_dup 2)
1417                             (const_int 16)))))]
1418   "TARGET_MULHW"
1419   "nmachhw. %0,%1,%2"
1420   [(set_attr "type" "halfmul")])
1422 (define_insn "*nmachhw"
1423   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1425                   (mult:SI (ashiftrt:SI
1426                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1427                             (const_int 16))
1428                            (ashiftrt:SI
1429                             (match_operand:SI 2 "gpc_reg_operand" "r")
1430                             (const_int 16)))))]
1431   "TARGET_MULHW"
1432   "nmachhw %0,%1,%2"
1433   [(set_attr "type" "halfmul")])
1435 (define_insn "*nmaclhwc"
1436   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1437         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1438                               (mult:SI (sign_extend:SI
1439                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1440                                        (sign_extend:SI
1441                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1442                     (const_int 0)))
1443    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444         (minus:SI (match_dup 4)
1445                   (mult:SI (sign_extend:SI
1446                             (match_dup 1))
1447                            (sign_extend:SI
1448                             (match_dup 2)))))]
1449   "TARGET_MULHW"
1450   "nmaclhw. %0,%1,%2"
1451   [(set_attr "type" "halfmul")])
1453 (define_insn "*nmaclhw"
1454   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1455         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1456                   (mult:SI (sign_extend:SI
1457                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1458                            (sign_extend:SI
1459                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1460   "TARGET_MULHW"
1461   "nmaclhw %0,%1,%2"
1462   [(set_attr "type" "halfmul")])
1464 (define_insn "*mulchwc"
1465   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1466         (compare:CC (mult:SI (ashiftrt:SI
1467                               (match_operand:SI 2 "gpc_reg_operand" "r")
1468                               (const_int 16))
1469                              (sign_extend:SI
1470                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1471                     (const_int 0)))
1472    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1473         (mult:SI (ashiftrt:SI
1474                   (match_dup 2)
1475                   (const_int 16))
1476                  (sign_extend:SI
1477                   (match_dup 1))))]
1478   "TARGET_MULHW"
1479   "mulchw. %0,%1,%2"
1480   [(set_attr "type" "halfmul")])
1482 (define_insn "*mulchw"
1483   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1484         (mult:SI (ashiftrt:SI
1485                   (match_operand:SI 2 "gpc_reg_operand" "r")
1486                   (const_int 16))
1487                  (sign_extend:SI
1488                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1489   "TARGET_MULHW"
1490   "mulchw %0,%1,%2"
1491   [(set_attr "type" "halfmul")])
1493 (define_insn "*mulchwuc"
1494   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1495         (compare:CC (mult:SI (lshiftrt:SI
1496                               (match_operand:SI 2 "gpc_reg_operand" "r")
1497                               (const_int 16))
1498                              (zero_extend:SI
1499                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1500                     (const_int 0)))
1501    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1502         (mult:SI (lshiftrt:SI
1503                   (match_dup 2)
1504                   (const_int 16))
1505                  (zero_extend:SI
1506                   (match_dup 1))))]
1507   "TARGET_MULHW"
1508   "mulchwu. %0,%1,%2"
1509   [(set_attr "type" "halfmul")])
1511 (define_insn "*mulchwu"
1512   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1513         (mult:SI (lshiftrt:SI
1514                   (match_operand:SI 2 "gpc_reg_operand" "r")
1515                   (const_int 16))
1516                  (zero_extend:SI
1517                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1518   "TARGET_MULHW"
1519   "mulchwu %0,%1,%2"
1520   [(set_attr "type" "halfmul")])
1522 (define_insn "*mulhhwc"
1523   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1524         (compare:CC (mult:SI (ashiftrt:SI
1525                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1526                               (const_int 16))
1527                              (ashiftrt:SI
1528                               (match_operand:SI 2 "gpc_reg_operand" "r")
1529                               (const_int 16)))
1530                     (const_int 0)))
1531    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532         (mult:SI (ashiftrt:SI
1533                   (match_dup 1)
1534                   (const_int 16))
1535                  (ashiftrt:SI
1536                   (match_dup 2)
1537                   (const_int 16))))]
1538   "TARGET_MULHW"
1539   "mulhhw. %0,%1,%2"
1540   [(set_attr "type" "halfmul")])
1542 (define_insn "*mulhhw"
1543   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1544         (mult:SI (ashiftrt:SI
1545                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1546                   (const_int 16))
1547                  (ashiftrt:SI
1548                   (match_operand:SI 2 "gpc_reg_operand" "r")
1549                   (const_int 16))))]
1550   "TARGET_MULHW"
1551   "mulhhw %0,%1,%2"
1552   [(set_attr "type" "halfmul")])
1554 (define_insn "*mulhhwuc"
1555   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1556         (compare:CC (mult:SI (lshiftrt:SI
1557                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1558                               (const_int 16))
1559                              (lshiftrt:SI
1560                               (match_operand:SI 2 "gpc_reg_operand" "r")
1561                               (const_int 16)))
1562                     (const_int 0)))
1563    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1564         (mult:SI (lshiftrt:SI
1565                   (match_dup 1)
1566                   (const_int 16))
1567                  (lshiftrt:SI
1568                   (match_dup 2)
1569                   (const_int 16))))]
1570   "TARGET_MULHW"
1571   "mulhhwu. %0,%1,%2"
1572   [(set_attr "type" "halfmul")])
1574 (define_insn "*mulhhwu"
1575   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1576         (mult:SI (lshiftrt:SI
1577                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1578                   (const_int 16))
1579                  (lshiftrt:SI
1580                   (match_operand:SI 2 "gpc_reg_operand" "r")
1581                   (const_int 16))))]
1582   "TARGET_MULHW"
1583   "mulhhwu %0,%1,%2"
1584   [(set_attr "type" "halfmul")])
1586 (define_insn "*mullhwc"
1587   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1588         (compare:CC (mult:SI (sign_extend:SI
1589                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1590                              (sign_extend:SI
1591                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1592                     (const_int 0)))
1593    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1594         (mult:SI (sign_extend:SI
1595                   (match_dup 1))
1596                  (sign_extend:SI
1597                   (match_dup 2))))]
1598   "TARGET_MULHW"
1599   "mullhw. %0,%1,%2"
1600   [(set_attr "type" "halfmul")])
1602 (define_insn "*mullhw"
1603   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1604         (mult:SI (sign_extend:SI
1605                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1606                  (sign_extend:SI
1607                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1608   "TARGET_MULHW"
1609   "mullhw %0,%1,%2"
1610   [(set_attr "type" "halfmul")])
1612 (define_insn "*mullhwuc"
1613   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1614         (compare:CC (mult:SI (zero_extend:SI
1615                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1616                              (zero_extend:SI
1617                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1618                     (const_int 0)))
1619    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1620         (mult:SI (zero_extend:SI
1621                   (match_dup 1))
1622                  (zero_extend:SI
1623                   (match_dup 2))))]
1624   "TARGET_MULHW"
1625   "mullhwu. %0,%1,%2"
1626   [(set_attr "type" "halfmul")])
1628 (define_insn "*mullhwu"
1629   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1630         (mult:SI (zero_extend:SI
1631                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1632                  (zero_extend:SI
1633                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1634   "TARGET_MULHW"
1635   "mullhwu %0,%1,%2"
1636   [(set_attr "type" "halfmul")])
1638 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1639 (define_insn "dlmzb"
1640   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1641         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1642                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1643                    UNSPEC_DLMZB_CR))
1644    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1645         (unspec:SI [(match_dup 1)
1646                     (match_dup 2)]
1647                    UNSPEC_DLMZB))]
1648   "TARGET_DLMZB"
1649   "dlmzb. %0,%1,%2")
1651 (define_expand "strlensi"
1652   [(set (match_operand:SI 0 "gpc_reg_operand")
1653         (unspec:SI [(match_operand:BLK 1 "general_operand")
1654                     (match_operand:QI 2 "const_int_operand")
1655                     (match_operand 3 "const_int_operand")]
1656                    UNSPEC_DLMZB_STRLEN))
1657    (clobber (match_scratch:CC 4))]
1658   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1660   rtx result = operands[0];
1661   rtx src = operands[1];
1662   rtx search_char = operands[2];
1663   rtx align = operands[3];
1664   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1665   rtx loop_label, end_label, mem, cr0, cond;
1666   if (search_char != const0_rtx
1667       || !CONST_INT_P (align)
1668       || INTVAL (align) < 8)
1669         FAIL;
1670   word1 = gen_reg_rtx (SImode);
1671   word2 = gen_reg_rtx (SImode);
1672   scratch_dlmzb = gen_reg_rtx (SImode);
1673   scratch_string = gen_reg_rtx (Pmode);
1674   loop_label = gen_label_rtx ();
1675   end_label = gen_label_rtx ();
1676   addr = force_reg (Pmode, XEXP (src, 0));
1677   emit_move_insn (scratch_string, addr);
1678   emit_label (loop_label);
1679   mem = change_address (src, SImode, scratch_string);
1680   emit_move_insn (word1, mem);
1681   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1682   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1683   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1684   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1685   emit_jump_insn (gen_rtx_SET (pc_rtx,
1686                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1687                                                      cond,
1688                                                      gen_rtx_LABEL_REF
1689                                                        (VOIDmode,
1690                                                         end_label),
1691                                                      pc_rtx)));
1692   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1693   emit_jump_insn (gen_rtx_SET (pc_rtx,
1694                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1695   emit_barrier ();
1696   emit_label (end_label);
1697   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1698   emit_insn (gen_subsi3 (result, scratch_string, addr));
1699   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1700   DONE;
1703 ;; Fixed-point arithmetic insns.
1705 (define_expand "add<mode>3"
1706   [(set (match_operand:SDI 0 "gpc_reg_operand")
1707         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1708                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1709   ""
1711   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1712     {
1713       rtx lo0 = gen_lowpart (SImode, operands[0]);
1714       rtx lo1 = gen_lowpart (SImode, operands[1]);
1715       rtx lo2 = gen_lowpart (SImode, operands[2]);
1716       rtx hi0 = gen_highpart (SImode, operands[0]);
1717       rtx hi1 = gen_highpart (SImode, operands[1]);
1718       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1720       if (!reg_or_short_operand (lo2, SImode))
1721         lo2 = force_reg (SImode, lo2);
1722       if (!adde_operand (hi2, SImode))
1723         hi2 = force_reg (SImode, hi2);
1725       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1726       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1727       DONE;
1728     }
1730   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1731     {
1732       rtx tmp = ((!can_create_pseudo_p ()
1733                   || rtx_equal_p (operands[0], operands[1]))
1734                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1736       /* Adding a constant to r0 is not a valid insn, so use a different
1737          strategy in that case.  */
1738       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1739         {
1740           if (operands[0] == operands[1])
1741             FAIL;
1742           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1743           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1744           DONE;
1745         }
1747       HOST_WIDE_INT val = INTVAL (operands[2]);
1748       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1749       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1751       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1752         FAIL;
1754       /* The ordering here is important for the prolog expander.
1755          When space is allocated from the stack, adding 'low' first may
1756          produce a temporary deallocation (which would be bad).  */
1757       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1758       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1759       DONE;
1760     }
1763 (define_insn "*add<mode>3"
1764   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1765         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1766                   (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1767   ""
1768   "@
1769    add %0,%1,%2
1770    addi %0,%1,%2
1771    addis %0,%1,%v2
1772    addi %0,%1,%2"
1773   [(set_attr "type" "add")
1774    (set_attr "isa" "*,*,*,fut")])
1776 (define_insn "*addsi3_high"
1777   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1778         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1779                  (high:SI (match_operand 2 "" ""))))]
1780   "TARGET_MACHO && !TARGET_64BIT"
1781   "addis %0,%1,ha16(%2)"
1782   [(set_attr "type" "add")])
1784 (define_insn_and_split "*add<mode>3_dot"
1785   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1786         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1787                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1788                     (const_int 0)))
1789    (clobber (match_scratch:GPR 0 "=r,r"))]
1790   "<MODE>mode == Pmode"
1791   "@
1792    add. %0,%1,%2
1793    #"
1794   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1795   [(set (match_dup 0)
1796         (plus:GPR (match_dup 1)
1797                  (match_dup 2)))
1798    (set (match_dup 3)
1799         (compare:CC (match_dup 0)
1800                     (const_int 0)))]
1801   ""
1802   [(set_attr "type" "add")
1803    (set_attr "dot" "yes")
1804    (set_attr "length" "4,8")])
1806 (define_insn_and_split "*add<mode>3_dot2"
1807   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1808         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1809                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1810                     (const_int 0)))
1811    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1812         (plus:GPR (match_dup 1)
1813                   (match_dup 2)))]
1814   "<MODE>mode == Pmode"
1815   "@
1816    add. %0,%1,%2
1817    #"
1818   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1819   [(set (match_dup 0)
1820         (plus:GPR (match_dup 1)
1821                   (match_dup 2)))
1822    (set (match_dup 3)
1823         (compare:CC (match_dup 0)
1824                     (const_int 0)))]
1825   ""
1826   [(set_attr "type" "add")
1827    (set_attr "dot" "yes")
1828    (set_attr "length" "4,8")])
1830 (define_insn_and_split "*add<mode>3_imm_dot"
1831   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1832         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1833                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1834                     (const_int 0)))
1835    (clobber (match_scratch:GPR 0 "=r,r"))
1836    (clobber (reg:GPR CA_REGNO))]
1837   "<MODE>mode == Pmode"
1838   "@
1839    addic. %0,%1,%2
1840    #"
1841   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1842   [(set (match_dup 0)
1843         (plus:GPR (match_dup 1)
1844                   (match_dup 2)))
1845    (set (match_dup 3)
1846         (compare:CC (match_dup 0)
1847                     (const_int 0)))]
1848   ""
1849   [(set_attr "type" "add")
1850    (set_attr "dot" "yes")
1851    (set_attr "length" "4,8")])
1853 (define_insn_and_split "*add<mode>3_imm_dot2"
1854   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1855         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1856                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1857                     (const_int 0)))
1858    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1859         (plus:GPR (match_dup 1)
1860                   (match_dup 2)))
1861    (clobber (reg:GPR CA_REGNO))]
1862   "<MODE>mode == Pmode"
1863   "@
1864    addic. %0,%1,%2
1865    #"
1866   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1867   [(set (match_dup 0)
1868         (plus:GPR (match_dup 1)
1869                   (match_dup 2)))
1870    (set (match_dup 3)
1871         (compare:CC (match_dup 0)
1872                     (const_int 0)))]
1873   ""
1874   [(set_attr "type" "add")
1875    (set_attr "dot" "yes")
1876    (set_attr "length" "4,8")])
1878 ;; Split an add that we can't do in one insn into two insns, each of which
1879 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1880 ;; add should be last in case the result gets used in an address.
1882 (define_split
1883   [(set (match_operand:GPR 0 "gpc_reg_operand")
1884         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1885                   (match_operand:GPR 2 "non_add_cint_operand")))]
1886   ""
1887   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1888    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1890   HOST_WIDE_INT val = INTVAL (operands[2]);
1891   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1892   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1894   operands[4] = GEN_INT (low);
1895   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1896     operands[3] = GEN_INT (rest);
1897   else if (can_create_pseudo_p ())
1898     {
1899       operands[3] = gen_reg_rtx (DImode);
1900       emit_move_insn (operands[3], operands[2]);
1901       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1902       DONE;
1903     }
1904   else
1905     FAIL;
1909 (define_insn "add<mode>3_carry"
1910   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1911         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1912                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1913    (set (reg:P CA_REGNO)
1914         (ltu:P (plus:P (match_dup 1)
1915                        (match_dup 2))
1916                (match_dup 1)))]
1917   ""
1918   "add%I2c %0,%1,%2"
1919   [(set_attr "type" "add")])
1921 (define_insn "*add<mode>3_imm_carry_pos"
1922   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1923         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1924                 (match_operand:P 2 "short_cint_operand" "n")))
1925    (set (reg:P CA_REGNO)
1926         (geu:P (match_dup 1)
1927                (match_operand:P 3 "const_int_operand" "n")))]
1928   "INTVAL (operands[2]) > 0
1929    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1930   "addic %0,%1,%2"
1931   [(set_attr "type" "add")])
1933 (define_insn "*add<mode>3_imm_carry_0"
1934   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1935         (match_operand:P 1 "gpc_reg_operand" "r"))
1936    (set (reg:P CA_REGNO)
1937         (const_int 0))]
1938   ""
1939   "addic %0,%1,0"
1940   [(set_attr "type" "add")])
1942 (define_insn "*add<mode>3_imm_carry_m1"
1943   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1944         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1945                 (const_int -1)))
1946    (set (reg:P CA_REGNO)
1947         (ne:P (match_dup 1)
1948               (const_int 0)))]
1949   ""
1950   "addic %0,%1,-1"
1951   [(set_attr "type" "add")])
1953 (define_insn "*add<mode>3_imm_carry_neg"
1954   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1955         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1956                 (match_operand:P 2 "short_cint_operand" "n")))
1957    (set (reg:P CA_REGNO)
1958         (gtu:P (match_dup 1)
1959                (match_operand:P 3 "const_int_operand" "n")))]
1960   "INTVAL (operands[2]) < 0
1961    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1962   "addic %0,%1,%2"
1963   [(set_attr "type" "add")])
1966 (define_expand "add<mode>3_carry_in"
1967   [(parallel [
1968      (set (match_operand:GPR 0 "gpc_reg_operand")
1969           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1970                               (match_operand:GPR 2 "adde_operand"))
1971                     (reg:GPR CA_REGNO)))
1972      (clobber (reg:GPR CA_REGNO))])]
1973   ""
1975   if (operands[2] == const0_rtx)
1976     {
1977       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1978       DONE;
1979     }
1980   if (operands[2] == constm1_rtx)
1981     {
1982       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1983       DONE;
1984     }
1987 (define_insn "*add<mode>3_carry_in_internal"
1988   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1989         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1990                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1991                   (reg:GPR CA_REGNO)))
1992    (clobber (reg:GPR CA_REGNO))]
1993   ""
1994   "adde %0,%1,%2"
1995   [(set_attr "type" "add")])
1997 (define_insn "*add<mode>3_carry_in_internal2"
1998   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1999         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2000                             (reg:GPR CA_REGNO))
2001                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2002    (clobber (reg:GPR CA_REGNO))]
2003   ""
2004   "adde %0,%1,%2"
2005   [(set_attr "type" "add")])
2007 (define_insn "add<mode>3_carry_in_0"
2008   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2009         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2010                   (reg:GPR CA_REGNO)))
2011    (clobber (reg:GPR CA_REGNO))]
2012   ""
2013   "addze %0,%1"
2014   [(set_attr "type" "add")])
2016 (define_insn "add<mode>3_carry_in_m1"
2017   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2018         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2019                             (reg:GPR CA_REGNO))
2020                   (const_int -1)))
2021    (clobber (reg:GPR CA_REGNO))]
2022   ""
2023   "addme %0,%1"
2024   [(set_attr "type" "add")])
2027 (define_expand "one_cmpl<mode>2"
2028   [(set (match_operand:SDI 0 "gpc_reg_operand")
2029         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2030   ""
2032   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2033     {
2034       rs6000_split_logical (operands, NOT, false, false, false);
2035       DONE;
2036     }
2039 (define_insn "*one_cmpl<mode>2"
2040   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2041         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2042   ""
2043   "not %0,%1")
2045 (define_insn_and_split "*one_cmpl<mode>2_dot"
2046   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2047         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2048                     (const_int 0)))
2049    (clobber (match_scratch:GPR 0 "=r,r"))]
2050   "<MODE>mode == Pmode"
2051   "@
2052    not. %0,%1
2053    #"
2054   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2055   [(set (match_dup 0)
2056         (not:GPR (match_dup 1)))
2057    (set (match_dup 2)
2058         (compare:CC (match_dup 0)
2059                     (const_int 0)))]
2060   ""
2061   [(set_attr "type" "logical")
2062    (set_attr "dot" "yes")
2063    (set_attr "length" "4,8")])
2065 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2066   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2067         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2068                     (const_int 0)))
2069    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2070         (not:GPR (match_dup 1)))]
2071   "<MODE>mode == Pmode"
2072   "@
2073    not. %0,%1
2074    #"
2075   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2076   [(set (match_dup 0)
2077         (not:GPR (match_dup 1)))
2078    (set (match_dup 2)
2079         (compare:CC (match_dup 0)
2080                     (const_int 0)))]
2081   ""
2082   [(set_attr "type" "logical")
2083    (set_attr "dot" "yes")
2084    (set_attr "length" "4,8")])
2087 (define_expand "sub<mode>3"
2088   [(set (match_operand:SDI 0 "gpc_reg_operand")
2089         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2090                    (match_operand:SDI 2 "gpc_reg_operand")))]
2091   ""
2093   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2094     {
2095       rtx lo0 = gen_lowpart (SImode, operands[0]);
2096       rtx lo1 = gen_lowpart (SImode, operands[1]);
2097       rtx lo2 = gen_lowpart (SImode, operands[2]);
2098       rtx hi0 = gen_highpart (SImode, operands[0]);
2099       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2100       rtx hi2 = gen_highpart (SImode, operands[2]);
2102       if (!reg_or_short_operand (lo1, SImode))
2103         lo1 = force_reg (SImode, lo1);
2104       if (!adde_operand (hi1, SImode))
2105         hi1 = force_reg (SImode, hi1);
2107       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2108       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2109       DONE;
2110     }
2112   if (short_cint_operand (operands[1], <MODE>mode))
2113     {
2114       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2115       DONE;
2116     }
2119 (define_insn "*subf<mode>3"
2120   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2121         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2122                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2123   ""
2124   "subf %0,%1,%2"
2125   [(set_attr "type" "add")])
2127 (define_insn_and_split "*subf<mode>3_dot"
2128   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2129         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2130                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2131                     (const_int 0)))
2132    (clobber (match_scratch:GPR 0 "=r,r"))]
2133   "<MODE>mode == Pmode"
2134   "@
2135    subf. %0,%1,%2
2136    #"
2137   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2138   [(set (match_dup 0)
2139         (minus:GPR (match_dup 2)
2140                    (match_dup 1)))
2141    (set (match_dup 3)
2142         (compare:CC (match_dup 0)
2143                     (const_int 0)))]
2144   ""
2145   [(set_attr "type" "add")
2146    (set_attr "dot" "yes")
2147    (set_attr "length" "4,8")])
2149 (define_insn_and_split "*subf<mode>3_dot2"
2150   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2151         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2152                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2153                     (const_int 0)))
2154    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2155         (minus:GPR (match_dup 2)
2156                    (match_dup 1)))]
2157   "<MODE>mode == Pmode"
2158   "@
2159    subf. %0,%1,%2
2160    #"
2161   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2162   [(set (match_dup 0)
2163         (minus:GPR (match_dup 2)
2164                    (match_dup 1)))
2165    (set (match_dup 3)
2166         (compare:CC (match_dup 0)
2167                     (const_int 0)))]
2168   ""
2169   [(set_attr "type" "add")
2170    (set_attr "dot" "yes")
2171    (set_attr "length" "4,8")])
2173 (define_insn "subf<mode>3_imm"
2174   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2175         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2176                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2177    (clobber (reg:GPR CA_REGNO))]
2178   ""
2179   "subfic %0,%1,%2"
2180   [(set_attr "type" "add")])
2182 (define_insn_and_split "subf<mode>3_carry_dot2"
2183   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2184         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2185                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2186                     (const_int 0)))
2187    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2188         (minus:P (match_dup 2)
2189                    (match_dup 1)))
2190    (set (reg:P CA_REGNO)
2191         (leu:P (match_dup 1)
2192                (match_dup 2)))]
2193   "<MODE>mode == Pmode"
2194   "@
2195    subfc. %0,%1,%2
2196    #"
2197   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2198   [(parallel [(set (match_dup 0)
2199                    (minus:P (match_dup 2)
2200                             (match_dup 1)))
2201               (set (reg:P CA_REGNO)
2202                    (leu:P (match_dup 1)
2203                           (match_dup 2)))])
2204    (set (match_dup 3)
2205         (compare:CC (match_dup 0)
2206                     (const_int 0)))]
2207   ""
2208   [(set_attr "type" "add")
2209    (set_attr "dot" "yes")
2210    (set_attr "length" "4,8")])
2212 (define_insn "subf<mode>3_carry"
2213   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2214         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2215                  (match_operand:P 1 "gpc_reg_operand" "r")))
2216    (set (reg:P CA_REGNO)
2217         (leu:P (match_dup 1)
2218                (match_dup 2)))]
2219   ""
2220   "subf%I2c %0,%1,%2"
2221   [(set_attr "type" "add")])
2223 (define_insn "*subf<mode>3_imm_carry_0"
2224   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2225         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2226    (set (reg:P CA_REGNO)
2227         (eq:P (match_dup 1)
2228               (const_int 0)))]
2229   ""
2230   "subfic %0,%1,0"
2231   [(set_attr "type" "add")])
2233 (define_insn "*subf<mode>3_imm_carry_m1"
2234   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2235         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2236    (set (reg:P CA_REGNO)
2237         (const_int 1))]
2238   ""
2239   "subfic %0,%1,-1"
2240   [(set_attr "type" "add")])
2243 (define_expand "subf<mode>3_carry_in"
2244   [(parallel [
2245      (set (match_operand:GPR 0 "gpc_reg_operand")
2246           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2247                               (reg:GPR CA_REGNO))
2248                     (match_operand:GPR 2 "adde_operand")))
2249      (clobber (reg:GPR CA_REGNO))])]
2250   ""
2252   if (operands[2] == const0_rtx)
2253     {
2254       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2255       DONE;
2256     }
2257   if (operands[2] == constm1_rtx)
2258     {
2259       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2260       DONE;
2261     }
2264 (define_insn "*subf<mode>3_carry_in_internal"
2265   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2266         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2267                             (reg:GPR CA_REGNO))
2268                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2269    (clobber (reg:GPR CA_REGNO))]
2270   ""
2271   "subfe %0,%1,%2"
2272   [(set_attr "type" "add")])
2274 (define_insn "subf<mode>3_carry_in_0"
2275   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2276         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2277                   (reg:GPR CA_REGNO)))
2278    (clobber (reg:GPR CA_REGNO))]
2279   ""
2280   "subfze %0,%1"
2281   [(set_attr "type" "add")])
2283 (define_insn "subf<mode>3_carry_in_m1"
2284   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2285         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2286                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2287                   (const_int -2)))
2288    (clobber (reg:GPR CA_REGNO))]
2289   ""
2290   "subfme %0,%1"
2291   [(set_attr "type" "add")])
2293 (define_insn "subf<mode>3_carry_in_xx"
2294   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295         (plus:GPR (reg:GPR CA_REGNO)
2296                   (const_int -1)))
2297    (clobber (reg:GPR CA_REGNO))]
2298   ""
2299   "subfe %0,%0,%0"
2300   [(set_attr "type" "add")])
2303 (define_insn "@neg<mode>2"
2304   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2305         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2306   ""
2307   "neg %0,%1"
2308   [(set_attr "type" "add")])
2310 (define_insn_and_split "*neg<mode>2_dot"
2311   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2312         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2313                     (const_int 0)))
2314    (clobber (match_scratch:GPR 0 "=r,r"))]
2315   "<MODE>mode == Pmode"
2316   "@
2317    neg. %0,%1
2318    #"
2319   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2320   [(set (match_dup 0)
2321         (neg:GPR (match_dup 1)))
2322    (set (match_dup 2)
2323         (compare:CC (match_dup 0)
2324                     (const_int 0)))]
2325   ""
2326   [(set_attr "type" "add")
2327    (set_attr "dot" "yes")
2328    (set_attr "length" "4,8")])
2330 (define_insn_and_split "*neg<mode>2_dot2"
2331   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2332         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2333                     (const_int 0)))
2334    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2335         (neg:GPR (match_dup 1)))]
2336   "<MODE>mode == Pmode"
2337   "@
2338    neg. %0,%1
2339    #"
2340   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2341   [(set (match_dup 0)
2342         (neg:GPR (match_dup 1)))
2343    (set (match_dup 2)
2344         (compare:CC (match_dup 0)
2345                     (const_int 0)))]
2346   ""
2347   [(set_attr "type" "add")
2348    (set_attr "dot" "yes")
2349    (set_attr "length" "4,8")])
2352 (define_insn "clz<mode>2"
2353   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2354         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2355   ""
2356   "cntlz<wd> %0,%1"
2357   [(set_attr "type" "cntlz")])
2359 (define_expand "ctz<mode>2"
2360    [(set (match_operand:GPR 0 "gpc_reg_operand")
2361          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2362   ""
2364   if (TARGET_CTZ)
2365     {
2366       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2367       DONE;
2368     }
2370   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2371   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2372   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2374   if (TARGET_POPCNTD)
2375     {
2376       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2377       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2378       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2379       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2380     }
2381   else
2382     {
2383       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2384       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2385       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2386       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2387     }
2389   DONE;
2392 (define_insn "ctz<mode>2_hw"
2393   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2394         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2395   "TARGET_CTZ"
2396   "cnttz<wd> %0,%1"
2397   [(set_attr "type" "cntlz")])
2399 (define_expand "ffs<mode>2"
2400   [(set (match_operand:GPR 0 "gpc_reg_operand")
2401         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2402   ""
2404   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2405   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2406   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2407   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2408   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2409   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2410   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2411   DONE;
2415 (define_expand "popcount<mode>2"
2416   [(set (match_operand:GPR 0 "gpc_reg_operand")
2417         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2418   "TARGET_POPCNTB || TARGET_POPCNTD"
2420   rs6000_emit_popcount (operands[0], operands[1]);
2421   DONE;
2424 (define_insn "popcntb<mode>2"
2425   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2426         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2427                     UNSPEC_POPCNTB))]
2428   "TARGET_POPCNTB"
2429   "popcntb %0,%1"
2430   [(set_attr "type" "popcnt")])
2432 (define_insn "popcntd<mode>2"
2433   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2434         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2435   "TARGET_POPCNTD"
2436   "popcnt<wd> %0,%1"
2437   [(set_attr "type" "popcnt")])
2440 (define_expand "parity<mode>2"
2441   [(set (match_operand:GPR 0 "gpc_reg_operand")
2442         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2443   "TARGET_POPCNTB"
2445   rs6000_emit_parity (operands[0], operands[1]);
2446   DONE;
2449 (define_insn "parity<mode>2_cmpb"
2450   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2451         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2452   "TARGET_CMPB && TARGET_POPCNTB"
2453   "prty<wd> %0,%1"
2454   [(set_attr "type" "popcnt")])
2456 (define_insn "cmpb<mode>3"
2457   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2458         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2459                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2460   "TARGET_CMPB"
2461   "cmpb %0,%1,%2"
2462   [(set_attr "type" "cmp")])
2464 ;; Since the hardware zeros the upper part of the register, save generating the
2465 ;; AND immediate if we are converting to unsigned
2466 (define_insn "*bswap<mode>2_extenddi"
2467   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2468         (zero_extend:DI
2469          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2470   "TARGET_POWERPC64"
2471   "l<wd>brx %0,%y1"
2472   [(set_attr "type" "load")])
2474 (define_insn "*bswaphi2_extendsi"
2475   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2476         (zero_extend:SI
2477          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2478   ""
2479   "lhbrx %0,%y1"
2480   [(set_attr "type" "load")])
2482 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2483 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2484 ;; load with byte swap, which can be slower than doing it in the registers.  It
2485 ;; also prevents certain failures with the RELOAD register allocator.
2487 (define_expand "bswap<mode>2"
2488   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2489    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2490   ""
2492   rtx dest = operands[0];
2493   rtx src = operands[1];
2495   if (!REG_P (dest) && !REG_P (src))
2496     src = force_reg (<MODE>mode, src);
2498   if (MEM_P (src))
2499     {
2500       src = rs6000_force_indexed_or_indirect_mem (src);
2501       emit_insn (gen_bswap<mode>2_load (dest, src));
2502     }
2503   else if (MEM_P (dest))
2504     {
2505       dest = rs6000_force_indexed_or_indirect_mem (dest);
2506       emit_insn (gen_bswap<mode>2_store (dest, src));
2507     }
2508   else
2509     emit_insn (gen_bswap<mode>2_reg (dest, src));
2510   DONE;
2513 (define_insn "bswap<mode>2_load"
2514   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2515         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2516   ""
2517   "l<wd>brx %0,%y1"
2518   [(set_attr "type" "load")])
2520 (define_insn "bswap<mode>2_store"
2521   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2522         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2523   ""
2524   "st<wd>brx %1,%y0"
2525   [(set_attr "type" "store")])
2527 (define_insn_and_split "bswaphi2_reg"
2528   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2529         (bswap:HI
2530          (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2531    (clobber (match_scratch:SI 2 "=&r,X"))]
2532   ""
2533   "@
2534    #
2535    xxbrh %x0,%x1"
2536   "reload_completed && int_reg_operand (operands[0], HImode)"
2537   [(set (match_dup 3)
2538         (and:SI (lshiftrt:SI (match_dup 4)
2539                              (const_int 8))
2540                 (const_int 255)))
2541    (set (match_dup 2)
2542         (and:SI (ashift:SI (match_dup 4)
2543                            (const_int 8))
2544                 (const_int 65280)))             ;; 0xff00
2545    (set (match_dup 3)
2546         (ior:SI (match_dup 3)
2547                 (match_dup 2)))]
2549   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2550   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2552   [(set_attr "length" "12,4")
2553    (set_attr "type" "*,vecperm")
2554    (set_attr "isa" "*,p9v")])
2556 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2557 ;; zero_extract insns do not change for -mlittle.
2558 (define_insn_and_split "bswapsi2_reg"
2559   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2560         (bswap:SI
2561          (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2562   ""
2563   "@
2564    #
2565    xxbrw %x0,%x1"
2566   "reload_completed && int_reg_operand (operands[0], SImode)"
2567   [(set (match_dup 0)                                   ; DABC
2568         (rotate:SI (match_dup 1)
2569                    (const_int 24)))
2570    (set (match_dup 0)                                   ; DCBC
2571         (ior:SI (and:SI (ashift:SI (match_dup 1)
2572                                    (const_int 8))
2573                         (const_int 16711680))
2574                 (and:SI (match_dup 0)
2575                         (const_int -16711681))))
2576    (set (match_dup 0)                                   ; DCBA
2577         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2578                                      (const_int 24))
2579                         (const_int 255))
2580                 (and:SI (match_dup 0)
2581                         (const_int -256))))]
2582   ""
2583   [(set_attr "length" "12,4")
2584    (set_attr "type" "*,vecperm")
2585    (set_attr "isa" "*,p9v")])
2587 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2588 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2589 ;; complex code.
2591 (define_expand "bswapdi2"
2592   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2593                    (bswap:DI
2594                     (match_operand:DI 1 "reg_or_mem_operand")))
2595               (clobber (match_scratch:DI 2))
2596               (clobber (match_scratch:DI 3))])]
2597   ""
2599   rtx dest = operands[0];
2600   rtx src = operands[1];
2602   if (!REG_P (dest) && !REG_P (src))
2603     operands[1] = src = force_reg (DImode, src);
2605   if (TARGET_POWERPC64 && TARGET_LDBRX)
2606     {
2607       if (MEM_P (src))
2608         {
2609           src = rs6000_force_indexed_or_indirect_mem (src);
2610           emit_insn (gen_bswapdi2_load (dest, src));
2611         }
2612       else if (MEM_P (dest))
2613         {
2614           dest = rs6000_force_indexed_or_indirect_mem (dest);
2615           emit_insn (gen_bswapdi2_store (dest, src));
2616         }
2617       else if (TARGET_P9_VECTOR)
2618         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2619       else
2620         emit_insn (gen_bswapdi2_reg (dest, src));
2621       DONE;
2622     }
2624   if (!TARGET_POWERPC64)
2625     {
2626       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2627          that uses 64-bit registers needs the same scratch registers as 64-bit
2628          mode.  */
2629       emit_insn (gen_bswapdi2_32bit (dest, src));
2630       DONE;
2631     }
2634 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2635 (define_insn "bswapdi2_load"
2636   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2637         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2638   "TARGET_POWERPC64 && TARGET_LDBRX"
2639   "ldbrx %0,%y1"
2640   [(set_attr "type" "load")])
2642 (define_insn "bswapdi2_store"
2643   [(set (match_operand:DI 0 "memory_operand" "=Z")
2644         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2645   "TARGET_POWERPC64 && TARGET_LDBRX"
2646   "stdbrx %1,%y0"
2647   [(set_attr "type" "store")])
2649 (define_insn "bswapdi2_xxbrd"
2650   [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2651         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2652   "TARGET_P9_VECTOR"
2653   "xxbrd %x0,%x1"
2654   [(set_attr "type" "vecperm")
2655    (set_attr "isa" "p9v")])
2657 (define_insn "bswapdi2_reg"
2658   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2659         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2660    (clobber (match_scratch:DI 2 "=&r"))
2661    (clobber (match_scratch:DI 3 "=&r"))]
2662   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2663   "#"
2664   [(set_attr "length" "36")])
2666 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2667 (define_insn "*bswapdi2_64bit"
2668   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2669         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2670    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2671    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2672   "TARGET_POWERPC64 && !TARGET_LDBRX
2673    && (REG_P (operands[0]) || REG_P (operands[1]))
2674    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2675    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2676   "#"
2677   [(set_attr "length" "16,12,36")])
2679 (define_split
2680   [(set (match_operand:DI 0 "gpc_reg_operand")
2681         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2682    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2683    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2684   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2685   [(const_int 0)]
2687   rtx dest   = operands[0];
2688   rtx src    = operands[1];
2689   rtx op2    = operands[2];
2690   rtx op3    = operands[3];
2691   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2692                                     BYTES_BIG_ENDIAN ? 4 : 0);
2693   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2694                                      BYTES_BIG_ENDIAN ? 4 : 0);
2695   rtx addr1;
2696   rtx addr2;
2697   rtx word1;
2698   rtx word2;
2700   addr1 = XEXP (src, 0);
2701   if (GET_CODE (addr1) == PLUS)
2702     {
2703       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2704       if (TARGET_AVOID_XFORM)
2705         {
2706           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2707           addr2 = op2;
2708         }
2709       else
2710         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2711     }
2712   else if (TARGET_AVOID_XFORM)
2713     {
2714       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2715       addr2 = op2;
2716     }
2717   else
2718     {
2719       emit_move_insn (op2, GEN_INT (4));
2720       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2721     }
2723   word1 = change_address (src, SImode, addr1);
2724   word2 = change_address (src, SImode, addr2);
2726   if (BYTES_BIG_ENDIAN)
2727     {
2728       emit_insn (gen_bswapsi2 (op3_32, word2));
2729       emit_insn (gen_bswapsi2 (dest_32, word1));
2730     }
2731   else
2732     {
2733       emit_insn (gen_bswapsi2 (op3_32, word1));
2734       emit_insn (gen_bswapsi2 (dest_32, word2));
2735     }
2737   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2738   emit_insn (gen_iordi3 (dest, dest, op3));
2739   DONE;
2742 (define_split
2743   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2744         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2745    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2746    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2747   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2748   [(const_int 0)]
2750   rtx dest   = operands[0];
2751   rtx src    = operands[1];
2752   rtx op2    = operands[2];
2753   rtx op3    = operands[3];
2754   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2755                                     BYTES_BIG_ENDIAN ? 4 : 0);
2756   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2757                                     BYTES_BIG_ENDIAN ? 4 : 0);
2758   rtx addr1;
2759   rtx addr2;
2760   rtx word1;
2761   rtx word2;
2763   addr1 = XEXP (dest, 0);
2764   if (GET_CODE (addr1) == PLUS)
2765     {
2766       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2767       if (TARGET_AVOID_XFORM)
2768         {
2769           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2770           addr2 = op2;
2771         }
2772       else
2773         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2774     }
2775   else if (TARGET_AVOID_XFORM)
2776     {
2777       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2778       addr2 = op2;
2779     }
2780   else
2781     {
2782       emit_move_insn (op2, GEN_INT (4));
2783       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2784     }
2786   word1 = change_address (dest, SImode, addr1);
2787   word2 = change_address (dest, SImode, addr2);
2789   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2791   if (BYTES_BIG_ENDIAN)
2792     {
2793       emit_insn (gen_bswapsi2 (word1, src_si));
2794       emit_insn (gen_bswapsi2 (word2, op3_si));
2795     }
2796   else
2797     {
2798       emit_insn (gen_bswapsi2 (word2, src_si));
2799       emit_insn (gen_bswapsi2 (word1, op3_si));
2800     }
2801   DONE;
2804 (define_split
2805   [(set (match_operand:DI 0 "gpc_reg_operand")
2806         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2807    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2808    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2809   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2810   [(const_int 0)]
2812   rtx dest    = operands[0];
2813   rtx src     = operands[1];
2814   rtx op2     = operands[2];
2815   rtx op3     = operands[3];
2816   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2817   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2818   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2819   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2820   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2822   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2823   emit_insn (gen_bswapsi2 (dest_si, src_si));
2824   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2825   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2826   emit_insn (gen_iordi3 (dest, dest, op3));
2827   DONE;
2830 (define_insn "bswapdi2_32bit"
2831   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2832         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2833    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2834   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2835   "#"
2836   [(set_attr "length" "16,12,36")])
2838 (define_split
2839   [(set (match_operand:DI 0 "gpc_reg_operand")
2840         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2841    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2842   "!TARGET_POWERPC64 && reload_completed"
2843   [(const_int 0)]
2845   rtx dest  = operands[0];
2846   rtx src   = operands[1];
2847   rtx op2   = operands[2];
2848   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2849   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2850   rtx addr1;
2851   rtx addr2;
2852   rtx word1;
2853   rtx word2;
2855   addr1 = XEXP (src, 0);
2856   if (GET_CODE (addr1) == PLUS)
2857     {
2858       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2859       if (TARGET_AVOID_XFORM
2860           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2861         {
2862           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2863           addr2 = op2;
2864         }
2865       else
2866         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2867     }
2868   else if (TARGET_AVOID_XFORM
2869            || REGNO (addr1) == REGNO (dest2))
2870     {
2871       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2872       addr2 = op2;
2873     }
2874   else
2875     {
2876       emit_move_insn (op2, GEN_INT (4));
2877       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2878     }
2880   word1 = change_address (src, SImode, addr1);
2881   word2 = change_address (src, SImode, addr2);
2883   emit_insn (gen_bswapsi2 (dest2, word1));
2884   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2885      thus allowing us to omit an early clobber on the output.  */
2886   emit_insn (gen_bswapsi2 (dest1, word2));
2887   DONE;
2890 (define_split
2891   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2892         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2893    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2894   "!TARGET_POWERPC64 && reload_completed"
2895   [(const_int 0)]
2897   rtx dest = operands[0];
2898   rtx src  = operands[1];
2899   rtx op2  = operands[2];
2900   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2901   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2902   rtx addr1;
2903   rtx addr2;
2904   rtx word1;
2905   rtx word2;
2907   addr1 = XEXP (dest, 0);
2908   if (GET_CODE (addr1) == PLUS)
2909     {
2910       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2911       if (TARGET_AVOID_XFORM)
2912         {
2913           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2914           addr2 = op2;
2915         }
2916       else
2917         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2918     }
2919   else if (TARGET_AVOID_XFORM)
2920     {
2921       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2922       addr2 = op2;
2923     }
2924   else
2925     {
2926       emit_move_insn (op2, GEN_INT (4));
2927       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2928     }
2930   word1 = change_address (dest, SImode, addr1);
2931   word2 = change_address (dest, SImode, addr2);
2933   emit_insn (gen_bswapsi2 (word2, src1));
2934   emit_insn (gen_bswapsi2 (word1, src2));
2935   DONE;
2938 (define_split
2939   [(set (match_operand:DI 0 "gpc_reg_operand")
2940         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2941    (clobber (match_operand:SI 2 ""))]
2942   "!TARGET_POWERPC64 && reload_completed"
2943   [(const_int 0)]
2945   rtx dest  = operands[0];
2946   rtx src   = operands[1];
2947   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2948   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2949   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2950   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2952   emit_insn (gen_bswapsi2 (dest1, src2));
2953   emit_insn (gen_bswapsi2 (dest2, src1));
2954   DONE;
2958 (define_insn "mul<mode>3"
2959   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2960         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2961                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2962   ""
2963   "@
2964    mull<wd> %0,%1,%2
2965    mulli %0,%1,%2"
2966    [(set_attr "type" "mul")
2967     (set (attr "size")
2968       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2969                 (const_string "8")
2970              (match_operand:GPR 2 "short_cint_operand")
2971                 (const_string "16")]
2972         (const_string "<bits>")))])
2974 (define_insn_and_split "*mul<mode>3_dot"
2975   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2976         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2977                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2978                     (const_int 0)))
2979    (clobber (match_scratch:GPR 0 "=r,r"))]
2980   "<MODE>mode == Pmode"
2981   "@
2982    mull<wd>. %0,%1,%2
2983    #"
2984   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2985   [(set (match_dup 0)
2986         (mult:GPR (match_dup 1)
2987                   (match_dup 2)))
2988    (set (match_dup 3)
2989         (compare:CC (match_dup 0)
2990                     (const_int 0)))]
2991   ""
2992   [(set_attr "type" "mul")
2993    (set_attr "size" "<bits>")
2994    (set_attr "dot" "yes")
2995    (set_attr "length" "4,8")])
2997 (define_insn_and_split "*mul<mode>3_dot2"
2998   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2999         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3000                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3001                     (const_int 0)))
3002    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3003         (mult:GPR (match_dup 1)
3004                   (match_dup 2)))]
3005   "<MODE>mode == Pmode"
3006   "@
3007    mull<wd>. %0,%1,%2
3008    #"
3009   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3010   [(set (match_dup 0)
3011         (mult:GPR (match_dup 1)
3012                   (match_dup 2)))
3013    (set (match_dup 3)
3014         (compare:CC (match_dup 0)
3015                     (const_int 0)))]
3016   ""
3017   [(set_attr "type" "mul")
3018    (set_attr "size" "<bits>")
3019    (set_attr "dot" "yes")
3020    (set_attr "length" "4,8")])
3023 (define_expand "<su>mul<mode>3_highpart"
3024   [(set (match_operand:GPR 0 "gpc_reg_operand")
3025         (subreg:GPR
3026           (mult:<DMODE> (any_extend:<DMODE>
3027                           (match_operand:GPR 1 "gpc_reg_operand"))
3028                         (any_extend:<DMODE>
3029                           (match_operand:GPR 2 "gpc_reg_operand")))
3030          0))]
3031   ""
3033   if (<MODE>mode == SImode && TARGET_POWERPC64)
3034     {
3035       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3036                                              operands[2]));
3037       DONE;
3038     }
3040   if (!WORDS_BIG_ENDIAN)
3041     {
3042       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3043                                                  operands[2]));
3044       DONE;
3045     }
3048 (define_insn "*<su>mul<mode>3_highpart"
3049   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3050         (subreg:GPR
3051           (mult:<DMODE> (any_extend:<DMODE>
3052                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
3053                         (any_extend:<DMODE>
3054                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
3055          0))]
3056   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3057   "mulh<wd><u> %0,%1,%2"
3058   [(set_attr "type" "mul")
3059    (set_attr "size" "<bits>")])
3061 (define_insn "<su>mulsi3_highpart_le"
3062   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3063         (subreg:SI
3064           (mult:DI (any_extend:DI
3065                      (match_operand:SI 1 "gpc_reg_operand" "r"))
3066                    (any_extend:DI
3067                      (match_operand:SI 2 "gpc_reg_operand" "r")))
3068          4))]
3069   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3070   "mulhw<u> %0,%1,%2"
3071   [(set_attr "type" "mul")])
3073 (define_insn "<su>muldi3_highpart_le"
3074   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3075         (subreg:DI
3076           (mult:TI (any_extend:TI
3077                      (match_operand:DI 1 "gpc_reg_operand" "r"))
3078                    (any_extend:TI
3079                      (match_operand:DI 2 "gpc_reg_operand" "r")))
3080          8))]
3081   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3082   "mulhd<u> %0,%1,%2"
3083   [(set_attr "type" "mul")
3084    (set_attr "size" "64")])
3086 (define_insn "<su>mulsi3_highpart_64"
3087   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3088         (truncate:SI
3089           (lshiftrt:DI
3090             (mult:DI (any_extend:DI
3091                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3092                      (any_extend:DI
3093                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3094             (const_int 32))))]
3095   "TARGET_POWERPC64"
3096   "mulhw<u> %0,%1,%2"
3097   [(set_attr "type" "mul")])
3099 (define_expand "<u>mul<mode><dmode>3"
3100   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3101         (mult:<DMODE> (any_extend:<DMODE>
3102                         (match_operand:GPR 1 "gpc_reg_operand"))
3103                       (any_extend:<DMODE>
3104                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3105   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3107   rtx l = gen_reg_rtx (<MODE>mode);
3108   rtx h = gen_reg_rtx (<MODE>mode);
3109   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3110   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3111   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3112   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3113   DONE;
3116 (define_insn "*maddld<mode>4"
3117   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3118         (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3119                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
3120                   (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3121   "TARGET_MADDLD"
3122   "maddld %0,%1,%2,%3"
3123   [(set_attr "type" "mul")])
3125 (define_insn "udiv<mode>3"
3126   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3127         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3128                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3129   ""
3130   "div<wd>u %0,%1,%2"
3131   [(set_attr "type" "div")
3132    (set_attr "size" "<bits>")])
3135 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3136 ;; modulus.  If it isn't a power of two, force operands into register and do
3137 ;; a normal divide.
3138 (define_expand "div<mode>3"
3139   [(set (match_operand:GPR 0 "gpc_reg_operand")
3140         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3141                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3142   ""
3144   if (CONST_INT_P (operands[2])
3145       && INTVAL (operands[2]) > 0
3146       && exact_log2 (INTVAL (operands[2])) >= 0)
3147     {
3148       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3149       DONE;
3150     }
3152   operands[2] = force_reg (<MODE>mode, operands[2]);
3155 (define_insn "*div<mode>3"
3156   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3157         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3158                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3159   ""
3160   "div<wd> %0,%1,%2"
3161   [(set_attr "type" "div")
3162    (set_attr "size" "<bits>")])
3164 (define_insn "div<mode>3_sra"
3165   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3166         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3167                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3168    (clobber (reg:GPR CA_REGNO))]
3169   ""
3170   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3171   [(set_attr "type" "two")
3172    (set_attr "length" "8")])
3174 (define_insn_and_split "*div<mode>3_sra_dot"
3175   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3176         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3177                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3178                     (const_int 0)))
3179    (clobber (match_scratch:GPR 0 "=r,r"))
3180    (clobber (reg:GPR CA_REGNO))]
3181   "<MODE>mode == Pmode"
3182   "@
3183    sra<wd>i %0,%1,%p2\;addze. %0,%0
3184    #"
3185   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3186   [(parallel [(set (match_dup 0)
3187                    (div:GPR (match_dup 1)
3188                             (match_dup 2)))
3189               (clobber (reg:GPR CA_REGNO))])
3190    (set (match_dup 3)
3191         (compare:CC (match_dup 0)
3192                     (const_int 0)))]
3193   ""
3194   [(set_attr "type" "two")
3195    (set_attr "length" "8,12")
3196    (set_attr "cell_micro" "not")])
3198 (define_insn_and_split "*div<mode>3_sra_dot2"
3199   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3200         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3201                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3202                     (const_int 0)))
3203    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3204         (div:GPR (match_dup 1)
3205                  (match_dup 2)))
3206    (clobber (reg:GPR CA_REGNO))]
3207   "<MODE>mode == Pmode"
3208   "@
3209    sra<wd>i %0,%1,%p2\;addze. %0,%0
3210    #"
3211   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3212   [(parallel [(set (match_dup 0)
3213                    (div:GPR (match_dup 1)
3214                             (match_dup 2)))
3215               (clobber (reg:GPR CA_REGNO))])
3216    (set (match_dup 3)
3217         (compare:CC (match_dup 0)
3218                     (const_int 0)))]
3219   ""
3220   [(set_attr "type" "two")
3221    (set_attr "length" "8,12")
3222    (set_attr "cell_micro" "not")])
3224 (define_expand "mod<mode>3"
3225   [(set (match_operand:GPR 0 "gpc_reg_operand")
3226         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3227                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3228   ""
3230   int i;
3231   rtx temp1;
3232   rtx temp2;
3234   if (!CONST_INT_P (operands[2])
3235       || INTVAL (operands[2]) <= 0
3236       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3237     {
3238       if (!TARGET_MODULO)
3239         FAIL;
3241       operands[2] = force_reg (<MODE>mode, operands[2]);
3242     }
3243   else
3244     {
3245       temp1 = gen_reg_rtx (<MODE>mode);
3246       temp2 = gen_reg_rtx (<MODE>mode);
3248       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3249       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3250       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3251       DONE;
3252     }
3255 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3256 ;; mod, prefer putting the result of mod into a different register
3257 (define_insn "*mod<mode>3"
3258   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3259         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3260                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3261   "TARGET_MODULO"
3262   "mods<wd> %0,%1,%2"
3263   [(set_attr "type" "div")
3264    (set_attr "size" "<bits>")])
3267 (define_insn "umod<mode>3"
3268   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3269         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3270                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3271   "TARGET_MODULO"
3272   "modu<wd> %0,%1,%2"
3273   [(set_attr "type" "div")
3274    (set_attr "size" "<bits>")])
3276 ;; On machines with modulo support, do a combined div/mod the old fashioned
3277 ;; method, since the multiply/subtract is faster than doing the mod instruction
3278 ;; after a divide.
3280 (define_peephole2
3281   [(set (match_operand:GPR 0 "gpc_reg_operand")
3282         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3283                  (match_operand:GPR 2 "gpc_reg_operand")))
3284    (set (match_operand:GPR 3 "gpc_reg_operand")
3285         (mod:GPR (match_dup 1)
3286                  (match_dup 2)))]
3287   "TARGET_MODULO
3288    && ! reg_mentioned_p (operands[0], operands[1])
3289    && ! reg_mentioned_p (operands[0], operands[2])
3290    && ! reg_mentioned_p (operands[3], operands[1])
3291    && ! reg_mentioned_p (operands[3], operands[2])"
3292   [(set (match_dup 0)
3293         (div:GPR (match_dup 1)
3294                  (match_dup 2)))
3295    (set (match_dup 3)
3296         (mult:GPR (match_dup 0)
3297                   (match_dup 2)))
3298    (set (match_dup 3)
3299         (minus:GPR (match_dup 1)
3300                    (match_dup 3)))])
3302 (define_peephole2
3303   [(set (match_operand:GPR 0 "gpc_reg_operand")
3304         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3305                   (match_operand:GPR 2 "gpc_reg_operand")))
3306    (set (match_operand:GPR 3 "gpc_reg_operand")
3307         (umod:GPR (match_dup 1)
3308                   (match_dup 2)))]
3309   "TARGET_MODULO
3310    && ! reg_mentioned_p (operands[0], operands[1])
3311    && ! reg_mentioned_p (operands[0], operands[2])
3312    && ! reg_mentioned_p (operands[3], operands[1])
3313    && ! reg_mentioned_p (operands[3], operands[2])"
3314   [(set (match_dup 0)
3315         (udiv:GPR (match_dup 1)
3316                   (match_dup 2)))
3317    (set (match_dup 3)
3318         (mult:GPR (match_dup 0)
3319                   (match_dup 2)))
3320    (set (match_dup 3)
3321         (minus:GPR (match_dup 1)
3322                    (match_dup 3)))])
3325 ;; Logical instructions
3326 ;; The logical instructions are mostly combined by using match_operator,
3327 ;; but the plain AND insns are somewhat different because there is no
3328 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3329 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3331 (define_expand "and<mode>3"
3332   [(set (match_operand:SDI 0 "gpc_reg_operand")
3333         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3334                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3335   ""
3337   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3338     {
3339       rs6000_split_logical (operands, AND, false, false, false);
3340       DONE;
3341     }
3343   if (CONST_INT_P (operands[2]))
3344     {
3345       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3346         {
3347           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3348           DONE;
3349         }
3351       if (logical_const_operand (operands[2], <MODE>mode))
3352         {
3353           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3354           DONE;
3355         }
3357       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3358         {
3359           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3360           DONE;
3361         }
3363       operands[2] = force_reg (<MODE>mode, operands[2]);
3364     }
3368 (define_insn "and<mode>3_imm"
3369   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3370         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3371                  (match_operand:GPR 2 "logical_const_operand" "n")))
3372    (clobber (match_scratch:CC 3 "=x"))]
3373   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3374   "andi%e2. %0,%1,%u2"
3375   [(set_attr "type" "logical")
3376    (set_attr "dot" "yes")])
3378 (define_insn_and_split "*and<mode>3_imm_dot"
3379   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3380         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3381                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3382                     (const_int 0)))
3383    (clobber (match_scratch:GPR 0 "=r,r"))
3384    (clobber (match_scratch:CC 4 "=X,x"))]
3385   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3386    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3387   "@
3388    andi%e2. %0,%1,%u2
3389    #"
3390   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3391   [(parallel [(set (match_dup 0)
3392                    (and:GPR (match_dup 1)
3393                             (match_dup 2)))
3394               (clobber (match_dup 4))])
3395    (set (match_dup 3)
3396         (compare:CC (match_dup 0)
3397                     (const_int 0)))]
3398   ""
3399   [(set_attr "type" "logical")
3400    (set_attr "dot" "yes")
3401    (set_attr "length" "4,8")])
3403 (define_insn_and_split "*and<mode>3_imm_dot2"
3404   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3405         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3406                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3407                     (const_int 0)))
3408    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3409         (and:GPR (match_dup 1)
3410                  (match_dup 2)))
3411    (clobber (match_scratch:CC 4 "=X,x"))]
3412   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3413    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3414   "@
3415    andi%e2. %0,%1,%u2
3416    #"
3417   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3418   [(parallel [(set (match_dup 0)
3419                    (and:GPR (match_dup 1)
3420                             (match_dup 2)))
3421               (clobber (match_dup 4))])
3422    (set (match_dup 3)
3423         (compare:CC (match_dup 0)
3424                     (const_int 0)))]
3425   ""
3426   [(set_attr "type" "logical")
3427    (set_attr "dot" "yes")
3428    (set_attr "length" "4,8")])
3430 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3431   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3432         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3433                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3434                     (const_int 0)))
3435    (clobber (match_scratch:GPR 0 "=r,r"))]
3436   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3437    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3438   "@
3439    andi%e2. %0,%1,%u2
3440    #"
3441   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3442   [(set (match_dup 0)
3443         (and:GPR (match_dup 1)
3444                  (match_dup 2)))
3445    (set (match_dup 3)
3446         (compare:CC (match_dup 0)
3447                     (const_int 0)))]
3448   ""
3449   [(set_attr "type" "logical")
3450    (set_attr "dot" "yes")
3451    (set_attr "length" "4,8")])
3453 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3454   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3455         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3456                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3457                     (const_int 0)))
3458    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3459         (and:GPR (match_dup 1)
3460                  (match_dup 2)))]
3461   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3462    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3463   "@
3464    andi%e2. %0,%1,%u2
3465    #"
3466   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3467   [(set (match_dup 0)
3468         (and:GPR (match_dup 1)
3469                  (match_dup 2)))
3470    (set (match_dup 3)
3471         (compare:CC (match_dup 0)
3472                     (const_int 0)))]
3473   ""
3474   [(set_attr "type" "logical")
3475    (set_attr "dot" "yes")
3476    (set_attr "length" "4,8")])
3478 (define_insn "*and<mode>3_imm_dot_shifted"
3479   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3480         (compare:CC
3481           (and:GPR
3482             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3483                           (match_operand:SI 4 "const_int_operand" "n"))
3484             (match_operand:GPR 2 "const_int_operand" "n"))
3485           (const_int 0)))
3486    (clobber (match_scratch:GPR 0 "=r"))]
3487   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3488                                    << INTVAL (operands[4])),
3489                           DImode)
3490    && (<MODE>mode == Pmode
3491        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3493   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3494   return "andi%e2. %0,%1,%u2";
3496   [(set_attr "type" "logical")
3497    (set_attr "dot" "yes")])
3500 (define_insn "and<mode>3_mask"
3501   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3502         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3503                  (match_operand:GPR 2 "const_int_operand" "n")))]
3504   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3506   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3508   [(set_attr "type" "shift")])
3510 (define_insn_and_split "*and<mode>3_mask_dot"
3511   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3512         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3513                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3514                     (const_int 0)))
3515    (clobber (match_scratch:GPR 0 "=r,r"))]
3516   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3517    && !logical_const_operand (operands[2], <MODE>mode)
3518    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3520   if (which_alternative == 0)
3521     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3522   else
3523     return "#";
3525   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3526   [(set (match_dup 0)
3527         (and:GPR (match_dup 1)
3528                  (match_dup 2)))
3529    (set (match_dup 3)
3530         (compare:CC (match_dup 0)
3531                     (const_int 0)))]
3532   ""
3533   [(set_attr "type" "shift")
3534    (set_attr "dot" "yes")
3535    (set_attr "length" "4,8")])
3537 (define_insn_and_split "*and<mode>3_mask_dot2"
3538   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3539         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3540                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3541                     (const_int 0)))
3542    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3543         (and:GPR (match_dup 1)
3544                  (match_dup 2)))]
3545   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3546    && !logical_const_operand (operands[2], <MODE>mode)
3547    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3549   if (which_alternative == 0)
3550     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3551   else
3552     return "#";
3554   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3555   [(set (match_dup 0)
3556         (and:GPR (match_dup 1)
3557                  (match_dup 2)))
3558    (set (match_dup 3)
3559         (compare:CC (match_dup 0)
3560                     (const_int 0)))]
3561   ""
3562   [(set_attr "type" "shift")
3563    (set_attr "dot" "yes")
3564    (set_attr "length" "4,8")])
3567 (define_insn_and_split "*and<mode>3_2insn"
3568   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3569         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3570                  (match_operand:GPR 2 "const_int_operand" "n")))]
3571   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3572    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3573         || logical_const_operand (operands[2], <MODE>mode))"
3574   "#"
3575   "&& 1"
3576   [(pc)]
3578   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3579   DONE;
3581   [(set_attr "type" "shift")
3582    (set_attr "length" "8")])
3584 (define_insn_and_split "*and<mode>3_2insn_dot"
3585   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3586         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3587                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3588                     (const_int 0)))
3589    (clobber (match_scratch:GPR 0 "=r,r"))]
3590   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3591    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3592    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3593         || logical_const_operand (operands[2], <MODE>mode))"
3594   "#"
3595   "&& reload_completed"
3596   [(pc)]
3598   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3599   DONE;
3601   [(set_attr "type" "shift")
3602    (set_attr "dot" "yes")
3603    (set_attr "length" "8,12")])
3605 (define_insn_and_split "*and<mode>3_2insn_dot2"
3606   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3607         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3608                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3609                     (const_int 0)))
3610    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3611         (and:GPR (match_dup 1)
3612                  (match_dup 2)))]
3613   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3614    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3615    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3616         || logical_const_operand (operands[2], <MODE>mode))"
3617   "#"
3618   "&& reload_completed"
3619   [(pc)]
3621   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3622   DONE;
3624   [(set_attr "type" "shift")
3625    (set_attr "dot" "yes")
3626    (set_attr "length" "8,12")])
3629 (define_expand "<code><mode>3"
3630   [(set (match_operand:SDI 0 "gpc_reg_operand")
3631         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3632                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3633   ""
3635   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3636     {
3637       rs6000_split_logical (operands, <CODE>, false, false, false);
3638       DONE;
3639     }
3641   if (non_logical_cint_operand (operands[2], <MODE>mode))
3642     {
3643       rtx tmp = ((!can_create_pseudo_p ()
3644                   || rtx_equal_p (operands[0], operands[1]))
3645                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3647       HOST_WIDE_INT value = INTVAL (operands[2]);
3648       HOST_WIDE_INT lo = value & 0xffff;
3649       HOST_WIDE_INT hi = value - lo;
3651       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3652       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3653       DONE;
3654     }
3656   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3657     operands[2] = force_reg (<MODE>mode, operands[2]);
3660 (define_split
3661   [(set (match_operand:GPR 0 "gpc_reg_operand")
3662         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3663                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3664   ""
3665   [(set (match_dup 3)
3666         (iorxor:GPR (match_dup 1)
3667                     (match_dup 4)))
3668    (set (match_dup 0)
3669         (iorxor:GPR (match_dup 3)
3670                     (match_dup 5)))]
3672   operands[3] = ((!can_create_pseudo_p ()
3673                   || rtx_equal_p (operands[0], operands[1]))
3674                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3676   HOST_WIDE_INT value = INTVAL (operands[2]);
3677   HOST_WIDE_INT lo = value & 0xffff;
3678   HOST_WIDE_INT hi = value - lo;
3680   operands[4] = GEN_INT (hi);
3681   operands[5] = GEN_INT (lo);
3684 (define_insn "*bool<mode>3_imm"
3685   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3686         (match_operator:GPR 3 "boolean_or_operator"
3687          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3688           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3689   ""
3690   "%q3i%e2 %0,%1,%u2"
3691   [(set_attr "type" "logical")])
3693 (define_insn "*bool<mode>3"
3694   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3695         (match_operator:GPR 3 "boolean_operator"
3696          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3697           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3698   ""
3699   "%q3 %0,%1,%2"
3700   [(set_attr "type" "logical")])
3702 (define_insn_and_split "*bool<mode>3_dot"
3703   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3704         (compare:CC (match_operator:GPR 3 "boolean_operator"
3705          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3706           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3707          (const_int 0)))
3708    (clobber (match_scratch:GPR 0 "=r,r"))]
3709   "<MODE>mode == Pmode"
3710   "@
3711    %q3. %0,%1,%2
3712    #"
3713   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3714   [(set (match_dup 0)
3715         (match_dup 3))
3716    (set (match_dup 4)
3717         (compare:CC (match_dup 0)
3718                     (const_int 0)))]
3719   ""
3720   [(set_attr "type" "logical")
3721    (set_attr "dot" "yes")
3722    (set_attr "length" "4,8")])
3724 (define_insn_and_split "*bool<mode>3_dot2"
3725   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3726         (compare:CC (match_operator:GPR 3 "boolean_operator"
3727          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3728           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3729          (const_int 0)))
3730    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3731         (match_dup 3))]
3732   "<MODE>mode == Pmode"
3733   "@
3734    %q3. %0,%1,%2
3735    #"
3736   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3737   [(set (match_dup 0)
3738         (match_dup 3))
3739    (set (match_dup 4)
3740         (compare:CC (match_dup 0)
3741                     (const_int 0)))]
3742   ""
3743   [(set_attr "type" "logical")
3744    (set_attr "dot" "yes")
3745    (set_attr "length" "4,8")])
3748 (define_insn "*boolc<mode>3"
3749   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3750         (match_operator:GPR 3 "boolean_operator"
3751          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3752           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3753   ""
3754   "%q3 %0,%1,%2"
3755   [(set_attr "type" "logical")])
3757 (define_insn_and_split "*boolc<mode>3_dot"
3758   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3759         (compare:CC (match_operator:GPR 3 "boolean_operator"
3760          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3761           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3762          (const_int 0)))
3763    (clobber (match_scratch:GPR 0 "=r,r"))]
3764   "<MODE>mode == Pmode"
3765   "@
3766    %q3. %0,%1,%2
3767    #"
3768   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3769   [(set (match_dup 0)
3770         (match_dup 3))
3771    (set (match_dup 4)
3772         (compare:CC (match_dup 0)
3773                     (const_int 0)))]
3774   ""
3775   [(set_attr "type" "logical")
3776    (set_attr "dot" "yes")
3777    (set_attr "length" "4,8")])
3779 (define_insn_and_split "*boolc<mode>3_dot2"
3780   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3781         (compare:CC (match_operator:GPR 3 "boolean_operator"
3782          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3783           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3784          (const_int 0)))
3785    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3786         (match_dup 3))]
3787   "<MODE>mode == Pmode"
3788   "@
3789    %q3. %0,%1,%2
3790    #"
3791   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3792   [(set (match_dup 0)
3793         (match_dup 3))
3794    (set (match_dup 4)
3795         (compare:CC (match_dup 0)
3796                     (const_int 0)))]
3797   ""
3798   [(set_attr "type" "logical")
3799    (set_attr "dot" "yes")
3800    (set_attr "length" "4,8")])
3803 (define_insn "*boolcc<mode>3"
3804   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3805         (match_operator:GPR 3 "boolean_operator"
3806          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3807           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3808   ""
3809   "%q3 %0,%1,%2"
3810   [(set_attr "type" "logical")])
3812 (define_insn_and_split "*boolcc<mode>3_dot"
3813   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3814         (compare:CC (match_operator:GPR 3 "boolean_operator"
3815          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3816           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3817          (const_int 0)))
3818    (clobber (match_scratch:GPR 0 "=r,r"))]
3819   "<MODE>mode == Pmode"
3820   "@
3821    %q3. %0,%1,%2
3822    #"
3823   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3824   [(set (match_dup 0)
3825         (match_dup 3))
3826    (set (match_dup 4)
3827         (compare:CC (match_dup 0)
3828                     (const_int 0)))]
3829   ""
3830   [(set_attr "type" "logical")
3831    (set_attr "dot" "yes")
3832    (set_attr "length" "4,8")])
3834 (define_insn_and_split "*boolcc<mode>3_dot2"
3835   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3836         (compare:CC (match_operator:GPR 3 "boolean_operator"
3837          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3838           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3839          (const_int 0)))
3840    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3841         (match_dup 3))]
3842   "<MODE>mode == Pmode"
3843   "@
3844    %q3. %0,%1,%2
3845    #"
3846   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3847   [(set (match_dup 0)
3848         (match_dup 3))
3849    (set (match_dup 4)
3850         (compare:CC (match_dup 0)
3851                     (const_int 0)))]
3852   ""
3853   [(set_attr "type" "logical")
3854    (set_attr "dot" "yes")
3855    (set_attr "length" "4,8")])
3858 ;; TODO: Should have dots of this as well.
3859 (define_insn "*eqv<mode>3"
3860   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3861         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3862                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3863   ""
3864   "eqv %0,%1,%2"
3865   [(set_attr "type" "logical")])
3867 ;; Rotate-and-mask and insert.
3869 (define_insn "*rotl<mode>3_mask"
3870   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3871         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3872                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3873                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3874                  (match_operand:GPR 3 "const_int_operand" "n")))]
3875   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3877   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3879   [(set_attr "type" "shift")
3880    (set_attr "maybe_var_shift" "yes")])
3882 (define_insn_and_split "*rotl<mode>3_mask_dot"
3883   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3884         (compare:CC
3885           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3886                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3887                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3888                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3889           (const_int 0)))
3890    (clobber (match_scratch:GPR 0 "=r,r"))]
3891   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3892    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3894   if (which_alternative == 0)
3895     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3896   else
3897     return "#";
3899   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3900   [(set (match_dup 0)
3901         (and:GPR (match_dup 4)
3902                  (match_dup 3)))
3903    (set (match_dup 5)
3904         (compare:CC (match_dup 0)
3905                     (const_int 0)))]
3906   ""
3907   [(set_attr "type" "shift")
3908    (set_attr "maybe_var_shift" "yes")
3909    (set_attr "dot" "yes")
3910    (set_attr "length" "4,8")])
3912 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3913   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3914         (compare:CC
3915           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3916                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3917                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3918                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3919           (const_int 0)))
3920    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3921         (and:GPR (match_dup 4)
3922                  (match_dup 3)))]
3923   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3924    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3926   if (which_alternative == 0)
3927     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3928   else
3929     return "#";
3931   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3932   [(set (match_dup 0)
3933         (and:GPR (match_dup 4)
3934                  (match_dup 3)))
3935    (set (match_dup 5)
3936         (compare:CC (match_dup 0)
3937                     (const_int 0)))]
3938   ""
3939   [(set_attr "type" "shift")
3940    (set_attr "maybe_var_shift" "yes")
3941    (set_attr "dot" "yes")
3942    (set_attr "length" "4,8")])
3944 ; Special case for less-than-0.  We can do it with just one machine
3945 ; instruction, but the generic optimizers do not realise it is cheap.
3946 (define_insn "*lt0_<mode>di"
3947   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3948         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3949                 (const_int 0)))]
3950   "TARGET_POWERPC64"
3951   "srdi %0,%1,63"
3952   [(set_attr "type" "shift")])
3954 (define_insn "*lt0_<mode>si"
3955   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3956         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3957                 (const_int 0)))]
3958   ""
3959   "rlwinm %0,%1,1,31,31"
3960   [(set_attr "type" "shift")])
3964 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3965 ; both are an AND so are the same precedence).
3966 (define_insn "*rotl<mode>3_insert"
3967   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3968         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3969                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3970                             (match_operand:SI 2 "const_int_operand" "n")])
3971                           (match_operand:GPR 3 "const_int_operand" "n"))
3972                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3973                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3974   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3975    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3977   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3979   [(set_attr "type" "insert")])
3980 ; FIXME: this needs an attr "size", so that the scheduler can see the
3981 ; difference between rlwimi and rldimi.  We also might want dot forms,
3982 ; but not for rlwimi on POWER4 and similar processors.
3984 (define_insn "*rotl<mode>3_insert_2"
3985   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3986         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3987                           (match_operand:GPR 6 "const_int_operand" "n"))
3988                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3989                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3990                             (match_operand:SI 2 "const_int_operand" "n")])
3991                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3992   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3993    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3995   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3997   [(set_attr "type" "insert")])
3999 ; There are also some forms without one of the ANDs.
4000 (define_insn "*rotl<mode>3_insert_3"
4001   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4002         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4003                           (match_operand:GPR 4 "const_int_operand" "n"))
4004                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4005                              (match_operand:SI 2 "const_int_operand" "n"))))]
4006   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4008   if (<MODE>mode == SImode)
4009     return "rlwimi %0,%1,%h2,0,31-%h2";
4010   else
4011     return "rldimi %0,%1,%H2,0";
4013   [(set_attr "type" "insert")])
4015 (define_insn "*rotl<mode>3_insert_4"
4016   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4017         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4018                           (match_operand:GPR 4 "const_int_operand" "n"))
4019                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4020                                (match_operand:SI 2 "const_int_operand" "n"))))]
4021   "<MODE>mode == SImode &&
4022    GET_MODE_PRECISION (<MODE>mode)
4023    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4025   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4026                          - INTVAL (operands[2]));
4027   if (<MODE>mode == SImode)
4028     return "rlwimi %0,%1,%h2,32-%h2,31";
4029   else
4030     return "rldimi %0,%1,%H2,64-%H2";
4032   [(set_attr "type" "insert")])
4034 (define_insn "*rotlsi3_insert_5"
4035   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4036         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4037                         (match_operand:SI 2 "const_int_operand" "n,n"))
4038                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4039                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
4040   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4041    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4042    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4043   "@
4044    rlwimi %0,%3,0,%4
4045    rlwimi %0,%1,0,%2"
4046   [(set_attr "type" "insert")])
4048 (define_insn "*rotldi3_insert_6"
4049   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4050         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4051                         (match_operand:DI 2 "const_int_operand" "n"))
4052                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4053                         (match_operand:DI 4 "const_int_operand" "n"))))]
4054   "exact_log2 (-UINTVAL (operands[2])) > 0
4055    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4057   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4058   return "rldimi %0,%3,0,%5";
4060   [(set_attr "type" "insert")
4061    (set_attr "size" "64")])
4063 (define_insn "*rotldi3_insert_7"
4064   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4065         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4066                         (match_operand:DI 4 "const_int_operand" "n"))
4067                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4068                         (match_operand:DI 2 "const_int_operand" "n"))))]
4069   "exact_log2 (-UINTVAL (operands[2])) > 0
4070    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4072   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4073   return "rldimi %0,%3,0,%5";
4075   [(set_attr "type" "insert")
4076    (set_attr "size" "64")])
4079 ; This handles the important case of multiple-precision shifts.  There is
4080 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4081 (define_split
4082   [(set (match_operand:GPR 0 "gpc_reg_operand")
4083         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4084                              (match_operand:SI 3 "const_int_operand"))
4085                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4086                                (match_operand:SI 4 "const_int_operand"))))]
4087   "can_create_pseudo_p ()
4088    && INTVAL (operands[3]) + INTVAL (operands[4])
4089       >= GET_MODE_PRECISION (<MODE>mode)"
4090   [(set (match_dup 5)
4091         (lshiftrt:GPR (match_dup 2)
4092                       (match_dup 4)))
4093    (set (match_dup 0)
4094         (ior:GPR (and:GPR (match_dup 5)
4095                           (match_dup 6))
4096                  (ashift:GPR (match_dup 1)
4097                              (match_dup 3))))]
4099   unsigned HOST_WIDE_INT mask = 1;
4100   mask = (mask << INTVAL (operands[3])) - 1;
4101   operands[5] = gen_reg_rtx (<MODE>mode);
4102   operands[6] = GEN_INT (mask);
4105 (define_split
4106   [(set (match_operand:GPR 0 "gpc_reg_operand")
4107         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4108                                (match_operand:SI 4 "const_int_operand"))
4109                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4110                              (match_operand:SI 3 "const_int_operand"))))]
4111   "can_create_pseudo_p ()
4112    && INTVAL (operands[3]) + INTVAL (operands[4])
4113       >= GET_MODE_PRECISION (<MODE>mode)"
4114   [(set (match_dup 5)
4115         (lshiftrt:GPR (match_dup 2)
4116                       (match_dup 4)))
4117    (set (match_dup 0)
4118         (ior:GPR (and:GPR (match_dup 5)
4119                           (match_dup 6))
4120                  (ashift:GPR (match_dup 1)
4121                              (match_dup 3))))]
4123   unsigned HOST_WIDE_INT mask = 1;
4124   mask = (mask << INTVAL (operands[3])) - 1;
4125   operands[5] = gen_reg_rtx (<MODE>mode);
4126   operands[6] = GEN_INT (mask);
4130 ; Another important case is setting some bits to 1; we can do that with
4131 ; an insert instruction, in many cases.
4132 (define_insn_and_split "*ior<mode>_mask"
4133   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4134         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4135                  (match_operand:GPR 2 "const_int_operand" "n")))
4136    (clobber (match_scratch:GPR 3 "=r"))]
4137   "!logical_const_operand (operands[2], <MODE>mode)
4138    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4139   "#"
4140   "&& 1"
4141   [(set (match_dup 3)
4142         (const_int -1))
4143    (set (match_dup 0)
4144         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4145                                       (match_dup 4))
4146                           (match_dup 2))
4147                  (and:GPR (match_dup 1)
4148                           (match_dup 5))))]
4150   int nb, ne;
4151   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4152   if (GET_CODE (operands[3]) == SCRATCH)
4153     operands[3] = gen_reg_rtx (<MODE>mode);
4154   operands[4] = GEN_INT (ne);
4155   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4157   [(set_attr "type" "two")
4158    (set_attr "length" "8")])
4161 ; Yet another case is an rldimi with the second value coming from memory.
4162 ; The zero_extend that should become part of the rldimi is merged into the
4163 ; load from memory instead.  Split things properly again.
4164 (define_split
4165   [(set (match_operand:DI 0 "gpc_reg_operand")
4166         (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4167                            (match_operand:SI 2 "const_int_operand"))
4168                 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4169   "INTVAL (operands[2]) == <bits>"
4170   [(set (match_dup 4)
4171         (zero_extend:DI (match_dup 3)))
4172    (set (match_dup 0)
4173         (ior:DI (and:DI (match_dup 4)
4174                         (match_dup 5))
4175                 (ashift:DI (match_dup 1)
4176                            (match_dup 2))))]
4178   operands[4] = gen_reg_rtx (DImode);
4179   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4182 ; rlwimi, too.
4183 (define_split
4184   [(set (match_operand:SI 0 "gpc_reg_operand")
4185         (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4186                            (match_operand:SI 2 "const_int_operand"))
4187                 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4188   "INTVAL (operands[2]) == <bits>"
4189   [(set (match_dup 4)
4190         (zero_extend:SI (match_dup 3)))
4191    (set (match_dup 0)
4192         (ior:SI (and:SI (match_dup 4)
4193                         (match_dup 5))
4194                 (ashift:SI (match_dup 1)
4195                            (match_dup 2))))]
4197   operands[4] = gen_reg_rtx (SImode);
4198   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4202 ;; Now the simple shifts.
4204 (define_insn "rotl<mode>3"
4205   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4206         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4207                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4208   ""
4209   "rotl<wd>%I2 %0,%1,%<hH>2"
4210   [(set_attr "type" "shift")
4211    (set_attr "maybe_var_shift" "yes")])
4213 (define_insn "*rotlsi3_64"
4214   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4215         (zero_extend:DI
4216             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4217                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4218   "TARGET_POWERPC64"
4219   "rotlw%I2 %0,%1,%h2"
4220   [(set_attr "type" "shift")
4221    (set_attr "maybe_var_shift" "yes")])
4223 (define_insn_and_split "*rotl<mode>3_dot"
4224   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4225         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4226                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4227                     (const_int 0)))
4228    (clobber (match_scratch:GPR 0 "=r,r"))]
4229   "<MODE>mode == Pmode"
4230   "@
4231    rotl<wd>%I2. %0,%1,%<hH>2
4232    #"
4233   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4234   [(set (match_dup 0)
4235         (rotate:GPR (match_dup 1)
4236                     (match_dup 2)))
4237    (set (match_dup 3)
4238         (compare:CC (match_dup 0)
4239                     (const_int 0)))]
4240   ""
4241   [(set_attr "type" "shift")
4242    (set_attr "maybe_var_shift" "yes")
4243    (set_attr "dot" "yes")
4244    (set_attr "length" "4,8")])
4246 (define_insn_and_split "*rotl<mode>3_dot2"
4247   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4248         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4249                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4250                     (const_int 0)))
4251    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4252         (rotate:GPR (match_dup 1)
4253                     (match_dup 2)))]
4254   "<MODE>mode == Pmode"
4255   "@
4256    rotl<wd>%I2. %0,%1,%<hH>2
4257    #"
4258   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4259   [(set (match_dup 0)
4260         (rotate:GPR (match_dup 1)
4261                     (match_dup 2)))
4262    (set (match_dup 3)
4263         (compare:CC (match_dup 0)
4264                     (const_int 0)))]
4265   ""
4266   [(set_attr "type" "shift")
4267    (set_attr "maybe_var_shift" "yes")
4268    (set_attr "dot" "yes")
4269    (set_attr "length" "4,8")])
4272 (define_insn "ashl<mode>3"
4273   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4274         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4275                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4276   ""
4277   "sl<wd>%I2 %0,%1,%<hH>2"
4278   [(set_attr "type" "shift")
4279    (set_attr "maybe_var_shift" "yes")])
4281 (define_insn "*ashlsi3_64"
4282   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4283         (zero_extend:DI
4284             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4285                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4286   "TARGET_POWERPC64"
4287   "slw%I2 %0,%1,%h2"
4288   [(set_attr "type" "shift")
4289    (set_attr "maybe_var_shift" "yes")])
4291 (define_insn_and_split "*ashl<mode>3_dot"
4292   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4293         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4294                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4295                     (const_int 0)))
4296    (clobber (match_scratch:GPR 0 "=r,r"))]
4297   "<MODE>mode == Pmode"
4298   "@
4299    sl<wd>%I2. %0,%1,%<hH>2
4300    #"
4301   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4302   [(set (match_dup 0)
4303         (ashift:GPR (match_dup 1)
4304                     (match_dup 2)))
4305    (set (match_dup 3)
4306         (compare:CC (match_dup 0)
4307                     (const_int 0)))]
4308   ""
4309   [(set_attr "type" "shift")
4310    (set_attr "maybe_var_shift" "yes")
4311    (set_attr "dot" "yes")
4312    (set_attr "length" "4,8")])
4314 (define_insn_and_split "*ashl<mode>3_dot2"
4315   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4316         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4317                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4318                     (const_int 0)))
4319    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4320         (ashift:GPR (match_dup 1)
4321                     (match_dup 2)))]
4322   "<MODE>mode == Pmode"
4323   "@
4324    sl<wd>%I2. %0,%1,%<hH>2
4325    #"
4326   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4327   [(set (match_dup 0)
4328         (ashift:GPR (match_dup 1)
4329                     (match_dup 2)))
4330    (set (match_dup 3)
4331         (compare:CC (match_dup 0)
4332                     (const_int 0)))]
4333   ""
4334   [(set_attr "type" "shift")
4335    (set_attr "maybe_var_shift" "yes")
4336    (set_attr "dot" "yes")
4337    (set_attr "length" "4,8")])
4339 ;; Pretend we have a memory form of extswsli until register allocation is done
4340 ;; so that we use LWZ to load the value from memory, instead of LWA.
4341 (define_insn_and_split "ashdi3_extswsli"
4342   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4343         (ashift:DI
4344          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4345          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4346   "TARGET_EXTSWSLI"
4347   "@
4348    extswsli %0,%1,%2
4349    #"
4350   "&& reload_completed && MEM_P (operands[1])"
4351   [(set (match_dup 3)
4352         (match_dup 1))
4353    (set (match_dup 0)
4354         (ashift:DI (sign_extend:DI (match_dup 3))
4355                    (match_dup 2)))]
4357   operands[3] = gen_lowpart (SImode, operands[0]);
4359   [(set_attr "type" "shift")
4360    (set_attr "maybe_var_shift" "no")])
4363 (define_insn_and_split "ashdi3_extswsli_dot"
4364   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4365         (compare:CC
4366          (ashift:DI
4367           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4368           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4369          (const_int 0)))
4370    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4371   "TARGET_EXTSWSLI"
4372   "@
4373    extswsli. %0,%1,%2
4374    #
4375    #
4376    #"
4377   "&& reload_completed
4378    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4379        || memory_operand (operands[1], SImode))"
4380   [(pc)]
4382   rtx dest = operands[0];
4383   rtx src = operands[1];
4384   rtx shift = operands[2];
4385   rtx cr = operands[3];
4386   rtx src2;
4388   if (!MEM_P (src))
4389     src2 = src;
4390   else
4391     {
4392       src2 = gen_lowpart (SImode, dest);
4393       emit_move_insn (src2, src);
4394     }
4396   if (REGNO (cr) == CR0_REGNO)
4397     {
4398       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4399       DONE;
4400     }
4402   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4403   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4404   DONE;
4406   [(set_attr "type" "shift")
4407    (set_attr "maybe_var_shift" "no")
4408    (set_attr "dot" "yes")
4409    (set_attr "length" "4,8,8,12")])
4411 (define_insn_and_split "ashdi3_extswsli_dot2"
4412   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4413         (compare:CC
4414          (ashift:DI
4415           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4416           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4417          (const_int 0)))
4418    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4419         (ashift:DI (sign_extend:DI (match_dup 1))
4420                    (match_dup 2)))]
4421   "TARGET_EXTSWSLI"
4422   "@
4423    extswsli. %0,%1,%2
4424    #
4425    #
4426    #"
4427   "&& reload_completed
4428    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4429        || memory_operand (operands[1], SImode))"
4430   [(pc)]
4432   rtx dest = operands[0];
4433   rtx src = operands[1];
4434   rtx shift = operands[2];
4435   rtx cr = operands[3];
4436   rtx src2;
4438   if (!MEM_P (src))
4439     src2 = src;
4440   else
4441     {
4442       src2 = gen_lowpart (SImode, dest);
4443       emit_move_insn (src2, src);
4444     }
4446   if (REGNO (cr) == CR0_REGNO)
4447     {
4448       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4449       DONE;
4450     }
4452   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4453   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4454   DONE;
4456   [(set_attr "type" "shift")
4457    (set_attr "maybe_var_shift" "no")
4458    (set_attr "dot" "yes")
4459    (set_attr "length" "4,8,8,12")])
4461 (define_insn "lshr<mode>3"
4462   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4463         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4464                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4465   ""
4466   "sr<wd>%I2 %0,%1,%<hH>2"
4467   [(set_attr "type" "shift")
4468    (set_attr "maybe_var_shift" "yes")])
4470 (define_insn "*lshrsi3_64"
4471   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4472         (zero_extend:DI
4473             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4474                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4475   "TARGET_POWERPC64"
4476   "srw%I2 %0,%1,%h2"
4477   [(set_attr "type" "shift")
4478    (set_attr "maybe_var_shift" "yes")])
4480 (define_insn_and_split "*lshr<mode>3_dot"
4481   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4482         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4483                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4484                     (const_int 0)))
4485    (clobber (match_scratch:GPR 0 "=r,r"))]
4486   "<MODE>mode == Pmode"
4487   "@
4488    sr<wd>%I2. %0,%1,%<hH>2
4489    #"
4490   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4491   [(set (match_dup 0)
4492         (lshiftrt:GPR (match_dup 1)
4493                       (match_dup 2)))
4494    (set (match_dup 3)
4495         (compare:CC (match_dup 0)
4496                     (const_int 0)))]
4497   ""
4498   [(set_attr "type" "shift")
4499    (set_attr "maybe_var_shift" "yes")
4500    (set_attr "dot" "yes")
4501    (set_attr "length" "4,8")])
4503 (define_insn_and_split "*lshr<mode>3_dot2"
4504   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4505         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4506                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4507                     (const_int 0)))
4508    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4509         (lshiftrt:GPR (match_dup 1)
4510                       (match_dup 2)))]
4511   "<MODE>mode == Pmode"
4512   "@
4513    sr<wd>%I2. %0,%1,%<hH>2
4514    #"
4515   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4516   [(set (match_dup 0)
4517         (lshiftrt:GPR (match_dup 1)
4518                       (match_dup 2)))
4519    (set (match_dup 3)
4520         (compare:CC (match_dup 0)
4521                     (const_int 0)))]
4522   ""
4523   [(set_attr "type" "shift")
4524    (set_attr "maybe_var_shift" "yes")
4525    (set_attr "dot" "yes")
4526    (set_attr "length" "4,8")])
4529 (define_insn "ashr<mode>3"
4530   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4531         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4532                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4533    (clobber (reg:GPR CA_REGNO))]
4534   ""
4535   "sra<wd>%I2 %0,%1,%<hH>2"
4536   [(set_attr "type" "shift")
4537    (set_attr "maybe_var_shift" "yes")])
4539 (define_insn "*ashrsi3_64"
4540   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4541         (sign_extend:DI
4542             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4543                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4544    (clobber (reg:SI CA_REGNO))]
4545   "TARGET_POWERPC64"
4546   "sraw%I2 %0,%1,%h2"
4547   [(set_attr "type" "shift")
4548    (set_attr "maybe_var_shift" "yes")])
4550 (define_insn_and_split "*ashr<mode>3_dot"
4551   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4552         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4553                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4554                     (const_int 0)))
4555    (clobber (match_scratch:GPR 0 "=r,r"))
4556    (clobber (reg:GPR CA_REGNO))]
4557   "<MODE>mode == Pmode"
4558   "@
4559    sra<wd>%I2. %0,%1,%<hH>2
4560    #"
4561   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4562   [(parallel [(set (match_dup 0)
4563                    (ashiftrt:GPR (match_dup 1)
4564                                  (match_dup 2)))
4565               (clobber (reg:GPR CA_REGNO))])
4566    (set (match_dup 3)
4567         (compare:CC (match_dup 0)
4568                     (const_int 0)))]
4569   ""
4570   [(set_attr "type" "shift")
4571    (set_attr "maybe_var_shift" "yes")
4572    (set_attr "dot" "yes")
4573    (set_attr "length" "4,8")])
4575 (define_insn_and_split "*ashr<mode>3_dot2"
4576   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4577         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4578                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4579                     (const_int 0)))
4580    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4581         (ashiftrt:GPR (match_dup 1)
4582                       (match_dup 2)))
4583    (clobber (reg:GPR CA_REGNO))]
4584   "<MODE>mode == Pmode"
4585   "@
4586    sra<wd>%I2. %0,%1,%<hH>2
4587    #"
4588   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4589   [(parallel [(set (match_dup 0)
4590                    (ashiftrt:GPR (match_dup 1)
4591                                  (match_dup 2)))
4592               (clobber (reg:GPR CA_REGNO))])
4593    (set (match_dup 3)
4594         (compare:CC (match_dup 0)
4595                     (const_int 0)))]
4596   ""
4597   [(set_attr "type" "shift")
4598    (set_attr "maybe_var_shift" "yes")
4599    (set_attr "dot" "yes")
4600    (set_attr "length" "4,8")])
4602 ;; Builtins to replace a division to generate FRE reciprocal estimate
4603 ;; instructions and the necessary fixup instructions
4604 (define_expand "recip<mode>3"
4605   [(match_operand:RECIPF 0 "gpc_reg_operand")
4606    (match_operand:RECIPF 1 "gpc_reg_operand")
4607    (match_operand:RECIPF 2 "gpc_reg_operand")]
4608   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4610    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4611    DONE;
4614 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4615 ;; hardware division.  This is only done before register allocation and with
4616 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4617 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4618 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4619 (define_split
4620   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4621         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4622                     (match_operand 2 "gpc_reg_operand")))]
4623   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4624    && can_create_pseudo_p () && flag_finite_math_only
4625    && !flag_trapping_math && flag_reciprocal_math"
4626   [(const_int 0)]
4628   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4629   DONE;
4632 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4633 ;; appropriate fixup.
4634 (define_expand "rsqrt<mode>2"
4635   [(match_operand:RECIPF 0 "gpc_reg_operand")
4636    (match_operand:RECIPF 1 "gpc_reg_operand")]
4637   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4639   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4640   DONE;
4643 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4644 ;; modes here, and also add in conditional vsx/power8-vector support to access
4645 ;; values in the traditional Altivec registers if the appropriate
4646 ;; -mupper-regs-{df,sf} option is enabled.
4648 (define_expand "abs<mode>2"
4649   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4650         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4651   "TARGET_HARD_FLOAT"
4652   "")
4654 (define_insn "*abs<mode>2_fpr"
4655   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4656         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4657   "TARGET_HARD_FLOAT"
4658   "@
4659    fabs %0,%1
4660    xsabsdp %x0,%x1"
4661   [(set_attr "type" "fpsimple")])
4663 (define_insn "*nabs<mode>2_fpr"
4664   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4665         (neg:SFDF
4666          (abs:SFDF
4667           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4668   "TARGET_HARD_FLOAT"
4669   "@
4670    fnabs %0,%1
4671    xsnabsdp %x0,%x1"
4672   [(set_attr "type" "fpsimple")])
4674 (define_expand "neg<mode>2"
4675   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4676         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4677   "TARGET_HARD_FLOAT"
4678   "")
4680 (define_insn "*neg<mode>2_fpr"
4681   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4682         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4683   "TARGET_HARD_FLOAT"
4684   "@
4685    fneg %0,%1
4686    xsnegdp %x0,%x1"
4687   [(set_attr "type" "fpsimple")])
4689 (define_expand "add<mode>3"
4690   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4691         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4692                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4693   "TARGET_HARD_FLOAT"
4694   "")
4696 (define_insn "*add<mode>3_fpr"
4697   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4698         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4699                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4700   "TARGET_HARD_FLOAT"
4701   "@
4702    fadd<s> %0,%1,%2
4703    xsadd<sd>p %x0,%x1,%x2"
4704   [(set_attr "type" "fp")
4705    (set_attr "isa" "*,<Fisa>")])
4707 (define_expand "sub<mode>3"
4708   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4709         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4710                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4711   "TARGET_HARD_FLOAT"
4712   "")
4714 (define_insn "*sub<mode>3_fpr"
4715   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4716         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4717                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4718   "TARGET_HARD_FLOAT"
4719   "@
4720    fsub<s> %0,%1,%2
4721    xssub<sd>p %x0,%x1,%x2"
4722   [(set_attr "type" "fp")
4723    (set_attr "isa" "*,<Fisa>")])
4725 (define_expand "mul<mode>3"
4726   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4727         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4728                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4729   "TARGET_HARD_FLOAT"
4730   "")
4732 (define_insn "*mul<mode>3_fpr"
4733   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4734         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4735                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4736   "TARGET_HARD_FLOAT"
4737   "@
4738    fmul<s> %0,%1,%2
4739    xsmul<sd>p %x0,%x1,%x2"
4740   [(set_attr "type" "dmul")
4741    (set_attr "isa" "*,<Fisa>")])
4743 (define_expand "div<mode>3"
4744   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4745         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4746                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4747   "TARGET_HARD_FLOAT"
4749   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4750       && can_create_pseudo_p () && flag_finite_math_only
4751       && !flag_trapping_math && flag_reciprocal_math)
4752     {
4753       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4754       DONE;
4755     }
4758 (define_insn "*div<mode>3_fpr"
4759   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4760         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4761                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4762   "TARGET_HARD_FLOAT"
4763   "@
4764    fdiv<s> %0,%1,%2
4765    xsdiv<sd>p %x0,%x1,%x2"
4766   [(set_attr "type" "<sd>div")
4767    (set_attr "isa" "*,<Fisa>")])
4769 (define_insn "*sqrt<mode>2_internal"
4770   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4771         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4772   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4773   "@
4774    fsqrt<s> %0,%1
4775    xssqrt<sd>p %x0,%x1"
4776   [(set_attr "type" "<sd>sqrt")
4777    (set_attr "isa" "*,<Fisa>")])
4779 (define_expand "sqrt<mode>2"
4780   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4781         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4782   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4784   if (<MODE>mode == SFmode
4785       && TARGET_RECIP_PRECISION
4786       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4787       && !optimize_function_for_size_p (cfun)
4788       && flag_finite_math_only && !flag_trapping_math
4789       && flag_unsafe_math_optimizations)
4790     {
4791       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4792       DONE;
4793     }
4796 ;; Floating point reciprocal approximation
4797 (define_insn "fre<sd>"
4798   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4799         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4800                      UNSPEC_FRES))]
4801   "TARGET_<FFRE>"
4802   "@
4803    fre<s> %0,%1
4804    xsre<sd>p %x0,%x1"
4805   [(set_attr "type" "fp")
4806    (set_attr "isa" "*,<Fisa>")])
4808 (define_insn "*rsqrt<mode>2"
4809   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4810         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4811                      UNSPEC_RSQRT))]
4812   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4813   "@
4814    frsqrte<s> %0,%1
4815    xsrsqrte<sd>p %x0,%x1"
4816   [(set_attr "type" "fp")
4817    (set_attr "isa" "*,<Fisa>")])
4819 ;; Floating point comparisons
4820 (define_insn "*cmp<mode>_fpr"
4821   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4822         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4823                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4824   "TARGET_HARD_FLOAT"
4825   "@
4826    fcmpu %0,%1,%2
4827    xscmpudp %0,%x1,%x2"
4828   [(set_attr "type" "fpcompare")
4829    (set_attr "isa" "*,<Fisa>")])
4831 ;; Floating point conversions
4832 (define_expand "extendsfdf2"
4833   [(set (match_operand:DF 0 "gpc_reg_operand")
4834         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4835   "TARGET_HARD_FLOAT"
4837   if (HONOR_SNANS (SFmode))
4838     operands[1] = force_reg (SFmode, operands[1]);
4841 (define_insn_and_split "*extendsfdf2_fpr"
4842   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4843         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4844   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4845   "@
4846    #
4847    fmr %0,%1
4848    lfs%U1%X1 %0,%1
4849    #
4850    xscpsgndp %x0,%x1,%x1
4851    lxsspx %x0,%y1
4852    lxssp %0,%1"
4853   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4854   [(const_int 0)]
4856   emit_note (NOTE_INSN_DELETED);
4857   DONE;
4859   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4860    (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4862 (define_insn "*extendsfdf2_snan"
4863   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4864         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4865   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4866   "@
4867    frsp %0,%1
4868    xsrsp %x0,%x1"
4869   [(set_attr "type" "fp")
4870    (set_attr "isa" "*,p8v")])
4872 (define_expand "truncdfsf2"
4873   [(set (match_operand:SF 0 "gpc_reg_operand")
4874         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4875   "TARGET_HARD_FLOAT"
4876   "")
4878 (define_insn "*truncdfsf2_fpr"
4879   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4880         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4881   "TARGET_HARD_FLOAT"
4882   "@
4883    frsp %0,%1
4884    xsrsp %x0,%x1"
4885   [(set_attr "type" "fp")
4886    (set_attr "isa" "*,p8v")])
4888 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4889 ;; builtins.c and optabs.c that are not correct for IBM long double
4890 ;; when little-endian.
4891 (define_expand "signbit<mode>2"
4892   [(set (match_dup 2)
4893         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4894    (set (match_dup 3)
4895         (subreg:DI (match_dup 2) 0))
4896    (set (match_dup 4)
4897         (match_dup 5))
4898    (set (match_operand:SI 0 "gpc_reg_operand")
4899         (match_dup 6))]
4900   "TARGET_HARD_FLOAT
4901    && (!FLOAT128_IEEE_P (<MODE>mode)
4902        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4904   if (FLOAT128_IEEE_P (<MODE>mode))
4905     {
4906       rtx dest = operands[0];
4907       rtx src = operands[1];
4908       rtx tmp = gen_reg_rtx (DImode);
4909       rtx dest_di = gen_lowpart (DImode, dest);
4911       emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4912       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4913       DONE;
4914     }
4915   operands[2] = gen_reg_rtx (DFmode);
4916   operands[3] = gen_reg_rtx (DImode);
4917   if (TARGET_POWERPC64)
4918     {
4919       operands[4] = gen_reg_rtx (DImode);
4920       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4921       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4922                                     WORDS_BIG_ENDIAN ? 4 : 0);
4923     }
4924   else
4925     {
4926       operands[4] = gen_reg_rtx (SImode);
4927       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4928                                     WORDS_BIG_ENDIAN ? 0 : 4);
4929       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4930     }
4933 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4934 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4935 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4936 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4938 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4939 ;; split allows the post reload phases to eliminate the move, and do the shift
4940 ;; directly with the register that contains the signbit.
4941 (define_insn_and_split "@signbit<mode>2_dm"
4942   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4943         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4944                    UNSPEC_SIGNBIT))]
4945   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4946   "@
4947    mfvsrd %0,%x1
4948    #"
4949   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4950   [(set (match_dup 0)
4951         (match_dup 2))]
4953   operands[2] = gen_highpart (DImode, operands[1]);
4955  [(set_attr "type" "mftgpr,*")])
4957 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4958 ;; register and then doing a direct move if the value comes from memory.  On
4959 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4960 (define_insn_and_split "*signbit<mode>2_dm_mem"
4961   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4962         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4963                    UNSPEC_SIGNBIT))]
4964   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4965   "#"
4966   "&& 1"
4967   [(set (match_dup 0)
4968         (match_dup 2))]
4970   rtx dest = operands[0];
4971   rtx src = operands[1];
4972   rtx addr = XEXP (src, 0);
4974   if (WORDS_BIG_ENDIAN)
4975     operands[2] = adjust_address (src, DImode, 0);
4977   else if (REG_P (addr) || SUBREG_P (addr))
4978     operands[2] = adjust_address (src, DImode, 8);
4980   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4981            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4982     operands[2] = adjust_address (src, DImode, 8);
4984   else
4985     {
4986       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4987       emit_insn (gen_rtx_SET (tmp, addr));
4988       operands[2] = change_address (src, DImode,
4989                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4990     }
4993 (define_expand "copysign<mode>3"
4994   [(set (match_dup 3)
4995         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4996    (set (match_dup 4)
4997         (neg:SFDF (abs:SFDF (match_dup 1))))
4998    (set (match_operand:SFDF 0 "gpc_reg_operand")
4999         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5000                                (match_dup 5))
5001                          (match_dup 3)
5002                          (match_dup 4)))]
5003   "TARGET_HARD_FLOAT
5004    && ((TARGET_PPC_GFXOPT
5005         && !HONOR_NANS (<MODE>mode)
5006         && !HONOR_SIGNED_ZEROS (<MODE>mode))
5007        || TARGET_CMPB
5008        || VECTOR_UNIT_VSX_P (<MODE>mode))"
5010   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5011     {
5012       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5013                                              operands[2]));
5014       DONE;
5015     }
5017    operands[3] = gen_reg_rtx (<MODE>mode);
5018    operands[4] = gen_reg_rtx (<MODE>mode);
5019    operands[5] = CONST0_RTX (<MODE>mode);
5020   })
5022 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5023 ;; compiler from optimizing -0.0
5024 (define_insn "copysign<mode>3_fcpsgn"
5025   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5026         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5027                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5028                      UNSPEC_COPYSIGN))]
5029   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5030   "@
5031    fcpsgn %0,%2,%1
5032    xscpsgndp %x0,%x2,%x1"
5033   [(set_attr "type" "fpsimple")])
5035 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5036 ;; fsel instruction and some auxiliary computations.  Then we just have a
5037 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5038 ;; combine.
5039 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5040 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5041 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
5042 ;; define_splits to make them if made by combine.  On VSX machines we have the
5043 ;; min/max instructions.
5045 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5046 ;; to allow either DF/SF to use only traditional registers.
5048 (define_expand "s<minmax><mode>3"
5049   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5050         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5051                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5052   "TARGET_MINMAX"
5054   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5055   DONE;
5058 (define_insn "*s<minmax><mode>3_vsx"
5059   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5060         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5061                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5062   "TARGET_VSX && TARGET_HARD_FLOAT"
5064   return (TARGET_P9_MINMAX
5065           ? "xs<minmax>cdp %x0,%x1,%x2"
5066           : "xs<minmax>dp %x0,%x1,%x2");
5068   [(set_attr "type" "fp")])
5070 ;; The conditional move instructions allow us to perform max and min operations
5071 ;; even when we don't have the appropriate max/min instruction using the FSEL
5072 ;; instruction.
5074 (define_insn_and_split "*s<minmax><mode>3_fpr"
5075   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5076         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5077                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5078   "!TARGET_VSX && TARGET_MINMAX"
5079   "#"
5080   "&& 1"
5081   [(const_int 0)]
5083   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5084   DONE;
5087 (define_expand "mov<mode>cc"
5088    [(set (match_operand:GPR 0 "gpc_reg_operand")
5089          (if_then_else:GPR (match_operand 1 "comparison_operator")
5090                            (match_operand:GPR 2 "gpc_reg_operand")
5091                            (match_operand:GPR 3 "gpc_reg_operand")))]
5092   "TARGET_ISEL"
5094   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5095     DONE;
5096   else
5097     FAIL;
5100 ;; We use the BASE_REGS for the isel input operands because, if rA is
5101 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5102 ;; because we may switch the operands and rB may end up being rA.
5104 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
5105 ;; leave out the mode in operand 4 and use one pattern, but reload can
5106 ;; change the mode underneath our feet and then gets confused trying
5107 ;; to reload the value.
5108 (define_mode_iterator CCEITHER [CC CCUNS])
5109 (define_mode_attr un [(CC "") (CCUNS "un")])
5110 (define_insn "isel_<un>signed_<GPR:mode>"
5111   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5112         (if_then_else:GPR
5113          (match_operator 1 "scc_comparison_operator"
5114                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5115                           (const_int 0)])
5116          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5117          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5118   "TARGET_ISEL"
5119   "isel %0,%2,%3,%j1"
5120   [(set_attr "type" "isel")])
5122 ;; These patterns can be useful for combine; they let combine know that
5123 ;; isel can handle reversed comparisons so long as the operands are
5124 ;; registers.
5126 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5127   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5128         (if_then_else:GPR
5129          (match_operator 1 "scc_rev_comparison_operator"
5130                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5131                           (const_int 0)])
5132          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5133          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5134   "TARGET_ISEL"
5136   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5137   return "isel %0,%3,%2,%j1";
5139   [(set_attr "type" "isel")])
5141 ;; Floating point conditional move
5142 (define_expand "mov<mode>cc"
5143    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5144          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5145                             (match_operand:SFDF 2 "gpc_reg_operand")
5146                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5147   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5149   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5150     DONE;
5151   else
5152     FAIL;
5155 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5156   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5157         (if_then_else:SFDF
5158          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5159              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5160          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5161          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5162   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5163   "fsel %0,%1,%2,%3"
5164   [(set_attr "type" "fp")])
5166 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5167   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5168         (if_then_else:SFDF
5169          (match_operator:CCFP 1 "fpmask_comparison_operator"
5170                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5171                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5172          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5173          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5174    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5175   "TARGET_P9_MINMAX"
5176   "#"
5177   ""
5178   [(set (match_dup 6)
5179         (if_then_else:V2DI (match_dup 1)
5180                            (match_dup 7)
5181                            (match_dup 8)))
5182    (set (match_dup 0)
5183         (if_then_else:SFDF (ne (match_dup 6)
5184                                (match_dup 8))
5185                            (match_dup 4)
5186                            (match_dup 5)))]
5188   if (GET_CODE (operands[6]) == SCRATCH)
5189     operands[6] = gen_reg_rtx (V2DImode);
5191   operands[7] = CONSTM1_RTX (V2DImode);
5192   operands[8] = CONST0_RTX (V2DImode);
5194  [(set_attr "length" "8")
5195   (set_attr "type" "vecperm")])
5197 ;; Handle inverting the fpmask comparisons.
5198 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5199   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5200         (if_then_else:SFDF
5201          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5202                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5203                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5204          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5205          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5206    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5207   "TARGET_P9_MINMAX"
5208   "#"
5209   "&& 1"
5210   [(set (match_dup 6)
5211         (if_then_else:V2DI (match_dup 9)
5212                            (match_dup 7)
5213                            (match_dup 8)))
5214    (set (match_dup 0)
5215         (if_then_else:SFDF (ne (match_dup 6)
5216                                (match_dup 8))
5217                            (match_dup 5)
5218                            (match_dup 4)))]
5220   rtx op1 = operands[1];
5221   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5223   if (GET_CODE (operands[6]) == SCRATCH)
5224     operands[6] = gen_reg_rtx (V2DImode);
5226   operands[7] = CONSTM1_RTX (V2DImode);
5227   operands[8] = CONST0_RTX (V2DImode);
5229   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5231  [(set_attr "length" "8")
5232   (set_attr "type" "vecperm")])
5234 (define_insn "*fpmask<mode>"
5235   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5236         (if_then_else:V2DI
5237          (match_operator:CCFP 1 "fpmask_comparison_operator"
5238                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5239                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5240          (match_operand:V2DI 4 "all_ones_constant" "")
5241          (match_operand:V2DI 5 "zero_constant" "")))]
5242   "TARGET_P9_MINMAX"
5243   "xscmp%V1dp %x0,%x2,%x3"
5244   [(set_attr "type" "fpcompare")])
5246 (define_insn "*xxsel<mode>"
5247   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5248         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5249                                (match_operand:V2DI 2 "zero_constant" ""))
5250                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5251                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5252   "TARGET_P9_MINMAX"
5253   "xxsel %x0,%x4,%x3,%x1"
5254   [(set_attr "type" "vecmove")])
5257 ;; Conversions to and from floating-point.
5259 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5260 ; don't want to support putting SImode in FPR registers.
5261 (define_insn "lfiwax"
5262   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5263         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5264                    UNSPEC_LFIWAX))]
5265   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5266   "@
5267    lfiwax %0,%y1
5268    lxsiwax %x0,%y1
5269    mtvsrwa %x0,%1
5270    vextsw2d %0,%1"
5271   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5272    (set_attr "isa" "*,p8v,p8v,p9v")])
5274 ; This split must be run before register allocation because it allocates the
5275 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5276 ; it earlier to allow for the combiner to merge insns together where it might
5277 ; not be needed and also in case the insns are deleted as dead code.
5279 (define_insn_and_split "floatsi<mode>2_lfiwax"
5280   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5281         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5282    (clobber (match_scratch:DI 2 "=d,wa"))]
5283   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5284    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5285   "#"
5286   ""
5287   [(pc)]
5289   rtx dest = operands[0];
5290   rtx src = operands[1];
5291   rtx tmp;
5293   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5294     tmp = convert_to_mode (DImode, src, false);
5295   else
5296     {
5297       tmp = operands[2];
5298       if (GET_CODE (tmp) == SCRATCH)
5299         tmp = gen_reg_rtx (DImode);
5300       if (MEM_P (src))
5301         {
5302           src = rs6000_force_indexed_or_indirect_mem (src);
5303           emit_insn (gen_lfiwax (tmp, src));
5304         }
5305       else
5306         {
5307           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5308           emit_move_insn (stack, src);
5309           emit_insn (gen_lfiwax (tmp, stack));
5310         }
5311     }
5312   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5313   DONE;
5315   [(set_attr "length" "12")
5316    (set_attr "type" "fpload")])
5318 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5319   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5320         (float:SFDF
5321          (sign_extend:DI
5322           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5323    (clobber (match_scratch:DI 2 "=d,wa"))]
5324   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5325   "#"
5326   ""
5327   [(pc)]
5329   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5330   if (GET_CODE (operands[2]) == SCRATCH)
5331     operands[2] = gen_reg_rtx (DImode);
5332   if (TARGET_P8_VECTOR)
5333     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5334   else
5335     emit_insn (gen_lfiwax (operands[2], operands[1]));
5336   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5337   DONE;
5339   [(set_attr "length" "8")
5340    (set_attr "type" "fpload")])
5342 (define_insn "lfiwzx"
5343   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5344         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5345                    UNSPEC_LFIWZX))]
5346   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5347   "@
5348    lfiwzx %0,%y1
5349    lxsiwzx %x0,%y1
5350    mtvsrwz %x0,%1
5351    xxextractuw %x0,%x1,4"
5352   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5353    (set_attr "isa" "*,p8v,p8v,p9v")])
5355 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5356   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5357         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5358    (clobber (match_scratch:DI 2 "=d,wa"))]
5359   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5360   "#"
5361   ""
5362   [(pc)]
5364   rtx dest = operands[0];
5365   rtx src = operands[1];
5366   rtx tmp;
5368   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5369     tmp = convert_to_mode (DImode, src, true);
5370   else
5371     {
5372       tmp = operands[2];
5373       if (GET_CODE (tmp) == SCRATCH)
5374         tmp = gen_reg_rtx (DImode);
5375       if (MEM_P (src))
5376         {
5377           src = rs6000_force_indexed_or_indirect_mem (src);
5378           emit_insn (gen_lfiwzx (tmp, src));
5379         }
5380       else
5381         {
5382           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5383           emit_move_insn (stack, src);
5384           emit_insn (gen_lfiwzx (tmp, stack));
5385         }
5386     }
5387   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5388   DONE;
5390   [(set_attr "length" "12")
5391    (set_attr "type" "fpload")])
5393 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5394   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5395         (unsigned_float:SFDF
5396          (zero_extend:DI
5397           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5398    (clobber (match_scratch:DI 2 "=d,wa"))]
5399   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5400   "#"
5401   ""
5402   [(pc)]
5404   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5405   if (GET_CODE (operands[2]) == SCRATCH)
5406     operands[2] = gen_reg_rtx (DImode);
5407   if (TARGET_P8_VECTOR)
5408     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5409   else
5410     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5411   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5412   DONE;
5414   [(set_attr "length" "8")
5415    (set_attr "type" "fpload")])
5417 ; For each of these conversions, there is a define_expand, a define_insn
5418 ; with a '#' template, and a define_split (with C code).  The idea is
5419 ; to allow constant folding with the template of the define_insn,
5420 ; then to have the insns split later (between sched1 and final).
5422 (define_expand "floatsidf2"
5423   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5424                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5425               (use (match_dup 2))
5426               (use (match_dup 3))
5427               (clobber (match_dup 4))
5428               (clobber (match_dup 5))
5429               (clobber (match_dup 6))])]
5430   "TARGET_HARD_FLOAT"
5432   if (TARGET_LFIWAX && TARGET_FCFID)
5433     {
5434       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5435       DONE;
5436     }
5437   else if (TARGET_FCFID)
5438     {
5439       rtx dreg = operands[1];
5440       if (!REG_P (dreg))
5441         dreg = force_reg (SImode, dreg);
5442       dreg = convert_to_mode (DImode, dreg, false);
5443       emit_insn (gen_floatdidf2 (operands[0], dreg));
5444       DONE;
5445     }
5447   if (!REG_P (operands[1]))
5448     operands[1] = force_reg (SImode, operands[1]);
5449   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5450   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5451   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5452   operands[5] = gen_reg_rtx (DFmode);
5453   operands[6] = gen_reg_rtx (SImode);
5456 (define_insn_and_split "*floatsidf2_internal"
5457   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5458         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5459    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5460    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5461    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5462    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5463    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5464   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5465   "#"
5466   ""
5467   [(pc)]
5469   rtx lowword, highword;
5470   gcc_assert (MEM_P (operands[4]));
5471   highword = adjust_address (operands[4], SImode, 0);
5472   lowword = adjust_address (operands[4], SImode, 4);
5473   if (! WORDS_BIG_ENDIAN)
5474     std::swap (lowword, highword);
5476   emit_insn (gen_xorsi3 (operands[6], operands[1],
5477                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5478   emit_move_insn (lowword, operands[6]);
5479   emit_move_insn (highword, operands[2]);
5480   emit_move_insn (operands[5], operands[4]);
5481   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5482   DONE;
5484   [(set_attr "length" "24")
5485    (set_attr "type" "fp")])
5487 ;; If we don't have a direct conversion to single precision, don't enable this
5488 ;; conversion for 32-bit without fast math, because we don't have the insn to
5489 ;; generate the fixup swizzle to avoid double rounding problems.
5490 (define_expand "floatunssisf2"
5491   [(set (match_operand:SF 0 "gpc_reg_operand")
5492         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5493   "TARGET_HARD_FLOAT
5494    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5495        || (TARGET_FCFID
5496            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5498   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5499     {
5500       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5501       DONE;
5502     }
5503   else
5504     {
5505       rtx dreg = operands[1];
5506       if (!REG_P (dreg))
5507         dreg = force_reg (SImode, dreg);
5508       dreg = convert_to_mode (DImode, dreg, true);
5509       emit_insn (gen_floatdisf2 (operands[0], dreg));
5510       DONE;
5511     }
5514 (define_expand "floatunssidf2"
5515   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5516                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5517               (use (match_dup 2))
5518               (use (match_dup 3))
5519               (clobber (match_dup 4))
5520               (clobber (match_dup 5))])]
5521   "TARGET_HARD_FLOAT"
5523   if (TARGET_LFIWZX && TARGET_FCFID)
5524     {
5525       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5526       DONE;
5527     }
5528   else if (TARGET_FCFID)
5529     {
5530       rtx dreg = operands[1];
5531       if (!REG_P (dreg))
5532         dreg = force_reg (SImode, dreg);
5533       dreg = convert_to_mode (DImode, dreg, true);
5534       emit_insn (gen_floatdidf2 (operands[0], dreg));
5535       DONE;
5536     }
5538   if (!REG_P (operands[1]))
5539     operands[1] = force_reg (SImode, operands[1]);
5540   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5541   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5542   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5543   operands[5] = gen_reg_rtx (DFmode);
5546 (define_insn_and_split "*floatunssidf2_internal"
5547   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5548         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5549    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5550    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5551    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5552    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5553   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5554    && !(TARGET_FCFID && TARGET_POWERPC64)"
5555   "#"
5556   ""
5557   [(pc)]
5559   rtx lowword, highword;
5560   gcc_assert (MEM_P (operands[4]));
5561   highword = adjust_address (operands[4], SImode, 0);
5562   lowword = adjust_address (operands[4], SImode, 4);
5563   if (! WORDS_BIG_ENDIAN)
5564     std::swap (lowword, highword);
5566   emit_move_insn (lowword, operands[1]);
5567   emit_move_insn (highword, operands[2]);
5568   emit_move_insn (operands[5], operands[4]);
5569   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5570   DONE;
5572   [(set_attr "length" "20")
5573    (set_attr "type" "fp")])
5575 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5576 ;; vector registers.  These insns favor doing the sign/zero extension in
5577 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5578 ;; extension and then a direct move.
5580 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5581   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5582                    (float:FP_ISA3
5583                     (match_operand:QHI 1 "input_operand")))
5584               (clobber (match_scratch:DI 2))
5585               (clobber (match_scratch:DI 3))
5586               (clobber (match_scratch:<QHI:MODE> 4))])]
5587   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5589   if (MEM_P (operands[1]))
5590     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5593 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5594   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5595         (float:FP_ISA3
5596          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5597    (clobber (match_scratch:DI 2 "=v,wa,v"))
5598    (clobber (match_scratch:DI 3 "=X,r,X"))
5599    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5600   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5601   "#"
5602   "&& reload_completed"
5603   [(const_int 0)]
5605   rtx result = operands[0];
5606   rtx input = operands[1];
5607   rtx di = operands[2];
5609   if (!MEM_P (input))
5610     {
5611       rtx tmp = operands[3];
5612       if (altivec_register_operand (input, <QHI:MODE>mode))
5613         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5614       else if (GET_CODE (tmp) == SCRATCH)
5615         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5616       else
5617         {
5618           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5619           emit_move_insn (di, tmp);
5620         }
5621     }
5622   else
5623     {
5624       rtx tmp = operands[4];
5625       emit_move_insn (tmp, input);
5626       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5627     }
5629   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5630   DONE;
5632   [(set_attr "isa" "p9v,*,p9v")])
5634 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5635   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5636                    (unsigned_float:FP_ISA3
5637                     (match_operand:QHI 1 "input_operand")))
5638               (clobber (match_scratch:DI 2))
5639               (clobber (match_scratch:DI 3))])]
5640   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5642   if (MEM_P (operands[1]))
5643     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5646 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5647   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5648         (unsigned_float:FP_ISA3
5649          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5650    (clobber (match_scratch:DI 2 "=v,wa,wa"))
5651    (clobber (match_scratch:DI 3 "=X,r,X"))]
5652   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5653   "#"
5654   "&& reload_completed"
5655   [(const_int 0)]
5657   rtx result = operands[0];
5658   rtx input = operands[1];
5659   rtx di = operands[2];
5661   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5662     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5663   else
5664     {
5665       rtx tmp = operands[3];
5666       if (GET_CODE (tmp) == SCRATCH)
5667         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5668       else
5669         {
5670           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5671           emit_move_insn (di, tmp);
5672         }
5673     }
5675   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5676   DONE;
5678   [(set_attr "isa" "p9v,*,p9v")])
5680 (define_expand "fix_trunc<mode>si2"
5681   [(set (match_operand:SI 0 "gpc_reg_operand")
5682         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5683   "TARGET_HARD_FLOAT"
5685   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5686     {
5687       rtx src = force_reg (<MODE>mode, operands[1]);
5689       if (TARGET_STFIWX)
5690         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5691       else
5692         {
5693           rtx tmp = gen_reg_rtx (DImode);
5694           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5695           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5696                                                       tmp, stack));
5697         }
5698       DONE;
5699     }
5702 ; Like the convert to float patterns, this insn must be split before
5703 ; register allocation so that it can allocate the memory slot if it
5704 ; needed
5705 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5706   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5707         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5708    (clobber (match_scratch:DI 2 "=d"))]
5709   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5710    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5711   "#"
5712   ""
5713   [(pc)]
5715   rtx dest = operands[0];
5716   rtx src = operands[1];
5717   rtx tmp = operands[2];
5719   if (GET_CODE (tmp) == SCRATCH)
5720     tmp = gen_reg_rtx (DImode);
5722   emit_insn (gen_fctiwz_<mode> (tmp, src));
5723   if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5724     {
5725       dest = rs6000_force_indexed_or_indirect_mem (dest);
5726       emit_insn (gen_stfiwx (dest, tmp));
5727       DONE;
5728     }
5729   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5730     {
5731       dest = gen_lowpart (DImode, dest);
5732       emit_move_insn (dest, tmp);
5733       DONE;
5734     }
5735   else
5736     {
5737       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5738       emit_insn (gen_stfiwx (stack, tmp));
5739       emit_move_insn (dest, stack);
5740       DONE;
5741     }
5743   [(set_attr "length" "12")
5744    (set_attr "type" "fp")])
5746 (define_insn_and_split "fix_trunc<mode>si2_internal"
5747   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5748         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5749    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5750    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5751   "TARGET_HARD_FLOAT
5752    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5753   "#"
5754   ""
5755   [(pc)]
5757   rtx lowword;
5758   gcc_assert (MEM_P (operands[3]));
5759   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5761   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5762   emit_move_insn (operands[3], operands[2]);
5763   emit_move_insn (operands[0], lowword);
5764   DONE;
5766   [(set_attr "length" "16")
5767    (set_attr "type" "fp")])
5769 (define_expand "fix_trunc<mode>di2"
5770   [(set (match_operand:DI 0 "gpc_reg_operand")
5771         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5772   "TARGET_HARD_FLOAT && TARGET_FCFID"
5773   "")
5775 (define_insn "*fix_trunc<mode>di2_fctidz"
5776   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5777         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5778   "TARGET_HARD_FLOAT && TARGET_FCFID"
5779   "@
5780    fctidz %0,%1
5781    xscvdpsxds %x0,%x1"
5782   [(set_attr "type" "fp")])
5784 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5785 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5786 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5787 ;; values can go in VSX registers.  Keeping the direct move part through
5788 ;; register allocation prevents the register allocator from doing a direct move
5789 ;; of the SImode value to a GPR, and then a store/load.
5790 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5791   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5792         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5793    (clobber (match_scratch:SI 2 "=X,X,wa"))]
5794   "TARGET_DIRECT_MOVE"
5795   "@
5796    fctiw<u>z %0,%1
5797    xscvdp<su>xws %x0,%x1
5798    #"
5799   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5800   [(set (match_dup 2)
5801         (any_fix:SI (match_dup 1)))
5802    (set (match_dup 3)
5803         (match_dup 2))]
5805   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5807   [(set_attr "type" "fp")
5808    (set_attr "length" "4,4,8")
5809    (set_attr "isa" "p9v,p9v,*")])
5811 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5812   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5813         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5814   "TARGET_DIRECT_MOVE"
5815   "@
5816    fctiw<u>z %0,%1
5817    xscvdp<su>xws %x0,%x1"
5818   [(set_attr "type" "fp")])
5820 ;; Keep the convert and store together through register allocation to prevent
5821 ;; the register allocator from getting clever and doing a direct move to a GPR
5822 ;; and then store for reg+offset stores.
5823 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5824   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5825         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5826    (clobber (match_scratch:SI 2 "=wa"))]
5827     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5828   "#"
5829   "&& reload_completed"
5830   [(set (match_dup 2)
5831         (any_fix:SI (match_dup 1)))
5832    (set (match_dup 0)
5833         (match_dup 3))]
5835   operands[3] = (<QHSI:MODE>mode == SImode
5836                  ? operands[2]
5837                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5840 (define_expand "fixuns_trunc<mode>si2"
5841   [(set (match_operand:SI 0 "gpc_reg_operand")
5842         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5843   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5845   if (!TARGET_P8_VECTOR)
5846     {
5847       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5848       DONE;
5849     }
5852 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5853   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5854         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5855    (clobber (match_scratch:DI 2 "=d"))]
5856   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5857    && TARGET_STFIWX && can_create_pseudo_p ()
5858    && !TARGET_P8_VECTOR"
5859   "#"
5860   ""
5861   [(pc)]
5863   rtx dest = operands[0];
5864   rtx src = operands[1];
5865   rtx tmp = operands[2];
5867   if (GET_CODE (tmp) == SCRATCH)
5868     tmp = gen_reg_rtx (DImode);
5870   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5871   if (MEM_P (dest))
5872     {
5873       dest = rs6000_force_indexed_or_indirect_mem (dest);
5874       emit_insn (gen_stfiwx (dest, tmp));
5875       DONE;
5876     }
5877   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5878     {
5879       dest = gen_lowpart (DImode, dest);
5880       emit_move_insn (dest, tmp);
5881       DONE;
5882     }
5883   else
5884     {
5885       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5886       emit_insn (gen_stfiwx (stack, tmp));
5887       emit_move_insn (dest, stack);
5888       DONE;
5889     }
5891   [(set_attr "length" "12")
5892    (set_attr "type" "fp")])
5894 (define_insn "fixuns_trunc<mode>di2"
5895   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5896         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5897   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5898   "@
5899    fctiduz %0,%1
5900    xscvdpuxds %x0,%x1"
5901   [(set_attr "type" "fp")])
5903 (define_insn "rs6000_mtfsb0"
5904   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5905                     UNSPECV_MTFSB0)]
5906   "TARGET_HARD_FLOAT"
5907   "mtfsb0 %0"
5908   [(set_attr "type" "fp")])
5910 (define_insn "rs6000_mtfsb1"
5911   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5912                     UNSPECV_MTFSB1)]
5913   "TARGET_HARD_FLOAT"
5914   "mtfsb1 %0"
5915   [(set_attr "type" "fp")])
5917 (define_insn "rs6000_mffscrn"
5918   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5919         (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5920                             UNSPECV_MFFSCRN))]
5921    "TARGET_P9_MISC"
5922    "mffscrn %0,%1"
5923   [(set_attr "type" "fp")])
5925 (define_insn "rs6000_mffscdrn"
5926   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5927    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5928    (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5929   "TARGET_P9_MISC"
5930   "mffscdrn %0,%1"
5931   [(set_attr "type" "fp")])
5933 (define_expand "rs6000_set_fpscr_rn"
5934  [(match_operand:DI 0 "reg_or_cint_operand")]
5935   "TARGET_HARD_FLOAT"
5937   rtx tmp_df = gen_reg_rtx (DFmode);
5939   /* The floating point rounding control bits are FPSCR[62:63]. Put the
5940      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5941   if (TARGET_P9_MISC)
5942     {
5943       rtx src_df = force_reg (DImode, operands[0]);
5944       src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5945       emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5946       DONE;
5947     }
5949   if (CONST_INT_P (operands[0]))
5950     {
5951       if ((INTVAL (operands[0]) & 0x1) == 0x1)
5952         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5953       else
5954         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5956       if ((INTVAL (operands[0]) & 0x2) == 0x2)
5957         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5958       else
5959         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5960     }
5961   else
5962     {
5963       rtx tmp_rn = gen_reg_rtx (DImode);
5964       rtx tmp_di = gen_reg_rtx (DImode);
5966       /* Extract new RN mode from operand.  */
5967       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5969       /* Insert new RN mode into FSCPR.  */
5970       emit_insn (gen_rs6000_mffs (tmp_df));
5971       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5972       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5973       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5975       /* Need to write to field k=15.  The fields are [0:15].  Hence with
5976          L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5977          8-bit field[0:7]. Need to set the bit that corresponds to the
5978          value of i that you want [0:7].  */
5979       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5980       emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5981     }
5982   DONE;
5985 (define_expand "rs6000_set_fpscr_drn"
5986   [(match_operand:DI 0  "gpc_reg_operand")]
5987   "TARGET_HARD_FLOAT"
5989   rtx tmp_df = gen_reg_rtx (DFmode);
5991   /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5992      new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5993   if (TARGET_P9_MISC)
5994     {
5995       rtx src_df = gen_reg_rtx (DFmode);
5997       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5998       src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5999       emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6000     }
6001   else
6002     {
6003       rtx tmp_rn = gen_reg_rtx (DImode);
6004       rtx tmp_di = gen_reg_rtx (DImode);
6006       /* Extract new DRN mode from operand.  */
6007       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6008       emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6010       /* Insert new RN mode into FSCPR.  */
6011       emit_insn (gen_rs6000_mffs (tmp_df));
6012       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6013       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6014       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6016       /* Need to write to field 7.  The fields are [0:15].  The equation to
6017          select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6018          i to 0x1 to get field 7 where i selects the field.  */
6019       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6020       emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6021     }
6022   DONE;
6025 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6026 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6027 ;; because the first makes it clear that operand 0 is not live
6028 ;; before the instruction.
6029 (define_insn "fctiwz_<mode>"
6030   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6031         (unspec:DI [(fix:SI
6032                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6033                    UNSPEC_FCTIWZ))]
6034   "TARGET_HARD_FLOAT"
6035   "@
6036    fctiwz %0,%1
6037    xscvdpsxws %x0,%x1"
6038   [(set_attr "type" "fp")])
6040 (define_insn "fctiwuz_<mode>"
6041   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6042         (unspec:DI [(unsigned_fix:SI
6043                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6044                    UNSPEC_FCTIWUZ))]
6045   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6046   "@
6047    fctiwuz %0,%1
6048    xscvdpuxws %x0,%x1"
6049   [(set_attr "type" "fp")])
6051 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6052 ;; since the friz instruction does not truncate the value if the floating
6053 ;; point value is < LONG_MIN or > LONG_MAX.
6054 (define_insn "*friz"
6055   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6056         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6057   "TARGET_HARD_FLOAT && TARGET_FPRND
6058    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6059   "@
6060    friz %0,%1
6061    xsrdpiz %x0,%x1"
6062   [(set_attr "type" "fp")])
6064 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
6065 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6066 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6067 ;; extend it, store it back on the stack from the GPR, load it back into the
6068 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6069 ;; disable using store and load to sign/zero extend the value.
6070 (define_insn_and_split "*round32<mode>2_fprs"
6071   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6072         (float:SFDF
6073          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6074    (clobber (match_scratch:DI 2 "=d"))
6075    (clobber (match_scratch:DI 3 "=d"))]
6076   "TARGET_HARD_FLOAT
6077    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6078    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6079   "#"
6080   ""
6081   [(pc)]
6083   rtx dest = operands[0];
6084   rtx src = operands[1];
6085   rtx tmp1 = operands[2];
6086   rtx tmp2 = operands[3];
6087   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6089   if (GET_CODE (tmp1) == SCRATCH)
6090     tmp1 = gen_reg_rtx (DImode);
6091   if (GET_CODE (tmp2) == SCRATCH)
6092     tmp2 = gen_reg_rtx (DImode);
6094   emit_insn (gen_fctiwz_<mode> (tmp1, src));
6095   emit_insn (gen_stfiwx (stack, tmp1));
6096   emit_insn (gen_lfiwax (tmp2, stack));
6097   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6098   DONE;
6100   [(set_attr "type" "fpload")
6101    (set_attr "length" "16")])
6103 (define_insn_and_split "*roundu32<mode>2_fprs"
6104   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6105         (unsigned_float:SFDF
6106          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6107    (clobber (match_scratch:DI 2 "=d"))
6108    (clobber (match_scratch:DI 3 "=d"))]
6109   "TARGET_HARD_FLOAT
6110    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6111    && can_create_pseudo_p ()"
6112   "#"
6113   ""
6114   [(pc)]
6116   rtx dest = operands[0];
6117   rtx src = operands[1];
6118   rtx tmp1 = operands[2];
6119   rtx tmp2 = operands[3];
6120   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6122   if (GET_CODE (tmp1) == SCRATCH)
6123     tmp1 = gen_reg_rtx (DImode);
6124   if (GET_CODE (tmp2) == SCRATCH)
6125     tmp2 = gen_reg_rtx (DImode);
6127   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6128   emit_insn (gen_stfiwx (stack, tmp1));
6129   emit_insn (gen_lfiwzx (tmp2, stack));
6130   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6131   DONE;
6133   [(set_attr "type" "fpload")
6134    (set_attr "length" "16")])
6136 ;; No VSX equivalent to fctid
6137 (define_insn "lrint<mode>di2"
6138   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6139         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6140                    UNSPEC_FCTID))]
6141   "TARGET_HARD_FLOAT && TARGET_FPRND"
6142   "fctid %0,%1"
6143   [(set_attr "type" "fp")])
6145 (define_insn "btrunc<mode>2"
6146   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6147         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6148                      UNSPEC_FRIZ))]
6149   "TARGET_HARD_FLOAT && TARGET_FPRND"
6150   "@
6151    friz %0,%1
6152    xsrdpiz %x0,%x1"
6153   [(set_attr "type" "fp")])
6155 (define_insn "ceil<mode>2"
6156   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6157         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6158                      UNSPEC_FRIP))]
6159   "TARGET_HARD_FLOAT && TARGET_FPRND"
6160   "@
6161    frip %0,%1
6162    xsrdpip %x0,%x1"
6163   [(set_attr "type" "fp")])
6165 (define_insn "floor<mode>2"
6166   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6167         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6168                      UNSPEC_FRIM))]
6169   "TARGET_HARD_FLOAT && TARGET_FPRND"
6170   "@
6171    frim %0,%1
6172    xsrdpim %x0,%x1"
6173   [(set_attr "type" "fp")])
6175 ;; No VSX equivalent to frin
6176 (define_insn "round<mode>2"
6177   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6178         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6179                      UNSPEC_FRIN))]
6180   "TARGET_HARD_FLOAT && TARGET_FPRND"
6181   "frin %0,%1"
6182   [(set_attr "type" "fp")])
6184 (define_insn "*xsrdpi<mode>2"
6185   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6186         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6187                      UNSPEC_XSRDPI))]
6188   "TARGET_HARD_FLOAT && TARGET_VSX"
6189   "xsrdpi %x0,%x1"
6190   [(set_attr "type" "fp")])
6192 (define_expand "lround<mode>di2"
6193   [(set (match_dup 2)
6194         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6195                      UNSPEC_XSRDPI))
6196    (set (match_operand:DI 0 "gpc_reg_operand")
6197         (unspec:DI [(match_dup 2)]
6198                    UNSPEC_FCTID))]
6199   "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6201   operands[2] = gen_reg_rtx (<MODE>mode);
6204 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6205 (define_insn "stfiwx"
6206   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6207         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6208                    UNSPEC_STFIWX))]
6209   "TARGET_PPC_GFXOPT"
6210   "@
6211    stfiwx %1,%y0
6212    stxsiwx %x1,%y0"
6213   [(set_attr "type" "fpstore")
6214    (set_attr "isa" "*,p8v")])
6216 ;; If we don't have a direct conversion to single precision, don't enable this
6217 ;; conversion for 32-bit without fast math, because we don't have the insn to
6218 ;; generate the fixup swizzle to avoid double rounding problems.
6219 (define_expand "floatsisf2"
6220   [(set (match_operand:SF 0 "gpc_reg_operand")
6221         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6222   "TARGET_HARD_FLOAT
6223    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6224        || (TARGET_FCFID
6225            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6227   if (TARGET_FCFIDS && TARGET_LFIWAX)
6228     {
6229       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6230       DONE;
6231     }
6232   else if (TARGET_FCFID && TARGET_LFIWAX)
6233     {
6234       rtx dfreg = gen_reg_rtx (DFmode);
6235       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6236       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6237       DONE;
6238     }
6239   else
6240     {
6241       rtx dreg = operands[1];
6242       if (!REG_P (dreg))
6243         dreg = force_reg (SImode, dreg);
6244       dreg = convert_to_mode (DImode, dreg, false);
6245       emit_insn (gen_floatdisf2 (operands[0], dreg));
6246       DONE;
6247     }
6250 (define_insn "floatdidf2"
6251   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6252         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6253   "TARGET_FCFID && TARGET_HARD_FLOAT"
6254   "@
6255    fcfid %0,%1
6256    xscvsxddp %x0,%x1"
6257   [(set_attr "type" "fp")])
6259 ; Allow the combiner to merge source memory operands to the conversion so that
6260 ; the optimizer/register allocator doesn't try to load the value too early in a
6261 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6262 ; hit.  We will split after reload to avoid the trip through the GPRs
6264 (define_insn_and_split "*floatdidf2_mem"
6265   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6266         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6267    (clobber (match_scratch:DI 2 "=d,wa"))]
6268   "TARGET_HARD_FLOAT && TARGET_FCFID"
6269   "#"
6270   "&& reload_completed"
6271   [(set (match_dup 2) (match_dup 1))
6272    (set (match_dup 0) (float:DF (match_dup 2)))]
6273   ""
6274   [(set_attr "length" "8")
6275    (set_attr "type" "fpload")])
6277 (define_expand "floatunsdidf2"
6278   [(set (match_operand:DF 0 "gpc_reg_operand")
6279         (unsigned_float:DF
6280          (match_operand:DI 1 "gpc_reg_operand")))]
6281   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6282   "")
6284 (define_insn "*floatunsdidf2_fcfidu"
6285   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6286         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6287   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6288   "@
6289    fcfidu %0,%1
6290    xscvuxddp %x0,%x1"
6291   [(set_attr "type" "fp")])
6293 (define_insn_and_split "*floatunsdidf2_mem"
6294   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6295         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6296    (clobber (match_scratch:DI 2 "=d,wa"))]
6297   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6298   "#"
6299   "&& reload_completed"
6300   [(set (match_dup 2) (match_dup 1))
6301    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6302   ""
6303   [(set_attr "length" "8")
6304    (set_attr "type" "fpload")])
6306 (define_expand "floatdisf2"
6307   [(set (match_operand:SF 0 "gpc_reg_operand")
6308         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6309   "TARGET_FCFID && TARGET_HARD_FLOAT
6310    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6312   if (!TARGET_FCFIDS)
6313     {
6314       rtx val = operands[1];
6315       if (!flag_unsafe_math_optimizations)
6316         {
6317           rtx label = gen_label_rtx ();
6318           val = gen_reg_rtx (DImode);
6319           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6320           emit_label (label);
6321         }
6322       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6323       DONE;
6324     }
6327 (define_insn "floatdisf2_fcfids"
6328   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6329         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6330   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6331   "@
6332    fcfids %0,%1
6333    xscvsxdsp %x0,%x1"
6334   [(set_attr "type" "fp")
6335    (set_attr "isa" "*,p8v")])
6337 (define_insn_and_split "*floatdisf2_mem"
6338   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6339         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6340    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6341   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6342   "#"
6343   "&& reload_completed"
6344   [(pc)]
6346   emit_move_insn (operands[2], operands[1]);
6347   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6348   DONE;
6350   [(set_attr "length" "8")
6351    (set_attr "isa" "*,p8v,p8v")])
6353 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6354 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6355 ;; from double rounding.
6356 ;; Instead of creating a new cpu type for two FP operations, just use fp
6357 (define_insn_and_split "floatdisf2_internal1"
6358   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6359         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6360    (clobber (match_scratch:DF 2 "=d"))]
6361   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6362   "#"
6363   "&& reload_completed"
6364   [(set (match_dup 2)
6365         (float:DF (match_dup 1)))
6366    (set (match_dup 0)
6367         (float_truncate:SF (match_dup 2)))]
6368   ""
6369   [(set_attr "length" "8")
6370    (set_attr "type" "fp")])
6372 ;; Twiddles bits to avoid double rounding.
6373 ;; Bits that might be truncated when converting to DFmode are replaced
6374 ;; by a bit that won't be lost at that stage, but is below the SFmode
6375 ;; rounding position.
6376 (define_expand "floatdisf2_internal2"
6377   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6378                                               (const_int 53)))
6379               (clobber (reg:DI CA_REGNO))])
6380    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6381                                         (const_int 2047)))
6382    (set (match_dup 3) (plus:DI (match_dup 3)
6383                                (const_int 1)))
6384    (set (match_dup 0) (plus:DI (match_dup 0)
6385                                (const_int 2047)))
6386    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6387                                      (const_int 2)))
6388    (set (match_dup 0) (ior:DI (match_dup 0)
6389                               (match_dup 1)))
6390    (set (match_dup 0) (and:DI (match_dup 0)
6391                               (const_int -2048)))
6392    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6393                            (label_ref (match_operand:DI 2 ""))
6394                            (pc)))
6395    (set (match_dup 0) (match_dup 1))]
6396   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6398   operands[3] = gen_reg_rtx (DImode);
6399   operands[4] = gen_reg_rtx (CCUNSmode);
6402 (define_expand "floatunsdisf2"
6403   [(set (match_operand:SF 0 "gpc_reg_operand")
6404         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6405   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6406   "")
6408 (define_insn "floatunsdisf2_fcfidus"
6409   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6410         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6411   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6412   "@
6413    fcfidus %0,%1
6414    xscvuxdsp %x0,%x1"
6415   [(set_attr "type" "fp")
6416    (set_attr "isa" "*,p8v")])
6418 (define_insn_and_split "*floatunsdisf2_mem"
6419   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6420         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6421    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6422   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6423   "#"
6424   "&& reload_completed"
6425   [(pc)]
6427   emit_move_insn (operands[2], operands[1]);
6428   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6429   DONE;
6431   [(set_attr "type" "fpload")
6432    (set_attr "length" "8")
6433    (set_attr "isa" "*,p8v,p8v")])
6435 ;; Define the TImode operations that can be done in a small number
6436 ;; of instructions.  The & constraints are to prevent the register
6437 ;; allocator from allocating registers that overlap with the inputs
6438 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6439 ;; also allow for the output being the same as one of the inputs.
6441 (define_expand "addti3"
6442   [(set (match_operand:TI 0 "gpc_reg_operand")
6443         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6444                  (match_operand:TI 2 "reg_or_short_operand")))]
6445   "TARGET_64BIT"
6447   rtx lo0 = gen_lowpart (DImode, operands[0]);
6448   rtx lo1 = gen_lowpart (DImode, operands[1]);
6449   rtx lo2 = gen_lowpart (DImode, operands[2]);
6450   rtx hi0 = gen_highpart (DImode, operands[0]);
6451   rtx hi1 = gen_highpart (DImode, operands[1]);
6452   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6454   if (!reg_or_short_operand (lo2, DImode))
6455     lo2 = force_reg (DImode, lo2);
6456   if (!adde_operand (hi2, DImode))
6457     hi2 = force_reg (DImode, hi2);
6459   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6460   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6461   DONE;
6464 (define_expand "subti3"
6465   [(set (match_operand:TI 0 "gpc_reg_operand")
6466         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6467                   (match_operand:TI 2 "gpc_reg_operand")))]
6468   "TARGET_64BIT"
6470   rtx lo0 = gen_lowpart (DImode, operands[0]);
6471   rtx lo1 = gen_lowpart (DImode, operands[1]);
6472   rtx lo2 = gen_lowpart (DImode, operands[2]);
6473   rtx hi0 = gen_highpart (DImode, operands[0]);
6474   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6475   rtx hi2 = gen_highpart (DImode, operands[2]);
6477   if (!reg_or_short_operand (lo1, DImode))
6478     lo1 = force_reg (DImode, lo1);
6479   if (!adde_operand (hi1, DImode))
6480     hi1 = force_reg (DImode, hi1);
6482   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6483   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6484   DONE;
6487 ;; 128-bit logical operations expanders
6489 (define_expand "and<mode>3"
6490   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6491         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6492                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6493   ""
6494   "")
6496 (define_expand "ior<mode>3"
6497   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6498         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6499                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6500   ""
6501   "")
6503 (define_expand "xor<mode>3"
6504   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6505         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6506                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6507   ""
6508   "")
6510 (define_expand "nor<mode>3"
6511   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6512         (and:BOOL_128
6513          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6514          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6515   ""
6516   "")
6518 (define_expand "andc<mode>3"
6519   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6520         (and:BOOL_128
6521          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6522          (match_operand:BOOL_128 1 "vlogical_operand")))]
6523   ""
6524   "")
6526 ;; Power8 vector logical instructions.
6527 (define_expand "eqv<mode>3"
6528   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6529         (not:BOOL_128
6530          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6531                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6532   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6533   "")
6535 ;; Rewrite nand into canonical form
6536 (define_expand "nand<mode>3"
6537   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6538         (ior:BOOL_128
6539          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6540          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6541   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6542   "")
6544 ;; The canonical form is to have the negated element first, so we need to
6545 ;; reverse arguments.
6546 (define_expand "orc<mode>3"
6547   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6548         (ior:BOOL_128
6549          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6550          (match_operand:BOOL_128 1 "vlogical_operand")))]
6551   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6552   "")
6554 ;; 128-bit logical operations insns and split operations
6555 (define_insn_and_split "*and<mode>3_internal"
6556   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6557         (and:BOOL_128
6558          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6559          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6560   ""
6562   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6563     return "xxland %x0,%x1,%x2";
6565   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6566     return "vand %0,%1,%2";
6568   return "#";
6570   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6571   [(const_int 0)]
6573   rs6000_split_logical (operands, AND, false, false, false);
6574   DONE;
6576   [(set (attr "type")
6577       (if_then_else
6578         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6579         (const_string "veclogical")
6580         (const_string "integer")))
6581    (set (attr "length")
6582       (if_then_else
6583         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6584         (const_string "4")
6585         (if_then_else
6586          (match_test "TARGET_POWERPC64")
6587          (const_string "8")
6588          (const_string "16"))))])
6590 ;; 128-bit IOR/XOR
6591 (define_insn_and_split "*bool<mode>3_internal"
6592   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6593         (match_operator:BOOL_128 3 "boolean_or_operator"
6594          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6595           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6596   ""
6598   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6599     return "xxl%q3 %x0,%x1,%x2";
6601   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6602     return "v%q3 %0,%1,%2";
6604   return "#";
6606   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6607   [(const_int 0)]
6609   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6610   DONE;
6612   [(set (attr "type")
6613       (if_then_else
6614         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6615         (const_string "veclogical")
6616         (const_string "integer")))
6617    (set (attr "length")
6618       (if_then_else
6619         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6620         (const_string "4")
6621         (if_then_else
6622          (match_test "TARGET_POWERPC64")
6623          (const_string "8")
6624          (const_string "16"))))])
6626 ;; 128-bit ANDC/ORC
6627 (define_insn_and_split "*boolc<mode>3_internal1"
6628   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6629         (match_operator:BOOL_128 3 "boolean_operator"
6630          [(not:BOOL_128
6631            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6632           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6633   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6635   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6636     return "xxl%q3 %x0,%x1,%x2";
6638   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6639     return "v%q3 %0,%1,%2";
6641   return "#";
6643   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6644    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6645   [(const_int 0)]
6647   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6648   DONE;
6650   [(set (attr "type")
6651       (if_then_else
6652         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6653         (const_string "veclogical")
6654         (const_string "integer")))
6655    (set (attr "length")
6656       (if_then_else
6657         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6658         (const_string "4")
6659         (if_then_else
6660          (match_test "TARGET_POWERPC64")
6661          (const_string "8")
6662          (const_string "16"))))])
6664 (define_insn_and_split "*boolc<mode>3_internal2"
6665   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6666         (match_operator:TI2 3 "boolean_operator"
6667          [(not:TI2
6668            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6669           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6670   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6671   "#"
6672   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6673   [(const_int 0)]
6675   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6676   DONE;
6678   [(set_attr "type" "integer")
6679    (set (attr "length")
6680         (if_then_else
6681          (match_test "TARGET_POWERPC64")
6682          (const_string "8")
6683          (const_string "16")))])
6685 ;; 128-bit NAND/NOR
6686 (define_insn_and_split "*boolcc<mode>3_internal1"
6687   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6688         (match_operator:BOOL_128 3 "boolean_operator"
6689          [(not:BOOL_128
6690            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6691           (not:BOOL_128
6692            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6693   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6695   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6696     return "xxl%q3 %x0,%x1,%x2";
6698   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6699     return "v%q3 %0,%1,%2";
6701   return "#";
6703   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6704    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6705   [(const_int 0)]
6707   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6708   DONE;
6710   [(set (attr "type")
6711       (if_then_else
6712         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6713         (const_string "veclogical")
6714         (const_string "integer")))
6715    (set (attr "length")
6716       (if_then_else
6717         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6718         (const_string "4")
6719         (if_then_else
6720          (match_test "TARGET_POWERPC64")
6721          (const_string "8")
6722          (const_string "16"))))])
6724 (define_insn_and_split "*boolcc<mode>3_internal2"
6725   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6726         (match_operator:TI2 3 "boolean_operator"
6727          [(not:TI2
6728            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6729           (not:TI2
6730            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6731   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6732   "#"
6733   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6734   [(const_int 0)]
6736   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6737   DONE;
6739   [(set_attr "type" "integer")
6740    (set (attr "length")
6741         (if_then_else
6742          (match_test "TARGET_POWERPC64")
6743          (const_string "8")
6744          (const_string "16")))])
6747 ;; 128-bit EQV
6748 (define_insn_and_split "*eqv<mode>3_internal1"
6749   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6750         (not:BOOL_128
6751          (xor:BOOL_128
6752           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6753           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6754   "TARGET_P8_VECTOR"
6756   if (vsx_register_operand (operands[0], <MODE>mode))
6757     return "xxleqv %x0,%x1,%x2";
6759   return "#";
6761   "TARGET_P8_VECTOR && reload_completed
6762    && int_reg_operand (operands[0], <MODE>mode)"
6763   [(const_int 0)]
6765   rs6000_split_logical (operands, XOR, true, false, false);
6766   DONE;
6768   [(set (attr "type")
6769       (if_then_else
6770         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6771         (const_string "veclogical")
6772         (const_string "integer")))
6773    (set (attr "length")
6774       (if_then_else
6775         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6776         (const_string "4")
6777         (if_then_else
6778          (match_test "TARGET_POWERPC64")
6779          (const_string "8")
6780          (const_string "16"))))])
6782 (define_insn_and_split "*eqv<mode>3_internal2"
6783   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6784         (not:TI2
6785          (xor:TI2
6786           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6787           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6788   "!TARGET_P8_VECTOR"
6789   "#"
6790   "reload_completed && !TARGET_P8_VECTOR"
6791   [(const_int 0)]
6793   rs6000_split_logical (operands, XOR, true, false, false);
6794   DONE;
6796   [(set_attr "type" "integer")
6797    (set (attr "length")
6798         (if_then_else
6799          (match_test "TARGET_POWERPC64")
6800          (const_string "8")
6801          (const_string "16")))])
6803 ;; 128-bit one's complement
6804 (define_insn_and_split "one_cmpl<mode>2"
6805   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6806         (not:BOOL_128
6807           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6808   ""
6810   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6811     return "xxlnor %x0,%x1,%x1";
6813   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6814     return "vnor %0,%1,%1";
6816   return "#";
6818   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6819   [(const_int 0)]
6821   rs6000_split_logical (operands, NOT, false, false, false);
6822   DONE;
6824   [(set (attr "type")
6825       (if_then_else
6826         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6827         (const_string "veclogical")
6828         (const_string "integer")))
6829    (set (attr "length")
6830       (if_then_else
6831         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6832         (const_string "4")
6833         (if_then_else
6834          (match_test "TARGET_POWERPC64")
6835          (const_string "8")
6836          (const_string "16"))))])
6839 ;; Now define ways of moving data around.
6841 ;; Set up a register with a value from the GOT table
6843 (define_expand "movsi_got"
6844   [(set (match_operand:SI 0 "gpc_reg_operand")
6845         (unspec:SI [(match_operand:SI 1 "got_operand")
6846                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6847   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6849   if (GET_CODE (operands[1]) == CONST)
6850     {
6851       rtx offset = const0_rtx;
6852       HOST_WIDE_INT value;
6854       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6855       value = INTVAL (offset);
6856       if (value != 0)
6857         {
6858           rtx tmp = (!can_create_pseudo_p ()
6859                      ? operands[0]
6860                      : gen_reg_rtx (Pmode));
6861           emit_insn (gen_movsi_got (tmp, operands[1]));
6862           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6863           DONE;
6864         }
6865     }
6867   operands[2] = rs6000_got_register (operands[1]);
6870 (define_insn "*movsi_got_internal"
6871   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6872         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6873                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6874                    UNSPEC_MOVSI_GOT))]
6875   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6876   "lwz %0,%a1@got(%2)"
6877   [(set_attr "type" "load")])
6879 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6880 ;; didn't get allocated to a hard register.
6881 (define_split
6882   [(set (match_operand:SI 0 "gpc_reg_operand")
6883         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6884                     (match_operand:SI 2 "memory_operand")]
6885                    UNSPEC_MOVSI_GOT))]
6886   "DEFAULT_ABI == ABI_V4
6887     && flag_pic == 1
6888     && reload_completed"
6889   [(set (match_dup 0) (match_dup 2))
6890    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6891                                  UNSPEC_MOVSI_GOT))]
6892   "")
6894 ;;         MR          LA
6895 ;;         LWZ         LFIWZX      LXSIWZX
6896 ;;         STW         STFIWX      STXSIWX
6897 ;;         LI          LIS         PLI         #
6898 ;;         XXLOR       XXSPLTIB 0  XXSPLTIB -1 VSPLTISW
6899 ;;         XXLXOR 0    XXLORC -1   P9 const
6900 ;;         MTVSRWZ     MFVSRWZ
6901 ;;         MF%1        MT%0        NOP
6903 (define_insn "*movsi_internal1"
6904   [(set (match_operand:SI 0 "nonimmediate_operand"
6905           "=r,         r,
6906            r,          d,          v,
6907            m,          Z,          Z,
6908            r,          r,          r,          r,
6909            wa,         wa,         wa,         v,
6910            wa,         v,          v,
6911            wa,         r,
6912            r,          *h,         *h")
6913         (match_operand:SI 1 "input_operand"
6914           "r,          U,
6915            m,          Z,          Z,
6916            r,          d,          v,
6917            I,          L,          eI,         n,
6918            wa,         O,          wM,         wB,
6919            O,          wM,         wS,
6920            r,          wa,
6921            *h,         r,          0"))]
6922   "gpc_reg_operand (operands[0], SImode)
6923    || gpc_reg_operand (operands[1], SImode)"
6924   "@
6925    mr %0,%1
6926    la %0,%a1
6927    lwz%U1%X1 %0,%1
6928    lfiwzx %0,%y1
6929    lxsiwzx %x0,%y1
6930    stw%U0%X0 %1,%0
6931    stfiwx %1,%y0
6932    stxsiwx %x1,%y0
6933    li %0,%1
6934    lis %0,%v1
6935    li %0,%1
6936    #
6937    xxlor %x0,%x1,%x1
6938    xxspltib %x0,0
6939    xxspltib %x0,255
6940    vspltisw %0,%1
6941    xxlxor %x0,%x0,%x0
6942    xxlorc %x0,%x0,%x0
6943    #
6944    mtvsrwz %x0,%1
6945    mfvsrwz %0,%x1
6946    mf%1 %0
6947    mt%0 %1
6948    nop"
6949   [(set_attr "type"
6950           "*,          *,
6951            load,       fpload,     fpload,
6952            store,      fpstore,    fpstore,
6953            *,          *,          *,          *,
6954            veclogical, vecsimple,  vecsimple,  vecsimple,
6955            veclogical, veclogical, vecsimple,
6956            mffgpr,     mftgpr,
6957            *,          *,          *")
6958    (set_attr "length"
6959           "*,          *,
6960            *,          *,          *,
6961            *,          *,          *,
6962            *,          *,          *,          8,
6963            *,          *,          *,          *,
6964            *,          *,          8,
6965            *,          *,
6966            *,          *,          *")
6967    (set_attr "isa"
6968           "*,          *,
6969            *,          p8v,        p8v,
6970            *,          p8v,        p8v,
6971            *,          *,          fut,        *,
6972            p8v,        p9v,        p9v,        p8v,
6973            p9v,        p8v,        p9v,
6974            p8v,        p8v,
6975            *,          *,          *")])
6977 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6978 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6980 ;; Because SF values are actually stored as DF values within the vector
6981 ;; registers, we need to convert the value to the vector SF format when
6982 ;; we need to use the bits in a union or similar cases.  We only need
6983 ;; to do this transformation when the value is a vector register.  Loads,
6984 ;; stores, and transfers within GPRs are assumed to be safe.
6986 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6987 ;; no alternatives, because the call is created as part of secondary_reload,
6988 ;; and operand #2's register class is used to allocate the temporary register.
6989 ;; This function is called before reload, and it creates the temporary as
6990 ;; needed.
6992 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6993 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6994 ;;              MTVSRWZ
6996 (define_insn_and_split "movsi_from_sf"
6997   [(set (match_operand:SI 0 "nonimmediate_operand"
6998                 "=r,         r,           ?*d,         ?*v,      m,
6999                  m,          wY,          Z,           r,        ?*wa,
7000                  wa")
7001         (unspec:SI [(match_operand:SF 1 "input_operand"
7002                 "r,          m,           Z,           Z,        r,
7003                  f,          v,           wa,          wa,       wa,
7004                  r")]
7005                     UNSPEC_SI_FROM_SF))
7006    (clobber (match_scratch:V4SF 2
7007                 "=X,         X,           X,           X,        X,
7008                  X,          X,           X,           wa,       X,
7009                  X"))]
7010   "TARGET_NO_SF_SUBREG
7011    && (register_operand (operands[0], SImode)
7012        || register_operand (operands[1], SFmode))"
7013   "@
7014    mr %0,%1
7015    lwz%U1%X1 %0,%1
7016    lfiwzx %0,%y1
7017    lxsiwzx %x0,%y1
7018    stw%U0%X0 %1,%0
7019    stfs%U0%X0 %1,%0
7020    stxssp %1,%0
7021    stxsspx %x1,%y0
7022    #
7023    xscvdpspn %x0,%x1
7024    mtvsrwz %x0,%1"
7025   "&& reload_completed
7026    && int_reg_operand (operands[0], SImode)
7027    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7028   [(const_int 0)]
7030   rtx op0 = operands[0];
7031   rtx op1 = operands[1];
7032   rtx op2 = operands[2];
7033   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7034   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7036   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7037   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7038   DONE;
7040   [(set_attr "type"
7041                 "*,          load,        fpload,      fpload,   store,
7042                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
7043                  mffgpr")
7044    (set_attr "length"
7045                 "*,          *,           *,           *,        *,
7046                  *,          *,           *,           8,        *,
7047                  *")
7048    (set_attr "isa"
7049                 "*,          *,           p8v,         p8v,      *,
7050                  *,          p9v,         p8v,         p8v,      p8v,
7051                  p8v")])
7053 ;; movsi_from_sf with zero extension
7055 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
7056 ;;              VSX->VSX     MTVSRWZ
7058 (define_insn_and_split "*movdi_from_sf_zero_ext"
7059   [(set (match_operand:DI 0 "gpc_reg_operand"
7060                 "=r,         r,           ?*d,         ?*v,      r,
7061                  ?v,         wa")
7062         (zero_extend:DI
7063          (unspec:SI [(match_operand:SF 1 "input_operand"
7064                 "r,          m,           Z,           Z,        wa,
7065                  wa,         r")]
7066                     UNSPEC_SI_FROM_SF)))
7067    (clobber (match_scratch:V4SF 2
7068                 "=X,         X,           X,           X,        wa,
7069                  wa,         X"))]
7070   "TARGET_DIRECT_MOVE_64BIT
7071    && (register_operand (operands[0], DImode)
7072        || register_operand (operands[1], SImode))"
7073   "@
7074    rldicl %0,%1,0,32
7075    lwz%U1%X1 %0,%1
7076    lfiwzx %0,%y1
7077    lxsiwzx %x0,%y1
7078    #
7079    #
7080    mtvsrwz %x0,%1"
7081   "&& reload_completed
7082    && register_operand (operands[0], DImode)
7083    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7084   [(const_int 0)]
7086   rtx op0 = operands[0];
7087   rtx op1 = operands[1];
7088   rtx op2 = operands[2];
7089   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7091   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7092   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7093   DONE;
7095   [(set_attr "type"
7096                 "*,          load,        fpload,      fpload,   two,
7097                  two,        mffgpr")
7098    (set_attr "length"
7099                 "*,          *,           *,           *,        8,
7100                  8,          *")
7101    (set_attr "isa"
7102                 "*,          *,           p8v,         p8v,      p8v,
7103                  p9v,        p8v")])
7105 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7106 ;; moving it to SImode.  We cannot do a SFmode store without having to do the
7107 ;; conversion explicitly since that doesn't work in most cases if the input
7108 ;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7109 ;; former handles cases where the input will not fit in a SFmode, and the
7110 ;; latter assumes the value has already been rounded.
7111 (define_insn "*movsi_from_df"
7112   [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7113         (unspec:SI [(float_truncate:SF
7114                      (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7115                     UNSPEC_SI_FROM_SF))]
7116   "TARGET_NO_SF_SUBREG"
7117   "xscvdpsp %x0,%x1"
7118   [(set_attr "type" "fp")])
7120 ;; Split a load of a large constant into the appropriate two-insn
7121 ;; sequence.
7123 (define_split
7124   [(set (match_operand:SI 0 "gpc_reg_operand")
7125         (match_operand:SI 1 "const_int_operand"))]
7126   "num_insns_constant (operands[1], SImode) > 1"
7127   [(set (match_dup 0)
7128         (match_dup 2))
7129    (set (match_dup 0)
7130         (ior:SI (match_dup 0)
7131                 (match_dup 3)))]
7133   if (rs6000_emit_set_const (operands[0], operands[1]))
7134     DONE;
7135   else
7136     FAIL;
7139 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7140 (define_split
7141   [(set (match_operand:DI 0 "altivec_register_operand")
7142         (match_operand:DI 1 "xxspltib_constant_split"))]
7143   "TARGET_P9_VECTOR && reload_completed"
7144   [(const_int 0)]
7146   rtx op0 = operands[0];
7147   rtx op1 = operands[1];
7148   int r = REGNO (op0);
7149   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7151   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7152   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7153   DONE;
7156 (define_insn "*mov<mode>_internal2"
7157   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7158         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7159                     (const_int 0)))
7160    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7161   ""
7162   "@
7163    cmp<wd>i %2,%0,0
7164    mr. %0,%1
7165    #"
7166   [(set_attr "type" "cmp,logical,cmp")
7167    (set_attr "dot" "yes")
7168    (set_attr "length" "4,4,8")])
7170 (define_split
7171   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7172         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7173                     (const_int 0)))
7174    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7175   "reload_completed"
7176   [(set (match_dup 0) (match_dup 1))
7177    (set (match_dup 2)
7178         (compare:CC (match_dup 0)
7179                     (const_int 0)))]
7180   "")
7182 (define_expand "mov<mode>"
7183   [(set (match_operand:INT 0 "general_operand")
7184         (match_operand:INT 1 "any_operand"))]
7185   ""
7187   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7188   DONE;
7191 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7192 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7193 ;;              MTVSRWZ     MF%1       MT%1       NOP
7194 (define_insn "*mov<mode>_internal"
7195   [(set (match_operand:QHI 0 "nonimmediate_operand"
7196                 "=r,        r,         wa,        m,         Z,         r,
7197                  wa,        wa,        wa,        v,         ?v,        r,
7198                  wa,        r,         *c*l,      *h")
7199         (match_operand:QHI 1 "input_operand"
7200                 "r,         m,         Z,         r,         wa,        i,
7201                  wa,        O,         wM,        wB,        wS,        wa,
7202                  r,         *h,        r,         0"))]
7203   "gpc_reg_operand (operands[0], <MODE>mode)
7204    || gpc_reg_operand (operands[1], <MODE>mode)"
7205   "@
7206    mr %0,%1
7207    l<wd>z%U1%X1 %0,%1
7208    lxsi<wd>zx %x0,%y1
7209    st<wd>%U0%X0 %1,%0
7210    stxsi<wd>x %x1,%y0
7211    li %0,%1
7212    xxlor %x0,%x1,%x1
7213    xxspltib %x0,0
7214    xxspltib %x0,255
7215    vspltis<wd> %0,%1
7216    #
7217    mfvsrwz %0,%x1
7218    mtvsrwz %x0,%1
7219    mf%1 %0
7220    mt%0 %1
7221    nop"
7222   [(set_attr "type"
7223                 "*,         load,      fpload,    store,     fpstore,   *,
7224                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7225                  mffgpr,    mfjmpr,    mtjmpr,    *")
7226    (set_attr "length"
7227                 "*,         *,         *,         *,         *,         *,
7228                  *,         *,         *,         *,         8,         *,
7229                  *,         *,         *,         *")
7230    (set_attr "isa"
7231                 "*,         *,         p9v,       *,         p9v,       *,
7232                  p9v,       p9v,       p9v,       p9v,       p9v,       p9v,
7233                  p9v,       *,         *,         *")])
7236 ;; Here is how to move condition codes around.  When we store CC data in
7237 ;; an integer register or memory, we store just the high-order 4 bits.
7238 ;; This lets us not shift in the most common case of CR0.
7239 (define_expand "movcc"
7240   [(set (match_operand:CC 0 "nonimmediate_operand")
7241         (match_operand:CC 1 "nonimmediate_operand"))]
7242   ""
7243   "")
7245 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7247 (define_insn "*movcc_<mode>"
7248   [(set (match_operand:CC_any 0 "nonimmediate_operand"
7249                                 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7250         (match_operand:CC_any 1 "general_operand"
7251                                 " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7252   "register_operand (operands[0], <MODE>mode)
7253    || register_operand (operands[1], <MODE>mode)"
7254   "@
7255    mcrf %0,%1
7256    mtcrf 128,%1
7257    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7258    crxor %0,%0,%0
7259    mfcr %0%Q1
7260    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7261    mr %0,%1
7262    li %0,%1
7263    mf%1 %0
7264    mt%0 %1
7265    lwz%U1%X1 %0,%1
7266    stw%U0%X0 %1,%0"
7267   [(set_attr_alternative "type"
7268      [(const_string "cr_logical")
7269       (const_string "mtcr")
7270       (const_string "mtcr")
7271       (const_string "cr_logical")
7272       (if_then_else (match_test "TARGET_MFCRF")
7273                     (const_string "mfcrf") (const_string "mfcr"))
7274       (if_then_else (match_test "TARGET_MFCRF")
7275                     (const_string "mfcrf") (const_string "mfcr"))
7276       (const_string "integer")
7277       (const_string "integer")
7278       (const_string "mfjmpr")
7279       (const_string "mtjmpr")
7280       (const_string "load")
7281       (const_string "store")])
7282    (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7284 ;; For floating-point, we normally deal with the floating-point registers
7285 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7286 ;; can produce floating-point values in fixed-point registers.  Unless the
7287 ;; value is a simple constant or already in memory, we deal with this by
7288 ;; allocating memory and copying the value explicitly via that memory location.
7290 ;; Move 32-bit binary/decimal floating point
7291 (define_expand "mov<mode>"
7292   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7293         (match_operand:FMOVE32 1 "any_operand"))]
7294   "<fmove_ok>"
7296   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7297   DONE;
7300 (define_split
7301   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7302         (match_operand:FMOVE32 1 "const_double_operand"))]
7303   "reload_completed
7304    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7305        || (SUBREG_P (operands[0])
7306            && REG_P (SUBREG_REG (operands[0]))
7307            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7308   [(set (match_dup 2) (match_dup 3))]
7310   long l;
7312   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7314   if (! TARGET_POWERPC64)
7315     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7316   else
7317     operands[2] = gen_lowpart (SImode, operands[0]);
7319   operands[3] = gen_int_mode (l, SImode);
7322 ;; Originally, we tried to keep movsf and movsd common, but the differences
7323 ;; addressing was making it rather difficult to hide with mode attributes.  In
7324 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7325 ;; before the VSX stores meant that the register allocator would tend to do a
7326 ;; direct move to the GPR (which involves conversion from scalar to
7327 ;; vector/memory formats) to save values in the traditional Altivec registers,
7328 ;; while SDmode had problems on power6 if the GPR store was not first due to
7329 ;; the power6 not having an integer store operation.
7331 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7332 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7333 ;;      MR           MT<x>      MF<x>       NOP
7335 (define_insn "movsf_hardfloat"
7336   [(set (match_operand:SF 0 "nonimmediate_operand"
7337          "=!r,       f,         v,          wa,        m,         wY,
7338           Z,         m,         wa,         !r,        f,         wa,
7339           !r,        *c*l,      !r,         *h")
7340         (match_operand:SF 1 "input_operand"
7341          "m,         m,         wY,         Z,         f,         v,
7342           wa,        r,         j,          j,         f,         wa,
7343           r,         r,         *h,         0"))]
7344   "(register_operand (operands[0], SFmode)
7345    || register_operand (operands[1], SFmode))
7346    && TARGET_HARD_FLOAT
7347    && (TARGET_ALLOW_SF_SUBREG
7348        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7349   "@
7350    lwz%U1%X1 %0,%1
7351    lfs%U1%X1 %0,%1
7352    lxssp %0,%1
7353    lxsspx %x0,%y1
7354    stfs%U0%X0 %1,%0
7355    stxssp %1,%0
7356    stxsspx %x1,%y0
7357    stw%U0%X0 %1,%0
7358    xxlxor %x0,%x0,%x0
7359    li %0,0
7360    fmr %0,%1
7361    xscpsgndp %x0,%x1,%x1
7362    mr %0,%1
7363    mt%0 %1
7364    mf%1 %0
7365    nop"
7366   [(set_attr "type"
7367         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7368          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7369          *,          mtjmpr,    mfjmpr,     *")
7370    (set_attr "isa"
7371         "*,          *,         p9v,        p8v,       *,         p9v,
7372          p8v,        *,         *,          *,         *,         *,
7373          *,          *,         *,          *")])
7375 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7376 ;;      FMR          MR         MT%0       MF%1       NOP
7377 (define_insn "movsd_hardfloat"
7378   [(set (match_operand:SD 0 "nonimmediate_operand"
7379          "=!r,       d,         m,         Z,         ?d,        ?r,
7380           f,         !r,        *c*l,      !r,        *h")
7381         (match_operand:SD 1 "input_operand"
7382          "m,         Z,         r,         wx,        r,         d,
7383           f,         r,         r,         *h,        0"))]
7384   "(register_operand (operands[0], SDmode)
7385    || register_operand (operands[1], SDmode))
7386    && TARGET_HARD_FLOAT"
7387   "@
7388    lwz%U1%X1 %0,%1
7389    lfiwzx %0,%y1
7390    stw%U0%X0 %1,%0
7391    stfiwx %1,%y0
7392    mtvsrwz %x0,%1
7393    mfvsrwz %0,%x1
7394    fmr %0,%1
7395    mr %0,%1
7396    mt%0 %1
7397    mf%1 %0
7398    nop"
7399   [(set_attr "type"
7400         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7401          fpsimple,   *,         mtjmpr,    mfjmpr,    *")
7402    (set_attr "isa"
7403         "*,          p7,        *,         *,         p8v,       p8v,
7404          *,          *,         *,         *,         *")])
7406 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7407 ;;      LIS          G-const.   F/n-const  NOP
7408 (define_insn "*mov<mode>_softfloat"
7409   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7410         "=r,         *c*l,      r,         r,         m,         r,
7411           r,         r,         r,         *h")
7413         (match_operand:FMOVE32 1 "input_operand"
7414          "r,         r,         *h,        m,         r,         I,
7415           L,         G,         Fn,        0"))]
7417   "(gpc_reg_operand (operands[0], <MODE>mode)
7418    || gpc_reg_operand (operands[1], <MODE>mode))
7419    && TARGET_SOFT_FLOAT"
7420   "@
7421    mr %0,%1
7422    mt%0 %1
7423    mf%1 %0
7424    lwz%U1%X1 %0,%1
7425    stw%U0%X0 %1,%0
7426    li %0,%1
7427    lis %0,%v1
7428    #
7429    #
7430    nop"
7431   [(set_attr "type"
7432         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7433          *,          *,         *,         *")
7435    (set_attr "length"
7436         "*,          *,         *,         *,         *,         *,
7437          *,          *,         8,         *")])
7439 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7440 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7442 ;; Because SF values are actually stored as DF values within the vector
7443 ;; registers, we need to convert the value to the vector SF format when
7444 ;; we need to use the bits in a union or similar cases.  We only need
7445 ;; to do this transformation when the value is a vector register.  Loads,
7446 ;; stores, and transfers within GPRs are assumed to be safe.
7448 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7449 ;; no alternatives, because the call is created as part of secondary_reload,
7450 ;; and operand #2's register class is used to allocate the temporary register.
7451 ;; This function is called before reload, and it creates the temporary as
7452 ;; needed.
7454 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7455 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7456 (define_insn_and_split "movsf_from_si"
7457   [(set (match_operand:SF 0 "nonimmediate_operand"
7458             "=!r,       f,         v,         wa,        m,         Z,
7459              Z,         wa,        ?r,        !r")
7460         (unspec:SF [(match_operand:SI 1 "input_operand" 
7461             "m,         m,         wY,        Z,         r,         f,
7462              wa,        r,         wa,        r")]
7463                    UNSPEC_SF_FROM_SI))
7464    (clobber (match_scratch:DI 2
7465             "=X,        X,         X,         X,         X,         X,
7466              X,         r,         X,         X"))]
7467   "TARGET_NO_SF_SUBREG
7468    && (register_operand (operands[0], SFmode)
7469        || register_operand (operands[1], SImode))"
7470   "@
7471    lwz%U1%X1 %0,%1
7472    lfs%U1%X1 %0,%1
7473    lxssp %0,%1
7474    lxsspx %x0,%y1
7475    stw%U0%X0 %1,%0
7476    stfiwx %1,%y0
7477    stxsiwx %x1,%y0
7478    #
7479    mfvsrwz %0,%x1
7480    mr %0,%1"
7482   "&& reload_completed
7483    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7484    && int_reg_operand_not_pseudo (operands[1], SImode)"
7485   [(const_int 0)]
7487   rtx op0 = operands[0];
7488   rtx op1 = operands[1];
7489   rtx op2 = operands[2];
7490   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7492   /* Move SF value to upper 32-bits for xscvspdpn.  */
7493   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7494   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7495   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7496   DONE;
7498   [(set_attr "length"
7499             "*,          *,         *,         *,         *,         *,
7500              *,          12,        *,         *")
7501    (set_attr "type"
7502             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7503              fpstore,    vecfloat,  mffgpr,    *")
7504    (set_attr "isa"
7505             "*,          *,         p9v,       p8v,       *,         *,
7506              p8v,        p8v,       p8v,       *")])
7509 ;; Move 64-bit binary/decimal floating point
7510 (define_expand "mov<mode>"
7511   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7512         (match_operand:FMOVE64 1 "any_operand"))]
7513   ""
7515   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7516   DONE;
7519 (define_split
7520   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7521         (match_operand:FMOVE64 1 "const_int_operand"))]
7522   "! TARGET_POWERPC64 && reload_completed
7523    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7524        || (SUBREG_P (operands[0])
7525            && REG_P (SUBREG_REG (operands[0]))
7526            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7527   [(set (match_dup 2) (match_dup 4))
7528    (set (match_dup 3) (match_dup 1))]
7530   int endian = (WORDS_BIG_ENDIAN == 0);
7531   HOST_WIDE_INT value = INTVAL (operands[1]);
7533   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7534   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7535   operands[4] = GEN_INT (value >> 32);
7536   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7539 (define_split
7540   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7541         (match_operand:FMOVE64 1 "const_double_operand"))]
7542   "! TARGET_POWERPC64 && reload_completed
7543    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7544        || (SUBREG_P (operands[0])
7545            && REG_P (SUBREG_REG (operands[0]))
7546            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7547   [(set (match_dup 2) (match_dup 4))
7548    (set (match_dup 3) (match_dup 5))]
7550   int endian = (WORDS_BIG_ENDIAN == 0);
7551   long l[2];
7553   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7555   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7556   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7557   operands[4] = gen_int_mode (l[endian], SImode);
7558   operands[5] = gen_int_mode (l[1 - endian], SImode);
7561 (define_split
7562   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7563         (match_operand:FMOVE64 1 "const_double_operand"))]
7564   "TARGET_POWERPC64 && reload_completed
7565    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7566        || (SUBREG_P (operands[0])
7567            && REG_P (SUBREG_REG (operands[0]))
7568            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7569   [(set (match_dup 2) (match_dup 3))]
7571   int endian = (WORDS_BIG_ENDIAN == 0);
7572   long l[2];
7573   HOST_WIDE_INT val;
7575   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7577   operands[2] = gen_lowpart (DImode, operands[0]);
7578   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7579   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7580          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7582   operands[3] = gen_int_mode (val, DImode);
7585 ;; Don't have reload use general registers to load a constant.  It is
7586 ;; less efficient than loading the constant into an FP register, since
7587 ;; it will probably be used there.
7589 ;; The move constraints are ordered to prefer floating point registers before
7590 ;; general purpose registers to avoid doing a store and a load to get the value
7591 ;; into a floating point register when it is needed for a floating point
7592 ;; operation.  Prefer traditional floating point registers over VSX registers,
7593 ;; since the D-form version of the memory instructions does not need a GPR for
7594 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7595 ;; registers.
7597 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7598 ;; except for 0.0 which can be created on VSX with an xor instruction.
7600 ;;           STFD         LFD         FMR         LXSD        STXSD
7601 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7602 ;;           LWZ          STW         MR
7605 (define_insn "*mov<mode>_hardfloat32"
7606   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7607             "=m,          d,          d,          <f64_p9>,   wY,
7608               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7609               Y,          r,          !r")
7610         (match_operand:FMOVE64 1 "input_operand"
7611              "d,          m,          d,          wY,         <f64_p9>,
7612               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7613               r,          Y,          r"))]
7614   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7615    && (gpc_reg_operand (operands[0], <MODE>mode)
7616        || gpc_reg_operand (operands[1], <MODE>mode))"
7617   "@
7618    stfd%U0%X0 %1,%0
7619    lfd%U1%X1 %0,%1
7620    fmr %0,%1
7621    lxsd %0,%1
7622    stxsd %1,%0
7623    lxsdx %x0,%y1
7624    stxsdx %x1,%y0
7625    xxlor %x0,%x1,%x1
7626    xxlxor %x0,%x0,%x0
7627    #
7628    #
7629    #
7630    #"
7631   [(set_attr "type"
7632             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7633              fpload,      fpstore,    veclogical, veclogical, two,
7634              store,       load,       two")
7635    (set_attr "size" "64")
7636    (set_attr "length"
7637             "*,           *,          *,          *,          *,
7638              *,           *,          *,          *,          8,
7639              8,           8,          8")
7640    (set_attr "isa"
7641             "*,           *,          *,          p9v,        p9v,
7642              p7v,         p7v,        *,          *,          *,
7643              *,           *,          *")])
7645 ;;           STW      LWZ     MR      G-const H-const F-const
7647 (define_insn "*mov<mode>_softfloat32"
7648   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7649            "=Y,       r,      r,      r,      r,      r")
7651         (match_operand:FMOVE64 1 "input_operand"
7652             "r,       Y,      r,      G,      H,      F"))]
7654   "!TARGET_POWERPC64
7655    && (gpc_reg_operand (operands[0], <MODE>mode)
7656        || gpc_reg_operand (operands[1], <MODE>mode))"
7657   "#"
7658   [(set_attr "type"
7659             "store,   load,   two,    *,      *,      *")
7661    (set_attr "length"
7662              "8,      8,      8,      8,      12,     16")])
7664 ; ld/std require word-aligned displacements -> 'Y' constraint.
7665 ; List Y->r and r->Y before r->r for reload.
7667 ;;           STFD         LFD         FMR         LXSD        STXSD
7668 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7669 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7670 ;;           NOP          MFVSRD      MTVSRD
7672 (define_insn "*mov<mode>_hardfloat64"
7673   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7674            "=m,           d,          d,          <f64_p9>,   wY,
7675              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7676              YZ,          r,          !r,         *c*l,       !r,
7677             *h,           r,          <f64_dm>")
7678         (match_operand:FMOVE64 1 "input_operand"
7679             "d,           m,          d,          wY,         <f64_p9>,
7680              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7681              r,           YZ,         r,          r,          *h,
7682              0,           <f64_dm>,   r"))]
7683   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7684    && (gpc_reg_operand (operands[0], <MODE>mode)
7685        || gpc_reg_operand (operands[1], <MODE>mode))"
7686   "@
7687    stfd%U0%X0 %1,%0
7688    lfd%U1%X1 %0,%1
7689    fmr %0,%1
7690    lxsd %0,%1
7691    stxsd %1,%0
7692    lxsdx %x0,%y1
7693    stxsdx %x1,%y0
7694    xxlor %x0,%x1,%x1
7695    xxlxor %x0,%x0,%x0
7696    li %0,0
7697    std%U0%X0 %1,%0
7698    ld%U1%X1 %0,%1
7699    mr %0,%1
7700    mt%0 %1
7701    mf%1 %0
7702    nop
7703    mfvsrd %0,%x1
7704    mtvsrd %x0,%1"
7705   [(set_attr "type"
7706             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7707              fpload,      fpstore,    veclogical, veclogical, integer,
7708              store,       load,       *,          mtjmpr,     mfjmpr,
7709              *,           mftgpr,     mffgpr")
7710    (set_attr "size" "64")
7711    (set_attr "isa"
7712             "*,           *,          *,          p9v,        p9v,
7713              p7v,         p7v,        *,          *,          *,
7714              *,           *,          *,          *,          *,
7715              *,           p8v,        p8v")])
7717 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7718 ;;           H-const  F-const  Special
7720 (define_insn "*mov<mode>_softfloat64"
7721   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7722            "=Y,       r,      r,      *c*l,   r,      r,
7723              r,       r,      *h")
7725         (match_operand:FMOVE64 1 "input_operand"
7726             "r,       Y,      r,      r,      *h,     G,
7727              H,       F,      0"))]
7729   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7730    && (gpc_reg_operand (operands[0], <MODE>mode)
7731        || gpc_reg_operand (operands[1], <MODE>mode))"
7732   "@
7733    std%U0%X0 %1,%0
7734    ld%U1%X1 %0,%1
7735    mr %0,%1
7736    mt%0 %1
7737    mf%1 %0
7738    #
7739    #
7740    #
7741    nop"
7742   [(set_attr "type"
7743             "store,   load,   *,      mtjmpr, mfjmpr, *,
7744              *,       *,      *")
7746    (set_attr "length"
7747             "*,       *,      *,      *,      *,      8,
7748              12,      16,     *")])
7750 (define_expand "mov<mode>"
7751   [(set (match_operand:FMOVE128 0 "general_operand")
7752         (match_operand:FMOVE128 1 "any_operand"))]
7753   ""
7755   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7756   DONE;
7759 ;; It's important to list Y->r and r->Y before r->r because otherwise
7760 ;; reload, given m->r, will try to pick r->r and reload it, which
7761 ;; doesn't make progress.
7763 ;; We can't split little endian direct moves of TDmode, because the words are
7764 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7765 ;; problematical.  Don't allow direct move for this case.
7767 ;;              FPR load    FPR store   FPR move    FPR zero    GPR load
7768 ;;              GPR zero    GPR store   GPR move    MFVSRD      MTVSRD
7770 (define_insn_and_split "*mov<mode>_64bit_dm"
7771   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7772                 "=m,        d,          d,          d,          Y,
7773                  r,         r,          r,          r,          d")
7775         (match_operand:FMOVE128_FPR 1 "input_operand"
7776                 "d,         m,          d,          <zero_fp>,  r,
7777                  <zero_fp>, Y,          r,          d,          r"))]
7779   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7780    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7781    && (gpc_reg_operand (operands[0], <MODE>mode)
7782        || gpc_reg_operand (operands[1], <MODE>mode))"
7783   "#"
7784   "&& reload_completed"
7785   [(pc)]
7787   rs6000_split_multireg_move (operands[0], operands[1]);
7788   DONE;
7790   [(set_attr "length" "8")
7791    (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7792    (set_attr "max_prefixed_insns" "2")
7793    (set_attr "num_insns" "2")])
7795 (define_insn_and_split "*movtd_64bit_nodm"
7796   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7797         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7798   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7799    && (gpc_reg_operand (operands[0], TDmode)
7800        || gpc_reg_operand (operands[1], TDmode))"
7801   "#"
7802   "&& reload_completed"
7803   [(pc)]
7805   rs6000_split_multireg_move (operands[0], operands[1]);
7806   DONE;
7808   [(set_attr "length" "8,8,8,12,12,8")
7809    (set_attr "max_prefixed_insns" "2")
7810    (set_attr "num_insns" "2,2,2,3,3,2")])
7812 (define_insn_and_split "*mov<mode>_32bit"
7813   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7814         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7815   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7816    && (FLOAT128_2REG_P (<MODE>mode)
7817        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7818        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7819    && (gpc_reg_operand (operands[0], <MODE>mode)
7820        || gpc_reg_operand (operands[1], <MODE>mode))"
7821   "#"
7822   "&& reload_completed"
7823   [(pc)]
7825   rs6000_split_multireg_move (operands[0], operands[1]);
7826   DONE;
7828   [(set_attr "length" "8,8,8,8,20,20,16")])
7830 (define_insn_and_split "*mov<mode>_softfloat"
7831   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7832         (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7833   "TARGET_SOFT_FLOAT
7834    && (gpc_reg_operand (operands[0], <MODE>mode)
7835        || gpc_reg_operand (operands[1], <MODE>mode))"
7836   "#"
7837   "&& reload_completed"
7838   [(pc)]
7840   rs6000_split_multireg_move (operands[0], operands[1]);
7841   DONE;
7843   [(set_attr_alternative "length"
7844        [(if_then_else (match_test "TARGET_POWERPC64")
7845             (const_string "8")
7846             (const_string "16"))
7847         (if_then_else (match_test "TARGET_POWERPC64")
7848             (const_string "8")
7849             (const_string "16"))
7850         (if_then_else (match_test "TARGET_POWERPC64")
7851             (const_string "16")
7852             (const_string "32"))
7853         (if_then_else (match_test "TARGET_POWERPC64")
7854             (const_string "8")
7855             (const_string "16"))])])
7857 (define_expand "@extenddf<mode>2"
7858   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7859         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7860   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7862   if (FLOAT128_IEEE_P (<MODE>mode))
7863     rs6000_expand_float128_convert (operands[0], operands[1], false);
7864   else if (TARGET_VSX)
7865     emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7866   else
7867     {
7868       rtx zero = gen_reg_rtx (DFmode);
7869       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7871       emit_insn (gen_extenddf2_fprs (<MODE>mode,
7872                                      operands[0], operands[1], zero));
7873     }
7874   DONE;
7877 ;; Allow memory operands for the source to be created by the combiner.
7878 (define_insn_and_split "@extenddf<mode>2_fprs"
7879   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7880         (float_extend:IBM128
7881          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7882    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7883   "!TARGET_VSX && TARGET_HARD_FLOAT
7884    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7885   "#"
7886   "&& reload_completed"
7887   [(set (match_dup 3) (match_dup 1))
7888    (set (match_dup 4) (match_dup 2))]
7890   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7891   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7893   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7894   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7897 (define_insn_and_split "@extenddf<mode>2_vsx"
7898   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7899         (float_extend:IBM128
7900          (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7901   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7902   "#"
7903   "&& reload_completed"
7904   [(set (match_dup 2) (match_dup 1))
7905    (set (match_dup 3) (match_dup 4))]
7907   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7908   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7910   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7911   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7912   operands[4] = CONST0_RTX (DFmode);
7915 (define_expand "extendsf<mode>2"
7916   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7917         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7918   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7920   if (FLOAT128_IEEE_P (<MODE>mode))
7921     rs6000_expand_float128_convert (operands[0], operands[1], false);
7922   else
7923     {
7924       rtx tmp = gen_reg_rtx (DFmode);
7925       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7926       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7927     }
7928   DONE;
7931 (define_expand "trunc<mode>df2"
7932   [(set (match_operand:DF 0 "gpc_reg_operand")
7933         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7934   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7936   if (FLOAT128_IEEE_P (<MODE>mode))
7937     {
7938       rs6000_expand_float128_convert (operands[0], operands[1], false);
7939       DONE;
7940     }
7943 (define_insn_and_split "trunc<mode>df2_internal1"
7944   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7945         (float_truncate:DF
7946          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7947   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7948    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7949   "@
7950    #
7951    fmr %0,%1"
7952   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7953   [(const_int 0)]
7955   emit_note (NOTE_INSN_DELETED);
7956   DONE;
7958   [(set_attr "type" "fpsimple")])
7960 (define_insn "trunc<mode>df2_internal2"
7961   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7962         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7963   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7964    && TARGET_LONG_DOUBLE_128"
7965   "fadd %0,%1,%L1"
7966   [(set_attr "type" "fp")])
7968 (define_expand "trunc<mode>sf2"
7969   [(set (match_operand:SF 0 "gpc_reg_operand")
7970         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7971   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7973   if (FLOAT128_IEEE_P (<MODE>mode))
7974     rs6000_expand_float128_convert (operands[0], operands[1], false);
7975   else
7976     {
7977       rtx tmp = gen_reg_rtx (DFmode);
7978       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7979       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7980     }
7981   DONE;
7984 (define_expand "floatsi<mode>2"
7985   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7986                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7987               (clobber (match_scratch:DI 2))])]
7988   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7990   rtx op0 = operands[0];
7991   rtx op1 = operands[1];
7993   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7994     ;
7995   else if (FLOAT128_IEEE_P (<MODE>mode))
7996     {
7997       rs6000_expand_float128_convert (op0, op1, false);
7998       DONE;
7999     }
8000   else
8001     {
8002       rtx tmp = gen_reg_rtx (DFmode);
8003       expand_float (tmp, op1, false);
8004       emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8005       DONE;
8006     }
8009 ; fadd, but rounding towards zero.
8010 ; This is probably not the optimal code sequence.
8011 (define_insn "fix_trunc_helper<mode>"
8012   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8013         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8014                    UNSPEC_FIX_TRUNC_TF))
8015    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8016   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8017   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8018   [(set_attr "type" "fp")
8019    (set_attr "length" "20")])
8021 (define_expand "fix_trunc<mode>si2"
8022   [(set (match_operand:SI 0 "gpc_reg_operand")
8023         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8024   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8026   rtx op0 = operands[0];
8027   rtx op1 = operands[1];
8029   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8030     ;
8031   else
8032     {
8033       if (FLOAT128_IEEE_P (<MODE>mode))
8034         rs6000_expand_float128_convert (op0, op1, false);
8035       else
8036         emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8037       DONE;
8038     }
8041 (define_expand "@fix_trunc<mode>si2_fprs"
8042   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8043                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8044               (clobber (match_dup 2))
8045               (clobber (match_dup 3))
8046               (clobber (match_dup 4))
8047               (clobber (match_dup 5))])]
8048   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8050   operands[2] = gen_reg_rtx (DFmode);
8051   operands[3] = gen_reg_rtx (DFmode);
8052   operands[4] = gen_reg_rtx (DImode);
8053   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8056 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8057   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8058         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8059    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8060    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8061    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8062    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8063   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8064   "#"
8065   ""
8066   [(pc)]
8068   rtx lowword;
8069   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8070                                          operands[3]));
8072   gcc_assert (MEM_P (operands[5]));
8073   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8075   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8076   emit_move_insn (operands[5], operands[4]);
8077   emit_move_insn (operands[0], lowword);
8078   DONE;
8081 (define_expand "fix_trunc<mode>di2"
8082   [(set (match_operand:DI 0 "gpc_reg_operand")
8083         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8084   "TARGET_FLOAT128_TYPE"
8086   if (!TARGET_FLOAT128_HW)
8087     {
8088       rs6000_expand_float128_convert (operands[0], operands[1], false);
8089       DONE;
8090     }
8093 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8094   [(set (match_operand:SDI 0 "gpc_reg_operand")
8095         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8096   "TARGET_FLOAT128_TYPE"
8098   rs6000_expand_float128_convert (operands[0], operands[1], true);
8099   DONE;
8102 (define_expand "floatdi<mode>2"
8103   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8104         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8105   "TARGET_FLOAT128_TYPE"
8107   if (!TARGET_FLOAT128_HW)
8108     {
8109       rs6000_expand_float128_convert (operands[0], operands[1], false);
8110       DONE;
8111     }
8114 (define_expand "floatunsdi<IEEE128:mode>2"
8115   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8116         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8117   "TARGET_FLOAT128_TYPE"
8119   if (!TARGET_FLOAT128_HW)
8120     {
8121       rs6000_expand_float128_convert (operands[0], operands[1], true);
8122       DONE;
8123     }
8126 (define_expand "floatuns<IEEE128:mode>2"
8127   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8128         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8129   "TARGET_FLOAT128_TYPE"
8131   rtx op0 = operands[0];
8132   rtx op1 = operands[1];
8134   if (TARGET_FLOAT128_HW)
8135     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8136   else
8137     rs6000_expand_float128_convert (op0, op1, true);
8138   DONE;
8141 (define_expand "neg<mode>2"
8142   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8143         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8144   "FLOAT128_IEEE_P (<MODE>mode)
8145    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8147   if (FLOAT128_IEEE_P (<MODE>mode))
8148     {
8149       if (TARGET_FLOAT128_HW)
8150         emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8151       else if (TARGET_FLOAT128_TYPE)
8152         emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8153                                              operands[0], operands[1]));
8154       else
8155         {
8156           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8157           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8158                                                 <MODE>mode,
8159                                                 operands[1], <MODE>mode);
8161           if (target && !rtx_equal_p (target, operands[0]))
8162             emit_move_insn (operands[0], target);
8163         }
8164       DONE;
8165     }
8168 (define_insn "neg<mode>2_internal"
8169   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8170         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8171   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8173   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8174     return "fneg %L0,%L1\;fneg %0,%1";
8175   else
8176     return "fneg %0,%1\;fneg %L0,%L1";
8178   [(set_attr "type" "fpsimple")
8179    (set_attr "length" "8")])
8181 (define_expand "abs<mode>2"
8182   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8183         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8184   "FLOAT128_IEEE_P (<MODE>mode)
8185    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8187   rtx label;
8189   if (FLOAT128_IEEE_P (<MODE>mode))
8190     {
8191       if (TARGET_FLOAT128_HW)
8192         {
8193           emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8194           DONE;
8195         }
8196       else if (TARGET_FLOAT128_TYPE)
8197         {
8198           emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8199                                                operands[0], operands[1]));
8200           DONE;
8201         }
8202       else
8203         FAIL;
8204     }
8206   label = gen_label_rtx ();
8207   emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8208   emit_label (label);
8209   DONE;
8212 (define_expand "@abs<mode>2_internal"
8213   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8214         (match_operand:IBM128 1 "gpc_reg_operand"))
8215    (set (match_dup 3) (match_dup 5))
8216    (set (match_dup 5) (abs:DF (match_dup 5)))
8217    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8218    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8219                            (label_ref (match_operand 2 ""))
8220                            (pc)))
8221    (set (match_dup 6) (neg:DF (match_dup 6)))]
8222   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8224   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8225   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8226   operands[3] = gen_reg_rtx (DFmode);
8227   operands[4] = gen_reg_rtx (CCFPmode);
8228   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8229   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8233 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8234 ;; register
8236 (define_expand "ieee_128bit_negative_zero"
8237   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8238   "TARGET_FLOAT128_TYPE"
8240   rtvec v = rtvec_alloc (16);
8241   int i, high;
8243   for (i = 0; i < 16; i++)
8244     RTVEC_ELT (v, i) = const0_rtx;
8246   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8247   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8249   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8250   DONE;
8253 ;; IEEE 128-bit negate
8255 ;; We have 2 insns here for negate and absolute value.  The first uses
8256 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8257 ;; insns, and second insn after the first split pass loads up the bit to
8258 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8259 ;; neg/abs to create the constant just once.
8261 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8262   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8263         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8264    (clobber (match_scratch:V16QI 2 "=v"))]
8265   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8266   "#"
8267   "&& 1"
8268   [(parallel [(set (match_dup 0)
8269                    (neg:IEEE128 (match_dup 1)))
8270               (use (match_dup 2))])]
8272   if (GET_CODE (operands[2]) == SCRATCH)
8273     operands[2] = gen_reg_rtx (V16QImode);
8275   operands[3] = gen_reg_rtx (V16QImode);
8276   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8278   [(set_attr "length" "8")
8279    (set_attr "type" "vecsimple")])
8281 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8282   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8283         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8284    (use (match_operand:V16QI 2 "register_operand" "v"))]
8285   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8286   "xxlxor %x0,%x1,%x2"
8287   [(set_attr "type" "veclogical")])
8289 ;; IEEE 128-bit absolute value
8290 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8291   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8292         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8293    (clobber (match_scratch:V16QI 2 "=v"))]
8294   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8295   "#"
8296   "&& 1"
8297   [(parallel [(set (match_dup 0)
8298                    (abs:IEEE128 (match_dup 1)))
8299               (use (match_dup 2))])]
8301   if (GET_CODE (operands[2]) == SCRATCH)
8302     operands[2] = gen_reg_rtx (V16QImode);
8304   operands[3] = gen_reg_rtx (V16QImode);
8305   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8307   [(set_attr "length" "8")
8308    (set_attr "type" "vecsimple")])
8310 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8311   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8312         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8313    (use (match_operand:V16QI 2 "register_operand" "v"))]
8314   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8315   "xxlandc %x0,%x1,%x2"
8316   [(set_attr "type" "veclogical")])
8318 ;; IEEE 128-bit negative absolute value
8319 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8320   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8321         (neg:IEEE128
8322          (abs:IEEE128
8323           (match_operand:IEEE128 1 "register_operand" "wa"))))
8324    (clobber (match_scratch:V16QI 2 "=v"))]
8325   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8326    && FLOAT128_IEEE_P (<MODE>mode)"
8327   "#"
8328   "&& 1"
8329   [(parallel [(set (match_dup 0)
8330                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8331               (use (match_dup 2))])]
8333   if (GET_CODE (operands[2]) == SCRATCH)
8334     operands[2] = gen_reg_rtx (V16QImode);
8336   operands[3] = gen_reg_rtx (V16QImode);
8337   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8339   [(set_attr "length" "8")
8340    (set_attr "type" "vecsimple")])
8342 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8343   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8344         (neg:IEEE128
8345          (abs:IEEE128
8346           (match_operand:IEEE128 1 "register_operand" "wa"))))
8347    (use (match_operand:V16QI 2 "register_operand" "v"))]
8348   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8349   "xxlor %x0,%x1,%x2"
8350   [(set_attr "type" "veclogical")])
8352 ;; Float128 conversion functions.  These expand to library function calls.
8353 ;; We use expand to convert from IBM double double to IEEE 128-bit
8354 ;; and trunc for the opposite.
8355 (define_expand "extendiftf2"
8356   [(set (match_operand:TF 0 "gpc_reg_operand")
8357         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8358   "TARGET_FLOAT128_TYPE"
8360   rs6000_expand_float128_convert (operands[0], operands[1], false);
8361   DONE;
8364 (define_expand "extendifkf2"
8365   [(set (match_operand:KF 0 "gpc_reg_operand")
8366         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8367   "TARGET_FLOAT128_TYPE"
8369   rs6000_expand_float128_convert (operands[0], operands[1], false);
8370   DONE;
8373 (define_expand "extendtfkf2"
8374   [(set (match_operand:KF 0 "gpc_reg_operand")
8375         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8376   "TARGET_FLOAT128_TYPE"
8378   rs6000_expand_float128_convert (operands[0], operands[1], false);
8379   DONE;
8382 (define_expand "extendtfif2"
8383   [(set (match_operand:IF 0 "gpc_reg_operand")
8384         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8385   "TARGET_FLOAT128_TYPE"
8387   rs6000_expand_float128_convert (operands[0], operands[1], false);
8388   DONE;
8391 (define_expand "trunciftf2"
8392   [(set (match_operand:TF 0 "gpc_reg_operand")
8393         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8394   "TARGET_FLOAT128_TYPE"
8396   rs6000_expand_float128_convert (operands[0], operands[1], false);
8397   DONE;
8400 (define_expand "truncifkf2"
8401   [(set (match_operand:KF 0 "gpc_reg_operand")
8402         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8403   "TARGET_FLOAT128_TYPE"
8405   rs6000_expand_float128_convert (operands[0], operands[1], false);
8406   DONE;
8409 (define_expand "trunckftf2"
8410   [(set (match_operand:TF 0 "gpc_reg_operand")
8411         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8412   "TARGET_FLOAT128_TYPE"
8414   rs6000_expand_float128_convert (operands[0], operands[1], false);
8415   DONE;
8418 (define_expand "trunctfif2"
8419   [(set (match_operand:IF 0 "gpc_reg_operand")
8420         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8421   "TARGET_FLOAT128_TYPE"
8423   rs6000_expand_float128_convert (operands[0], operands[1], false);
8424   DONE;
8427 (define_insn_and_split "*extend<mode>tf2_internal"
8428   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8429         (float_extend:TF
8430          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8431    "TARGET_FLOAT128_TYPE
8432     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8433   "#"
8434   "&& reload_completed"
8435   [(set (match_dup 0) (match_dup 2))]
8437   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8440 (define_insn_and_split "*extendtf<mode>2_internal"
8441   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8442         (float_extend:IFKF
8443          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8444    "TARGET_FLOAT128_TYPE
8445     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8446   "#"
8447   "&& reload_completed"
8448   [(set (match_dup 0) (match_dup 2))]
8450   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8454 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8455 ;; must have 3 arguments, and scratch register constraint must be a single
8456 ;; constraint.
8458 ;; Reload patterns to support gpr load/store with misaligned mem.
8459 ;; and multiple gpr load/store at offset >= 0xfffc
8460 (define_expand "reload_<mode>_store"
8461   [(parallel [(match_operand 0 "memory_operand" "=m")
8462               (match_operand 1 "gpc_reg_operand" "r")
8463               (match_operand:GPR 2 "register_operand" "=&b")])]
8464   ""
8466   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8467   DONE;
8470 (define_expand "reload_<mode>_load"
8471   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8472               (match_operand 1 "memory_operand" "m")
8473               (match_operand:GPR 2 "register_operand" "=b")])]
8474   ""
8476   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8477   DONE;
8481 ;; Reload patterns for various types using the vector registers.  We may need
8482 ;; an additional base register to convert the reg+offset addressing to reg+reg
8483 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8484 ;; index register for gpr registers.
8485 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8486   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8487               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8488               (match_operand:P 2 "register_operand" "=b")])]
8489   "<P:tptrsize>"
8491   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8492   DONE;
8495 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8496   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8497               (match_operand:RELOAD 1 "memory_operand" "m")
8498               (match_operand:P 2 "register_operand" "=b")])]
8499   "<P:tptrsize>"
8501   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8502   DONE;
8506 ;; Reload sometimes tries to move the address to a GPR, and can generate
8507 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8508 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8510 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8511   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8512         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8513                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8514                (const_int -16)))]
8515   "TARGET_ALTIVEC && reload_completed"
8516   "#"
8517   "&& reload_completed"
8518   [(set (match_dup 0)
8519         (plus:P (match_dup 1)
8520                 (match_dup 2)))
8521    (set (match_dup 0)
8522         (and:P (match_dup 0)
8523                (const_int -16)))])
8525 ;; Power8 merge instructions to allow direct move to/from floating point
8526 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8527 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8528 ;; value, since it is allocated in reload and not all of the flow information
8529 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8530 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8531 ;; schedule other instructions between the two instructions.
8533 (define_insn "p8_fmrgow_<mode>"
8534   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8535         (unspec:FMOVE64X [
8536                 (match_operand:DF 1 "register_operand" "d")
8537                 (match_operand:DF 2 "register_operand" "d")]
8538                          UNSPEC_P8V_FMRGOW))]
8539   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8540   "fmrgow %0,%1,%2"
8541   [(set_attr "type" "fpsimple")])
8543 (define_insn "p8_mtvsrwz"
8544   [(set (match_operand:DF 0 "register_operand" "=d")
8545         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8546                    UNSPEC_P8V_MTVSRWZ))]
8547   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8548   "mtvsrwz %x0,%1"
8549   [(set_attr "type" "mftgpr")])
8551 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8552   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8553         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8554                          UNSPEC_P8V_RELOAD_FROM_GPR))
8555    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8556   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8557   "#"
8558   "&& reload_completed"
8559   [(const_int 0)]
8561   rtx dest = operands[0];
8562   rtx src = operands[1];
8563   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8564   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8565   rtx gpr_hi_reg = gen_highpart (SImode, src);
8566   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8568   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8569   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8570   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8571   DONE;
8573   [(set_attr "length" "12")
8574    (set_attr "type" "three")])
8576 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8577 (define_insn "p8_mtvsrd_df"
8578   [(set (match_operand:DF 0 "register_operand" "=wa")
8579         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8580                    UNSPEC_P8V_MTVSRD))]
8581   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8582   "mtvsrd %x0,%1"
8583   [(set_attr "type" "mftgpr")])
8585 (define_insn "p8_xxpermdi_<mode>"
8586   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8587         (unspec:FMOVE128_GPR [
8588                 (match_operand:DF 1 "register_operand" "wa")
8589                 (match_operand:DF 2 "register_operand" "wa")]
8590                 UNSPEC_P8V_XXPERMDI))]
8591   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8592   "xxpermdi %x0,%x1,%x2,0"
8593   [(set_attr "type" "vecperm")])
8595 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8596   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8597         (unspec:FMOVE128_GPR
8598          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8599          UNSPEC_P8V_RELOAD_FROM_GPR))
8600    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8601   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8602   "#"
8603   "&& reload_completed"
8604   [(const_int 0)]
8606   rtx dest = operands[0];
8607   rtx src = operands[1];
8608   /* You might think that we could use op0 as one temp and a DF clobber
8609      as op2, but you'd be wrong.  Secondary reload move patterns don't
8610      check for overlap of the clobber and the destination.  */
8611   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8612   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8613   rtx gpr_hi_reg = gen_highpart (DImode, src);
8614   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8616   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8617   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8618   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8619   DONE;
8621   [(set_attr "length" "12")
8622    (set_attr "type" "three")])
8624 (define_split
8625   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8626         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8627   "reload_completed
8628    && (int_reg_operand (operands[0], <MODE>mode)
8629        || int_reg_operand (operands[1], <MODE>mode))
8630    && (!TARGET_DIRECT_MOVE_128
8631        || (!vsx_register_operand (operands[0], <MODE>mode)
8632            && !vsx_register_operand (operands[1], <MODE>mode)))"
8633   [(pc)]
8635   rs6000_split_multireg_move (operands[0], operands[1]);
8636   DONE;
8639 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8640 ;; type is stored internally as double precision in the VSX registers, we have
8641 ;; to convert it from the vector format.
8642 (define_insn "p8_mtvsrd_sf"
8643   [(set (match_operand:SF 0 "register_operand" "=wa")
8644         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8645                    UNSPEC_P8V_MTVSRD))]
8646   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8647   "mtvsrd %x0,%1"
8648   [(set_attr "type" "mftgpr")])
8650 (define_insn_and_split "reload_vsx_from_gprsf"
8651   [(set (match_operand:SF 0 "register_operand" "=wa")
8652         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8653                    UNSPEC_P8V_RELOAD_FROM_GPR))
8654    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8655   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8656   "#"
8657   "&& reload_completed"
8658   [(const_int 0)]
8660   rtx op0 = operands[0];
8661   rtx op1 = operands[1];
8662   rtx op2 = operands[2];
8663   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8665   /* Move SF value to upper 32-bits for xscvspdpn.  */
8666   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8667   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8668   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8669   DONE;
8671   [(set_attr "length" "8")
8672    (set_attr "type" "two")])
8674 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8675 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8676 ;; and then doing a move of that.
8677 (define_insn "p8_mfvsrd_3_<mode>"
8678   [(set (match_operand:DF 0 "register_operand" "=r")
8679         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8680                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8681   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8682   "mfvsrd %0,%x1"
8683   [(set_attr "type" "mftgpr")])
8685 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8686   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8687         (unspec:FMOVE128_GPR
8688          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8689          UNSPEC_P8V_RELOAD_FROM_VSX))
8690    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8691   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8692   "#"
8693   "&& reload_completed"
8694   [(const_int 0)]
8696   rtx dest = operands[0];
8697   rtx src = operands[1];
8698   rtx tmp = operands[2];
8699   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8700   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8702   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8703   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8704   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8705   DONE;
8707   [(set_attr "length" "12")
8708    (set_attr "type" "three")])
8710 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8711 ;; type is stored internally as double precision, we have to convert it to the
8712 ;; vector format.
8714 (define_insn_and_split "reload_gpr_from_vsxsf"
8715   [(set (match_operand:SF 0 "register_operand" "=r")
8716         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8717                    UNSPEC_P8V_RELOAD_FROM_VSX))
8718    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8719   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8720   "#"
8721   "&& reload_completed"
8722   [(const_int 0)]
8724   rtx op0 = operands[0];
8725   rtx op1 = operands[1];
8726   rtx op2 = operands[2];
8727   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8728   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8730   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8731   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8732   DONE;
8734   [(set_attr "length" "8")
8735    (set_attr "type" "two")
8736    (set_attr "isa" "p8v")])
8738 ;; Next come the multi-word integer load and store and the load and store
8739 ;; multiple insns.
8741 ;; List r->r after r->Y, otherwise reload will try to reload a
8742 ;; non-offsettable address by using r->r which won't make progress.
8743 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8744 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8746 ;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8747 ;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8748 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8749 ;;        AVX const  
8751 (define_insn "*movdi_internal32"
8752   [(set (match_operand:DI 0 "nonimmediate_operand"
8753          "=Y,        r,         r,         m,         ^d,        ^d,
8754           r,         wY,        Z,         ^v,        $v,        ^wa,
8755           wa,        wa,        v,         wa,        *i,        v,
8756           v")
8757         (match_operand:DI 1 "input_operand"
8758          "r,         Y,         r,         ^d,        m,         ^d,
8759           IJKnF,     ^v,        $v,        wY,        Z,         ^wa,
8760           Oj,        wM,        OjwM,      Oj,        wM,        wS,
8761           wB"))]
8762   "! TARGET_POWERPC64
8763    && (gpc_reg_operand (operands[0], DImode)
8764        || gpc_reg_operand (operands[1], DImode))"
8765   "@
8766    #
8767    #
8768    #
8769    stfd%U0%X0 %1,%0
8770    lfd%U1%X1 %0,%1
8771    fmr %0,%1
8772    #
8773    stxsd %1,%0
8774    stxsdx %x1,%y0
8775    lxsd %0,%1
8776    lxsdx %x0,%y1
8777    xxlor %x0,%x1,%x1
8778    xxspltib %x0,0
8779    xxspltib %x0,255
8780    vspltisw %0,%1
8781    xxlxor %x0,%x0,%x0
8782    xxlorc %x0,%x0,%x0
8783    #
8784    #"
8785   [(set_attr "type"
8786          "store,     load,      *,         fpstore,   fpload,    fpsimple,
8787           *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8788           vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8789           vecsimple")
8790    (set_attr "size" "64")
8791    (set_attr "length"
8792          "8,         8,         8,         *,         *,         *,
8793           16,        *,         *,         *,         *,         *,
8794           *,         *,         *,         *,         *,         8,
8795           *")
8796    (set_attr "isa"
8797          "*,         *,         *,         *,         *,         *,
8798           *,         p9v,       p7v,       p9v,       p7v,       *,
8799           p9v,       p9v,       p7v,       *,         *,         p7v,
8800           p7v")])
8802 (define_split
8803   [(set (match_operand:DI 0 "gpc_reg_operand")
8804         (match_operand:DI 1 "const_int_operand"))]
8805   "! TARGET_POWERPC64 && reload_completed
8806    && gpr_or_gpr_p (operands[0], operands[1])
8807    && !direct_move_p (operands[0], operands[1])"
8808   [(set (match_dup 2) (match_dup 4))
8809    (set (match_dup 3) (match_dup 1))]
8811   HOST_WIDE_INT value = INTVAL (operands[1]);
8812   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8813                                        DImode);
8814   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8815                                        DImode);
8816   operands[4] = GEN_INT (value >> 32);
8817   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8820 (define_split
8821   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8822         (match_operand:DIFD 1 "input_operand"))]
8823   "reload_completed && !TARGET_POWERPC64
8824    && gpr_or_gpr_p (operands[0], operands[1])
8825    && !direct_move_p (operands[0], operands[1])"
8826   [(pc)]
8828   rs6000_split_multireg_move (operands[0], operands[1]);
8829   DONE;
8832 ;;         GPR store   GPR load    GPR move
8833 ;;         GPR li      GPR lis     GPR pli     GPR #
8834 ;;         FPR store   FPR load    FPR move
8835 ;;         AVX store   AVX store   AVX load    AVX load    VSX move
8836 ;;         P9 0        P9 -1       AVX 0/-1    VSX 0       VSX -1
8837 ;;         P9 const    AVX const
8838 ;;         From SPR    To SPR      SPR<->SPR
8839 ;;         VSX->GPR    GPR->VSX
8840 (define_insn "*movdi_internal64"
8841   [(set (match_operand:DI 0 "nonimmediate_operand"
8842           "=YZ,        r,          r,
8843            r,          r,          r,          r,
8844            m,          ^d,         ^d,
8845            wY,         Z,          $v,         $v,         ^wa,
8846            wa,         wa,         v,          wa,         wa,
8847            v,          v,
8848            r,          *h,         *h,
8849            ?r,         ?wa")
8850         (match_operand:DI 1 "input_operand"
8851           "r,          YZ,         r,
8852            I,          L,          eI,         nF,
8853            ^d,         m,          ^d,
8854            ^v,         $v,         wY,         Z,          ^wa,
8855            Oj,         wM,         OjwM,       Oj,         wM,
8856            wS,         wB,
8857            *h,         r,          0,
8858            wa,         r"))]
8859   "TARGET_POWERPC64
8860    && (gpc_reg_operand (operands[0], DImode)
8861        || gpc_reg_operand (operands[1], DImode))"
8862   "@
8863    std%U0%X0 %1,%0
8864    ld%U1%X1 %0,%1
8865    mr %0,%1
8866    li %0,%1
8867    lis %0,%v1
8868    li %0,%1
8869    #
8870    stfd%U0%X0 %1,%0
8871    lfd%U1%X1 %0,%1
8872    fmr %0,%1
8873    stxsd %1,%0
8874    stxsdx %x1,%y0
8875    lxsd %0,%1
8876    lxsdx %x0,%y1
8877    xxlor %x0,%x1,%x1
8878    xxspltib %x0,0
8879    xxspltib %x0,255
8880    #
8881    xxlxor %x0,%x0,%x0
8882    xxlorc %x0,%x0,%x0
8883    #
8884    #
8885    mf%1 %0
8886    mt%0 %1
8887    nop
8888    mfvsrd %0,%x1
8889    mtvsrd %x0,%1"
8890   [(set_attr "type"
8891           "store,      load,       *,
8892            *,          *,          *,          *,
8893            fpstore,    fpload,     fpsimple,
8894            fpstore,    fpstore,    fpload,     fpload,     veclogical,
8895            vecsimple,  vecsimple,  vecsimple,  veclogical, veclogical,
8896            vecsimple,  vecsimple,
8897            mfjmpr,     mtjmpr,     *,
8898            mftgpr,     mffgpr")
8899    (set_attr "size" "64")
8900    (set_attr "length"
8901           "*,          *,          *,
8902            *,          *,          *,          20,
8903            *,          *,          *,
8904            *,          *,          *,          *,          *,
8905            *,          *,          *,          *,          *,
8906            8,          *,
8907            *,          *,          *,
8908            *,          *")
8909    (set_attr "isa"
8910           "*,          *,          *,
8911            *,          *,          fut,        *,
8912            *,          *,          *,
8913            p9v,        p7v,        p9v,        p7v,        *,
8914            p9v,        p9v,        p7v,        *,          *,
8915            p7v,        p7v,
8916            *,          *,          *,
8917            p8v,        p8v")])
8919 ; Some DImode loads are best done as a load of -1 followed by a mask
8920 ; instruction.
8921 (define_split
8922   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8923         (match_operand:DI 1 "const_int_operand"))]
8924   "TARGET_POWERPC64
8925    && num_insns_constant (operands[1], DImode) > 1
8926    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8927    && rs6000_is_valid_and_mask (operands[1], DImode)"
8928   [(set (match_dup 0)
8929         (const_int -1))
8930    (set (match_dup 0)
8931         (and:DI (match_dup 0)
8932                 (match_dup 1)))]
8933   "")
8935 ;; Split a load of a large constant into the appropriate five-instruction
8936 ;; sequence.  Handle anything in a constant number of insns.
8937 ;; When non-easy constants can go in the TOC, this should use
8938 ;; easy_fp_constant predicate.
8939 (define_split
8940   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8941         (match_operand:DI 1 "const_int_operand"))]
8942   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8943   [(set (match_dup 0) (match_dup 2))
8944    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8946   if (rs6000_emit_set_const (operands[0], operands[1]))
8947     DONE;
8948   else
8949     FAIL;
8952 (define_split
8953   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8954         (match_operand:DI 1 "const_scalar_int_operand"))]
8955   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8956   [(set (match_dup 0) (match_dup 2))
8957    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8959   if (rs6000_emit_set_const (operands[0], operands[1]))
8960     DONE;
8961   else
8962     FAIL;
8965 (define_split
8966   [(set (match_operand:DI 0 "altivec_register_operand")
8967         (match_operand:DI 1 "s5bit_cint_operand"))]
8968   "TARGET_VSX && reload_completed"
8969   [(const_int 0)]
8971   rtx op0 = operands[0];
8972   rtx op1 = operands[1];
8973   int r = REGNO (op0);
8974   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8976   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8977   if (op1 != const0_rtx && op1 != constm1_rtx)
8978     {
8979       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8980       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8981     }
8982   DONE;
8985 ;; Split integer constants that can be loaded with XXSPLTIB and a
8986 ;; sign extend operation.
8987 (define_split
8988   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8989         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8990   "TARGET_P9_VECTOR && reload_completed"
8991   [(const_int 0)]
8993   rtx op0 = operands[0];
8994   rtx op1 = operands[1];
8995   int r = REGNO (op0);
8996   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8998   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8999   if (<MODE>mode == DImode)
9000     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9001   else if (<MODE>mode == SImode)
9002     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9003   else if (<MODE>mode == HImode)
9004     {
9005       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9006       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9007     }
9008   DONE;
9012 ;; TImode/PTImode is similar, except that we usually want to compute the
9013 ;; address into a register and use lsi/stsi (the exception is during reload).
9015 (define_insn "*mov<mode>_string"
9016   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9017         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9018   "! TARGET_POWERPC64
9019    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9020    && (gpc_reg_operand (operands[0], <MODE>mode)
9021        || gpc_reg_operand (operands[1], <MODE>mode))"
9022   "#"
9023   [(set_attr "type" "store,store,load,load,*,*")
9024    (set_attr "update" "yes")
9025    (set_attr "indexed" "yes")
9026    (set_attr "cell_micro" "conditional")])
9028 (define_insn "*mov<mode>_ppc64"
9029   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9030         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9031   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9032    && (gpc_reg_operand (operands[0], <MODE>mode)
9033        || gpc_reg_operand (operands[1], <MODE>mode)))"
9035   return rs6000_output_move_128bit (operands);
9037   [(set_attr "type" "store,store,load,load,*,*")
9038    (set_attr "length" "8")
9039    (set_attr "max_prefixed_insns" "2")])
9041 (define_split
9042   [(set (match_operand:TI2 0 "int_reg_operand")
9043         (match_operand:TI2 1 "const_scalar_int_operand"))]
9044   "TARGET_POWERPC64
9045    && (VECTOR_MEM_NONE_P (<MODE>mode)
9046        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9047   [(set (match_dup 2) (match_dup 4))
9048    (set (match_dup 3) (match_dup 5))]
9050   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9051                                        <MODE>mode);
9052   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9053                                        <MODE>mode);
9054   if (CONST_WIDE_INT_P (operands[1]))
9055     {
9056       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9057       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9058     }
9059   else if (CONST_INT_P (operands[1]))
9060     {
9061       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9062       operands[5] = operands[1];
9063     }
9064   else
9065     FAIL;
9068 (define_split
9069   [(set (match_operand:TI2 0 "nonimmediate_operand")
9070         (match_operand:TI2 1 "input_operand"))]
9071   "reload_completed
9072    && gpr_or_gpr_p (operands[0], operands[1])
9073    && !direct_move_p (operands[0], operands[1])
9074    && !quad_load_store_p (operands[0], operands[1])"
9075   [(pc)]
9077   rs6000_split_multireg_move (operands[0], operands[1]);
9078   DONE;
9081 (define_expand "setmemsi"
9082   [(parallel [(set (match_operand:BLK 0 "")
9083                    (match_operand 2 "const_int_operand"))
9084               (use (match_operand:SI 1 ""))
9085               (use (match_operand:SI 3 ""))])]
9086   ""
9088   /* If value to set is not zero, use the library routine.  */
9089   if (operands[2] != const0_rtx)
9090     FAIL;
9092   if (expand_block_clear (operands))
9093     DONE;
9094   else
9095     FAIL;
9098 ;; String compare N insn.
9099 ;; Argument 0 is the target (result)
9100 ;; Argument 1 is the destination
9101 ;; Argument 2 is the source
9102 ;; Argument 3 is the length
9103 ;; Argument 4 is the alignment
9105 (define_expand "cmpstrnsi"
9106   [(parallel [(set (match_operand:SI 0)
9107                (compare:SI (match_operand:BLK 1)
9108                            (match_operand:BLK 2)))
9109               (use (match_operand:SI 3))
9110               (use (match_operand:SI 4))])]
9111   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9113   if (optimize_insn_for_size_p ())
9114     FAIL;
9116   if (expand_strn_compare (operands, 0))
9117     DONE;
9118   else  
9119     FAIL;
9122 ;; String compare insn.
9123 ;; Argument 0 is the target (result)
9124 ;; Argument 1 is the destination
9125 ;; Argument 2 is the source
9126 ;; Argument 3 is the alignment
9128 (define_expand "cmpstrsi"
9129   [(parallel [(set (match_operand:SI 0)
9130                (compare:SI (match_operand:BLK 1)
9131                            (match_operand:BLK 2)))
9132               (use (match_operand:SI 3))])]
9133   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9135   if (optimize_insn_for_size_p ())
9136     FAIL;
9138   if (expand_strn_compare (operands, 1))
9139     DONE;
9140   else  
9141     FAIL;
9144 ;; Block compare insn.
9145 ;; Argument 0 is the target (result)
9146 ;; Argument 1 is the destination
9147 ;; Argument 2 is the source
9148 ;; Argument 3 is the length
9149 ;; Argument 4 is the alignment
9151 (define_expand "cmpmemsi"
9152   [(parallel [(set (match_operand:SI 0)
9153                (compare:SI (match_operand:BLK 1)
9154                            (match_operand:BLK 2)))
9155               (use (match_operand:SI 3))
9156               (use (match_operand:SI 4))])]
9157   "TARGET_POPCNTD"
9159   if (expand_block_compare (operands))
9160     DONE;
9161   else
9162     FAIL;
9165 ;; String/block copy insn (source and destination must not overlap).
9166 ;; Argument 0 is the destination
9167 ;; Argument 1 is the source
9168 ;; Argument 2 is the length
9169 ;; Argument 3 is the alignment
9171 (define_expand "cpymemsi"
9172   [(parallel [(set (match_operand:BLK 0 "")
9173                    (match_operand:BLK 1 ""))
9174               (use (match_operand:SI 2 ""))
9175               (use (match_operand:SI 3 ""))])]
9176   ""
9178   if (expand_block_move (operands, false))
9179     DONE;
9180   else
9181     FAIL;
9184 ;; String/block move insn (source and destination may overlap).
9185 ;; Argument 0 is the destination
9186 ;; Argument 1 is the source
9187 ;; Argument 2 is the length
9188 ;; Argument 3 is the alignment
9190 (define_expand "movmemsi"
9191   [(parallel [(set (match_operand:BLK 0 "")
9192                    (match_operand:BLK 1 ""))
9193               (use (match_operand:SI 2 ""))
9194               (use (match_operand:SI 3 ""))])]
9195   ""
9197   if (expand_block_move (operands, true))
9198     DONE;
9199   else
9200     FAIL;
9204 ;; Define insns that do load or store with update.  Some of these we can
9205 ;; get by using pre-decrement or pre-increment, but the hardware can also
9206 ;; do cases where the increment is not the size of the object.
9208 ;; In all these cases, we use operands 0 and 1 for the register being
9209 ;; incremented because those are the operands that local-alloc will
9210 ;; tie and these are the pair most likely to be tieable (and the ones
9211 ;; that will benefit the most).
9213 (define_insn "*movdi_update1"
9214   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9215         (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9216                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9217    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9218         (plus:P (match_dup 1) (match_dup 2)))]
9219   "TARGET_POWERPC64 && TARGET_UPDATE
9220    && (!avoiding_indexed_address_p (DImode)
9221        || !gpc_reg_operand (operands[2], Pmode))"
9222   "@
9223    ldux %3,%0,%2
9224    ldu %3,%2(%0)"
9225   [(set_attr "type" "load")
9226    (set_attr "update" "yes")
9227    (set_attr "indexed" "yes,no")])
9229 (define_insn "movdi_<mode>_update"
9230   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9231                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9232         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9233    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9234         (plus:P (match_dup 1) (match_dup 2)))]
9235   "TARGET_POWERPC64 && TARGET_UPDATE
9236    && (!avoiding_indexed_address_p (DImode)
9237        || !gpc_reg_operand (operands[2], Pmode)
9238        || (REG_P (operands[0])
9239            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9240   "@
9241    stdux %3,%0,%2
9242    stdu %3,%2(%0)"
9243   [(set_attr "type" "store")
9244    (set_attr "update" "yes")
9245    (set_attr "indexed" "yes,no")])
9247 ;; This pattern is only conditional on TARGET_64BIT, as it is
9248 ;; needed for stack allocation, even if the user passes -mno-update.
9249 (define_insn "movdi_update_stack"
9250   [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9251                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9252         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9253    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9254         (plus:DI (match_dup 1) (match_dup 2)))]
9255   "TARGET_64BIT"
9256   "@
9257    stdux %3,%0,%2
9258    stdu %3,%2(%0)"
9259   [(set_attr "type" "store")
9260    (set_attr "update" "yes")
9261    (set_attr "indexed" "yes,no")])
9263 (define_insn "*movsi_update1"
9264   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9265         (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9266                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9267    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9268         (plus:P (match_dup 1) (match_dup 2)))]
9269   "TARGET_UPDATE
9270    && (!avoiding_indexed_address_p (SImode)
9271        || !gpc_reg_operand (operands[2], Pmode))"
9272   "@
9273    lwzux %3,%0,%2
9274    lwzu %3,%2(%0)"
9275   [(set_attr "type" "load")
9276    (set_attr "update" "yes")
9277    (set_attr "indexed" "yes,no")])
9279 (define_insn "*movsi_update2"
9280   [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9281         (sign_extend:EXTSI
9282          (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9283                          (match_operand:P 2 "gpc_reg_operand" "r")))))
9284    (set (match_operand:P 0 "gpc_reg_operand" "=b")
9285         (plus:P (match_dup 1) (match_dup 2)))]
9286   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9287   "lwaux %3,%0,%2"
9288   [(set_attr "type" "load")
9289    (set_attr "sign_extend" "yes")
9290    (set_attr "update" "yes")
9291    (set_attr "indexed" "yes")])
9293 (define_insn "movsi_<mode>_update"
9294   [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9295                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9296         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9297    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9298         (plus:P (match_dup 1) (match_dup 2)))]
9299   "TARGET_UPDATE
9300    && (!avoiding_indexed_address_p (SImode)
9301        || !gpc_reg_operand (operands[2], Pmode)
9302        || (REG_P (operands[0])
9303            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9304   "@
9305    stwux %3,%0,%2
9306    stwu %3,%2(%0)"
9307   [(set_attr "type" "store")
9308    (set_attr "update" "yes")
9309    (set_attr "indexed" "yes,no")])
9311 ;; This is an unconditional pattern; needed for stack allocation, even
9312 ;; if the user passes -mno-update.
9313 (define_insn "movsi_update_stack"
9314   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9315                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9316         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9317    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9318         (plus:SI (match_dup 1) (match_dup 2)))]
9319   "TARGET_32BIT"
9320   "@
9321    stwux %3,%0,%2
9322    stwu %3,%2(%0)"
9323   [(set_attr "type" "store")
9324    (set_attr "update" "yes")
9325    (set_attr "indexed" "yes,no")])
9327 (define_insn "*movhi_update1"
9328   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9329         (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9330                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9331    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9332         (plus:P (match_dup 1) (match_dup 2)))]
9333   "TARGET_UPDATE
9334    && (!avoiding_indexed_address_p (HImode)
9335        || !gpc_reg_operand (operands[2], SImode))"
9336   "@
9337    lhzux %3,%0,%2
9338    lhzu %3,%2(%0)"
9339   [(set_attr "type" "load")
9340    (set_attr "update" "yes")
9341    (set_attr "indexed" "yes,no")])
9343 (define_insn "*movhi_update2"
9344   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9345         (zero_extend:EXTHI
9346          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9347                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9348    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9349         (plus:P (match_dup 1) (match_dup 2)))]
9350   "TARGET_UPDATE
9351    && (!avoiding_indexed_address_p (HImode)
9352        || !gpc_reg_operand (operands[2], Pmode))"
9353   "@
9354    lhzux %3,%0,%2
9355    lhzu %3,%2(%0)"
9356   [(set_attr "type" "load")
9357    (set_attr "update" "yes")
9358    (set_attr "indexed" "yes,no")])
9360 (define_insn "*movhi_update3"
9361   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9362         (sign_extend:EXTHI
9363          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9364                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9365    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9366         (plus:P (match_dup 1) (match_dup 2)))]
9367   "TARGET_UPDATE
9368    && !(avoiding_indexed_address_p (HImode)
9369         && gpc_reg_operand (operands[2], Pmode))"
9370   "@
9371    lhaux %3,%0,%2
9372    lhau %3,%2(%0)"
9373   [(set_attr "type" "load")
9374    (set_attr "sign_extend" "yes")
9375    (set_attr "update" "yes")
9376    (set_attr "indexed" "yes,no")])
9378 (define_insn "*movhi_update4"
9379   [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9380                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9381         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9382    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9383         (plus:P (match_dup 1) (match_dup 2)))]
9384   "TARGET_UPDATE
9385    && (!avoiding_indexed_address_p (HImode)
9386        || !gpc_reg_operand (operands[2], Pmode))"
9387   "@
9388    sthux %3,%0,%2
9389    sthu %3,%2(%0)"
9390   [(set_attr "type" "store")
9391    (set_attr "update" "yes")
9392    (set_attr "indexed" "yes,no")])
9394 (define_insn "*movqi_update1"
9395   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9396         (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9397                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9398    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9399         (plus:P (match_dup 1) (match_dup 2)))]
9400   "TARGET_UPDATE
9401    && (!avoiding_indexed_address_p (QImode)
9402        || !gpc_reg_operand (operands[2], Pmode))"
9403   "@
9404    lbzux %3,%0,%2
9405    lbzu %3,%2(%0)"
9406   [(set_attr "type" "load")
9407    (set_attr "update" "yes")
9408    (set_attr "indexed" "yes,no")])
9410 (define_insn "*movqi_update2"
9411   [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9412         (zero_extend:EXTQI
9413          (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9414                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9415    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9416         (plus:P (match_dup 1) (match_dup 2)))]
9417   "TARGET_UPDATE
9418    && (!avoiding_indexed_address_p (QImode)
9419        || !gpc_reg_operand (operands[2], Pmode))"
9420   "@
9421    lbzux %3,%0,%2
9422    lbzu %3,%2(%0)"
9423   [(set_attr "type" "load")
9424    (set_attr "update" "yes")
9425    (set_attr "indexed" "yes,no")])
9427 (define_insn "*movqi_update3"
9428   [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9429                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9430         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9431    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9432         (plus:P (match_dup 1) (match_dup 2)))]
9433   "TARGET_UPDATE
9434    && (!avoiding_indexed_address_p (QImode)
9435        || !gpc_reg_operand (operands[2], Pmode))"
9436   "@
9437    stbux %3,%0,%2
9438    stbu %3,%2(%0)"
9439   [(set_attr "type" "store")
9440    (set_attr "update" "yes")
9441    (set_attr "indexed" "yes,no")])
9443 (define_insn "*mov<SFDF:mode>_update1"
9444   [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9445         (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9446                           (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9447    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9448         (plus:P (match_dup 1) (match_dup 2)))]
9449   "TARGET_HARD_FLOAT && TARGET_UPDATE
9450    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9451        || !gpc_reg_operand (operands[2], Pmode))"
9452   "@
9453    lf<sd>ux %3,%0,%2
9454    lf<sd>u %3,%2(%0)"
9455   [(set_attr "type" "fpload")
9456    (set_attr "update" "yes")
9457    (set_attr "indexed" "yes,no")
9458    (set_attr "size" "<SFDF:bits>")])
9460 (define_insn "*mov<SFDF:mode>_update2"
9461   [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9462                           (match_operand:P 2 "reg_or_short_operand" "r,I")))
9463         (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9464    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9465         (plus:P (match_dup 1) (match_dup 2)))]
9466   "TARGET_HARD_FLOAT && TARGET_UPDATE
9467    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9468        || !gpc_reg_operand (operands[2], Pmode))"
9469   "@
9470    stf<sd>ux %3,%0,%2
9471    stf<sd>u %3,%2(%0)"
9472   [(set_attr "type" "fpstore")
9473    (set_attr "update" "yes")
9474    (set_attr "indexed" "yes,no")
9475    (set_attr "size" "<SFDF:bits>")])
9477 (define_insn "*movsf_update3"
9478   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9479         (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9480                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9481    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9482         (plus:P (match_dup 1) (match_dup 2)))]
9483   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9484    && (!avoiding_indexed_address_p (SFmode)
9485        || !gpc_reg_operand (operands[2], Pmode))"
9486   "@
9487    lwzux %3,%0,%2
9488    lwzu %3,%2(%0)"
9489   [(set_attr "type" "load")
9490    (set_attr "update" "yes")
9491    (set_attr "indexed" "yes,no")])
9493 (define_insn "*movsf_update4"
9494   [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9495                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9496         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9497    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9498         (plus:P (match_dup 1) (match_dup 2)))]
9499   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9500    && (!avoiding_indexed_address_p (SFmode)
9501        || !gpc_reg_operand (operands[2], Pmode))"
9502   "@
9503    stwux %3,%0,%2
9504    stwu %3,%2(%0)"
9505   [(set_attr "type" "store")
9506    (set_attr "update" "yes")
9507    (set_attr "indexed" "yes,no")])
9510 ;; After inserting conditional returns we can sometimes have
9511 ;; unnecessary register moves.  Unfortunately we cannot have a
9512 ;; modeless peephole here, because some single SImode sets have early
9513 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9514 ;; sequences, using get_attr_length here will smash the operands
9515 ;; array.  Neither is there an early_cobbler_p predicate.
9516 ;; Also this optimization interferes with scalars going into
9517 ;; altivec registers (the code does reloading through the FPRs).
9518 (define_peephole2
9519   [(set (match_operand:DF 0 "gpc_reg_operand")
9520         (match_operand:DF 1 "any_operand"))
9521    (set (match_operand:DF 2 "gpc_reg_operand")
9522         (match_dup 0))]
9523   "!TARGET_VSX
9524    && peep2_reg_dead_p (2, operands[0])"
9525   [(set (match_dup 2) (match_dup 1))])
9527 (define_peephole2
9528   [(set (match_operand:SF 0 "gpc_reg_operand")
9529         (match_operand:SF 1 "any_operand"))
9530    (set (match_operand:SF 2 "gpc_reg_operand")
9531         (match_dup 0))]
9532   "!TARGET_P8_VECTOR
9533    && peep2_reg_dead_p (2, operands[0])"
9534   [(set (match_dup 2) (match_dup 1))])
9537 ;; TLS support.
9539 (define_insn "*tls_gd_pcrel<bits>"
9540   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9541         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9542                    (const_int 0)]
9543                   UNSPEC_TLSGD))]
9544   "HAVE_AS_TLS && TARGET_ELF"
9545   "la %0,%1@got@tlsgd@pcrel"
9546   [(set_attr "prefixed" "yes")])
9548 (define_insn_and_split "*tls_gd<bits>"
9549   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9550         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9551                    (match_operand:P 2 "gpc_reg_operand" "b")]
9552                   UNSPEC_TLSGD))]
9553   "HAVE_AS_TLS && TARGET_ELF"
9554   "addi %0,%2,%1@got@tlsgd"
9555   "&& TARGET_CMODEL != CMODEL_SMALL"
9556   [(set (match_dup 3)
9557         (high:P
9558             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9559    (set (match_dup 0)
9560         (lo_sum:P (match_dup 3)
9561             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9563   operands[3] = gen_reg_rtx (<MODE>mode);
9565   [(set (attr "length")
9566      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9567                    (const_int 8)
9568                    (const_int 4)))])
9570 (define_insn "*tls_gd_high<bits>"
9571   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9572      (high:P
9573        (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9574                   (match_operand:P 2 "gpc_reg_operand" "b")]
9575                  UNSPEC_TLSGD)))]
9576   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9577   "addis %0,%2,%1@got@tlsgd@ha")
9579 (define_insn "*tls_gd_low<bits>"
9580   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9581      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9582        (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9583                   (match_operand:P 3 "gpc_reg_operand" "b")]
9584                  UNSPEC_TLSGD)))]
9585   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9586   "addi %0,%1,%2@got@tlsgd@l")
9588 (define_insn "*tls_ld_pcrel<bits>"
9589   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9590         (unspec:P [(const_int 0)]
9591                   UNSPEC_TLSLD))]
9592   "HAVE_AS_TLS && TARGET_ELF"
9593   "la %0,%&@got@tlsld@pcrel"
9594   [(set_attr "prefixed" "yes")])
9596 (define_insn_and_split "*tls_ld<bits>"
9597   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9598         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9599                   UNSPEC_TLSLD))]
9600   "HAVE_AS_TLS && TARGET_ELF"
9601   "addi %0,%1,%&@got@tlsld"
9602   "&& TARGET_CMODEL != CMODEL_SMALL"
9603   [(set (match_dup 2)
9604         (high:P
9605             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9606    (set (match_dup 0)
9607         (lo_sum:P (match_dup 2)
9608             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9610   operands[2] = gen_reg_rtx (<MODE>mode);
9612   [(set (attr "length")
9613      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9614                    (const_int 8)
9615                    (const_int 4)))])
9617 (define_insn "*tls_ld_high<bits>"
9618   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9619      (high:P
9620        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9621                  UNSPEC_TLSLD)))]
9622   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9623   "addis %0,%1,%&@got@tlsld@ha")
9625 (define_insn "*tls_ld_low<bits>"
9626   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9627      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9628        (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9629                  UNSPEC_TLSLD)))]
9630   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9631   "addi %0,%1,%&@got@tlsld@l")
9633 (define_insn "tls_dtprel_<bits>"
9634   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9635         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9636                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9637                   UNSPEC_TLSDTPREL))]
9638   "HAVE_AS_TLS"
9639   "addi %0,%1,%2@dtprel"
9640   [(set (attr "prefixed")
9641         (if_then_else (match_test "rs6000_tls_size == 16")
9642                       (const_string "no")
9643                       (const_string "yes")))])
9645 (define_insn "tls_dtprel_ha_<bits>"
9646   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9647         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9648                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9649                   UNSPEC_TLSDTPRELHA))]
9650   "HAVE_AS_TLS"
9651   "addis %0,%1,%2@dtprel@ha")
9653 (define_insn "tls_dtprel_lo_<bits>"
9654   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9655         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9656                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9657                   UNSPEC_TLSDTPRELLO))]
9658   "HAVE_AS_TLS"
9659   "addi %0,%1,%2@dtprel@l")
9661 (define_insn_and_split "tls_got_dtprel_<bits>"
9662   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9663         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9664                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9665                   UNSPEC_TLSGOTDTPREL))]
9666   "HAVE_AS_TLS"
9667   "<ptrload> %0,%2@got@dtprel(%1)"
9668   "&& TARGET_CMODEL != CMODEL_SMALL"
9669   [(set (match_dup 3)
9670         (high:P
9671             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9672    (set (match_dup 0)
9673         (lo_sum:P (match_dup 3)
9674             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9676   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9678   [(set (attr "length")
9679      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9680                    (const_int 8)
9681                    (const_int 4)))])
9683 (define_insn "*tls_got_dtprel_high<bits>"
9684   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9685      (high:P
9686        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9687                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9688                  UNSPEC_TLSGOTDTPREL)))]
9689   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9690   "addis %0,%1,%2@got@dtprel@ha")
9692 (define_insn "*tls_got_dtprel_low<bits>"
9693   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9694      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9695          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9696                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9697                    UNSPEC_TLSGOTDTPREL)))]
9698   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9699   "<ptrload> %0,%2@got@dtprel@l(%1)")
9701 (define_insn "tls_tprel_<bits>"
9702   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9703         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9704                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9705                   UNSPEC_TLSTPREL))]
9706   "HAVE_AS_TLS"
9707   "addi %0,%1,%2@tprel"
9708   [(set (attr "prefixed")
9709         (if_then_else (match_test "rs6000_tls_size == 16")
9710                       (const_string "no")
9711                       (const_string "yes")))])
9713 (define_insn "tls_tprel_ha_<bits>"
9714   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9715         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9716                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9717                   UNSPEC_TLSTPRELHA))]
9718   "HAVE_AS_TLS"
9719   "addis %0,%1,%2@tprel@ha")
9721 (define_insn "tls_tprel_lo_<bits>"
9722   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9723         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9724                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9725                   UNSPEC_TLSTPRELLO))]
9726   "HAVE_AS_TLS"
9727   "addi %0,%1,%2@tprel@l")
9729 (define_insn "*tls_got_tprel_pcrel_<bits>"
9730   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9731         (unspec:P [(const_int 0)
9732                    (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9733                   UNSPEC_TLSGOTTPREL))]
9734   "HAVE_AS_TLS"
9735   "<ptrload> %0,%1@got@tprel@pcrel"
9736   [(set_attr "prefixed" "yes")])
9738 ;; "b" output constraint here and on tls_tls input to support linker tls
9739 ;; optimization.  The linker may edit the instructions emitted by a
9740 ;; tls_got_tprel/tls_tls pair to addis,addi.
9741 (define_insn_and_split "tls_got_tprel_<bits>"
9742   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9743         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9744                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9745                   UNSPEC_TLSGOTTPREL))]
9746   "HAVE_AS_TLS"
9747   "<ptrload> %0,%2@got@tprel(%1)"
9748   "&& TARGET_CMODEL != CMODEL_SMALL"
9749   [(set (match_dup 3)
9750         (high:P
9751             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9752    (set (match_dup 0)
9753         (lo_sum:P (match_dup 3)
9754             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9756   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9758   [(set (attr "length")
9759      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9760                    (const_int 8)
9761                    (const_int 4)))])
9763 (define_insn "*tls_got_tprel_high<bits>"
9764   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9765      (high:P
9766        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9767                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9768                  UNSPEC_TLSGOTTPREL)))]
9769   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9770   "addis %0,%1,%2@got@tprel@ha")
9772 (define_insn "*tls_got_tprel_low<bits>"
9773   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9774      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9775          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9776                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9777                    UNSPEC_TLSGOTTPREL)))]
9778   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9779   "<ptrload> %0,%2@got@tprel@l(%1)")
9781 (define_insn "tls_tls_pcrel_<bits>"
9782   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9783         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9784                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9785                   UNSPEC_TLSTLS_PCREL))]
9786   "TARGET_ELF && HAVE_AS_TLS"
9787   "add %0,%1,%2@tls@pcrel")
9789 (define_insn "tls_tls_<bits>"
9790   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9791         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9792                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9793                   UNSPEC_TLSTLS))]
9794   "TARGET_ELF && HAVE_AS_TLS"
9795   "add %0,%1,%2@tls")
9797 (define_expand "tls_get_tpointer"
9798   [(set (match_operand:SI 0 "gpc_reg_operand")
9799         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9800   "TARGET_XCOFF && HAVE_AS_TLS"
9802   emit_insn (gen_tls_get_tpointer_internal ());
9803   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9804   DONE;
9807 (define_insn "tls_get_tpointer_internal"
9808   [(set (reg:SI 3)
9809         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9810    (clobber (reg:SI LR_REGNO))]
9811   "TARGET_XCOFF && HAVE_AS_TLS"
9812   "bla __get_tpointer")
9814 (define_expand "tls_get_addr<mode>"
9815   [(set (match_operand:P 0 "gpc_reg_operand")
9816         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9817                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9818   "TARGET_XCOFF && HAVE_AS_TLS"
9820   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9821   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9822   emit_insn (gen_tls_get_addr_internal<mode> ());
9823   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9824   DONE;
9827 (define_insn "tls_get_addr_internal<mode>"
9828   [(set (reg:P 3)
9829         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9830    (clobber (reg:P 0))
9831    (clobber (reg:P 4))
9832    (clobber (reg:P 5))
9833    (clobber (reg:P 11))
9834    (clobber (reg:CC CR0_REGNO))
9835    (clobber (reg:P LR_REGNO))]
9836   "TARGET_XCOFF && HAVE_AS_TLS"
9837   "bla __tls_get_addr")
9839 ;; Next come insns related to the calling sequence.
9841 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9842 ;; We move the back-chain and decrement the stack pointer.
9844 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9845 ;; constant alloca, using that predicate will force the generic code to put
9846 ;; the constant size into a register before calling the expander.
9848 ;; As a result the expander would not have the constant size information
9849 ;; in those cases and would have to generate less efficient code.
9851 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9852 ;; the constant size.  The value is forced into a register if necessary.
9854 (define_expand "allocate_stack"
9855   [(set (match_operand 0 "gpc_reg_operand")
9856         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9857    (set (reg 1)
9858         (minus (reg 1) (match_dup 1)))]
9859   ""
9861   rtx chain = gen_reg_rtx (Pmode);
9862   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9863   rtx neg_op0;
9864   rtx insn, par, set, mem;
9866   /* By allowing reg_or_cint_operand as the predicate we can get
9867      better code for stack-clash-protection because we do not lose
9868      size information.  But the rest of the code expects the operand
9869      to be reg_or_short_operand.  If it isn't, then force it into
9870      a register.  */
9871   rtx orig_op1 = operands[1];
9872   if (!reg_or_short_operand (operands[1], Pmode))
9873     operands[1] = force_reg (Pmode, operands[1]);
9875   emit_move_insn (chain, stack_bot);
9877   /* Check stack bounds if necessary.  */
9878   if (crtl->limit_stack)
9879     {
9880       rtx available;
9881       available = expand_binop (Pmode, sub_optab,
9882                                 stack_pointer_rtx, stack_limit_rtx,
9883                                 NULL_RTX, 1, OPTAB_WIDEN);
9884       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9885     }
9887   /* Allocate and probe if requested.
9888      This may look similar to the loop we use for prologue allocations,
9889      but it is critically different.  For the former we know the loop
9890      will iterate, but do not know that generally here.  The former
9891      uses that knowledge to rotate the loop.  Combining them would be
9892      possible with some performance cost.  */
9893   if (flag_stack_clash_protection)
9894     {
9895       rtx rounded_size, last_addr, residual;
9896       HOST_WIDE_INT probe_interval;
9897       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9898                                                 &residual, &probe_interval,
9899                                                 orig_op1);
9900       
9901       /* We do occasionally get in here with constant sizes, we might
9902          as well do a reasonable job when we obviously can.  */
9903       if (rounded_size != const0_rtx)
9904         {
9905           rtx loop_lab, end_loop;
9906           bool rotated = CONST_INT_P (rounded_size);
9907           rtx update = GEN_INT (-probe_interval);
9908           if (probe_interval > 32768)
9909             update = force_reg (Pmode, update);
9911           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9912                                                         last_addr, rotated);
9914           if (TARGET_32BIT)
9915             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9916                                                stack_pointer_rtx,
9917                                                update, chain));
9918           else
9919             emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9920                                                stack_pointer_rtx,
9921                                                update, chain));
9922           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9923                                                       last_addr, rotated);
9924         }
9926       /* Now handle residuals.  We just have to set operands[1] correctly
9927          and let the rest of the expander run.  */
9928       operands[1] = residual;
9929     }
9931   if (!(CONST_INT_P (operands[1])
9932         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9933     {
9934       operands[1] = force_reg (Pmode, operands[1]);
9935       neg_op0 = gen_reg_rtx (Pmode);
9936       emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9937     }
9938   else
9939     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9941   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9942                                        : gen_movdi_update_stack))
9943                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9944                          chain));
9945   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9946      it now and set the alias set/attributes. The above gen_*_update
9947      calls will generate a PARALLEL with the MEM set being the first
9948      operation. */
9949   par = PATTERN (insn);
9950   gcc_assert (GET_CODE (par) == PARALLEL);
9951   set = XVECEXP (par, 0, 0);
9952   gcc_assert (GET_CODE (set) == SET);
9953   mem = SET_DEST (set);
9954   gcc_assert (MEM_P (mem));
9955   MEM_NOTRAP_P (mem) = 1;
9956   set_mem_alias_set (mem, get_frame_alias_set ());
9958   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9959   DONE;
9962 ;; These patterns say how to save and restore the stack pointer.  We need not
9963 ;; save the stack pointer at function level since we are careful to
9964 ;; preserve the backchain.  At block level, we have to restore the backchain
9965 ;; when we restore the stack pointer.
9967 ;; For nonlocal gotos, we must save both the stack pointer and its
9968 ;; backchain and restore both.  Note that in the nonlocal case, the
9969 ;; save area is a memory location.
9971 (define_expand "save_stack_function"
9972   [(match_operand 0 "any_operand")
9973    (match_operand 1 "any_operand")]
9974   ""
9975   "DONE;")
9977 (define_expand "restore_stack_function"
9978   [(match_operand 0 "any_operand")
9979    (match_operand 1 "any_operand")]
9980   ""
9981   "DONE;")
9983 ;; Adjust stack pointer (op0) to a new value (op1).
9984 ;; First copy old stack backchain to new location, and ensure that the
9985 ;; scheduler won't reorder the sp assignment before the backchain write.
9986 (define_expand "restore_stack_block"
9987   [(set (match_dup 2) (match_dup 3))
9988    (set (match_dup 4) (match_dup 2))
9989    (match_dup 5)
9990    (set (match_operand 0 "register_operand")
9991         (match_operand 1 "register_operand"))]
9992   ""
9994   rtvec p;
9996   operands[1] = force_reg (Pmode, operands[1]);
9997   operands[2] = gen_reg_rtx (Pmode);
9998   operands[3] = gen_frame_mem (Pmode, operands[0]);
9999   operands[4] = gen_frame_mem (Pmode, operands[1]);
10000   p = rtvec_alloc (1);
10001   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10002                                   const0_rtx);
10003   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10006 (define_expand "save_stack_nonlocal"
10007   [(set (match_dup 3) (match_dup 4))
10008    (set (match_operand 0 "memory_operand") (match_dup 3))
10009    (set (match_dup 2) (match_operand 1 "register_operand"))]
10010   ""
10012   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10014   /* Copy the backchain to the first word, sp to the second.  */
10015   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10016   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10017   operands[3] = gen_reg_rtx (Pmode);
10018   operands[4] = gen_frame_mem (Pmode, operands[1]);
10021 (define_expand "restore_stack_nonlocal"
10022   [(set (match_dup 2) (match_operand 1 "memory_operand"))
10023    (set (match_dup 3) (match_dup 4))
10024    (set (match_dup 5) (match_dup 2))
10025    (match_dup 6)
10026    (set (match_operand 0 "register_operand") (match_dup 3))]
10027   ""
10029   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10030   rtvec p;
10032   /* Restore the backchain from the first word, sp from the second.  */
10033   operands[2] = gen_reg_rtx (Pmode);
10034   operands[3] = gen_reg_rtx (Pmode);
10035   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10036   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10037   operands[5] = gen_frame_mem (Pmode, operands[3]);
10038   p = rtvec_alloc (1);
10039   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10040                                   const0_rtx);
10041   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10044 ;; Load up a PC-relative address.  Print_operand_address will append a @pcrel
10045 ;; to the symbol or label.
10046 (define_insn "*pcrel_local_addr"
10047   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10048         (match_operand:DI 1 "pcrel_local_address"))]
10049   "TARGET_PCREL"
10050   "la %0,%a1"
10051   [(set_attr "prefixed" "yes")])
10053 ;; Load up a PC-relative address to an external symbol.  If the symbol and the
10054 ;; program are both defined in the main program, the linker will optimize this
10055 ;; to a PADDI.  Otherwise, it will create a GOT address that is relocated by
10056 ;; the dynamic linker and loaded up.  Print_operand_address will append a
10057 ;; @got@pcrel to the symbol.
10058 (define_insn "*pcrel_extern_addr"
10059   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10060         (match_operand:DI 1 "pcrel_external_address"))]
10061   "TARGET_PCREL"
10062   "ld %0,%a1"
10063   [(set_attr "prefixed" "yes")
10064    (set_attr "type" "load")])
10066 ;; TOC register handling.
10068 ;; Code to initialize the TOC register...
10070 (define_insn "load_toc_aix_si"
10071   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10072                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10073               (use (reg:SI 2))])]
10074   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10076   char buf[30];
10077   extern int need_toc_init;
10078   need_toc_init = 1;
10079   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10080   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10081   operands[2] = gen_rtx_REG (Pmode, 2);
10082   return "lwz %0,%1(%2)";
10084   [(set_attr "type" "load")
10085    (set_attr "update" "no")
10086    (set_attr "indexed" "no")])
10088 (define_insn "load_toc_aix_di"
10089   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10090                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10091               (use (reg:DI 2))])]
10092   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10094   char buf[30];
10095   extern int need_toc_init;
10096   need_toc_init = 1;
10097   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10098                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10099   if (TARGET_ELF)
10100     strcat (buf, "@toc");
10101   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10102   operands[2] = gen_rtx_REG (Pmode, 2);
10103   return "ld %0,%1(%2)";
10105   [(set_attr "type" "load")
10106    (set_attr "update" "no")
10107    (set_attr "indexed" "no")])
10109 (define_insn "load_toc_v4_pic_si"
10110   [(set (reg:SI LR_REGNO)
10111         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10112   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10113   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10114   [(set_attr "type" "branch")])
10116 (define_expand "load_toc_v4_PIC_1"
10117   [(parallel [(set (reg:SI LR_REGNO)
10118                    (match_operand:SI 0 "immediate_operand" "s"))
10119               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10120   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10121    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10122   "")
10124 (define_insn "load_toc_v4_PIC_1_normal"
10125   [(set (reg:SI LR_REGNO)
10126         (match_operand:SI 0 "immediate_operand" "s"))
10127    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10128   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10129    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10130   "bcl 20,31,%0\n%0:"
10131   [(set_attr "type" "branch")
10132    (set_attr "cannot_copy" "yes")])
10134 (define_insn "load_toc_v4_PIC_1_476"
10135   [(set (reg:SI LR_REGNO)
10136         (match_operand:SI 0 "immediate_operand" "s"))
10137    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10138   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10139    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10141   char name[32];
10142   static char templ[32];
10144   get_ppc476_thunk_name (name);
10145   sprintf (templ, "bl %s\n%%0:", name);
10146   return templ;
10148   [(set_attr "type" "branch")
10149    (set_attr "cannot_copy" "yes")])
10151 (define_expand "load_toc_v4_PIC_1b"
10152   [(parallel [(set (reg:SI LR_REGNO)
10153                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10154                                (label_ref (match_operand 1 ""))]
10155                            UNSPEC_TOCPTR))
10156               (match_dup 1)])]
10157   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10158   "")
10160 (define_insn "load_toc_v4_PIC_1b_normal"
10161   [(set (reg:SI LR_REGNO)
10162         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10163                     (label_ref (match_operand 1 "" ""))]
10164                 UNSPEC_TOCPTR))
10165    (match_dup 1)]
10166   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10167   "bcl 20,31,$+8\;.long %0-$"
10168   [(set_attr "type" "branch")
10169    (set_attr "length" "8")])
10171 (define_insn "load_toc_v4_PIC_1b_476"
10172   [(set (reg:SI LR_REGNO)
10173         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10174                     (label_ref (match_operand 1 "" ""))]
10175                 UNSPEC_TOCPTR))
10176    (match_dup 1)]
10177   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10179   char name[32];
10180   static char templ[32];
10182   get_ppc476_thunk_name (name);
10183   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10184   return templ;
10186   [(set_attr "type" "branch")
10187    (set_attr "length" "16")])
10189 (define_insn "load_toc_v4_PIC_2"
10190   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10191         (mem:SI (plus:SI
10192                   (match_operand:SI 1 "gpc_reg_operand" "b")
10193                   (const
10194                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10195                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10196   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10197   "lwz %0,%2-%3(%1)"
10198   [(set_attr "type" "load")])
10200 (define_insn "load_toc_v4_PIC_3b"
10201   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10202         (plus:SI
10203           (match_operand:SI 1 "gpc_reg_operand" "b")
10204           (high:SI
10205             (const
10206               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10207                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10208   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10209   "addis %0,%1,%2-%3@ha")
10211 (define_insn "load_toc_v4_PIC_3c"
10212   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10213         (lo_sum:SI
10214           (match_operand:SI 1 "gpc_reg_operand" "b")
10215           (const
10216             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10217                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10218   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10219   "addi %0,%1,%2-%3@l")
10221 ;; If the TOC is shared over a translation unit, as happens with all
10222 ;; the kinds of PIC that we support, we need to restore the TOC
10223 ;; pointer only when jumping over units of translation.
10224 ;; On Darwin, we need to reload the picbase.
10226 (define_expand "builtin_setjmp_receiver"
10227   [(use (label_ref (match_operand 0 "")))]
10228   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10229    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10230    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10232 #if TARGET_MACHO
10233   if (DEFAULT_ABI == ABI_DARWIN)
10234     {
10235       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10236       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10237       rtx tmplabrtx;
10238       char tmplab[20];
10240       crtl->uses_pic_offset_table = 1;
10241       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10242                                   CODE_LABEL_NUMBER (operands[0]));
10243       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10245       emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10246       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10247       emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10248                                         picrtx, tmplabrtx));
10249     }
10250   else
10251 #endif
10252     rs6000_emit_load_toc_table (FALSE);
10253   DONE;
10256 ;; Largetoc support
10257 (define_insn "*largetoc_high"
10258   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10259         (high:DI
10260           (unspec [(match_operand:DI 1 "" "")
10261                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10262                   UNSPEC_TOCREL)))]
10263    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10264    "addis %0,%2,%1@toc@ha")
10266 (define_insn "*largetoc_high_aix<mode>"
10267   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10268         (high:P
10269           (unspec [(match_operand:P 1 "" "")
10270                    (match_operand:P 2 "gpc_reg_operand" "b")]
10271                   UNSPEC_TOCREL)))]
10272    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10273    "addis %0,%1@u(%2)")
10275 (define_insn "*largetoc_high_plus"
10276   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10277         (high:DI
10278           (plus:DI
10279             (unspec [(match_operand:DI 1 "" "")
10280                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10281                     UNSPEC_TOCREL)
10282             (match_operand:DI 3 "add_cint_operand" "n"))))]
10283    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10284    "addis %0,%2,%1+%3@toc@ha")
10286 (define_insn "*largetoc_high_plus_aix<mode>"
10287   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10288         (high:P
10289           (plus:P
10290             (unspec [(match_operand:P 1 "" "")
10291                      (match_operand:P 2 "gpc_reg_operand" "b")]
10292                     UNSPEC_TOCREL)
10293             (match_operand:P 3 "add_cint_operand" "n"))))]
10294    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10295    "addis %0,%1+%3@u(%2)")
10297 (define_insn "*largetoc_low"
10298   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10299         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10300                    (match_operand:DI 2 "" "")))]
10301    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10302    "addi %0,%1,%2@l")
10304 (define_insn "*largetoc_low_aix<mode>"
10305   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10306         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10307                    (match_operand:P 2 "" "")))]
10308    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10309    "la %0,%2@l(%1)")
10311 (define_insn_and_split "*tocref<mode>"
10312   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10313         (match_operand:P 1 "small_toc_ref" "R"))]
10314    "TARGET_TOC"
10315    "la %0,%a1"
10316    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10317   [(set (match_dup 0) (high:P (match_dup 1)))
10318    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10320 ;; Elf specific ways of loading addresses for non-PIC code.
10321 ;; The output of this could be r0, but we make a very strong
10322 ;; preference for a base register because it will usually
10323 ;; be needed there.
10324 (define_insn "elf_high"
10325   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10326         (high:SI (match_operand 1 "" "")))]
10327   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10328   "lis %0,%1@ha")
10330 (define_insn "elf_low"
10331   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10332         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10333                    (match_operand 2 "" "")))]
10334    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10335    "la %0,%2@l(%1)")
10337 (define_insn "*pltseq_tocsave_<mode>"
10338   [(set (match_operand:P 0 "memory_operand" "=m")
10339         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10340                    (match_operand:P 2 "symbol_ref_operand" "s")
10341                    (match_operand:P 3 "" "")]
10342                   UNSPEC_PLTSEQ))]
10343   "TARGET_PLTSEQ
10344    && DEFAULT_ABI == ABI_ELFv2"
10346   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10349 (define_insn "*pltseq_plt16_ha_<mode>"
10350   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10351         (unspec:P [(match_operand:P 1 "" "")
10352                    (match_operand:P 2 "symbol_ref_operand" "s")
10353                    (match_operand:P 3 "" "")]
10354                   UNSPEC_PLT16_HA))]
10355   "TARGET_PLTSEQ"
10357   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10360 (define_insn "*pltseq_plt16_lo_<mode>"
10361   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10362         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10363                    (match_operand:P 2 "symbol_ref_operand" "s")
10364                    (match_operand:P 3 "" "")]
10365                   UNSPEC_PLT16_LO))]
10366   "TARGET_PLTSEQ"
10368   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10370   [(set_attr "type" "load")])
10372 (define_insn "*pltseq_mtctr_<mode>"
10373   [(set (match_operand:P 0 "register_operand" "=c")
10374         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10375                    (match_operand:P 2 "symbol_ref_operand" "s")
10376                    (match_operand:P 3 "" "")]
10377                   UNSPEC_PLTSEQ))]
10378   "TARGET_PLTSEQ"
10380   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10383 (define_insn "*pltseq_plt_pcrel<mode>"
10384   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10385         (unspec:P [(match_operand:P 1 "" "")
10386                    (match_operand:P 2 "symbol_ref_operand" "s")
10387                    (match_operand:P 3 "" "")]
10388                   UNSPEC_PLT_PCREL))]
10389   "HAVE_AS_PLTSEQ && TARGET_ELF
10390    && rs6000_pcrel_p (cfun)"
10392   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10394   [(set_attr "type" "load")
10395    (set_attr "length" "12")])
10397 ;; Call and call_value insns
10398 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10399 (define_expand "call"
10400   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10401                     (match_operand 1 ""))
10402               (use (match_operand 2 ""))
10403               (clobber (reg:SI LR_REGNO))])]
10404   ""
10406 #if TARGET_MACHO
10407   if (MACHOPIC_INDIRECT)
10408     operands[0] = machopic_indirect_call_target (operands[0]);
10409 #endif
10411   gcc_assert (MEM_P (operands[0]));
10413   operands[0] = XEXP (operands[0], 0);
10415   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10416     rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10417   else if (DEFAULT_ABI == ABI_V4)
10418     rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10419   else if (DEFAULT_ABI == ABI_DARWIN)
10420     rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10421   else
10422     gcc_unreachable ();
10424   DONE;
10427 (define_expand "call_value"
10428   [(parallel [(set (match_operand 0 "")
10429                    (call (mem:SI (match_operand 1 "address_operand"))
10430                          (match_operand 2 "")))
10431               (use (match_operand 3 ""))
10432               (clobber (reg:SI LR_REGNO))])]
10433   ""
10435 #if TARGET_MACHO
10436   if (MACHOPIC_INDIRECT)
10437     operands[1] = machopic_indirect_call_target (operands[1]);
10438 #endif
10440   gcc_assert (MEM_P (operands[1]));
10442   operands[1] = XEXP (operands[1], 0);
10444   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10445     rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10446   else if (DEFAULT_ABI == ABI_V4)
10447     rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10448   else if (DEFAULT_ABI == ABI_DARWIN)
10449     rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10450   else
10451     gcc_unreachable ();
10453   DONE;
10456 ;; Call to function in current module.  No TOC pointer reload needed.
10457 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10458 ;; either the function was not prototyped, or it was prototyped as a
10459 ;; variable argument function.  It is > 0 if FP registers were passed
10460 ;; and < 0 if they were not.
10462 (define_insn "*call_local32"
10463   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10464          (match_operand 1))
10465    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10466    (clobber (reg:SI LR_REGNO))]
10467   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10469   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10470     output_asm_insn ("crxor 6,6,6", operands);
10472   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10473     output_asm_insn ("creqv 6,6,6", operands);
10475   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10477   [(set_attr "type" "branch")
10478    (set_attr "length" "4,8")])
10480 (define_insn "*call_local64"
10481   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10482          (match_operand 1))
10483    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10484    (clobber (reg:DI LR_REGNO))]
10485   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10487   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10488     output_asm_insn ("crxor 6,6,6", operands);
10490   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10491     output_asm_insn ("creqv 6,6,6", operands);
10493   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10495   [(set_attr "type" "branch")
10496    (set_attr "length" "4,8")])
10498 (define_insn "*call_value_local32"
10499   [(set (match_operand 0 "" "")
10500         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10501               (match_operand 2)))
10502    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10503    (clobber (reg:SI LR_REGNO))]
10504   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10506   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10507     output_asm_insn ("crxor 6,6,6", operands);
10509   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10510     output_asm_insn ("creqv 6,6,6", operands);
10512   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10514   [(set_attr "type" "branch")
10515    (set_attr "length" "4,8")])
10518 (define_insn "*call_value_local64"
10519   [(set (match_operand 0 "" "")
10520         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10521               (match_operand 2)))
10522    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10523    (clobber (reg:DI LR_REGNO))]
10524   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10526   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10527     output_asm_insn ("crxor 6,6,6", operands);
10529   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10530     output_asm_insn ("creqv 6,6,6", operands);
10532   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10534   [(set_attr "type" "branch")
10535    (set_attr "length" "4,8")])
10538 ;; A function pointer under System V is just a normal pointer
10539 ;; operands[0] is the function pointer
10540 ;; operands[1] is the tls call arg
10541 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10542 ;; which indicates how to set cr1
10544 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10545   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10546          (match_operand 1))
10547    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10548    (clobber (reg:P LR_REGNO))]
10549   "DEFAULT_ABI == ABI_V4
10550    || DEFAULT_ABI == ABI_DARWIN"
10552   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10553     output_asm_insn ("crxor 6,6,6", operands);
10555   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10556     output_asm_insn ("creqv 6,6,6", operands);
10558   return rs6000_indirect_call_template (operands, 0);
10560   [(set_attr "type" "jmpreg")
10561    (set (attr "length")
10562         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10563                          (match_test "which_alternative != 1"))
10564                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10565                   (const_string "12")
10566                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10567                          (match_test "which_alternative != 1"))
10568                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10569                   (const_string "8")]
10570               (const_string "4")))])
10572 (define_insn "*call_nonlocal_sysv<mode>"
10573   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10574          (match_operand 1))
10575    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10576    (clobber (reg:P LR_REGNO))]
10577   "(DEFAULT_ABI == ABI_DARWIN
10578    || (DEFAULT_ABI == ABI_V4
10579        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10581   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10582     output_asm_insn ("crxor 6,6,6", operands);
10584   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10585     output_asm_insn ("creqv 6,6,6", operands);
10587   return rs6000_call_template (operands, 0);
10589   [(set_attr "type" "branch,branch")
10590    (set_attr "length" "4,8")])
10592 (define_insn "*call_nonlocal_sysv_secure<mode>"
10593   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10594          (match_operand 1))
10595    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10596    (use (match_operand:SI 3 "register_operand" "r,r"))
10597    (clobber (reg:P LR_REGNO))]
10598   "(DEFAULT_ABI == ABI_V4
10599     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10600     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10602   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10603     output_asm_insn ("crxor 6,6,6", operands);
10605   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10606     output_asm_insn ("creqv 6,6,6", operands);
10608   return rs6000_call_template (operands, 0);
10610   [(set_attr "type" "branch,branch")
10611    (set_attr "length" "4,8")])
10613 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10614   [(set (match_operand 0 "" "")
10615         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10616               (match_operand:P 2 "unspec_tls" "")))
10617    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10618    (clobber (reg:P LR_REGNO))]
10619   "DEFAULT_ABI == ABI_V4
10620    || DEFAULT_ABI == ABI_DARWIN"
10622   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10623     output_asm_insn ("crxor 6,6,6", operands);
10625   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10626     output_asm_insn ("creqv 6,6,6", operands);
10628   return rs6000_indirect_call_template (operands, 1);
10630   [(set_attr "type" "jmpreg")
10631    (set (attr "length")
10632         (plus
10633           (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10634             (const_int 4)
10635             (const_int 0))
10636           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10637                              (match_test "which_alternative != 1"))
10638             (const_int 8)
10639             (const_int 4))))])
10641 (define_insn "*call_value_nonlocal_sysv<mode>"
10642   [(set (match_operand 0 "" "")
10643         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10644               (match_operand:P 2 "unspec_tls" "")))
10645    (use (match_operand:SI 3 "immediate_operand" "n"))
10646    (clobber (reg:P LR_REGNO))]
10647   "(DEFAULT_ABI == ABI_DARWIN
10648     || (DEFAULT_ABI == ABI_V4
10649         && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10651   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10652     output_asm_insn ("crxor 6,6,6", operands);
10654   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10655     output_asm_insn ("creqv 6,6,6", operands);
10657   return rs6000_call_template (operands, 1);
10659   [(set_attr "type" "branch")
10660    (set (attr "length")
10661         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10662           (const_int 8)
10663           (const_int 4)))])
10665 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10666   [(set (match_operand 0 "" "")
10667         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10668               (match_operand:P 2 "unspec_tls" "")))
10669    (use (match_operand:SI 3 "immediate_operand" "n"))
10670    (use (match_operand:SI 4 "register_operand" "r"))
10671    (clobber (reg:P LR_REGNO))]
10672   "(DEFAULT_ABI == ABI_V4
10673     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10674     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10676   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10677     output_asm_insn ("crxor 6,6,6", operands);
10679   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10680     output_asm_insn ("creqv 6,6,6", operands);
10682   return rs6000_call_template (operands, 1);
10684   [(set_attr "type" "branch")
10685    (set (attr "length")
10686         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10687           (const_int 8)
10688           (const_int 4)))])
10690 ;; Call to AIX abi function in the same module.
10692 (define_insn "*call_local_aix<mode>"
10693   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10694          (match_operand 1))
10695    (clobber (reg:P LR_REGNO))]
10696   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10698   if (rs6000_pcrel_p (cfun))
10699     return "bl %z0@notoc";
10700   return "bl %z0";
10702   [(set_attr "type" "branch")])
10704 (define_insn "*call_value_local_aix<mode>"
10705   [(set (match_operand 0 "" "")
10706         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10707               (match_operand 2)))
10708    (clobber (reg:P LR_REGNO))]
10709   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10711   if (rs6000_pcrel_p (cfun))
10712     return "bl %z1@notoc";
10713   return "bl %z1";
10715   [(set_attr "type" "branch")])
10717 ;; Call to AIX abi function which may be in another module.
10718 ;; Restore the TOC pointer (r2) after the call.
10720 (define_insn "*call_nonlocal_aix<mode>"
10721   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10722          (match_operand 1))
10723    (clobber (reg:P LR_REGNO))]
10724   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10726   return rs6000_call_template (operands, 0);
10728   [(set_attr "type" "branch")
10729    (set (attr "length")
10730         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10731           (const_int 4)
10732           (const_int 8)))])
10734 (define_insn "*call_value_nonlocal_aix<mode>"
10735   [(set (match_operand 0 "" "")
10736         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10737               (match_operand:P 2 "unspec_tls" "")))
10738    (clobber (reg:P LR_REGNO))]
10739   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10741   return rs6000_call_template (operands, 1);
10743   [(set_attr "type" "branch")
10744    (set (attr "length")
10745         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10746             (const_int 4)
10747             (const_int 8)))])
10749 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10750 ;; Operand0 is the addresss of the function to call
10751 ;; Operand2 is the location in the function descriptor to load r2 from
10752 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10754 (define_insn "*call_indirect_aix<mode>"
10755   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10756          (match_operand 1))
10757    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10758    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10759    (clobber (reg:P LR_REGNO))]
10760   "DEFAULT_ABI == ABI_AIX"
10762   return rs6000_indirect_call_template (operands, 0);
10764   [(set_attr "type" "jmpreg")
10765    (set (attr "length")
10766         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10767                            (match_test "which_alternative != 1"))
10768                       (const_string "16")
10769                       (const_string "12")))])
10771 (define_insn "*call_value_indirect_aix<mode>"
10772   [(set (match_operand 0 "" "")
10773         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10774               (match_operand:P 2 "unspec_tls" "")))
10775    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10776    (set (reg:P TOC_REGNUM)
10777         (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10778                   UNSPEC_TOCSLOT))
10779    (clobber (reg:P LR_REGNO))]
10780   "DEFAULT_ABI == ABI_AIX"
10782   return rs6000_indirect_call_template (operands, 1);
10784   [(set_attr "type" "jmpreg")
10785    (set (attr "length")
10786         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10787                            (match_test "which_alternative != 1"))
10788             (const_string "16")
10789             (const_string "12")))])
10791 ;; Call to indirect functions with the ELFv2 ABI.
10792 ;; Operand0 is the addresss of the function to call
10793 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10795 (define_insn "*call_indirect_elfv2<mode>"
10796   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10797          (match_operand 1))
10798    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10799    (clobber (reg:P LR_REGNO))]
10800   "DEFAULT_ABI == ABI_ELFv2"
10802   return rs6000_indirect_call_template (operands, 0);
10804   [(set_attr "type" "jmpreg")
10805    (set (attr "length")
10806         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10807                            (match_test "which_alternative != 1"))
10808                       (const_string "12")
10809                       (const_string "8")))])
10811 (define_insn "*call_indirect_pcrel<mode>"
10812   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10813          (match_operand 1))
10814    (clobber (reg:P LR_REGNO))]
10815   "rs6000_pcrel_p (cfun)"
10817   return rs6000_indirect_call_template (operands, 0);
10819   [(set_attr "type" "jmpreg")
10820    (set (attr "length")
10821         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10822                            (match_test "which_alternative != 1"))
10823                       (const_string "8")
10824                       (const_string "4")))])
10826 (define_insn "*call_value_indirect_elfv2<mode>"
10827   [(set (match_operand 0 "" "")
10828         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10829               (match_operand:P 2 "unspec_tls" "")))
10830    (set (reg:P TOC_REGNUM)
10831         (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10832                   UNSPEC_TOCSLOT))
10833    (clobber (reg:P LR_REGNO))]
10834   "DEFAULT_ABI == ABI_ELFv2"
10836   return rs6000_indirect_call_template (operands, 1);
10838   [(set_attr "type" "jmpreg")
10839    (set (attr "length")
10840         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10841                            (match_test "which_alternative != 1"))
10842             (const_string "12")
10843             (const_string "8")))])
10845 (define_insn "*call_value_indirect_pcrel<mode>"
10846   [(set (match_operand 0 "" "")
10847         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10848               (match_operand:P 2 "unspec_tls" "")))
10849    (clobber (reg:P LR_REGNO))]
10850   "rs6000_pcrel_p (cfun)"
10852   return rs6000_indirect_call_template (operands, 1);
10854   [(set_attr "type" "jmpreg")
10855    (set (attr "length")
10856         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10857                            (match_test "which_alternative != 1"))
10858             (const_string "8")
10859             (const_string "4")))])
10861 ;; Call subroutine returning any type.
10862 (define_expand "untyped_call"
10863   [(parallel [(call (match_operand 0 "")
10864                     (const_int 0))
10865               (match_operand 1 "")
10866               (match_operand 2 "")])]
10867   ""
10869   int i;
10871   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10873   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10874     {
10875       rtx set = XVECEXP (operands[2], 0, i);
10876       emit_move_insn (SET_DEST (set), SET_SRC (set));
10877     }
10879   /* The optimizer does not know that the call sets the function value
10880      registers we stored in the result block.  We avoid problems by
10881      claiming that all hard registers are used and clobbered at this
10882      point.  */
10883   emit_insn (gen_blockage ());
10885   DONE;
10888 ;; sibling call patterns
10889 (define_expand "sibcall"
10890   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10891                     (match_operand 1 ""))
10892               (use (match_operand 2 ""))
10893               (simple_return)])]
10894   ""
10896 #if TARGET_MACHO
10897   if (MACHOPIC_INDIRECT)
10898     operands[0] = machopic_indirect_call_target (operands[0]);
10899 #endif
10901   gcc_assert (MEM_P (operands[0]));
10902   gcc_assert (CONST_INT_P (operands[1]));
10904   operands[0] = XEXP (operands[0], 0);
10906   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10907     rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10908   else if (DEFAULT_ABI == ABI_V4)
10909     rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10910   else if (DEFAULT_ABI == ABI_DARWIN)
10911     rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10912   else
10913     gcc_unreachable ();
10915   DONE;
10918 (define_expand "sibcall_value"
10919   [(parallel [(set (match_operand 0 "register_operand")
10920                 (call (mem:SI (match_operand 1 "address_operand"))
10921                       (match_operand 2 "")))
10922               (use (match_operand 3 ""))
10923               (simple_return)])]
10924   ""
10926 #if TARGET_MACHO
10927   if (MACHOPIC_INDIRECT)
10928     operands[1] = machopic_indirect_call_target (operands[1]);
10929 #endif
10931   gcc_assert (MEM_P (operands[1]));
10932   gcc_assert (CONST_INT_P (operands[2]));
10934   operands[1] = XEXP (operands[1], 0);
10936   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10937     rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10938   else if (DEFAULT_ABI == ABI_V4)
10939     rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10940   else if (DEFAULT_ABI == ABI_DARWIN)
10941     rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10942   else
10943     gcc_unreachable ();
10945   DONE;
10948 (define_insn "*sibcall_local32"
10949   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10950          (match_operand 1))
10951    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10952    (simple_return)]
10953   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10955   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10956     output_asm_insn ("crxor 6,6,6", operands);
10958   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10959     output_asm_insn ("creqv 6,6,6", operands);
10961   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10963   [(set_attr "type" "branch")
10964    (set_attr "length" "4,8")])
10966 (define_insn "*sibcall_local64"
10967   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10968          (match_operand 1))
10969    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10970    (simple_return)]
10971   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10973   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10974     output_asm_insn ("crxor 6,6,6", operands);
10976   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10977     output_asm_insn ("creqv 6,6,6", operands);
10979   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10981   [(set_attr "type" "branch")
10982    (set_attr "length" "4,8")])
10984 (define_insn "*sibcall_value_local32"
10985   [(set (match_operand 0 "" "")
10986         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10987               (match_operand 2)))
10988    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10989    (simple_return)]
10990   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10992   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10993     output_asm_insn ("crxor 6,6,6", operands);
10995   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10996     output_asm_insn ("creqv 6,6,6", operands);
10998   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11000   [(set_attr "type" "branch")
11001    (set_attr "length" "4,8")])
11003 (define_insn "*sibcall_value_local64"
11004   [(set (match_operand 0 "" "")
11005         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11006               (match_operand 2)))
11007    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11008    (simple_return)]
11009   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11011   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11012     output_asm_insn ("crxor 6,6,6", operands);
11014   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11015     output_asm_insn ("creqv 6,6,6", operands);
11017   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11019   [(set_attr "type" "branch")
11020    (set_attr "length" "4,8")])
11022 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11023   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11024          (match_operand 1))
11025    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11026    (simple_return)]
11027   "DEFAULT_ABI == ABI_V4
11028    || DEFAULT_ABI == ABI_DARWIN"
11030   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11031     output_asm_insn ("crxor 6,6,6", operands);
11033   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11034     output_asm_insn ("creqv 6,6,6", operands);
11036   return rs6000_indirect_sibcall_template (operands, 0);
11038   [(set_attr "type" "jmpreg")
11039    (set (attr "length")
11040         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11041                          (match_test "which_alternative != 1"))
11042                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11043                   (const_string "12")
11044                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11045                          (match_test "which_alternative != 1"))
11046                    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11047                   (const_string "8")]
11048               (const_string "4")))])
11050 (define_insn "*sibcall_nonlocal_sysv<mode>"
11051   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11052          (match_operand 1))
11053    (use (match_operand 2 "immediate_operand" "O,n"))
11054    (simple_return)]
11055   "(DEFAULT_ABI == ABI_DARWIN
11056     || DEFAULT_ABI == ABI_V4)
11057    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11059   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11060     output_asm_insn ("crxor 6,6,6", operands);
11062   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11063     output_asm_insn ("creqv 6,6,6", operands);
11065   return rs6000_sibcall_template (operands, 0);
11067   [(set_attr "type" "branch")
11068    (set_attr "length" "4,8")])
11070 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11071   [(set (match_operand 0 "" "")
11072         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11073               (match_operand 2)))
11074    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11075    (simple_return)]
11076   "DEFAULT_ABI == ABI_V4
11077    || DEFAULT_ABI == ABI_DARWIN"
11079   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11080     output_asm_insn ("crxor 6,6,6", operands);
11082   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11083     output_asm_insn ("creqv 6,6,6", operands);
11085   return rs6000_indirect_sibcall_template (operands, 1);
11087   [(set_attr "type" "jmpreg")
11088    (set (attr "length")
11089         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11090                          (match_test "which_alternative != 1"))
11091                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11092                   (const_string "12")
11093                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11094                          (match_test "which_alternative != 1"))
11095                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11096                   (const_string "8")]
11097               (const_string "4")))])
11099 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11100   [(set (match_operand 0 "" "")
11101         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11102               (match_operand 2)))
11103    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11104    (simple_return)]
11105   "(DEFAULT_ABI == ABI_DARWIN
11106     || DEFAULT_ABI == ABI_V4)
11107    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11109   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11110     output_asm_insn ("crxor 6,6,6", operands);
11112   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11113     output_asm_insn ("creqv 6,6,6", operands);
11115   return rs6000_sibcall_template (operands, 1);
11117   [(set_attr "type" "branch")
11118    (set_attr "length" "4,8")])
11120 ;; AIX ABI sibling call patterns.
11122 (define_insn "*sibcall_aix<mode>"
11123   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11124          (match_operand 1))
11125    (simple_return)]
11126   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11128   if (which_alternative == 0)
11129     return rs6000_sibcall_template (operands, 0);
11130   else
11131     return "b%T0";
11133   [(set_attr "type" "branch")])
11135 (define_insn "*sibcall_value_aix<mode>"
11136   [(set (match_operand 0 "" "")
11137         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11138               (match_operand 2)))
11139    (simple_return)]
11140   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11142   if (which_alternative == 0)
11143     return rs6000_sibcall_template (operands, 1);
11144   else
11145     return "b%T1";
11147   [(set_attr "type" "branch")])
11149 (define_expand "sibcall_epilogue"
11150   [(use (const_int 0))]
11151   ""
11153   if (!TARGET_SCHED_PROLOG)
11154     emit_insn (gen_blockage ());
11155   rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11156   DONE;
11159 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11160 ;; all of memory.  This blocks insns from being moved across this point.
11162 (define_insn "blockage"
11163   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11164   ""
11165   ""
11166   [(set_attr "length" "0")])
11168 (define_expand "probe_stack_address"
11169   [(use (match_operand 0 "address_operand"))]
11170   ""
11172   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11173   MEM_VOLATILE_P (operands[0]) = 1;
11175   if (TARGET_64BIT)
11176     emit_insn (gen_probe_stack_di (operands[0]));
11177   else
11178     emit_insn (gen_probe_stack_si (operands[0]));
11179   DONE;
11182 (define_insn "probe_stack_<mode>"
11183   [(set (match_operand:P 0 "memory_operand" "=m")
11184         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11185   ""
11187   operands[1] = gen_rtx_REG (Pmode, 0);
11188   return "st<wd>%U0%X0 %1,%0";
11190   [(set_attr "type" "store")
11191    (set (attr "update")
11192         (if_then_else (match_operand 0 "update_address_mem")
11193                       (const_string "yes")
11194                       (const_string "no")))
11195    (set (attr "indexed")
11196         (if_then_else (match_operand 0 "indexed_address_mem")
11197                       (const_string "yes")
11198                       (const_string "no")))])
11200 (define_insn "probe_stack_range<P:mode>"
11201   [(set (match_operand:P 0 "register_operand" "=&r")
11202         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11203                             (match_operand:P 2 "register_operand" "r")
11204                             (match_operand:P 3 "register_operand" "r")]
11205                            UNSPECV_PROBE_STACK_RANGE))]
11206   ""
11207   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11208   [(set_attr "type" "three")])
11210 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11211 ;; signed & unsigned, and one type of branch.
11213 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11214 ;; insns, and branches.
11216 (define_expand "cbranch<mode>4"
11217   [(use (match_operator 0 "comparison_operator"
11218          [(match_operand:GPR 1 "gpc_reg_operand")
11219           (match_operand:GPR 2 "reg_or_short_operand")]))
11220    (use (match_operand 3))]
11221   ""
11223   /* Take care of the possibility that operands[2] might be negative but
11224      this might be a logical operation.  That insn doesn't exist.  */
11225   if (CONST_INT_P (operands[2])
11226       && INTVAL (operands[2]) < 0)
11227     {
11228       operands[2] = force_reg (<MODE>mode, operands[2]);
11229       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11230                                     GET_MODE (operands[0]),
11231                                     operands[1], operands[2]);
11232    }
11234   rs6000_emit_cbranch (<MODE>mode, operands);
11235   DONE;
11238 (define_expand "cbranch<mode>4"
11239   [(use (match_operator 0 "comparison_operator"
11240          [(match_operand:FP 1 "gpc_reg_operand")
11241           (match_operand:FP 2 "gpc_reg_operand")]))
11242    (use (match_operand 3))]
11243   ""
11245   rs6000_emit_cbranch (<MODE>mode, operands);
11246   DONE;
11249 (define_expand "cstore<mode>4_signed"
11250   [(use (match_operator 1 "signed_comparison_operator"
11251          [(match_operand:P 2 "gpc_reg_operand")
11252           (match_operand:P 3 "gpc_reg_operand")]))
11253    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11254   ""
11256   enum rtx_code cond_code = GET_CODE (operands[1]);
11258   rtx op0 = operands[0];
11259   rtx op1 = operands[2];
11260   rtx op2 = operands[3];
11262   if (cond_code == GE || cond_code == LT)
11263     {
11264       cond_code = swap_condition (cond_code);
11265       std::swap (op1, op2);
11266     }
11268   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11269   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11270   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11272   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11273   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11274   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11276   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11278   if (cond_code == LE)
11279     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11280   else
11281     {
11282       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11283       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11284       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11285     }
11287   DONE;
11290 (define_expand "cstore<mode>4_unsigned"
11291   [(use (match_operator 1 "unsigned_comparison_operator"
11292          [(match_operand:P 2 "gpc_reg_operand")
11293           (match_operand:P 3 "reg_or_short_operand")]))
11294    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11295   ""
11297   enum rtx_code cond_code = GET_CODE (operands[1]);
11299   rtx op0 = operands[0];
11300   rtx op1 = operands[2];
11301   rtx op2 = operands[3];
11303   if (cond_code == GEU || cond_code == LTU)
11304     {
11305       cond_code = swap_condition (cond_code);
11306       std::swap (op1, op2);
11307     }
11309   if (!gpc_reg_operand (op1, <MODE>mode))
11310     op1 = force_reg (<MODE>mode, op1);
11311   if (!reg_or_short_operand (op2, <MODE>mode))
11312     op2 = force_reg (<MODE>mode, op2);
11314   rtx tmp = gen_reg_rtx (<MODE>mode);
11315   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11317   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11318   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11320   if (cond_code == LEU)
11321     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11322   else
11323     emit_insn (gen_neg<mode>2 (op0, tmp2));
11325   DONE;
11328 (define_expand "cstore_si_as_di"
11329   [(use (match_operator 1 "unsigned_comparison_operator"
11330          [(match_operand:SI 2 "gpc_reg_operand")
11331           (match_operand:SI 3 "reg_or_short_operand")]))
11332    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11333   ""
11335   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11336   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11338   operands[2] = force_reg (SImode, operands[2]);
11339   operands[3] = force_reg (SImode, operands[3]);
11340   rtx op1 = gen_reg_rtx (DImode);
11341   rtx op2 = gen_reg_rtx (DImode);
11342   convert_move (op1, operands[2], uns_flag);
11343   convert_move (op2, operands[3], uns_flag);
11345   if (cond_code == GT || cond_code == LE)
11346     {
11347       cond_code = swap_condition (cond_code);
11348       std::swap (op1, op2);
11349     }
11351   rtx tmp = gen_reg_rtx (DImode);
11352   rtx tmp2 = gen_reg_rtx (DImode);
11353   emit_insn (gen_subdi3 (tmp, op1, op2));
11354   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11356   rtx tmp3;
11357   switch (cond_code)
11358     {
11359     default:
11360       gcc_unreachable ();
11361     case LT:
11362       tmp3 = tmp2;
11363       break;
11364     case GE:
11365       tmp3 = gen_reg_rtx (DImode);
11366       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11367       break;
11368     }
11370   convert_move (operands[0], tmp3, 1);
11372   DONE;
11375 (define_expand "cstore<mode>4_signed_imm"
11376   [(use (match_operator 1 "signed_comparison_operator"
11377          [(match_operand:GPR 2 "gpc_reg_operand")
11378           (match_operand:GPR 3 "immediate_operand")]))
11379    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11380   ""
11382   bool invert = false;
11384   enum rtx_code cond_code = GET_CODE (operands[1]);
11386   rtx op0 = operands[0];
11387   rtx op1 = operands[2];
11388   HOST_WIDE_INT val = INTVAL (operands[3]);
11390   if (cond_code == GE || cond_code == GT)
11391     {
11392       cond_code = reverse_condition (cond_code);
11393       invert = true;
11394     }
11396   if (cond_code == LE)
11397     val++;
11399   rtx tmp = gen_reg_rtx (<MODE>mode);
11400   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11401   rtx x = gen_reg_rtx (<MODE>mode);
11402   if (val < 0)
11403     emit_insn (gen_and<mode>3 (x, op1, tmp));
11404   else
11405     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11407   if (invert)
11408     {
11409       rtx tmp = gen_reg_rtx (<MODE>mode);
11410       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11411       x = tmp;
11412     }
11414   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11415   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11417   DONE;
11420 (define_expand "cstore<mode>4_unsigned_imm"
11421   [(use (match_operator 1 "unsigned_comparison_operator"
11422          [(match_operand:GPR 2 "gpc_reg_operand")
11423           (match_operand:GPR 3 "immediate_operand")]))
11424    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11425   ""
11427   bool invert = false;
11429   enum rtx_code cond_code = GET_CODE (operands[1]);
11431   rtx op0 = operands[0];
11432   rtx op1 = operands[2];
11433   HOST_WIDE_INT val = INTVAL (operands[3]);
11435   if (cond_code == GEU || cond_code == GTU)
11436     {
11437       cond_code = reverse_condition (cond_code);
11438       invert = true;
11439     }
11441   if (cond_code == LEU)
11442     val++;
11444   rtx tmp = gen_reg_rtx (<MODE>mode);
11445   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11446   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11447   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11448   rtx x = gen_reg_rtx (<MODE>mode);
11449   if (val < 0)
11450     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11451   else
11452     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11454   if (invert)
11455     {
11456       rtx tmp = gen_reg_rtx (<MODE>mode);
11457       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11458       x = tmp;
11459     }
11461   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11462   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11464   DONE;
11467 (define_expand "cstore<mode>4"
11468   [(use (match_operator 1 "comparison_operator"
11469          [(match_operand:GPR 2 "gpc_reg_operand")
11470           (match_operand:GPR 3 "reg_or_short_operand")]))
11471    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11472   ""
11474   /* Expanding EQ and NE directly to some machine instructions does not help
11475      but does hurt combine.  So don't.  */
11476   if (GET_CODE (operands[1]) == EQ)
11477     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11478   else if (<MODE>mode == Pmode
11479            && GET_CODE (operands[1]) == NE)
11480     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11481   else if (GET_CODE (operands[1]) == NE)
11482     {
11483       rtx tmp = gen_reg_rtx (<MODE>mode);
11484       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11485       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11486     }
11488   /* If ISEL is fast, expand to it.  */
11489   else if (TARGET_ISEL)
11490     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11492   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11493      etc. combinations magically work out just right.  */
11494   else if (<MODE>mode == Pmode
11495            && unsigned_comparison_operator (operands[1], VOIDmode))
11496     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11497                                            operands[2], operands[3]));
11499   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11500   else if (<MODE>mode == SImode && Pmode == DImode)
11501     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11502                                     operands[2], operands[3]));
11504   /* For signed comparisons against a constant, we can do some simple
11505      bit-twiddling.  */
11506   else if (signed_comparison_operator (operands[1], VOIDmode)
11507            && CONST_INT_P (operands[3]))
11508     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11509                                              operands[2], operands[3]));
11511   /* And similarly for unsigned comparisons.  */
11512   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11513            && CONST_INT_P (operands[3]))
11514     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11515                                                operands[2], operands[3]));
11517   /* We also do not want to use mfcr for signed comparisons.  */
11518   else if (<MODE>mode == Pmode
11519            && signed_comparison_operator (operands[1], VOIDmode))
11520     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11521                                          operands[2], operands[3]));
11523   /* Everything else, use the mfcr brute force.  */
11524   else
11525     rs6000_emit_sCOND (<MODE>mode, operands);
11527   DONE;
11530 (define_expand "cstore<mode>4"
11531   [(use (match_operator 1 "comparison_operator"
11532          [(match_operand:FP 2 "gpc_reg_operand")
11533           (match_operand:FP 3 "gpc_reg_operand")]))
11534    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11535   ""
11537   rs6000_emit_sCOND (<MODE>mode, operands);
11538   DONE;
11542 (define_expand "stack_protect_set"
11543   [(match_operand 0 "memory_operand")
11544    (match_operand 1 "memory_operand")]
11545   ""
11547   if (rs6000_stack_protector_guard == SSP_TLS)
11548     {
11549       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11550       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11551       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11552       operands[1] = gen_rtx_MEM (Pmode, addr);
11553     }
11555   if (TARGET_64BIT)
11556     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11557   else
11558     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11560   DONE;
11563 (define_insn "stack_protect_setsi"
11564   [(set (match_operand:SI 0 "memory_operand" "=m")
11565         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11566    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11567   "TARGET_32BIT"
11568   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11569   [(set_attr "type" "three")
11570    (set_attr "length" "12")])
11572 ;; We can't use the prefixed attribute here because there are two memory
11573 ;; instructions.  We can't split the insn due to the fact that this operation
11574 ;; needs to be done in one piece.
11575 (define_insn "stack_protect_setdi"
11576   [(set (match_operand:DI 0 "memory_operand" "=Y")
11577         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11578    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11579   "TARGET_64BIT"
11581   if (prefixed_memory (operands[1], DImode))
11582     output_asm_insn ("pld %2,%1", operands);
11583   else
11584     output_asm_insn ("ld%U1%X1 %2,%1", operands);
11586   if (prefixed_memory (operands[0], DImode))
11587     output_asm_insn ("pstd %2,%0", operands);
11588   else
11589     output_asm_insn ("std%U0%X0 %2,%0", operands);
11591   return "li %2,0";
11593   [(set_attr "type" "three")
11595   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11596   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in 4 bytes for
11597   ;; the LI 0 at the end.
11598    (set_attr "prefixed" "no")
11599    (set_attr "num_insns" "3")
11600    (set (attr "length")
11601         (cond [(and (match_operand 0 "prefixed_memory")
11602                     (match_operand 1 "prefixed_memory"))
11603                (const_int 24)
11605                (ior (match_operand 0 "prefixed_memory")
11606                     (match_operand 1 "prefixed_memory"))
11607                (const_int 20)]
11609               (const_int 12)))])
11611 (define_expand "stack_protect_test"
11612   [(match_operand 0 "memory_operand")
11613    (match_operand 1 "memory_operand")
11614    (match_operand 2 "")]
11615   ""
11617   rtx guard = operands[1];
11619   if (rs6000_stack_protector_guard == SSP_TLS)
11620     {
11621       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11622       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11623       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11624       guard = gen_rtx_MEM (Pmode, addr);
11625     }
11627   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11628   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11629   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11630   emit_jump_insn (jump);
11632   DONE;
11635 (define_insn "stack_protect_testsi"
11636   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11637         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11638                       (match_operand:SI 2 "memory_operand" "m,m")]
11639                      UNSPEC_SP_TEST))
11640    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11641    (clobber (match_scratch:SI 3 "=&r,&r"))]
11642   "TARGET_32BIT"
11643   "@
11644    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11645    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11646   [(set_attr "length" "16,20")])
11648 ;; We can't use the prefixed attribute here because there are two memory
11649 ;; instructions.  We can't split the insn due to the fact that this operation
11650 ;; needs to be done in one piece.
11651 (define_insn "stack_protect_testdi"
11652   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11653         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11654                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11655                      UNSPEC_SP_TEST))
11656    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11657    (clobber (match_scratch:DI 3 "=&r,&r"))]
11658   "TARGET_64BIT"
11660   if (prefixed_memory (operands[1], DImode))
11661     output_asm_insn ("pld %3,%1", operands);
11662   else
11663     output_asm_insn ("ld%U1%X1 %3,%1", operands);
11665   if (prefixed_memory (operands[2], DImode))
11666     output_asm_insn ("pld %4,%2", operands);
11667   else
11668     output_asm_insn ("ld%U2%X2 %4,%2", operands);
11670   if (which_alternative == 0)
11671     output_asm_insn ("xor. %3,%3,%4", operands);
11672   else
11673     output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11675   return "li %4,0";
11677   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11678   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in either 4 or
11679   ;; 8 bytes to do the test.
11680   [(set_attr "prefixed" "no")
11681    (set_attr "num_insns" "4,5")
11682    (set (attr "length")
11683         (cond [(and (match_operand 1 "prefixed_memory")
11684                     (match_operand 2 "prefixed_memory"))
11685                (if_then_else (eq_attr "alternative" "0")
11686                              (const_int 28)
11687                              (const_int 32))
11689                (ior (match_operand 1 "prefixed_memory")
11690                     (match_operand 2 "prefixed_memory"))
11691                (if_then_else (eq_attr "alternative" "0")
11692                              (const_int 20)
11693                              (const_int 24))]
11695               (if_then_else (eq_attr "alternative" "0")
11696                             (const_int 16)
11697                             (const_int 20))))])
11700 ;; Here are the actual compare insns.
11701 (define_insn "*cmp<mode>_signed"
11702   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11703         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11704                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11705   ""
11706   "cmp<wd>%I2 %0,%1,%2"
11707   [(set_attr "type" "cmp")])
11709 (define_insn "*cmp<mode>_unsigned"
11710   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11711         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11712                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11713   ""
11714   "cmpl<wd>%I2 %0,%1,%2"
11715   [(set_attr "type" "cmp")])
11717 ;; If we are comparing a register for equality with a large constant,
11718 ;; we can do this with an XOR followed by a compare.  But this is profitable
11719 ;; only if the large constant is only used for the comparison (and in this
11720 ;; case we already have a register to reuse as scratch).
11722 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11723 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11725 (define_peephole2
11726   [(set (match_operand:SI 0 "register_operand")
11727         (match_operand:SI 1 "logical_const_operand"))
11728    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11729                        [(match_dup 0)
11730                         (match_operand:SI 2 "logical_const_operand")]))
11731    (set (match_operand:CC 4 "cc_reg_operand")
11732         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11733                     (match_dup 0)))
11734    (set (pc)
11735         (if_then_else (match_operator 6 "equality_operator"
11736                        [(match_dup 4) (const_int 0)])
11737                       (match_operand 7 "")
11738                       (match_operand 8 "")))]
11739   "peep2_reg_dead_p (3, operands[0])
11740    && peep2_reg_dead_p (4, operands[4])
11741    && REGNO (operands[0]) != REGNO (operands[5])"
11742  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11743   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11744   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11747   /* Get the constant we are comparing against, and see what it looks like
11748      when sign-extended from 16 to 32 bits.  Then see what constant we could
11749      XOR with SEXTC to get the sign-extended value.  */
11750   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11751                                               SImode,
11752                                               operands[1], operands[2]);
11753   HOST_WIDE_INT c = INTVAL (cnst);
11754   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11755   HOST_WIDE_INT xorv = c ^ sextc;
11757   operands[9] = GEN_INT (xorv);
11758   operands[10] = GEN_INT (sextc);
11761 ;; Only need to compare second words if first words equal
11762 (define_insn "*cmp<mode>_internal1"
11763   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11764         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11765                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11766   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11767    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11768   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11769   [(set_attr "type" "fpcompare")
11770    (set_attr "length" "12")])
11772 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11773   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11774         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11775                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11776     (clobber (match_scratch:DF 3 "=d"))
11777     (clobber (match_scratch:DF 4 "=d"))
11778     (clobber (match_scratch:DF 5 "=d"))
11779     (clobber (match_scratch:DF 6 "=d"))
11780     (clobber (match_scratch:DF 7 "=d"))
11781     (clobber (match_scratch:DF 8 "=d"))
11782     (clobber (match_scratch:DF 9 "=d"))
11783     (clobber (match_scratch:DF 10 "=d"))
11784     (clobber (match_scratch:GPR 11 "=b"))]
11785   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11786    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11787   "#"
11788   "&& reload_completed"
11789   [(set (match_dup 3) (match_dup 14))
11790    (set (match_dup 4) (match_dup 15))
11791    (set (match_dup 9) (abs:DF (match_dup 5)))
11792    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11793    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11794                            (label_ref (match_dup 12))
11795                            (pc)))
11796    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11797    (set (pc) (label_ref (match_dup 13)))
11798    (match_dup 12)
11799    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11800    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11801    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11802    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11803    (match_dup 13)]
11805   REAL_VALUE_TYPE rv;
11806   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11807   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11809   operands[5] = simplify_gen_subreg (DFmode, operands[1],
11810                                      <IBM128:MODE>mode, hi_word);
11811   operands[6] = simplify_gen_subreg (DFmode, operands[1],
11812                                      <IBM128:MODE>mode, lo_word);
11813   operands[7] = simplify_gen_subreg (DFmode, operands[2],
11814                                      <IBM128:MODE>mode, hi_word);
11815   operands[8] = simplify_gen_subreg (DFmode, operands[2],
11816                                      <IBM128:MODE>mode, lo_word);
11817   operands[12] = gen_label_rtx ();
11818   operands[13] = gen_label_rtx ();
11819   real_inf (&rv);
11820   operands[14] = force_const_mem (DFmode,
11821                                   const_double_from_real_value (rv, DFmode));
11822   operands[15] = force_const_mem (DFmode,
11823                                   const_double_from_real_value (dconst0,
11824                                                                 DFmode));
11825   if (TARGET_TOC)
11826     {
11827       rtx tocref;
11828       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11829       operands[14] = gen_const_mem (DFmode, tocref);
11830       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11831       operands[15] = gen_const_mem (DFmode, tocref);
11832       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11833       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11834     }
11837 ;; Now we have the scc insns.  We can do some combinations because of the
11838 ;; way the machine works.
11840 ;; Note that this is probably faster if we can put an insn between the
11841 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11842 ;; cases the insns below which don't use an intermediate CR field will
11843 ;; be used instead.
11844 (define_insn "set<mode>_cc"
11845   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11846         (match_operator:GPR 1 "scc_comparison_operator"
11847                             [(match_operand 2 "cc_reg_operand" "y")
11848                              (const_int 0)]))]
11849   ""
11850   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11851   [(set (attr "type")
11852      (cond [(match_test "TARGET_MFCRF")
11853                 (const_string "mfcrf")
11854            ]
11855         (const_string "mfcr")))
11856    (set_attr "length" "8")])
11859 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11860 (define_code_attr UNS [(eq "CC")
11861                        (ne "CC")
11862                        (lt "CC") (ltu "CCUNS")
11863                        (gt "CC") (gtu "CCUNS")
11864                        (le "CC") (leu "CCUNS")
11865                        (ge "CC") (geu "CCUNS")])
11866 (define_code_attr UNSu_ [(eq "")
11867                          (ne "")
11868                          (lt "") (ltu "u_")
11869                          (gt "") (gtu "u_")
11870                          (le "") (leu "u_")
11871                          (ge "") (geu "u_")])
11872 (define_code_attr UNSIK [(eq "I")
11873                          (ne "I")
11874                          (lt "I") (ltu "K")
11875                          (gt "I") (gtu "K")
11876                          (le "I") (leu "K")
11877                          (ge "I") (geu "K")])
11879 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11880   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11881         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11882                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11883    (clobber (match_scratch:GPR 3 "=r"))
11884    (clobber (match_scratch:GPR 4 "=r"))
11885    (clobber (match_scratch:<UNS> 5 "=y"))]
11886   "TARGET_ISEL
11887    && !(<CODE> == EQ && operands[2] == const0_rtx)
11888    && !(<CODE> == NE && operands[2] == const0_rtx
11889         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11890   "#"
11891   "&& 1"
11892   [(pc)]
11894   rtx_code code = <CODE>;
11895   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11896     {
11897       HOST_WIDE_INT val = INTVAL (operands[2]);
11898       if (code == LT && val != -0x8000)
11899         {
11900           code = LE;
11901           val--;
11902         }
11903       if (code == GT && val != 0x7fff)
11904         {
11905           code = GE;
11906           val++;
11907         }
11908       if (code == LTU && val != 0)
11909         {
11910           code = LEU;
11911           val--;
11912         }
11913       if (code == GTU && val != 0xffff)
11914         {
11915           code = GEU;
11916           val++;
11917         }
11918       operands[2] = GEN_INT (val);
11919     }
11921   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11922     operands[3] = const0_rtx;
11923   else
11924     {
11925       if (GET_CODE (operands[3]) == SCRATCH)
11926         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11927       emit_move_insn (operands[3], const0_rtx);
11928     }
11930   if (GET_CODE (operands[4]) == SCRATCH)
11931     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11932   emit_move_insn (operands[4], const1_rtx);
11934   if (GET_CODE (operands[5]) == SCRATCH)
11935     operands[5] = gen_reg_rtx (<UNS>mode);
11937   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11938   emit_insn (gen_rtx_SET (operands[5], c1));
11940   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11941   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11942   emit_move_insn (operands[0], x);
11944   DONE;
11946   [(set (attr "cost")
11947         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11948                                    || <CODE> == NE
11949                                    || <CODE> == LE || <CODE> == GE
11950                                    || <CODE> == LEU || <CODE> == GEU")
11951                       (const_string "9")
11952                       (const_string "10")))])
11954 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11955                               (DI "rKJI")])
11957 (define_expand "eq<mode>3"
11958   [(parallel [
11959      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11960           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11961                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11962      (clobber (match_scratch:GPR 3 "=r"))
11963      (clobber (match_scratch:GPR 4 "=r"))])]
11964   ""
11966   if (TARGET_ISEL && operands[2] != const0_rtx)
11967     {
11968       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11969                                            operands[2]));
11970       DONE;
11971     }
11974 (define_insn_and_split "*eq<mode>3"
11975   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11976         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11977                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11978    (clobber (match_scratch:GPR 3 "=r"))
11979    (clobber (match_scratch:GPR 4 "=r"))]
11980   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11981   "#"
11982   "&& 1"
11983   [(set (match_dup 4)
11984         (clz:GPR (match_dup 3)))
11985    (set (match_dup 0)
11986         (lshiftrt:GPR (match_dup 4)
11987                       (match_dup 5)))]
11989   operands[3] = rs6000_emit_eqne (<MODE>mode,
11990                                   operands[1], operands[2], operands[3]);
11992   if (GET_CODE (operands[4]) == SCRATCH)
11993     operands[4] = gen_reg_rtx (<MODE>mode);
11995   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11997   [(set (attr "length")
11998         (if_then_else (match_test "operands[2] == const0_rtx")
11999                       (const_string "8")
12000                       (const_string "12")))])
12002 (define_expand "ne<mode>3"
12003   [(parallel [
12004      (set (match_operand:P 0 "gpc_reg_operand" "=r")
12005           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12006                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12007      (clobber (match_scratch:P 3 "=r"))
12008      (clobber (match_scratch:P 4 "=r"))
12009      (clobber (reg:P CA_REGNO))])]
12010   ""
12012   if (TARGET_ISEL && operands[2] != const0_rtx)
12013     {
12014       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12015                                            operands[2]));
12016       DONE;
12017     }
12020 (define_insn_and_split "*ne<mode>3"
12021   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12022         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12023               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12024    (clobber (match_scratch:P 3 "=r"))
12025    (clobber (match_scratch:P 4 "=r"))
12026    (clobber (reg:P CA_REGNO))]
12027   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12028   "#"
12029   "&& 1"
12030   [(parallel [(set (match_dup 4)
12031                    (plus:P (match_dup 3)
12032                            (const_int -1)))
12033               (set (reg:P CA_REGNO)
12034                    (ne:P (match_dup 3)
12035                          (const_int 0)))])
12036    (parallel [(set (match_dup 0)
12037                    (plus:P (plus:P (not:P (match_dup 4))
12038                                    (reg:P CA_REGNO))
12039                            (match_dup 3)))
12040               (clobber (reg:P CA_REGNO))])]
12042   operands[3] = rs6000_emit_eqne (<MODE>mode,
12043                                   operands[1], operands[2], operands[3]);
12045   if (GET_CODE (operands[4]) == SCRATCH)
12046     operands[4] = gen_reg_rtx (<MODE>mode);
12048   [(set (attr "length")
12049         (if_then_else (match_test "operands[2] == const0_rtx")
12050                       (const_string "8")
12051                       (const_string "12")))])
12053 (define_insn_and_split "*neg_eq_<mode>"
12054   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12055         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12056                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12057    (clobber (match_scratch:P 3 "=r"))
12058    (clobber (match_scratch:P 4 "=r"))
12059    (clobber (reg:P CA_REGNO))]
12060   ""
12061   "#"
12062   ""
12063   [(parallel [(set (match_dup 4)
12064                    (plus:P (match_dup 3)
12065                            (const_int -1)))
12066               (set (reg:P CA_REGNO)
12067                    (ne:P (match_dup 3)
12068                          (const_int 0)))])
12069    (parallel [(set (match_dup 0)
12070                    (plus:P (reg:P CA_REGNO)
12071                            (const_int -1)))
12072               (clobber (reg:P CA_REGNO))])]
12074   operands[3] = rs6000_emit_eqne (<MODE>mode,
12075                                   operands[1], operands[2], operands[3]);
12077   if (GET_CODE (operands[4]) == SCRATCH)
12078     operands[4] = gen_reg_rtx (<MODE>mode);
12080   [(set (attr "length")
12081         (if_then_else (match_test "operands[2] == const0_rtx")
12082                       (const_string "8")
12083                       (const_string "12")))])
12085 (define_insn_and_split "*neg_ne_<mode>"
12086   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12087         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12088                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12089    (clobber (match_scratch:P 3 "=r"))
12090    (clobber (match_scratch:P 4 "=r"))
12091    (clobber (reg:P CA_REGNO))]
12092   ""
12093   "#"
12094   ""
12095   [(parallel [(set (match_dup 4)
12096                    (neg:P (match_dup 3)))
12097               (set (reg:P CA_REGNO)
12098                    (eq:P (match_dup 3)
12099                          (const_int 0)))])
12100    (parallel [(set (match_dup 0)
12101                    (plus:P (reg:P CA_REGNO)
12102                            (const_int -1)))
12103               (clobber (reg:P CA_REGNO))])]
12105   operands[3] = rs6000_emit_eqne (<MODE>mode,
12106                                   operands[1], operands[2], operands[3]);
12108   if (GET_CODE (operands[4]) == SCRATCH)
12109     operands[4] = gen_reg_rtx (<MODE>mode);
12111   [(set (attr "length")
12112         (if_then_else (match_test "operands[2] == const0_rtx")
12113                       (const_string "8")
12114                       (const_string "12")))])
12116 (define_insn_and_split "*plus_eq_<mode>"
12117   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12118         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12119                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12120                 (match_operand:P 3 "gpc_reg_operand" "r")))
12121    (clobber (match_scratch:P 4 "=r"))
12122    (clobber (match_scratch:P 5 "=r"))
12123    (clobber (reg:P CA_REGNO))]
12124   ""
12125   "#"
12126   ""
12127   [(parallel [(set (match_dup 5)
12128                    (neg:P (match_dup 4)))
12129               (set (reg:P CA_REGNO)
12130                    (eq:P (match_dup 4)
12131                          (const_int 0)))])
12132    (parallel [(set (match_dup 0)
12133                    (plus:P (match_dup 3)
12134                            (reg:P CA_REGNO)))
12135               (clobber (reg:P CA_REGNO))])]
12137   operands[4] = rs6000_emit_eqne (<MODE>mode,
12138                                   operands[1], operands[2], operands[4]);
12140   if (GET_CODE (operands[5]) == SCRATCH)
12141     operands[5] = gen_reg_rtx (<MODE>mode);
12143   [(set (attr "length")
12144         (if_then_else (match_test "operands[2] == const0_rtx")
12145                       (const_string "8")
12146                       (const_string "12")))])
12148 (define_insn_and_split "*plus_ne_<mode>"
12149   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12150         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12151                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12152                 (match_operand:P 3 "gpc_reg_operand" "r")))
12153    (clobber (match_scratch:P 4 "=r"))
12154    (clobber (match_scratch:P 5 "=r"))
12155    (clobber (reg:P CA_REGNO))]
12156   ""
12157   "#"
12158   ""
12159   [(parallel [(set (match_dup 5)
12160                    (plus:P (match_dup 4)
12161                            (const_int -1)))
12162               (set (reg:P CA_REGNO)
12163                    (ne:P (match_dup 4)
12164                          (const_int 0)))])
12165    (parallel [(set (match_dup 0)
12166                    (plus:P (match_dup 3)
12167                            (reg:P CA_REGNO)))
12168               (clobber (reg:P CA_REGNO))])]
12170   operands[4] = rs6000_emit_eqne (<MODE>mode,
12171                                   operands[1], operands[2], operands[4]);
12173   if (GET_CODE (operands[5]) == SCRATCH)
12174     operands[5] = gen_reg_rtx (<MODE>mode);
12176   [(set (attr "length")
12177         (if_then_else (match_test "operands[2] == const0_rtx")
12178                       (const_string "8")
12179                       (const_string "12")))])
12181 (define_insn_and_split "*minus_eq_<mode>"
12182   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12183         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12184                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12185                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12186    (clobber (match_scratch:P 4 "=r"))
12187    (clobber (match_scratch:P 5 "=r"))
12188    (clobber (reg:P CA_REGNO))]
12189   ""
12190   "#"
12191   ""
12192   [(parallel [(set (match_dup 5)
12193                    (plus:P (match_dup 4)
12194                            (const_int -1)))
12195               (set (reg:P CA_REGNO)
12196                    (ne:P (match_dup 4)
12197                          (const_int 0)))])
12198    (parallel [(set (match_dup 0)
12199                    (plus:P (plus:P (match_dup 3)
12200                                    (reg:P CA_REGNO))
12201                            (const_int -1)))
12202               (clobber (reg:P CA_REGNO))])]
12204   operands[4] = rs6000_emit_eqne (<MODE>mode,
12205                                   operands[1], operands[2], operands[4]);
12207   if (GET_CODE (operands[5]) == SCRATCH)
12208     operands[5] = gen_reg_rtx (<MODE>mode);
12210   [(set (attr "length")
12211         (if_then_else (match_test "operands[2] == const0_rtx")
12212                       (const_string "8")
12213                       (const_string "12")))])
12215 (define_insn_and_split "*minus_ne_<mode>"
12216   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12217         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12218                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12219                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12220    (clobber (match_scratch:P 4 "=r"))
12221    (clobber (match_scratch:P 5 "=r"))
12222    (clobber (reg:P CA_REGNO))]
12223   ""
12224   "#"
12225   ""
12226   [(parallel [(set (match_dup 5)
12227                    (neg:P (match_dup 4)))
12228               (set (reg:P CA_REGNO)
12229                    (eq:P (match_dup 4)
12230                          (const_int 0)))])
12231    (parallel [(set (match_dup 0)
12232                    (plus:P (plus:P (match_dup 3)
12233                                    (reg:P CA_REGNO))
12234                            (const_int -1)))
12235               (clobber (reg:P CA_REGNO))])]
12237   operands[4] = rs6000_emit_eqne (<MODE>mode,
12238                                   operands[1], operands[2], operands[4]);
12240   if (GET_CODE (operands[5]) == SCRATCH)
12241     operands[5] = gen_reg_rtx (<MODE>mode);
12243   [(set (attr "length")
12244         (if_then_else (match_test "operands[2] == const0_rtx")
12245                       (const_string "8")
12246                       (const_string "12")))])
12248 (define_insn_and_split "*eqsi3_ext<mode>"
12249   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12250         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12251                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12252    (clobber (match_scratch:SI 3 "=r"))
12253    (clobber (match_scratch:SI 4 "=r"))]
12254   ""
12255   "#"
12256   ""
12257   [(set (match_dup 4)
12258         (clz:SI (match_dup 3)))
12259    (set (match_dup 0)
12260         (zero_extend:EXTSI
12261           (lshiftrt:SI (match_dup 4)
12262                        (const_int 5))))]
12264   operands[3] = rs6000_emit_eqne (SImode,
12265                                   operands[1], operands[2], operands[3]);
12267   if (GET_CODE (operands[4]) == SCRATCH)
12268     operands[4] = gen_reg_rtx (SImode);
12270   [(set (attr "length")
12271         (if_then_else (match_test "operands[2] == const0_rtx")
12272                       (const_string "8")
12273                       (const_string "12")))])
12275 (define_insn_and_split "*nesi3_ext<mode>"
12276   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12277         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12278                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12279    (clobber (match_scratch:SI 3 "=r"))
12280    (clobber (match_scratch:SI 4 "=r"))
12281    (clobber (match_scratch:EXTSI 5 "=r"))]
12282   "!TARGET_ISEL"
12283   "#"
12284   "&& 1"
12285   [(set (match_dup 4)
12286         (clz:SI (match_dup 3)))
12287    (set (match_dup 5)
12288         (zero_extend:EXTSI
12289           (lshiftrt:SI (match_dup 4)
12290                        (const_int 5))))
12291    (set (match_dup 0)
12292         (xor:EXTSI (match_dup 5)
12293                    (const_int 1)))]
12295   operands[3] = rs6000_emit_eqne (SImode,
12296                                   operands[1], operands[2], operands[3]);
12298   if (GET_CODE (operands[4]) == SCRATCH)
12299     operands[4] = gen_reg_rtx (SImode);
12300   if (GET_CODE (operands[5]) == SCRATCH)
12301     operands[5] = gen_reg_rtx (<MODE>mode);
12303   [(set (attr "length")
12304         (if_then_else (match_test "operands[2] == const0_rtx")
12305                       (const_string "12")
12306                       (const_string "16")))])
12309 (define_code_iterator fp_rev [ordered ne unle unge])
12310 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12312 (define_insn_and_split "*<code><mode>_cc"
12313   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12314         (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12315                     (const_int 0)))]
12316   "!flag_finite_math_only"
12317   "#"
12318   "&& 1"
12319   [(pc)]
12321   rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12322   rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12323   rtx tmp = gen_reg_rtx (<MODE>mode);
12324   emit_move_insn (tmp, eq);
12325   emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12326   DONE;
12328   [(set_attr "length" "12")])
12330 (define_insn_and_split "*<code><mode>_cc"
12331   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12332         (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12333                   (const_int 0)))]
12334   "!flag_finite_math_only"
12335   "#"
12336   "&& 1"
12337   [(pc)]
12339   rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12341   emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12342   DONE;
12344   [(set_attr "length" "12")])
12346 ;; Conditional branches.
12347 ;; These either are a single bc insn, or a bc around a b.
12349 (define_insn "*cbranch"
12350   [(set (pc)
12351         (if_then_else (match_operator 1 "branch_comparison_operator"
12352                                       [(match_operand 2 "cc_reg_operand" "y")
12353                                        (const_int 0)])
12354                       (label_ref (match_operand 0))
12355                       (pc)))]
12356   ""
12358   return output_cbranch (operands[1], "%l0", 0, insn);
12360   [(set_attr "type" "branch")
12361    (set (attr "length")
12362         (if_then_else (and (ge (minus (match_dup 0) (pc))
12363                                (const_int -32768))
12364                            (lt (minus (match_dup 0) (pc))
12365                                (const_int 32764)))
12366                       (const_int 4)
12367                       (const_int 8)))])
12369 (define_insn_and_split "*cbranch_2insn"
12370   [(set (pc)
12371         (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12372                                       [(match_operand 2 "cc_reg_operand" "y")
12373                                        (const_int 0)])
12374                       (label_ref (match_operand 0))
12375                       (pc)))]
12376   "!flag_finite_math_only"
12377   "#"
12378   "&& 1"
12379   [(pc)]
12381   rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12383   rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12385   rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12386   rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12387   rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12388   emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12390   if (note)
12391     {
12392       profile_probability prob
12393         = profile_probability::from_reg_br_prob_note (XINT (note, 0));
12395       add_reg_br_prob_note (get_last_insn (), prob);
12396     }
12398   DONE;
12400   [(set_attr "type" "branch")
12401    (set (attr "length")
12402         (if_then_else (and (ge (minus (match_dup 0) (pc))
12403                                (const_int -32764))
12404                            (lt (minus (match_dup 0) (pc))
12405                                (const_int 32760)))
12406                       (const_int 8)
12407                       (const_int 16)))])
12409 ;; Conditional return.
12410 (define_insn "*creturn"
12411   [(set (pc)
12412         (if_then_else (match_operator 0 "branch_comparison_operator"
12413                                       [(match_operand 1 "cc_reg_operand" "y")
12414                                        (const_int 0)])
12415                       (any_return)
12416                       (pc)))]
12417   "<return_pred>"
12419   return output_cbranch (operands[0], NULL, 0, insn);
12421   [(set_attr "type" "jmpreg")])
12423 ;; Logic on condition register values.
12425 ; This pattern matches things like
12426 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12427 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12428 ;                                  (const_int 1)))
12429 ; which are generated by the branch logic.
12430 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12432 (define_insn "@cceq_ior_compare_<mode>"
12433   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12434         (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12435                         [(match_operator:GPR 2
12436                                       "branch_positive_comparison_operator"
12437                                       [(match_operand 3
12438                                                       "cc_reg_operand" "y,y")
12439                                        (const_int 0)])
12440                          (match_operator:GPR 4
12441                                       "branch_positive_comparison_operator"
12442                                       [(match_operand 5
12443                                                       "cc_reg_operand" "0,y")
12444                                        (const_int 0)])])
12445                       (const_int 1)))]
12446   ""
12447   "cr%q1 %E0,%j2,%j4"
12448   [(set_attr "type" "cr_logical")
12449    (set_attr "cr_logical_3op" "no,yes")])
12451 ; Why is the constant -1 here, but 1 in the previous pattern?
12452 ; Because ~1 has all but the low bit set.
12453 (define_insn "cceq_ior_compare_complement"
12454   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12455         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12456                         [(not:SI (match_operator:SI 2
12457                                       "branch_positive_comparison_operator"
12458                                       [(match_operand 3
12459                                                       "cc_reg_operand" "y,y")
12460                                        (const_int 0)]))
12461                          (match_operator:SI 4
12462                                 "branch_positive_comparison_operator"
12463                                 [(match_operand 5
12464                                                 "cc_reg_operand" "0,y")
12465                                  (const_int 0)])])
12466                       (const_int -1)))]
12467   ""
12468   "cr%q1 %E0,%j2,%j4"
12469   [(set_attr "type" "cr_logical")
12470    (set_attr "cr_logical_3op" "no,yes")])
12472 (define_insn "@cceq_rev_compare_<mode>"
12473   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12474         (compare:CCEQ (match_operator:GPR 1
12475                                       "branch_positive_comparison_operator"
12476                                       [(match_operand 2
12477                                                       "cc_reg_operand" "0,y")
12478                                        (const_int 0)])
12479                       (const_int 0)))]
12480   ""
12481   "crnot %E0,%j1"
12482   [(set_attr "type" "cr_logical")
12483    (set_attr "cr_logical_3op" "no,yes")])
12485 ;; If we are comparing the result of two comparisons, this can be done
12486 ;; using creqv or crxor.
12488 (define_insn_and_split ""
12489   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12490         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12491                               [(match_operand 2 "cc_reg_operand" "y")
12492                                (const_int 0)])
12493                       (match_operator 3 "branch_comparison_operator"
12494                               [(match_operand 4 "cc_reg_operand" "y")
12495                                (const_int 0)])))]
12496   ""
12497   "#"
12498   ""
12499   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12500                                     (match_dup 5)))]
12502   int positive_1, positive_2;
12504   positive_1 = branch_positive_comparison_operator (operands[1],
12505                                                     GET_MODE (operands[1]));
12506   positive_2 = branch_positive_comparison_operator (operands[3],
12507                                                     GET_MODE (operands[3]));
12509   if (! positive_1)
12510     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12511                                                             GET_CODE (operands[1])),
12512                                   SImode,
12513                                   operands[2], const0_rtx);
12514   else if (GET_MODE (operands[1]) != SImode)
12515     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12516                                   operands[2], const0_rtx);
12518   if (! positive_2)
12519     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12520                                                             GET_CODE (operands[3])),
12521                                   SImode,
12522                                   operands[4], const0_rtx);
12523   else if (GET_MODE (operands[3]) != SImode)
12524     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12525                                   operands[4], const0_rtx);
12527   if (positive_1 == positive_2)
12528     {
12529       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12530       operands[5] = constm1_rtx;
12531     }
12532   else
12533     {
12534       operands[5] = const1_rtx;
12535     }
12538 ;; Unconditional branch and return.
12540 (define_insn "jump"
12541   [(set (pc)
12542         (label_ref (match_operand 0)))]
12543   ""
12544   "b %l0"
12545   [(set_attr "type" "branch")])
12547 (define_insn "<return_str>return"
12548   [(any_return)]
12549   "<return_pred>"
12550   "blr"
12551   [(set_attr "type" "jmpreg")])
12553 (define_expand "indirect_jump"
12554   [(set (pc) (match_operand 0 "register_operand"))]
12555  ""
12557   if (!rs6000_speculate_indirect_jumps) {
12558     rtx ccreg = gen_reg_rtx (CCmode);
12559     emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12560     DONE;
12561   }
12564 (define_insn "*indirect_jump<mode>"
12565   [(set (pc)
12566         (match_operand:P 0 "register_operand" "c,*l"))]
12567   "rs6000_speculate_indirect_jumps"
12568   "b%T0"
12569   [(set_attr "type" "jmpreg")])
12571 (define_insn "@indirect_jump<mode>_nospec"
12572   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12573    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12574   "!rs6000_speculate_indirect_jumps"
12575   "crset %E1\;beq%T0- %1\;b $"
12576   [(set_attr "type" "jmpreg")
12577    (set_attr "length" "12")])
12579 ;; Table jump for switch statements:
12580 (define_expand "tablejump"
12581   [(use (match_operand 0))
12582    (use (label_ref (match_operand 1)))]
12583   ""
12585   if (rs6000_speculate_indirect_jumps)
12586     {
12587       if (TARGET_32BIT)
12588         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12589       else
12590         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12591     }
12592   else
12593     {
12594       rtx ccreg = gen_reg_rtx (CCmode);
12595       rtx jump;
12596       if (TARGET_32BIT)
12597         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12598       else
12599         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12600       emit_jump_insn (jump);
12601     }
12602   DONE;
12605 (define_expand "tablejumpsi"
12606   [(set (match_dup 3)
12607         (plus:SI (match_operand:SI 0)
12608                  (match_dup 2)))
12609    (parallel [(set (pc)
12610                    (match_dup 3))
12611               (use (label_ref (match_operand 1)))])]
12612   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12614   operands[0] = force_reg (SImode, operands[0]);
12615   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12616   operands[3] = gen_reg_rtx (SImode);
12619 (define_expand "tablejumpsi_nospec"
12620   [(set (match_dup 4)
12621         (plus:SI (match_operand:SI 0)
12622                  (match_dup 3)))
12623    (parallel [(set (pc)
12624                    (match_dup 4))
12625               (use (label_ref (match_operand 1)))
12626               (clobber (match_operand 2))])]
12627   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12629   operands[0] = force_reg (SImode, operands[0]);
12630   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12631   operands[4] = gen_reg_rtx (SImode);
12634 (define_expand "tablejumpdi"
12635   [(set (match_dup 4)
12636         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12637    (set (match_dup 3)
12638         (plus:DI (match_dup 4)
12639                  (match_dup 2)))
12640    (parallel [(set (pc)
12641                    (match_dup 3))
12642               (use (label_ref (match_operand 1)))])]
12643   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12645   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12646   operands[3] = gen_reg_rtx (DImode);
12647   operands[4] = gen_reg_rtx (DImode);
12650 (define_expand "tablejumpdi_nospec"
12651   [(set (match_dup 5)
12652         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12653    (set (match_dup 4)
12654         (plus:DI (match_dup 5)
12655                  (match_dup 3)))
12656    (parallel [(set (pc)
12657                    (match_dup 4))
12658               (use (label_ref (match_operand 1)))
12659               (clobber (match_operand 2))])]
12660   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12662   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12663   operands[4] = gen_reg_rtx (DImode);
12664   operands[5] = gen_reg_rtx (DImode);
12667 (define_insn "*tablejump<mode>_internal1"
12668   [(set (pc)
12669         (match_operand:P 0 "register_operand" "c,*l"))
12670    (use (label_ref (match_operand 1)))]
12671   "rs6000_speculate_indirect_jumps"
12672   "b%T0"
12673   [(set_attr "type" "jmpreg")])
12675 (define_insn "*tablejump<mode>_internal1_nospec"
12676   [(set (pc)
12677         (match_operand:P 0 "register_operand" "c,*l"))
12678    (use (label_ref (match_operand 1)))
12679    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12680   "!rs6000_speculate_indirect_jumps"
12681   "crset %E2\;beq%T0- %2\;b $"
12682   [(set_attr "type" "jmpreg")
12683    (set_attr "length" "12")])
12685 (define_insn "nop"
12686   [(unspec [(const_int 0)] UNSPEC_NOP)]
12687   ""
12688   "nop")
12690 (define_insn "group_ending_nop"
12691   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12692   ""
12694   operands[0] = gen_rtx_REG (Pmode,
12695                              rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12696   return "ori %0,%0,0";
12699 (define_insn "speculation_barrier"
12700   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12701   ""
12703   operands[0] = gen_rtx_REG (Pmode, 31);
12704   return "ori %0,%0,0";
12707 ;; Define the subtract-one-and-jump insns, starting with the template
12708 ;; so loop.c knows what to generate.
12710 (define_expand "doloop_end"
12711   [(use (match_operand 0))      ; loop pseudo
12712    (use (match_operand 1))]     ; label
12713   ""
12715   if (GET_MODE (operands[0]) != Pmode)
12716     FAIL;
12718   emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12719   DONE;
12722 (define_expand "@ctr<mode>"
12723   [(parallel [(set (pc)
12724                    (if_then_else (ne (match_operand:P 0 "register_operand")
12725                                      (const_int 1))
12726                                  (label_ref (match_operand 1))
12727                                  (pc)))
12728               (set (match_dup 0)
12729                    (plus:P (match_dup 0)
12730                             (const_int -1)))
12731               (clobber (match_scratch:CC 2))
12732               (clobber (match_scratch:P 3))])]
12733   ""
12734   "")
12736 ;; We need to be able to do this for any operand, including MEM, or we
12737 ;; will cause reload to blow up since we don't allow output reloads on
12738 ;; JUMP_INSNs.
12739 ;; For the length attribute to be calculated correctly, the
12740 ;; label MUST be operand 0.
12741 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12742 ;; the ctr<mode> insns.
12744 (define_code_iterator eqne [eq ne])
12745 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12746 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12748 (define_insn "<bd>_<mode>"
12749   [(set (pc)
12750         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12751                           (const_int 1))
12752                       (label_ref (match_operand 0))
12753                       (pc)))
12754    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12755         (plus:P (match_dup 1)
12756                 (const_int -1)))
12757    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12758    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12759   ""
12761   if (which_alternative != 0)
12762     return "#";
12763   else if (get_attr_length (insn) == 4)
12764     return "<bd> %l0";
12765   else
12766     return "<bd_neg> $+8\;b %l0";
12768   [(set_attr "type" "branch")
12769    (set_attr_alternative "length"
12770      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12771                              (const_int -32768))
12772                          (lt (minus (match_dup 0) (pc))
12773                              (const_int 32764)))
12774                     (const_int 4)
12775                     (const_int 8))
12776       (const_string "16")
12777       (const_string "20")
12778       (const_string "20")])])
12780 ;; Now the splitter if we could not allocate the CTR register
12781 (define_split
12782   [(set (pc)
12783         (if_then_else (match_operator 2 "comparison_operator"
12784                                       [(match_operand:P 1 "gpc_reg_operand")
12785                                        (const_int 1)])
12786                       (match_operand 5)
12787                       (match_operand 6)))
12788    (set (match_operand:P 0 "nonimmediate_operand")
12789         (plus:P (match_dup 1)
12790                 (const_int -1)))
12791    (clobber (match_scratch:CC 3))
12792    (clobber (match_scratch:P 4))]
12793   "reload_completed"
12794   [(set (pc)
12795         (if_then_else (match_dup 7)
12796                       (match_dup 5)
12797                       (match_dup 6)))]
12799   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12800                                 const0_rtx);
12801   emit_insn (gen_rtx_SET (operands[3],
12802                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12803   if (int_reg_operand (operands[0], <MODE>mode))
12804     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12805   else
12806     {
12807       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12808       emit_move_insn (operands[0], operands[4]);
12809     } 
12810     /* No DONE so branch comes from the pattern.  */
12813 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12814 ;; Note that in the case of long branches we have to decompose this into
12815 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12816 ;; and the CR bit, which means there is no way to conveniently invert the
12817 ;; comparison as is done with plain bdnz/bdz.
12819 (define_insn "<bd>tf_<mode>"
12820   [(set (pc)
12821         (if_then_else
12822           (and
12823              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12824                    (const_int 1))
12825              (match_operator 3 "branch_comparison_operator"
12826                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12827                        (const_int 0)]))
12828           (label_ref (match_operand 0))
12829           (pc)))
12830    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12831         (plus:P (match_dup 1)
12832                 (const_int -1)))
12833    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12834    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12835    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12836   ""
12838   if (which_alternative != 0)
12839     return "#";
12840   else if (get_attr_length (insn) == 4)
12841     {
12842       if (branch_positive_comparison_operator (operands[3],
12843                                                GET_MODE (operands[3])))
12844         return "<bd>t %j3,%l0";
12845       else
12846         return "<bd>f %j3,%l0";
12847     }
12848   else
12849     {
12850       static char seq[96];
12851       char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12852       sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12853       return seq;
12854     }
12856   [(set_attr "type" "branch")
12857    (set_attr_alternative "length"
12858      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12859                              (const_int -32768))
12860                          (lt (minus (match_dup 0) (pc))
12861                              (const_int 32764)))
12862                     (const_int 4)
12863                     (const_int 8))
12864       (const_string "16")
12865       (const_string "20")
12866       (const_string "20")])])
12868 ;; Now the splitter if we could not allocate the CTR register
12869 (define_split
12870   [(set (pc)
12871         (if_then_else
12872           (and
12873              (match_operator 1 "comparison_operator"
12874                              [(match_operand:P 0 "gpc_reg_operand")
12875                               (const_int 1)])
12876              (match_operator 3 "branch_comparison_operator"
12877                       [(match_operand 2 "cc_reg_operand")
12878                        (const_int 0)]))
12879           (match_operand 4)
12880           (match_operand 5)))
12881    (set (match_operand:P 6 "nonimmediate_operand")
12882         (plus:P (match_dup 0)
12883                 (const_int -1)))
12884    (clobber (match_scratch:P 7))
12885    (clobber (match_scratch:CC 8))
12886    (clobber (match_scratch:CCEQ 9))]
12887   "reload_completed"
12888 [(pc)]
12890   rtx ctr = operands[0];
12891   rtx ctrcmp = operands[1];
12892   rtx ccin = operands[2];
12893   rtx cccmp = operands[3];
12894   rtx dst1 = operands[4];
12895   rtx dst2 = operands[5];
12896   rtx ctrout = operands[6];
12897   rtx ctrtmp = operands[7];
12898   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12899   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12900   if (!ispos)
12901     cmpcode = reverse_condition (cmpcode);
12902   /* Generate crand/crandc here.  */
12903   emit_insn (gen_rtx_SET (operands[8],
12904                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12905   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12907   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12908   if (ispos)
12909      emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
12910                                       operands[8], cccmp, ccin));
12911   else
12912      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12913                                                  operands[8], cccmp, ccin));
12914   if (int_reg_operand (ctrout, <MODE>mode))
12915      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12916   else
12917     {
12918       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12919       emit_move_insn (ctrout, ctrtmp);
12920     }
12921   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12922   emit_jump_insn (gen_rtx_SET (pc_rtx,
12923                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12924                                                      dst1, dst2)));
12925   DONE;
12929 (define_insn "trap"
12930   [(trap_if (const_int 1) (const_int 0))]
12931   ""
12932   "trap"
12933   [(set_attr "type" "trap")])
12935 (define_expand "ctrap<mode>4"
12936   [(trap_if (match_operator 0 "ordered_comparison_operator"
12937                             [(match_operand:GPR 1 "register_operand")
12938                              (match_operand:GPR 2 "reg_or_short_operand")])
12939             (match_operand 3 "zero_constant" ""))]
12940   ""
12941   "")
12943 (define_insn ""
12944   [(trap_if (match_operator 0 "ordered_comparison_operator"
12945                             [(match_operand:GPR 1 "register_operand" "r")
12946                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12947             (const_int 0))]
12948   ""
12949   "t<wd>%V0%I2 %1,%2"
12950   [(set_attr "type" "trap")])
12952 ;; Insns related to generating the function prologue and epilogue.
12954 (define_expand "prologue"
12955   [(use (const_int 0))]
12956   ""
12958   rs6000_emit_prologue ();
12959   if (!TARGET_SCHED_PROLOG)
12960     emit_insn (gen_blockage ());
12961   DONE;
12964 (define_insn "*movesi_from_cr_one"
12965   [(match_parallel 0 "mfcr_operation"
12966                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12967                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12968                                      (match_operand 3 "immediate_operand" "n")]
12969                           UNSPEC_MOVESI_FROM_CR))])]
12970   "TARGET_MFCRF"
12972   int mask = 0;
12973   int i;
12974   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12975   {
12976     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12977     operands[4] = GEN_INT (mask);
12978     output_asm_insn ("mfcr %1,%4", operands);
12979   }
12980   return "";
12982   [(set_attr "type" "mfcrf")])
12984 ;; Don't include the volatile CRs since their values are not used wrt CR save
12985 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12986 ;; prologue past an insn (early exit test) that defines a register used in the
12987 ;; prologue.
12988 (define_insn "prologue_movesi_from_cr"
12989   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12990         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12991                     (reg:CC CR4_REGNO)]
12992                    UNSPEC_MOVESI_FROM_CR))]
12993   ""
12994   "mfcr %0"
12995   [(set_attr "type" "mfcr")])
12997 (define_insn "*crsave"
12998   [(match_parallel 0 "crsave_operation"
12999                    [(set (match_operand:SI 1 "memory_operand" "=m")
13000                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13001   ""
13002   "stw %2,%1"
13003   [(set_attr "type" "store")])
13005 (define_insn "*stmw"
13006   [(match_parallel 0 "stmw_operation"
13007                    [(set (match_operand:SI 1 "memory_operand" "=m")
13008                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13009   "TARGET_MULTIPLE"
13010   "stmw %2,%1"
13011   [(set_attr "type" "store")
13012    (set_attr "update" "yes")
13013    (set_attr "indexed" "yes")])
13015 ; The following comment applies to:
13016 ;     save_gpregs_*
13017 ;     save_fpregs_*
13018 ;     restore_gpregs*
13019 ;     return_and_restore_gpregs*
13020 ;     return_and_restore_fpregs*
13021 ;     return_and_restore_fpregs_aix*
13023 ; The out-of-line save / restore functions expects one input argument.
13024 ; Since those are not standard call_insn's, we must avoid using
13025 ; MATCH_OPERAND for that argument. That way the register rename
13026 ; optimization will not try to rename this register.
13027 ; Each pattern is repeated for each possible register number used in 
13028 ; various ABIs (r11, r1, and for some functions r12)
13030 (define_insn "*save_gpregs_<mode>_r11"
13031   [(match_parallel 0 "any_parallel_operand"
13032                    [(clobber (reg:P LR_REGNO))
13033                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13034                     (use (reg:P 11))
13035                     (set (match_operand:P 2 "memory_operand" "=m")
13036                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13037   ""
13038   "bl %1"
13039   [(set_attr "type" "branch")])
13041 (define_insn "*save_gpregs_<mode>_r12"
13042   [(match_parallel 0 "any_parallel_operand"
13043                    [(clobber (reg:P LR_REGNO))
13044                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13045                     (use (reg:P 12))
13046                     (set (match_operand:P 2 "memory_operand" "=m")
13047                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13048   ""
13049   "bl %1"
13050   [(set_attr "type" "branch")])
13052 (define_insn "*save_gpregs_<mode>_r1"
13053   [(match_parallel 0 "any_parallel_operand"
13054                    [(clobber (reg:P LR_REGNO))
13055                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13056                     (use (reg:P 1))
13057                     (set (match_operand:P 2 "memory_operand" "=m")
13058                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13059   ""
13060   "bl %1"
13061   [(set_attr "type" "branch")])
13063 (define_insn "*save_fpregs_<mode>_r11"
13064   [(match_parallel 0 "any_parallel_operand"
13065                    [(clobber (reg:P LR_REGNO))
13066                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13067                     (use (reg:P 11))
13068                     (set (match_operand:DF 2 "memory_operand" "=m")
13069                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13070   ""
13071   "bl %1"
13072   [(set_attr "type" "branch")])
13074 (define_insn "*save_fpregs_<mode>_r12"
13075   [(match_parallel 0 "any_parallel_operand"
13076                    [(clobber (reg:P LR_REGNO))
13077                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13078                     (use (reg:P 12))
13079                     (set (match_operand:DF 2 "memory_operand" "=m")
13080                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13081   ""
13082   "bl %1"
13083   [(set_attr "type" "branch")])
13085 (define_insn "*save_fpregs_<mode>_r1"
13086   [(match_parallel 0 "any_parallel_operand"
13087                    [(clobber (reg:P LR_REGNO))
13088                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13089                     (use (reg:P 1))
13090                     (set (match_operand:DF 2 "memory_operand" "=m")
13091                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13092   ""
13093   "bl %1"
13094   [(set_attr "type" "branch")])
13096 ; This is to explain that changes to the stack pointer should
13097 ; not be moved over loads from or stores to stack memory.
13098 (define_insn "stack_tie"
13099   [(match_parallel 0 "tie_operand"
13100                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13101   ""
13102   ""
13103   [(set_attr "length" "0")])
13105 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13106 ; stay behind all restores from the stack, it cannot be reordered to before
13107 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13108 (define_insn "stack_restore_tie"
13109   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13110         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13111                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13112    (set (mem:BLK (scratch)) (const_int 0))]
13113   "TARGET_32BIT"
13114   "@
13115    mr %0,%1
13116    add%I2 %0,%1,%2"
13117   [(set_attr "type" "*,add")])
13119 (define_expand "epilogue"
13120   [(use (const_int 0))]
13121   ""
13123   if (!TARGET_SCHED_PROLOG)
13124     emit_insn (gen_blockage ());
13125   rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13126   DONE;
13129 ; On some processors, doing the mtcrf one CC register at a time is
13130 ; faster (like on the 604e).  On others, doing them all at once is
13131 ; faster; for instance, on the 601 and 750.
13133 (define_expand "movsi_to_cr_one"
13134   [(set (match_operand:CC 0 "cc_reg_operand")
13135         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13136                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13137   ""
13138   "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13140 (define_insn "*movsi_to_cr"
13141   [(match_parallel 0 "mtcrf_operation"
13142                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13143                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13144                                      (match_operand 3 "immediate_operand" "n")]
13145                                     UNSPEC_MOVESI_TO_CR))])]
13146  ""
13148   int mask = 0;
13149   int i;
13150   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13151     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13152   operands[4] = GEN_INT (mask);
13153   return "mtcrf %4,%2";
13155   [(set_attr "type" "mtcr")])
13157 (define_insn "*mtcrfsi"
13158   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13159         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13160                     (match_operand 2 "immediate_operand" "n")]
13161                    UNSPEC_MOVESI_TO_CR))]
13162   "REG_P (operands[0])
13163    && CR_REGNO_P (REGNO (operands[0]))
13164    && CONST_INT_P (operands[2])
13165    && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13166   "mtcrf %R0,%1"
13167   [(set_attr "type" "mtcr")])
13169 ; The load-multiple instructions have similar properties.
13170 ; Note that "load_multiple" is a name known to the machine-independent
13171 ; code that actually corresponds to the PowerPC load-string.
13173 (define_insn "*lmw"
13174   [(match_parallel 0 "lmw_operation"
13175                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13176                          (match_operand:SI 2 "memory_operand" "m"))])]
13177   "TARGET_MULTIPLE"
13178   "lmw %1,%2"
13179   [(set_attr "type" "load")
13180    (set_attr "update" "yes")
13181    (set_attr "indexed" "yes")
13182    (set_attr "cell_micro" "always")])
13184 ; FIXME: "any_parallel_operand" is a bit flexible...
13186 ; The following comment applies to:
13187 ;     save_gpregs_*
13188 ;     save_fpregs_*
13189 ;     restore_gpregs*
13190 ;     return_and_restore_gpregs*
13191 ;     return_and_restore_fpregs*
13192 ;     return_and_restore_fpregs_aix*
13194 ; The out-of-line save / restore functions expects one input argument.
13195 ; Since those are not standard call_insn's, we must avoid using
13196 ; MATCH_OPERAND for that argument. That way the register rename
13197 ; optimization will not try to rename this register.
13198 ; Each pattern is repeated for each possible register number used in 
13199 ; various ABIs (r11, r1, and for some functions r12)
13201 (define_insn "*restore_gpregs_<mode>_r11"
13202  [(match_parallel 0 "any_parallel_operand"
13203                   [(clobber (reg:P LR_REGNO))
13204                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13205                    (use (reg:P 11))
13206                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13207                         (match_operand:P 3 "memory_operand" "m"))])]
13208  ""
13209  "bl %1"
13210  [(set_attr "type" "branch")])
13212 (define_insn "*restore_gpregs_<mode>_r12"
13213  [(match_parallel 0 "any_parallel_operand"
13214                   [(clobber (reg:P LR_REGNO))
13215                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13216                    (use (reg:P 12))
13217                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13218                         (match_operand:P 3 "memory_operand" "m"))])]
13219  ""
13220  "bl %1"
13221  [(set_attr "type" "branch")])
13223 (define_insn "*restore_gpregs_<mode>_r1"
13224  [(match_parallel 0 "any_parallel_operand"
13225                   [(clobber (reg:P LR_REGNO))
13226                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13227                    (use (reg:P 1))
13228                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13229                         (match_operand:P 3 "memory_operand" "m"))])]
13230  ""
13231  "bl %1"
13232  [(set_attr "type" "branch")])
13234 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13235  [(match_parallel 0 "any_parallel_operand"
13236                   [(return)
13237                    (clobber (reg:P LR_REGNO))
13238                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13239                    (use (reg:P 11))
13240                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13241                         (match_operand:P 3 "memory_operand" "m"))])]
13242  ""
13243  "b %1"
13244  [(set_attr "type" "branch")])
13246 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13247  [(match_parallel 0 "any_parallel_operand"
13248                   [(return)
13249                    (clobber (reg:P LR_REGNO))
13250                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13251                    (use (reg:P 12))
13252                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13253                         (match_operand:P 3 "memory_operand" "m"))])]
13254  ""
13255  "b %1"
13256  [(set_attr "type" "branch")])
13258 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13259  [(match_parallel 0 "any_parallel_operand"
13260                   [(return)
13261                    (clobber (reg:P LR_REGNO))
13262                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13263                    (use (reg:P 1))
13264                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13265                         (match_operand:P 3 "memory_operand" "m"))])]
13266  ""
13267  "b %1"
13268  [(set_attr "type" "branch")])
13270 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13271  [(match_parallel 0 "any_parallel_operand"
13272                   [(return)
13273                    (clobber (reg:P LR_REGNO))
13274                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13275                    (use (reg:P 11))
13276                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13277                         (match_operand:DF 3 "memory_operand" "m"))])]
13278  ""
13279  "b %1"
13280  [(set_attr "type" "branch")])
13282 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13283  [(match_parallel 0 "any_parallel_operand"
13284                   [(return)
13285                    (clobber (reg:P LR_REGNO))
13286                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13287                    (use (reg:P 12))
13288                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13289                         (match_operand:DF 3 "memory_operand" "m"))])]
13290  ""
13291  "b %1"
13292  [(set_attr "type" "branch")])
13294 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13295  [(match_parallel 0 "any_parallel_operand"
13296                   [(return)
13297                    (clobber (reg:P LR_REGNO))
13298                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13299                    (use (reg:P 1))
13300                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13301                         (match_operand:DF 3 "memory_operand" "m"))])]
13302  ""
13303  "b %1"
13304  [(set_attr "type" "branch")])
13306 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13307  [(match_parallel 0 "any_parallel_operand"
13308                   [(return)
13309                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13310                    (use (reg:P 11))
13311                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13312                         (match_operand:DF 3 "memory_operand" "m"))])]
13313  ""
13314  "b %1"
13315  [(set_attr "type" "branch")])
13317 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13318  [(match_parallel 0 "any_parallel_operand"
13319                   [(return)
13320                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13321                    (use (reg:P 1))
13322                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13323                         (match_operand:DF 3 "memory_operand" "m"))])]
13324  ""
13325  "b %1"
13326  [(set_attr "type" "branch")])
13328 ; This is used in compiling the unwind routines.
13329 (define_expand "eh_return"
13330   [(use (match_operand 0 "general_operand"))]
13331   ""
13333   emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13334   DONE;
13337 ; We can't expand this before we know where the link register is stored.
13338 (define_insn_and_split "@eh_set_lr_<mode>"
13339   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13340    (clobber (match_scratch:P 1 "=&b"))]
13341   ""
13342   "#"
13343   "reload_completed"
13344   [(const_int 0)]
13346   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13347   DONE;
13350 (define_insn "prefetch"
13351   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13352              (match_operand:SI 1 "const_int_operand" "n")
13353              (match_operand:SI 2 "const_int_operand" "n"))]
13354   ""
13358   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13359      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13360      The AIX assembler does not support the three operand form of dcbt
13361      and dcbtst on Power 7 (-mpwr7).  */
13362   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13364   if (REG_P (operands[0]))
13365     {
13366       if (INTVAL (operands[1]) == 0)
13367         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13368       else
13369         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13370     }
13371   else
13372     {
13373       if (INTVAL (operands[1]) == 0)
13374         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13375       else
13376         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13377     }
13379   [(set_attr "type" "load")])
13381 ;; Handle -fsplit-stack.
13383 (define_expand "split_stack_prologue"
13384   [(const_int 0)]
13385   ""
13387   rs6000_expand_split_stack_prologue ();
13388   DONE;
13391 (define_expand "load_split_stack_limit"
13392   [(set (match_operand 0)
13393         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13394   ""
13396   emit_insn (gen_rtx_SET (operands[0],
13397                           gen_rtx_UNSPEC (Pmode,
13398                                           gen_rtvec (1, const0_rtx),
13399                                           UNSPEC_STACK_CHECK)));
13400   DONE;
13403 (define_insn "load_split_stack_limit_di"
13404   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13405         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13406   "TARGET_64BIT"
13407   "ld %0,-0x7040(13)"
13408   [(set_attr "type" "load")
13409    (set_attr "update" "no")
13410    (set_attr "indexed" "no")])
13412 (define_insn "load_split_stack_limit_si"
13413   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13414         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13415   "!TARGET_64BIT"
13416   "lwz %0,-0x7020(2)"
13417   [(set_attr "type" "load")
13418    (set_attr "update" "no")
13419    (set_attr "indexed" "no")])
13421 ;; A return instruction which the middle-end doesn't see.
13422 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13423 ;; after the call to __morestack.
13424 (define_insn "split_stack_return"
13425   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13426   ""
13427   "blr"
13428   [(set_attr "type" "jmpreg")])
13430 ;; If there are operand 0 bytes available on the stack, jump to
13431 ;; operand 1.
13432 (define_expand "split_stack_space_check"
13433   [(set (match_dup 2)
13434         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13435    (set (match_dup 3)
13436         (minus (reg STACK_POINTER_REGNUM)
13437                (match_operand 0)))
13438    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13439    (set (pc) (if_then_else
13440               (geu (match_dup 4) (const_int 0))
13441               (label_ref (match_operand 1))
13442               (pc)))]
13443   ""
13445   rs6000_split_stack_space_check (operands[0], operands[1]);
13446   DONE;
13449 (define_insn "bpermd_<mode>"
13450   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13451         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13452                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13453   "TARGET_POPCNTD"
13454   "bpermd %0,%1,%2"
13455   [(set_attr "type" "popcnt")])
13458 ;; Builtin fma support.  Handle 
13459 ;; Note that the conditions for expansion are in the FMA_F iterator.
13461 (define_expand "fma<mode>4"
13462   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13463         (fma:FMA_F
13464           (match_operand:FMA_F 1 "gpc_reg_operand")
13465           (match_operand:FMA_F 2 "gpc_reg_operand")
13466           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13467   ""
13468   "")
13470 (define_insn "*fma<mode>4_fpr"
13471   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13472         (fma:SFDF
13473           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13474           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13475           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13476   "TARGET_HARD_FLOAT"
13477   "@
13478    fmadd<s> %0,%1,%2,%3
13479    xsmadda<sd>p %x0,%x1,%x2
13480    xsmaddm<sd>p %x0,%x1,%x3"
13481   [(set_attr "type" "fp")
13482    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13484 ; Altivec only has fma and nfms.
13485 (define_expand "fms<mode>4"
13486   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13487         (fma:FMA_F
13488           (match_operand:FMA_F 1 "gpc_reg_operand")
13489           (match_operand:FMA_F 2 "gpc_reg_operand")
13490           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13491   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13492   "")
13494 (define_insn "*fms<mode>4_fpr"
13495   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13496         (fma:SFDF
13497          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13498          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13499          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13500   "TARGET_HARD_FLOAT"
13501   "@
13502    fmsub<s> %0,%1,%2,%3
13503    xsmsuba<sd>p %x0,%x1,%x2
13504    xsmsubm<sd>p %x0,%x1,%x3"
13505   [(set_attr "type" "fp")
13506    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13508 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13509 (define_expand "fnma<mode>4"
13510   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13511         (neg:FMA_F
13512           (fma:FMA_F
13513             (match_operand:FMA_F 1 "gpc_reg_operand")
13514             (match_operand:FMA_F 2 "gpc_reg_operand")
13515             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13516   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13517   "")
13519 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13520 (define_expand "fnms<mode>4"
13521   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13522         (neg:FMA_F
13523           (fma:FMA_F
13524             (match_operand:FMA_F 1 "gpc_reg_operand")
13525             (match_operand:FMA_F 2 "gpc_reg_operand")
13526             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13527   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13528   "")
13530 ; Not an official optab name, but used from builtins.
13531 (define_expand "nfma<mode>4"
13532   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13533         (neg:FMA_F
13534           (fma:FMA_F
13535             (match_operand:FMA_F 1 "gpc_reg_operand")
13536             (match_operand:FMA_F 2 "gpc_reg_operand")
13537             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13538   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13539   "")
13541 (define_insn "*nfma<mode>4_fpr"
13542   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13543         (neg:SFDF
13544          (fma:SFDF
13545           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13546           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13547           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13548   "TARGET_HARD_FLOAT"
13549   "@
13550    fnmadd<s> %0,%1,%2,%3
13551    xsnmadda<sd>p %x0,%x1,%x2
13552    xsnmaddm<sd>p %x0,%x1,%x3"
13553   [(set_attr "type" "fp")
13554    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13556 ; Not an official optab name, but used from builtins.
13557 (define_expand "nfms<mode>4"
13558   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13559         (neg:FMA_F
13560           (fma:FMA_F
13561             (match_operand:FMA_F 1 "gpc_reg_operand")
13562             (match_operand:FMA_F 2 "gpc_reg_operand")
13563             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13564   ""
13565   "")
13567 (define_insn "*nfmssf4_fpr"
13568   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13569         (neg:SFDF
13570          (fma:SFDF
13571           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13572           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13573           (neg:SFDF
13574            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13575   "TARGET_HARD_FLOAT"
13576   "@
13577    fnmsub<s> %0,%1,%2,%3
13578    xsnmsuba<sd>p %x0,%x1,%x2
13579    xsnmsubm<sd>p %x0,%x1,%x3"
13580   [(set_attr "type" "fp")
13581    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13583 (define_expand "rs6000_get_timebase"
13584   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13585   ""
13587   if (TARGET_POWERPC64)
13588     emit_insn (gen_rs6000_mftb_di (operands[0]));
13589   else
13590     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13591   DONE;
13594 (define_insn "rs6000_get_timebase_ppc32"
13595   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13596         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13597    (clobber (match_scratch:SI 1 "=r"))
13598    (clobber (match_scratch:CC 2 "=y"))]
13599   "!TARGET_POWERPC64"
13601   if (WORDS_BIG_ENDIAN)
13602     if (TARGET_MFCRF)
13603       {
13604         return "mfspr %0,269\;"
13605                "mfspr %L0,268\;"
13606                "mfspr %1,269\;"
13607                "cmpw %2,%0,%1\;"
13608                "bne- %2,$-16";
13609       }
13610     else
13611       {
13612         return "mftbu %0\;"
13613                "mftb %L0\;"
13614                "mftbu %1\;"
13615                "cmpw %2,%0,%1\;"
13616                "bne- %2,$-16";
13617       }
13618   else
13619     if (TARGET_MFCRF)
13620       {
13621         return "mfspr %L0,269\;"
13622                "mfspr %0,268\;"
13623                "mfspr %1,269\;"
13624                "cmpw %2,%L0,%1\;"
13625                "bne- %2,$-16";
13626       }
13627     else
13628       {
13629         return "mftbu %L0\;"
13630                "mftb %0\;"
13631                "mftbu %1\;"
13632                "cmpw %2,%L0,%1\;"
13633                "bne- %2,$-16";
13634       }
13636   [(set_attr "length" "20")])
13638 (define_insn "rs6000_mftb_<mode>"
13639   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13640         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13641   ""
13643   if (TARGET_MFCRF)
13644     return "mfspr %0,268";
13645   else
13646     return "mftb %0";
13650 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13651 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13652 (define_insn "rs6000_mffsl_hw"
13653   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13654         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13655   "TARGET_HARD_FLOAT"
13656   "mffsl %0")
13658 (define_expand "rs6000_mffsl"
13659   [(set (match_operand:DF 0 "gpc_reg_operand")
13660         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13661   "TARGET_HARD_FLOAT"
13663   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13664      otherwise fall back to the older mffs instruction to emulate the mffsl
13665      instruction.  */
13667   if (!TARGET_P9_MISC)
13668     {
13669        rtx tmp_di = gen_reg_rtx (DImode);
13670        rtx tmp_df = gen_reg_rtx (DFmode);
13672        /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13673           instruction using the mffs instruction and masking off the bits
13674           the mmsl instruciton actually reads.  */
13675        emit_insn (gen_rs6000_mffs (tmp_df));
13676        tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13677        emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13679        operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13680        DONE;
13681     }
13683     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13684     DONE;
13687 (define_insn "rs6000_mffs"
13688   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13689         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13690   "TARGET_HARD_FLOAT"
13691   "mffs %0")
13693 (define_insn "rs6000_mtfsf"
13694   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13695                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13696                     UNSPECV_MTFSF)]
13697   "TARGET_HARD_FLOAT"
13698   "mtfsf %0,%1")
13700 (define_insn "rs6000_mtfsf_hi"
13701   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13702                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13703                     UNSPECV_MTFSF_HI)]
13704   "TARGET_HARD_FLOAT"
13705   "mtfsf %0,%1,0,1")
13708 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13709 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13710 ;; register that is being loaded.  The fused ops must be physically adjacent.
13712 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13713 ;; peephole2 then gathers any other fused possibilities that it can find after
13714 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13715 ;; point loads/stores.
13717 ;; Find cases where the addis that feeds into a load instruction is either used
13718 ;; once or is the same as the target register, and replace it with the fusion
13719 ;; insn
13721 (define_peephole2
13722   [(set (match_operand:P 0 "base_reg_operand")
13723         (match_operand:P 1 "fusion_gpr_addis"))
13724    (set (match_operand:INT1 2 "base_reg_operand")
13725         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13726   "TARGET_P8_FUSION
13727    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13728                          operands[3])"
13729   [(const_int 0)]
13731   expand_fusion_gpr_load (operands);
13732   DONE;
13735 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13736 ;; reload)
13738 (define_insn "*fusion_gpr_load_<mode>"
13739   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13740         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13741                      UNSPEC_FUSION_GPR))]
13742   "TARGET_P8_FUSION"
13744   return emit_fusion_gpr_load (operands[0], operands[1]);
13746   [(set_attr "type" "load")
13747    (set_attr "length" "8")])
13750 ;; Optimize cases where we want to do a D-form load (register+offset) on
13751 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13752 ;; has generated:
13753 ;;      LFD 0,32(3)
13754 ;;      XXLOR 32,0,0
13756 ;; and we change this to:
13757 ;;      LI 0,32
13758 ;;      LXSDX 32,3,9
13760 (define_peephole2
13761   [(match_scratch:P 0 "b")
13762    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13763         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13764    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13765         (match_dup 1))]
13766   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13767   [(set (match_dup 0)
13768         (match_dup 4))
13769    (set (match_dup 3)
13770         (match_dup 5))]
13772   rtx tmp_reg = operands[0];
13773   rtx mem = operands[2];
13774   rtx addr = XEXP (mem, 0);
13775   rtx add_op0, add_op1, new_addr;
13777   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13778   add_op0 = XEXP (addr, 0);
13779   add_op1 = XEXP (addr, 1);
13780   gcc_assert (REG_P (add_op0));
13781   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13783   operands[4] = add_op1;
13784   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13787 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13788 ;; Altivec register, and the register allocator has generated:
13789 ;;      XXLOR 0,32,32
13790 ;;      STFD 0,32(3)
13792 ;; and we change this to:
13793 ;;      LI 0,32
13794 ;;      STXSDX 32,3,9
13796 (define_peephole2
13797   [(match_scratch:P 0 "b")
13798    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13799         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13800    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13801         (match_dup 1))]
13802   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13803   [(set (match_dup 0)
13804         (match_dup 4))
13805    (set (match_dup 5)
13806         (match_dup 2))]
13808   rtx tmp_reg = operands[0];
13809   rtx mem = operands[3];
13810   rtx addr = XEXP (mem, 0);
13811   rtx add_op0, add_op1, new_addr;
13813   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13814   add_op0 = XEXP (addr, 0);
13815   add_op1 = XEXP (addr, 1);
13816   gcc_assert (REG_P (add_op0));
13817   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13819   operands[4] = add_op1;
13820   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13822    
13824 ;; Miscellaneous ISA 2.06 (power7) instructions
13825 (define_insn "addg6s"
13826   [(set (match_operand:SI 0 "register_operand" "=r")
13827         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13828                     (match_operand:SI 2 "register_operand" "r")]
13829                    UNSPEC_ADDG6S))]
13830   "TARGET_POPCNTD"
13831   "addg6s %0,%1,%2"
13832   [(set_attr "type" "integer")])
13834 (define_insn "cdtbcd"
13835   [(set (match_operand:SI 0 "register_operand" "=r")
13836         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13837                    UNSPEC_CDTBCD))]
13838   "TARGET_POPCNTD"
13839   "cdtbcd %0,%1"
13840   [(set_attr "type" "integer")])
13842 (define_insn "cbcdtd"
13843   [(set (match_operand:SI 0 "register_operand" "=r")
13844         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13845                    UNSPEC_CBCDTD))]
13846   "TARGET_POPCNTD"
13847   "cbcdtd %0,%1"
13848   [(set_attr "type" "integer")])
13850 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13851                                         UNSPEC_DIVEU])
13853 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13854                              (UNSPEC_DIVEU      "eu")])
13856 (define_insn "div<div_extend>_<mode>"
13857   [(set (match_operand:GPR 0 "register_operand" "=r")
13858         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13859                      (match_operand:GPR 2 "register_operand" "r")]
13860                     UNSPEC_DIV_EXTEND))]
13861   "TARGET_POPCNTD"
13862   "div<wd><div_extend> %0,%1,%2"
13863   [(set_attr "type" "div")
13864    (set_attr "size" "<bits>")])
13867 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13869 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13870 (define_mode_attr FP128_64 [(TF "DF")
13871                             (IF "DF")
13872                             (TD "DI")
13873                             (KF "DI")])
13875 (define_expand "unpack<mode>"
13876   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13877         (unspec:<FP128_64>
13878          [(match_operand:FMOVE128 1 "register_operand")
13879           (match_operand:QI 2 "const_0_to_1_operand")]
13880          UNSPEC_UNPACK_128BIT))]
13881   "FLOAT128_2REG_P (<MODE>mode)"
13882   "")
13884 (define_insn_and_split "unpack<mode>_dm"
13885   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13886         (unspec:<FP128_64>
13887          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13888           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13889          UNSPEC_UNPACK_128BIT))]
13890   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13891   "#"
13892   "&& reload_completed"
13893   [(set (match_dup 0) (match_dup 3))]
13895   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13897   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13898     {
13899       emit_note (NOTE_INSN_DELETED);
13900       DONE;
13901     }
13903   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13905   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13907 (define_insn_and_split "unpack<mode>_nodm"
13908   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13909         (unspec:<FP128_64>
13910          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13911           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13912          UNSPEC_UNPACK_128BIT))]
13913   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13914   "#"
13915   "&& reload_completed"
13916   [(set (match_dup 0) (match_dup 3))]
13918   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13920   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13921     {
13922       emit_note (NOTE_INSN_DELETED);
13923       DONE;
13924     }
13926   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13928   [(set_attr "type" "fp,fpstore")])
13930 (define_insn_and_split "pack<mode>"
13931   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13932         (unspec:FMOVE128
13933          [(match_operand:<FP128_64> 1 "register_operand" "d")
13934           (match_operand:<FP128_64> 2 "register_operand" "d")]
13935          UNSPEC_PACK_128BIT))]
13936   "FLOAT128_2REG_P (<MODE>mode)"
13937   "#"
13938   "&& reload_completed"
13939   [(set (match_dup 3) (match_dup 1))
13940    (set (match_dup 4) (match_dup 2))]
13942   unsigned dest_hi = REGNO (operands[0]);
13943   unsigned dest_lo = dest_hi + 1;
13945   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13946   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13948   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13949   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13951   [(set_attr "type" "fp")
13952    (set_attr "length" "8")])
13954 (define_insn "unpack<mode>"
13955   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13956         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13957                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13958          UNSPEC_UNPACK_128BIT))]
13959   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13961   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13962     return ASM_COMMENT_START " xxpermdi to same register";
13964   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13965   return "xxpermdi %x0,%x1,%x1,%3";
13967   [(set_attr "type" "vecperm")])
13969 (define_insn "pack<mode>"
13970   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13971         (unspec:FMOVE128_VSX
13972          [(match_operand:DI 1 "register_operand" "wa")
13973           (match_operand:DI 2 "register_operand" "wa")]
13974          UNSPEC_PACK_128BIT))]
13975   "TARGET_VSX"
13976   "xxpermdi %x0,%x1,%x2,0"
13977   [(set_attr "type" "vecperm")])
13981 ;; ISA 2.08 IEEE 128-bit floating point support.
13983 (define_insn "add<mode>3"
13984   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13985         (plus:IEEE128
13986          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13987          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13988   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13989   "xsaddqp %0,%1,%2"
13990   [(set_attr "type" "vecfloat")
13991    (set_attr "size" "128")])
13993 (define_insn "sub<mode>3"
13994   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13995         (minus:IEEE128
13996          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13997          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13998   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13999   "xssubqp %0,%1,%2"
14000   [(set_attr "type" "vecfloat")
14001    (set_attr "size" "128")])
14003 (define_insn "mul<mode>3"
14004   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14005         (mult:IEEE128
14006          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14007          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14008   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14009   "xsmulqp %0,%1,%2"
14010   [(set_attr "type" "qmul")
14011    (set_attr "size" "128")])
14013 (define_insn "div<mode>3"
14014   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14015         (div:IEEE128
14016          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14017          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14018   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14019   "xsdivqp %0,%1,%2"
14020   [(set_attr "type" "vecdiv")
14021    (set_attr "size" "128")])
14023 (define_insn "sqrt<mode>2"
14024   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14025         (sqrt:IEEE128
14026          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14027   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14028    "xssqrtqp %0,%1"
14029   [(set_attr "type" "vecdiv")
14030    (set_attr "size" "128")])
14032 (define_expand "copysign<mode>3"
14033   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14034    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14035    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14036   "FLOAT128_IEEE_P (<MODE>mode)"
14038   if (TARGET_FLOAT128_HW)
14039     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14040                                          operands[2]));
14041   else
14042     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14043                                          operands[2]));
14044   DONE;
14047 (define_insn "copysign<mode>3_hard"
14048   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14049         (unspec:IEEE128
14050          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14051           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14052          UNSPEC_COPYSIGN))]
14053   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14054    "xscpsgnqp %0,%2,%1"
14055   [(set_attr "type" "vecmove")
14056    (set_attr "size" "128")])
14058 (define_insn "copysign<mode>3_soft"
14059   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14060         (unspec:IEEE128
14061          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14062           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14063          UNSPEC_COPYSIGN))
14064    (clobber (match_scratch:IEEE128 3 "=&v"))]
14065   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14066    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14067   [(set_attr "type" "veccomplex")
14068    (set_attr "length" "8")])
14070 (define_insn "@neg<mode>2_hw"
14071   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14072         (neg:IEEE128
14073          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14074   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14075   "xsnegqp %0,%1"
14076   [(set_attr "type" "vecmove")
14077    (set_attr "size" "128")])
14080 (define_insn "@abs<mode>2_hw"
14081   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14082         (abs:IEEE128
14083          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14084   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14085   "xsabsqp %0,%1"
14086   [(set_attr "type" "vecmove")
14087    (set_attr "size" "128")])
14090 (define_insn "*nabs<mode>2_hw"
14091   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14092         (neg:IEEE128
14093          (abs:IEEE128
14094           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14095   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14096   "xsnabsqp %0,%1"
14097   [(set_attr "type" "vecmove")
14098    (set_attr "size" "128")])
14100 ;; Initially don't worry about doing fusion
14101 (define_insn "fma<mode>4_hw"
14102   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14103         (fma:IEEE128
14104          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14105          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14106          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14107   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14108   "xsmaddqp %0,%1,%2"
14109   [(set_attr "type" "qmul")
14110    (set_attr "size" "128")])
14112 (define_insn "*fms<mode>4_hw"
14113   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14114         (fma:IEEE128
14115          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14116          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14117          (neg:IEEE128
14118           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14119   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14120   "xsmsubqp %0,%1,%2"
14121   [(set_attr "type" "qmul")
14122    (set_attr "size" "128")])
14124 (define_insn "*nfma<mode>4_hw"
14125   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14126         (neg:IEEE128
14127          (fma:IEEE128
14128           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14129           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14130           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14131   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14132   "xsnmaddqp %0,%1,%2"
14133   [(set_attr "type" "qmul")
14134    (set_attr "size" "128")])
14136 (define_insn "*nfms<mode>4_hw"
14137   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14138         (neg:IEEE128
14139          (fma:IEEE128
14140           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14141           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14142           (neg:IEEE128
14143            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14144   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14145   "xsnmsubqp %0,%1,%2"
14146   [(set_attr "type" "qmul")
14147    (set_attr "size" "128")])
14149 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14150   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14151         (float_extend:IEEE128
14152          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14153   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14154   "xscvdpqp %0,%1"
14155   [(set_attr "type" "vecfloat")
14156    (set_attr "size" "128")])
14158 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14159 ;; point is a simple copy.
14160 (define_insn_and_split "extendkftf2"
14161   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14162         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14163   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14164   "@
14165    #
14166    xxlor %x0,%x1,%x1"
14167   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14168   [(const_int 0)]
14170   emit_note (NOTE_INSN_DELETED);
14171   DONE;
14173   [(set_attr "type" "*,veclogical")
14174    (set_attr "length" "0,4")])
14176 (define_insn_and_split "trunctfkf2"
14177   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14178         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14179   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14180   "@
14181    #
14182    xxlor %x0,%x1,%x1"
14183   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14184   [(const_int 0)]
14186   emit_note (NOTE_INSN_DELETED);
14187   DONE;
14189   [(set_attr "type" "*,veclogical")
14190    (set_attr "length" "0,4")])
14192 (define_insn "trunc<mode>df2_hw"
14193   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14194         (float_truncate:DF
14195          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14196   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14197   "xscvqpdp %0,%1"
14198   [(set_attr "type" "vecfloat")
14199    (set_attr "size" "128")])
14201 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14202 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14203 ;; conversion
14204 (define_insn_and_split "trunc<mode>sf2_hw"
14205   [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14206         (float_truncate:SF
14207          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14208    (clobber (match_scratch:DF 2 "=v"))]
14209   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14210   "#"
14211   "&& 1"
14212   [(set (match_dup 2)
14213         (unspec:DF [(match_dup 1)]
14214                    UNSPEC_TRUNC_ROUND_TO_ODD))
14215    (set (match_dup 0)
14216         (float_truncate:SF (match_dup 2)))]
14218   if (GET_CODE (operands[2]) == SCRATCH)
14219     operands[2] = gen_reg_rtx (DFmode);
14221   [(set_attr "type" "vecfloat")
14222    (set_attr "length" "8")
14223    (set_attr "isa" "p8v")])
14225 ;; Conversion between IEEE 128-bit and integer types
14227 ;; The fix function for DImode and SImode was declared earlier as a
14228 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14229 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14230 ;; unless we have the IEEE 128-bit hardware.
14232 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14233 ;; to provide a GPR target that used direct move and a conversion in the GPR
14234 ;; which works around QImode/HImode not being allowed in vector registers in
14235 ;; ISA 2.07 (power8).
14236 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14237   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14238         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14239   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14240   "xscvqp<su><wd>z %0,%1"
14241   [(set_attr "type" "vecfloat")
14242    (set_attr "size" "128")])
14244 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14245   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14246         (any_fix:QHI
14247          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14248   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14249   "xscvqp<su>wz %0,%1"
14250   [(set_attr "type" "vecfloat")
14251    (set_attr "size" "128")])
14253 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14254 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14255 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14256   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14257         (any_fix:QHSI
14258          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14259    (clobber (match_scratch:QHSI 2 "=v"))]
14260   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14261   "#"
14262   "&& reload_completed"
14263   [(set (match_dup 2)
14264         (any_fix:QHSI (match_dup 1)))
14265    (set (match_dup 0)
14266         (match_dup 2))])
14268 (define_insn "float_<mode>di2_hw"
14269   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14270         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14271   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14272   "xscvsdqp %0,%1"
14273   [(set_attr "type" "vecfloat")
14274    (set_attr "size" "128")])
14276 (define_insn_and_split "float_<mode>si2_hw"
14277   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14278         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14279    (clobber (match_scratch:DI 2 "=v"))]
14280   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14281   "#"
14282   "&& 1"
14283   [(set (match_dup 2)
14284         (sign_extend:DI (match_dup 1)))
14285    (set (match_dup 0)
14286         (float:IEEE128 (match_dup 2)))]
14288   if (GET_CODE (operands[2]) == SCRATCH)
14289     operands[2] = gen_reg_rtx (DImode);
14291   if (MEM_P (operands[1]))
14292     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14295 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14296   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14297         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14298    (clobber (match_scratch:DI 2 "=X,r,X"))]
14299   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14300   "#"
14301   "&& reload_completed"
14302   [(const_int 0)]
14304   rtx dest = operands[0];
14305   rtx src = operands[1];
14306   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14308   if (altivec_register_operand (src, <QHI:MODE>mode))
14309     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14310   else if (int_reg_operand (src, <QHI:MODE>mode))
14311     {
14312       rtx ext_di = operands[2];
14313       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14314       emit_move_insn (dest_di, ext_di);
14315     }
14316   else if (MEM_P (src))
14317     {
14318       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14319       emit_move_insn (dest_qhi, src);
14320       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14321     }
14322   else
14323     gcc_unreachable ();
14325   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14326   DONE;
14328   [(set_attr "length" "8,12,12")
14329    (set_attr "type" "vecfloat")
14330    (set_attr "size" "128")])
14332 (define_insn "floatuns_<mode>di2_hw"
14333   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14334         (unsigned_float:IEEE128
14335          (match_operand:DI 1 "altivec_register_operand" "v")))]
14336   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14337   "xscvudqp %0,%1"
14338   [(set_attr "type" "vecfloat")
14339    (set_attr "size" "128")])
14341 (define_insn_and_split "floatuns_<mode>si2_hw"
14342   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14343         (unsigned_float:IEEE128
14344          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14345    (clobber (match_scratch:DI 2 "=v"))]
14346   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14347   "#"
14348   "&& 1"
14349   [(set (match_dup 2)
14350         (zero_extend:DI (match_dup 1)))
14351    (set (match_dup 0)
14352         (float:IEEE128 (match_dup 2)))]
14354   if (GET_CODE (operands[2]) == SCRATCH)
14355     operands[2] = gen_reg_rtx (DImode);
14357   if (MEM_P (operands[1]))
14358     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14361 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14362   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14363         (unsigned_float:IEEE128
14364          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14365    (clobber (match_scratch:DI 2 "=X,r,X"))]
14366   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14367   "#"
14368   "&& reload_completed"
14369   [(const_int 0)]
14371   rtx dest = operands[0];
14372   rtx src = operands[1];
14373   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14375   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14376     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14377   else if (int_reg_operand (src, <QHI:MODE>mode))
14378     {
14379       rtx ext_di = operands[2];
14380       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14381       emit_move_insn (dest_di, ext_di);
14382     }
14383   else
14384     gcc_unreachable ();
14386   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14387   DONE;
14389   [(set_attr "length" "8,12,8")
14390    (set_attr "type" "vecfloat")
14391    (set_attr "size" "128")])
14393 ;; IEEE 128-bit round to integer built-in functions
14394 (define_insn "floor<mode>2"
14395   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14396         (unspec:IEEE128
14397          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14398          UNSPEC_FRIM))]
14399   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14400   "xsrqpi 1,%0,%1,3"
14401   [(set_attr "type" "vecfloat")
14402    (set_attr "size" "128")])
14404 (define_insn "ceil<mode>2"
14405   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14406         (unspec:IEEE128
14407          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14408          UNSPEC_FRIP))]
14409   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14410   "xsrqpi 1,%0,%1,2"
14411   [(set_attr "type" "vecfloat")
14412    (set_attr "size" "128")])
14414 (define_insn "btrunc<mode>2"
14415   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14416         (unspec:IEEE128
14417          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14418          UNSPEC_FRIZ))]
14419   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14420   "xsrqpi 1,%0,%1,1"
14421   [(set_attr "type" "vecfloat")
14422    (set_attr "size" "128")])
14424 (define_insn "round<mode>2"
14425   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14426         (unspec:IEEE128
14427          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14428          UNSPEC_FRIN))]
14429   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14430   "xsrqpi 0,%0,%1,0"
14431   [(set_attr "type" "vecfloat")
14432    (set_attr "size" "128")])
14434 ;; IEEE 128-bit instructions with round to odd semantics
14435 (define_insn "add<mode>3_odd"
14436   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14437         (unspec:IEEE128
14438          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14439           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14440          UNSPEC_ADD_ROUND_TO_ODD))]
14441   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14442   "xsaddqpo %0,%1,%2"
14443   [(set_attr "type" "vecfloat")
14444    (set_attr "size" "128")])
14446 (define_insn "sub<mode>3_odd"
14447   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14448         (unspec:IEEE128
14449          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14450           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14451          UNSPEC_SUB_ROUND_TO_ODD))]
14452   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14453   "xssubqpo %0,%1,%2"
14454   [(set_attr "type" "vecfloat")
14455    (set_attr "size" "128")])
14457 (define_insn "mul<mode>3_odd"
14458   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14459         (unspec:IEEE128
14460          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14461           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14462          UNSPEC_MUL_ROUND_TO_ODD))]
14463   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14464   "xsmulqpo %0,%1,%2"
14465   [(set_attr "type" "qmul")
14466    (set_attr "size" "128")])
14468 (define_insn "div<mode>3_odd"
14469   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14470         (unspec:IEEE128
14471          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14472           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14473          UNSPEC_DIV_ROUND_TO_ODD))]
14474   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14475   "xsdivqpo %0,%1,%2"
14476   [(set_attr "type" "vecdiv")
14477    (set_attr "size" "128")])
14479 (define_insn "sqrt<mode>2_odd"
14480   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14481         (unspec:IEEE128
14482          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14483          UNSPEC_SQRT_ROUND_TO_ODD))]
14484   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14485    "xssqrtqpo %0,%1"
14486   [(set_attr "type" "vecdiv")
14487    (set_attr "size" "128")])
14489 (define_insn "fma<mode>4_odd"
14490   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14491         (unspec:IEEE128
14492          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14493           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14494           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14495          UNSPEC_FMA_ROUND_TO_ODD))]
14496   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14497   "xsmaddqpo %0,%1,%2"
14498   [(set_attr "type" "qmul")
14499    (set_attr "size" "128")])
14501 (define_insn "*fms<mode>4_odd"
14502   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14503         (unspec:IEEE128
14504          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14505           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14506           (neg:IEEE128
14507            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14508          UNSPEC_FMA_ROUND_TO_ODD))]
14509   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14510   "xsmsubqpo %0,%1,%2"
14511   [(set_attr "type" "qmul")
14512    (set_attr "size" "128")])
14514 (define_insn "*nfma<mode>4_odd"
14515   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14516         (neg:IEEE128
14517          (unspec:IEEE128
14518           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14519            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14520            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14521           UNSPEC_FMA_ROUND_TO_ODD)))]
14522   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14523   "xsnmaddqpo %0,%1,%2"
14524   [(set_attr "type" "qmul")
14525    (set_attr "size" "128")])
14527 (define_insn "*nfms<mode>4_odd"
14528   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14529         (neg:IEEE128
14530          (unspec:IEEE128
14531           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14532            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14533            (neg:IEEE128
14534             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14535           UNSPEC_FMA_ROUND_TO_ODD)))]
14536   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14537   "xsnmsubqpo %0,%1,%2"
14538   [(set_attr "type" "qmul")
14539    (set_attr "size" "128")])
14541 (define_insn "trunc<mode>df2_odd"
14542   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14543         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14544                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14545   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14546   "xscvqpdpo %0,%1"
14547   [(set_attr "type" "vecfloat")
14548    (set_attr "size" "128")])
14550 ;; IEEE 128-bit comparisons
14551 (define_insn "*cmp<mode>_hw"
14552   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14553         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14554                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14555   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14556    "xscmpuqp %0,%1,%2"
14557   [(set_attr "type" "veccmp")
14558    (set_attr "size" "128")])
14560 ;; Miscellaneous ISA 3.0 (power9) instructions
14562 (define_insn "darn_32"
14563   [(set (match_operand:SI 0 "register_operand" "=r")
14564         (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14565   "TARGET_P9_MISC"
14566   "darn %0,0"
14567   [(set_attr "type" "integer")])
14569 (define_insn "darn_raw"
14570   [(set (match_operand:DI 0 "register_operand" "=r")
14571         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14572   "TARGET_P9_MISC && TARGET_64BIT"
14573   "darn %0,2"
14574   [(set_attr "type" "integer")])
14576 (define_insn "darn"
14577   [(set (match_operand:DI 0 "register_operand" "=r")
14578         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14579   "TARGET_P9_MISC && TARGET_64BIT"
14580   "darn %0,1"
14581   [(set_attr "type" "integer")])
14583 ;; Test byte within range.
14585 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14586 ;; represents a byte whose value is ignored in this context and
14587 ;; vv, the least significant byte, holds the byte value that is to
14588 ;; be tested for membership within the range specified by operand 2.
14589 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14591 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14592 ;; vv <= hi.  Otherwise, set register operand 0 to 0.
14594 ;; Though the instructions to which this expansion maps operate on
14595 ;; 64-bit registers, the current implementation only operates on
14596 ;; SI-mode operands as the high-order bits provide no information
14597 ;; that is not already available in the low-order bits.  To avoid the
14598 ;; costs of data widening operations, future enhancements might allow
14599 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14600 (define_expand "cmprb"
14601   [(set (match_dup 3)
14602         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14603                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14604          UNSPEC_CMPRB))
14605    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14606         (if_then_else:SI (lt (match_dup 3)
14607                              (const_int 0))
14608                          (const_int -1)
14609                          (if_then_else (gt (match_dup 3)
14610                                            (const_int 0))
14611                                        (const_int 1)
14612                                        (const_int 0))))]
14613   "TARGET_P9_MISC"
14615   operands[3] = gen_reg_rtx (CCmode);
14618 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14619 ;; represents a byte whose value is ignored in this context and
14620 ;; vv, the least significant byte, holds the byte value that is to
14621 ;; be tested for membership within the range specified by operand 2.
14622 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14624 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14625 ;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
14626 ;; 3 bits of the target CR register are all set to 0.
14627 (define_insn "*cmprb_internal"
14628   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14629         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14630                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14631          UNSPEC_CMPRB))]
14632   "TARGET_P9_MISC"
14633   "cmprb %0,0,%1,%2"
14634   [(set_attr "type" "logical")])
14636 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14637 ;; register operand 1 is on.  Otherwise, set operand 0 register to 1
14638 ;; if the GT bit (0x4) of condition register operand 1 is on.
14639 ;; Otherwise, set operand 0 to 0.  Note that the result stored into
14640 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14641 ;; within condition register operand 1.
14642 (define_insn "setb_signed"
14643    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14644          (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14645                               (const_int 0))
14646                           (const_int -1)
14647                           (if_then_else (gt (match_dup 1)
14648                                             (const_int 0))
14649                                         (const_int 1)
14650                                         (const_int 0))))]
14651   "TARGET_P9_MISC"
14652   "setb %0,%1"
14653   [(set_attr "type" "logical")])
14655 (define_insn "setb_unsigned"
14656    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14657          (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14658                               (const_int 0))
14659                           (const_int -1)
14660                           (if_then_else (gtu (match_dup 1)
14661                                             (const_int 0))
14662                                         (const_int 1)
14663                                         (const_int 0))))]
14664   "TARGET_P9_MISC"
14665   "setb %0,%1"
14666   [(set_attr "type" "logical")])
14668 ;; Test byte within two ranges.
14670 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14671 ;; represents a byte whose value is ignored in this context and
14672 ;; vv, the least significant byte, holds the byte value that is to
14673 ;; be tested for membership within the range specified by operand 2.
14674 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14676 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14677 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
14678 ;; operand 0 to 0.
14680 ;; Though the instructions to which this expansion maps operate on
14681 ;; 64-bit registers, the current implementation only operates on
14682 ;; SI-mode operands as the high-order bits provide no information
14683 ;; that is not already available in the low-order bits.  To avoid the
14684 ;; costs of data widening operations, future enhancements might allow
14685 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14686 (define_expand "cmprb2"
14687   [(set (match_dup 3)
14688         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14689                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14690          UNSPEC_CMPRB2))
14691    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14692         (if_then_else:SI (lt (match_dup 3)
14693                              (const_int 0))
14694                          (const_int -1)
14695                          (if_then_else (gt (match_dup 3)
14696                                            (const_int 0))
14697                                        (const_int 1)
14698                                        (const_int 0))))]
14699   "TARGET_P9_MISC"
14701   operands[3] = gen_reg_rtx (CCmode);
14704 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14705 ;; represents a byte whose value is ignored in this context and
14706 ;; vv, the least significant byte, holds the byte value that is to
14707 ;; be tested for membership within the ranges specified by operand 2.
14708 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14710 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14711 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14712 ;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
14713 ;; CR register are all set to 0.
14714 (define_insn "*cmprb2_internal"
14715   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14716         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14717                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14718          UNSPEC_CMPRB2))]
14719   "TARGET_P9_MISC"
14720   "cmprb %0,1,%1,%2"
14721   [(set_attr "type" "logical")])
14723 ;; Test byte membership within set of 8 bytes.
14725 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14726 ;; represents a byte whose value is ignored in this context and
14727 ;; vv, the least significant byte, holds the byte value that is to
14728 ;; be tested for membership within the set specified by operand 2.
14729 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14731 ;; Return in target register operand 0 a value of 1 if vv equals one
14732 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
14733 ;; register operand 0 to 0.  Note that the 8 byte values held within
14734 ;; operand 2 need not be unique.
14736 ;; Though the instructions to which this expansion maps operate on
14737 ;; 64-bit registers, the current implementation requires that operands
14738 ;; 0 and 1 have mode SI as the high-order bits provide no information
14739 ;; that is not already available in the low-order bits.  To avoid the
14740 ;; costs of data widening operations, future enhancements might allow
14741 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14742 (define_expand "cmpeqb"
14743   [(set (match_dup 3)
14744         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14745                     (match_operand:DI 2 "gpc_reg_operand" "r")]
14746          UNSPEC_CMPEQB))
14747    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14748         (if_then_else:SI (lt (match_dup 3)
14749                              (const_int 0))
14750                          (const_int -1)
14751                          (if_then_else (gt (match_dup 3)
14752                                            (const_int 0))
14753                                        (const_int 1)
14754                                        (const_int 0))))]
14755   "TARGET_P9_MISC && TARGET_64BIT"
14757   operands[3] = gen_reg_rtx (CCmode);
14760 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14761 ;; represents a byte whose value is ignored in this context and
14762 ;; vv, the least significant byte, holds the byte value that is to
14763 ;; be tested for membership within the set specified by operand 2.
14764 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14766 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14767 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
14768 ;; set the GT bit to zero.  The other 3 bits of the target CR register
14769 ;; are all set to 0.
14770 (define_insn "*cmpeqb_internal"
14771   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14772          (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14773                      (match_operand:DI 2 "gpc_reg_operand" "r")]
14774           UNSPEC_CMPEQB))]
14775   "TARGET_P9_MISC && TARGET_64BIT"
14776   "cmpeqb %0,%1,%2"
14777   [(set_attr "type" "logical")])
14780 (include "sync.md")
14781 (include "vector.md")
14782 (include "vsx.md")
14783 (include "altivec.md")
14784 (include "dfp.md")
14785 (include "crypto.md")
14786 (include "htm.md")