Use PLI to load up 32-bit SImode constants if -mcpu=future.
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob6e12d62e23a6b34f574c4349a2c5999be4789ec9
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2019 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_ADDR")
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")
1765         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1766                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1767   ""
1768   "@
1769    add %0,%1,%2
1770    addi %0,%1,%2
1771    addis %0,%1,%v2"
1772   [(set_attr "type" "add")])
1774 (define_insn "*addsi3_high"
1775   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1776         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1777                  (high:SI (match_operand 2 "" ""))))]
1778   "TARGET_MACHO && !TARGET_64BIT"
1779   "addis %0,%1,ha16(%2)"
1780   [(set_attr "type" "add")])
1782 (define_insn_and_split "*add<mode>3_dot"
1783   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1784         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1785                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1786                     (const_int 0)))
1787    (clobber (match_scratch:GPR 0 "=r,r"))]
1788   "<MODE>mode == Pmode"
1789   "@
1790    add. %0,%1,%2
1791    #"
1792   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1793   [(set (match_dup 0)
1794         (plus:GPR (match_dup 1)
1795                  (match_dup 2)))
1796    (set (match_dup 3)
1797         (compare:CC (match_dup 0)
1798                     (const_int 0)))]
1799   ""
1800   [(set_attr "type" "add")
1801    (set_attr "dot" "yes")
1802    (set_attr "length" "4,8")])
1804 (define_insn_and_split "*add<mode>3_dot2"
1805   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1806         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1807                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1808                     (const_int 0)))
1809    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1810         (plus:GPR (match_dup 1)
1811                   (match_dup 2)))]
1812   "<MODE>mode == Pmode"
1813   "@
1814    add. %0,%1,%2
1815    #"
1816   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1817   [(set (match_dup 0)
1818         (plus:GPR (match_dup 1)
1819                   (match_dup 2)))
1820    (set (match_dup 3)
1821         (compare:CC (match_dup 0)
1822                     (const_int 0)))]
1823   ""
1824   [(set_attr "type" "add")
1825    (set_attr "dot" "yes")
1826    (set_attr "length" "4,8")])
1828 (define_insn_and_split "*add<mode>3_imm_dot"
1829   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1830         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1831                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1832                     (const_int 0)))
1833    (clobber (match_scratch:GPR 0 "=r,r"))
1834    (clobber (reg:GPR CA_REGNO))]
1835   "<MODE>mode == Pmode"
1836   "@
1837    addic. %0,%1,%2
1838    #"
1839   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1840   [(set (match_dup 0)
1841         (plus:GPR (match_dup 1)
1842                   (match_dup 2)))
1843    (set (match_dup 3)
1844         (compare:CC (match_dup 0)
1845                     (const_int 0)))]
1846   ""
1847   [(set_attr "type" "add")
1848    (set_attr "dot" "yes")
1849    (set_attr "length" "4,8")])
1851 (define_insn_and_split "*add<mode>3_imm_dot2"
1852   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1853         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1854                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1855                     (const_int 0)))
1856    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1857         (plus:GPR (match_dup 1)
1858                   (match_dup 2)))
1859    (clobber (reg:GPR CA_REGNO))]
1860   "<MODE>mode == Pmode"
1861   "@
1862    addic. %0,%1,%2
1863    #"
1864   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1865   [(set (match_dup 0)
1866         (plus:GPR (match_dup 1)
1867                   (match_dup 2)))
1868    (set (match_dup 3)
1869         (compare:CC (match_dup 0)
1870                     (const_int 0)))]
1871   ""
1872   [(set_attr "type" "add")
1873    (set_attr "dot" "yes")
1874    (set_attr "length" "4,8")])
1876 ;; Split an add that we can't do in one insn into two insns, each of which
1877 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1878 ;; add should be last in case the result gets used in an address.
1880 (define_split
1881   [(set (match_operand:GPR 0 "gpc_reg_operand")
1882         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1883                   (match_operand:GPR 2 "non_add_cint_operand")))]
1884   ""
1885   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1886    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1888   HOST_WIDE_INT val = INTVAL (operands[2]);
1889   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1890   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1892   operands[4] = GEN_INT (low);
1893   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1894     operands[3] = GEN_INT (rest);
1895   else if (can_create_pseudo_p ())
1896     {
1897       operands[3] = gen_reg_rtx (DImode);
1898       emit_move_insn (operands[3], operands[2]);
1899       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1900       DONE;
1901     }
1902   else
1903     FAIL;
1907 (define_insn "add<mode>3_carry"
1908   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1909         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1910                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1911    (set (reg:P CA_REGNO)
1912         (ltu:P (plus:P (match_dup 1)
1913                        (match_dup 2))
1914                (match_dup 1)))]
1915   ""
1916   "add%I2c %0,%1,%2"
1917   [(set_attr "type" "add")])
1919 (define_insn "*add<mode>3_imm_carry_pos"
1920   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1921         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1922                 (match_operand:P 2 "short_cint_operand" "n")))
1923    (set (reg:P CA_REGNO)
1924         (geu:P (match_dup 1)
1925                (match_operand:P 3 "const_int_operand" "n")))]
1926   "INTVAL (operands[2]) > 0
1927    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1928   "addic %0,%1,%2"
1929   [(set_attr "type" "add")])
1931 (define_insn "*add<mode>3_imm_carry_0"
1932   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1933         (match_operand:P 1 "gpc_reg_operand" "r"))
1934    (set (reg:P CA_REGNO)
1935         (const_int 0))]
1936   ""
1937   "addic %0,%1,0"
1938   [(set_attr "type" "add")])
1940 (define_insn "*add<mode>3_imm_carry_m1"
1941   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1942         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1943                 (const_int -1)))
1944    (set (reg:P CA_REGNO)
1945         (ne:P (match_dup 1)
1946               (const_int 0)))]
1947   ""
1948   "addic %0,%1,-1"
1949   [(set_attr "type" "add")])
1951 (define_insn "*add<mode>3_imm_carry_neg"
1952   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1953         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1954                 (match_operand:P 2 "short_cint_operand" "n")))
1955    (set (reg:P CA_REGNO)
1956         (gtu:P (match_dup 1)
1957                (match_operand:P 3 "const_int_operand" "n")))]
1958   "INTVAL (operands[2]) < 0
1959    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1960   "addic %0,%1,%2"
1961   [(set_attr "type" "add")])
1964 (define_expand "add<mode>3_carry_in"
1965   [(parallel [
1966      (set (match_operand:GPR 0 "gpc_reg_operand")
1967           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1968                               (match_operand:GPR 2 "adde_operand"))
1969                     (reg:GPR CA_REGNO)))
1970      (clobber (reg:GPR CA_REGNO))])]
1971   ""
1973   if (operands[2] == const0_rtx)
1974     {
1975       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1976       DONE;
1977     }
1978   if (operands[2] == constm1_rtx)
1979     {
1980       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1981       DONE;
1982     }
1985 (define_insn "*add<mode>3_carry_in_internal"
1986   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1987         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1988                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1989                   (reg:GPR CA_REGNO)))
1990    (clobber (reg:GPR CA_REGNO))]
1991   ""
1992   "adde %0,%1,%2"
1993   [(set_attr "type" "add")])
1995 (define_insn "*add<mode>3_carry_in_internal2"
1996   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1997         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1998                             (reg:GPR CA_REGNO))
1999                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2000    (clobber (reg:GPR CA_REGNO))]
2001   ""
2002   "adde %0,%1,%2"
2003   [(set_attr "type" "add")])
2005 (define_insn "add<mode>3_carry_in_0"
2006   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2007         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2008                   (reg:GPR CA_REGNO)))
2009    (clobber (reg:GPR CA_REGNO))]
2010   ""
2011   "addze %0,%1"
2012   [(set_attr "type" "add")])
2014 (define_insn "add<mode>3_carry_in_m1"
2015   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2016         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2017                             (reg:GPR CA_REGNO))
2018                   (const_int -1)))
2019    (clobber (reg:GPR CA_REGNO))]
2020   ""
2021   "addme %0,%1"
2022   [(set_attr "type" "add")])
2025 (define_expand "one_cmpl<mode>2"
2026   [(set (match_operand:SDI 0 "gpc_reg_operand")
2027         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2028   ""
2030   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2031     {
2032       rs6000_split_logical (operands, NOT, false, false, false);
2033       DONE;
2034     }
2037 (define_insn "*one_cmpl<mode>2"
2038   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2039         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2040   ""
2041   "not %0,%1")
2043 (define_insn_and_split "*one_cmpl<mode>2_dot"
2044   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2045         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2046                     (const_int 0)))
2047    (clobber (match_scratch:GPR 0 "=r,r"))]
2048   "<MODE>mode == Pmode"
2049   "@
2050    not. %0,%1
2051    #"
2052   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2053   [(set (match_dup 0)
2054         (not:GPR (match_dup 1)))
2055    (set (match_dup 2)
2056         (compare:CC (match_dup 0)
2057                     (const_int 0)))]
2058   ""
2059   [(set_attr "type" "logical")
2060    (set_attr "dot" "yes")
2061    (set_attr "length" "4,8")])
2063 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2064   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2065         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2066                     (const_int 0)))
2067    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2068         (not:GPR (match_dup 1)))]
2069   "<MODE>mode == Pmode"
2070   "@
2071    not. %0,%1
2072    #"
2073   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2074   [(set (match_dup 0)
2075         (not:GPR (match_dup 1)))
2076    (set (match_dup 2)
2077         (compare:CC (match_dup 0)
2078                     (const_int 0)))]
2079   ""
2080   [(set_attr "type" "logical")
2081    (set_attr "dot" "yes")
2082    (set_attr "length" "4,8")])
2085 (define_expand "sub<mode>3"
2086   [(set (match_operand:SDI 0 "gpc_reg_operand")
2087         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2088                    (match_operand:SDI 2 "gpc_reg_operand")))]
2089   ""
2091   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2092     {
2093       rtx lo0 = gen_lowpart (SImode, operands[0]);
2094       rtx lo1 = gen_lowpart (SImode, operands[1]);
2095       rtx lo2 = gen_lowpart (SImode, operands[2]);
2096       rtx hi0 = gen_highpart (SImode, operands[0]);
2097       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2098       rtx hi2 = gen_highpart (SImode, operands[2]);
2100       if (!reg_or_short_operand (lo1, SImode))
2101         lo1 = force_reg (SImode, lo1);
2102       if (!adde_operand (hi1, SImode))
2103         hi1 = force_reg (SImode, hi1);
2105       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2106       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2107       DONE;
2108     }
2110   if (short_cint_operand (operands[1], <MODE>mode))
2111     {
2112       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2113       DONE;
2114     }
2117 (define_insn "*subf<mode>3"
2118   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2119         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2120                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2121   ""
2122   "subf %0,%1,%2"
2123   [(set_attr "type" "add")])
2125 (define_insn_and_split "*subf<mode>3_dot"
2126   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2127         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2128                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2129                     (const_int 0)))
2130    (clobber (match_scratch:GPR 0 "=r,r"))]
2131   "<MODE>mode == Pmode"
2132   "@
2133    subf. %0,%1,%2
2134    #"
2135   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2136   [(set (match_dup 0)
2137         (minus:GPR (match_dup 2)
2138                    (match_dup 1)))
2139    (set (match_dup 3)
2140         (compare:CC (match_dup 0)
2141                     (const_int 0)))]
2142   ""
2143   [(set_attr "type" "add")
2144    (set_attr "dot" "yes")
2145    (set_attr "length" "4,8")])
2147 (define_insn_and_split "*subf<mode>3_dot2"
2148   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2149         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2150                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2151                     (const_int 0)))
2152    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2153         (minus:GPR (match_dup 2)
2154                    (match_dup 1)))]
2155   "<MODE>mode == Pmode"
2156   "@
2157    subf. %0,%1,%2
2158    #"
2159   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2160   [(set (match_dup 0)
2161         (minus:GPR (match_dup 2)
2162                    (match_dup 1)))
2163    (set (match_dup 3)
2164         (compare:CC (match_dup 0)
2165                     (const_int 0)))]
2166   ""
2167   [(set_attr "type" "add")
2168    (set_attr "dot" "yes")
2169    (set_attr "length" "4,8")])
2171 (define_insn "subf<mode>3_imm"
2172   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2173         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2174                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2175    (clobber (reg:GPR CA_REGNO))]
2176   ""
2177   "subfic %0,%1,%2"
2178   [(set_attr "type" "add")])
2180 (define_insn_and_split "subf<mode>3_carry_dot2"
2181   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2182         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2183                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2184                     (const_int 0)))
2185    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2186         (minus:P (match_dup 2)
2187                    (match_dup 1)))
2188    (set (reg:P CA_REGNO)
2189         (leu:P (match_dup 1)
2190                (match_dup 2)))]
2191   "<MODE>mode == Pmode"
2192   "@
2193    subfc. %0,%1,%2
2194    #"
2195   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2196   [(parallel [(set (match_dup 0)
2197                    (minus:P (match_dup 2)
2198                             (match_dup 1)))
2199               (set (reg:P CA_REGNO)
2200                    (leu:P (match_dup 1)
2201                           (match_dup 2)))])
2202    (set (match_dup 3)
2203         (compare:CC (match_dup 0)
2204                     (const_int 0)))]
2205   ""
2206   [(set_attr "type" "add")
2207    (set_attr "dot" "yes")
2208    (set_attr "length" "4,8")])
2210 (define_insn "subf<mode>3_carry"
2211   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2212         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2213                  (match_operand:P 1 "gpc_reg_operand" "r")))
2214    (set (reg:P CA_REGNO)
2215         (leu:P (match_dup 1)
2216                (match_dup 2)))]
2217   ""
2218   "subf%I2c %0,%1,%2"
2219   [(set_attr "type" "add")])
2221 (define_insn "*subf<mode>3_imm_carry_0"
2222   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2223         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2224    (set (reg:P CA_REGNO)
2225         (eq:P (match_dup 1)
2226               (const_int 0)))]
2227   ""
2228   "subfic %0,%1,0"
2229   [(set_attr "type" "add")])
2231 (define_insn "*subf<mode>3_imm_carry_m1"
2232   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2233         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2234    (set (reg:P CA_REGNO)
2235         (const_int 1))]
2236   ""
2237   "subfic %0,%1,-1"
2238   [(set_attr "type" "add")])
2241 (define_expand "subf<mode>3_carry_in"
2242   [(parallel [
2243      (set (match_operand:GPR 0 "gpc_reg_operand")
2244           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2245                               (reg:GPR CA_REGNO))
2246                     (match_operand:GPR 2 "adde_operand")))
2247      (clobber (reg:GPR CA_REGNO))])]
2248   ""
2250   if (operands[2] == const0_rtx)
2251     {
2252       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2253       DONE;
2254     }
2255   if (operands[2] == constm1_rtx)
2256     {
2257       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2258       DONE;
2259     }
2262 (define_insn "*subf<mode>3_carry_in_internal"
2263   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2264         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2265                             (reg:GPR CA_REGNO))
2266                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2267    (clobber (reg:GPR CA_REGNO))]
2268   ""
2269   "subfe %0,%1,%2"
2270   [(set_attr "type" "add")])
2272 (define_insn "subf<mode>3_carry_in_0"
2273   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2274         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2275                   (reg:GPR CA_REGNO)))
2276    (clobber (reg:GPR CA_REGNO))]
2277   ""
2278   "subfze %0,%1"
2279   [(set_attr "type" "add")])
2281 (define_insn "subf<mode>3_carry_in_m1"
2282   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2283         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2284                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2285                   (const_int -2)))
2286    (clobber (reg:GPR CA_REGNO))]
2287   ""
2288   "subfme %0,%1"
2289   [(set_attr "type" "add")])
2291 (define_insn "subf<mode>3_carry_in_xx"
2292   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2293         (plus:GPR (reg:GPR CA_REGNO)
2294                   (const_int -1)))
2295    (clobber (reg:GPR CA_REGNO))]
2296   ""
2297   "subfe %0,%0,%0"
2298   [(set_attr "type" "add")])
2301 (define_insn "@neg<mode>2"
2302   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2303         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2304   ""
2305   "neg %0,%1"
2306   [(set_attr "type" "add")])
2308 (define_insn_and_split "*neg<mode>2_dot"
2309   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2310         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2311                     (const_int 0)))
2312    (clobber (match_scratch:GPR 0 "=r,r"))]
2313   "<MODE>mode == Pmode"
2314   "@
2315    neg. %0,%1
2316    #"
2317   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2318   [(set (match_dup 0)
2319         (neg:GPR (match_dup 1)))
2320    (set (match_dup 2)
2321         (compare:CC (match_dup 0)
2322                     (const_int 0)))]
2323   ""
2324   [(set_attr "type" "add")
2325    (set_attr "dot" "yes")
2326    (set_attr "length" "4,8")])
2328 (define_insn_and_split "*neg<mode>2_dot2"
2329   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2330         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2331                     (const_int 0)))
2332    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2333         (neg:GPR (match_dup 1)))]
2334   "<MODE>mode == Pmode"
2335   "@
2336    neg. %0,%1
2337    #"
2338   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2339   [(set (match_dup 0)
2340         (neg:GPR (match_dup 1)))
2341    (set (match_dup 2)
2342         (compare:CC (match_dup 0)
2343                     (const_int 0)))]
2344   ""
2345   [(set_attr "type" "add")
2346    (set_attr "dot" "yes")
2347    (set_attr "length" "4,8")])
2350 (define_insn "clz<mode>2"
2351   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2352         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2353   ""
2354   "cntlz<wd> %0,%1"
2355   [(set_attr "type" "cntlz")])
2357 (define_expand "ctz<mode>2"
2358    [(set (match_operand:GPR 0 "gpc_reg_operand")
2359          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2360   ""
2362   if (TARGET_CTZ)
2363     {
2364       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2365       DONE;
2366     }
2368   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2369   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2370   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2372   if (TARGET_POPCNTD)
2373     {
2374       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2375       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2376       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2377       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2378     }
2379   else
2380     {
2381       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2382       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2383       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2384       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2385     }
2387   DONE;
2390 (define_insn "ctz<mode>2_hw"
2391   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2392         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2393   "TARGET_CTZ"
2394   "cnttz<wd> %0,%1"
2395   [(set_attr "type" "cntlz")])
2397 (define_expand "ffs<mode>2"
2398   [(set (match_operand:GPR 0 "gpc_reg_operand")
2399         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2400   ""
2402   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2403   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2404   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2405   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2406   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2407   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2408   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2409   DONE;
2413 (define_expand "popcount<mode>2"
2414   [(set (match_operand:GPR 0 "gpc_reg_operand")
2415         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2416   "TARGET_POPCNTB || TARGET_POPCNTD"
2418   rs6000_emit_popcount (operands[0], operands[1]);
2419   DONE;
2422 (define_insn "popcntb<mode>2"
2423   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2424         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2425                     UNSPEC_POPCNTB))]
2426   "TARGET_POPCNTB"
2427   "popcntb %0,%1"
2428   [(set_attr "type" "popcnt")])
2430 (define_insn "popcntd<mode>2"
2431   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2432         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2433   "TARGET_POPCNTD"
2434   "popcnt<wd> %0,%1"
2435   [(set_attr "type" "popcnt")])
2438 (define_expand "parity<mode>2"
2439   [(set (match_operand:GPR 0 "gpc_reg_operand")
2440         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2441   "TARGET_POPCNTB"
2443   rs6000_emit_parity (operands[0], operands[1]);
2444   DONE;
2447 (define_insn "parity<mode>2_cmpb"
2448   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2449         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2450   "TARGET_CMPB && TARGET_POPCNTB"
2451   "prty<wd> %0,%1"
2452   [(set_attr "type" "popcnt")])
2454 (define_insn "cmpb<mode>3"
2455   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2456         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2457                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2458   "TARGET_CMPB"
2459   "cmpb %0,%1,%2"
2460   [(set_attr "type" "cmp")])
2462 ;; Since the hardware zeros the upper part of the register, save generating the
2463 ;; AND immediate if we are converting to unsigned
2464 (define_insn "*bswap<mode>2_extenddi"
2465   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2466         (zero_extend:DI
2467          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2468   "TARGET_POWERPC64"
2469   "l<wd>brx %0,%y1"
2470   [(set_attr "type" "load")])
2472 (define_insn "*bswaphi2_extendsi"
2473   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2474         (zero_extend:SI
2475          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2476   ""
2477   "lhbrx %0,%y1"
2478   [(set_attr "type" "load")])
2480 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2481 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2482 ;; load with byte swap, which can be slower than doing it in the registers.  It
2483 ;; also prevents certain failures with the RELOAD register allocator.
2485 (define_expand "bswap<mode>2"
2486   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2487    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2488   ""
2490   rtx dest = operands[0];
2491   rtx src = operands[1];
2493   if (!REG_P (dest) && !REG_P (src))
2494     src = force_reg (<MODE>mode, src);
2496   if (MEM_P (src))
2497     {
2498       src = rs6000_force_indexed_or_indirect_mem (src);
2499       emit_insn (gen_bswap<mode>2_load (dest, src));
2500     }
2501   else if (MEM_P (dest))
2502     {
2503       dest = rs6000_force_indexed_or_indirect_mem (dest);
2504       emit_insn (gen_bswap<mode>2_store (dest, src));
2505     }
2506   else
2507     emit_insn (gen_bswap<mode>2_reg (dest, src));
2508   DONE;
2511 (define_insn "bswap<mode>2_load"
2512   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2513         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2514   ""
2515   "l<wd>brx %0,%y1"
2516   [(set_attr "type" "load")])
2518 (define_insn "bswap<mode>2_store"
2519   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2520         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2521   ""
2522   "st<wd>brx %1,%y0"
2523   [(set_attr "type" "store")])
2525 (define_insn_and_split "bswaphi2_reg"
2526   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2527         (bswap:HI
2528          (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2529    (clobber (match_scratch:SI 2 "=&r,X"))]
2530   ""
2531   "@
2532    #
2533    xxbrh %x0,%x1"
2534   "reload_completed && int_reg_operand (operands[0], HImode)"
2535   [(set (match_dup 3)
2536         (and:SI (lshiftrt:SI (match_dup 4)
2537                              (const_int 8))
2538                 (const_int 255)))
2539    (set (match_dup 2)
2540         (and:SI (ashift:SI (match_dup 4)
2541                            (const_int 8))
2542                 (const_int 65280)))             ;; 0xff00
2543    (set (match_dup 3)
2544         (ior:SI (match_dup 3)
2545                 (match_dup 2)))]
2547   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2548   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2550   [(set_attr "length" "12,4")
2551    (set_attr "type" "*,vecperm")
2552    (set_attr "isa" "*,p9v")])
2554 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2555 ;; zero_extract insns do not change for -mlittle.
2556 (define_insn_and_split "bswapsi2_reg"
2557   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2558         (bswap:SI
2559          (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2560   ""
2561   "@
2562    #
2563    xxbrw %x0,%x1"
2564   "reload_completed && int_reg_operand (operands[0], SImode)"
2565   [(set (match_dup 0)                                   ; DABC
2566         (rotate:SI (match_dup 1)
2567                    (const_int 24)))
2568    (set (match_dup 0)                                   ; DCBC
2569         (ior:SI (and:SI (ashift:SI (match_dup 1)
2570                                    (const_int 8))
2571                         (const_int 16711680))
2572                 (and:SI (match_dup 0)
2573                         (const_int -16711681))))
2574    (set (match_dup 0)                                   ; DCBA
2575         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2576                                      (const_int 24))
2577                         (const_int 255))
2578                 (and:SI (match_dup 0)
2579                         (const_int -256))))]
2580   ""
2581   [(set_attr "length" "12,4")
2582    (set_attr "type" "*,vecperm")
2583    (set_attr "isa" "*,p9v")])
2585 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2586 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2587 ;; complex code.
2589 (define_expand "bswapdi2"
2590   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2591                    (bswap:DI
2592                     (match_operand:DI 1 "reg_or_mem_operand")))
2593               (clobber (match_scratch:DI 2))
2594               (clobber (match_scratch:DI 3))])]
2595   ""
2597   rtx dest = operands[0];
2598   rtx src = operands[1];
2600   if (!REG_P (dest) && !REG_P (src))
2601     operands[1] = src = force_reg (DImode, src);
2603   if (TARGET_POWERPC64 && TARGET_LDBRX)
2604     {
2605       if (MEM_P (src))
2606         {
2607           src = rs6000_force_indexed_or_indirect_mem (src);
2608           emit_insn (gen_bswapdi2_load (dest, src));
2609         }
2610       else if (MEM_P (dest))
2611         {
2612           dest = rs6000_force_indexed_or_indirect_mem (dest);
2613           emit_insn (gen_bswapdi2_store (dest, src));
2614         }
2615       else if (TARGET_P9_VECTOR)
2616         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2617       else
2618         emit_insn (gen_bswapdi2_reg (dest, src));
2619       DONE;
2620     }
2622   if (!TARGET_POWERPC64)
2623     {
2624       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2625          that uses 64-bit registers needs the same scratch registers as 64-bit
2626          mode.  */
2627       emit_insn (gen_bswapdi2_32bit (dest, src));
2628       DONE;
2629     }
2632 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2633 (define_insn "bswapdi2_load"
2634   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2635         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2636   "TARGET_POWERPC64 && TARGET_LDBRX"
2637   "ldbrx %0,%y1"
2638   [(set_attr "type" "load")])
2640 (define_insn "bswapdi2_store"
2641   [(set (match_operand:DI 0 "memory_operand" "=Z")
2642         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2643   "TARGET_POWERPC64 && TARGET_LDBRX"
2644   "stdbrx %1,%y0"
2645   [(set_attr "type" "store")])
2647 (define_insn "bswapdi2_xxbrd"
2648   [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2649         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2650   "TARGET_P9_VECTOR"
2651   "xxbrd %x0,%x1"
2652   [(set_attr "type" "vecperm")
2653    (set_attr "isa" "p9v")])
2655 (define_insn "bswapdi2_reg"
2656   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2657         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2658    (clobber (match_scratch:DI 2 "=&r"))
2659    (clobber (match_scratch:DI 3 "=&r"))]
2660   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2661   "#"
2662   [(set_attr "length" "36")])
2664 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2665 (define_insn "*bswapdi2_64bit"
2666   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2667         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2668    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2669    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2670   "TARGET_POWERPC64 && !TARGET_LDBRX
2671    && (REG_P (operands[0]) || REG_P (operands[1]))
2672    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2673    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2674   "#"
2675   [(set_attr "length" "16,12,36")])
2677 (define_split
2678   [(set (match_operand:DI 0 "gpc_reg_operand")
2679         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2680    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2681    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2682   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2683   [(const_int 0)]
2685   rtx dest   = operands[0];
2686   rtx src    = operands[1];
2687   rtx op2    = operands[2];
2688   rtx op3    = operands[3];
2689   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2690                                     BYTES_BIG_ENDIAN ? 4 : 0);
2691   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2692                                      BYTES_BIG_ENDIAN ? 4 : 0);
2693   rtx addr1;
2694   rtx addr2;
2695   rtx word1;
2696   rtx word2;
2698   addr1 = XEXP (src, 0);
2699   if (GET_CODE (addr1) == PLUS)
2700     {
2701       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2702       if (TARGET_AVOID_XFORM)
2703         {
2704           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2705           addr2 = op2;
2706         }
2707       else
2708         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2709     }
2710   else if (TARGET_AVOID_XFORM)
2711     {
2712       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2713       addr2 = op2;
2714     }
2715   else
2716     {
2717       emit_move_insn (op2, GEN_INT (4));
2718       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2719     }
2721   word1 = change_address (src, SImode, addr1);
2722   word2 = change_address (src, SImode, addr2);
2724   if (BYTES_BIG_ENDIAN)
2725     {
2726       emit_insn (gen_bswapsi2 (op3_32, word2));
2727       emit_insn (gen_bswapsi2 (dest_32, word1));
2728     }
2729   else
2730     {
2731       emit_insn (gen_bswapsi2 (op3_32, word1));
2732       emit_insn (gen_bswapsi2 (dest_32, word2));
2733     }
2735   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2736   emit_insn (gen_iordi3 (dest, dest, op3));
2737   DONE;
2740 (define_split
2741   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2742         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2743    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2744    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2745   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2746   [(const_int 0)]
2748   rtx dest   = operands[0];
2749   rtx src    = operands[1];
2750   rtx op2    = operands[2];
2751   rtx op3    = operands[3];
2752   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2753                                     BYTES_BIG_ENDIAN ? 4 : 0);
2754   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2755                                     BYTES_BIG_ENDIAN ? 4 : 0);
2756   rtx addr1;
2757   rtx addr2;
2758   rtx word1;
2759   rtx word2;
2761   addr1 = XEXP (dest, 0);
2762   if (GET_CODE (addr1) == PLUS)
2763     {
2764       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2765       if (TARGET_AVOID_XFORM)
2766         {
2767           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2768           addr2 = op2;
2769         }
2770       else
2771         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2772     }
2773   else if (TARGET_AVOID_XFORM)
2774     {
2775       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2776       addr2 = op2;
2777     }
2778   else
2779     {
2780       emit_move_insn (op2, GEN_INT (4));
2781       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2782     }
2784   word1 = change_address (dest, SImode, addr1);
2785   word2 = change_address (dest, SImode, addr2);
2787   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2789   if (BYTES_BIG_ENDIAN)
2790     {
2791       emit_insn (gen_bswapsi2 (word1, src_si));
2792       emit_insn (gen_bswapsi2 (word2, op3_si));
2793     }
2794   else
2795     {
2796       emit_insn (gen_bswapsi2 (word2, src_si));
2797       emit_insn (gen_bswapsi2 (word1, op3_si));
2798     }
2799   DONE;
2802 (define_split
2803   [(set (match_operand:DI 0 "gpc_reg_operand")
2804         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2805    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2806    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2807   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2808   [(const_int 0)]
2810   rtx dest    = operands[0];
2811   rtx src     = operands[1];
2812   rtx op2     = operands[2];
2813   rtx op3     = operands[3];
2814   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2815   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2816   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2817   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2818   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2820   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2821   emit_insn (gen_bswapsi2 (dest_si, src_si));
2822   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2823   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2824   emit_insn (gen_iordi3 (dest, dest, op3));
2825   DONE;
2828 (define_insn "bswapdi2_32bit"
2829   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2830         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2831    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2832   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2833   "#"
2834   [(set_attr "length" "16,12,36")])
2836 (define_split
2837   [(set (match_operand:DI 0 "gpc_reg_operand")
2838         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2839    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2840   "!TARGET_POWERPC64 && reload_completed"
2841   [(const_int 0)]
2843   rtx dest  = operands[0];
2844   rtx src   = operands[1];
2845   rtx op2   = operands[2];
2846   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2847   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2848   rtx addr1;
2849   rtx addr2;
2850   rtx word1;
2851   rtx word2;
2853   addr1 = XEXP (src, 0);
2854   if (GET_CODE (addr1) == PLUS)
2855     {
2856       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2857       if (TARGET_AVOID_XFORM
2858           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2859         {
2860           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2861           addr2 = op2;
2862         }
2863       else
2864         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2865     }
2866   else if (TARGET_AVOID_XFORM
2867            || REGNO (addr1) == REGNO (dest2))
2868     {
2869       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2870       addr2 = op2;
2871     }
2872   else
2873     {
2874       emit_move_insn (op2, GEN_INT (4));
2875       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2876     }
2878   word1 = change_address (src, SImode, addr1);
2879   word2 = change_address (src, SImode, addr2);
2881   emit_insn (gen_bswapsi2 (dest2, word1));
2882   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2883      thus allowing us to omit an early clobber on the output.  */
2884   emit_insn (gen_bswapsi2 (dest1, word2));
2885   DONE;
2888 (define_split
2889   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2890         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2891    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2892   "!TARGET_POWERPC64 && reload_completed"
2893   [(const_int 0)]
2895   rtx dest = operands[0];
2896   rtx src  = operands[1];
2897   rtx op2  = operands[2];
2898   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2899   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2900   rtx addr1;
2901   rtx addr2;
2902   rtx word1;
2903   rtx word2;
2905   addr1 = XEXP (dest, 0);
2906   if (GET_CODE (addr1) == PLUS)
2907     {
2908       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2909       if (TARGET_AVOID_XFORM)
2910         {
2911           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2912           addr2 = op2;
2913         }
2914       else
2915         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2916     }
2917   else if (TARGET_AVOID_XFORM)
2918     {
2919       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2920       addr2 = op2;
2921     }
2922   else
2923     {
2924       emit_move_insn (op2, GEN_INT (4));
2925       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2926     }
2928   word1 = change_address (dest, SImode, addr1);
2929   word2 = change_address (dest, SImode, addr2);
2931   emit_insn (gen_bswapsi2 (word2, src1));
2932   emit_insn (gen_bswapsi2 (word1, src2));
2933   DONE;
2936 (define_split
2937   [(set (match_operand:DI 0 "gpc_reg_operand")
2938         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2939    (clobber (match_operand:SI 2 ""))]
2940   "!TARGET_POWERPC64 && reload_completed"
2941   [(const_int 0)]
2943   rtx dest  = operands[0];
2944   rtx src   = operands[1];
2945   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2946   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2947   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2948   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2950   emit_insn (gen_bswapsi2 (dest1, src2));
2951   emit_insn (gen_bswapsi2 (dest2, src1));
2952   DONE;
2956 (define_insn "mul<mode>3"
2957   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2958         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2959                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2960   ""
2961   "@
2962    mull<wd> %0,%1,%2
2963    mulli %0,%1,%2"
2964    [(set_attr "type" "mul")
2965     (set (attr "size")
2966       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2967                 (const_string "8")
2968              (match_operand:GPR 2 "short_cint_operand")
2969                 (const_string "16")]
2970         (const_string "<bits>")))])
2972 (define_insn_and_split "*mul<mode>3_dot"
2973   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2974         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2975                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2976                     (const_int 0)))
2977    (clobber (match_scratch:GPR 0 "=r,r"))]
2978   "<MODE>mode == Pmode"
2979   "@
2980    mull<wd>. %0,%1,%2
2981    #"
2982   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2983   [(set (match_dup 0)
2984         (mult:GPR (match_dup 1)
2985                   (match_dup 2)))
2986    (set (match_dup 3)
2987         (compare:CC (match_dup 0)
2988                     (const_int 0)))]
2989   ""
2990   [(set_attr "type" "mul")
2991    (set_attr "size" "<bits>")
2992    (set_attr "dot" "yes")
2993    (set_attr "length" "4,8")])
2995 (define_insn_and_split "*mul<mode>3_dot2"
2996   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2997         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2998                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2999                     (const_int 0)))
3000    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3001         (mult:GPR (match_dup 1)
3002                   (match_dup 2)))]
3003   "<MODE>mode == Pmode"
3004   "@
3005    mull<wd>. %0,%1,%2
3006    #"
3007   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3008   [(set (match_dup 0)
3009         (mult:GPR (match_dup 1)
3010                   (match_dup 2)))
3011    (set (match_dup 3)
3012         (compare:CC (match_dup 0)
3013                     (const_int 0)))]
3014   ""
3015   [(set_attr "type" "mul")
3016    (set_attr "size" "<bits>")
3017    (set_attr "dot" "yes")
3018    (set_attr "length" "4,8")])
3021 (define_expand "<su>mul<mode>3_highpart"
3022   [(set (match_operand:GPR 0 "gpc_reg_operand")
3023         (subreg:GPR
3024           (mult:<DMODE> (any_extend:<DMODE>
3025                           (match_operand:GPR 1 "gpc_reg_operand"))
3026                         (any_extend:<DMODE>
3027                           (match_operand:GPR 2 "gpc_reg_operand")))
3028          0))]
3029   ""
3031   if (<MODE>mode == SImode && TARGET_POWERPC64)
3032     {
3033       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3034                                              operands[2]));
3035       DONE;
3036     }
3038   if (!WORDS_BIG_ENDIAN)
3039     {
3040       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3041                                                  operands[2]));
3042       DONE;
3043     }
3046 (define_insn "*<su>mul<mode>3_highpart"
3047   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3048         (subreg:GPR
3049           (mult:<DMODE> (any_extend:<DMODE>
3050                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
3051                         (any_extend:<DMODE>
3052                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
3053          0))]
3054   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3055   "mulh<wd><u> %0,%1,%2"
3056   [(set_attr "type" "mul")
3057    (set_attr "size" "<bits>")])
3059 (define_insn "<su>mulsi3_highpart_le"
3060   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3061         (subreg:SI
3062           (mult:DI (any_extend:DI
3063                      (match_operand:SI 1 "gpc_reg_operand" "r"))
3064                    (any_extend:DI
3065                      (match_operand:SI 2 "gpc_reg_operand" "r")))
3066          4))]
3067   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3068   "mulhw<u> %0,%1,%2"
3069   [(set_attr "type" "mul")])
3071 (define_insn "<su>muldi3_highpart_le"
3072   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3073         (subreg:DI
3074           (mult:TI (any_extend:TI
3075                      (match_operand:DI 1 "gpc_reg_operand" "r"))
3076                    (any_extend:TI
3077                      (match_operand:DI 2 "gpc_reg_operand" "r")))
3078          8))]
3079   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3080   "mulhd<u> %0,%1,%2"
3081   [(set_attr "type" "mul")
3082    (set_attr "size" "64")])
3084 (define_insn "<su>mulsi3_highpart_64"
3085   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3086         (truncate:SI
3087           (lshiftrt:DI
3088             (mult:DI (any_extend:DI
3089                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3090                      (any_extend:DI
3091                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3092             (const_int 32))))]
3093   "TARGET_POWERPC64"
3094   "mulhw<u> %0,%1,%2"
3095   [(set_attr "type" "mul")])
3097 (define_expand "<u>mul<mode><dmode>3"
3098   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3099         (mult:<DMODE> (any_extend:<DMODE>
3100                         (match_operand:GPR 1 "gpc_reg_operand"))
3101                       (any_extend:<DMODE>
3102                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3103   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3105   rtx l = gen_reg_rtx (<MODE>mode);
3106   rtx h = gen_reg_rtx (<MODE>mode);
3107   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3108   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3109   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3110   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3111   DONE;
3114 (define_insn "*maddld<mode>4"
3115   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3116         (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3117                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
3118                   (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3119   "TARGET_MADDLD"
3120   "maddld %0,%1,%2,%3"
3121   [(set_attr "type" "mul")])
3123 (define_insn "udiv<mode>3"
3124   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3125         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3126                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3127   ""
3128   "div<wd>u %0,%1,%2"
3129   [(set_attr "type" "div")
3130    (set_attr "size" "<bits>")])
3133 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3134 ;; modulus.  If it isn't a power of two, force operands into register and do
3135 ;; a normal divide.
3136 (define_expand "div<mode>3"
3137   [(set (match_operand:GPR 0 "gpc_reg_operand")
3138         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3139                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3140   ""
3142   if (CONST_INT_P (operands[2])
3143       && INTVAL (operands[2]) > 0
3144       && exact_log2 (INTVAL (operands[2])) >= 0)
3145     {
3146       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3147       DONE;
3148     }
3150   operands[2] = force_reg (<MODE>mode, operands[2]);
3153 (define_insn "*div<mode>3"
3154   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3155         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3156                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3157   ""
3158   "div<wd> %0,%1,%2"
3159   [(set_attr "type" "div")
3160    (set_attr "size" "<bits>")])
3162 (define_insn "div<mode>3_sra"
3163   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3164         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3165                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3166    (clobber (reg:GPR CA_REGNO))]
3167   ""
3168   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3169   [(set_attr "type" "two")
3170    (set_attr "length" "8")])
3172 (define_insn_and_split "*div<mode>3_sra_dot"
3173   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3174         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3175                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3176                     (const_int 0)))
3177    (clobber (match_scratch:GPR 0 "=r,r"))
3178    (clobber (reg:GPR CA_REGNO))]
3179   "<MODE>mode == Pmode"
3180   "@
3181    sra<wd>i %0,%1,%p2\;addze. %0,%0
3182    #"
3183   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3184   [(parallel [(set (match_dup 0)
3185                    (div:GPR (match_dup 1)
3186                             (match_dup 2)))
3187               (clobber (reg:GPR CA_REGNO))])
3188    (set (match_dup 3)
3189         (compare:CC (match_dup 0)
3190                     (const_int 0)))]
3191   ""
3192   [(set_attr "type" "two")
3193    (set_attr "length" "8,12")
3194    (set_attr "cell_micro" "not")])
3196 (define_insn_and_split "*div<mode>3_sra_dot2"
3197   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3198         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3199                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3200                     (const_int 0)))
3201    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3202         (div:GPR (match_dup 1)
3203                  (match_dup 2)))
3204    (clobber (reg:GPR CA_REGNO))]
3205   "<MODE>mode == Pmode"
3206   "@
3207    sra<wd>i %0,%1,%p2\;addze. %0,%0
3208    #"
3209   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3210   [(parallel [(set (match_dup 0)
3211                    (div:GPR (match_dup 1)
3212                             (match_dup 2)))
3213               (clobber (reg:GPR CA_REGNO))])
3214    (set (match_dup 3)
3215         (compare:CC (match_dup 0)
3216                     (const_int 0)))]
3217   ""
3218   [(set_attr "type" "two")
3219    (set_attr "length" "8,12")
3220    (set_attr "cell_micro" "not")])
3222 (define_expand "mod<mode>3"
3223   [(set (match_operand:GPR 0 "gpc_reg_operand")
3224         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3225                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3226   ""
3228   int i;
3229   rtx temp1;
3230   rtx temp2;
3232   if (!CONST_INT_P (operands[2])
3233       || INTVAL (operands[2]) <= 0
3234       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3235     {
3236       if (!TARGET_MODULO)
3237         FAIL;
3239       operands[2] = force_reg (<MODE>mode, operands[2]);
3240     }
3241   else
3242     {
3243       temp1 = gen_reg_rtx (<MODE>mode);
3244       temp2 = gen_reg_rtx (<MODE>mode);
3246       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3247       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3248       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3249       DONE;
3250     }
3253 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3254 ;; mod, prefer putting the result of mod into a different register
3255 (define_insn "*mod<mode>3"
3256   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3257         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3258                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3259   "TARGET_MODULO"
3260   "mods<wd> %0,%1,%2"
3261   [(set_attr "type" "div")
3262    (set_attr "size" "<bits>")])
3265 (define_insn "umod<mode>3"
3266   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3267         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3268                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3269   "TARGET_MODULO"
3270   "modu<wd> %0,%1,%2"
3271   [(set_attr "type" "div")
3272    (set_attr "size" "<bits>")])
3274 ;; On machines with modulo support, do a combined div/mod the old fashioned
3275 ;; method, since the multiply/subtract is faster than doing the mod instruction
3276 ;; after a divide.
3278 (define_peephole2
3279   [(set (match_operand:GPR 0 "gpc_reg_operand")
3280         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3281                  (match_operand:GPR 2 "gpc_reg_operand")))
3282    (set (match_operand:GPR 3 "gpc_reg_operand")
3283         (mod:GPR (match_dup 1)
3284                  (match_dup 2)))]
3285   "TARGET_MODULO
3286    && ! reg_mentioned_p (operands[0], operands[1])
3287    && ! reg_mentioned_p (operands[0], operands[2])
3288    && ! reg_mentioned_p (operands[3], operands[1])
3289    && ! reg_mentioned_p (operands[3], operands[2])"
3290   [(set (match_dup 0)
3291         (div:GPR (match_dup 1)
3292                  (match_dup 2)))
3293    (set (match_dup 3)
3294         (mult:GPR (match_dup 0)
3295                   (match_dup 2)))
3296    (set (match_dup 3)
3297         (minus:GPR (match_dup 1)
3298                    (match_dup 3)))])
3300 (define_peephole2
3301   [(set (match_operand:GPR 0 "gpc_reg_operand")
3302         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3303                   (match_operand:GPR 2 "gpc_reg_operand")))
3304    (set (match_operand:GPR 3 "gpc_reg_operand")
3305         (umod:GPR (match_dup 1)
3306                   (match_dup 2)))]
3307   "TARGET_MODULO
3308    && ! reg_mentioned_p (operands[0], operands[1])
3309    && ! reg_mentioned_p (operands[0], operands[2])
3310    && ! reg_mentioned_p (operands[3], operands[1])
3311    && ! reg_mentioned_p (operands[3], operands[2])"
3312   [(set (match_dup 0)
3313         (udiv:GPR (match_dup 1)
3314                   (match_dup 2)))
3315    (set (match_dup 3)
3316         (mult:GPR (match_dup 0)
3317                   (match_dup 2)))
3318    (set (match_dup 3)
3319         (minus:GPR (match_dup 1)
3320                    (match_dup 3)))])
3323 ;; Logical instructions
3324 ;; The logical instructions are mostly combined by using match_operator,
3325 ;; but the plain AND insns are somewhat different because there is no
3326 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3327 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3329 (define_expand "and<mode>3"
3330   [(set (match_operand:SDI 0 "gpc_reg_operand")
3331         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3332                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3333   ""
3335   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3336     {
3337       rs6000_split_logical (operands, AND, false, false, false);
3338       DONE;
3339     }
3341   if (CONST_INT_P (operands[2]))
3342     {
3343       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3344         {
3345           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3346           DONE;
3347         }
3349       if (logical_const_operand (operands[2], <MODE>mode))
3350         {
3351           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3352           DONE;
3353         }
3355       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3356         {
3357           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3358           DONE;
3359         }
3361       operands[2] = force_reg (<MODE>mode, operands[2]);
3362     }
3366 (define_insn "and<mode>3_imm"
3367   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3368         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3369                  (match_operand:GPR 2 "logical_const_operand" "n")))
3370    (clobber (match_scratch:CC 3 "=x"))]
3371   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3372   "andi%e2. %0,%1,%u2"
3373   [(set_attr "type" "logical")
3374    (set_attr "dot" "yes")])
3376 (define_insn_and_split "*and<mode>3_imm_dot"
3377   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3378         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3379                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3380                     (const_int 0)))
3381    (clobber (match_scratch:GPR 0 "=r,r"))
3382    (clobber (match_scratch:CC 4 "=X,x"))]
3383   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3384    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3385   "@
3386    andi%e2. %0,%1,%u2
3387    #"
3388   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3389   [(parallel [(set (match_dup 0)
3390                    (and:GPR (match_dup 1)
3391                             (match_dup 2)))
3392               (clobber (match_dup 4))])
3393    (set (match_dup 3)
3394         (compare:CC (match_dup 0)
3395                     (const_int 0)))]
3396   ""
3397   [(set_attr "type" "logical")
3398    (set_attr "dot" "yes")
3399    (set_attr "length" "4,8")])
3401 (define_insn_and_split "*and<mode>3_imm_dot2"
3402   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3403         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3404                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3405                     (const_int 0)))
3406    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3407         (and:GPR (match_dup 1)
3408                  (match_dup 2)))
3409    (clobber (match_scratch:CC 4 "=X,x"))]
3410   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3411    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3412   "@
3413    andi%e2. %0,%1,%u2
3414    #"
3415   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3416   [(parallel [(set (match_dup 0)
3417                    (and:GPR (match_dup 1)
3418                             (match_dup 2)))
3419               (clobber (match_dup 4))])
3420    (set (match_dup 3)
3421         (compare:CC (match_dup 0)
3422                     (const_int 0)))]
3423   ""
3424   [(set_attr "type" "logical")
3425    (set_attr "dot" "yes")
3426    (set_attr "length" "4,8")])
3428 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3429   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3430         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3431                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3432                     (const_int 0)))
3433    (clobber (match_scratch:GPR 0 "=r,r"))]
3434   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3435    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3436   "@
3437    andi%e2. %0,%1,%u2
3438    #"
3439   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3440   [(set (match_dup 0)
3441         (and:GPR (match_dup 1)
3442                  (match_dup 2)))
3443    (set (match_dup 3)
3444         (compare:CC (match_dup 0)
3445                     (const_int 0)))]
3446   ""
3447   [(set_attr "type" "logical")
3448    (set_attr "dot" "yes")
3449    (set_attr "length" "4,8")])
3451 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3452   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3453         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3454                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3455                     (const_int 0)))
3456    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3457         (and:GPR (match_dup 1)
3458                  (match_dup 2)))]
3459   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3460    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3461   "@
3462    andi%e2. %0,%1,%u2
3463    #"
3464   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3465   [(set (match_dup 0)
3466         (and:GPR (match_dup 1)
3467                  (match_dup 2)))
3468    (set (match_dup 3)
3469         (compare:CC (match_dup 0)
3470                     (const_int 0)))]
3471   ""
3472   [(set_attr "type" "logical")
3473    (set_attr "dot" "yes")
3474    (set_attr "length" "4,8")])
3476 (define_insn "*and<mode>3_imm_dot_shifted"
3477   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3478         (compare:CC
3479           (and:GPR
3480             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3481                           (match_operand:SI 4 "const_int_operand" "n"))
3482             (match_operand:GPR 2 "const_int_operand" "n"))
3483           (const_int 0)))
3484    (clobber (match_scratch:GPR 0 "=r"))]
3485   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3486                                    << INTVAL (operands[4])),
3487                           DImode)
3488    && (<MODE>mode == Pmode
3489        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3491   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3492   return "andi%e2. %0,%1,%u2";
3494   [(set_attr "type" "logical")
3495    (set_attr "dot" "yes")])
3498 (define_insn "and<mode>3_mask"
3499   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3500         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3501                  (match_operand:GPR 2 "const_int_operand" "n")))]
3502   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3504   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3506   [(set_attr "type" "shift")])
3508 (define_insn_and_split "*and<mode>3_mask_dot"
3509   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3510         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3511                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3512                     (const_int 0)))
3513    (clobber (match_scratch:GPR 0 "=r,r"))]
3514   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515    && !logical_const_operand (operands[2], <MODE>mode)
3516    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3518   if (which_alternative == 0)
3519     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3520   else
3521     return "#";
3523   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3524   [(set (match_dup 0)
3525         (and:GPR (match_dup 1)
3526                  (match_dup 2)))
3527    (set (match_dup 3)
3528         (compare:CC (match_dup 0)
3529                     (const_int 0)))]
3530   ""
3531   [(set_attr "type" "shift")
3532    (set_attr "dot" "yes")
3533    (set_attr "length" "4,8")])
3535 (define_insn_and_split "*and<mode>3_mask_dot2"
3536   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3537         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3538                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3539                     (const_int 0)))
3540    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3541         (and:GPR (match_dup 1)
3542                  (match_dup 2)))]
3543   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3544    && !logical_const_operand (operands[2], <MODE>mode)
3545    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3547   if (which_alternative == 0)
3548     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3549   else
3550     return "#";
3552   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3553   [(set (match_dup 0)
3554         (and:GPR (match_dup 1)
3555                  (match_dup 2)))
3556    (set (match_dup 3)
3557         (compare:CC (match_dup 0)
3558                     (const_int 0)))]
3559   ""
3560   [(set_attr "type" "shift")
3561    (set_attr "dot" "yes")
3562    (set_attr "length" "4,8")])
3565 (define_insn_and_split "*and<mode>3_2insn"
3566   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3567         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3568                  (match_operand:GPR 2 "const_int_operand" "n")))]
3569   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3570    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3571         || logical_const_operand (operands[2], <MODE>mode))"
3572   "#"
3573   "&& 1"
3574   [(pc)]
3576   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3577   DONE;
3579   [(set_attr "type" "shift")
3580    (set_attr "length" "8")])
3582 (define_insn_and_split "*and<mode>3_2insn_dot"
3583   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3584         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3585                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3586                     (const_int 0)))
3587    (clobber (match_scratch:GPR 0 "=r,r"))]
3588   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3589    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3590    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3591         || logical_const_operand (operands[2], <MODE>mode))"
3592   "#"
3593   "&& reload_completed"
3594   [(pc)]
3596   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3597   DONE;
3599   [(set_attr "type" "shift")
3600    (set_attr "dot" "yes")
3601    (set_attr "length" "8,12")])
3603 (define_insn_and_split "*and<mode>3_2insn_dot2"
3604   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3605         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3606                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3607                     (const_int 0)))
3608    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3609         (and:GPR (match_dup 1)
3610                  (match_dup 2)))]
3611   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3612    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3613    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3614         || logical_const_operand (operands[2], <MODE>mode))"
3615   "#"
3616   "&& reload_completed"
3617   [(pc)]
3619   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3620   DONE;
3622   [(set_attr "type" "shift")
3623    (set_attr "dot" "yes")
3624    (set_attr "length" "8,12")])
3627 (define_expand "<code><mode>3"
3628   [(set (match_operand:SDI 0 "gpc_reg_operand")
3629         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3630                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3631   ""
3633   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3634     {
3635       rs6000_split_logical (operands, <CODE>, false, false, false);
3636       DONE;
3637     }
3639   if (non_logical_cint_operand (operands[2], <MODE>mode))
3640     {
3641       rtx tmp = ((!can_create_pseudo_p ()
3642                   || rtx_equal_p (operands[0], operands[1]))
3643                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3645       HOST_WIDE_INT value = INTVAL (operands[2]);
3646       HOST_WIDE_INT lo = value & 0xffff;
3647       HOST_WIDE_INT hi = value - lo;
3649       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3650       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3651       DONE;
3652     }
3654   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3655     operands[2] = force_reg (<MODE>mode, operands[2]);
3658 (define_split
3659   [(set (match_operand:GPR 0 "gpc_reg_operand")
3660         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3661                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3662   ""
3663   [(set (match_dup 3)
3664         (iorxor:GPR (match_dup 1)
3665                     (match_dup 4)))
3666    (set (match_dup 0)
3667         (iorxor:GPR (match_dup 3)
3668                     (match_dup 5)))]
3670   operands[3] = ((!can_create_pseudo_p ()
3671                   || rtx_equal_p (operands[0], operands[1]))
3672                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3674   HOST_WIDE_INT value = INTVAL (operands[2]);
3675   HOST_WIDE_INT lo = value & 0xffff;
3676   HOST_WIDE_INT hi = value - lo;
3678   operands[4] = GEN_INT (hi);
3679   operands[5] = GEN_INT (lo);
3682 (define_insn "*bool<mode>3_imm"
3683   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3684         (match_operator:GPR 3 "boolean_or_operator"
3685          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3686           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3687   ""
3688   "%q3i%e2 %0,%1,%u2"
3689   [(set_attr "type" "logical")])
3691 (define_insn "*bool<mode>3"
3692   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3693         (match_operator:GPR 3 "boolean_operator"
3694          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3695           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3696   ""
3697   "%q3 %0,%1,%2"
3698   [(set_attr "type" "logical")])
3700 (define_insn_and_split "*bool<mode>3_dot"
3701   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3702         (compare:CC (match_operator:GPR 3 "boolean_operator"
3703          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3704           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3705          (const_int 0)))
3706    (clobber (match_scratch:GPR 0 "=r,r"))]
3707   "<MODE>mode == Pmode"
3708   "@
3709    %q3. %0,%1,%2
3710    #"
3711   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3712   [(set (match_dup 0)
3713         (match_dup 3))
3714    (set (match_dup 4)
3715         (compare:CC (match_dup 0)
3716                     (const_int 0)))]
3717   ""
3718   [(set_attr "type" "logical")
3719    (set_attr "dot" "yes")
3720    (set_attr "length" "4,8")])
3722 (define_insn_and_split "*bool<mode>3_dot2"
3723   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3724         (compare:CC (match_operator:GPR 3 "boolean_operator"
3725          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3726           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3727          (const_int 0)))
3728    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3729         (match_dup 3))]
3730   "<MODE>mode == Pmode"
3731   "@
3732    %q3. %0,%1,%2
3733    #"
3734   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3735   [(set (match_dup 0)
3736         (match_dup 3))
3737    (set (match_dup 4)
3738         (compare:CC (match_dup 0)
3739                     (const_int 0)))]
3740   ""
3741   [(set_attr "type" "logical")
3742    (set_attr "dot" "yes")
3743    (set_attr "length" "4,8")])
3746 (define_insn "*boolc<mode>3"
3747   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3748         (match_operator:GPR 3 "boolean_operator"
3749          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3750           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3751   ""
3752   "%q3 %0,%1,%2"
3753   [(set_attr "type" "logical")])
3755 (define_insn_and_split "*boolc<mode>3_dot"
3756   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3757         (compare:CC (match_operator:GPR 3 "boolean_operator"
3758          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3759           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3760          (const_int 0)))
3761    (clobber (match_scratch:GPR 0 "=r,r"))]
3762   "<MODE>mode == Pmode"
3763   "@
3764    %q3. %0,%1,%2
3765    #"
3766   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3767   [(set (match_dup 0)
3768         (match_dup 3))
3769    (set (match_dup 4)
3770         (compare:CC (match_dup 0)
3771                     (const_int 0)))]
3772   ""
3773   [(set_attr "type" "logical")
3774    (set_attr "dot" "yes")
3775    (set_attr "length" "4,8")])
3777 (define_insn_and_split "*boolc<mode>3_dot2"
3778   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3779         (compare:CC (match_operator:GPR 3 "boolean_operator"
3780          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3781           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3782          (const_int 0)))
3783    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3784         (match_dup 3))]
3785   "<MODE>mode == Pmode"
3786   "@
3787    %q3. %0,%1,%2
3788    #"
3789   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3790   [(set (match_dup 0)
3791         (match_dup 3))
3792    (set (match_dup 4)
3793         (compare:CC (match_dup 0)
3794                     (const_int 0)))]
3795   ""
3796   [(set_attr "type" "logical")
3797    (set_attr "dot" "yes")
3798    (set_attr "length" "4,8")])
3801 (define_insn "*boolcc<mode>3"
3802   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3803         (match_operator:GPR 3 "boolean_operator"
3804          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3805           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3806   ""
3807   "%q3 %0,%1,%2"
3808   [(set_attr "type" "logical")])
3810 (define_insn_and_split "*boolcc<mode>3_dot"
3811   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3812         (compare:CC (match_operator:GPR 3 "boolean_operator"
3813          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3814           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3815          (const_int 0)))
3816    (clobber (match_scratch:GPR 0 "=r,r"))]
3817   "<MODE>mode == Pmode"
3818   "@
3819    %q3. %0,%1,%2
3820    #"
3821   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3822   [(set (match_dup 0)
3823         (match_dup 3))
3824    (set (match_dup 4)
3825         (compare:CC (match_dup 0)
3826                     (const_int 0)))]
3827   ""
3828   [(set_attr "type" "logical")
3829    (set_attr "dot" "yes")
3830    (set_attr "length" "4,8")])
3832 (define_insn_and_split "*boolcc<mode>3_dot2"
3833   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3834         (compare:CC (match_operator:GPR 3 "boolean_operator"
3835          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3836           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3837          (const_int 0)))
3838    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3839         (match_dup 3))]
3840   "<MODE>mode == Pmode"
3841   "@
3842    %q3. %0,%1,%2
3843    #"
3844   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3845   [(set (match_dup 0)
3846         (match_dup 3))
3847    (set (match_dup 4)
3848         (compare:CC (match_dup 0)
3849                     (const_int 0)))]
3850   ""
3851   [(set_attr "type" "logical")
3852    (set_attr "dot" "yes")
3853    (set_attr "length" "4,8")])
3856 ;; TODO: Should have dots of this as well.
3857 (define_insn "*eqv<mode>3"
3858   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3859         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3860                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3861   ""
3862   "eqv %0,%1,%2"
3863   [(set_attr "type" "logical")])
3865 ;; Rotate-and-mask and insert.
3867 (define_insn "*rotl<mode>3_mask"
3868   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3872                  (match_operand:GPR 3 "const_int_operand" "n")))]
3873   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3875   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3877   [(set_attr "type" "shift")
3878    (set_attr "maybe_var_shift" "yes")])
3880 (define_insn_and_split "*rotl<mode>3_mask_dot"
3881   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3882         (compare:CC
3883           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3884                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3885                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3886                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3887           (const_int 0)))
3888    (clobber (match_scratch:GPR 0 "=r,r"))]
3889   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3890    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3892   if (which_alternative == 0)
3893     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3894   else
3895     return "#";
3897   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3898   [(set (match_dup 0)
3899         (and:GPR (match_dup 4)
3900                  (match_dup 3)))
3901    (set (match_dup 5)
3902         (compare:CC (match_dup 0)
3903                     (const_int 0)))]
3904   ""
3905   [(set_attr "type" "shift")
3906    (set_attr "maybe_var_shift" "yes")
3907    (set_attr "dot" "yes")
3908    (set_attr "length" "4,8")])
3910 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3911   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3912         (compare:CC
3913           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3914                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3915                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3916                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3917           (const_int 0)))
3918    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3919         (and:GPR (match_dup 4)
3920                  (match_dup 3)))]
3921   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3922    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3924   if (which_alternative == 0)
3925     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3926   else
3927     return "#";
3929   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3930   [(set (match_dup 0)
3931         (and:GPR (match_dup 4)
3932                  (match_dup 3)))
3933    (set (match_dup 5)
3934         (compare:CC (match_dup 0)
3935                     (const_int 0)))]
3936   ""
3937   [(set_attr "type" "shift")
3938    (set_attr "maybe_var_shift" "yes")
3939    (set_attr "dot" "yes")
3940    (set_attr "length" "4,8")])
3942 ; Special case for less-than-0.  We can do it with just one machine
3943 ; instruction, but the generic optimizers do not realise it is cheap.
3944 (define_insn "*lt0_<mode>di"
3945   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3946         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3947                 (const_int 0)))]
3948   "TARGET_POWERPC64"
3949   "srdi %0,%1,63"
3950   [(set_attr "type" "shift")])
3952 (define_insn "*lt0_<mode>si"
3953   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3954         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3955                 (const_int 0)))]
3956   ""
3957   "rlwinm %0,%1,1,31,31"
3958   [(set_attr "type" "shift")])
3962 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3963 ; both are an AND so are the same precedence).
3964 (define_insn "*rotl<mode>3_insert"
3965   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3966         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3967                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3968                             (match_operand:SI 2 "const_int_operand" "n")])
3969                           (match_operand:GPR 3 "const_int_operand" "n"))
3970                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3971                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3972   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3973    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3975   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3977   [(set_attr "type" "insert")])
3978 ; FIXME: this needs an attr "size", so that the scheduler can see the
3979 ; difference between rlwimi and rldimi.  We also might want dot forms,
3980 ; but not for rlwimi on POWER4 and similar processors.
3982 (define_insn "*rotl<mode>3_insert_2"
3983   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3984         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3985                           (match_operand:GPR 6 "const_int_operand" "n"))
3986                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3987                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3988                             (match_operand:SI 2 "const_int_operand" "n")])
3989                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3990   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3991    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3993   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3995   [(set_attr "type" "insert")])
3997 ; There are also some forms without one of the ANDs.
3998 (define_insn "*rotl<mode>3_insert_3"
3999   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4000         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4001                           (match_operand:GPR 4 "const_int_operand" "n"))
4002                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4003                              (match_operand:SI 2 "const_int_operand" "n"))))]
4004   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4006   if (<MODE>mode == SImode)
4007     return "rlwimi %0,%1,%h2,0,31-%h2";
4008   else
4009     return "rldimi %0,%1,%H2,0";
4011   [(set_attr "type" "insert")])
4013 (define_insn "*rotl<mode>3_insert_4"
4014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4015         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4016                           (match_operand:GPR 4 "const_int_operand" "n"))
4017                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4018                                (match_operand:SI 2 "const_int_operand" "n"))))]
4019   "<MODE>mode == SImode &&
4020    GET_MODE_PRECISION (<MODE>mode)
4021    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4023   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4024                          - INTVAL (operands[2]));
4025   if (<MODE>mode == SImode)
4026     return "rlwimi %0,%1,%h2,32-%h2,31";
4027   else
4028     return "rldimi %0,%1,%H2,64-%H2";
4030   [(set_attr "type" "insert")])
4032 (define_insn "*rotlsi3_insert_5"
4033   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4034         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4035                         (match_operand:SI 2 "const_int_operand" "n,n"))
4036                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4037                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
4038   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4039    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4040    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4041   "@
4042    rlwimi %0,%3,0,%4
4043    rlwimi %0,%1,0,%2"
4044   [(set_attr "type" "insert")])
4046 (define_insn "*rotldi3_insert_6"
4047   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4048         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4049                         (match_operand:DI 2 "const_int_operand" "n"))
4050                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4051                         (match_operand:DI 4 "const_int_operand" "n"))))]
4052   "exact_log2 (-UINTVAL (operands[2])) > 0
4053    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4055   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4056   return "rldimi %0,%3,0,%5";
4058   [(set_attr "type" "insert")
4059    (set_attr "size" "64")])
4061 (define_insn "*rotldi3_insert_7"
4062   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4063         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4064                         (match_operand:DI 4 "const_int_operand" "n"))
4065                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4066                         (match_operand:DI 2 "const_int_operand" "n"))))]
4067   "exact_log2 (-UINTVAL (operands[2])) > 0
4068    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4070   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4071   return "rldimi %0,%3,0,%5";
4073   [(set_attr "type" "insert")
4074    (set_attr "size" "64")])
4077 ; This handles the important case of multiple-precision shifts.  There is
4078 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4079 (define_split
4080   [(set (match_operand:GPR 0 "gpc_reg_operand")
4081         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4082                              (match_operand:SI 3 "const_int_operand"))
4083                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4084                                (match_operand:SI 4 "const_int_operand"))))]
4085   "can_create_pseudo_p ()
4086    && INTVAL (operands[3]) + INTVAL (operands[4])
4087       >= GET_MODE_PRECISION (<MODE>mode)"
4088   [(set (match_dup 5)
4089         (lshiftrt:GPR (match_dup 2)
4090                       (match_dup 4)))
4091    (set (match_dup 0)
4092         (ior:GPR (and:GPR (match_dup 5)
4093                           (match_dup 6))
4094                  (ashift:GPR (match_dup 1)
4095                              (match_dup 3))))]
4097   unsigned HOST_WIDE_INT mask = 1;
4098   mask = (mask << INTVAL (operands[3])) - 1;
4099   operands[5] = gen_reg_rtx (<MODE>mode);
4100   operands[6] = GEN_INT (mask);
4103 (define_split
4104   [(set (match_operand:GPR 0 "gpc_reg_operand")
4105         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4106                                (match_operand:SI 4 "const_int_operand"))
4107                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4108                              (match_operand:SI 3 "const_int_operand"))))]
4109   "can_create_pseudo_p ()
4110    && INTVAL (operands[3]) + INTVAL (operands[4])
4111       >= GET_MODE_PRECISION (<MODE>mode)"
4112   [(set (match_dup 5)
4113         (lshiftrt:GPR (match_dup 2)
4114                       (match_dup 4)))
4115    (set (match_dup 0)
4116         (ior:GPR (and:GPR (match_dup 5)
4117                           (match_dup 6))
4118                  (ashift:GPR (match_dup 1)
4119                              (match_dup 3))))]
4121   unsigned HOST_WIDE_INT mask = 1;
4122   mask = (mask << INTVAL (operands[3])) - 1;
4123   operands[5] = gen_reg_rtx (<MODE>mode);
4124   operands[6] = GEN_INT (mask);
4128 ; Another important case is setting some bits to 1; we can do that with
4129 ; an insert instruction, in many cases.
4130 (define_insn_and_split "*ior<mode>_mask"
4131   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4132         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4133                  (match_operand:GPR 2 "const_int_operand" "n")))
4134    (clobber (match_scratch:GPR 3 "=r"))]
4135   "!logical_const_operand (operands[2], <MODE>mode)
4136    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4137   "#"
4138   "&& 1"
4139   [(set (match_dup 3)
4140         (const_int -1))
4141    (set (match_dup 0)
4142         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4143                                       (match_dup 4))
4144                           (match_dup 2))
4145                  (and:GPR (match_dup 1)
4146                           (match_dup 5))))]
4148   int nb, ne;
4149   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4150   if (GET_CODE (operands[3]) == SCRATCH)
4151     operands[3] = gen_reg_rtx (<MODE>mode);
4152   operands[4] = GEN_INT (ne);
4153   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4155   [(set_attr "type" "two")
4156    (set_attr "length" "8")])
4159 ; Yet another case is an rldimi with the second value coming from memory.
4160 ; The zero_extend that should become part of the rldimi is merged into the
4161 ; load from memory instead.  Split things properly again.
4162 (define_split
4163   [(set (match_operand:DI 0 "gpc_reg_operand")
4164         (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4165                            (match_operand:SI 2 "const_int_operand"))
4166                 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4167   "INTVAL (operands[2]) == <bits>"
4168   [(set (match_dup 4)
4169         (zero_extend:DI (match_dup 3)))
4170    (set (match_dup 0)
4171         (ior:DI (and:DI (match_dup 4)
4172                         (match_dup 5))
4173                 (ashift:DI (match_dup 1)
4174                            (match_dup 2))))]
4176   operands[4] = gen_reg_rtx (DImode);
4177   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4180 ; rlwimi, too.
4181 (define_split
4182   [(set (match_operand:SI 0 "gpc_reg_operand")
4183         (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4184                            (match_operand:SI 2 "const_int_operand"))
4185                 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4186   "INTVAL (operands[2]) == <bits>"
4187   [(set (match_dup 4)
4188         (zero_extend:SI (match_dup 3)))
4189    (set (match_dup 0)
4190         (ior:SI (and:SI (match_dup 4)
4191                         (match_dup 5))
4192                 (ashift:SI (match_dup 1)
4193                            (match_dup 2))))]
4195   operands[4] = gen_reg_rtx (SImode);
4196   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4200 ;; Now the simple shifts.
4202 (define_insn "rotl<mode>3"
4203   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4204         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4205                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4206   ""
4207   "rotl<wd>%I2 %0,%1,%<hH>2"
4208   [(set_attr "type" "shift")
4209    (set_attr "maybe_var_shift" "yes")])
4211 (define_insn "*rotlsi3_64"
4212   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4213         (zero_extend:DI
4214             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4215                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4216   "TARGET_POWERPC64"
4217   "rotlw%I2 %0,%1,%h2"
4218   [(set_attr "type" "shift")
4219    (set_attr "maybe_var_shift" "yes")])
4221 (define_insn_and_split "*rotl<mode>3_dot"
4222   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4223         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4224                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4225                     (const_int 0)))
4226    (clobber (match_scratch:GPR 0 "=r,r"))]
4227   "<MODE>mode == Pmode"
4228   "@
4229    rotl<wd>%I2. %0,%1,%<hH>2
4230    #"
4231   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4232   [(set (match_dup 0)
4233         (rotate:GPR (match_dup 1)
4234                     (match_dup 2)))
4235    (set (match_dup 3)
4236         (compare:CC (match_dup 0)
4237                     (const_int 0)))]
4238   ""
4239   [(set_attr "type" "shift")
4240    (set_attr "maybe_var_shift" "yes")
4241    (set_attr "dot" "yes")
4242    (set_attr "length" "4,8")])
4244 (define_insn_and_split "*rotl<mode>3_dot2"
4245   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4246         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4247                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4248                     (const_int 0)))
4249    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4250         (rotate:GPR (match_dup 1)
4251                     (match_dup 2)))]
4252   "<MODE>mode == Pmode"
4253   "@
4254    rotl<wd>%I2. %0,%1,%<hH>2
4255    #"
4256   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4257   [(set (match_dup 0)
4258         (rotate:GPR (match_dup 1)
4259                     (match_dup 2)))
4260    (set (match_dup 3)
4261         (compare:CC (match_dup 0)
4262                     (const_int 0)))]
4263   ""
4264   [(set_attr "type" "shift")
4265    (set_attr "maybe_var_shift" "yes")
4266    (set_attr "dot" "yes")
4267    (set_attr "length" "4,8")])
4270 (define_insn "ashl<mode>3"
4271   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4272         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4273                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4274   ""
4275   "sl<wd>%I2 %0,%1,%<hH>2"
4276   [(set_attr "type" "shift")
4277    (set_attr "maybe_var_shift" "yes")])
4279 (define_insn "*ashlsi3_64"
4280   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4281         (zero_extend:DI
4282             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4283                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4284   "TARGET_POWERPC64"
4285   "slw%I2 %0,%1,%h2"
4286   [(set_attr "type" "shift")
4287    (set_attr "maybe_var_shift" "yes")])
4289 (define_insn_and_split "*ashl<mode>3_dot"
4290   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4291         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4292                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4293                     (const_int 0)))
4294    (clobber (match_scratch:GPR 0 "=r,r"))]
4295   "<MODE>mode == Pmode"
4296   "@
4297    sl<wd>%I2. %0,%1,%<hH>2
4298    #"
4299   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4300   [(set (match_dup 0)
4301         (ashift:GPR (match_dup 1)
4302                     (match_dup 2)))
4303    (set (match_dup 3)
4304         (compare:CC (match_dup 0)
4305                     (const_int 0)))]
4306   ""
4307   [(set_attr "type" "shift")
4308    (set_attr "maybe_var_shift" "yes")
4309    (set_attr "dot" "yes")
4310    (set_attr "length" "4,8")])
4312 (define_insn_and_split "*ashl<mode>3_dot2"
4313   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4314         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4315                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4316                     (const_int 0)))
4317    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4318         (ashift:GPR (match_dup 1)
4319                     (match_dup 2)))]
4320   "<MODE>mode == Pmode"
4321   "@
4322    sl<wd>%I2. %0,%1,%<hH>2
4323    #"
4324   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4325   [(set (match_dup 0)
4326         (ashift:GPR (match_dup 1)
4327                     (match_dup 2)))
4328    (set (match_dup 3)
4329         (compare:CC (match_dup 0)
4330                     (const_int 0)))]
4331   ""
4332   [(set_attr "type" "shift")
4333    (set_attr "maybe_var_shift" "yes")
4334    (set_attr "dot" "yes")
4335    (set_attr "length" "4,8")])
4337 ;; Pretend we have a memory form of extswsli until register allocation is done
4338 ;; so that we use LWZ to load the value from memory, instead of LWA.
4339 (define_insn_and_split "ashdi3_extswsli"
4340   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4341         (ashift:DI
4342          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4343          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4344   "TARGET_EXTSWSLI"
4345   "@
4346    extswsli %0,%1,%2
4347    #"
4348   "&& reload_completed && MEM_P (operands[1])"
4349   [(set (match_dup 3)
4350         (match_dup 1))
4351    (set (match_dup 0)
4352         (ashift:DI (sign_extend:DI (match_dup 3))
4353                    (match_dup 2)))]
4355   operands[3] = gen_lowpart (SImode, operands[0]);
4357   [(set_attr "type" "shift")
4358    (set_attr "maybe_var_shift" "no")])
4361 (define_insn_and_split "ashdi3_extswsli_dot"
4362   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4363         (compare:CC
4364          (ashift:DI
4365           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4366           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4367          (const_int 0)))
4368    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4369   "TARGET_EXTSWSLI"
4370   "@
4371    extswsli. %0,%1,%2
4372    #
4373    #
4374    #"
4375   "&& reload_completed
4376    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4377        || memory_operand (operands[1], SImode))"
4378   [(pc)]
4380   rtx dest = operands[0];
4381   rtx src = operands[1];
4382   rtx shift = operands[2];
4383   rtx cr = operands[3];
4384   rtx src2;
4386   if (!MEM_P (src))
4387     src2 = src;
4388   else
4389     {
4390       src2 = gen_lowpart (SImode, dest);
4391       emit_move_insn (src2, src);
4392     }
4394   if (REGNO (cr) == CR0_REGNO)
4395     {
4396       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4397       DONE;
4398     }
4400   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4401   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4402   DONE;
4404   [(set_attr "type" "shift")
4405    (set_attr "maybe_var_shift" "no")
4406    (set_attr "dot" "yes")
4407    (set_attr "length" "4,8,8,12")])
4409 (define_insn_and_split "ashdi3_extswsli_dot2"
4410   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4411         (compare:CC
4412          (ashift:DI
4413           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4414           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4415          (const_int 0)))
4416    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4417         (ashift:DI (sign_extend:DI (match_dup 1))
4418                    (match_dup 2)))]
4419   "TARGET_EXTSWSLI"
4420   "@
4421    extswsli. %0,%1,%2
4422    #
4423    #
4424    #"
4425   "&& reload_completed
4426    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4427        || memory_operand (operands[1], SImode))"
4428   [(pc)]
4430   rtx dest = operands[0];
4431   rtx src = operands[1];
4432   rtx shift = operands[2];
4433   rtx cr = operands[3];
4434   rtx src2;
4436   if (!MEM_P (src))
4437     src2 = src;
4438   else
4439     {
4440       src2 = gen_lowpart (SImode, dest);
4441       emit_move_insn (src2, src);
4442     }
4444   if (REGNO (cr) == CR0_REGNO)
4445     {
4446       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4447       DONE;
4448     }
4450   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4451   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4452   DONE;
4454   [(set_attr "type" "shift")
4455    (set_attr "maybe_var_shift" "no")
4456    (set_attr "dot" "yes")
4457    (set_attr "length" "4,8,8,12")])
4459 (define_insn "lshr<mode>3"
4460   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4461         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4462                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4463   ""
4464   "sr<wd>%I2 %0,%1,%<hH>2"
4465   [(set_attr "type" "shift")
4466    (set_attr "maybe_var_shift" "yes")])
4468 (define_insn "*lshrsi3_64"
4469   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4470         (zero_extend:DI
4471             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4472                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4473   "TARGET_POWERPC64"
4474   "srw%I2 %0,%1,%h2"
4475   [(set_attr "type" "shift")
4476    (set_attr "maybe_var_shift" "yes")])
4478 (define_insn_and_split "*lshr<mode>3_dot"
4479   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4480         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4481                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4482                     (const_int 0)))
4483    (clobber (match_scratch:GPR 0 "=r,r"))]
4484   "<MODE>mode == Pmode"
4485   "@
4486    sr<wd>%I2. %0,%1,%<hH>2
4487    #"
4488   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4489   [(set (match_dup 0)
4490         (lshiftrt:GPR (match_dup 1)
4491                       (match_dup 2)))
4492    (set (match_dup 3)
4493         (compare:CC (match_dup 0)
4494                     (const_int 0)))]
4495   ""
4496   [(set_attr "type" "shift")
4497    (set_attr "maybe_var_shift" "yes")
4498    (set_attr "dot" "yes")
4499    (set_attr "length" "4,8")])
4501 (define_insn_and_split "*lshr<mode>3_dot2"
4502   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4503         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4504                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4505                     (const_int 0)))
4506    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4507         (lshiftrt:GPR (match_dup 1)
4508                       (match_dup 2)))]
4509   "<MODE>mode == Pmode"
4510   "@
4511    sr<wd>%I2. %0,%1,%<hH>2
4512    #"
4513   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4514   [(set (match_dup 0)
4515         (lshiftrt:GPR (match_dup 1)
4516                       (match_dup 2)))
4517    (set (match_dup 3)
4518         (compare:CC (match_dup 0)
4519                     (const_int 0)))]
4520   ""
4521   [(set_attr "type" "shift")
4522    (set_attr "maybe_var_shift" "yes")
4523    (set_attr "dot" "yes")
4524    (set_attr "length" "4,8")])
4527 (define_insn "ashr<mode>3"
4528   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4529         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4530                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4531    (clobber (reg:GPR CA_REGNO))]
4532   ""
4533   "sra<wd>%I2 %0,%1,%<hH>2"
4534   [(set_attr "type" "shift")
4535    (set_attr "maybe_var_shift" "yes")])
4537 (define_insn "*ashrsi3_64"
4538   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4539         (sign_extend:DI
4540             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4541                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4542    (clobber (reg:SI CA_REGNO))]
4543   "TARGET_POWERPC64"
4544   "sraw%I2 %0,%1,%h2"
4545   [(set_attr "type" "shift")
4546    (set_attr "maybe_var_shift" "yes")])
4548 (define_insn_and_split "*ashr<mode>3_dot"
4549   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4550         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4551                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4552                     (const_int 0)))
4553    (clobber (match_scratch:GPR 0 "=r,r"))
4554    (clobber (reg:GPR CA_REGNO))]
4555   "<MODE>mode == Pmode"
4556   "@
4557    sra<wd>%I2. %0,%1,%<hH>2
4558    #"
4559   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4560   [(parallel [(set (match_dup 0)
4561                    (ashiftrt:GPR (match_dup 1)
4562                                  (match_dup 2)))
4563               (clobber (reg:GPR CA_REGNO))])
4564    (set (match_dup 3)
4565         (compare:CC (match_dup 0)
4566                     (const_int 0)))]
4567   ""
4568   [(set_attr "type" "shift")
4569    (set_attr "maybe_var_shift" "yes")
4570    (set_attr "dot" "yes")
4571    (set_attr "length" "4,8")])
4573 (define_insn_and_split "*ashr<mode>3_dot2"
4574   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4575         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4576                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4577                     (const_int 0)))
4578    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4579         (ashiftrt:GPR (match_dup 1)
4580                       (match_dup 2)))
4581    (clobber (reg:GPR CA_REGNO))]
4582   "<MODE>mode == Pmode"
4583   "@
4584    sra<wd>%I2. %0,%1,%<hH>2
4585    #"
4586   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4587   [(parallel [(set (match_dup 0)
4588                    (ashiftrt:GPR (match_dup 1)
4589                                  (match_dup 2)))
4590               (clobber (reg:GPR CA_REGNO))])
4591    (set (match_dup 3)
4592         (compare:CC (match_dup 0)
4593                     (const_int 0)))]
4594   ""
4595   [(set_attr "type" "shift")
4596    (set_attr "maybe_var_shift" "yes")
4597    (set_attr "dot" "yes")
4598    (set_attr "length" "4,8")])
4600 ;; Builtins to replace a division to generate FRE reciprocal estimate
4601 ;; instructions and the necessary fixup instructions
4602 (define_expand "recip<mode>3"
4603   [(match_operand:RECIPF 0 "gpc_reg_operand")
4604    (match_operand:RECIPF 1 "gpc_reg_operand")
4605    (match_operand:RECIPF 2 "gpc_reg_operand")]
4606   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4608    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4609    DONE;
4612 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4613 ;; hardware division.  This is only done before register allocation and with
4614 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4615 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4616 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4617 (define_split
4618   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4619         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4620                     (match_operand 2 "gpc_reg_operand")))]
4621   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4622    && can_create_pseudo_p () && flag_finite_math_only
4623    && !flag_trapping_math && flag_reciprocal_math"
4624   [(const_int 0)]
4626   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4627   DONE;
4630 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4631 ;; appropriate fixup.
4632 (define_expand "rsqrt<mode>2"
4633   [(match_operand:RECIPF 0 "gpc_reg_operand")
4634    (match_operand:RECIPF 1 "gpc_reg_operand")]
4635   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4637   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4638   DONE;
4641 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4642 ;; modes here, and also add in conditional vsx/power8-vector support to access
4643 ;; values in the traditional Altivec registers if the appropriate
4644 ;; -mupper-regs-{df,sf} option is enabled.
4646 (define_expand "abs<mode>2"
4647   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4648         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4649   "TARGET_HARD_FLOAT"
4650   "")
4652 (define_insn "*abs<mode>2_fpr"
4653   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4654         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4655   "TARGET_HARD_FLOAT"
4656   "@
4657    fabs %0,%1
4658    xsabsdp %x0,%x1"
4659   [(set_attr "type" "fpsimple")])
4661 (define_insn "*nabs<mode>2_fpr"
4662   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4663         (neg:SFDF
4664          (abs:SFDF
4665           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4666   "TARGET_HARD_FLOAT"
4667   "@
4668    fnabs %0,%1
4669    xsnabsdp %x0,%x1"
4670   [(set_attr "type" "fpsimple")])
4672 (define_expand "neg<mode>2"
4673   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4674         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4675   "TARGET_HARD_FLOAT"
4676   "")
4678 (define_insn "*neg<mode>2_fpr"
4679   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4680         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4681   "TARGET_HARD_FLOAT"
4682   "@
4683    fneg %0,%1
4684    xsnegdp %x0,%x1"
4685   [(set_attr "type" "fpsimple")])
4687 (define_expand "add<mode>3"
4688   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4689         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4690                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4691   "TARGET_HARD_FLOAT"
4692   "")
4694 (define_insn "*add<mode>3_fpr"
4695   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4696         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4697                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4698   "TARGET_HARD_FLOAT"
4699   "@
4700    fadd<s> %0,%1,%2
4701    xsadd<sd>p %x0,%x1,%x2"
4702   [(set_attr "type" "fp")
4703    (set_attr "isa" "*,<Fisa>")])
4705 (define_expand "sub<mode>3"
4706   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4707         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4708                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4709   "TARGET_HARD_FLOAT"
4710   "")
4712 (define_insn "*sub<mode>3_fpr"
4713   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4714         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4715                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4716   "TARGET_HARD_FLOAT"
4717   "@
4718    fsub<s> %0,%1,%2
4719    xssub<sd>p %x0,%x1,%x2"
4720   [(set_attr "type" "fp")
4721    (set_attr "isa" "*,<Fisa>")])
4723 (define_expand "mul<mode>3"
4724   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4725         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4726                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4727   "TARGET_HARD_FLOAT"
4728   "")
4730 (define_insn "*mul<mode>3_fpr"
4731   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4732         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4733                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4734   "TARGET_HARD_FLOAT"
4735   "@
4736    fmul<s> %0,%1,%2
4737    xsmul<sd>p %x0,%x1,%x2"
4738   [(set_attr "type" "dmul")
4739    (set_attr "isa" "*,<Fisa>")])
4741 (define_expand "div<mode>3"
4742   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4743         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4744                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4745   "TARGET_HARD_FLOAT"
4747   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4748       && can_create_pseudo_p () && flag_finite_math_only
4749       && !flag_trapping_math && flag_reciprocal_math)
4750     {
4751       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4752       DONE;
4753     }
4756 (define_insn "*div<mode>3_fpr"
4757   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4758         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4759                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4760   "TARGET_HARD_FLOAT"
4761   "@
4762    fdiv<s> %0,%1,%2
4763    xsdiv<sd>p %x0,%x1,%x2"
4764   [(set_attr "type" "<sd>div")
4765    (set_attr "isa" "*,<Fisa>")])
4767 (define_insn "*sqrt<mode>2_internal"
4768   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4769         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4770   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4771   "@
4772    fsqrt<s> %0,%1
4773    xssqrt<sd>p %x0,%x1"
4774   [(set_attr "type" "<sd>sqrt")
4775    (set_attr "isa" "*,<Fisa>")])
4777 (define_expand "sqrt<mode>2"
4778   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4779         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4780   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4782   if (<MODE>mode == SFmode
4783       && TARGET_RECIP_PRECISION
4784       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4785       && !optimize_function_for_size_p (cfun)
4786       && flag_finite_math_only && !flag_trapping_math
4787       && flag_unsafe_math_optimizations)
4788     {
4789       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4790       DONE;
4791     }
4794 ;; Floating point reciprocal approximation
4795 (define_insn "fre<sd>"
4796   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4797         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4798                      UNSPEC_FRES))]
4799   "TARGET_<FFRE>"
4800   "@
4801    fre<s> %0,%1
4802    xsre<sd>p %x0,%x1"
4803   [(set_attr "type" "fp")
4804    (set_attr "isa" "*,<Fisa>")])
4806 (define_insn "*rsqrt<mode>2"
4807   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4808         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4809                      UNSPEC_RSQRT))]
4810   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4811   "@
4812    frsqrte<s> %0,%1
4813    xsrsqrte<sd>p %x0,%x1"
4814   [(set_attr "type" "fp")
4815    (set_attr "isa" "*,<Fisa>")])
4817 ;; Floating point comparisons
4818 (define_insn "*cmp<mode>_fpr"
4819   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4820         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4821                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4822   "TARGET_HARD_FLOAT"
4823   "@
4824    fcmpu %0,%1,%2
4825    xscmpudp %0,%x1,%x2"
4826   [(set_attr "type" "fpcompare")
4827    (set_attr "isa" "*,<Fisa>")])
4829 ;; Floating point conversions
4830 (define_expand "extendsfdf2"
4831   [(set (match_operand:DF 0 "gpc_reg_operand")
4832         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4833   "TARGET_HARD_FLOAT"
4835   if (HONOR_SNANS (SFmode))
4836     operands[1] = force_reg (SFmode, operands[1]);
4839 (define_insn_and_split "*extendsfdf2_fpr"
4840   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4841         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4842   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4843   "@
4844    #
4845    fmr %0,%1
4846    lfs%U1%X1 %0,%1
4847    #
4848    xscpsgndp %x0,%x1,%x1
4849    lxsspx %x0,%y1
4850    lxssp %0,%1"
4851   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4852   [(const_int 0)]
4854   emit_note (NOTE_INSN_DELETED);
4855   DONE;
4857   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4858    (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4860 (define_insn "*extendsfdf2_snan"
4861   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4862         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4863   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4864   "@
4865    frsp %0,%1
4866    xsrsp %x0,%x1"
4867   [(set_attr "type" "fp")
4868    (set_attr "isa" "*,p8v")])
4870 (define_expand "truncdfsf2"
4871   [(set (match_operand:SF 0 "gpc_reg_operand")
4872         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4873   "TARGET_HARD_FLOAT"
4874   "")
4876 (define_insn "*truncdfsf2_fpr"
4877   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4878         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4879   "TARGET_HARD_FLOAT"
4880   "@
4881    frsp %0,%1
4882    xsrsp %x0,%x1"
4883   [(set_attr "type" "fp")
4884    (set_attr "isa" "*,p8v")])
4886 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4887 ;; builtins.c and optabs.c that are not correct for IBM long double
4888 ;; when little-endian.
4889 (define_expand "signbit<mode>2"
4890   [(set (match_dup 2)
4891         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4892    (set (match_dup 3)
4893         (subreg:DI (match_dup 2) 0))
4894    (set (match_dup 4)
4895         (match_dup 5))
4896    (set (match_operand:SI 0 "gpc_reg_operand")
4897         (match_dup 6))]
4898   "TARGET_HARD_FLOAT
4899    && (!FLOAT128_IEEE_P (<MODE>mode)
4900        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4902   if (FLOAT128_IEEE_P (<MODE>mode))
4903     {
4904       rtx dest = operands[0];
4905       rtx src = operands[1];
4906       rtx tmp = gen_reg_rtx (DImode);
4907       rtx dest_di = gen_lowpart (DImode, dest);
4909       emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4910       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4911       DONE;
4912     }
4913   operands[2] = gen_reg_rtx (DFmode);
4914   operands[3] = gen_reg_rtx (DImode);
4915   if (TARGET_POWERPC64)
4916     {
4917       operands[4] = gen_reg_rtx (DImode);
4918       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4919       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4920                                     WORDS_BIG_ENDIAN ? 4 : 0);
4921     }
4922   else
4923     {
4924       operands[4] = gen_reg_rtx (SImode);
4925       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4926                                     WORDS_BIG_ENDIAN ? 0 : 4);
4927       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4928     }
4931 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4932 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4933 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4934 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4936 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4937 ;; split allows the post reload phases to eliminate the move, and do the shift
4938 ;; directly with the register that contains the signbit.
4939 (define_insn_and_split "@signbit<mode>2_dm"
4940   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4941         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4942                    UNSPEC_SIGNBIT))]
4943   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4944   "@
4945    mfvsrd %0,%x1
4946    #"
4947   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4948   [(set (match_dup 0)
4949         (match_dup 2))]
4951   operands[2] = gen_highpart (DImode, operands[1]);
4953  [(set_attr "type" "mftgpr,*")])
4955 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4956 ;; register and then doing a direct move if the value comes from memory.  On
4957 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4958 (define_insn_and_split "*signbit<mode>2_dm_mem"
4959   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4960         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4961                    UNSPEC_SIGNBIT))]
4962   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4963   "#"
4964   "&& 1"
4965   [(set (match_dup 0)
4966         (match_dup 2))]
4968   rtx dest = operands[0];
4969   rtx src = operands[1];
4970   rtx addr = XEXP (src, 0);
4972   if (WORDS_BIG_ENDIAN)
4973     operands[2] = adjust_address (src, DImode, 0);
4975   else if (REG_P (addr) || SUBREG_P (addr))
4976     operands[2] = adjust_address (src, DImode, 8);
4978   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4979            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4980     operands[2] = adjust_address (src, DImode, 8);
4982   else
4983     {
4984       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4985       emit_insn (gen_rtx_SET (tmp, addr));
4986       operands[2] = change_address (src, DImode,
4987                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4988     }
4991 (define_expand "copysign<mode>3"
4992   [(set (match_dup 3)
4993         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4994    (set (match_dup 4)
4995         (neg:SFDF (abs:SFDF (match_dup 1))))
4996    (set (match_operand:SFDF 0 "gpc_reg_operand")
4997         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4998                                (match_dup 5))
4999                          (match_dup 3)
5000                          (match_dup 4)))]
5001   "TARGET_HARD_FLOAT
5002    && ((TARGET_PPC_GFXOPT
5003         && !HONOR_NANS (<MODE>mode)
5004         && !HONOR_SIGNED_ZEROS (<MODE>mode))
5005        || TARGET_CMPB
5006        || VECTOR_UNIT_VSX_P (<MODE>mode))"
5008   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5009     {
5010       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5011                                              operands[2]));
5012       DONE;
5013     }
5015    operands[3] = gen_reg_rtx (<MODE>mode);
5016    operands[4] = gen_reg_rtx (<MODE>mode);
5017    operands[5] = CONST0_RTX (<MODE>mode);
5018   })
5020 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5021 ;; compiler from optimizing -0.0
5022 (define_insn "copysign<mode>3_fcpsgn"
5023   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5024         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5025                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5026                      UNSPEC_COPYSIGN))]
5027   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5028   "@
5029    fcpsgn %0,%2,%1
5030    xscpsgndp %x0,%x2,%x1"
5031   [(set_attr "type" "fpsimple")])
5033 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5034 ;; fsel instruction and some auxiliary computations.  Then we just have a
5035 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5036 ;; combine.
5037 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5038 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5039 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
5040 ;; define_splits to make them if made by combine.  On VSX machines we have the
5041 ;; min/max instructions.
5043 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5044 ;; to allow either DF/SF to use only traditional registers.
5046 (define_expand "s<minmax><mode>3"
5047   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5048         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5049                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5050   "TARGET_MINMAX"
5052   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5053   DONE;
5056 (define_insn "*s<minmax><mode>3_vsx"
5057   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5058         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5059                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5060   "TARGET_VSX && TARGET_HARD_FLOAT"
5062   return (TARGET_P9_MINMAX
5063           ? "xs<minmax>cdp %x0,%x1,%x2"
5064           : "xs<minmax>dp %x0,%x1,%x2");
5066   [(set_attr "type" "fp")])
5068 ;; The conditional move instructions allow us to perform max and min operations
5069 ;; even when we don't have the appropriate max/min instruction using the FSEL
5070 ;; instruction.
5072 (define_insn_and_split "*s<minmax><mode>3_fpr"
5073   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5074         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5075                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5076   "!TARGET_VSX && TARGET_MINMAX"
5077   "#"
5078   "&& 1"
5079   [(const_int 0)]
5081   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5082   DONE;
5085 (define_expand "mov<mode>cc"
5086    [(set (match_operand:GPR 0 "gpc_reg_operand")
5087          (if_then_else:GPR (match_operand 1 "comparison_operator")
5088                            (match_operand:GPR 2 "gpc_reg_operand")
5089                            (match_operand:GPR 3 "gpc_reg_operand")))]
5090   "TARGET_ISEL"
5092   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5093     DONE;
5094   else
5095     FAIL;
5098 ;; We use the BASE_REGS for the isel input operands because, if rA is
5099 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5100 ;; because we may switch the operands and rB may end up being rA.
5102 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
5103 ;; leave out the mode in operand 4 and use one pattern, but reload can
5104 ;; change the mode underneath our feet and then gets confused trying
5105 ;; to reload the value.
5106 (define_mode_iterator CCEITHER [CC CCUNS])
5107 (define_mode_attr un [(CC "") (CCUNS "un")])
5108 (define_insn "isel_<un>signed_<GPR:mode>"
5109   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5110         (if_then_else:GPR
5111          (match_operator 1 "scc_comparison_operator"
5112                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5113                           (const_int 0)])
5114          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5115          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5116   "TARGET_ISEL"
5117   "isel %0,%2,%3,%j1"
5118   [(set_attr "type" "isel")])
5120 ;; These patterns can be useful for combine; they let combine know that
5121 ;; isel can handle reversed comparisons so long as the operands are
5122 ;; registers.
5124 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5125   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5126         (if_then_else:GPR
5127          (match_operator 1 "scc_rev_comparison_operator"
5128                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5129                           (const_int 0)])
5130          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5131          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5132   "TARGET_ISEL"
5134   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5135   return "isel %0,%3,%2,%j1";
5137   [(set_attr "type" "isel")])
5139 ;; Floating point conditional move
5140 (define_expand "mov<mode>cc"
5141    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5142          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5143                             (match_operand:SFDF 2 "gpc_reg_operand")
5144                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5145   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5147   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5148     DONE;
5149   else
5150     FAIL;
5153 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5154   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5155         (if_then_else:SFDF
5156          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5157              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5158          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5159          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5160   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5161   "fsel %0,%1,%2,%3"
5162   [(set_attr "type" "fp")])
5164 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5165   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5166         (if_then_else:SFDF
5167          (match_operator:CCFP 1 "fpmask_comparison_operator"
5168                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5169                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5170          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5171          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5172    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5173   "TARGET_P9_MINMAX"
5174   "#"
5175   ""
5176   [(set (match_dup 6)
5177         (if_then_else:V2DI (match_dup 1)
5178                            (match_dup 7)
5179                            (match_dup 8)))
5180    (set (match_dup 0)
5181         (if_then_else:SFDF (ne (match_dup 6)
5182                                (match_dup 8))
5183                            (match_dup 4)
5184                            (match_dup 5)))]
5186   if (GET_CODE (operands[6]) == SCRATCH)
5187     operands[6] = gen_reg_rtx (V2DImode);
5189   operands[7] = CONSTM1_RTX (V2DImode);
5190   operands[8] = CONST0_RTX (V2DImode);
5192  [(set_attr "length" "8")
5193   (set_attr "type" "vecperm")])
5195 ;; Handle inverting the fpmask comparisons.
5196 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5197   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5198         (if_then_else:SFDF
5199          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5200                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5201                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5202          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5203          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5204    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5205   "TARGET_P9_MINMAX"
5206   "#"
5207   "&& 1"
5208   [(set (match_dup 6)
5209         (if_then_else:V2DI (match_dup 9)
5210                            (match_dup 7)
5211                            (match_dup 8)))
5212    (set (match_dup 0)
5213         (if_then_else:SFDF (ne (match_dup 6)
5214                                (match_dup 8))
5215                            (match_dup 5)
5216                            (match_dup 4)))]
5218   rtx op1 = operands[1];
5219   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5221   if (GET_CODE (operands[6]) == SCRATCH)
5222     operands[6] = gen_reg_rtx (V2DImode);
5224   operands[7] = CONSTM1_RTX (V2DImode);
5225   operands[8] = CONST0_RTX (V2DImode);
5227   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5229  [(set_attr "length" "8")
5230   (set_attr "type" "vecperm")])
5232 (define_insn "*fpmask<mode>"
5233   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5234         (if_then_else:V2DI
5235          (match_operator:CCFP 1 "fpmask_comparison_operator"
5236                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5237                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5238          (match_operand:V2DI 4 "all_ones_constant" "")
5239          (match_operand:V2DI 5 "zero_constant" "")))]
5240   "TARGET_P9_MINMAX"
5241   "xscmp%V1dp %x0,%x2,%x3"
5242   [(set_attr "type" "fpcompare")])
5244 (define_insn "*xxsel<mode>"
5245   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5246         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5247                                (match_operand:V2DI 2 "zero_constant" ""))
5248                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5249                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5250   "TARGET_P9_MINMAX"
5251   "xxsel %x0,%x4,%x3,%x1"
5252   [(set_attr "type" "vecmove")])
5255 ;; Conversions to and from floating-point.
5257 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5258 ; don't want to support putting SImode in FPR registers.
5259 (define_insn "lfiwax"
5260   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5261         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5262                    UNSPEC_LFIWAX))]
5263   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5264   "@
5265    lfiwax %0,%y1
5266    lxsiwax %x0,%y1
5267    mtvsrwa %x0,%1
5268    vextsw2d %0,%1"
5269   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5270    (set_attr "isa" "*,p8v,p8v,p9v")])
5272 ; This split must be run before register allocation because it allocates the
5273 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5274 ; it earlier to allow for the combiner to merge insns together where it might
5275 ; not be needed and also in case the insns are deleted as dead code.
5277 (define_insn_and_split "floatsi<mode>2_lfiwax"
5278   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5279         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5280    (clobber (match_scratch:DI 2 "=d,wa"))]
5281   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5282    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5283   "#"
5284   ""
5285   [(pc)]
5287   rtx dest = operands[0];
5288   rtx src = operands[1];
5289   rtx tmp;
5291   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5292     tmp = convert_to_mode (DImode, src, false);
5293   else
5294     {
5295       tmp = operands[2];
5296       if (GET_CODE (tmp) == SCRATCH)
5297         tmp = gen_reg_rtx (DImode);
5298       if (MEM_P (src))
5299         {
5300           src = rs6000_force_indexed_or_indirect_mem (src);
5301           emit_insn (gen_lfiwax (tmp, src));
5302         }
5303       else
5304         {
5305           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5306           emit_move_insn (stack, src);
5307           emit_insn (gen_lfiwax (tmp, stack));
5308         }
5309     }
5310   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5311   DONE;
5313   [(set_attr "length" "12")
5314    (set_attr "type" "fpload")])
5316 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5317   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5318         (float:SFDF
5319          (sign_extend:DI
5320           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5321    (clobber (match_scratch:DI 2 "=d,wa"))]
5322   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5323   "#"
5324   ""
5325   [(pc)]
5327   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5328   if (GET_CODE (operands[2]) == SCRATCH)
5329     operands[2] = gen_reg_rtx (DImode);
5330   if (TARGET_P8_VECTOR)
5331     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5332   else
5333     emit_insn (gen_lfiwax (operands[2], operands[1]));
5334   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5335   DONE;
5337   [(set_attr "length" "8")
5338    (set_attr "type" "fpload")])
5340 (define_insn "lfiwzx"
5341   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5342         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5343                    UNSPEC_LFIWZX))]
5344   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5345   "@
5346    lfiwzx %0,%y1
5347    lxsiwzx %x0,%y1
5348    mtvsrwz %x0,%1
5349    xxextractuw %x0,%x1,4"
5350   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5351    (set_attr "isa" "*,p8v,p8v,p9v")])
5353 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5354   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5355         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5356    (clobber (match_scratch:DI 2 "=d,wa"))]
5357   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5358   "#"
5359   ""
5360   [(pc)]
5362   rtx dest = operands[0];
5363   rtx src = operands[1];
5364   rtx tmp;
5366   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5367     tmp = convert_to_mode (DImode, src, true);
5368   else
5369     {
5370       tmp = operands[2];
5371       if (GET_CODE (tmp) == SCRATCH)
5372         tmp = gen_reg_rtx (DImode);
5373       if (MEM_P (src))
5374         {
5375           src = rs6000_force_indexed_or_indirect_mem (src);
5376           emit_insn (gen_lfiwzx (tmp, src));
5377         }
5378       else
5379         {
5380           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5381           emit_move_insn (stack, src);
5382           emit_insn (gen_lfiwzx (tmp, stack));
5383         }
5384     }
5385   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5386   DONE;
5388   [(set_attr "length" "12")
5389    (set_attr "type" "fpload")])
5391 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5392   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5393         (unsigned_float:SFDF
5394          (zero_extend:DI
5395           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5396    (clobber (match_scratch:DI 2 "=d,wa"))]
5397   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5398   "#"
5399   ""
5400   [(pc)]
5402   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5403   if (GET_CODE (operands[2]) == SCRATCH)
5404     operands[2] = gen_reg_rtx (DImode);
5405   if (TARGET_P8_VECTOR)
5406     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5407   else
5408     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5409   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5410   DONE;
5412   [(set_attr "length" "8")
5413    (set_attr "type" "fpload")])
5415 ; For each of these conversions, there is a define_expand, a define_insn
5416 ; with a '#' template, and a define_split (with C code).  The idea is
5417 ; to allow constant folding with the template of the define_insn,
5418 ; then to have the insns split later (between sched1 and final).
5420 (define_expand "floatsidf2"
5421   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5422                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5423               (use (match_dup 2))
5424               (use (match_dup 3))
5425               (clobber (match_dup 4))
5426               (clobber (match_dup 5))
5427               (clobber (match_dup 6))])]
5428   "TARGET_HARD_FLOAT"
5430   if (TARGET_LFIWAX && TARGET_FCFID)
5431     {
5432       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5433       DONE;
5434     }
5435   else if (TARGET_FCFID)
5436     {
5437       rtx dreg = operands[1];
5438       if (!REG_P (dreg))
5439         dreg = force_reg (SImode, dreg);
5440       dreg = convert_to_mode (DImode, dreg, false);
5441       emit_insn (gen_floatdidf2 (operands[0], dreg));
5442       DONE;
5443     }
5445   if (!REG_P (operands[1]))
5446     operands[1] = force_reg (SImode, operands[1]);
5447   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5448   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5449   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5450   operands[5] = gen_reg_rtx (DFmode);
5451   operands[6] = gen_reg_rtx (SImode);
5454 (define_insn_and_split "*floatsidf2_internal"
5455   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5456         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5457    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5458    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5459    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5460    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5461    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5462   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5463   "#"
5464   ""
5465   [(pc)]
5467   rtx lowword, highword;
5468   gcc_assert (MEM_P (operands[4]));
5469   highword = adjust_address (operands[4], SImode, 0);
5470   lowword = adjust_address (operands[4], SImode, 4);
5471   if (! WORDS_BIG_ENDIAN)
5472     std::swap (lowword, highword);
5474   emit_insn (gen_xorsi3 (operands[6], operands[1],
5475                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5476   emit_move_insn (lowword, operands[6]);
5477   emit_move_insn (highword, operands[2]);
5478   emit_move_insn (operands[5], operands[4]);
5479   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5480   DONE;
5482   [(set_attr "length" "24")
5483    (set_attr "type" "fp")])
5485 ;; If we don't have a direct conversion to single precision, don't enable this
5486 ;; conversion for 32-bit without fast math, because we don't have the insn to
5487 ;; generate the fixup swizzle to avoid double rounding problems.
5488 (define_expand "floatunssisf2"
5489   [(set (match_operand:SF 0 "gpc_reg_operand")
5490         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5491   "TARGET_HARD_FLOAT
5492    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5493        || (TARGET_FCFID
5494            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5496   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5497     {
5498       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5499       DONE;
5500     }
5501   else
5502     {
5503       rtx dreg = operands[1];
5504       if (!REG_P (dreg))
5505         dreg = force_reg (SImode, dreg);
5506       dreg = convert_to_mode (DImode, dreg, true);
5507       emit_insn (gen_floatdisf2 (operands[0], dreg));
5508       DONE;
5509     }
5512 (define_expand "floatunssidf2"
5513   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5514                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5515               (use (match_dup 2))
5516               (use (match_dup 3))
5517               (clobber (match_dup 4))
5518               (clobber (match_dup 5))])]
5519   "TARGET_HARD_FLOAT"
5521   if (TARGET_LFIWZX && TARGET_FCFID)
5522     {
5523       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5524       DONE;
5525     }
5526   else if (TARGET_FCFID)
5527     {
5528       rtx dreg = operands[1];
5529       if (!REG_P (dreg))
5530         dreg = force_reg (SImode, dreg);
5531       dreg = convert_to_mode (DImode, dreg, true);
5532       emit_insn (gen_floatdidf2 (operands[0], dreg));
5533       DONE;
5534     }
5536   if (!REG_P (operands[1]))
5537     operands[1] = force_reg (SImode, operands[1]);
5538   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5539   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5540   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5541   operands[5] = gen_reg_rtx (DFmode);
5544 (define_insn_and_split "*floatunssidf2_internal"
5545   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5546         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5547    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5548    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5549    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5550    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5551   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5552    && !(TARGET_FCFID && TARGET_POWERPC64)"
5553   "#"
5554   ""
5555   [(pc)]
5557   rtx lowword, highword;
5558   gcc_assert (MEM_P (operands[4]));
5559   highword = adjust_address (operands[4], SImode, 0);
5560   lowword = adjust_address (operands[4], SImode, 4);
5561   if (! WORDS_BIG_ENDIAN)
5562     std::swap (lowword, highword);
5564   emit_move_insn (lowword, operands[1]);
5565   emit_move_insn (highword, operands[2]);
5566   emit_move_insn (operands[5], operands[4]);
5567   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5568   DONE;
5570   [(set_attr "length" "20")
5571    (set_attr "type" "fp")])
5573 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5574 ;; vector registers.  These insns favor doing the sign/zero extension in
5575 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5576 ;; extension and then a direct move.
5578 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5579   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5580                    (float:FP_ISA3
5581                     (match_operand:QHI 1 "input_operand")))
5582               (clobber (match_scratch:DI 2))
5583               (clobber (match_scratch:DI 3))
5584               (clobber (match_scratch:<QHI:MODE> 4))])]
5585   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5587   if (MEM_P (operands[1]))
5588     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5591 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5592   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5593         (float:FP_ISA3
5594          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5595    (clobber (match_scratch:DI 2 "=v,wa,v"))
5596    (clobber (match_scratch:DI 3 "=X,r,X"))
5597    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5598   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5599   "#"
5600   "&& reload_completed"
5601   [(const_int 0)]
5603   rtx result = operands[0];
5604   rtx input = operands[1];
5605   rtx di = operands[2];
5607   if (!MEM_P (input))
5608     {
5609       rtx tmp = operands[3];
5610       if (altivec_register_operand (input, <QHI:MODE>mode))
5611         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5612       else if (GET_CODE (tmp) == SCRATCH)
5613         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5614       else
5615         {
5616           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5617           emit_move_insn (di, tmp);
5618         }
5619     }
5620   else
5621     {
5622       rtx tmp = operands[4];
5623       emit_move_insn (tmp, input);
5624       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5625     }
5627   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5628   DONE;
5630   [(set_attr "isa" "p9v,*,p9v")])
5632 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5633   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5634                    (unsigned_float:FP_ISA3
5635                     (match_operand:QHI 1 "input_operand")))
5636               (clobber (match_scratch:DI 2))
5637               (clobber (match_scratch:DI 3))])]
5638   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5640   if (MEM_P (operands[1]))
5641     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5644 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5645   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5646         (unsigned_float:FP_ISA3
5647          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5648    (clobber (match_scratch:DI 2 "=v,wa,wa"))
5649    (clobber (match_scratch:DI 3 "=X,r,X"))]
5650   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5651   "#"
5652   "&& reload_completed"
5653   [(const_int 0)]
5655   rtx result = operands[0];
5656   rtx input = operands[1];
5657   rtx di = operands[2];
5659   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5660     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5661   else
5662     {
5663       rtx tmp = operands[3];
5664       if (GET_CODE (tmp) == SCRATCH)
5665         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5666       else
5667         {
5668           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5669           emit_move_insn (di, tmp);
5670         }
5671     }
5673   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5674   DONE;
5676   [(set_attr "isa" "p9v,*,p9v")])
5678 (define_expand "fix_trunc<mode>si2"
5679   [(set (match_operand:SI 0 "gpc_reg_operand")
5680         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5681   "TARGET_HARD_FLOAT"
5683   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5684     {
5685       rtx src = force_reg (<MODE>mode, operands[1]);
5687       if (TARGET_STFIWX)
5688         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5689       else
5690         {
5691           rtx tmp = gen_reg_rtx (DImode);
5692           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5693           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5694                                                       tmp, stack));
5695         }
5696       DONE;
5697     }
5700 ; Like the convert to float patterns, this insn must be split before
5701 ; register allocation so that it can allocate the memory slot if it
5702 ; needed
5703 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5704   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5705         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5706    (clobber (match_scratch:DI 2 "=d"))]
5707   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5708    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5709   "#"
5710   ""
5711   [(pc)]
5713   rtx dest = operands[0];
5714   rtx src = operands[1];
5715   rtx tmp = operands[2];
5717   if (GET_CODE (tmp) == SCRATCH)
5718     tmp = gen_reg_rtx (DImode);
5720   emit_insn (gen_fctiwz_<mode> (tmp, src));
5721   if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5722     {
5723       dest = rs6000_force_indexed_or_indirect_mem (dest);
5724       emit_insn (gen_stfiwx (dest, tmp));
5725       DONE;
5726     }
5727   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5728     {
5729       dest = gen_lowpart (DImode, dest);
5730       emit_move_insn (dest, tmp);
5731       DONE;
5732     }
5733   else
5734     {
5735       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5736       emit_insn (gen_stfiwx (stack, tmp));
5737       emit_move_insn (dest, stack);
5738       DONE;
5739     }
5741   [(set_attr "length" "12")
5742    (set_attr "type" "fp")])
5744 (define_insn_and_split "fix_trunc<mode>si2_internal"
5745   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5746         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5747    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5748    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5749   "TARGET_HARD_FLOAT
5750    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5751   "#"
5752   ""
5753   [(pc)]
5755   rtx lowword;
5756   gcc_assert (MEM_P (operands[3]));
5757   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5759   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5760   emit_move_insn (operands[3], operands[2]);
5761   emit_move_insn (operands[0], lowword);
5762   DONE;
5764   [(set_attr "length" "16")
5765    (set_attr "type" "fp")])
5767 (define_expand "fix_trunc<mode>di2"
5768   [(set (match_operand:DI 0 "gpc_reg_operand")
5769         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5770   "TARGET_HARD_FLOAT && TARGET_FCFID"
5771   "")
5773 (define_insn "*fix_trunc<mode>di2_fctidz"
5774   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5775         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5776   "TARGET_HARD_FLOAT && TARGET_FCFID"
5777   "@
5778    fctidz %0,%1
5779    xscvdpsxds %x0,%x1"
5780   [(set_attr "type" "fp")])
5782 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5783 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5784 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5785 ;; values can go in VSX registers.  Keeping the direct move part through
5786 ;; register allocation prevents the register allocator from doing a direct move
5787 ;; of the SImode value to a GPR, and then a store/load.
5788 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5789   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5790         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5791    (clobber (match_scratch:SI 2 "=X,X,wa"))]
5792   "TARGET_DIRECT_MOVE"
5793   "@
5794    fctiw<u>z %0,%1
5795    xscvdp<su>xws %x0,%x1
5796    #"
5797   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5798   [(set (match_dup 2)
5799         (any_fix:SI (match_dup 1)))
5800    (set (match_dup 3)
5801         (match_dup 2))]
5803   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5805   [(set_attr "type" "fp")
5806    (set_attr "length" "4,4,8")
5807    (set_attr "isa" "p9v,p9v,*")])
5809 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5810   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5811         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5812   "TARGET_DIRECT_MOVE"
5813   "@
5814    fctiw<u>z %0,%1
5815    xscvdp<su>xws %x0,%x1"
5816   [(set_attr "type" "fp")])
5818 ;; Keep the convert and store together through register allocation to prevent
5819 ;; the register allocator from getting clever and doing a direct move to a GPR
5820 ;; and then store for reg+offset stores.
5821 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5822   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5823         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5824    (clobber (match_scratch:SI 2 "=wa"))]
5825     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5826   "#"
5827   "&& reload_completed"
5828   [(set (match_dup 2)
5829         (any_fix:SI (match_dup 1)))
5830    (set (match_dup 0)
5831         (match_dup 3))]
5833   operands[3] = (<QHSI:MODE>mode == SImode
5834                  ? operands[2]
5835                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5838 (define_expand "fixuns_trunc<mode>si2"
5839   [(set (match_operand:SI 0 "gpc_reg_operand")
5840         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5841   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5843   if (!TARGET_P8_VECTOR)
5844     {
5845       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5846       DONE;
5847     }
5850 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5851   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5852         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5853    (clobber (match_scratch:DI 2 "=d"))]
5854   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5855    && TARGET_STFIWX && can_create_pseudo_p ()
5856    && !TARGET_P8_VECTOR"
5857   "#"
5858   ""
5859   [(pc)]
5861   rtx dest = operands[0];
5862   rtx src = operands[1];
5863   rtx tmp = operands[2];
5865   if (GET_CODE (tmp) == SCRATCH)
5866     tmp = gen_reg_rtx (DImode);
5868   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5869   if (MEM_P (dest))
5870     {
5871       dest = rs6000_force_indexed_or_indirect_mem (dest);
5872       emit_insn (gen_stfiwx (dest, tmp));
5873       DONE;
5874     }
5875   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5876     {
5877       dest = gen_lowpart (DImode, dest);
5878       emit_move_insn (dest, tmp);
5879       DONE;
5880     }
5881   else
5882     {
5883       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5884       emit_insn (gen_stfiwx (stack, tmp));
5885       emit_move_insn (dest, stack);
5886       DONE;
5887     }
5889   [(set_attr "length" "12")
5890    (set_attr "type" "fp")])
5892 (define_insn "fixuns_trunc<mode>di2"
5893   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5894         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5895   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5896   "@
5897    fctiduz %0,%1
5898    xscvdpuxds %x0,%x1"
5899   [(set_attr "type" "fp")])
5901 (define_insn "rs6000_mtfsb0"
5902   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5903                     UNSPECV_MTFSB0)]
5904   "TARGET_HARD_FLOAT"
5905   "mtfsb0 %0"
5906   [(set_attr "type" "fp")])
5908 (define_insn "rs6000_mtfsb1"
5909   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5910                     UNSPECV_MTFSB1)]
5911   "TARGET_HARD_FLOAT"
5912   "mtfsb1 %0"
5913   [(set_attr "type" "fp")])
5915 (define_insn "rs6000_mffscrn"
5916   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5917         (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5918                             UNSPECV_MFFSCRN))]
5919    "TARGET_P9_MISC"
5920    "mffscrn %0,%1"
5921   [(set_attr "type" "fp")])
5923 (define_insn "rs6000_mffscdrn"
5924   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5925    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5926    (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5927   "TARGET_P9_MISC"
5928   "mffscdrn %0,%1"
5929   [(set_attr "type" "fp")])
5931 (define_expand "rs6000_set_fpscr_rn"
5932  [(match_operand:DI 0 "reg_or_cint_operand")]
5933   "TARGET_HARD_FLOAT"
5935   rtx tmp_df = gen_reg_rtx (DFmode);
5937   /* The floating point rounding control bits are FPSCR[62:63]. Put the
5938      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5939   if (TARGET_P9_MISC)
5940     {
5941       rtx src_df = force_reg (DImode, operands[0]);
5942       src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5943       emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5944       DONE;
5945     }
5947   if (CONST_INT_P (operands[0]))
5948     {
5949       if ((INTVAL (operands[0]) & 0x1) == 0x1)
5950         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5951       else
5952         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5954       if ((INTVAL (operands[0]) & 0x2) == 0x2)
5955         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5956       else
5957         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5958     }
5959   else
5960     {
5961       rtx tmp_rn = gen_reg_rtx (DImode);
5962       rtx tmp_di = gen_reg_rtx (DImode);
5964       /* Extract new RN mode from operand.  */
5965       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5967       /* Insert new RN mode into FSCPR.  */
5968       emit_insn (gen_rs6000_mffs (tmp_df));
5969       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5970       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5971       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5973       /* Need to write to field k=15.  The fields are [0:15].  Hence with
5974          L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5975          8-bit field[0:7]. Need to set the bit that corresponds to the
5976          value of i that you want [0:7].  */
5977       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5978       emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5979     }
5980   DONE;
5983 (define_expand "rs6000_set_fpscr_drn"
5984   [(match_operand:DI 0  "gpc_reg_operand")]
5985   "TARGET_HARD_FLOAT"
5987   rtx tmp_df = gen_reg_rtx (DFmode);
5989   /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5990      new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5991   if (TARGET_P9_MISC)
5992     {
5993       rtx src_df = gen_reg_rtx (DFmode);
5995       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5996       src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5997       emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5998     }
5999   else
6000     {
6001       rtx tmp_rn = gen_reg_rtx (DImode);
6002       rtx tmp_di = gen_reg_rtx (DImode);
6004       /* Extract new DRN mode from operand.  */
6005       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6006       emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6008       /* Insert new RN mode into FSCPR.  */
6009       emit_insn (gen_rs6000_mffs (tmp_df));
6010       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6011       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6012       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6014       /* Need to write to field 7.  The fields are [0:15].  The equation to
6015          select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6016          i to 0x1 to get field 7 where i selects the field.  */
6017       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6018       emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6019     }
6020   DONE;
6023 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6024 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6025 ;; because the first makes it clear that operand 0 is not live
6026 ;; before the instruction.
6027 (define_insn "fctiwz_<mode>"
6028   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6029         (unspec:DI [(fix:SI
6030                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6031                    UNSPEC_FCTIWZ))]
6032   "TARGET_HARD_FLOAT"
6033   "@
6034    fctiwz %0,%1
6035    xscvdpsxws %x0,%x1"
6036   [(set_attr "type" "fp")])
6038 (define_insn "fctiwuz_<mode>"
6039   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6040         (unspec:DI [(unsigned_fix:SI
6041                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6042                    UNSPEC_FCTIWUZ))]
6043   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6044   "@
6045    fctiwuz %0,%1
6046    xscvdpuxws %x0,%x1"
6047   [(set_attr "type" "fp")])
6049 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6050 ;; since the friz instruction does not truncate the value if the floating
6051 ;; point value is < LONG_MIN or > LONG_MAX.
6052 (define_insn "*friz"
6053   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6054         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6055   "TARGET_HARD_FLOAT && TARGET_FPRND
6056    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6057   "@
6058    friz %0,%1
6059    xsrdpiz %x0,%x1"
6060   [(set_attr "type" "fp")])
6062 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
6063 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6064 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6065 ;; extend it, store it back on the stack from the GPR, load it back into the
6066 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6067 ;; disable using store and load to sign/zero extend the value.
6068 (define_insn_and_split "*round32<mode>2_fprs"
6069   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6070         (float:SFDF
6071          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6072    (clobber (match_scratch:DI 2 "=d"))
6073    (clobber (match_scratch:DI 3 "=d"))]
6074   "TARGET_HARD_FLOAT
6075    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6076    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6077   "#"
6078   ""
6079   [(pc)]
6081   rtx dest = operands[0];
6082   rtx src = operands[1];
6083   rtx tmp1 = operands[2];
6084   rtx tmp2 = operands[3];
6085   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6087   if (GET_CODE (tmp1) == SCRATCH)
6088     tmp1 = gen_reg_rtx (DImode);
6089   if (GET_CODE (tmp2) == SCRATCH)
6090     tmp2 = gen_reg_rtx (DImode);
6092   emit_insn (gen_fctiwz_<mode> (tmp1, src));
6093   emit_insn (gen_stfiwx (stack, tmp1));
6094   emit_insn (gen_lfiwax (tmp2, stack));
6095   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6096   DONE;
6098   [(set_attr "type" "fpload")
6099    (set_attr "length" "16")])
6101 (define_insn_and_split "*roundu32<mode>2_fprs"
6102   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6103         (unsigned_float:SFDF
6104          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6105    (clobber (match_scratch:DI 2 "=d"))
6106    (clobber (match_scratch:DI 3 "=d"))]
6107   "TARGET_HARD_FLOAT
6108    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6109    && can_create_pseudo_p ()"
6110   "#"
6111   ""
6112   [(pc)]
6114   rtx dest = operands[0];
6115   rtx src = operands[1];
6116   rtx tmp1 = operands[2];
6117   rtx tmp2 = operands[3];
6118   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6120   if (GET_CODE (tmp1) == SCRATCH)
6121     tmp1 = gen_reg_rtx (DImode);
6122   if (GET_CODE (tmp2) == SCRATCH)
6123     tmp2 = gen_reg_rtx (DImode);
6125   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6126   emit_insn (gen_stfiwx (stack, tmp1));
6127   emit_insn (gen_lfiwzx (tmp2, stack));
6128   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6129   DONE;
6131   [(set_attr "type" "fpload")
6132    (set_attr "length" "16")])
6134 ;; No VSX equivalent to fctid
6135 (define_insn "lrint<mode>di2"
6136   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6137         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6138                    UNSPEC_FCTID))]
6139   "TARGET_HARD_FLOAT && TARGET_FPRND"
6140   "fctid %0,%1"
6141   [(set_attr "type" "fp")])
6143 (define_insn "btrunc<mode>2"
6144   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6145         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6146                      UNSPEC_FRIZ))]
6147   "TARGET_HARD_FLOAT && TARGET_FPRND"
6148   "@
6149    friz %0,%1
6150    xsrdpiz %x0,%x1"
6151   [(set_attr "type" "fp")])
6153 (define_insn "ceil<mode>2"
6154   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6155         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6156                      UNSPEC_FRIP))]
6157   "TARGET_HARD_FLOAT && TARGET_FPRND"
6158   "@
6159    frip %0,%1
6160    xsrdpip %x0,%x1"
6161   [(set_attr "type" "fp")])
6163 (define_insn "floor<mode>2"
6164   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6165         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6166                      UNSPEC_FRIM))]
6167   "TARGET_HARD_FLOAT && TARGET_FPRND"
6168   "@
6169    frim %0,%1
6170    xsrdpim %x0,%x1"
6171   [(set_attr "type" "fp")])
6173 ;; No VSX equivalent to frin
6174 (define_insn "round<mode>2"
6175   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6176         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6177                      UNSPEC_FRIN))]
6178   "TARGET_HARD_FLOAT && TARGET_FPRND"
6179   "frin %0,%1"
6180   [(set_attr "type" "fp")])
6182 (define_insn "*xsrdpi<mode>2"
6183   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6184         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6185                      UNSPEC_XSRDPI))]
6186   "TARGET_HARD_FLOAT && TARGET_VSX"
6187   "xsrdpi %x0,%x1"
6188   [(set_attr "type" "fp")])
6190 (define_expand "lround<mode>di2"
6191   [(set (match_dup 2)
6192         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6193                      UNSPEC_XSRDPI))
6194    (set (match_operand:DI 0 "gpc_reg_operand")
6195         (unspec:DI [(match_dup 2)]
6196                    UNSPEC_FCTID))]
6197   "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6199   operands[2] = gen_reg_rtx (<MODE>mode);
6202 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6203 (define_insn "stfiwx"
6204   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6205         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6206                    UNSPEC_STFIWX))]
6207   "TARGET_PPC_GFXOPT"
6208   "@
6209    stfiwx %1,%y0
6210    stxsiwx %x1,%y0"
6211   [(set_attr "type" "fpstore")
6212    (set_attr "isa" "*,p8v")])
6214 ;; If we don't have a direct conversion to single precision, don't enable this
6215 ;; conversion for 32-bit without fast math, because we don't have the insn to
6216 ;; generate the fixup swizzle to avoid double rounding problems.
6217 (define_expand "floatsisf2"
6218   [(set (match_operand:SF 0 "gpc_reg_operand")
6219         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6220   "TARGET_HARD_FLOAT
6221    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6222        || (TARGET_FCFID
6223            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6225   if (TARGET_FCFIDS && TARGET_LFIWAX)
6226     {
6227       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6228       DONE;
6229     }
6230   else if (TARGET_FCFID && TARGET_LFIWAX)
6231     {
6232       rtx dfreg = gen_reg_rtx (DFmode);
6233       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6234       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6235       DONE;
6236     }
6237   else
6238     {
6239       rtx dreg = operands[1];
6240       if (!REG_P (dreg))
6241         dreg = force_reg (SImode, dreg);
6242       dreg = convert_to_mode (DImode, dreg, false);
6243       emit_insn (gen_floatdisf2 (operands[0], dreg));
6244       DONE;
6245     }
6248 (define_insn "floatdidf2"
6249   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6250         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6251   "TARGET_FCFID && TARGET_HARD_FLOAT"
6252   "@
6253    fcfid %0,%1
6254    xscvsxddp %x0,%x1"
6255   [(set_attr "type" "fp")])
6257 ; Allow the combiner to merge source memory operands to the conversion so that
6258 ; the optimizer/register allocator doesn't try to load the value too early in a
6259 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6260 ; hit.  We will split after reload to avoid the trip through the GPRs
6262 (define_insn_and_split "*floatdidf2_mem"
6263   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6264         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6265    (clobber (match_scratch:DI 2 "=d,wa"))]
6266   "TARGET_HARD_FLOAT && TARGET_FCFID"
6267   "#"
6268   "&& reload_completed"
6269   [(set (match_dup 2) (match_dup 1))
6270    (set (match_dup 0) (float:DF (match_dup 2)))]
6271   ""
6272   [(set_attr "length" "8")
6273    (set_attr "type" "fpload")])
6275 (define_expand "floatunsdidf2"
6276   [(set (match_operand:DF 0 "gpc_reg_operand")
6277         (unsigned_float:DF
6278          (match_operand:DI 1 "gpc_reg_operand")))]
6279   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6280   "")
6282 (define_insn "*floatunsdidf2_fcfidu"
6283   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6284         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6285   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6286   "@
6287    fcfidu %0,%1
6288    xscvuxddp %x0,%x1"
6289   [(set_attr "type" "fp")])
6291 (define_insn_and_split "*floatunsdidf2_mem"
6292   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6293         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6294    (clobber (match_scratch:DI 2 "=d,wa"))]
6295   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6296   "#"
6297   "&& reload_completed"
6298   [(set (match_dup 2) (match_dup 1))
6299    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6300   ""
6301   [(set_attr "length" "8")
6302    (set_attr "type" "fpload")])
6304 (define_expand "floatdisf2"
6305   [(set (match_operand:SF 0 "gpc_reg_operand")
6306         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6307   "TARGET_FCFID && TARGET_HARD_FLOAT
6308    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6310   if (!TARGET_FCFIDS)
6311     {
6312       rtx val = operands[1];
6313       if (!flag_unsafe_math_optimizations)
6314         {
6315           rtx label = gen_label_rtx ();
6316           val = gen_reg_rtx (DImode);
6317           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6318           emit_label (label);
6319         }
6320       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6321       DONE;
6322     }
6325 (define_insn "floatdisf2_fcfids"
6326   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6327         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6328   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6329   "@
6330    fcfids %0,%1
6331    xscvsxdsp %x0,%x1"
6332   [(set_attr "type" "fp")
6333    (set_attr "isa" "*,p8v")])
6335 (define_insn_and_split "*floatdisf2_mem"
6336   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6337         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6338    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6339   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6340   "#"
6341   "&& reload_completed"
6342   [(pc)]
6344   emit_move_insn (operands[2], operands[1]);
6345   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6346   DONE;
6348   [(set_attr "length" "8")
6349    (set_attr "isa" "*,p8v,p8v")])
6351 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6352 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6353 ;; from double rounding.
6354 ;; Instead of creating a new cpu type for two FP operations, just use fp
6355 (define_insn_and_split "floatdisf2_internal1"
6356   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6357         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6358    (clobber (match_scratch:DF 2 "=d"))]
6359   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6360   "#"
6361   "&& reload_completed"
6362   [(set (match_dup 2)
6363         (float:DF (match_dup 1)))
6364    (set (match_dup 0)
6365         (float_truncate:SF (match_dup 2)))]
6366   ""
6367   [(set_attr "length" "8")
6368    (set_attr "type" "fp")])
6370 ;; Twiddles bits to avoid double rounding.
6371 ;; Bits that might be truncated when converting to DFmode are replaced
6372 ;; by a bit that won't be lost at that stage, but is below the SFmode
6373 ;; rounding position.
6374 (define_expand "floatdisf2_internal2"
6375   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6376                                               (const_int 53)))
6377               (clobber (reg:DI CA_REGNO))])
6378    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6379                                         (const_int 2047)))
6380    (set (match_dup 3) (plus:DI (match_dup 3)
6381                                (const_int 1)))
6382    (set (match_dup 0) (plus:DI (match_dup 0)
6383                                (const_int 2047)))
6384    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6385                                      (const_int 2)))
6386    (set (match_dup 0) (ior:DI (match_dup 0)
6387                               (match_dup 1)))
6388    (set (match_dup 0) (and:DI (match_dup 0)
6389                               (const_int -2048)))
6390    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6391                            (label_ref (match_operand:DI 2 ""))
6392                            (pc)))
6393    (set (match_dup 0) (match_dup 1))]
6394   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6396   operands[3] = gen_reg_rtx (DImode);
6397   operands[4] = gen_reg_rtx (CCUNSmode);
6400 (define_expand "floatunsdisf2"
6401   [(set (match_operand:SF 0 "gpc_reg_operand")
6402         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6403   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6404   "")
6406 (define_insn "floatunsdisf2_fcfidus"
6407   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6408         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6409   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6410   "@
6411    fcfidus %0,%1
6412    xscvuxdsp %x0,%x1"
6413   [(set_attr "type" "fp")
6414    (set_attr "isa" "*,p8v")])
6416 (define_insn_and_split "*floatunsdisf2_mem"
6417   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6418         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6419    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6420   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6421   "#"
6422   "&& reload_completed"
6423   [(pc)]
6425   emit_move_insn (operands[2], operands[1]);
6426   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6427   DONE;
6429   [(set_attr "type" "fpload")
6430    (set_attr "length" "8")
6431    (set_attr "isa" "*,p8v,p8v")])
6433 ;; Define the TImode operations that can be done in a small number
6434 ;; of instructions.  The & constraints are to prevent the register
6435 ;; allocator from allocating registers that overlap with the inputs
6436 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6437 ;; also allow for the output being the same as one of the inputs.
6439 (define_expand "addti3"
6440   [(set (match_operand:TI 0 "gpc_reg_operand")
6441         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6442                  (match_operand:TI 2 "reg_or_short_operand")))]
6443   "TARGET_64BIT"
6445   rtx lo0 = gen_lowpart (DImode, operands[0]);
6446   rtx lo1 = gen_lowpart (DImode, operands[1]);
6447   rtx lo2 = gen_lowpart (DImode, operands[2]);
6448   rtx hi0 = gen_highpart (DImode, operands[0]);
6449   rtx hi1 = gen_highpart (DImode, operands[1]);
6450   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6452   if (!reg_or_short_operand (lo2, DImode))
6453     lo2 = force_reg (DImode, lo2);
6454   if (!adde_operand (hi2, DImode))
6455     hi2 = force_reg (DImode, hi2);
6457   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6458   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6459   DONE;
6462 (define_expand "subti3"
6463   [(set (match_operand:TI 0 "gpc_reg_operand")
6464         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6465                   (match_operand:TI 2 "gpc_reg_operand")))]
6466   "TARGET_64BIT"
6468   rtx lo0 = gen_lowpart (DImode, operands[0]);
6469   rtx lo1 = gen_lowpart (DImode, operands[1]);
6470   rtx lo2 = gen_lowpart (DImode, operands[2]);
6471   rtx hi0 = gen_highpart (DImode, operands[0]);
6472   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6473   rtx hi2 = gen_highpart (DImode, operands[2]);
6475   if (!reg_or_short_operand (lo1, DImode))
6476     lo1 = force_reg (DImode, lo1);
6477   if (!adde_operand (hi1, DImode))
6478     hi1 = force_reg (DImode, hi1);
6480   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6481   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6482   DONE;
6485 ;; 128-bit logical operations expanders
6487 (define_expand "and<mode>3"
6488   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6489         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6490                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6491   ""
6492   "")
6494 (define_expand "ior<mode>3"
6495   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6496         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6497                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6498   ""
6499   "")
6501 (define_expand "xor<mode>3"
6502   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6503         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6504                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6505   ""
6506   "")
6508 (define_expand "nor<mode>3"
6509   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6510         (and:BOOL_128
6511          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6512          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6513   ""
6514   "")
6516 (define_expand "andc<mode>3"
6517   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6518         (and:BOOL_128
6519          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6520          (match_operand:BOOL_128 1 "vlogical_operand")))]
6521   ""
6522   "")
6524 ;; Power8 vector logical instructions.
6525 (define_expand "eqv<mode>3"
6526   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6527         (not:BOOL_128
6528          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6529                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6530   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6531   "")
6533 ;; Rewrite nand into canonical form
6534 (define_expand "nand<mode>3"
6535   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6536         (ior:BOOL_128
6537          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6538          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6539   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6540   "")
6542 ;; The canonical form is to have the negated element first, so we need to
6543 ;; reverse arguments.
6544 (define_expand "orc<mode>3"
6545   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6546         (ior:BOOL_128
6547          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6548          (match_operand:BOOL_128 1 "vlogical_operand")))]
6549   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6550   "")
6552 ;; 128-bit logical operations insns and split operations
6553 (define_insn_and_split "*and<mode>3_internal"
6554   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6555         (and:BOOL_128
6556          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6557          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6558   ""
6560   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6561     return "xxland %x0,%x1,%x2";
6563   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6564     return "vand %0,%1,%2";
6566   return "#";
6568   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6569   [(const_int 0)]
6571   rs6000_split_logical (operands, AND, false, false, false);
6572   DONE;
6574   [(set (attr "type")
6575       (if_then_else
6576         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6577         (const_string "veclogical")
6578         (const_string "integer")))
6579    (set (attr "length")
6580       (if_then_else
6581         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6582         (const_string "4")
6583         (if_then_else
6584          (match_test "TARGET_POWERPC64")
6585          (const_string "8")
6586          (const_string "16"))))])
6588 ;; 128-bit IOR/XOR
6589 (define_insn_and_split "*bool<mode>3_internal"
6590   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6591         (match_operator:BOOL_128 3 "boolean_or_operator"
6592          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6593           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6594   ""
6596   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6597     return "xxl%q3 %x0,%x1,%x2";
6599   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6600     return "v%q3 %0,%1,%2";
6602   return "#";
6604   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6605   [(const_int 0)]
6607   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6608   DONE;
6610   [(set (attr "type")
6611       (if_then_else
6612         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6613         (const_string "veclogical")
6614         (const_string "integer")))
6615    (set (attr "length")
6616       (if_then_else
6617         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6618         (const_string "4")
6619         (if_then_else
6620          (match_test "TARGET_POWERPC64")
6621          (const_string "8")
6622          (const_string "16"))))])
6624 ;; 128-bit ANDC/ORC
6625 (define_insn_and_split "*boolc<mode>3_internal1"
6626   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6627         (match_operator:BOOL_128 3 "boolean_operator"
6628          [(not:BOOL_128
6629            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6630           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6631   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6633   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6634     return "xxl%q3 %x0,%x1,%x2";
6636   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6637     return "v%q3 %0,%1,%2";
6639   return "#";
6641   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6642    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6643   [(const_int 0)]
6645   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6646   DONE;
6648   [(set (attr "type")
6649       (if_then_else
6650         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6651         (const_string "veclogical")
6652         (const_string "integer")))
6653    (set (attr "length")
6654       (if_then_else
6655         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6656         (const_string "4")
6657         (if_then_else
6658          (match_test "TARGET_POWERPC64")
6659          (const_string "8")
6660          (const_string "16"))))])
6662 (define_insn_and_split "*boolc<mode>3_internal2"
6663   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6664         (match_operator:TI2 3 "boolean_operator"
6665          [(not:TI2
6666            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6667           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6668   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6669   "#"
6670   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6671   [(const_int 0)]
6673   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6674   DONE;
6676   [(set_attr "type" "integer")
6677    (set (attr "length")
6678         (if_then_else
6679          (match_test "TARGET_POWERPC64")
6680          (const_string "8")
6681          (const_string "16")))])
6683 ;; 128-bit NAND/NOR
6684 (define_insn_and_split "*boolcc<mode>3_internal1"
6685   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6686         (match_operator:BOOL_128 3 "boolean_operator"
6687          [(not:BOOL_128
6688            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6689           (not:BOOL_128
6690            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6691   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6693   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6694     return "xxl%q3 %x0,%x1,%x2";
6696   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6697     return "v%q3 %0,%1,%2";
6699   return "#";
6701   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6702    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6703   [(const_int 0)]
6705   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6706   DONE;
6708   [(set (attr "type")
6709       (if_then_else
6710         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6711         (const_string "veclogical")
6712         (const_string "integer")))
6713    (set (attr "length")
6714       (if_then_else
6715         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6716         (const_string "4")
6717         (if_then_else
6718          (match_test "TARGET_POWERPC64")
6719          (const_string "8")
6720          (const_string "16"))))])
6722 (define_insn_and_split "*boolcc<mode>3_internal2"
6723   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6724         (match_operator:TI2 3 "boolean_operator"
6725          [(not:TI2
6726            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6727           (not:TI2
6728            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6729   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6730   "#"
6731   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6732   [(const_int 0)]
6734   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6735   DONE;
6737   [(set_attr "type" "integer")
6738    (set (attr "length")
6739         (if_then_else
6740          (match_test "TARGET_POWERPC64")
6741          (const_string "8")
6742          (const_string "16")))])
6745 ;; 128-bit EQV
6746 (define_insn_and_split "*eqv<mode>3_internal1"
6747   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6748         (not:BOOL_128
6749          (xor:BOOL_128
6750           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6751           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6752   "TARGET_P8_VECTOR"
6754   if (vsx_register_operand (operands[0], <MODE>mode))
6755     return "xxleqv %x0,%x1,%x2";
6757   return "#";
6759   "TARGET_P8_VECTOR && reload_completed
6760    && int_reg_operand (operands[0], <MODE>mode)"
6761   [(const_int 0)]
6763   rs6000_split_logical (operands, XOR, true, false, false);
6764   DONE;
6766   [(set (attr "type")
6767       (if_then_else
6768         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6769         (const_string "veclogical")
6770         (const_string "integer")))
6771    (set (attr "length")
6772       (if_then_else
6773         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6774         (const_string "4")
6775         (if_then_else
6776          (match_test "TARGET_POWERPC64")
6777          (const_string "8")
6778          (const_string "16"))))])
6780 (define_insn_and_split "*eqv<mode>3_internal2"
6781   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6782         (not:TI2
6783          (xor:TI2
6784           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6785           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6786   "!TARGET_P8_VECTOR"
6787   "#"
6788   "reload_completed && !TARGET_P8_VECTOR"
6789   [(const_int 0)]
6791   rs6000_split_logical (operands, XOR, true, false, false);
6792   DONE;
6794   [(set_attr "type" "integer")
6795    (set (attr "length")
6796         (if_then_else
6797          (match_test "TARGET_POWERPC64")
6798          (const_string "8")
6799          (const_string "16")))])
6801 ;; 128-bit one's complement
6802 (define_insn_and_split "one_cmpl<mode>2"
6803   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6804         (not:BOOL_128
6805           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6806   ""
6808   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6809     return "xxlnor %x0,%x1,%x1";
6811   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6812     return "vnor %0,%1,%1";
6814   return "#";
6816   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6817   [(const_int 0)]
6819   rs6000_split_logical (operands, NOT, false, false, false);
6820   DONE;
6822   [(set (attr "type")
6823       (if_then_else
6824         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6825         (const_string "veclogical")
6826         (const_string "integer")))
6827    (set (attr "length")
6828       (if_then_else
6829         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6830         (const_string "4")
6831         (if_then_else
6832          (match_test "TARGET_POWERPC64")
6833          (const_string "8")
6834          (const_string "16"))))])
6837 ;; Now define ways of moving data around.
6839 ;; Set up a register with a value from the GOT table
6841 (define_expand "movsi_got"
6842   [(set (match_operand:SI 0 "gpc_reg_operand")
6843         (unspec:SI [(match_operand:SI 1 "got_operand")
6844                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6845   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6847   if (GET_CODE (operands[1]) == CONST)
6848     {
6849       rtx offset = const0_rtx;
6850       HOST_WIDE_INT value;
6852       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6853       value = INTVAL (offset);
6854       if (value != 0)
6855         {
6856           rtx tmp = (!can_create_pseudo_p ()
6857                      ? operands[0]
6858                      : gen_reg_rtx (Pmode));
6859           emit_insn (gen_movsi_got (tmp, operands[1]));
6860           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6861           DONE;
6862         }
6863     }
6865   operands[2] = rs6000_got_register (operands[1]);
6868 (define_insn "*movsi_got_internal"
6869   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6870         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6871                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6872                    UNSPEC_MOVSI_GOT))]
6873   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6874   "lwz %0,%a1@got(%2)"
6875   [(set_attr "type" "load")])
6877 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6878 ;; didn't get allocated to a hard register.
6879 (define_split
6880   [(set (match_operand:SI 0 "gpc_reg_operand")
6881         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6882                     (match_operand:SI 2 "memory_operand")]
6883                    UNSPEC_MOVSI_GOT))]
6884   "DEFAULT_ABI == ABI_V4
6885     && flag_pic == 1
6886     && reload_completed"
6887   [(set (match_dup 0) (match_dup 2))
6888    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6889                                  UNSPEC_MOVSI_GOT))]
6890   "")
6892 ;;         MR          LA
6893 ;;         LWZ         LFIWZX      LXSIWZX
6894 ;;         STW         STFIWX      STXSIWX
6895 ;;         LI          LIS         PLI         #
6896 ;;         XXLOR       XXSPLTIB 0  XXSPLTIB -1 VSPLTISW
6897 ;;         XXLXOR 0    XXLORC -1   P9 const
6898 ;;         MTVSRWZ     MFVSRWZ
6899 ;;         MF%1        MT%0        NOP
6901 (define_insn "*movsi_internal1"
6902   [(set (match_operand:SI 0 "nonimmediate_operand"
6903           "=r,         r,
6904            r,          d,          v,
6905            m,          Z,          Z,
6906            r,          r,          r,          r,
6907            wa,         wa,         wa,         v,
6908            wa,         v,          v,
6909            wa,         r,
6910            r,          *h,         *h")
6911         (match_operand:SI 1 "input_operand"
6912           "r,          U,
6913            m,          Z,          Z,
6914            r,          d,          v,
6915            I,          L,          eI,         n,
6916            wa,         O,          wM,         wB,
6917            O,          wM,         wS,
6918            r,          wa,
6919            *h,         r,          0"))]
6920   "gpc_reg_operand (operands[0], SImode)
6921    || gpc_reg_operand (operands[1], SImode)"
6922   "@
6923    mr %0,%1
6924    la %0,%a1
6925    lwz%U1%X1 %0,%1
6926    lfiwzx %0,%y1
6927    lxsiwzx %x0,%y1
6928    stw%U0%X0 %1,%0
6929    stfiwx %1,%y0
6930    stxsiwx %x1,%y0
6931    li %0,%1
6932    lis %0,%v1
6933    li %0,%1
6934    #
6935    xxlor %x0,%x1,%x1
6936    xxspltib %x0,0
6937    xxspltib %x0,255
6938    vspltisw %0,%1
6939    xxlxor %x0,%x0,%x0
6940    xxlorc %x0,%x0,%x0
6941    #
6942    mtvsrwz %x0,%1
6943    mfvsrwz %0,%x1
6944    mf%1 %0
6945    mt%0 %1
6946    nop"
6947   [(set_attr "type"
6948           "*,          *,
6949            load,       fpload,     fpload,
6950            store,      fpstore,    fpstore,
6951            *,          *,          *,          *,
6952            veclogical, vecsimple,  vecsimple,  vecsimple,
6953            veclogical, veclogical, vecsimple,
6954            mffgpr,     mftgpr,
6955            *,          *,          *")
6956    (set_attr "length"
6957           "*,          *,
6958            *,          *,          *,
6959            *,          *,          *,
6960            *,          *,          *,          8,
6961            *,          *,          *,          *,
6962            *,          *,          8,
6963            *,          *,
6964            *,          *,          *")
6965    (set_attr "isa"
6966           "*,          *,
6967            *,          p8v,        p8v,
6968            *,          p8v,        p8v,
6969            *,          *,          fut,        *,
6970            p8v,        p9v,        p9v,        p8v,
6971            p9v,        p8v,        p9v,
6972            p8v,        p8v,
6973            *,          *,          *")])
6975 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6976 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6978 ;; Because SF values are actually stored as DF values within the vector
6979 ;; registers, we need to convert the value to the vector SF format when
6980 ;; we need to use the bits in a union or similar cases.  We only need
6981 ;; to do this transformation when the value is a vector register.  Loads,
6982 ;; stores, and transfers within GPRs are assumed to be safe.
6984 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6985 ;; no alternatives, because the call is created as part of secondary_reload,
6986 ;; and operand #2's register class is used to allocate the temporary register.
6987 ;; This function is called before reload, and it creates the temporary as
6988 ;; needed.
6990 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6991 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6992 ;;              MTVSRWZ
6994 (define_insn_and_split "movsi_from_sf"
6995   [(set (match_operand:SI 0 "nonimmediate_operand"
6996                 "=r,         r,           ?*d,         ?*v,      m,
6997                  m,          wY,          Z,           r,        ?*wa,
6998                  wa")
6999         (unspec:SI [(match_operand:SF 1 "input_operand"
7000                 "r,          m,           Z,           Z,        r,
7001                  f,          v,           wa,          wa,       wa,
7002                  r")]
7003                     UNSPEC_SI_FROM_SF))
7004    (clobber (match_scratch:V4SF 2
7005                 "=X,         X,           X,           X,        X,
7006                  X,          X,           X,           wa,       X,
7007                  X"))]
7008   "TARGET_NO_SF_SUBREG
7009    && (register_operand (operands[0], SImode)
7010        || register_operand (operands[1], SFmode))"
7011   "@
7012    mr %0,%1
7013    lwz%U1%X1 %0,%1
7014    lfiwzx %0,%y1
7015    lxsiwzx %x0,%y1
7016    stw%U0%X0 %1,%0
7017    stfs%U0%X0 %1,%0
7018    stxssp %1,%0
7019    stxsspx %x1,%y0
7020    #
7021    xscvdpspn %x0,%x1
7022    mtvsrwz %x0,%1"
7023   "&& reload_completed
7024    && int_reg_operand (operands[0], SImode)
7025    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7026   [(const_int 0)]
7028   rtx op0 = operands[0];
7029   rtx op1 = operands[1];
7030   rtx op2 = operands[2];
7031   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7032   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7034   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7035   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7036   DONE;
7038   [(set_attr "type"
7039                 "*,          load,        fpload,      fpload,   store,
7040                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
7041                  mffgpr")
7042    (set_attr "length"
7043                 "*,          *,           *,           *,        *,
7044                  *,          *,           *,           8,        *,
7045                  *")
7046    (set_attr "isa"
7047                 "*,          *,           p8v,         p8v,      *,
7048                  *,          p9v,         p8v,         p8v,      p8v,
7049                  p8v")])
7051 ;; movsi_from_sf with zero extension
7053 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
7054 ;;              VSX->VSX     MTVSRWZ
7056 (define_insn_and_split "*movdi_from_sf_zero_ext"
7057   [(set (match_operand:DI 0 "gpc_reg_operand"
7058                 "=r,         r,           ?*d,         ?*v,      r,
7059                  ?v,         wa")
7060         (zero_extend:DI
7061          (unspec:SI [(match_operand:SF 1 "input_operand"
7062                 "r,          m,           Z,           Z,        wa,
7063                  wa,         r")]
7064                     UNSPEC_SI_FROM_SF)))
7065    (clobber (match_scratch:V4SF 2
7066                 "=X,         X,           X,           X,        wa,
7067                  wa,         X"))]
7068   "TARGET_DIRECT_MOVE_64BIT
7069    && (register_operand (operands[0], DImode)
7070        || register_operand (operands[1], SImode))"
7071   "@
7072    rldicl %0,%1,0,32
7073    lwz%U1%X1 %0,%1
7074    lfiwzx %0,%y1
7075    lxsiwzx %x0,%y1
7076    #
7077    #
7078    mtvsrwz %x0,%1"
7079   "&& reload_completed
7080    && register_operand (operands[0], DImode)
7081    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7082   [(const_int 0)]
7084   rtx op0 = operands[0];
7085   rtx op1 = operands[1];
7086   rtx op2 = operands[2];
7087   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7089   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7090   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7091   DONE;
7093   [(set_attr "type"
7094                 "*,          load,        fpload,      fpload,   two,
7095                  two,        mffgpr")
7096    (set_attr "length"
7097                 "*,          *,           *,           *,        8,
7098                  8,          *")
7099    (set_attr "isa"
7100                 "*,          *,           p8v,         p8v,      p8v,
7101                  p9v,        p8v")])
7103 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7104 ;; moving it to SImode.  We cannot do a SFmode store without having to do the
7105 ;; conversion explicitly since that doesn't work in most cases if the input
7106 ;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7107 ;; former handles cases where the input will not fit in a SFmode, and the
7108 ;; latter assumes the value has already been rounded.
7109 (define_insn "*movsi_from_df"
7110   [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7111         (unspec:SI [(float_truncate:SF
7112                      (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7113                     UNSPEC_SI_FROM_SF))]
7114   "TARGET_NO_SF_SUBREG"
7115   "xscvdpsp %x0,%x1"
7116   [(set_attr "type" "fp")])
7118 ;; Split a load of a large constant into the appropriate two-insn
7119 ;; sequence.
7121 (define_split
7122   [(set (match_operand:SI 0 "gpc_reg_operand")
7123         (match_operand:SI 1 "const_int_operand"))]
7124   "num_insns_constant (operands[1], SImode) > 1"
7125   [(set (match_dup 0)
7126         (match_dup 2))
7127    (set (match_dup 0)
7128         (ior:SI (match_dup 0)
7129                 (match_dup 3)))]
7131   if (rs6000_emit_set_const (operands[0], operands[1]))
7132     DONE;
7133   else
7134     FAIL;
7137 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7138 (define_split
7139   [(set (match_operand:DI 0 "altivec_register_operand")
7140         (match_operand:DI 1 "xxspltib_constant_split"))]
7141   "TARGET_P9_VECTOR && reload_completed"
7142   [(const_int 0)]
7144   rtx op0 = operands[0];
7145   rtx op1 = operands[1];
7146   int r = REGNO (op0);
7147   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7149   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7150   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7151   DONE;
7154 (define_insn "*mov<mode>_internal2"
7155   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7156         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7157                     (const_int 0)))
7158    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7159   ""
7160   "@
7161    cmp<wd>i %2,%0,0
7162    mr. %0,%1
7163    #"
7164   [(set_attr "type" "cmp,logical,cmp")
7165    (set_attr "dot" "yes")
7166    (set_attr "length" "4,4,8")])
7168 (define_split
7169   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7170         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7171                     (const_int 0)))
7172    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7173   "reload_completed"
7174   [(set (match_dup 0) (match_dup 1))
7175    (set (match_dup 2)
7176         (compare:CC (match_dup 0)
7177                     (const_int 0)))]
7178   "")
7180 (define_expand "mov<mode>"
7181   [(set (match_operand:INT 0 "general_operand")
7182         (match_operand:INT 1 "any_operand"))]
7183   ""
7185   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7186   DONE;
7189 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7190 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7191 ;;              MTVSRWZ     MF%1       MT%1       NOP
7192 (define_insn "*mov<mode>_internal"
7193   [(set (match_operand:QHI 0 "nonimmediate_operand"
7194                 "=r,        r,         wa,        m,         Z,         r,
7195                  wa,        wa,        wa,        v,         ?v,        r,
7196                  wa,        r,         *c*l,      *h")
7197         (match_operand:QHI 1 "input_operand"
7198                 "r,         m,         Z,         r,         wa,        i,
7199                  wa,        O,         wM,        wB,        wS,        wa,
7200                  r,         *h,        r,         0"))]
7201   "gpc_reg_operand (operands[0], <MODE>mode)
7202    || gpc_reg_operand (operands[1], <MODE>mode)"
7203   "@
7204    mr %0,%1
7205    l<wd>z%U1%X1 %0,%1
7206    lxsi<wd>zx %x0,%y1
7207    st<wd>%U0%X0 %1,%0
7208    stxsi<wd>x %x1,%y0
7209    li %0,%1
7210    xxlor %x0,%x1,%x1
7211    xxspltib %x0,0
7212    xxspltib %x0,255
7213    vspltis<wd> %0,%1
7214    #
7215    mfvsrwz %0,%x1
7216    mtvsrwz %x0,%1
7217    mf%1 %0
7218    mt%0 %1
7219    nop"
7220   [(set_attr "type"
7221                 "*,         load,      fpload,    store,     fpstore,   *,
7222                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7223                  mffgpr,    mfjmpr,    mtjmpr,    *")
7224    (set_attr "length"
7225                 "*,         *,         *,         *,         *,         *,
7226                  *,         *,         *,         *,         8,         *,
7227                  *,         *,         *,         *")
7228    (set_attr "isa"
7229                 "*,         *,         p9v,       *,         p9v,       *,
7230                  p9v,       p9v,       p9v,       p9v,       p9v,       p9v,
7231                  p9v,       *,         *,         *")])
7234 ;; Here is how to move condition codes around.  When we store CC data in
7235 ;; an integer register or memory, we store just the high-order 4 bits.
7236 ;; This lets us not shift in the most common case of CR0.
7237 (define_expand "movcc"
7238   [(set (match_operand:CC 0 "nonimmediate_operand")
7239         (match_operand:CC 1 "nonimmediate_operand"))]
7240   ""
7241   "")
7243 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7245 (define_insn "*movcc_<mode>"
7246   [(set (match_operand:CC_any 0 "nonimmediate_operand"
7247                                 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7248         (match_operand:CC_any 1 "general_operand"
7249                                 " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7250   "register_operand (operands[0], <MODE>mode)
7251    || register_operand (operands[1], <MODE>mode)"
7252   "@
7253    mcrf %0,%1
7254    mtcrf 128,%1
7255    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7256    crxor %0,%0,%0
7257    mfcr %0%Q1
7258    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7259    mr %0,%1
7260    li %0,%1
7261    mf%1 %0
7262    mt%0 %1
7263    lwz%U1%X1 %0,%1
7264    stw%U0%X0 %1,%0"
7265   [(set_attr_alternative "type"
7266      [(const_string "cr_logical")
7267       (const_string "mtcr")
7268       (const_string "mtcr")
7269       (const_string "cr_logical")
7270       (if_then_else (match_test "TARGET_MFCRF")
7271                     (const_string "mfcrf") (const_string "mfcr"))
7272       (if_then_else (match_test "TARGET_MFCRF")
7273                     (const_string "mfcrf") (const_string "mfcr"))
7274       (const_string "integer")
7275       (const_string "integer")
7276       (const_string "mfjmpr")
7277       (const_string "mtjmpr")
7278       (const_string "load")
7279       (const_string "store")])
7280    (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7282 ;; For floating-point, we normally deal with the floating-point registers
7283 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7284 ;; can produce floating-point values in fixed-point registers.  Unless the
7285 ;; value is a simple constant or already in memory, we deal with this by
7286 ;; allocating memory and copying the value explicitly via that memory location.
7288 ;; Move 32-bit binary/decimal floating point
7289 (define_expand "mov<mode>"
7290   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7291         (match_operand:FMOVE32 1 "any_operand"))]
7292   "<fmove_ok>"
7294   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7295   DONE;
7298 (define_split
7299   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7300         (match_operand:FMOVE32 1 "const_double_operand"))]
7301   "reload_completed
7302    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7303        || (SUBREG_P (operands[0])
7304            && REG_P (SUBREG_REG (operands[0]))
7305            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7306   [(set (match_dup 2) (match_dup 3))]
7308   long l;
7310   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7312   if (! TARGET_POWERPC64)
7313     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7314   else
7315     operands[2] = gen_lowpart (SImode, operands[0]);
7317   operands[3] = gen_int_mode (l, SImode);
7320 ;; Originally, we tried to keep movsf and movsd common, but the differences
7321 ;; addressing was making it rather difficult to hide with mode attributes.  In
7322 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7323 ;; before the VSX stores meant that the register allocator would tend to do a
7324 ;; direct move to the GPR (which involves conversion from scalar to
7325 ;; vector/memory formats) to save values in the traditional Altivec registers,
7326 ;; while SDmode had problems on power6 if the GPR store was not first due to
7327 ;; the power6 not having an integer store operation.
7329 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7330 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7331 ;;      MR           MT<x>      MF<x>       NOP
7333 (define_insn "movsf_hardfloat"
7334   [(set (match_operand:SF 0 "nonimmediate_operand"
7335          "=!r,       f,         v,          wa,        m,         wY,
7336           Z,         m,         wa,         !r,        f,         wa,
7337           !r,        *c*l,      !r,         *h")
7338         (match_operand:SF 1 "input_operand"
7339          "m,         m,         wY,         Z,         f,         v,
7340           wa,        r,         j,          j,         f,         wa,
7341           r,         r,         *h,         0"))]
7342   "(register_operand (operands[0], SFmode)
7343    || register_operand (operands[1], SFmode))
7344    && TARGET_HARD_FLOAT
7345    && (TARGET_ALLOW_SF_SUBREG
7346        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7347   "@
7348    lwz%U1%X1 %0,%1
7349    lfs%U1%X1 %0,%1
7350    lxssp %0,%1
7351    lxsspx %x0,%y1
7352    stfs%U0%X0 %1,%0
7353    stxssp %1,%0
7354    stxsspx %x1,%y0
7355    stw%U0%X0 %1,%0
7356    xxlxor %x0,%x0,%x0
7357    li %0,0
7358    fmr %0,%1
7359    xscpsgndp %x0,%x1,%x1
7360    mr %0,%1
7361    mt%0 %1
7362    mf%1 %0
7363    nop"
7364   [(set_attr "type"
7365         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7366          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7367          *,          mtjmpr,    mfjmpr,     *")
7368    (set_attr "isa"
7369         "*,          *,         p9v,        p8v,       *,         p9v,
7370          p8v,        *,         *,          *,         *,         *,
7371          *,          *,         *,          *")])
7373 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7374 ;;      FMR          MR         MT%0       MF%1       NOP
7375 (define_insn "movsd_hardfloat"
7376   [(set (match_operand:SD 0 "nonimmediate_operand"
7377          "=!r,       d,         m,         Z,         ?d,        ?r,
7378           f,         !r,        *c*l,      !r,        *h")
7379         (match_operand:SD 1 "input_operand"
7380          "m,         Z,         r,         wx,        r,         d,
7381           f,         r,         r,         *h,        0"))]
7382   "(register_operand (operands[0], SDmode)
7383    || register_operand (operands[1], SDmode))
7384    && TARGET_HARD_FLOAT"
7385   "@
7386    lwz%U1%X1 %0,%1
7387    lfiwzx %0,%y1
7388    stw%U0%X0 %1,%0
7389    stfiwx %1,%y0
7390    mtvsrwz %x0,%1
7391    mfvsrwz %0,%x1
7392    fmr %0,%1
7393    mr %0,%1
7394    mt%0 %1
7395    mf%1 %0
7396    nop"
7397   [(set_attr "type"
7398         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7399          fpsimple,   *,         mtjmpr,    mfjmpr,    *")
7400    (set_attr "isa"
7401         "*,          p7,        *,         *,         p8v,       p8v,
7402          *,          *,         *,         *,         *")])
7404 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7405 ;;      LIS          G-const.   F/n-const  NOP
7406 (define_insn "*mov<mode>_softfloat"
7407   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7408         "=r,         *c*l,      r,         r,         m,         r,
7409           r,         r,         r,         *h")
7411         (match_operand:FMOVE32 1 "input_operand"
7412          "r,         r,         *h,        m,         r,         I,
7413           L,         G,         Fn,        0"))]
7415   "(gpc_reg_operand (operands[0], <MODE>mode)
7416    || gpc_reg_operand (operands[1], <MODE>mode))
7417    && TARGET_SOFT_FLOAT"
7418   "@
7419    mr %0,%1
7420    mt%0 %1
7421    mf%1 %0
7422    lwz%U1%X1 %0,%1
7423    stw%U0%X0 %1,%0
7424    li %0,%1
7425    lis %0,%v1
7426    #
7427    #
7428    nop"
7429   [(set_attr "type"
7430         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7431          *,          *,         *,         *")
7433    (set_attr "length"
7434         "*,          *,         *,         *,         *,         *,
7435          *,          *,         8,         *")])
7437 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7438 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7440 ;; Because SF values are actually stored as DF values within the vector
7441 ;; registers, we need to convert the value to the vector SF format when
7442 ;; we need to use the bits in a union or similar cases.  We only need
7443 ;; to do this transformation when the value is a vector register.  Loads,
7444 ;; stores, and transfers within GPRs are assumed to be safe.
7446 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7447 ;; no alternatives, because the call is created as part of secondary_reload,
7448 ;; and operand #2's register class is used to allocate the temporary register.
7449 ;; This function is called before reload, and it creates the temporary as
7450 ;; needed.
7452 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7453 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7454 (define_insn_and_split "movsf_from_si"
7455   [(set (match_operand:SF 0 "nonimmediate_operand"
7456             "=!r,       f,         v,         wa,        m,         Z,
7457              Z,         wa,        ?r,        !r")
7458         (unspec:SF [(match_operand:SI 1 "input_operand" 
7459             "m,         m,         wY,        Z,         r,         f,
7460              wa,        r,         wa,        r")]
7461                    UNSPEC_SF_FROM_SI))
7462    (clobber (match_scratch:DI 2
7463             "=X,        X,         X,         X,         X,         X,
7464              X,         r,         X,         X"))]
7465   "TARGET_NO_SF_SUBREG
7466    && (register_operand (operands[0], SFmode)
7467        || register_operand (operands[1], SImode))"
7468   "@
7469    lwz%U1%X1 %0,%1
7470    lfs%U1%X1 %0,%1
7471    lxssp %0,%1
7472    lxsspx %x0,%y1
7473    stw%U0%X0 %1,%0
7474    stfiwx %1,%y0
7475    stxsiwx %x1,%y0
7476    #
7477    mfvsrwz %0,%x1
7478    mr %0,%1"
7480   "&& reload_completed
7481    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7482    && int_reg_operand_not_pseudo (operands[1], SImode)"
7483   [(const_int 0)]
7485   rtx op0 = operands[0];
7486   rtx op1 = operands[1];
7487   rtx op2 = operands[2];
7488   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7490   /* Move SF value to upper 32-bits for xscvspdpn.  */
7491   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7492   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7493   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7494   DONE;
7496   [(set_attr "length"
7497             "*,          *,         *,         *,         *,         *,
7498              *,          12,        *,         *")
7499    (set_attr "type"
7500             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7501              fpstore,    vecfloat,  mffgpr,    *")
7502    (set_attr "isa"
7503             "*,          *,         p9v,       p8v,       *,         *,
7504              p8v,        p8v,       p8v,       *")])
7507 ;; Move 64-bit binary/decimal floating point
7508 (define_expand "mov<mode>"
7509   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7510         (match_operand:FMOVE64 1 "any_operand"))]
7511   ""
7513   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7514   DONE;
7517 (define_split
7518   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7519         (match_operand:FMOVE64 1 "const_int_operand"))]
7520   "! TARGET_POWERPC64 && reload_completed
7521    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7522        || (SUBREG_P (operands[0])
7523            && REG_P (SUBREG_REG (operands[0]))
7524            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7525   [(set (match_dup 2) (match_dup 4))
7526    (set (match_dup 3) (match_dup 1))]
7528   int endian = (WORDS_BIG_ENDIAN == 0);
7529   HOST_WIDE_INT value = INTVAL (operands[1]);
7531   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7532   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7533   operands[4] = GEN_INT (value >> 32);
7534   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7537 (define_split
7538   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7539         (match_operand:FMOVE64 1 "const_double_operand"))]
7540   "! TARGET_POWERPC64 && reload_completed
7541    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7542        || (SUBREG_P (operands[0])
7543            && REG_P (SUBREG_REG (operands[0]))
7544            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7545   [(set (match_dup 2) (match_dup 4))
7546    (set (match_dup 3) (match_dup 5))]
7548   int endian = (WORDS_BIG_ENDIAN == 0);
7549   long l[2];
7551   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7553   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7554   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7555   operands[4] = gen_int_mode (l[endian], SImode);
7556   operands[5] = gen_int_mode (l[1 - endian], SImode);
7559 (define_split
7560   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7561         (match_operand:FMOVE64 1 "const_double_operand"))]
7562   "TARGET_POWERPC64 && reload_completed
7563    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7564        || (SUBREG_P (operands[0])
7565            && REG_P (SUBREG_REG (operands[0]))
7566            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7567   [(set (match_dup 2) (match_dup 3))]
7569   int endian = (WORDS_BIG_ENDIAN == 0);
7570   long l[2];
7571   HOST_WIDE_INT val;
7573   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7575   operands[2] = gen_lowpart (DImode, operands[0]);
7576   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7577   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7578          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7580   operands[3] = gen_int_mode (val, DImode);
7583 ;; Don't have reload use general registers to load a constant.  It is
7584 ;; less efficient than loading the constant into an FP register, since
7585 ;; it will probably be used there.
7587 ;; The move constraints are ordered to prefer floating point registers before
7588 ;; general purpose registers to avoid doing a store and a load to get the value
7589 ;; into a floating point register when it is needed for a floating point
7590 ;; operation.  Prefer traditional floating point registers over VSX registers,
7591 ;; since the D-form version of the memory instructions does not need a GPR for
7592 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7593 ;; registers.
7595 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7596 ;; except for 0.0 which can be created on VSX with an xor instruction.
7598 ;;           STFD         LFD         FMR         LXSD        STXSD
7599 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7600 ;;           LWZ          STW         MR
7603 (define_insn "*mov<mode>_hardfloat32"
7604   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7605             "=m,          d,          d,          <f64_p9>,   wY,
7606               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7607               Y,          r,          !r")
7608         (match_operand:FMOVE64 1 "input_operand"
7609              "d,          m,          d,          wY,         <f64_p9>,
7610               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7611               r,          Y,          r"))]
7612   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7613    && (gpc_reg_operand (operands[0], <MODE>mode)
7614        || gpc_reg_operand (operands[1], <MODE>mode))"
7615   "@
7616    stfd%U0%X0 %1,%0
7617    lfd%U1%X1 %0,%1
7618    fmr %0,%1
7619    lxsd %0,%1
7620    stxsd %1,%0
7621    lxsdx %x0,%y1
7622    stxsdx %x1,%y0
7623    xxlor %x0,%x1,%x1
7624    xxlxor %x0,%x0,%x0
7625    #
7626    #
7627    #
7628    #"
7629   [(set_attr "type"
7630             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7631              fpload,      fpstore,    veclogical, veclogical, two,
7632              store,       load,       two")
7633    (set_attr "size" "64")
7634    (set_attr "length"
7635             "*,           *,          *,          *,          *,
7636              *,           *,          *,          *,          8,
7637              8,           8,          8")
7638    (set_attr "isa"
7639             "*,           *,          *,          p9v,        p9v,
7640              p7v,         p7v,        *,          *,          *,
7641              *,           *,          *")])
7643 ;;           STW      LWZ     MR      G-const H-const F-const
7645 (define_insn "*mov<mode>_softfloat32"
7646   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7647            "=Y,       r,      r,      r,      r,      r")
7649         (match_operand:FMOVE64 1 "input_operand"
7650             "r,       Y,      r,      G,      H,      F"))]
7652   "!TARGET_POWERPC64
7653    && (gpc_reg_operand (operands[0], <MODE>mode)
7654        || gpc_reg_operand (operands[1], <MODE>mode))"
7655   "#"
7656   [(set_attr "type"
7657             "store,   load,   two,    *,      *,      *")
7659    (set_attr "length"
7660              "8,      8,      8,      8,      12,     16")])
7662 ; ld/std require word-aligned displacements -> 'Y' constraint.
7663 ; List Y->r and r->Y before r->r for reload.
7665 ;;           STFD         LFD         FMR         LXSD        STXSD
7666 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7667 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7668 ;;           NOP          MFVSRD      MTVSRD
7670 (define_insn "*mov<mode>_hardfloat64"
7671   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7672            "=m,           d,          d,          <f64_p9>,   wY,
7673              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7674              YZ,          r,          !r,         *c*l,       !r,
7675             *h,           r,          <f64_dm>")
7676         (match_operand:FMOVE64 1 "input_operand"
7677             "d,           m,          d,          wY,         <f64_p9>,
7678              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7679              r,           YZ,         r,          r,          *h,
7680              0,           <f64_dm>,   r"))]
7681   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7682    && (gpc_reg_operand (operands[0], <MODE>mode)
7683        || gpc_reg_operand (operands[1], <MODE>mode))"
7684   "@
7685    stfd%U0%X0 %1,%0
7686    lfd%U1%X1 %0,%1
7687    fmr %0,%1
7688    lxsd %0,%1
7689    stxsd %1,%0
7690    lxsdx %x0,%y1
7691    stxsdx %x1,%y0
7692    xxlor %x0,%x1,%x1
7693    xxlxor %x0,%x0,%x0
7694    li %0,0
7695    std%U0%X0 %1,%0
7696    ld%U1%X1 %0,%1
7697    mr %0,%1
7698    mt%0 %1
7699    mf%1 %0
7700    nop
7701    mfvsrd %0,%x1
7702    mtvsrd %x0,%1"
7703   [(set_attr "type"
7704             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7705              fpload,      fpstore,    veclogical, veclogical, integer,
7706              store,       load,       *,          mtjmpr,     mfjmpr,
7707              *,           mftgpr,     mffgpr")
7708    (set_attr "size" "64")
7709    (set_attr "isa"
7710             "*,           *,          *,          p9v,        p9v,
7711              p7v,         p7v,        *,          *,          *,
7712              *,           *,          *,          *,          *,
7713              *,           p8v,        p8v")])
7715 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7716 ;;           H-const  F-const  Special
7718 (define_insn "*mov<mode>_softfloat64"
7719   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7720            "=Y,       r,      r,      *c*l,   r,      r,
7721              r,       r,      *h")
7723         (match_operand:FMOVE64 1 "input_operand"
7724             "r,       Y,      r,      r,      *h,     G,
7725              H,       F,      0"))]
7727   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7728    && (gpc_reg_operand (operands[0], <MODE>mode)
7729        || gpc_reg_operand (operands[1], <MODE>mode))"
7730   "@
7731    std%U0%X0 %1,%0
7732    ld%U1%X1 %0,%1
7733    mr %0,%1
7734    mt%0 %1
7735    mf%1 %0
7736    #
7737    #
7738    #
7739    nop"
7740   [(set_attr "type"
7741             "store,   load,   *,      mtjmpr, mfjmpr, *,
7742              *,       *,      *")
7744    (set_attr "length"
7745             "*,       *,      *,      *,      *,      8,
7746              12,      16,     *")])
7748 (define_expand "mov<mode>"
7749   [(set (match_operand:FMOVE128 0 "general_operand")
7750         (match_operand:FMOVE128 1 "any_operand"))]
7751   ""
7753   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7754   DONE;
7757 ;; It's important to list Y->r and r->Y before r->r because otherwise
7758 ;; reload, given m->r, will try to pick r->r and reload it, which
7759 ;; doesn't make progress.
7761 ;; We can't split little endian direct moves of TDmode, because the words are
7762 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7763 ;; problematical.  Don't allow direct move for this case.
7765 ;;              FPR load    FPR store   FPR move    FPR zero    GPR load
7766 ;;              GPR zero    GPR store   GPR move    MFVSRD      MTVSRD
7768 (define_insn_and_split "*mov<mode>_64bit_dm"
7769   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7770                 "=m,        d,          d,          d,          Y,
7771                  r,         r,          r,          r,          d")
7773         (match_operand:FMOVE128_FPR 1 "input_operand"
7774                 "d,         m,          d,          <zero_fp>,  r,
7775                  <zero_fp>, Y,          r,          d,          r"))]
7777   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7778    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7779    && (gpc_reg_operand (operands[0], <MODE>mode)
7780        || gpc_reg_operand (operands[1], <MODE>mode))"
7781   "#"
7782   "&& reload_completed"
7783   [(pc)]
7785   rs6000_split_multireg_move (operands[0], operands[1]);
7786   DONE;
7788   [(set_attr "length" "8")
7789    (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7790    (set_attr "max_prefixed_insns" "2")
7791    (set_attr "num_insns" "2")])
7793 (define_insn_and_split "*movtd_64bit_nodm"
7794   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7795         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7796   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7797    && (gpc_reg_operand (operands[0], TDmode)
7798        || gpc_reg_operand (operands[1], TDmode))"
7799   "#"
7800   "&& reload_completed"
7801   [(pc)]
7803   rs6000_split_multireg_move (operands[0], operands[1]);
7804   DONE;
7806   [(set_attr "length" "8,8,8,12,12,8")
7807    (set_attr "max_prefixed_insns" "2")
7808    (set_attr "num_insns" "2,2,2,3,3,2")])
7810 (define_insn_and_split "*mov<mode>_32bit"
7811   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7812         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7813   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7814    && (FLOAT128_2REG_P (<MODE>mode)
7815        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7816        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7817    && (gpc_reg_operand (operands[0], <MODE>mode)
7818        || gpc_reg_operand (operands[1], <MODE>mode))"
7819   "#"
7820   "&& reload_completed"
7821   [(pc)]
7823   rs6000_split_multireg_move (operands[0], operands[1]);
7824   DONE;
7826   [(set_attr "length" "8,8,8,8,20,20,16")])
7828 (define_insn_and_split "*mov<mode>_softfloat"
7829   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7830         (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7831   "TARGET_SOFT_FLOAT
7832    && (gpc_reg_operand (operands[0], <MODE>mode)
7833        || gpc_reg_operand (operands[1], <MODE>mode))"
7834   "#"
7835   "&& reload_completed"
7836   [(pc)]
7838   rs6000_split_multireg_move (operands[0], operands[1]);
7839   DONE;
7841   [(set_attr_alternative "length"
7842        [(if_then_else (match_test "TARGET_POWERPC64")
7843             (const_string "8")
7844             (const_string "16"))
7845         (if_then_else (match_test "TARGET_POWERPC64")
7846             (const_string "8")
7847             (const_string "16"))
7848         (if_then_else (match_test "TARGET_POWERPC64")
7849             (const_string "16")
7850             (const_string "32"))
7851         (if_then_else (match_test "TARGET_POWERPC64")
7852             (const_string "8")
7853             (const_string "16"))])])
7855 (define_expand "@extenddf<mode>2"
7856   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7857         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7858   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7860   if (FLOAT128_IEEE_P (<MODE>mode))
7861     rs6000_expand_float128_convert (operands[0], operands[1], false);
7862   else if (TARGET_VSX)
7863     emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7864   else
7865     {
7866       rtx zero = gen_reg_rtx (DFmode);
7867       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7869       emit_insn (gen_extenddf2_fprs (<MODE>mode,
7870                                      operands[0], operands[1], zero));
7871     }
7872   DONE;
7875 ;; Allow memory operands for the source to be created by the combiner.
7876 (define_insn_and_split "@extenddf<mode>2_fprs"
7877   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7878         (float_extend:IBM128
7879          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7880    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7881   "!TARGET_VSX && TARGET_HARD_FLOAT
7882    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7883   "#"
7884   "&& reload_completed"
7885   [(set (match_dup 3) (match_dup 1))
7886    (set (match_dup 4) (match_dup 2))]
7888   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7889   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7891   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7892   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7895 (define_insn_and_split "@extenddf<mode>2_vsx"
7896   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7897         (float_extend:IBM128
7898          (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7899   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7900   "#"
7901   "&& reload_completed"
7902   [(set (match_dup 2) (match_dup 1))
7903    (set (match_dup 3) (match_dup 4))]
7905   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7906   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7908   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7909   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7910   operands[4] = CONST0_RTX (DFmode);
7913 (define_expand "extendsf<mode>2"
7914   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7915         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7916   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7918   if (FLOAT128_IEEE_P (<MODE>mode))
7919     rs6000_expand_float128_convert (operands[0], operands[1], false);
7920   else
7921     {
7922       rtx tmp = gen_reg_rtx (DFmode);
7923       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7924       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7925     }
7926   DONE;
7929 (define_expand "trunc<mode>df2"
7930   [(set (match_operand:DF 0 "gpc_reg_operand")
7931         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7932   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7934   if (FLOAT128_IEEE_P (<MODE>mode))
7935     {
7936       rs6000_expand_float128_convert (operands[0], operands[1], false);
7937       DONE;
7938     }
7941 (define_insn_and_split "trunc<mode>df2_internal1"
7942   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7943         (float_truncate:DF
7944          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7945   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7946    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7947   "@
7948    #
7949    fmr %0,%1"
7950   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7951   [(const_int 0)]
7953   emit_note (NOTE_INSN_DELETED);
7954   DONE;
7956   [(set_attr "type" "fpsimple")])
7958 (define_insn "trunc<mode>df2_internal2"
7959   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7960         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7961   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7962    && TARGET_LONG_DOUBLE_128"
7963   "fadd %0,%1,%L1"
7964   [(set_attr "type" "fp")])
7966 (define_expand "trunc<mode>sf2"
7967   [(set (match_operand:SF 0 "gpc_reg_operand")
7968         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7969   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7971   if (FLOAT128_IEEE_P (<MODE>mode))
7972     rs6000_expand_float128_convert (operands[0], operands[1], false);
7973   else
7974     {
7975       rtx tmp = gen_reg_rtx (DFmode);
7976       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7977       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7978     }
7979   DONE;
7982 (define_expand "floatsi<mode>2"
7983   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7984                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7985               (clobber (match_scratch:DI 2))])]
7986   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7988   rtx op0 = operands[0];
7989   rtx op1 = operands[1];
7991   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7992     ;
7993   else if (FLOAT128_IEEE_P (<MODE>mode))
7994     {
7995       rs6000_expand_float128_convert (op0, op1, false);
7996       DONE;
7997     }
7998   else
7999     {
8000       rtx tmp = gen_reg_rtx (DFmode);
8001       expand_float (tmp, op1, false);
8002       emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8003       DONE;
8004     }
8007 ; fadd, but rounding towards zero.
8008 ; This is probably not the optimal code sequence.
8009 (define_insn "fix_trunc_helper<mode>"
8010   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8011         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8012                    UNSPEC_FIX_TRUNC_TF))
8013    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8014   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8015   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8016   [(set_attr "type" "fp")
8017    (set_attr "length" "20")])
8019 (define_expand "fix_trunc<mode>si2"
8020   [(set (match_operand:SI 0 "gpc_reg_operand")
8021         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8022   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8024   rtx op0 = operands[0];
8025   rtx op1 = operands[1];
8027   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8028     ;
8029   else
8030     {
8031       if (FLOAT128_IEEE_P (<MODE>mode))
8032         rs6000_expand_float128_convert (op0, op1, false);
8033       else
8034         emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8035       DONE;
8036     }
8039 (define_expand "@fix_trunc<mode>si2_fprs"
8040   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8041                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8042               (clobber (match_dup 2))
8043               (clobber (match_dup 3))
8044               (clobber (match_dup 4))
8045               (clobber (match_dup 5))])]
8046   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8048   operands[2] = gen_reg_rtx (DFmode);
8049   operands[3] = gen_reg_rtx (DFmode);
8050   operands[4] = gen_reg_rtx (DImode);
8051   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8054 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8055   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8056         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8057    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8058    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8059    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8060    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8061   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8062   "#"
8063   ""
8064   [(pc)]
8066   rtx lowword;
8067   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8068                                          operands[3]));
8070   gcc_assert (MEM_P (operands[5]));
8071   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8073   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8074   emit_move_insn (operands[5], operands[4]);
8075   emit_move_insn (operands[0], lowword);
8076   DONE;
8079 (define_expand "fix_trunc<mode>di2"
8080   [(set (match_operand:DI 0 "gpc_reg_operand")
8081         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8082   "TARGET_FLOAT128_TYPE"
8084   if (!TARGET_FLOAT128_HW)
8085     {
8086       rs6000_expand_float128_convert (operands[0], operands[1], false);
8087       DONE;
8088     }
8091 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8092   [(set (match_operand:SDI 0 "gpc_reg_operand")
8093         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8094   "TARGET_FLOAT128_TYPE"
8096   rs6000_expand_float128_convert (operands[0], operands[1], true);
8097   DONE;
8100 (define_expand "floatdi<mode>2"
8101   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8102         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8103   "TARGET_FLOAT128_TYPE"
8105   if (!TARGET_FLOAT128_HW)
8106     {
8107       rs6000_expand_float128_convert (operands[0], operands[1], false);
8108       DONE;
8109     }
8112 (define_expand "floatunsdi<IEEE128:mode>2"
8113   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8114         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8115   "TARGET_FLOAT128_TYPE"
8117   if (!TARGET_FLOAT128_HW)
8118     {
8119       rs6000_expand_float128_convert (operands[0], operands[1], true);
8120       DONE;
8121     }
8124 (define_expand "floatuns<IEEE128:mode>2"
8125   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8126         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8127   "TARGET_FLOAT128_TYPE"
8129   rtx op0 = operands[0];
8130   rtx op1 = operands[1];
8132   if (TARGET_FLOAT128_HW)
8133     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8134   else
8135     rs6000_expand_float128_convert (op0, op1, true);
8136   DONE;
8139 (define_expand "neg<mode>2"
8140   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8141         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8142   "FLOAT128_IEEE_P (<MODE>mode)
8143    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8145   if (FLOAT128_IEEE_P (<MODE>mode))
8146     {
8147       if (TARGET_FLOAT128_HW)
8148         emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8149       else if (TARGET_FLOAT128_TYPE)
8150         emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8151                                              operands[0], operands[1]));
8152       else
8153         {
8154           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8155           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8156                                                 <MODE>mode,
8157                                                 operands[1], <MODE>mode);
8159           if (target && !rtx_equal_p (target, operands[0]))
8160             emit_move_insn (operands[0], target);
8161         }
8162       DONE;
8163     }
8166 (define_insn "neg<mode>2_internal"
8167   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8168         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8169   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8171   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8172     return "fneg %L0,%L1\;fneg %0,%1";
8173   else
8174     return "fneg %0,%1\;fneg %L0,%L1";
8176   [(set_attr "type" "fpsimple")
8177    (set_attr "length" "8")])
8179 (define_expand "abs<mode>2"
8180   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8181         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8182   "FLOAT128_IEEE_P (<MODE>mode)
8183    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8185   rtx label;
8187   if (FLOAT128_IEEE_P (<MODE>mode))
8188     {
8189       if (TARGET_FLOAT128_HW)
8190         {
8191           emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8192           DONE;
8193         }
8194       else if (TARGET_FLOAT128_TYPE)
8195         {
8196           emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8197                                                operands[0], operands[1]));
8198           DONE;
8199         }
8200       else
8201         FAIL;
8202     }
8204   label = gen_label_rtx ();
8205   emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8206   emit_label (label);
8207   DONE;
8210 (define_expand "@abs<mode>2_internal"
8211   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8212         (match_operand:IBM128 1 "gpc_reg_operand"))
8213    (set (match_dup 3) (match_dup 5))
8214    (set (match_dup 5) (abs:DF (match_dup 5)))
8215    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8216    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8217                            (label_ref (match_operand 2 ""))
8218                            (pc)))
8219    (set (match_dup 6) (neg:DF (match_dup 6)))]
8220   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8222   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8223   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8224   operands[3] = gen_reg_rtx (DFmode);
8225   operands[4] = gen_reg_rtx (CCFPmode);
8226   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8227   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8231 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8232 ;; register
8234 (define_expand "ieee_128bit_negative_zero"
8235   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8236   "TARGET_FLOAT128_TYPE"
8238   rtvec v = rtvec_alloc (16);
8239   int i, high;
8241   for (i = 0; i < 16; i++)
8242     RTVEC_ELT (v, i) = const0_rtx;
8244   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8245   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8247   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8248   DONE;
8251 ;; IEEE 128-bit negate
8253 ;; We have 2 insns here for negate and absolute value.  The first uses
8254 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8255 ;; insns, and second insn after the first split pass loads up the bit to
8256 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8257 ;; neg/abs to create the constant just once.
8259 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8260   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8261         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8262    (clobber (match_scratch:V16QI 2 "=v"))]
8263   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8264   "#"
8265   "&& 1"
8266   [(parallel [(set (match_dup 0)
8267                    (neg:IEEE128 (match_dup 1)))
8268               (use (match_dup 2))])]
8270   if (GET_CODE (operands[2]) == SCRATCH)
8271     operands[2] = gen_reg_rtx (V16QImode);
8273   operands[3] = gen_reg_rtx (V16QImode);
8274   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8276   [(set_attr "length" "8")
8277    (set_attr "type" "vecsimple")])
8279 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8280   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8281         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8282    (use (match_operand:V16QI 2 "register_operand" "v"))]
8283   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8284   "xxlxor %x0,%x1,%x2"
8285   [(set_attr "type" "veclogical")])
8287 ;; IEEE 128-bit absolute value
8288 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8289   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8290         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8291    (clobber (match_scratch:V16QI 2 "=v"))]
8292   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8293   "#"
8294   "&& 1"
8295   [(parallel [(set (match_dup 0)
8296                    (abs:IEEE128 (match_dup 1)))
8297               (use (match_dup 2))])]
8299   if (GET_CODE (operands[2]) == SCRATCH)
8300     operands[2] = gen_reg_rtx (V16QImode);
8302   operands[3] = gen_reg_rtx (V16QImode);
8303   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8305   [(set_attr "length" "8")
8306    (set_attr "type" "vecsimple")])
8308 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8309   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8310         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8311    (use (match_operand:V16QI 2 "register_operand" "v"))]
8312   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8313   "xxlandc %x0,%x1,%x2"
8314   [(set_attr "type" "veclogical")])
8316 ;; IEEE 128-bit negative absolute value
8317 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8318   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8319         (neg:IEEE128
8320          (abs:IEEE128
8321           (match_operand:IEEE128 1 "register_operand" "wa"))))
8322    (clobber (match_scratch:V16QI 2 "=v"))]
8323   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8324    && FLOAT128_IEEE_P (<MODE>mode)"
8325   "#"
8326   "&& 1"
8327   [(parallel [(set (match_dup 0)
8328                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8329               (use (match_dup 2))])]
8331   if (GET_CODE (operands[2]) == SCRATCH)
8332     operands[2] = gen_reg_rtx (V16QImode);
8334   operands[3] = gen_reg_rtx (V16QImode);
8335   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8337   [(set_attr "length" "8")
8338    (set_attr "type" "vecsimple")])
8340 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8341   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8342         (neg:IEEE128
8343          (abs:IEEE128
8344           (match_operand:IEEE128 1 "register_operand" "wa"))))
8345    (use (match_operand:V16QI 2 "register_operand" "v"))]
8346   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8347   "xxlor %x0,%x1,%x2"
8348   [(set_attr "type" "veclogical")])
8350 ;; Float128 conversion functions.  These expand to library function calls.
8351 ;; We use expand to convert from IBM double double to IEEE 128-bit
8352 ;; and trunc for the opposite.
8353 (define_expand "extendiftf2"
8354   [(set (match_operand:TF 0 "gpc_reg_operand")
8355         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8356   "TARGET_FLOAT128_TYPE"
8358   rs6000_expand_float128_convert (operands[0], operands[1], false);
8359   DONE;
8362 (define_expand "extendifkf2"
8363   [(set (match_operand:KF 0 "gpc_reg_operand")
8364         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8365   "TARGET_FLOAT128_TYPE"
8367   rs6000_expand_float128_convert (operands[0], operands[1], false);
8368   DONE;
8371 (define_expand "extendtfkf2"
8372   [(set (match_operand:KF 0 "gpc_reg_operand")
8373         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8374   "TARGET_FLOAT128_TYPE"
8376   rs6000_expand_float128_convert (operands[0], operands[1], false);
8377   DONE;
8380 (define_expand "extendtfif2"
8381   [(set (match_operand:IF 0 "gpc_reg_operand")
8382         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8383   "TARGET_FLOAT128_TYPE"
8385   rs6000_expand_float128_convert (operands[0], operands[1], false);
8386   DONE;
8389 (define_expand "trunciftf2"
8390   [(set (match_operand:TF 0 "gpc_reg_operand")
8391         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8392   "TARGET_FLOAT128_TYPE"
8394   rs6000_expand_float128_convert (operands[0], operands[1], false);
8395   DONE;
8398 (define_expand "truncifkf2"
8399   [(set (match_operand:KF 0 "gpc_reg_operand")
8400         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8401   "TARGET_FLOAT128_TYPE"
8403   rs6000_expand_float128_convert (operands[0], operands[1], false);
8404   DONE;
8407 (define_expand "trunckftf2"
8408   [(set (match_operand:TF 0 "gpc_reg_operand")
8409         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8410   "TARGET_FLOAT128_TYPE"
8412   rs6000_expand_float128_convert (operands[0], operands[1], false);
8413   DONE;
8416 (define_expand "trunctfif2"
8417   [(set (match_operand:IF 0 "gpc_reg_operand")
8418         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8419   "TARGET_FLOAT128_TYPE"
8421   rs6000_expand_float128_convert (operands[0], operands[1], false);
8422   DONE;
8425 (define_insn_and_split "*extend<mode>tf2_internal"
8426   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8427         (float_extend:TF
8428          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8429    "TARGET_FLOAT128_TYPE
8430     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8431   "#"
8432   "&& reload_completed"
8433   [(set (match_dup 0) (match_dup 2))]
8435   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8438 (define_insn_and_split "*extendtf<mode>2_internal"
8439   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8440         (float_extend:IFKF
8441          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8442    "TARGET_FLOAT128_TYPE
8443     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8444   "#"
8445   "&& reload_completed"
8446   [(set (match_dup 0) (match_dup 2))]
8448   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8452 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8453 ;; must have 3 arguments, and scratch register constraint must be a single
8454 ;; constraint.
8456 ;; Reload patterns to support gpr load/store with misaligned mem.
8457 ;; and multiple gpr load/store at offset >= 0xfffc
8458 (define_expand "reload_<mode>_store"
8459   [(parallel [(match_operand 0 "memory_operand" "=m")
8460               (match_operand 1 "gpc_reg_operand" "r")
8461               (match_operand:GPR 2 "register_operand" "=&b")])]
8462   ""
8464   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8465   DONE;
8468 (define_expand "reload_<mode>_load"
8469   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8470               (match_operand 1 "memory_operand" "m")
8471               (match_operand:GPR 2 "register_operand" "=b")])]
8472   ""
8474   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8475   DONE;
8479 ;; Reload patterns for various types using the vector registers.  We may need
8480 ;; an additional base register to convert the reg+offset addressing to reg+reg
8481 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8482 ;; index register for gpr registers.
8483 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8484   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8485               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8486               (match_operand:P 2 "register_operand" "=b")])]
8487   "<P:tptrsize>"
8489   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8490   DONE;
8493 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8494   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8495               (match_operand:RELOAD 1 "memory_operand" "m")
8496               (match_operand:P 2 "register_operand" "=b")])]
8497   "<P:tptrsize>"
8499   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8500   DONE;
8504 ;; Reload sometimes tries to move the address to a GPR, and can generate
8505 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8506 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8508 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8509   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8510         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8511                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8512                (const_int -16)))]
8513   "TARGET_ALTIVEC && reload_completed"
8514   "#"
8515   "&& reload_completed"
8516   [(set (match_dup 0)
8517         (plus:P (match_dup 1)
8518                 (match_dup 2)))
8519    (set (match_dup 0)
8520         (and:P (match_dup 0)
8521                (const_int -16)))])
8523 ;; Power8 merge instructions to allow direct move to/from floating point
8524 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8525 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8526 ;; value, since it is allocated in reload and not all of the flow information
8527 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8528 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8529 ;; schedule other instructions between the two instructions.
8531 (define_insn "p8_fmrgow_<mode>"
8532   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8533         (unspec:FMOVE64X [
8534                 (match_operand:DF 1 "register_operand" "d")
8535                 (match_operand:DF 2 "register_operand" "d")]
8536                          UNSPEC_P8V_FMRGOW))]
8537   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8538   "fmrgow %0,%1,%2"
8539   [(set_attr "type" "fpsimple")])
8541 (define_insn "p8_mtvsrwz"
8542   [(set (match_operand:DF 0 "register_operand" "=d")
8543         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8544                    UNSPEC_P8V_MTVSRWZ))]
8545   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8546   "mtvsrwz %x0,%1"
8547   [(set_attr "type" "mftgpr")])
8549 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8550   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8551         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8552                          UNSPEC_P8V_RELOAD_FROM_GPR))
8553    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8554   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8555   "#"
8556   "&& reload_completed"
8557   [(const_int 0)]
8559   rtx dest = operands[0];
8560   rtx src = operands[1];
8561   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8562   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8563   rtx gpr_hi_reg = gen_highpart (SImode, src);
8564   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8566   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8567   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8568   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8569   DONE;
8571   [(set_attr "length" "12")
8572    (set_attr "type" "three")])
8574 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8575 (define_insn "p8_mtvsrd_df"
8576   [(set (match_operand:DF 0 "register_operand" "=wa")
8577         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8578                    UNSPEC_P8V_MTVSRD))]
8579   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8580   "mtvsrd %x0,%1"
8581   [(set_attr "type" "mftgpr")])
8583 (define_insn "p8_xxpermdi_<mode>"
8584   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8585         (unspec:FMOVE128_GPR [
8586                 (match_operand:DF 1 "register_operand" "wa")
8587                 (match_operand:DF 2 "register_operand" "wa")]
8588                 UNSPEC_P8V_XXPERMDI))]
8589   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8590   "xxpermdi %x0,%x1,%x2,0"
8591   [(set_attr "type" "vecperm")])
8593 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8594   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8595         (unspec:FMOVE128_GPR
8596          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8597          UNSPEC_P8V_RELOAD_FROM_GPR))
8598    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8599   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8600   "#"
8601   "&& reload_completed"
8602   [(const_int 0)]
8604   rtx dest = operands[0];
8605   rtx src = operands[1];
8606   /* You might think that we could use op0 as one temp and a DF clobber
8607      as op2, but you'd be wrong.  Secondary reload move patterns don't
8608      check for overlap of the clobber and the destination.  */
8609   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8610   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8611   rtx gpr_hi_reg = gen_highpart (DImode, src);
8612   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8614   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8615   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8616   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8617   DONE;
8619   [(set_attr "length" "12")
8620    (set_attr "type" "three")])
8622 (define_split
8623   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8624         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8625   "reload_completed
8626    && (int_reg_operand (operands[0], <MODE>mode)
8627        || int_reg_operand (operands[1], <MODE>mode))
8628    && (!TARGET_DIRECT_MOVE_128
8629        || (!vsx_register_operand (operands[0], <MODE>mode)
8630            && !vsx_register_operand (operands[1], <MODE>mode)))"
8631   [(pc)]
8633   rs6000_split_multireg_move (operands[0], operands[1]);
8634   DONE;
8637 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8638 ;; type is stored internally as double precision in the VSX registers, we have
8639 ;; to convert it from the vector format.
8640 (define_insn "p8_mtvsrd_sf"
8641   [(set (match_operand:SF 0 "register_operand" "=wa")
8642         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8643                    UNSPEC_P8V_MTVSRD))]
8644   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8645   "mtvsrd %x0,%1"
8646   [(set_attr "type" "mftgpr")])
8648 (define_insn_and_split "reload_vsx_from_gprsf"
8649   [(set (match_operand:SF 0 "register_operand" "=wa")
8650         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8651                    UNSPEC_P8V_RELOAD_FROM_GPR))
8652    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8653   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8654   "#"
8655   "&& reload_completed"
8656   [(const_int 0)]
8658   rtx op0 = operands[0];
8659   rtx op1 = operands[1];
8660   rtx op2 = operands[2];
8661   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8663   /* Move SF value to upper 32-bits for xscvspdpn.  */
8664   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8665   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8666   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8667   DONE;
8669   [(set_attr "length" "8")
8670    (set_attr "type" "two")])
8672 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8673 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8674 ;; and then doing a move of that.
8675 (define_insn "p8_mfvsrd_3_<mode>"
8676   [(set (match_operand:DF 0 "register_operand" "=r")
8677         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8678                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8679   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8680   "mfvsrd %0,%x1"
8681   [(set_attr "type" "mftgpr")])
8683 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8684   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8685         (unspec:FMOVE128_GPR
8686          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8687          UNSPEC_P8V_RELOAD_FROM_VSX))
8688    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8689   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8690   "#"
8691   "&& reload_completed"
8692   [(const_int 0)]
8694   rtx dest = operands[0];
8695   rtx src = operands[1];
8696   rtx tmp = operands[2];
8697   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8698   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8700   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8701   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8702   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8703   DONE;
8705   [(set_attr "length" "12")
8706    (set_attr "type" "three")])
8708 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8709 ;; type is stored internally as double precision, we have to convert it to the
8710 ;; vector format.
8712 (define_insn_and_split "reload_gpr_from_vsxsf"
8713   [(set (match_operand:SF 0 "register_operand" "=r")
8714         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8715                    UNSPEC_P8V_RELOAD_FROM_VSX))
8716    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8717   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8718   "#"
8719   "&& reload_completed"
8720   [(const_int 0)]
8722   rtx op0 = operands[0];
8723   rtx op1 = operands[1];
8724   rtx op2 = operands[2];
8725   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8726   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8728   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8729   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8730   DONE;
8732   [(set_attr "length" "8")
8733    (set_attr "type" "two")
8734    (set_attr "isa" "p8v")])
8736 ;; Next come the multi-word integer load and store and the load and store
8737 ;; multiple insns.
8739 ;; List r->r after r->Y, otherwise reload will try to reload a
8740 ;; non-offsettable address by using r->r which won't make progress.
8741 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8742 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8744 ;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8745 ;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8746 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8747 ;;        AVX const  
8749 (define_insn "*movdi_internal32"
8750   [(set (match_operand:DI 0 "nonimmediate_operand"
8751          "=Y,        r,         r,         m,         ^d,        ^d,
8752           r,         wY,        Z,         ^v,        $v,        ^wa,
8753           wa,        wa,        v,         wa,        *i,        v,
8754           v")
8755         (match_operand:DI 1 "input_operand"
8756          "r,         Y,         r,         ^d,        m,         ^d,
8757           IJKnF,     ^v,        $v,        wY,        Z,         ^wa,
8758           Oj,        wM,        OjwM,      Oj,        wM,        wS,
8759           wB"))]
8760   "! TARGET_POWERPC64
8761    && (gpc_reg_operand (operands[0], DImode)
8762        || gpc_reg_operand (operands[1], DImode))"
8763   "@
8764    #
8765    #
8766    #
8767    stfd%U0%X0 %1,%0
8768    lfd%U1%X1 %0,%1
8769    fmr %0,%1
8770    #
8771    stxsd %1,%0
8772    stxsdx %x1,%y0
8773    lxsd %0,%1
8774    lxsdx %x0,%y1
8775    xxlor %x0,%x1,%x1
8776    xxspltib %x0,0
8777    xxspltib %x0,255
8778    vspltisw %0,%1
8779    xxlxor %x0,%x0,%x0
8780    xxlorc %x0,%x0,%x0
8781    #
8782    #"
8783   [(set_attr "type"
8784          "store,     load,      *,         fpstore,   fpload,    fpsimple,
8785           *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8786           vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8787           vecsimple")
8788    (set_attr "size" "64")
8789    (set_attr "length"
8790          "8,         8,         8,         *,         *,         *,
8791           16,        *,         *,         *,         *,         *,
8792           *,         *,         *,         *,         *,         8,
8793           *")
8794    (set_attr "isa"
8795          "*,         *,         *,         *,         *,         *,
8796           *,         p9v,       p7v,       p9v,       p7v,       *,
8797           p9v,       p9v,       p7v,       *,         *,         p7v,
8798           p7v")])
8800 (define_split
8801   [(set (match_operand:DI 0 "gpc_reg_operand")
8802         (match_operand:DI 1 "const_int_operand"))]
8803   "! TARGET_POWERPC64 && reload_completed
8804    && gpr_or_gpr_p (operands[0], operands[1])
8805    && !direct_move_p (operands[0], operands[1])"
8806   [(set (match_dup 2) (match_dup 4))
8807    (set (match_dup 3) (match_dup 1))]
8809   HOST_WIDE_INT value = INTVAL (operands[1]);
8810   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8811                                        DImode);
8812   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8813                                        DImode);
8814   operands[4] = GEN_INT (value >> 32);
8815   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8818 (define_split
8819   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8820         (match_operand:DIFD 1 "input_operand"))]
8821   "reload_completed && !TARGET_POWERPC64
8822    && gpr_or_gpr_p (operands[0], operands[1])
8823    && !direct_move_p (operands[0], operands[1])"
8824   [(pc)]
8826   rs6000_split_multireg_move (operands[0], operands[1]);
8827   DONE;
8830 ;;         GPR store   GPR load    GPR move
8831 ;;         GPR li      GPR lis     GPR pli     GPR #
8832 ;;         FPR store   FPR load    FPR move
8833 ;;         AVX store   AVX store   AVX load    AVX load    VSX move
8834 ;;         P9 0        P9 -1       AVX 0/-1    VSX 0       VSX -1
8835 ;;         P9 const    AVX const
8836 ;;         From SPR    To SPR      SPR<->SPR
8837 ;;         VSX->GPR    GPR->VSX
8838 (define_insn "*movdi_internal64"
8839   [(set (match_operand:DI 0 "nonimmediate_operand"
8840           "=YZ,        r,          r,
8841            r,          r,          r,          r,
8842            m,          ^d,         ^d,
8843            wY,         Z,          $v,         $v,         ^wa,
8844            wa,         wa,         v,          wa,         wa,
8845            v,          v,
8846            r,          *h,         *h,
8847            ?r,         ?wa")
8848         (match_operand:DI 1 "input_operand"
8849           "r,          YZ,         r,
8850            I,          L,          eI,         nF,
8851            ^d,         m,          ^d,
8852            ^v,         $v,         wY,         Z,          ^wa,
8853            Oj,         wM,         OjwM,       Oj,         wM,
8854            wS,         wB,
8855            *h,         r,          0,
8856            wa,         r"))]
8857   "TARGET_POWERPC64
8858    && (gpc_reg_operand (operands[0], DImode)
8859        || gpc_reg_operand (operands[1], DImode))"
8860   "@
8861    std%U0%X0 %1,%0
8862    ld%U1%X1 %0,%1
8863    mr %0,%1
8864    li %0,%1
8865    lis %0,%v1
8866    li %0,%1
8867    #
8868    stfd%U0%X0 %1,%0
8869    lfd%U1%X1 %0,%1
8870    fmr %0,%1
8871    stxsd %1,%0
8872    stxsdx %x1,%y0
8873    lxsd %0,%1
8874    lxsdx %x0,%y1
8875    xxlor %x0,%x1,%x1
8876    xxspltib %x0,0
8877    xxspltib %x0,255
8878    #
8879    xxlxor %x0,%x0,%x0
8880    xxlorc %x0,%x0,%x0
8881    #
8882    #
8883    mf%1 %0
8884    mt%0 %1
8885    nop
8886    mfvsrd %0,%x1
8887    mtvsrd %x0,%1"
8888   [(set_attr "type"
8889           "store,      load,       *,
8890            *,          *,          *,          *,
8891            fpstore,    fpload,     fpsimple,
8892            fpstore,    fpstore,    fpload,     fpload,     veclogical,
8893            vecsimple,  vecsimple,  vecsimple,  veclogical, veclogical,
8894            vecsimple,  vecsimple,
8895            mfjmpr,     mtjmpr,     *,
8896            mftgpr,     mffgpr")
8897    (set_attr "size" "64")
8898    (set_attr "length"
8899           "*,          *,          *,
8900            *,          *,          *,          20,
8901            *,          *,          *,
8902            *,          *,          *,          *,          *,
8903            *,          *,          *,          *,          *,
8904            8,          *,
8905            *,          *,          *,
8906            *,          *")
8907    (set_attr "isa"
8908           "*,          *,          *,
8909            *,          *,          fut,        *,
8910            *,          *,          *,
8911            p9v,        p7v,        p9v,        p7v,        *,
8912            p9v,        p9v,        p7v,        *,          *,
8913            p7v,        p7v,
8914            *,          *,          *,
8915            p8v,        p8v")])
8917 ; Some DImode loads are best done as a load of -1 followed by a mask
8918 ; instruction.
8919 (define_split
8920   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8921         (match_operand:DI 1 "const_int_operand"))]
8922   "TARGET_POWERPC64
8923    && num_insns_constant (operands[1], DImode) > 1
8924    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8925    && rs6000_is_valid_and_mask (operands[1], DImode)"
8926   [(set (match_dup 0)
8927         (const_int -1))
8928    (set (match_dup 0)
8929         (and:DI (match_dup 0)
8930                 (match_dup 1)))]
8931   "")
8933 ;; Split a load of a large constant into the appropriate five-instruction
8934 ;; sequence.  Handle anything in a constant number of insns.
8935 ;; When non-easy constants can go in the TOC, this should use
8936 ;; easy_fp_constant predicate.
8937 (define_split
8938   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8939         (match_operand:DI 1 "const_int_operand"))]
8940   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8941   [(set (match_dup 0) (match_dup 2))
8942    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8944   if (rs6000_emit_set_const (operands[0], operands[1]))
8945     DONE;
8946   else
8947     FAIL;
8950 (define_split
8951   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8952         (match_operand:DI 1 "const_scalar_int_operand"))]
8953   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8954   [(set (match_dup 0) (match_dup 2))
8955    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8957   if (rs6000_emit_set_const (operands[0], operands[1]))
8958     DONE;
8959   else
8960     FAIL;
8963 (define_split
8964   [(set (match_operand:DI 0 "altivec_register_operand")
8965         (match_operand:DI 1 "s5bit_cint_operand"))]
8966   "TARGET_VSX && reload_completed"
8967   [(const_int 0)]
8969   rtx op0 = operands[0];
8970   rtx op1 = operands[1];
8971   int r = REGNO (op0);
8972   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8974   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8975   if (op1 != const0_rtx && op1 != constm1_rtx)
8976     {
8977       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8978       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8979     }
8980   DONE;
8983 ;; Split integer constants that can be loaded with XXSPLTIB and a
8984 ;; sign extend operation.
8985 (define_split
8986   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8987         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8988   "TARGET_P9_VECTOR && reload_completed"
8989   [(const_int 0)]
8991   rtx op0 = operands[0];
8992   rtx op1 = operands[1];
8993   int r = REGNO (op0);
8994   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8996   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8997   if (<MODE>mode == DImode)
8998     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8999   else if (<MODE>mode == SImode)
9000     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9001   else if (<MODE>mode == HImode)
9002     {
9003       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9004       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9005     }
9006   DONE;
9010 ;; TImode/PTImode is similar, except that we usually want to compute the
9011 ;; address into a register and use lsi/stsi (the exception is during reload).
9013 (define_insn "*mov<mode>_string"
9014   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9015         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9016   "! TARGET_POWERPC64
9017    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9018    && (gpc_reg_operand (operands[0], <MODE>mode)
9019        || gpc_reg_operand (operands[1], <MODE>mode))"
9020   "#"
9021   [(set_attr "type" "store,store,load,load,*,*")
9022    (set_attr "update" "yes")
9023    (set_attr "indexed" "yes")
9024    (set_attr "cell_micro" "conditional")])
9026 (define_insn "*mov<mode>_ppc64"
9027   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9028         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9029   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9030    && (gpc_reg_operand (operands[0], <MODE>mode)
9031        || gpc_reg_operand (operands[1], <MODE>mode)))"
9033   return rs6000_output_move_128bit (operands);
9035   [(set_attr "type" "store,store,load,load,*,*")
9036    (set_attr "length" "8")
9037    (set_attr "max_prefixed_insns" "2")])
9039 (define_split
9040   [(set (match_operand:TI2 0 "int_reg_operand")
9041         (match_operand:TI2 1 "const_scalar_int_operand"))]
9042   "TARGET_POWERPC64
9043    && (VECTOR_MEM_NONE_P (<MODE>mode)
9044        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9045   [(set (match_dup 2) (match_dup 4))
9046    (set (match_dup 3) (match_dup 5))]
9048   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9049                                        <MODE>mode);
9050   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9051                                        <MODE>mode);
9052   if (CONST_WIDE_INT_P (operands[1]))
9053     {
9054       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9055       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9056     }
9057   else if (CONST_INT_P (operands[1]))
9058     {
9059       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9060       operands[5] = operands[1];
9061     }
9062   else
9063     FAIL;
9066 (define_split
9067   [(set (match_operand:TI2 0 "nonimmediate_operand")
9068         (match_operand:TI2 1 "input_operand"))]
9069   "reload_completed
9070    && gpr_or_gpr_p (operands[0], operands[1])
9071    && !direct_move_p (operands[0], operands[1])
9072    && !quad_load_store_p (operands[0], operands[1])"
9073   [(pc)]
9075   rs6000_split_multireg_move (operands[0], operands[1]);
9076   DONE;
9079 (define_expand "setmemsi"
9080   [(parallel [(set (match_operand:BLK 0 "")
9081                    (match_operand 2 "const_int_operand"))
9082               (use (match_operand:SI 1 ""))
9083               (use (match_operand:SI 3 ""))])]
9084   ""
9086   /* If value to set is not zero, use the library routine.  */
9087   if (operands[2] != const0_rtx)
9088     FAIL;
9090   if (expand_block_clear (operands))
9091     DONE;
9092   else
9093     FAIL;
9096 ;; String compare N insn.
9097 ;; Argument 0 is the target (result)
9098 ;; Argument 1 is the destination
9099 ;; Argument 2 is the source
9100 ;; Argument 3 is the length
9101 ;; Argument 4 is the alignment
9103 (define_expand "cmpstrnsi"
9104   [(parallel [(set (match_operand:SI 0)
9105                (compare:SI (match_operand:BLK 1)
9106                            (match_operand:BLK 2)))
9107               (use (match_operand:SI 3))
9108               (use (match_operand:SI 4))])]
9109   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9111   if (optimize_insn_for_size_p ())
9112     FAIL;
9114   if (expand_strn_compare (operands, 0))
9115     DONE;
9116   else  
9117     FAIL;
9120 ;; String compare insn.
9121 ;; Argument 0 is the target (result)
9122 ;; Argument 1 is the destination
9123 ;; Argument 2 is the source
9124 ;; Argument 3 is the alignment
9126 (define_expand "cmpstrsi"
9127   [(parallel [(set (match_operand:SI 0)
9128                (compare:SI (match_operand:BLK 1)
9129                            (match_operand:BLK 2)))
9130               (use (match_operand:SI 3))])]
9131   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9133   if (optimize_insn_for_size_p ())
9134     FAIL;
9136   if (expand_strn_compare (operands, 1))
9137     DONE;
9138   else  
9139     FAIL;
9142 ;; Block compare insn.
9143 ;; Argument 0 is the target (result)
9144 ;; Argument 1 is the destination
9145 ;; Argument 2 is the source
9146 ;; Argument 3 is the length
9147 ;; Argument 4 is the alignment
9149 (define_expand "cmpmemsi"
9150   [(parallel [(set (match_operand:SI 0)
9151                (compare:SI (match_operand:BLK 1)
9152                            (match_operand:BLK 2)))
9153               (use (match_operand:SI 3))
9154               (use (match_operand:SI 4))])]
9155   "TARGET_POPCNTD"
9157   if (expand_block_compare (operands))
9158     DONE;
9159   else
9160     FAIL;
9163 ;; String/block copy insn (source and destination must not overlap).
9164 ;; Argument 0 is the destination
9165 ;; Argument 1 is the source
9166 ;; Argument 2 is the length
9167 ;; Argument 3 is the alignment
9169 (define_expand "cpymemsi"
9170   [(parallel [(set (match_operand:BLK 0 "")
9171                    (match_operand:BLK 1 ""))
9172               (use (match_operand:SI 2 ""))
9173               (use (match_operand:SI 3 ""))])]
9174   ""
9176   if (expand_block_move (operands, false))
9177     DONE;
9178   else
9179     FAIL;
9182 ;; String/block move insn (source and destination may overlap).
9183 ;; Argument 0 is the destination
9184 ;; Argument 1 is the source
9185 ;; Argument 2 is the length
9186 ;; Argument 3 is the alignment
9188 (define_expand "movmemsi"
9189   [(parallel [(set (match_operand:BLK 0 "")
9190                    (match_operand:BLK 1 ""))
9191               (use (match_operand:SI 2 ""))
9192               (use (match_operand:SI 3 ""))])]
9193   ""
9195   if (expand_block_move (operands, true))
9196     DONE;
9197   else
9198     FAIL;
9202 ;; Define insns that do load or store with update.  Some of these we can
9203 ;; get by using pre-decrement or pre-increment, but the hardware can also
9204 ;; do cases where the increment is not the size of the object.
9206 ;; In all these cases, we use operands 0 and 1 for the register being
9207 ;; incremented because those are the operands that local-alloc will
9208 ;; tie and these are the pair most likely to be tieable (and the ones
9209 ;; that will benefit the most).
9211 (define_insn "*movdi_update1"
9212   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9213         (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9214                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9215    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9216         (plus:P (match_dup 1) (match_dup 2)))]
9217   "TARGET_POWERPC64 && TARGET_UPDATE
9218    && (!avoiding_indexed_address_p (DImode)
9219        || !gpc_reg_operand (operands[2], Pmode))"
9220   "@
9221    ldux %3,%0,%2
9222    ldu %3,%2(%0)"
9223   [(set_attr "type" "load")
9224    (set_attr "update" "yes")
9225    (set_attr "indexed" "yes,no")])
9227 (define_insn "movdi_<mode>_update"
9228   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9229                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9230         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9231    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9232         (plus:P (match_dup 1) (match_dup 2)))]
9233   "TARGET_POWERPC64 && TARGET_UPDATE
9234    && (!avoiding_indexed_address_p (DImode)
9235        || !gpc_reg_operand (operands[2], Pmode)
9236        || (REG_P (operands[0])
9237            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9238   "@
9239    stdux %3,%0,%2
9240    stdu %3,%2(%0)"
9241   [(set_attr "type" "store")
9242    (set_attr "update" "yes")
9243    (set_attr "indexed" "yes,no")])
9245 ;; This pattern is only conditional on TARGET_64BIT, as it is
9246 ;; needed for stack allocation, even if the user passes -mno-update.
9247 (define_insn "movdi_update_stack"
9248   [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9249                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9250         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9251    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9252         (plus:DI (match_dup 1) (match_dup 2)))]
9253   "TARGET_64BIT"
9254   "@
9255    stdux %3,%0,%2
9256    stdu %3,%2(%0)"
9257   [(set_attr "type" "store")
9258    (set_attr "update" "yes")
9259    (set_attr "indexed" "yes,no")])
9261 (define_insn "*movsi_update1"
9262   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9263         (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9264                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9265    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9266         (plus:P (match_dup 1) (match_dup 2)))]
9267   "TARGET_UPDATE
9268    && (!avoiding_indexed_address_p (SImode)
9269        || !gpc_reg_operand (operands[2], Pmode))"
9270   "@
9271    lwzux %3,%0,%2
9272    lwzu %3,%2(%0)"
9273   [(set_attr "type" "load")
9274    (set_attr "update" "yes")
9275    (set_attr "indexed" "yes,no")])
9277 (define_insn "*movsi_update2"
9278   [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9279         (sign_extend:EXTSI
9280          (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9281                          (match_operand:P 2 "gpc_reg_operand" "r")))))
9282    (set (match_operand:P 0 "gpc_reg_operand" "=b")
9283         (plus:P (match_dup 1) (match_dup 2)))]
9284   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9285   "lwaux %3,%0,%2"
9286   [(set_attr "type" "load")
9287    (set_attr "sign_extend" "yes")
9288    (set_attr "update" "yes")
9289    (set_attr "indexed" "yes")])
9291 (define_insn "movsi_<mode>_update"
9292   [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9293                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9294         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9295    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9296         (plus:P (match_dup 1) (match_dup 2)))]
9297   "TARGET_UPDATE
9298    && (!avoiding_indexed_address_p (SImode)
9299        || !gpc_reg_operand (operands[2], Pmode)
9300        || (REG_P (operands[0])
9301            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9302   "@
9303    stwux %3,%0,%2
9304    stwu %3,%2(%0)"
9305   [(set_attr "type" "store")
9306    (set_attr "update" "yes")
9307    (set_attr "indexed" "yes,no")])
9309 ;; This is an unconditional pattern; needed for stack allocation, even
9310 ;; if the user passes -mno-update.
9311 (define_insn "movsi_update_stack"
9312   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9313                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9314         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9315    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9316         (plus:SI (match_dup 1) (match_dup 2)))]
9317   "TARGET_32BIT"
9318   "@
9319    stwux %3,%0,%2
9320    stwu %3,%2(%0)"
9321   [(set_attr "type" "store")
9322    (set_attr "update" "yes")
9323    (set_attr "indexed" "yes,no")])
9325 (define_insn "*movhi_update1"
9326   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9327         (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9328                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9329    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9330         (plus:P (match_dup 1) (match_dup 2)))]
9331   "TARGET_UPDATE
9332    && (!avoiding_indexed_address_p (HImode)
9333        || !gpc_reg_operand (operands[2], SImode))"
9334   "@
9335    lhzux %3,%0,%2
9336    lhzu %3,%2(%0)"
9337   [(set_attr "type" "load")
9338    (set_attr "update" "yes")
9339    (set_attr "indexed" "yes,no")])
9341 (define_insn "*movhi_update2"
9342   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9343         (zero_extend:EXTHI
9344          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9345                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9346    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9347         (plus:P (match_dup 1) (match_dup 2)))]
9348   "TARGET_UPDATE
9349    && (!avoiding_indexed_address_p (HImode)
9350        || !gpc_reg_operand (operands[2], Pmode))"
9351   "@
9352    lhzux %3,%0,%2
9353    lhzu %3,%2(%0)"
9354   [(set_attr "type" "load")
9355    (set_attr "update" "yes")
9356    (set_attr "indexed" "yes,no")])
9358 (define_insn "*movhi_update3"
9359   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9360         (sign_extend:EXTHI
9361          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9362                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9363    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9364         (plus:P (match_dup 1) (match_dup 2)))]
9365   "TARGET_UPDATE
9366    && !(avoiding_indexed_address_p (HImode)
9367         && gpc_reg_operand (operands[2], Pmode))"
9368   "@
9369    lhaux %3,%0,%2
9370    lhau %3,%2(%0)"
9371   [(set_attr "type" "load")
9372    (set_attr "sign_extend" "yes")
9373    (set_attr "update" "yes")
9374    (set_attr "indexed" "yes,no")])
9376 (define_insn "*movhi_update4"
9377   [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9378                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9379         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9380    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9381         (plus:P (match_dup 1) (match_dup 2)))]
9382   "TARGET_UPDATE
9383    && (!avoiding_indexed_address_p (HImode)
9384        || !gpc_reg_operand (operands[2], Pmode))"
9385   "@
9386    sthux %3,%0,%2
9387    sthu %3,%2(%0)"
9388   [(set_attr "type" "store")
9389    (set_attr "update" "yes")
9390    (set_attr "indexed" "yes,no")])
9392 (define_insn "*movqi_update1"
9393   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9394         (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9395                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9396    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9397         (plus:P (match_dup 1) (match_dup 2)))]
9398   "TARGET_UPDATE
9399    && (!avoiding_indexed_address_p (QImode)
9400        || !gpc_reg_operand (operands[2], Pmode))"
9401   "@
9402    lbzux %3,%0,%2
9403    lbzu %3,%2(%0)"
9404   [(set_attr "type" "load")
9405    (set_attr "update" "yes")
9406    (set_attr "indexed" "yes,no")])
9408 (define_insn "*movqi_update2"
9409   [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9410         (zero_extend:EXTQI
9411          (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9412                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9413    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9414         (plus:P (match_dup 1) (match_dup 2)))]
9415   "TARGET_UPDATE
9416    && (!avoiding_indexed_address_p (QImode)
9417        || !gpc_reg_operand (operands[2], Pmode))"
9418   "@
9419    lbzux %3,%0,%2
9420    lbzu %3,%2(%0)"
9421   [(set_attr "type" "load")
9422    (set_attr "update" "yes")
9423    (set_attr "indexed" "yes,no")])
9425 (define_insn "*movqi_update3"
9426   [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9427                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9428         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9429    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9430         (plus:P (match_dup 1) (match_dup 2)))]
9431   "TARGET_UPDATE
9432    && (!avoiding_indexed_address_p (QImode)
9433        || !gpc_reg_operand (operands[2], Pmode))"
9434   "@
9435    stbux %3,%0,%2
9436    stbu %3,%2(%0)"
9437   [(set_attr "type" "store")
9438    (set_attr "update" "yes")
9439    (set_attr "indexed" "yes,no")])
9441 (define_insn "*mov<SFDF:mode>_update1"
9442   [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9443         (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9444                           (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9445    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9446         (plus:P (match_dup 1) (match_dup 2)))]
9447   "TARGET_HARD_FLOAT && TARGET_UPDATE
9448    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9449        || !gpc_reg_operand (operands[2], Pmode))"
9450   "@
9451    lf<sd>ux %3,%0,%2
9452    lf<sd>u %3,%2(%0)"
9453   [(set_attr "type" "fpload")
9454    (set_attr "update" "yes")
9455    (set_attr "indexed" "yes,no")
9456    (set_attr "size" "<SFDF:bits>")])
9458 (define_insn "*mov<SFDF:mode>_update2"
9459   [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9460                           (match_operand:P 2 "reg_or_short_operand" "r,I")))
9461         (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9462    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9463         (plus:P (match_dup 1) (match_dup 2)))]
9464   "TARGET_HARD_FLOAT && TARGET_UPDATE
9465    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9466        || !gpc_reg_operand (operands[2], Pmode))"
9467   "@
9468    stf<sd>ux %3,%0,%2
9469    stf<sd>u %3,%2(%0)"
9470   [(set_attr "type" "fpstore")
9471    (set_attr "update" "yes")
9472    (set_attr "indexed" "yes,no")
9473    (set_attr "size" "<SFDF:bits>")])
9475 (define_insn "*movsf_update3"
9476   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9477         (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9478                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9479    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9480         (plus:P (match_dup 1) (match_dup 2)))]
9481   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9482    && (!avoiding_indexed_address_p (SFmode)
9483        || !gpc_reg_operand (operands[2], Pmode))"
9484   "@
9485    lwzux %3,%0,%2
9486    lwzu %3,%2(%0)"
9487   [(set_attr "type" "load")
9488    (set_attr "update" "yes")
9489    (set_attr "indexed" "yes,no")])
9491 (define_insn "*movsf_update4"
9492   [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9493                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9494         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9495    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9496         (plus:P (match_dup 1) (match_dup 2)))]
9497   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9498    && (!avoiding_indexed_address_p (SFmode)
9499        || !gpc_reg_operand (operands[2], Pmode))"
9500   "@
9501    stwux %3,%0,%2
9502    stwu %3,%2(%0)"
9503   [(set_attr "type" "store")
9504    (set_attr "update" "yes")
9505    (set_attr "indexed" "yes,no")])
9508 ;; After inserting conditional returns we can sometimes have
9509 ;; unnecessary register moves.  Unfortunately we cannot have a
9510 ;; modeless peephole here, because some single SImode sets have early
9511 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9512 ;; sequences, using get_attr_length here will smash the operands
9513 ;; array.  Neither is there an early_cobbler_p predicate.
9514 ;; Also this optimization interferes with scalars going into
9515 ;; altivec registers (the code does reloading through the FPRs).
9516 (define_peephole2
9517   [(set (match_operand:DF 0 "gpc_reg_operand")
9518         (match_operand:DF 1 "any_operand"))
9519    (set (match_operand:DF 2 "gpc_reg_operand")
9520         (match_dup 0))]
9521   "!TARGET_VSX
9522    && peep2_reg_dead_p (2, operands[0])"
9523   [(set (match_dup 2) (match_dup 1))])
9525 (define_peephole2
9526   [(set (match_operand:SF 0 "gpc_reg_operand")
9527         (match_operand:SF 1 "any_operand"))
9528    (set (match_operand:SF 2 "gpc_reg_operand")
9529         (match_dup 0))]
9530   "!TARGET_P8_VECTOR
9531    && peep2_reg_dead_p (2, operands[0])"
9532   [(set (match_dup 2) (match_dup 1))])
9535 ;; TLS support.
9537 (define_insn "*tls_gd_pcrel<bits>"
9538   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9539         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9540                    (const_int 0)]
9541                   UNSPEC_TLSGD))]
9542   "HAVE_AS_TLS && TARGET_ELF"
9543   "la %0,%1@got@tlsgd@pcrel"
9544   [(set_attr "prefixed" "yes")])
9546 (define_insn_and_split "*tls_gd<bits>"
9547   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9548         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9549                    (match_operand:P 2 "gpc_reg_operand" "b")]
9550                   UNSPEC_TLSGD))]
9551   "HAVE_AS_TLS && TARGET_ELF"
9552   "addi %0,%2,%1@got@tlsgd"
9553   "&& TARGET_CMODEL != CMODEL_SMALL"
9554   [(set (match_dup 3)
9555         (high:P
9556             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9557    (set (match_dup 0)
9558         (lo_sum:P (match_dup 3)
9559             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9561   operands[3] = gen_reg_rtx (<MODE>mode);
9563   [(set (attr "length")
9564      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9565                    (const_int 8)
9566                    (const_int 4)))])
9568 (define_insn "*tls_gd_high<bits>"
9569   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9570      (high:P
9571        (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9572                   (match_operand:P 2 "gpc_reg_operand" "b")]
9573                  UNSPEC_TLSGD)))]
9574   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9575   "addis %0,%2,%1@got@tlsgd@ha")
9577 (define_insn "*tls_gd_low<bits>"
9578   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9579      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9580        (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9581                   (match_operand:P 3 "gpc_reg_operand" "b")]
9582                  UNSPEC_TLSGD)))]
9583   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9584   "addi %0,%1,%2@got@tlsgd@l")
9586 (define_insn "*tls_ld_pcrel<bits>"
9587   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9588         (unspec:P [(const_int 0)]
9589                   UNSPEC_TLSLD))]
9590   "HAVE_AS_TLS && TARGET_ELF"
9591   "la %0,%&@got@tlsld@pcrel"
9592   [(set_attr "prefixed" "yes")])
9594 (define_insn_and_split "*tls_ld<bits>"
9595   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9596         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9597                   UNSPEC_TLSLD))]
9598   "HAVE_AS_TLS && TARGET_ELF"
9599   "addi %0,%1,%&@got@tlsld"
9600   "&& TARGET_CMODEL != CMODEL_SMALL"
9601   [(set (match_dup 2)
9602         (high:P
9603             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9604    (set (match_dup 0)
9605         (lo_sum:P (match_dup 2)
9606             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9608   operands[2] = gen_reg_rtx (<MODE>mode);
9610   [(set (attr "length")
9611      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9612                    (const_int 8)
9613                    (const_int 4)))])
9615 (define_insn "*tls_ld_high<bits>"
9616   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9617      (high:P
9618        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9619                  UNSPEC_TLSLD)))]
9620   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9621   "addis %0,%1,%&@got@tlsld@ha")
9623 (define_insn "*tls_ld_low<bits>"
9624   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9625      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9626        (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9627                  UNSPEC_TLSLD)))]
9628   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9629   "addi %0,%1,%&@got@tlsld@l")
9631 (define_insn "tls_dtprel_<bits>"
9632   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9633         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9634                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9635                   UNSPEC_TLSDTPREL))]
9636   "HAVE_AS_TLS"
9637   "addi %0,%1,%2@dtprel"
9638   [(set (attr "prefixed")
9639         (if_then_else (match_test "rs6000_tls_size == 16")
9640                       (const_string "no")
9641                       (const_string "yes")))])
9643 (define_insn "tls_dtprel_ha_<bits>"
9644   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9645         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9646                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9647                   UNSPEC_TLSDTPRELHA))]
9648   "HAVE_AS_TLS"
9649   "addis %0,%1,%2@dtprel@ha")
9651 (define_insn "tls_dtprel_lo_<bits>"
9652   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9653         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9654                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9655                   UNSPEC_TLSDTPRELLO))]
9656   "HAVE_AS_TLS"
9657   "addi %0,%1,%2@dtprel@l")
9659 (define_insn_and_split "tls_got_dtprel_<bits>"
9660   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9661         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9662                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9663                   UNSPEC_TLSGOTDTPREL))]
9664   "HAVE_AS_TLS"
9665   "<ptrload> %0,%2@got@dtprel(%1)"
9666   "&& TARGET_CMODEL != CMODEL_SMALL"
9667   [(set (match_dup 3)
9668         (high:P
9669             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9670    (set (match_dup 0)
9671         (lo_sum:P (match_dup 3)
9672             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9674   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9676   [(set (attr "length")
9677      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9678                    (const_int 8)
9679                    (const_int 4)))])
9681 (define_insn "*tls_got_dtprel_high<bits>"
9682   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9683      (high:P
9684        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9685                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9686                  UNSPEC_TLSGOTDTPREL)))]
9687   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9688   "addis %0,%1,%2@got@dtprel@ha")
9690 (define_insn "*tls_got_dtprel_low<bits>"
9691   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9692      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9693          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9694                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9695                    UNSPEC_TLSGOTDTPREL)))]
9696   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9697   "<ptrload> %0,%2@got@dtprel@l(%1)")
9699 (define_insn "tls_tprel_<bits>"
9700   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9701         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9702                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9703                   UNSPEC_TLSTPREL))]
9704   "HAVE_AS_TLS"
9705   "addi %0,%1,%2@tprel"
9706   [(set (attr "prefixed")
9707         (if_then_else (match_test "rs6000_tls_size == 16")
9708                       (const_string "no")
9709                       (const_string "yes")))])
9711 (define_insn "tls_tprel_ha_<bits>"
9712   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9713         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9714                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9715                   UNSPEC_TLSTPRELHA))]
9716   "HAVE_AS_TLS"
9717   "addis %0,%1,%2@tprel@ha")
9719 (define_insn "tls_tprel_lo_<bits>"
9720   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9721         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9722                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9723                   UNSPEC_TLSTPRELLO))]
9724   "HAVE_AS_TLS"
9725   "addi %0,%1,%2@tprel@l")
9727 (define_insn "*tls_got_tprel_pcrel_<bits>"
9728   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9729         (unspec:P [(const_int 0)
9730                    (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9731                   UNSPEC_TLSGOTTPREL))]
9732   "HAVE_AS_TLS"
9733   "<ptrload> %0,%1@got@tprel@pcrel"
9734   [(set_attr "prefixed" "yes")])
9736 ;; "b" output constraint here and on tls_tls input to support linker tls
9737 ;; optimization.  The linker may edit the instructions emitted by a
9738 ;; tls_got_tprel/tls_tls pair to addis,addi.
9739 (define_insn_and_split "tls_got_tprel_<bits>"
9740   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9741         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9742                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9743                   UNSPEC_TLSGOTTPREL))]
9744   "HAVE_AS_TLS"
9745   "<ptrload> %0,%2@got@tprel(%1)"
9746   "&& TARGET_CMODEL != CMODEL_SMALL"
9747   [(set (match_dup 3)
9748         (high:P
9749             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9750    (set (match_dup 0)
9751         (lo_sum:P (match_dup 3)
9752             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9754   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9756   [(set (attr "length")
9757      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9758                    (const_int 8)
9759                    (const_int 4)))])
9761 (define_insn "*tls_got_tprel_high<bits>"
9762   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9763      (high:P
9764        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9765                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9766                  UNSPEC_TLSGOTTPREL)))]
9767   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9768   "addis %0,%1,%2@got@tprel@ha")
9770 (define_insn "*tls_got_tprel_low<bits>"
9771   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9772      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9773          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9774                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9775                    UNSPEC_TLSGOTTPREL)))]
9776   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9777   "<ptrload> %0,%2@got@tprel@l(%1)")
9779 (define_insn "tls_tls_pcrel_<bits>"
9780   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9781         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9782                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9783                   UNSPEC_TLSTLS_PCREL))]
9784   "TARGET_ELF && HAVE_AS_TLS"
9785   "add %0,%1,%2@tls@pcrel")
9787 (define_insn "tls_tls_<bits>"
9788   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9789         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9790                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9791                   UNSPEC_TLSTLS))]
9792   "TARGET_ELF && HAVE_AS_TLS"
9793   "add %0,%1,%2@tls")
9795 (define_expand "tls_get_tpointer"
9796   [(set (match_operand:SI 0 "gpc_reg_operand")
9797         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9798   "TARGET_XCOFF && HAVE_AS_TLS"
9800   emit_insn (gen_tls_get_tpointer_internal ());
9801   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9802   DONE;
9805 (define_insn "tls_get_tpointer_internal"
9806   [(set (reg:SI 3)
9807         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9808    (clobber (reg:SI LR_REGNO))]
9809   "TARGET_XCOFF && HAVE_AS_TLS"
9810   "bla __get_tpointer")
9812 (define_expand "tls_get_addr<mode>"
9813   [(set (match_operand:P 0 "gpc_reg_operand")
9814         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9815                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9816   "TARGET_XCOFF && HAVE_AS_TLS"
9818   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9819   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9820   emit_insn (gen_tls_get_addr_internal<mode> ());
9821   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9822   DONE;
9825 (define_insn "tls_get_addr_internal<mode>"
9826   [(set (reg:P 3)
9827         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9828    (clobber (reg:P 0))
9829    (clobber (reg:P 4))
9830    (clobber (reg:P 5))
9831    (clobber (reg:P 11))
9832    (clobber (reg:CC CR0_REGNO))
9833    (clobber (reg:P LR_REGNO))]
9834   "TARGET_XCOFF && HAVE_AS_TLS"
9835   "bla __tls_get_addr")
9837 ;; Next come insns related to the calling sequence.
9839 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9840 ;; We move the back-chain and decrement the stack pointer.
9842 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9843 ;; constant alloca, using that predicate will force the generic code to put
9844 ;; the constant size into a register before calling the expander.
9846 ;; As a result the expander would not have the constant size information
9847 ;; in those cases and would have to generate less efficient code.
9849 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9850 ;; the constant size.  The value is forced into a register if necessary.
9852 (define_expand "allocate_stack"
9853   [(set (match_operand 0 "gpc_reg_operand")
9854         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9855    (set (reg 1)
9856         (minus (reg 1) (match_dup 1)))]
9857   ""
9859   rtx chain = gen_reg_rtx (Pmode);
9860   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9861   rtx neg_op0;
9862   rtx insn, par, set, mem;
9864   /* By allowing reg_or_cint_operand as the predicate we can get
9865      better code for stack-clash-protection because we do not lose
9866      size information.  But the rest of the code expects the operand
9867      to be reg_or_short_operand.  If it isn't, then force it into
9868      a register.  */
9869   rtx orig_op1 = operands[1];
9870   if (!reg_or_short_operand (operands[1], Pmode))
9871     operands[1] = force_reg (Pmode, operands[1]);
9873   emit_move_insn (chain, stack_bot);
9875   /* Check stack bounds if necessary.  */
9876   if (crtl->limit_stack)
9877     {
9878       rtx available;
9879       available = expand_binop (Pmode, sub_optab,
9880                                 stack_pointer_rtx, stack_limit_rtx,
9881                                 NULL_RTX, 1, OPTAB_WIDEN);
9882       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9883     }
9885   /* Allocate and probe if requested.
9886      This may look similar to the loop we use for prologue allocations,
9887      but it is critically different.  For the former we know the loop
9888      will iterate, but do not know that generally here.  The former
9889      uses that knowledge to rotate the loop.  Combining them would be
9890      possible with some performance cost.  */
9891   if (flag_stack_clash_protection)
9892     {
9893       rtx rounded_size, last_addr, residual;
9894       HOST_WIDE_INT probe_interval;
9895       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9896                                                 &residual, &probe_interval,
9897                                                 orig_op1);
9898       
9899       /* We do occasionally get in here with constant sizes, we might
9900          as well do a reasonable job when we obviously can.  */
9901       if (rounded_size != const0_rtx)
9902         {
9903           rtx loop_lab, end_loop;
9904           bool rotated = CONST_INT_P (rounded_size);
9905           rtx update = GEN_INT (-probe_interval);
9906           if (probe_interval > 32768)
9907             update = force_reg (Pmode, update);
9909           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9910                                                         last_addr, rotated);
9912           if (TARGET_32BIT)
9913             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9914                                                stack_pointer_rtx,
9915                                                update, chain));
9916           else
9917             emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9918                                                stack_pointer_rtx,
9919                                                update, chain));
9920           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9921                                                       last_addr, rotated);
9922         }
9924       /* Now handle residuals.  We just have to set operands[1] correctly
9925          and let the rest of the expander run.  */
9926       operands[1] = residual;
9927     }
9929   if (!(CONST_INT_P (operands[1])
9930         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9931     {
9932       operands[1] = force_reg (Pmode, operands[1]);
9933       neg_op0 = gen_reg_rtx (Pmode);
9934       emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9935     }
9936   else
9937     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9939   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9940                                        : gen_movdi_update_stack))
9941                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9942                          chain));
9943   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9944      it now and set the alias set/attributes. The above gen_*_update
9945      calls will generate a PARALLEL with the MEM set being the first
9946      operation. */
9947   par = PATTERN (insn);
9948   gcc_assert (GET_CODE (par) == PARALLEL);
9949   set = XVECEXP (par, 0, 0);
9950   gcc_assert (GET_CODE (set) == SET);
9951   mem = SET_DEST (set);
9952   gcc_assert (MEM_P (mem));
9953   MEM_NOTRAP_P (mem) = 1;
9954   set_mem_alias_set (mem, get_frame_alias_set ());
9956   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9957   DONE;
9960 ;; These patterns say how to save and restore the stack pointer.  We need not
9961 ;; save the stack pointer at function level since we are careful to
9962 ;; preserve the backchain.  At block level, we have to restore the backchain
9963 ;; when we restore the stack pointer.
9965 ;; For nonlocal gotos, we must save both the stack pointer and its
9966 ;; backchain and restore both.  Note that in the nonlocal case, the
9967 ;; save area is a memory location.
9969 (define_expand "save_stack_function"
9970   [(match_operand 0 "any_operand")
9971    (match_operand 1 "any_operand")]
9972   ""
9973   "DONE;")
9975 (define_expand "restore_stack_function"
9976   [(match_operand 0 "any_operand")
9977    (match_operand 1 "any_operand")]
9978   ""
9979   "DONE;")
9981 ;; Adjust stack pointer (op0) to a new value (op1).
9982 ;; First copy old stack backchain to new location, and ensure that the
9983 ;; scheduler won't reorder the sp assignment before the backchain write.
9984 (define_expand "restore_stack_block"
9985   [(set (match_dup 2) (match_dup 3))
9986    (set (match_dup 4) (match_dup 2))
9987    (match_dup 5)
9988    (set (match_operand 0 "register_operand")
9989         (match_operand 1 "register_operand"))]
9990   ""
9992   rtvec p;
9994   operands[1] = force_reg (Pmode, operands[1]);
9995   operands[2] = gen_reg_rtx (Pmode);
9996   operands[3] = gen_frame_mem (Pmode, operands[0]);
9997   operands[4] = gen_frame_mem (Pmode, operands[1]);
9998   p = rtvec_alloc (1);
9999   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10000                                   const0_rtx);
10001   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10004 (define_expand "save_stack_nonlocal"
10005   [(set (match_dup 3) (match_dup 4))
10006    (set (match_operand 0 "memory_operand") (match_dup 3))
10007    (set (match_dup 2) (match_operand 1 "register_operand"))]
10008   ""
10010   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10012   /* Copy the backchain to the first word, sp to the second.  */
10013   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10014   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10015   operands[3] = gen_reg_rtx (Pmode);
10016   operands[4] = gen_frame_mem (Pmode, operands[1]);
10019 (define_expand "restore_stack_nonlocal"
10020   [(set (match_dup 2) (match_operand 1 "memory_operand"))
10021    (set (match_dup 3) (match_dup 4))
10022    (set (match_dup 5) (match_dup 2))
10023    (match_dup 6)
10024    (set (match_operand 0 "register_operand") (match_dup 3))]
10025   ""
10027   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10028   rtvec p;
10030   /* Restore the backchain from the first word, sp from the second.  */
10031   operands[2] = gen_reg_rtx (Pmode);
10032   operands[3] = gen_reg_rtx (Pmode);
10033   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10034   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10035   operands[5] = gen_frame_mem (Pmode, operands[3]);
10036   p = rtvec_alloc (1);
10037   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10038                                   const0_rtx);
10039   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10042 ;; Load up a PC-relative address.  Print_operand_address will append a @pcrel
10043 ;; to the symbol or label.
10044 (define_insn "*pcrel_local_addr"
10045   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10046         (match_operand:DI 1 "pcrel_local_address"))]
10047   "TARGET_PCREL"
10048   "la %0,%a1"
10049   [(set_attr "prefixed" "yes")])
10051 ;; Load up a PC-relative address to an external symbol.  If the symbol and the
10052 ;; program are both defined in the main program, the linker will optimize this
10053 ;; to a PADDI.  Otherwise, it will create a GOT address that is relocated by
10054 ;; the dynamic linker and loaded up.  Print_operand_address will append a
10055 ;; @got@pcrel to the symbol.
10056 (define_insn "*pcrel_extern_addr"
10057   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10058         (match_operand:DI 1 "pcrel_external_address"))]
10059   "TARGET_PCREL"
10060   "ld %0,%a1"
10061   [(set_attr "prefixed" "yes")
10062    (set_attr "type" "load")])
10064 ;; TOC register handling.
10066 ;; Code to initialize the TOC register...
10068 (define_insn "load_toc_aix_si"
10069   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10070                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10071               (use (reg:SI 2))])]
10072   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10074   char buf[30];
10075   extern int need_toc_init;
10076   need_toc_init = 1;
10077   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10078   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10079   operands[2] = gen_rtx_REG (Pmode, 2);
10080   return "lwz %0,%1(%2)";
10082   [(set_attr "type" "load")
10083    (set_attr "update" "no")
10084    (set_attr "indexed" "no")])
10086 (define_insn "load_toc_aix_di"
10087   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10088                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10089               (use (reg:DI 2))])]
10090   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10092   char buf[30];
10093   extern int need_toc_init;
10094   need_toc_init = 1;
10095   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10096                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10097   if (TARGET_ELF)
10098     strcat (buf, "@toc");
10099   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10100   operands[2] = gen_rtx_REG (Pmode, 2);
10101   return "ld %0,%1(%2)";
10103   [(set_attr "type" "load")
10104    (set_attr "update" "no")
10105    (set_attr "indexed" "no")])
10107 (define_insn "load_toc_v4_pic_si"
10108   [(set (reg:SI LR_REGNO)
10109         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10110   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10111   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10112   [(set_attr "type" "branch")])
10114 (define_expand "load_toc_v4_PIC_1"
10115   [(parallel [(set (reg:SI LR_REGNO)
10116                    (match_operand:SI 0 "immediate_operand" "s"))
10117               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10118   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10119    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10120   "")
10122 (define_insn "load_toc_v4_PIC_1_normal"
10123   [(set (reg:SI LR_REGNO)
10124         (match_operand:SI 0 "immediate_operand" "s"))
10125    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10126   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10127    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10128   "bcl 20,31,%0\n%0:"
10129   [(set_attr "type" "branch")
10130    (set_attr "cannot_copy" "yes")])
10132 (define_insn "load_toc_v4_PIC_1_476"
10133   [(set (reg:SI LR_REGNO)
10134         (match_operand:SI 0 "immediate_operand" "s"))
10135    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10136   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10137    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10139   char name[32];
10140   static char templ[32];
10142   get_ppc476_thunk_name (name);
10143   sprintf (templ, "bl %s\n%%0:", name);
10144   return templ;
10146   [(set_attr "type" "branch")
10147    (set_attr "cannot_copy" "yes")])
10149 (define_expand "load_toc_v4_PIC_1b"
10150   [(parallel [(set (reg:SI LR_REGNO)
10151                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10152                                (label_ref (match_operand 1 ""))]
10153                            UNSPEC_TOCPTR))
10154               (match_dup 1)])]
10155   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10156   "")
10158 (define_insn "load_toc_v4_PIC_1b_normal"
10159   [(set (reg:SI LR_REGNO)
10160         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10161                     (label_ref (match_operand 1 "" ""))]
10162                 UNSPEC_TOCPTR))
10163    (match_dup 1)]
10164   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10165   "bcl 20,31,$+8\;.long %0-$"
10166   [(set_attr "type" "branch")
10167    (set_attr "length" "8")])
10169 (define_insn "load_toc_v4_PIC_1b_476"
10170   [(set (reg:SI LR_REGNO)
10171         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10172                     (label_ref (match_operand 1 "" ""))]
10173                 UNSPEC_TOCPTR))
10174    (match_dup 1)]
10175   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10177   char name[32];
10178   static char templ[32];
10180   get_ppc476_thunk_name (name);
10181   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10182   return templ;
10184   [(set_attr "type" "branch")
10185    (set_attr "length" "16")])
10187 (define_insn "load_toc_v4_PIC_2"
10188   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10189         (mem:SI (plus:SI
10190                   (match_operand:SI 1 "gpc_reg_operand" "b")
10191                   (const
10192                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10193                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10194   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10195   "lwz %0,%2-%3(%1)"
10196   [(set_attr "type" "load")])
10198 (define_insn "load_toc_v4_PIC_3b"
10199   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10200         (plus:SI
10201           (match_operand:SI 1 "gpc_reg_operand" "b")
10202           (high:SI
10203             (const
10204               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10205                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10206   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10207   "addis %0,%1,%2-%3@ha")
10209 (define_insn "load_toc_v4_PIC_3c"
10210   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10211         (lo_sum:SI
10212           (match_operand:SI 1 "gpc_reg_operand" "b")
10213           (const
10214             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10215                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10216   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10217   "addi %0,%1,%2-%3@l")
10219 ;; If the TOC is shared over a translation unit, as happens with all
10220 ;; the kinds of PIC that we support, we need to restore the TOC
10221 ;; pointer only when jumping over units of translation.
10222 ;; On Darwin, we need to reload the picbase.
10224 (define_expand "builtin_setjmp_receiver"
10225   [(use (label_ref (match_operand 0 "")))]
10226   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10227    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10228    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10230 #if TARGET_MACHO
10231   if (DEFAULT_ABI == ABI_DARWIN)
10232     {
10233       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10234       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10235       rtx tmplabrtx;
10236       char tmplab[20];
10238       crtl->uses_pic_offset_table = 1;
10239       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10240                                   CODE_LABEL_NUMBER (operands[0]));
10241       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10243       emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10244       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10245       emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10246                                         picrtx, tmplabrtx));
10247     }
10248   else
10249 #endif
10250     rs6000_emit_load_toc_table (FALSE);
10251   DONE;
10254 ;; Largetoc support
10255 (define_insn "*largetoc_high"
10256   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10257         (high:DI
10258           (unspec [(match_operand:DI 1 "" "")
10259                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10260                   UNSPEC_TOCREL)))]
10261    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10262    "addis %0,%2,%1@toc@ha")
10264 (define_insn "*largetoc_high_aix<mode>"
10265   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10266         (high:P
10267           (unspec [(match_operand:P 1 "" "")
10268                    (match_operand:P 2 "gpc_reg_operand" "b")]
10269                   UNSPEC_TOCREL)))]
10270    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10271    "addis %0,%1@u(%2)")
10273 (define_insn "*largetoc_high_plus"
10274   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10275         (high:DI
10276           (plus:DI
10277             (unspec [(match_operand:DI 1 "" "")
10278                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10279                     UNSPEC_TOCREL)
10280             (match_operand:DI 3 "add_cint_operand" "n"))))]
10281    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10282    "addis %0,%2,%1+%3@toc@ha")
10284 (define_insn "*largetoc_high_plus_aix<mode>"
10285   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10286         (high:P
10287           (plus:P
10288             (unspec [(match_operand:P 1 "" "")
10289                      (match_operand:P 2 "gpc_reg_operand" "b")]
10290                     UNSPEC_TOCREL)
10291             (match_operand:P 3 "add_cint_operand" "n"))))]
10292    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10293    "addis %0,%1+%3@u(%2)")
10295 (define_insn "*largetoc_low"
10296   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10297         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10298                    (match_operand:DI 2 "" "")))]
10299    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10300    "addi %0,%1,%2@l")
10302 (define_insn "*largetoc_low_aix<mode>"
10303   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10304         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10305                    (match_operand:P 2 "" "")))]
10306    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10307    "la %0,%2@l(%1)")
10309 (define_insn_and_split "*tocref<mode>"
10310   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10311         (match_operand:P 1 "small_toc_ref" "R"))]
10312    "TARGET_TOC"
10313    "la %0,%a1"
10314    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10315   [(set (match_dup 0) (high:P (match_dup 1)))
10316    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10318 ;; Elf specific ways of loading addresses for non-PIC code.
10319 ;; The output of this could be r0, but we make a very strong
10320 ;; preference for a base register because it will usually
10321 ;; be needed there.
10322 (define_insn "elf_high"
10323   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10324         (high:SI (match_operand 1 "" "")))]
10325   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10326   "lis %0,%1@ha")
10328 (define_insn "elf_low"
10329   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10330         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10331                    (match_operand 2 "" "")))]
10332    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10333    "la %0,%2@l(%1)")
10335 (define_insn "*pltseq_tocsave_<mode>"
10336   [(set (match_operand:P 0 "memory_operand" "=m")
10337         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10338                    (match_operand:P 2 "symbol_ref_operand" "s")
10339                    (match_operand:P 3 "" "")]
10340                   UNSPEC_PLTSEQ))]
10341   "TARGET_PLTSEQ
10342    && DEFAULT_ABI == ABI_ELFv2"
10344   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10347 (define_insn "*pltseq_plt16_ha_<mode>"
10348   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10349         (unspec:P [(match_operand:P 1 "" "")
10350                    (match_operand:P 2 "symbol_ref_operand" "s")
10351                    (match_operand:P 3 "" "")]
10352                   UNSPEC_PLT16_HA))]
10353   "TARGET_PLTSEQ"
10355   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10358 (define_insn "*pltseq_plt16_lo_<mode>"
10359   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10360         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10361                    (match_operand:P 2 "symbol_ref_operand" "s")
10362                    (match_operand:P 3 "" "")]
10363                   UNSPEC_PLT16_LO))]
10364   "TARGET_PLTSEQ"
10366   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10368   [(set_attr "type" "load")])
10370 (define_insn "*pltseq_mtctr_<mode>"
10371   [(set (match_operand:P 0 "register_operand" "=c")
10372         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10373                    (match_operand:P 2 "symbol_ref_operand" "s")
10374                    (match_operand:P 3 "" "")]
10375                   UNSPEC_PLTSEQ))]
10376   "TARGET_PLTSEQ"
10378   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10381 (define_insn "*pltseq_plt_pcrel<mode>"
10382   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10383         (unspec:P [(match_operand:P 1 "" "")
10384                    (match_operand:P 2 "symbol_ref_operand" "s")
10385                    (match_operand:P 3 "" "")]
10386                   UNSPEC_PLT_PCREL))]
10387   "HAVE_AS_PLTSEQ && TARGET_ELF
10388    && rs6000_pcrel_p (cfun)"
10390   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10392   [(set_attr "type" "load")
10393    (set_attr "length" "12")])
10395 ;; Call and call_value insns
10396 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10397 (define_expand "call"
10398   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10399                     (match_operand 1 ""))
10400               (use (match_operand 2 ""))
10401               (clobber (reg:SI LR_REGNO))])]
10402   ""
10404 #if TARGET_MACHO
10405   if (MACHOPIC_INDIRECT)
10406     operands[0] = machopic_indirect_call_target (operands[0]);
10407 #endif
10409   gcc_assert (MEM_P (operands[0]));
10411   operands[0] = XEXP (operands[0], 0);
10413   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10414     rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10415   else if (DEFAULT_ABI == ABI_V4)
10416     rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10417   else if (DEFAULT_ABI == ABI_DARWIN)
10418     rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10419   else
10420     gcc_unreachable ();
10422   DONE;
10425 (define_expand "call_value"
10426   [(parallel [(set (match_operand 0 "")
10427                    (call (mem:SI (match_operand 1 "address_operand"))
10428                          (match_operand 2 "")))
10429               (use (match_operand 3 ""))
10430               (clobber (reg:SI LR_REGNO))])]
10431   ""
10433 #if TARGET_MACHO
10434   if (MACHOPIC_INDIRECT)
10435     operands[1] = machopic_indirect_call_target (operands[1]);
10436 #endif
10438   gcc_assert (MEM_P (operands[1]));
10440   operands[1] = XEXP (operands[1], 0);
10442   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10443     rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10444   else if (DEFAULT_ABI == ABI_V4)
10445     rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10446   else if (DEFAULT_ABI == ABI_DARWIN)
10447     rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10448   else
10449     gcc_unreachable ();
10451   DONE;
10454 ;; Call to function in current module.  No TOC pointer reload needed.
10455 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10456 ;; either the function was not prototyped, or it was prototyped as a
10457 ;; variable argument function.  It is > 0 if FP registers were passed
10458 ;; and < 0 if they were not.
10460 (define_insn "*call_local32"
10461   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10462          (match_operand 1))
10463    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10464    (clobber (reg:SI LR_REGNO))]
10465   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10467   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10468     output_asm_insn ("crxor 6,6,6", operands);
10470   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10471     output_asm_insn ("creqv 6,6,6", operands);
10473   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10475   [(set_attr "type" "branch")
10476    (set_attr "length" "4,8")])
10478 (define_insn "*call_local64"
10479   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10480          (match_operand 1))
10481    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10482    (clobber (reg:DI LR_REGNO))]
10483   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10485   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10486     output_asm_insn ("crxor 6,6,6", operands);
10488   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10489     output_asm_insn ("creqv 6,6,6", operands);
10491   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10493   [(set_attr "type" "branch")
10494    (set_attr "length" "4,8")])
10496 (define_insn "*call_value_local32"
10497   [(set (match_operand 0 "" "")
10498         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10499               (match_operand 2)))
10500    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10501    (clobber (reg:SI LR_REGNO))]
10502   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10504   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10505     output_asm_insn ("crxor 6,6,6", operands);
10507   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10508     output_asm_insn ("creqv 6,6,6", operands);
10510   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10512   [(set_attr "type" "branch")
10513    (set_attr "length" "4,8")])
10516 (define_insn "*call_value_local64"
10517   [(set (match_operand 0 "" "")
10518         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10519               (match_operand 2)))
10520    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10521    (clobber (reg:DI LR_REGNO))]
10522   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10524   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10525     output_asm_insn ("crxor 6,6,6", operands);
10527   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10528     output_asm_insn ("creqv 6,6,6", operands);
10530   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10532   [(set_attr "type" "branch")
10533    (set_attr "length" "4,8")])
10536 ;; A function pointer under System V is just a normal pointer
10537 ;; operands[0] is the function pointer
10538 ;; operands[1] is the tls call arg
10539 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10540 ;; which indicates how to set cr1
10542 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10543   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10544          (match_operand 1))
10545    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10546    (clobber (reg:P LR_REGNO))]
10547   "DEFAULT_ABI == ABI_V4
10548    || DEFAULT_ABI == ABI_DARWIN"
10550   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10551     output_asm_insn ("crxor 6,6,6", operands);
10553   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10554     output_asm_insn ("creqv 6,6,6", operands);
10556   return rs6000_indirect_call_template (operands, 0);
10558   [(set_attr "type" "jmpreg")
10559    (set (attr "length")
10560         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10561                          (match_test "which_alternative != 1"))
10562                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10563                   (const_string "12")
10564                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10565                          (match_test "which_alternative != 1"))
10566                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10567                   (const_string "8")]
10568               (const_string "4")))])
10570 (define_insn "*call_nonlocal_sysv<mode>"
10571   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10572          (match_operand 1))
10573    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10574    (clobber (reg:P LR_REGNO))]
10575   "(DEFAULT_ABI == ABI_DARWIN
10576    || (DEFAULT_ABI == ABI_V4
10577        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10579   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10580     output_asm_insn ("crxor 6,6,6", operands);
10582   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10583     output_asm_insn ("creqv 6,6,6", operands);
10585   return rs6000_call_template (operands, 0);
10587   [(set_attr "type" "branch,branch")
10588    (set_attr "length" "4,8")])
10590 (define_insn "*call_nonlocal_sysv_secure<mode>"
10591   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10592          (match_operand 1))
10593    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10594    (use (match_operand:SI 3 "register_operand" "r,r"))
10595    (clobber (reg:P LR_REGNO))]
10596   "(DEFAULT_ABI == ABI_V4
10597     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10598     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10600   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10601     output_asm_insn ("crxor 6,6,6", operands);
10603   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10604     output_asm_insn ("creqv 6,6,6", operands);
10606   return rs6000_call_template (operands, 0);
10608   [(set_attr "type" "branch,branch")
10609    (set_attr "length" "4,8")])
10611 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10612   [(set (match_operand 0 "" "")
10613         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10614               (match_operand:P 2 "unspec_tls" "")))
10615    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10616    (clobber (reg:P LR_REGNO))]
10617   "DEFAULT_ABI == ABI_V4
10618    || DEFAULT_ABI == ABI_DARWIN"
10620   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10621     output_asm_insn ("crxor 6,6,6", operands);
10623   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10624     output_asm_insn ("creqv 6,6,6", operands);
10626   return rs6000_indirect_call_template (operands, 1);
10628   [(set_attr "type" "jmpreg")
10629    (set (attr "length")
10630         (plus
10631           (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10632             (const_int 4)
10633             (const_int 0))
10634           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10635                              (match_test "which_alternative != 1"))
10636             (const_int 8)
10637             (const_int 4))))])
10639 (define_insn "*call_value_nonlocal_sysv<mode>"
10640   [(set (match_operand 0 "" "")
10641         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10642               (match_operand:P 2 "unspec_tls" "")))
10643    (use (match_operand:SI 3 "immediate_operand" "n"))
10644    (clobber (reg:P LR_REGNO))]
10645   "(DEFAULT_ABI == ABI_DARWIN
10646     || (DEFAULT_ABI == ABI_V4
10647         && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10649   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10650     output_asm_insn ("crxor 6,6,6", operands);
10652   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10653     output_asm_insn ("creqv 6,6,6", operands);
10655   return rs6000_call_template (operands, 1);
10657   [(set_attr "type" "branch")
10658    (set (attr "length")
10659         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10660           (const_int 8)
10661           (const_int 4)))])
10663 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10664   [(set (match_operand 0 "" "")
10665         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10666               (match_operand:P 2 "unspec_tls" "")))
10667    (use (match_operand:SI 3 "immediate_operand" "n"))
10668    (use (match_operand:SI 4 "register_operand" "r"))
10669    (clobber (reg:P LR_REGNO))]
10670   "(DEFAULT_ABI == ABI_V4
10671     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10672     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10674   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10675     output_asm_insn ("crxor 6,6,6", operands);
10677   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10678     output_asm_insn ("creqv 6,6,6", operands);
10680   return rs6000_call_template (operands, 1);
10682   [(set_attr "type" "branch")
10683    (set (attr "length")
10684         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10685           (const_int 8)
10686           (const_int 4)))])
10688 ;; Call to AIX abi function in the same module.
10690 (define_insn "*call_local_aix<mode>"
10691   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10692          (match_operand 1))
10693    (clobber (reg:P LR_REGNO))]
10694   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10696   if (rs6000_pcrel_p (cfun))
10697     return "bl %z0@notoc";
10698   return "bl %z0";
10700   [(set_attr "type" "branch")])
10702 (define_insn "*call_value_local_aix<mode>"
10703   [(set (match_operand 0 "" "")
10704         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10705               (match_operand 2)))
10706    (clobber (reg:P LR_REGNO))]
10707   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10709   if (rs6000_pcrel_p (cfun))
10710     return "bl %z1@notoc";
10711   return "bl %z1";
10713   [(set_attr "type" "branch")])
10715 ;; Call to AIX abi function which may be in another module.
10716 ;; Restore the TOC pointer (r2) after the call.
10718 (define_insn "*call_nonlocal_aix<mode>"
10719   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10720          (match_operand 1))
10721    (clobber (reg:P LR_REGNO))]
10722   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10724   return rs6000_call_template (operands, 0);
10726   [(set_attr "type" "branch")
10727    (set (attr "length")
10728         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10729           (const_int 4)
10730           (const_int 8)))])
10732 (define_insn "*call_value_nonlocal_aix<mode>"
10733   [(set (match_operand 0 "" "")
10734         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10735               (match_operand:P 2 "unspec_tls" "")))
10736    (clobber (reg:P LR_REGNO))]
10737   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10739   return rs6000_call_template (operands, 1);
10741   [(set_attr "type" "branch")
10742    (set (attr "length")
10743         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10744             (const_int 4)
10745             (const_int 8)))])
10747 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10748 ;; Operand0 is the addresss of the function to call
10749 ;; Operand2 is the location in the function descriptor to load r2 from
10750 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10752 (define_insn "*call_indirect_aix<mode>"
10753   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10754          (match_operand 1))
10755    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10756    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10757    (clobber (reg:P LR_REGNO))]
10758   "DEFAULT_ABI == ABI_AIX"
10760   return rs6000_indirect_call_template (operands, 0);
10762   [(set_attr "type" "jmpreg")
10763    (set (attr "length")
10764         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10765                            (match_test "which_alternative != 1"))
10766                       (const_string "16")
10767                       (const_string "12")))])
10769 (define_insn "*call_value_indirect_aix<mode>"
10770   [(set (match_operand 0 "" "")
10771         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10772               (match_operand:P 2 "unspec_tls" "")))
10773    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10774    (set (reg:P TOC_REGNUM)
10775         (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10776                   UNSPEC_TOCSLOT))
10777    (clobber (reg:P LR_REGNO))]
10778   "DEFAULT_ABI == ABI_AIX"
10780   return rs6000_indirect_call_template (operands, 1);
10782   [(set_attr "type" "jmpreg")
10783    (set (attr "length")
10784         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10785                            (match_test "which_alternative != 1"))
10786             (const_string "16")
10787             (const_string "12")))])
10789 ;; Call to indirect functions with the ELFv2 ABI.
10790 ;; Operand0 is the addresss of the function to call
10791 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10793 (define_insn "*call_indirect_elfv2<mode>"
10794   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10795          (match_operand 1))
10796    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10797    (clobber (reg:P LR_REGNO))]
10798   "DEFAULT_ABI == ABI_ELFv2"
10800   return rs6000_indirect_call_template (operands, 0);
10802   [(set_attr "type" "jmpreg")
10803    (set (attr "length")
10804         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10805                            (match_test "which_alternative != 1"))
10806                       (const_string "12")
10807                       (const_string "8")))])
10809 (define_insn "*call_indirect_pcrel<mode>"
10810   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10811          (match_operand 1))
10812    (clobber (reg:P LR_REGNO))]
10813   "rs6000_pcrel_p (cfun)"
10815   return rs6000_indirect_call_template (operands, 0);
10817   [(set_attr "type" "jmpreg")
10818    (set (attr "length")
10819         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10820                            (match_test "which_alternative != 1"))
10821                       (const_string "8")
10822                       (const_string "4")))])
10824 (define_insn "*call_value_indirect_elfv2<mode>"
10825   [(set (match_operand 0 "" "")
10826         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10827               (match_operand:P 2 "unspec_tls" "")))
10828    (set (reg:P TOC_REGNUM)
10829         (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10830                   UNSPEC_TOCSLOT))
10831    (clobber (reg:P LR_REGNO))]
10832   "DEFAULT_ABI == ABI_ELFv2"
10834   return rs6000_indirect_call_template (operands, 1);
10836   [(set_attr "type" "jmpreg")
10837    (set (attr "length")
10838         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10839                            (match_test "which_alternative != 1"))
10840             (const_string "12")
10841             (const_string "8")))])
10843 (define_insn "*call_value_indirect_pcrel<mode>"
10844   [(set (match_operand 0 "" "")
10845         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10846               (match_operand:P 2 "unspec_tls" "")))
10847    (clobber (reg:P LR_REGNO))]
10848   "rs6000_pcrel_p (cfun)"
10850   return rs6000_indirect_call_template (operands, 1);
10852   [(set_attr "type" "jmpreg")
10853    (set (attr "length")
10854         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10855                            (match_test "which_alternative != 1"))
10856             (const_string "8")
10857             (const_string "4")))])
10859 ;; Call subroutine returning any type.
10860 (define_expand "untyped_call"
10861   [(parallel [(call (match_operand 0 "")
10862                     (const_int 0))
10863               (match_operand 1 "")
10864               (match_operand 2 "")])]
10865   ""
10867   int i;
10869   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10871   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10872     {
10873       rtx set = XVECEXP (operands[2], 0, i);
10874       emit_move_insn (SET_DEST (set), SET_SRC (set));
10875     }
10877   /* The optimizer does not know that the call sets the function value
10878      registers we stored in the result block.  We avoid problems by
10879      claiming that all hard registers are used and clobbered at this
10880      point.  */
10881   emit_insn (gen_blockage ());
10883   DONE;
10886 ;; sibling call patterns
10887 (define_expand "sibcall"
10888   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10889                     (match_operand 1 ""))
10890               (use (match_operand 2 ""))
10891               (simple_return)])]
10892   ""
10894 #if TARGET_MACHO
10895   if (MACHOPIC_INDIRECT)
10896     operands[0] = machopic_indirect_call_target (operands[0]);
10897 #endif
10899   gcc_assert (MEM_P (operands[0]));
10900   gcc_assert (CONST_INT_P (operands[1]));
10902   operands[0] = XEXP (operands[0], 0);
10904   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10905     rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10906   else if (DEFAULT_ABI == ABI_V4)
10907     rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10908   else if (DEFAULT_ABI == ABI_DARWIN)
10909     rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10910   else
10911     gcc_unreachable ();
10913   DONE;
10916 (define_expand "sibcall_value"
10917   [(parallel [(set (match_operand 0 "register_operand")
10918                 (call (mem:SI (match_operand 1 "address_operand"))
10919                       (match_operand 2 "")))
10920               (use (match_operand 3 ""))
10921               (simple_return)])]
10922   ""
10924 #if TARGET_MACHO
10925   if (MACHOPIC_INDIRECT)
10926     operands[1] = machopic_indirect_call_target (operands[1]);
10927 #endif
10929   gcc_assert (MEM_P (operands[1]));
10930   gcc_assert (CONST_INT_P (operands[2]));
10932   operands[1] = XEXP (operands[1], 0);
10934   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10935     rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10936   else if (DEFAULT_ABI == ABI_V4)
10937     rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10938   else if (DEFAULT_ABI == ABI_DARWIN)
10939     rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10940   else
10941     gcc_unreachable ();
10943   DONE;
10946 (define_insn "*sibcall_local32"
10947   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10948          (match_operand 1))
10949    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10950    (simple_return)]
10951   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10953   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10954     output_asm_insn ("crxor 6,6,6", operands);
10956   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10957     output_asm_insn ("creqv 6,6,6", operands);
10959   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10961   [(set_attr "type" "branch")
10962    (set_attr "length" "4,8")])
10964 (define_insn "*sibcall_local64"
10965   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10966          (match_operand 1))
10967    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10968    (simple_return)]
10969   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10971   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10972     output_asm_insn ("crxor 6,6,6", operands);
10974   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10975     output_asm_insn ("creqv 6,6,6", operands);
10977   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10979   [(set_attr "type" "branch")
10980    (set_attr "length" "4,8")])
10982 (define_insn "*sibcall_value_local32"
10983   [(set (match_operand 0 "" "")
10984         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10985               (match_operand 2)))
10986    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10987    (simple_return)]
10988   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10990   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10991     output_asm_insn ("crxor 6,6,6", operands);
10993   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10994     output_asm_insn ("creqv 6,6,6", operands);
10996   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10998   [(set_attr "type" "branch")
10999    (set_attr "length" "4,8")])
11001 (define_insn "*sibcall_value_local64"
11002   [(set (match_operand 0 "" "")
11003         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11004               (match_operand 2)))
11005    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11006    (simple_return)]
11007   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11009   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11010     output_asm_insn ("crxor 6,6,6", operands);
11012   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11013     output_asm_insn ("creqv 6,6,6", operands);
11015   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11017   [(set_attr "type" "branch")
11018    (set_attr "length" "4,8")])
11020 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11021   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11022          (match_operand 1))
11023    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11024    (simple_return)]
11025   "DEFAULT_ABI == ABI_V4
11026    || DEFAULT_ABI == ABI_DARWIN"
11028   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11029     output_asm_insn ("crxor 6,6,6", operands);
11031   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11032     output_asm_insn ("creqv 6,6,6", operands);
11034   return rs6000_indirect_sibcall_template (operands, 0);
11036   [(set_attr "type" "jmpreg")
11037    (set (attr "length")
11038         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11039                          (match_test "which_alternative != 1"))
11040                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11041                   (const_string "12")
11042                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11043                          (match_test "which_alternative != 1"))
11044                    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11045                   (const_string "8")]
11046               (const_string "4")))])
11048 (define_insn "*sibcall_nonlocal_sysv<mode>"
11049   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11050          (match_operand 1))
11051    (use (match_operand 2 "immediate_operand" "O,n"))
11052    (simple_return)]
11053   "(DEFAULT_ABI == ABI_DARWIN
11054     || DEFAULT_ABI == ABI_V4)
11055    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11057   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11058     output_asm_insn ("crxor 6,6,6", operands);
11060   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11061     output_asm_insn ("creqv 6,6,6", operands);
11063   return rs6000_sibcall_template (operands, 0);
11065   [(set_attr "type" "branch")
11066    (set_attr "length" "4,8")])
11068 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11069   [(set (match_operand 0 "" "")
11070         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11071               (match_operand 2)))
11072    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11073    (simple_return)]
11074   "DEFAULT_ABI == ABI_V4
11075    || DEFAULT_ABI == ABI_DARWIN"
11077   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11078     output_asm_insn ("crxor 6,6,6", operands);
11080   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11081     output_asm_insn ("creqv 6,6,6", operands);
11083   return rs6000_indirect_sibcall_template (operands, 1);
11085   [(set_attr "type" "jmpreg")
11086    (set (attr "length")
11087         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11088                          (match_test "which_alternative != 1"))
11089                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11090                   (const_string "12")
11091                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11092                          (match_test "which_alternative != 1"))
11093                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11094                   (const_string "8")]
11095               (const_string "4")))])
11097 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11098   [(set (match_operand 0 "" "")
11099         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11100               (match_operand 2)))
11101    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11102    (simple_return)]
11103   "(DEFAULT_ABI == ABI_DARWIN
11104     || DEFAULT_ABI == ABI_V4)
11105    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11107   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11108     output_asm_insn ("crxor 6,6,6", operands);
11110   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11111     output_asm_insn ("creqv 6,6,6", operands);
11113   return rs6000_sibcall_template (operands, 1);
11115   [(set_attr "type" "branch")
11116    (set_attr "length" "4,8")])
11118 ;; AIX ABI sibling call patterns.
11120 (define_insn "*sibcall_aix<mode>"
11121   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11122          (match_operand 1))
11123    (simple_return)]
11124   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11126   if (which_alternative == 0)
11127     return rs6000_sibcall_template (operands, 0);
11128   else
11129     return "b%T0";
11131   [(set_attr "type" "branch")])
11133 (define_insn "*sibcall_value_aix<mode>"
11134   [(set (match_operand 0 "" "")
11135         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11136               (match_operand 2)))
11137    (simple_return)]
11138   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11140   if (which_alternative == 0)
11141     return rs6000_sibcall_template (operands, 1);
11142   else
11143     return "b%T1";
11145   [(set_attr "type" "branch")])
11147 (define_expand "sibcall_epilogue"
11148   [(use (const_int 0))]
11149   ""
11151   if (!TARGET_SCHED_PROLOG)
11152     emit_insn (gen_blockage ());
11153   rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11154   DONE;
11157 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11158 ;; all of memory.  This blocks insns from being moved across this point.
11160 (define_insn "blockage"
11161   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11162   ""
11163   ""
11164   [(set_attr "length" "0")])
11166 (define_expand "probe_stack_address"
11167   [(use (match_operand 0 "address_operand"))]
11168   ""
11170   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11171   MEM_VOLATILE_P (operands[0]) = 1;
11173   if (TARGET_64BIT)
11174     emit_insn (gen_probe_stack_di (operands[0]));
11175   else
11176     emit_insn (gen_probe_stack_si (operands[0]));
11177   DONE;
11180 (define_insn "probe_stack_<mode>"
11181   [(set (match_operand:P 0 "memory_operand" "=m")
11182         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11183   ""
11185   operands[1] = gen_rtx_REG (Pmode, 0);
11186   return "st<wd>%U0%X0 %1,%0";
11188   [(set_attr "type" "store")
11189    (set (attr "update")
11190         (if_then_else (match_operand 0 "update_address_mem")
11191                       (const_string "yes")
11192                       (const_string "no")))
11193    (set (attr "indexed")
11194         (if_then_else (match_operand 0 "indexed_address_mem")
11195                       (const_string "yes")
11196                       (const_string "no")))])
11198 (define_insn "probe_stack_range<P:mode>"
11199   [(set (match_operand:P 0 "register_operand" "=&r")
11200         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11201                             (match_operand:P 2 "register_operand" "r")
11202                             (match_operand:P 3 "register_operand" "r")]
11203                            UNSPECV_PROBE_STACK_RANGE))]
11204   ""
11205   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11206   [(set_attr "type" "three")])
11208 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11209 ;; signed & unsigned, and one type of branch.
11211 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11212 ;; insns, and branches.
11214 (define_expand "cbranch<mode>4"
11215   [(use (match_operator 0 "comparison_operator"
11216          [(match_operand:GPR 1 "gpc_reg_operand")
11217           (match_operand:GPR 2 "reg_or_short_operand")]))
11218    (use (match_operand 3))]
11219   ""
11221   /* Take care of the possibility that operands[2] might be negative but
11222      this might be a logical operation.  That insn doesn't exist.  */
11223   if (CONST_INT_P (operands[2])
11224       && INTVAL (operands[2]) < 0)
11225     {
11226       operands[2] = force_reg (<MODE>mode, operands[2]);
11227       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11228                                     GET_MODE (operands[0]),
11229                                     operands[1], operands[2]);
11230    }
11232   rs6000_emit_cbranch (<MODE>mode, operands);
11233   DONE;
11236 (define_expand "cbranch<mode>4"
11237   [(use (match_operator 0 "comparison_operator"
11238          [(match_operand:FP 1 "gpc_reg_operand")
11239           (match_operand:FP 2 "gpc_reg_operand")]))
11240    (use (match_operand 3))]
11241   ""
11243   rs6000_emit_cbranch (<MODE>mode, operands);
11244   DONE;
11247 (define_expand "cstore<mode>4_signed"
11248   [(use (match_operator 1 "signed_comparison_operator"
11249          [(match_operand:P 2 "gpc_reg_operand")
11250           (match_operand:P 3 "gpc_reg_operand")]))
11251    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11252   ""
11254   enum rtx_code cond_code = GET_CODE (operands[1]);
11256   rtx op0 = operands[0];
11257   rtx op1 = operands[2];
11258   rtx op2 = operands[3];
11260   if (cond_code == GE || cond_code == LT)
11261     {
11262       cond_code = swap_condition (cond_code);
11263       std::swap (op1, op2);
11264     }
11266   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11267   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11268   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11270   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11271   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11272   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11274   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11276   if (cond_code == LE)
11277     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11278   else
11279     {
11280       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11281       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11282       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11283     }
11285   DONE;
11288 (define_expand "cstore<mode>4_unsigned"
11289   [(use (match_operator 1 "unsigned_comparison_operator"
11290          [(match_operand:P 2 "gpc_reg_operand")
11291           (match_operand:P 3 "reg_or_short_operand")]))
11292    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11293   ""
11295   enum rtx_code cond_code = GET_CODE (operands[1]);
11297   rtx op0 = operands[0];
11298   rtx op1 = operands[2];
11299   rtx op2 = operands[3];
11301   if (cond_code == GEU || cond_code == LTU)
11302     {
11303       cond_code = swap_condition (cond_code);
11304       std::swap (op1, op2);
11305     }
11307   if (!gpc_reg_operand (op1, <MODE>mode))
11308     op1 = force_reg (<MODE>mode, op1);
11309   if (!reg_or_short_operand (op2, <MODE>mode))
11310     op2 = force_reg (<MODE>mode, op2);
11312   rtx tmp = gen_reg_rtx (<MODE>mode);
11313   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11315   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11316   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11318   if (cond_code == LEU)
11319     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11320   else
11321     emit_insn (gen_neg<mode>2 (op0, tmp2));
11323   DONE;
11326 (define_expand "cstore_si_as_di"
11327   [(use (match_operator 1 "unsigned_comparison_operator"
11328          [(match_operand:SI 2 "gpc_reg_operand")
11329           (match_operand:SI 3 "reg_or_short_operand")]))
11330    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11331   ""
11333   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11334   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11336   operands[2] = force_reg (SImode, operands[2]);
11337   operands[3] = force_reg (SImode, operands[3]);
11338   rtx op1 = gen_reg_rtx (DImode);
11339   rtx op2 = gen_reg_rtx (DImode);
11340   convert_move (op1, operands[2], uns_flag);
11341   convert_move (op2, operands[3], uns_flag);
11343   if (cond_code == GT || cond_code == LE)
11344     {
11345       cond_code = swap_condition (cond_code);
11346       std::swap (op1, op2);
11347     }
11349   rtx tmp = gen_reg_rtx (DImode);
11350   rtx tmp2 = gen_reg_rtx (DImode);
11351   emit_insn (gen_subdi3 (tmp, op1, op2));
11352   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11354   rtx tmp3;
11355   switch (cond_code)
11356     {
11357     default:
11358       gcc_unreachable ();
11359     case LT:
11360       tmp3 = tmp2;
11361       break;
11362     case GE:
11363       tmp3 = gen_reg_rtx (DImode);
11364       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11365       break;
11366     }
11368   convert_move (operands[0], tmp3, 1);
11370   DONE;
11373 (define_expand "cstore<mode>4_signed_imm"
11374   [(use (match_operator 1 "signed_comparison_operator"
11375          [(match_operand:GPR 2 "gpc_reg_operand")
11376           (match_operand:GPR 3 "immediate_operand")]))
11377    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11378   ""
11380   bool invert = false;
11382   enum rtx_code cond_code = GET_CODE (operands[1]);
11384   rtx op0 = operands[0];
11385   rtx op1 = operands[2];
11386   HOST_WIDE_INT val = INTVAL (operands[3]);
11388   if (cond_code == GE || cond_code == GT)
11389     {
11390       cond_code = reverse_condition (cond_code);
11391       invert = true;
11392     }
11394   if (cond_code == LE)
11395     val++;
11397   rtx tmp = gen_reg_rtx (<MODE>mode);
11398   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11399   rtx x = gen_reg_rtx (<MODE>mode);
11400   if (val < 0)
11401     emit_insn (gen_and<mode>3 (x, op1, tmp));
11402   else
11403     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11405   if (invert)
11406     {
11407       rtx tmp = gen_reg_rtx (<MODE>mode);
11408       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11409       x = tmp;
11410     }
11412   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11413   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11415   DONE;
11418 (define_expand "cstore<mode>4_unsigned_imm"
11419   [(use (match_operator 1 "unsigned_comparison_operator"
11420          [(match_operand:GPR 2 "gpc_reg_operand")
11421           (match_operand:GPR 3 "immediate_operand")]))
11422    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11423   ""
11425   bool invert = false;
11427   enum rtx_code cond_code = GET_CODE (operands[1]);
11429   rtx op0 = operands[0];
11430   rtx op1 = operands[2];
11431   HOST_WIDE_INT val = INTVAL (operands[3]);
11433   if (cond_code == GEU || cond_code == GTU)
11434     {
11435       cond_code = reverse_condition (cond_code);
11436       invert = true;
11437     }
11439   if (cond_code == LEU)
11440     val++;
11442   rtx tmp = gen_reg_rtx (<MODE>mode);
11443   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11444   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11445   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11446   rtx x = gen_reg_rtx (<MODE>mode);
11447   if (val < 0)
11448     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11449   else
11450     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11452   if (invert)
11453     {
11454       rtx tmp = gen_reg_rtx (<MODE>mode);
11455       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11456       x = tmp;
11457     }
11459   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11460   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11462   DONE;
11465 (define_expand "cstore<mode>4"
11466   [(use (match_operator 1 "comparison_operator"
11467          [(match_operand:GPR 2 "gpc_reg_operand")
11468           (match_operand:GPR 3 "reg_or_short_operand")]))
11469    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11470   ""
11472   /* Expanding EQ and NE directly to some machine instructions does not help
11473      but does hurt combine.  So don't.  */
11474   if (GET_CODE (operands[1]) == EQ)
11475     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11476   else if (<MODE>mode == Pmode
11477            && GET_CODE (operands[1]) == NE)
11478     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11479   else if (GET_CODE (operands[1]) == NE)
11480     {
11481       rtx tmp = gen_reg_rtx (<MODE>mode);
11482       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11483       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11484     }
11486   /* If ISEL is fast, expand to it.  */
11487   else if (TARGET_ISEL)
11488     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11490   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11491      etc. combinations magically work out just right.  */
11492   else if (<MODE>mode == Pmode
11493            && unsigned_comparison_operator (operands[1], VOIDmode))
11494     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11495                                            operands[2], operands[3]));
11497   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11498   else if (<MODE>mode == SImode && Pmode == DImode)
11499     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11500                                     operands[2], operands[3]));
11502   /* For signed comparisons against a constant, we can do some simple
11503      bit-twiddling.  */
11504   else if (signed_comparison_operator (operands[1], VOIDmode)
11505            && CONST_INT_P (operands[3]))
11506     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11507                                              operands[2], operands[3]));
11509   /* And similarly for unsigned comparisons.  */
11510   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11511            && CONST_INT_P (operands[3]))
11512     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11513                                                operands[2], operands[3]));
11515   /* We also do not want to use mfcr for signed comparisons.  */
11516   else if (<MODE>mode == Pmode
11517            && signed_comparison_operator (operands[1], VOIDmode))
11518     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11519                                          operands[2], operands[3]));
11521   /* Everything else, use the mfcr brute force.  */
11522   else
11523     rs6000_emit_sCOND (<MODE>mode, operands);
11525   DONE;
11528 (define_expand "cstore<mode>4"
11529   [(use (match_operator 1 "comparison_operator"
11530          [(match_operand:FP 2 "gpc_reg_operand")
11531           (match_operand:FP 3 "gpc_reg_operand")]))
11532    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11533   ""
11535   rs6000_emit_sCOND (<MODE>mode, operands);
11536   DONE;
11540 (define_expand "stack_protect_set"
11541   [(match_operand 0 "memory_operand")
11542    (match_operand 1 "memory_operand")]
11543   ""
11545   if (rs6000_stack_protector_guard == SSP_TLS)
11546     {
11547       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11548       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11549       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11550       operands[1] = gen_rtx_MEM (Pmode, addr);
11551     }
11553   if (TARGET_64BIT)
11554     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11555   else
11556     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11558   DONE;
11561 (define_insn "stack_protect_setsi"
11562   [(set (match_operand:SI 0 "memory_operand" "=m")
11563         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11564    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11565   "TARGET_32BIT"
11566   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11567   [(set_attr "type" "three")
11568    (set_attr "length" "12")])
11570 ;; We can't use the prefixed attribute here because there are two memory
11571 ;; instructions.  We can't split the insn due to the fact that this operation
11572 ;; needs to be done in one piece.
11573 (define_insn "stack_protect_setdi"
11574   [(set (match_operand:DI 0 "memory_operand" "=Y")
11575         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11576    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11577   "TARGET_64BIT"
11579   if (prefixed_memory (operands[1], DImode))
11580     output_asm_insn ("pld %2,%1", operands);
11581   else
11582     output_asm_insn ("ld%U1%X1 %2,%1", operands);
11584   if (prefixed_memory (operands[0], DImode))
11585     output_asm_insn ("pstd %2,%0", operands);
11586   else
11587     output_asm_insn ("std%U0%X0 %2,%0", operands);
11589   return "li %2,0";
11591   [(set_attr "type" "three")
11593   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11594   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in 4 bytes for
11595   ;; the LI 0 at the end.
11596    (set_attr "prefixed" "no")
11597    (set_attr "num_insns" "3")
11598    (set (attr "length")
11599         (cond [(and (match_operand 0 "prefixed_memory")
11600                     (match_operand 1 "prefixed_memory"))
11601                (const_int 24)
11603                (ior (match_operand 0 "prefixed_memory")
11604                     (match_operand 1 "prefixed_memory"))
11605                (const_int 20)]
11607               (const_int 12)))])
11609 (define_expand "stack_protect_test"
11610   [(match_operand 0 "memory_operand")
11611    (match_operand 1 "memory_operand")
11612    (match_operand 2 "")]
11613   ""
11615   rtx guard = operands[1];
11617   if (rs6000_stack_protector_guard == SSP_TLS)
11618     {
11619       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11620       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11621       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11622       guard = gen_rtx_MEM (Pmode, addr);
11623     }
11625   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11626   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11627   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11628   emit_jump_insn (jump);
11630   DONE;
11633 (define_insn "stack_protect_testsi"
11634   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11635         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11636                       (match_operand:SI 2 "memory_operand" "m,m")]
11637                      UNSPEC_SP_TEST))
11638    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11639    (clobber (match_scratch:SI 3 "=&r,&r"))]
11640   "TARGET_32BIT"
11641   "@
11642    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11643    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11644   [(set_attr "length" "16,20")])
11646 ;; We can't use the prefixed attribute here because there are two memory
11647 ;; instructions.  We can't split the insn due to the fact that this operation
11648 ;; needs to be done in one piece.
11649 (define_insn "stack_protect_testdi"
11650   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11651         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11652                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11653                      UNSPEC_SP_TEST))
11654    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11655    (clobber (match_scratch:DI 3 "=&r,&r"))]
11656   "TARGET_64BIT"
11658   if (prefixed_memory (operands[1], DImode))
11659     output_asm_insn ("pld %3,%1", operands);
11660   else
11661     output_asm_insn ("ld%U1%X1 %3,%1", operands);
11663   if (prefixed_memory (operands[2], DImode))
11664     output_asm_insn ("pld %4,%2", operands);
11665   else
11666     output_asm_insn ("ld%U2%X2 %4,%2", operands);
11668   if (which_alternative == 0)
11669     output_asm_insn ("xor. %3,%3,%4", operands);
11670   else
11671     output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11673   return "li %4,0";
11675   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11676   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in either 4 or
11677   ;; 8 bytes to do the test.
11678   [(set_attr "prefixed" "no")
11679    (set_attr "num_insns" "4,5")
11680    (set (attr "length")
11681         (cond [(and (match_operand 1 "prefixed_memory")
11682                     (match_operand 2 "prefixed_memory"))
11683                (if_then_else (eq_attr "alternative" "0")
11684                              (const_int 28)
11685                              (const_int 32))
11687                (ior (match_operand 1 "prefixed_memory")
11688                     (match_operand 2 "prefixed_memory"))
11689                (if_then_else (eq_attr "alternative" "0")
11690                              (const_int 20)
11691                              (const_int 24))]
11693               (if_then_else (eq_attr "alternative" "0")
11694                             (const_int 16)
11695                             (const_int 20))))])
11698 ;; Here are the actual compare insns.
11699 (define_insn "*cmp<mode>_signed"
11700   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11701         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11702                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11703   ""
11704   "cmp<wd>%I2 %0,%1,%2"
11705   [(set_attr "type" "cmp")])
11707 (define_insn "*cmp<mode>_unsigned"
11708   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11709         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11710                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11711   ""
11712   "cmpl<wd>%I2 %0,%1,%2"
11713   [(set_attr "type" "cmp")])
11715 ;; If we are comparing a register for equality with a large constant,
11716 ;; we can do this with an XOR followed by a compare.  But this is profitable
11717 ;; only if the large constant is only used for the comparison (and in this
11718 ;; case we already have a register to reuse as scratch).
11720 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11721 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11723 (define_peephole2
11724   [(set (match_operand:SI 0 "register_operand")
11725         (match_operand:SI 1 "logical_const_operand"))
11726    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11727                        [(match_dup 0)
11728                         (match_operand:SI 2 "logical_const_operand")]))
11729    (set (match_operand:CC 4 "cc_reg_operand")
11730         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11731                     (match_dup 0)))
11732    (set (pc)
11733         (if_then_else (match_operator 6 "equality_operator"
11734                        [(match_dup 4) (const_int 0)])
11735                       (match_operand 7 "")
11736                       (match_operand 8 "")))]
11737   "peep2_reg_dead_p (3, operands[0])
11738    && peep2_reg_dead_p (4, operands[4])
11739    && REGNO (operands[0]) != REGNO (operands[5])"
11740  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11741   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11742   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11745   /* Get the constant we are comparing against, and see what it looks like
11746      when sign-extended from 16 to 32 bits.  Then see what constant we could
11747      XOR with SEXTC to get the sign-extended value.  */
11748   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11749                                               SImode,
11750                                               operands[1], operands[2]);
11751   HOST_WIDE_INT c = INTVAL (cnst);
11752   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11753   HOST_WIDE_INT xorv = c ^ sextc;
11755   operands[9] = GEN_INT (xorv);
11756   operands[10] = GEN_INT (sextc);
11759 ;; Only need to compare second words if first words equal
11760 (define_insn "*cmp<mode>_internal1"
11761   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11762         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11763                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11764   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11765    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11766   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11767   [(set_attr "type" "fpcompare")
11768    (set_attr "length" "12")])
11770 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11771   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11772         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11773                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11774     (clobber (match_scratch:DF 3 "=d"))
11775     (clobber (match_scratch:DF 4 "=d"))
11776     (clobber (match_scratch:DF 5 "=d"))
11777     (clobber (match_scratch:DF 6 "=d"))
11778     (clobber (match_scratch:DF 7 "=d"))
11779     (clobber (match_scratch:DF 8 "=d"))
11780     (clobber (match_scratch:DF 9 "=d"))
11781     (clobber (match_scratch:DF 10 "=d"))
11782     (clobber (match_scratch:GPR 11 "=b"))]
11783   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11784    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11785   "#"
11786   "&& reload_completed"
11787   [(set (match_dup 3) (match_dup 14))
11788    (set (match_dup 4) (match_dup 15))
11789    (set (match_dup 9) (abs:DF (match_dup 5)))
11790    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11791    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11792                            (label_ref (match_dup 12))
11793                            (pc)))
11794    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11795    (set (pc) (label_ref (match_dup 13)))
11796    (match_dup 12)
11797    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11798    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11799    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11800    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11801    (match_dup 13)]
11803   REAL_VALUE_TYPE rv;
11804   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11805   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11807   operands[5] = simplify_gen_subreg (DFmode, operands[1],
11808                                      <IBM128:MODE>mode, hi_word);
11809   operands[6] = simplify_gen_subreg (DFmode, operands[1],
11810                                      <IBM128:MODE>mode, lo_word);
11811   operands[7] = simplify_gen_subreg (DFmode, operands[2],
11812                                      <IBM128:MODE>mode, hi_word);
11813   operands[8] = simplify_gen_subreg (DFmode, operands[2],
11814                                      <IBM128:MODE>mode, lo_word);
11815   operands[12] = gen_label_rtx ();
11816   operands[13] = gen_label_rtx ();
11817   real_inf (&rv);
11818   operands[14] = force_const_mem (DFmode,
11819                                   const_double_from_real_value (rv, DFmode));
11820   operands[15] = force_const_mem (DFmode,
11821                                   const_double_from_real_value (dconst0,
11822                                                                 DFmode));
11823   if (TARGET_TOC)
11824     {
11825       rtx tocref;
11826       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11827       operands[14] = gen_const_mem (DFmode, tocref);
11828       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11829       operands[15] = gen_const_mem (DFmode, tocref);
11830       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11831       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11832     }
11835 ;; Now we have the scc insns.  We can do some combinations because of the
11836 ;; way the machine works.
11838 ;; Note that this is probably faster if we can put an insn between the
11839 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11840 ;; cases the insns below which don't use an intermediate CR field will
11841 ;; be used instead.
11842 (define_insn "set<mode>_cc"
11843   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11844         (match_operator:GPR 1 "scc_comparison_operator"
11845                             [(match_operand 2 "cc_reg_operand" "y")
11846                              (const_int 0)]))]
11847   ""
11848   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11849   [(set (attr "type")
11850      (cond [(match_test "TARGET_MFCRF")
11851                 (const_string "mfcrf")
11852            ]
11853         (const_string "mfcr")))
11854    (set_attr "length" "8")])
11857 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11858 (define_code_attr UNS [(eq "CC")
11859                        (ne "CC")
11860                        (lt "CC") (ltu "CCUNS")
11861                        (gt "CC") (gtu "CCUNS")
11862                        (le "CC") (leu "CCUNS")
11863                        (ge "CC") (geu "CCUNS")])
11864 (define_code_attr UNSu_ [(eq "")
11865                          (ne "")
11866                          (lt "") (ltu "u_")
11867                          (gt "") (gtu "u_")
11868                          (le "") (leu "u_")
11869                          (ge "") (geu "u_")])
11870 (define_code_attr UNSIK [(eq "I")
11871                          (ne "I")
11872                          (lt "I") (ltu "K")
11873                          (gt "I") (gtu "K")
11874                          (le "I") (leu "K")
11875                          (ge "I") (geu "K")])
11877 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11878   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11879         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11880                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11881    (clobber (match_scratch:GPR 3 "=r"))
11882    (clobber (match_scratch:GPR 4 "=r"))
11883    (clobber (match_scratch:<UNS> 5 "=y"))]
11884   "TARGET_ISEL
11885    && !(<CODE> == EQ && operands[2] == const0_rtx)
11886    && !(<CODE> == NE && operands[2] == const0_rtx
11887         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11888   "#"
11889   "&& 1"
11890   [(pc)]
11892   rtx_code code = <CODE>;
11893   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11894     {
11895       HOST_WIDE_INT val = INTVAL (operands[2]);
11896       if (code == LT && val != -0x8000)
11897         {
11898           code = LE;
11899           val--;
11900         }
11901       if (code == GT && val != 0x7fff)
11902         {
11903           code = GE;
11904           val++;
11905         }
11906       if (code == LTU && val != 0)
11907         {
11908           code = LEU;
11909           val--;
11910         }
11911       if (code == GTU && val != 0xffff)
11912         {
11913           code = GEU;
11914           val++;
11915         }
11916       operands[2] = GEN_INT (val);
11917     }
11919   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11920     operands[3] = const0_rtx;
11921   else
11922     {
11923       if (GET_CODE (operands[3]) == SCRATCH)
11924         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11925       emit_move_insn (operands[3], const0_rtx);
11926     }
11928   if (GET_CODE (operands[4]) == SCRATCH)
11929     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11930   emit_move_insn (operands[4], const1_rtx);
11932   if (GET_CODE (operands[5]) == SCRATCH)
11933     operands[5] = gen_reg_rtx (<UNS>mode);
11935   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11936   emit_insn (gen_rtx_SET (operands[5], c1));
11938   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11939   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11940   emit_move_insn (operands[0], x);
11942   DONE;
11944   [(set (attr "cost")
11945         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11946                                    || <CODE> == NE
11947                                    || <CODE> == LE || <CODE> == GE
11948                                    || <CODE> == LEU || <CODE> == GEU")
11949                       (const_string "9")
11950                       (const_string "10")))])
11952 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11953                               (DI "rKJI")])
11955 (define_expand "eq<mode>3"
11956   [(parallel [
11957      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11958           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11959                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11960      (clobber (match_scratch:GPR 3 "=r"))
11961      (clobber (match_scratch:GPR 4 "=r"))])]
11962   ""
11964   if (TARGET_ISEL && operands[2] != const0_rtx)
11965     {
11966       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11967                                            operands[2]));
11968       DONE;
11969     }
11972 (define_insn_and_split "*eq<mode>3"
11973   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11974         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11975                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11976    (clobber (match_scratch:GPR 3 "=r"))
11977    (clobber (match_scratch:GPR 4 "=r"))]
11978   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11979   "#"
11980   "&& 1"
11981   [(set (match_dup 4)
11982         (clz:GPR (match_dup 3)))
11983    (set (match_dup 0)
11984         (lshiftrt:GPR (match_dup 4)
11985                       (match_dup 5)))]
11987   operands[3] = rs6000_emit_eqne (<MODE>mode,
11988                                   operands[1], operands[2], operands[3]);
11990   if (GET_CODE (operands[4]) == SCRATCH)
11991     operands[4] = gen_reg_rtx (<MODE>mode);
11993   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11995   [(set (attr "length")
11996         (if_then_else (match_test "operands[2] == const0_rtx")
11997                       (const_string "8")
11998                       (const_string "12")))])
12000 (define_expand "ne<mode>3"
12001   [(parallel [
12002      (set (match_operand:P 0 "gpc_reg_operand" "=r")
12003           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12004                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12005      (clobber (match_scratch:P 3 "=r"))
12006      (clobber (match_scratch:P 4 "=r"))
12007      (clobber (reg:P CA_REGNO))])]
12008   ""
12010   if (TARGET_ISEL && operands[2] != const0_rtx)
12011     {
12012       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12013                                            operands[2]));
12014       DONE;
12015     }
12018 (define_insn_and_split "*ne<mode>3"
12019   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12020         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12021               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12022    (clobber (match_scratch:P 3 "=r"))
12023    (clobber (match_scratch:P 4 "=r"))
12024    (clobber (reg:P CA_REGNO))]
12025   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12026   "#"
12027   "&& 1"
12028   [(parallel [(set (match_dup 4)
12029                    (plus:P (match_dup 3)
12030                            (const_int -1)))
12031               (set (reg:P CA_REGNO)
12032                    (ne:P (match_dup 3)
12033                          (const_int 0)))])
12034    (parallel [(set (match_dup 0)
12035                    (plus:P (plus:P (not:P (match_dup 4))
12036                                    (reg:P CA_REGNO))
12037                            (match_dup 3)))
12038               (clobber (reg:P CA_REGNO))])]
12040   operands[3] = rs6000_emit_eqne (<MODE>mode,
12041                                   operands[1], operands[2], operands[3]);
12043   if (GET_CODE (operands[4]) == SCRATCH)
12044     operands[4] = gen_reg_rtx (<MODE>mode);
12046   [(set (attr "length")
12047         (if_then_else (match_test "operands[2] == const0_rtx")
12048                       (const_string "8")
12049                       (const_string "12")))])
12051 (define_insn_and_split "*neg_eq_<mode>"
12052   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12053         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12054                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12055    (clobber (match_scratch:P 3 "=r"))
12056    (clobber (match_scratch:P 4 "=r"))
12057    (clobber (reg:P CA_REGNO))]
12058   ""
12059   "#"
12060   ""
12061   [(parallel [(set (match_dup 4)
12062                    (plus:P (match_dup 3)
12063                            (const_int -1)))
12064               (set (reg:P CA_REGNO)
12065                    (ne:P (match_dup 3)
12066                          (const_int 0)))])
12067    (parallel [(set (match_dup 0)
12068                    (plus:P (reg:P CA_REGNO)
12069                            (const_int -1)))
12070               (clobber (reg:P CA_REGNO))])]
12072   operands[3] = rs6000_emit_eqne (<MODE>mode,
12073                                   operands[1], operands[2], operands[3]);
12075   if (GET_CODE (operands[4]) == SCRATCH)
12076     operands[4] = gen_reg_rtx (<MODE>mode);
12078   [(set (attr "length")
12079         (if_then_else (match_test "operands[2] == const0_rtx")
12080                       (const_string "8")
12081                       (const_string "12")))])
12083 (define_insn_and_split "*neg_ne_<mode>"
12084   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12085         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12086                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12087    (clobber (match_scratch:P 3 "=r"))
12088    (clobber (match_scratch:P 4 "=r"))
12089    (clobber (reg:P CA_REGNO))]
12090   ""
12091   "#"
12092   ""
12093   [(parallel [(set (match_dup 4)
12094                    (neg:P (match_dup 3)))
12095               (set (reg:P CA_REGNO)
12096                    (eq:P (match_dup 3)
12097                          (const_int 0)))])
12098    (parallel [(set (match_dup 0)
12099                    (plus:P (reg:P CA_REGNO)
12100                            (const_int -1)))
12101               (clobber (reg:P CA_REGNO))])]
12103   operands[3] = rs6000_emit_eqne (<MODE>mode,
12104                                   operands[1], operands[2], operands[3]);
12106   if (GET_CODE (operands[4]) == SCRATCH)
12107     operands[4] = gen_reg_rtx (<MODE>mode);
12109   [(set (attr "length")
12110         (if_then_else (match_test "operands[2] == const0_rtx")
12111                       (const_string "8")
12112                       (const_string "12")))])
12114 (define_insn_and_split "*plus_eq_<mode>"
12115   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12116         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12117                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12118                 (match_operand:P 3 "gpc_reg_operand" "r")))
12119    (clobber (match_scratch:P 4 "=r"))
12120    (clobber (match_scratch:P 5 "=r"))
12121    (clobber (reg:P CA_REGNO))]
12122   ""
12123   "#"
12124   ""
12125   [(parallel [(set (match_dup 5)
12126                    (neg:P (match_dup 4)))
12127               (set (reg:P CA_REGNO)
12128                    (eq:P (match_dup 4)
12129                          (const_int 0)))])
12130    (parallel [(set (match_dup 0)
12131                    (plus:P (match_dup 3)
12132                            (reg:P CA_REGNO)))
12133               (clobber (reg:P CA_REGNO))])]
12135   operands[4] = rs6000_emit_eqne (<MODE>mode,
12136                                   operands[1], operands[2], operands[4]);
12138   if (GET_CODE (operands[5]) == SCRATCH)
12139     operands[5] = gen_reg_rtx (<MODE>mode);
12141   [(set (attr "length")
12142         (if_then_else (match_test "operands[2] == const0_rtx")
12143                       (const_string "8")
12144                       (const_string "12")))])
12146 (define_insn_and_split "*plus_ne_<mode>"
12147   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12148         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12149                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12150                 (match_operand:P 3 "gpc_reg_operand" "r")))
12151    (clobber (match_scratch:P 4 "=r"))
12152    (clobber (match_scratch:P 5 "=r"))
12153    (clobber (reg:P CA_REGNO))]
12154   ""
12155   "#"
12156   ""
12157   [(parallel [(set (match_dup 5)
12158                    (plus:P (match_dup 4)
12159                            (const_int -1)))
12160               (set (reg:P CA_REGNO)
12161                    (ne:P (match_dup 4)
12162                          (const_int 0)))])
12163    (parallel [(set (match_dup 0)
12164                    (plus:P (match_dup 3)
12165                            (reg:P CA_REGNO)))
12166               (clobber (reg:P CA_REGNO))])]
12168   operands[4] = rs6000_emit_eqne (<MODE>mode,
12169                                   operands[1], operands[2], operands[4]);
12171   if (GET_CODE (operands[5]) == SCRATCH)
12172     operands[5] = gen_reg_rtx (<MODE>mode);
12174   [(set (attr "length")
12175         (if_then_else (match_test "operands[2] == const0_rtx")
12176                       (const_string "8")
12177                       (const_string "12")))])
12179 (define_insn_and_split "*minus_eq_<mode>"
12180   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12181         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12182                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12183                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12184    (clobber (match_scratch:P 4 "=r"))
12185    (clobber (match_scratch:P 5 "=r"))
12186    (clobber (reg:P CA_REGNO))]
12187   ""
12188   "#"
12189   ""
12190   [(parallel [(set (match_dup 5)
12191                    (plus:P (match_dup 4)
12192                            (const_int -1)))
12193               (set (reg:P CA_REGNO)
12194                    (ne:P (match_dup 4)
12195                          (const_int 0)))])
12196    (parallel [(set (match_dup 0)
12197                    (plus:P (plus:P (match_dup 3)
12198                                    (reg:P CA_REGNO))
12199                            (const_int -1)))
12200               (clobber (reg:P CA_REGNO))])]
12202   operands[4] = rs6000_emit_eqne (<MODE>mode,
12203                                   operands[1], operands[2], operands[4]);
12205   if (GET_CODE (operands[5]) == SCRATCH)
12206     operands[5] = gen_reg_rtx (<MODE>mode);
12208   [(set (attr "length")
12209         (if_then_else (match_test "operands[2] == const0_rtx")
12210                       (const_string "8")
12211                       (const_string "12")))])
12213 (define_insn_and_split "*minus_ne_<mode>"
12214   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12215         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12216                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12217                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12218    (clobber (match_scratch:P 4 "=r"))
12219    (clobber (match_scratch:P 5 "=r"))
12220    (clobber (reg:P CA_REGNO))]
12221   ""
12222   "#"
12223   ""
12224   [(parallel [(set (match_dup 5)
12225                    (neg:P (match_dup 4)))
12226               (set (reg:P CA_REGNO)
12227                    (eq:P (match_dup 4)
12228                          (const_int 0)))])
12229    (parallel [(set (match_dup 0)
12230                    (plus:P (plus:P (match_dup 3)
12231                                    (reg:P CA_REGNO))
12232                            (const_int -1)))
12233               (clobber (reg:P CA_REGNO))])]
12235   operands[4] = rs6000_emit_eqne (<MODE>mode,
12236                                   operands[1], operands[2], operands[4]);
12238   if (GET_CODE (operands[5]) == SCRATCH)
12239     operands[5] = gen_reg_rtx (<MODE>mode);
12241   [(set (attr "length")
12242         (if_then_else (match_test "operands[2] == const0_rtx")
12243                       (const_string "8")
12244                       (const_string "12")))])
12246 (define_insn_and_split "*eqsi3_ext<mode>"
12247   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12248         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12249                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12250    (clobber (match_scratch:SI 3 "=r"))
12251    (clobber (match_scratch:SI 4 "=r"))]
12252   ""
12253   "#"
12254   ""
12255   [(set (match_dup 4)
12256         (clz:SI (match_dup 3)))
12257    (set (match_dup 0)
12258         (zero_extend:EXTSI
12259           (lshiftrt:SI (match_dup 4)
12260                        (const_int 5))))]
12262   operands[3] = rs6000_emit_eqne (SImode,
12263                                   operands[1], operands[2], operands[3]);
12265   if (GET_CODE (operands[4]) == SCRATCH)
12266     operands[4] = gen_reg_rtx (SImode);
12268   [(set (attr "length")
12269         (if_then_else (match_test "operands[2] == const0_rtx")
12270                       (const_string "8")
12271                       (const_string "12")))])
12273 (define_insn_and_split "*nesi3_ext<mode>"
12274   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12275         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12276                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12277    (clobber (match_scratch:SI 3 "=r"))
12278    (clobber (match_scratch:SI 4 "=r"))
12279    (clobber (match_scratch:EXTSI 5 "=r"))]
12280   "!TARGET_ISEL"
12281   "#"
12282   "&& 1"
12283   [(set (match_dup 4)
12284         (clz:SI (match_dup 3)))
12285    (set (match_dup 5)
12286         (zero_extend:EXTSI
12287           (lshiftrt:SI (match_dup 4)
12288                        (const_int 5))))
12289    (set (match_dup 0)
12290         (xor:EXTSI (match_dup 5)
12291                    (const_int 1)))]
12293   operands[3] = rs6000_emit_eqne (SImode,
12294                                   operands[1], operands[2], operands[3]);
12296   if (GET_CODE (operands[4]) == SCRATCH)
12297     operands[4] = gen_reg_rtx (SImode);
12298   if (GET_CODE (operands[5]) == SCRATCH)
12299     operands[5] = gen_reg_rtx (<MODE>mode);
12301   [(set (attr "length")
12302         (if_then_else (match_test "operands[2] == const0_rtx")
12303                       (const_string "12")
12304                       (const_string "16")))])
12307 (define_code_iterator fp_rev [ordered ne unle unge])
12308 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12310 (define_insn_and_split "*<code><mode>_cc"
12311   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12312         (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12313                     (const_int 0)))]
12314   "!flag_finite_math_only"
12315   "#"
12316   "&& 1"
12317   [(pc)]
12319   rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12320   rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12321   rtx tmp = gen_reg_rtx (<MODE>mode);
12322   emit_move_insn (tmp, eq);
12323   emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12324   DONE;
12326   [(set_attr "length" "12")])
12328 (define_insn_and_split "*<code><mode>_cc"
12329   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12330         (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12331                   (const_int 0)))]
12332   "!flag_finite_math_only"
12333   "#"
12334   "&& 1"
12335   [(pc)]
12337   rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12339   emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12340   DONE;
12342   [(set_attr "length" "12")])
12344 ;; Conditional branches.
12345 ;; These either are a single bc insn, or a bc around a b.
12347 (define_insn "*cbranch"
12348   [(set (pc)
12349         (if_then_else (match_operator 1 "branch_comparison_operator"
12350                                       [(match_operand 2 "cc_reg_operand" "y")
12351                                        (const_int 0)])
12352                       (label_ref (match_operand 0))
12353                       (pc)))]
12354   ""
12356   return output_cbranch (operands[1], "%l0", 0, insn);
12358   [(set_attr "type" "branch")
12359    (set (attr "length")
12360         (if_then_else (and (ge (minus (match_dup 0) (pc))
12361                                (const_int -32768))
12362                            (lt (minus (match_dup 0) (pc))
12363                                (const_int 32764)))
12364                       (const_int 4)
12365                       (const_int 8)))])
12367 (define_insn_and_split "*cbranch_2insn"
12368   [(set (pc)
12369         (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12370                                       [(match_operand 2 "cc_reg_operand" "y")
12371                                        (const_int 0)])
12372                       (label_ref (match_operand 0))
12373                       (pc)))]
12374   "!flag_finite_math_only"
12375   "#"
12376   "&& 1"
12377   [(pc)]
12379   rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12381   rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12383   rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12384   rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12385   rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12386   emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12388   if (note)
12389     {
12390       profile_probability prob
12391         = profile_probability::from_reg_br_prob_note (XINT (note, 0));
12393       add_reg_br_prob_note (get_last_insn (), prob);
12394     }
12396   DONE;
12398   [(set_attr "type" "branch")
12399    (set (attr "length")
12400         (if_then_else (and (ge (minus (match_dup 0) (pc))
12401                                (const_int -32764))
12402                            (lt (minus (match_dup 0) (pc))
12403                                (const_int 32760)))
12404                       (const_int 8)
12405                       (const_int 16)))])
12407 ;; Conditional return.
12408 (define_insn "*creturn"
12409   [(set (pc)
12410         (if_then_else (match_operator 0 "branch_comparison_operator"
12411                                       [(match_operand 1 "cc_reg_operand" "y")
12412                                        (const_int 0)])
12413                       (any_return)
12414                       (pc)))]
12415   "<return_pred>"
12417   return output_cbranch (operands[0], NULL, 0, insn);
12419   [(set_attr "type" "jmpreg")])
12421 ;; Logic on condition register values.
12423 ; This pattern matches things like
12424 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12425 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12426 ;                                  (const_int 1)))
12427 ; which are generated by the branch logic.
12428 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12430 (define_insn "@cceq_ior_compare_<mode>"
12431   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12432         (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12433                         [(match_operator:GPR 2
12434                                       "branch_positive_comparison_operator"
12435                                       [(match_operand 3
12436                                                       "cc_reg_operand" "y,y")
12437                                        (const_int 0)])
12438                          (match_operator:GPR 4
12439                                       "branch_positive_comparison_operator"
12440                                       [(match_operand 5
12441                                                       "cc_reg_operand" "0,y")
12442                                        (const_int 0)])])
12443                       (const_int 1)))]
12444   ""
12445   "cr%q1 %E0,%j2,%j4"
12446   [(set_attr "type" "cr_logical")
12447    (set_attr "cr_logical_3op" "no,yes")])
12449 ; Why is the constant -1 here, but 1 in the previous pattern?
12450 ; Because ~1 has all but the low bit set.
12451 (define_insn "cceq_ior_compare_complement"
12452   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12453         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12454                         [(not:SI (match_operator:SI 2
12455                                       "branch_positive_comparison_operator"
12456                                       [(match_operand 3
12457                                                       "cc_reg_operand" "y,y")
12458                                        (const_int 0)]))
12459                          (match_operator:SI 4
12460                                 "branch_positive_comparison_operator"
12461                                 [(match_operand 5
12462                                                 "cc_reg_operand" "0,y")
12463                                  (const_int 0)])])
12464                       (const_int -1)))]
12465   ""
12466   "cr%q1 %E0,%j2,%j4"
12467   [(set_attr "type" "cr_logical")
12468    (set_attr "cr_logical_3op" "no,yes")])
12470 (define_insn "@cceq_rev_compare_<mode>"
12471   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12472         (compare:CCEQ (match_operator:GPR 1
12473                                       "branch_positive_comparison_operator"
12474                                       [(match_operand 2
12475                                                       "cc_reg_operand" "0,y")
12476                                        (const_int 0)])
12477                       (const_int 0)))]
12478   ""
12479   "crnot %E0,%j1"
12480   [(set_attr "type" "cr_logical")
12481    (set_attr "cr_logical_3op" "no,yes")])
12483 ;; If we are comparing the result of two comparisons, this can be done
12484 ;; using creqv or crxor.
12486 (define_insn_and_split ""
12487   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12488         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12489                               [(match_operand 2 "cc_reg_operand" "y")
12490                                (const_int 0)])
12491                       (match_operator 3 "branch_comparison_operator"
12492                               [(match_operand 4 "cc_reg_operand" "y")
12493                                (const_int 0)])))]
12494   ""
12495   "#"
12496   ""
12497   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12498                                     (match_dup 5)))]
12500   int positive_1, positive_2;
12502   positive_1 = branch_positive_comparison_operator (operands[1],
12503                                                     GET_MODE (operands[1]));
12504   positive_2 = branch_positive_comparison_operator (operands[3],
12505                                                     GET_MODE (operands[3]));
12507   if (! positive_1)
12508     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12509                                                             GET_CODE (operands[1])),
12510                                   SImode,
12511                                   operands[2], const0_rtx);
12512   else if (GET_MODE (operands[1]) != SImode)
12513     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12514                                   operands[2], const0_rtx);
12516   if (! positive_2)
12517     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12518                                                             GET_CODE (operands[3])),
12519                                   SImode,
12520                                   operands[4], const0_rtx);
12521   else if (GET_MODE (operands[3]) != SImode)
12522     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12523                                   operands[4], const0_rtx);
12525   if (positive_1 == positive_2)
12526     {
12527       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12528       operands[5] = constm1_rtx;
12529     }
12530   else
12531     {
12532       operands[5] = const1_rtx;
12533     }
12536 ;; Unconditional branch and return.
12538 (define_insn "jump"
12539   [(set (pc)
12540         (label_ref (match_operand 0)))]
12541   ""
12542   "b %l0"
12543   [(set_attr "type" "branch")])
12545 (define_insn "<return_str>return"
12546   [(any_return)]
12547   "<return_pred>"
12548   "blr"
12549   [(set_attr "type" "jmpreg")])
12551 (define_expand "indirect_jump"
12552   [(set (pc) (match_operand 0 "register_operand"))]
12553  ""
12555   if (!rs6000_speculate_indirect_jumps) {
12556     rtx ccreg = gen_reg_rtx (CCmode);
12557     emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12558     DONE;
12559   }
12562 (define_insn "*indirect_jump<mode>"
12563   [(set (pc)
12564         (match_operand:P 0 "register_operand" "c,*l"))]
12565   "rs6000_speculate_indirect_jumps"
12566   "b%T0"
12567   [(set_attr "type" "jmpreg")])
12569 (define_insn "@indirect_jump<mode>_nospec"
12570   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12571    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12572   "!rs6000_speculate_indirect_jumps"
12573   "crset %E1\;beq%T0- %1\;b $"
12574   [(set_attr "type" "jmpreg")
12575    (set_attr "length" "12")])
12577 ;; Table jump for switch statements:
12578 (define_expand "tablejump"
12579   [(use (match_operand 0))
12580    (use (label_ref (match_operand 1)))]
12581   ""
12583   if (rs6000_speculate_indirect_jumps)
12584     {
12585       if (TARGET_32BIT)
12586         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12587       else
12588         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12589     }
12590   else
12591     {
12592       rtx ccreg = gen_reg_rtx (CCmode);
12593       rtx jump;
12594       if (TARGET_32BIT)
12595         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12596       else
12597         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12598       emit_jump_insn (jump);
12599     }
12600   DONE;
12603 (define_expand "tablejumpsi"
12604   [(set (match_dup 3)
12605         (plus:SI (match_operand:SI 0)
12606                  (match_dup 2)))
12607    (parallel [(set (pc)
12608                    (match_dup 3))
12609               (use (label_ref (match_operand 1)))])]
12610   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12612   operands[0] = force_reg (SImode, operands[0]);
12613   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12614   operands[3] = gen_reg_rtx (SImode);
12617 (define_expand "tablejumpsi_nospec"
12618   [(set (match_dup 4)
12619         (plus:SI (match_operand:SI 0)
12620                  (match_dup 3)))
12621    (parallel [(set (pc)
12622                    (match_dup 4))
12623               (use (label_ref (match_operand 1)))
12624               (clobber (match_operand 2))])]
12625   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12627   operands[0] = force_reg (SImode, operands[0]);
12628   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12629   operands[4] = gen_reg_rtx (SImode);
12632 (define_expand "tablejumpdi"
12633   [(set (match_dup 4)
12634         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12635    (set (match_dup 3)
12636         (plus:DI (match_dup 4)
12637                  (match_dup 2)))
12638    (parallel [(set (pc)
12639                    (match_dup 3))
12640               (use (label_ref (match_operand 1)))])]
12641   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12643   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12644   operands[3] = gen_reg_rtx (DImode);
12645   operands[4] = gen_reg_rtx (DImode);
12648 (define_expand "tablejumpdi_nospec"
12649   [(set (match_dup 5)
12650         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12651    (set (match_dup 4)
12652         (plus:DI (match_dup 5)
12653                  (match_dup 3)))
12654    (parallel [(set (pc)
12655                    (match_dup 4))
12656               (use (label_ref (match_operand 1)))
12657               (clobber (match_operand 2))])]
12658   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12660   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12661   operands[4] = gen_reg_rtx (DImode);
12662   operands[5] = gen_reg_rtx (DImode);
12665 (define_insn "*tablejump<mode>_internal1"
12666   [(set (pc)
12667         (match_operand:P 0 "register_operand" "c,*l"))
12668    (use (label_ref (match_operand 1)))]
12669   "rs6000_speculate_indirect_jumps"
12670   "b%T0"
12671   [(set_attr "type" "jmpreg")])
12673 (define_insn "*tablejump<mode>_internal1_nospec"
12674   [(set (pc)
12675         (match_operand:P 0 "register_operand" "c,*l"))
12676    (use (label_ref (match_operand 1)))
12677    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12678   "!rs6000_speculate_indirect_jumps"
12679   "crset %E2\;beq%T0- %2\;b $"
12680   [(set_attr "type" "jmpreg")
12681    (set_attr "length" "12")])
12683 (define_insn "nop"
12684   [(unspec [(const_int 0)] UNSPEC_NOP)]
12685   ""
12686   "nop")
12688 (define_insn "group_ending_nop"
12689   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12690   ""
12692   operands[0] = gen_rtx_REG (Pmode,
12693                              rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12694   return "ori %0,%0,0";
12697 (define_insn "speculation_barrier"
12698   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12699   ""
12701   operands[0] = gen_rtx_REG (Pmode, 31);
12702   return "ori %0,%0,0";
12705 ;; Define the subtract-one-and-jump insns, starting with the template
12706 ;; so loop.c knows what to generate.
12708 (define_expand "doloop_end"
12709   [(use (match_operand 0))      ; loop pseudo
12710    (use (match_operand 1))]     ; label
12711   ""
12713   if (GET_MODE (operands[0]) != Pmode)
12714     FAIL;
12716   emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12717   DONE;
12720 (define_expand "@ctr<mode>"
12721   [(parallel [(set (pc)
12722                    (if_then_else (ne (match_operand:P 0 "register_operand")
12723                                      (const_int 1))
12724                                  (label_ref (match_operand 1))
12725                                  (pc)))
12726               (set (match_dup 0)
12727                    (plus:P (match_dup 0)
12728                             (const_int -1)))
12729               (clobber (match_scratch:CC 2))
12730               (clobber (match_scratch:P 3))])]
12731   ""
12732   "")
12734 ;; We need to be able to do this for any operand, including MEM, or we
12735 ;; will cause reload to blow up since we don't allow output reloads on
12736 ;; JUMP_INSNs.
12737 ;; For the length attribute to be calculated correctly, the
12738 ;; label MUST be operand 0.
12739 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12740 ;; the ctr<mode> insns.
12742 (define_code_iterator eqne [eq ne])
12743 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12744 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12746 (define_insn "<bd>_<mode>"
12747   [(set (pc)
12748         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12749                           (const_int 1))
12750                       (label_ref (match_operand 0))
12751                       (pc)))
12752    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12753         (plus:P (match_dup 1)
12754                 (const_int -1)))
12755    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12756    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12757   ""
12759   if (which_alternative != 0)
12760     return "#";
12761   else if (get_attr_length (insn) == 4)
12762     return "<bd> %l0";
12763   else
12764     return "<bd_neg> $+8\;b %l0";
12766   [(set_attr "type" "branch")
12767    (set_attr_alternative "length"
12768      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12769                              (const_int -32768))
12770                          (lt (minus (match_dup 0) (pc))
12771                              (const_int 32764)))
12772                     (const_int 4)
12773                     (const_int 8))
12774       (const_string "16")
12775       (const_string "20")
12776       (const_string "20")])])
12778 ;; Now the splitter if we could not allocate the CTR register
12779 (define_split
12780   [(set (pc)
12781         (if_then_else (match_operator 2 "comparison_operator"
12782                                       [(match_operand:P 1 "gpc_reg_operand")
12783                                        (const_int 1)])
12784                       (match_operand 5)
12785                       (match_operand 6)))
12786    (set (match_operand:P 0 "nonimmediate_operand")
12787         (plus:P (match_dup 1)
12788                 (const_int -1)))
12789    (clobber (match_scratch:CC 3))
12790    (clobber (match_scratch:P 4))]
12791   "reload_completed"
12792   [(set (pc)
12793         (if_then_else (match_dup 7)
12794                       (match_dup 5)
12795                       (match_dup 6)))]
12797   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12798                                 const0_rtx);
12799   emit_insn (gen_rtx_SET (operands[3],
12800                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12801   if (int_reg_operand (operands[0], <MODE>mode))
12802     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12803   else
12804     {
12805       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12806       emit_move_insn (operands[0], operands[4]);
12807     } 
12808     /* No DONE so branch comes from the pattern.  */
12811 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12812 ;; Note that in the case of long branches we have to decompose this into
12813 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12814 ;; and the CR bit, which means there is no way to conveniently invert the
12815 ;; comparison as is done with plain bdnz/bdz.
12817 (define_insn "<bd>tf_<mode>"
12818   [(set (pc)
12819         (if_then_else
12820           (and
12821              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12822                    (const_int 1))
12823              (match_operator 3 "branch_comparison_operator"
12824                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12825                        (const_int 0)]))
12826           (label_ref (match_operand 0))
12827           (pc)))
12828    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12829         (plus:P (match_dup 1)
12830                 (const_int -1)))
12831    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12832    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12833    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12834   ""
12836   if (which_alternative != 0)
12837     return "#";
12838   else if (get_attr_length (insn) == 4)
12839     {
12840       if (branch_positive_comparison_operator (operands[3],
12841                                                GET_MODE (operands[3])))
12842         return "<bd>t %j3,%l0";
12843       else
12844         return "<bd>f %j3,%l0";
12845     }
12846   else
12847     {
12848       static char seq[96];
12849       char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12850       sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12851       return seq;
12852     }
12854   [(set_attr "type" "branch")
12855    (set_attr_alternative "length"
12856      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12857                              (const_int -32768))
12858                          (lt (minus (match_dup 0) (pc))
12859                              (const_int 32764)))
12860                     (const_int 4)
12861                     (const_int 8))
12862       (const_string "16")
12863       (const_string "20")
12864       (const_string "20")])])
12866 ;; Now the splitter if we could not allocate the CTR register
12867 (define_split
12868   [(set (pc)
12869         (if_then_else
12870           (and
12871              (match_operator 1 "comparison_operator"
12872                              [(match_operand:P 0 "gpc_reg_operand")
12873                               (const_int 1)])
12874              (match_operator 3 "branch_comparison_operator"
12875                       [(match_operand 2 "cc_reg_operand")
12876                        (const_int 0)]))
12877           (match_operand 4)
12878           (match_operand 5)))
12879    (set (match_operand:P 6 "nonimmediate_operand")
12880         (plus:P (match_dup 0)
12881                 (const_int -1)))
12882    (clobber (match_scratch:P 7))
12883    (clobber (match_scratch:CC 8))
12884    (clobber (match_scratch:CCEQ 9))]
12885   "reload_completed"
12886 [(pc)]
12888   rtx ctr = operands[0];
12889   rtx ctrcmp = operands[1];
12890   rtx ccin = operands[2];
12891   rtx cccmp = operands[3];
12892   rtx dst1 = operands[4];
12893   rtx dst2 = operands[5];
12894   rtx ctrout = operands[6];
12895   rtx ctrtmp = operands[7];
12896   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12897   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12898   if (!ispos)
12899     cmpcode = reverse_condition (cmpcode);
12900   /* Generate crand/crandc here.  */
12901   emit_insn (gen_rtx_SET (operands[8],
12902                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12903   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12905   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12906   if (ispos)
12907      emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
12908                                       operands[8], cccmp, ccin));
12909   else
12910      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12911                                                  operands[8], cccmp, ccin));
12912   if (int_reg_operand (ctrout, <MODE>mode))
12913      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12914   else
12915     {
12916       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12917       emit_move_insn (ctrout, ctrtmp);
12918     }
12919   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12920   emit_jump_insn (gen_rtx_SET (pc_rtx,
12921                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12922                                                      dst1, dst2)));
12923   DONE;
12927 (define_insn "trap"
12928   [(trap_if (const_int 1) (const_int 0))]
12929   ""
12930   "trap"
12931   [(set_attr "type" "trap")])
12933 (define_expand "ctrap<mode>4"
12934   [(trap_if (match_operator 0 "ordered_comparison_operator"
12935                             [(match_operand:GPR 1 "register_operand")
12936                              (match_operand:GPR 2 "reg_or_short_operand")])
12937             (match_operand 3 "zero_constant" ""))]
12938   ""
12939   "")
12941 (define_insn ""
12942   [(trap_if (match_operator 0 "ordered_comparison_operator"
12943                             [(match_operand:GPR 1 "register_operand" "r")
12944                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12945             (const_int 0))]
12946   ""
12947   "t<wd>%V0%I2 %1,%2"
12948   [(set_attr "type" "trap")])
12950 ;; Insns related to generating the function prologue and epilogue.
12952 (define_expand "prologue"
12953   [(use (const_int 0))]
12954   ""
12956   rs6000_emit_prologue ();
12957   if (!TARGET_SCHED_PROLOG)
12958     emit_insn (gen_blockage ());
12959   DONE;
12962 (define_insn "*movesi_from_cr_one"
12963   [(match_parallel 0 "mfcr_operation"
12964                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12965                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12966                                      (match_operand 3 "immediate_operand" "n")]
12967                           UNSPEC_MOVESI_FROM_CR))])]
12968   "TARGET_MFCRF"
12970   int mask = 0;
12971   int i;
12972   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12973   {
12974     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12975     operands[4] = GEN_INT (mask);
12976     output_asm_insn ("mfcr %1,%4", operands);
12977   }
12978   return "";
12980   [(set_attr "type" "mfcrf")])
12982 ;; Don't include the volatile CRs since their values are not used wrt CR save
12983 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12984 ;; prologue past an insn (early exit test) that defines a register used in the
12985 ;; prologue.
12986 (define_insn "prologue_movesi_from_cr"
12987   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12988         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12989                     (reg:CC CR4_REGNO)]
12990                    UNSPEC_MOVESI_FROM_CR))]
12991   ""
12992   "mfcr %0"
12993   [(set_attr "type" "mfcr")])
12995 (define_insn "*crsave"
12996   [(match_parallel 0 "crsave_operation"
12997                    [(set (match_operand:SI 1 "memory_operand" "=m")
12998                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12999   ""
13000   "stw %2,%1"
13001   [(set_attr "type" "store")])
13003 (define_insn "*stmw"
13004   [(match_parallel 0 "stmw_operation"
13005                    [(set (match_operand:SI 1 "memory_operand" "=m")
13006                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13007   "TARGET_MULTIPLE"
13008   "stmw %2,%1"
13009   [(set_attr "type" "store")
13010    (set_attr "update" "yes")
13011    (set_attr "indexed" "yes")])
13013 ; The following comment applies to:
13014 ;     save_gpregs_*
13015 ;     save_fpregs_*
13016 ;     restore_gpregs*
13017 ;     return_and_restore_gpregs*
13018 ;     return_and_restore_fpregs*
13019 ;     return_and_restore_fpregs_aix*
13021 ; The out-of-line save / restore functions expects one input argument.
13022 ; Since those are not standard call_insn's, we must avoid using
13023 ; MATCH_OPERAND for that argument. That way the register rename
13024 ; optimization will not try to rename this register.
13025 ; Each pattern is repeated for each possible register number used in 
13026 ; various ABIs (r11, r1, and for some functions r12)
13028 (define_insn "*save_gpregs_<mode>_r11"
13029   [(match_parallel 0 "any_parallel_operand"
13030                    [(clobber (reg:P LR_REGNO))
13031                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13032                     (use (reg:P 11))
13033                     (set (match_operand:P 2 "memory_operand" "=m")
13034                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13035   ""
13036   "bl %1"
13037   [(set_attr "type" "branch")])
13039 (define_insn "*save_gpregs_<mode>_r12"
13040   [(match_parallel 0 "any_parallel_operand"
13041                    [(clobber (reg:P LR_REGNO))
13042                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13043                     (use (reg:P 12))
13044                     (set (match_operand:P 2 "memory_operand" "=m")
13045                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13046   ""
13047   "bl %1"
13048   [(set_attr "type" "branch")])
13050 (define_insn "*save_gpregs_<mode>_r1"
13051   [(match_parallel 0 "any_parallel_operand"
13052                    [(clobber (reg:P LR_REGNO))
13053                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13054                     (use (reg:P 1))
13055                     (set (match_operand:P 2 "memory_operand" "=m")
13056                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13057   ""
13058   "bl %1"
13059   [(set_attr "type" "branch")])
13061 (define_insn "*save_fpregs_<mode>_r11"
13062   [(match_parallel 0 "any_parallel_operand"
13063                    [(clobber (reg:P LR_REGNO))
13064                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13065                     (use (reg:P 11))
13066                     (set (match_operand:DF 2 "memory_operand" "=m")
13067                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13068   ""
13069   "bl %1"
13070   [(set_attr "type" "branch")])
13072 (define_insn "*save_fpregs_<mode>_r12"
13073   [(match_parallel 0 "any_parallel_operand"
13074                    [(clobber (reg:P LR_REGNO))
13075                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13076                     (use (reg:P 12))
13077                     (set (match_operand:DF 2 "memory_operand" "=m")
13078                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13079   ""
13080   "bl %1"
13081   [(set_attr "type" "branch")])
13083 (define_insn "*save_fpregs_<mode>_r1"
13084   [(match_parallel 0 "any_parallel_operand"
13085                    [(clobber (reg:P LR_REGNO))
13086                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13087                     (use (reg:P 1))
13088                     (set (match_operand:DF 2 "memory_operand" "=m")
13089                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13090   ""
13091   "bl %1"
13092   [(set_attr "type" "branch")])
13094 ; This is to explain that changes to the stack pointer should
13095 ; not be moved over loads from or stores to stack memory.
13096 (define_insn "stack_tie"
13097   [(match_parallel 0 "tie_operand"
13098                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13099   ""
13100   ""
13101   [(set_attr "length" "0")])
13103 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13104 ; stay behind all restores from the stack, it cannot be reordered to before
13105 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13106 (define_insn "stack_restore_tie"
13107   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13108         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13109                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13110    (set (mem:BLK (scratch)) (const_int 0))]
13111   "TARGET_32BIT"
13112   "@
13113    mr %0,%1
13114    add%I2 %0,%1,%2"
13115   [(set_attr "type" "*,add")])
13117 (define_expand "epilogue"
13118   [(use (const_int 0))]
13119   ""
13121   if (!TARGET_SCHED_PROLOG)
13122     emit_insn (gen_blockage ());
13123   rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13124   DONE;
13127 ; On some processors, doing the mtcrf one CC register at a time is
13128 ; faster (like on the 604e).  On others, doing them all at once is
13129 ; faster; for instance, on the 601 and 750.
13131 (define_expand "movsi_to_cr_one"
13132   [(set (match_operand:CC 0 "cc_reg_operand")
13133         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13134                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13135   ""
13136   "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13138 (define_insn "*movsi_to_cr"
13139   [(match_parallel 0 "mtcrf_operation"
13140                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13141                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13142                                      (match_operand 3 "immediate_operand" "n")]
13143                                     UNSPEC_MOVESI_TO_CR))])]
13144  ""
13146   int mask = 0;
13147   int i;
13148   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13149     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13150   operands[4] = GEN_INT (mask);
13151   return "mtcrf %4,%2";
13153   [(set_attr "type" "mtcr")])
13155 (define_insn "*mtcrfsi"
13156   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13157         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13158                     (match_operand 2 "immediate_operand" "n")]
13159                    UNSPEC_MOVESI_TO_CR))]
13160   "REG_P (operands[0])
13161    && CR_REGNO_P (REGNO (operands[0]))
13162    && CONST_INT_P (operands[2])
13163    && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13164   "mtcrf %R0,%1"
13165   [(set_attr "type" "mtcr")])
13167 ; The load-multiple instructions have similar properties.
13168 ; Note that "load_multiple" is a name known to the machine-independent
13169 ; code that actually corresponds to the PowerPC load-string.
13171 (define_insn "*lmw"
13172   [(match_parallel 0 "lmw_operation"
13173                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13174                          (match_operand:SI 2 "memory_operand" "m"))])]
13175   "TARGET_MULTIPLE"
13176   "lmw %1,%2"
13177   [(set_attr "type" "load")
13178    (set_attr "update" "yes")
13179    (set_attr "indexed" "yes")
13180    (set_attr "cell_micro" "always")])
13182 ; FIXME: "any_parallel_operand" is a bit flexible...
13184 ; The following comment applies to:
13185 ;     save_gpregs_*
13186 ;     save_fpregs_*
13187 ;     restore_gpregs*
13188 ;     return_and_restore_gpregs*
13189 ;     return_and_restore_fpregs*
13190 ;     return_and_restore_fpregs_aix*
13192 ; The out-of-line save / restore functions expects one input argument.
13193 ; Since those are not standard call_insn's, we must avoid using
13194 ; MATCH_OPERAND for that argument. That way the register rename
13195 ; optimization will not try to rename this register.
13196 ; Each pattern is repeated for each possible register number used in 
13197 ; various ABIs (r11, r1, and for some functions r12)
13199 (define_insn "*restore_gpregs_<mode>_r11"
13200  [(match_parallel 0 "any_parallel_operand"
13201                   [(clobber (reg:P LR_REGNO))
13202                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13203                    (use (reg:P 11))
13204                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13205                         (match_operand:P 3 "memory_operand" "m"))])]
13206  ""
13207  "bl %1"
13208  [(set_attr "type" "branch")])
13210 (define_insn "*restore_gpregs_<mode>_r12"
13211  [(match_parallel 0 "any_parallel_operand"
13212                   [(clobber (reg:P LR_REGNO))
13213                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13214                    (use (reg:P 12))
13215                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13216                         (match_operand:P 3 "memory_operand" "m"))])]
13217  ""
13218  "bl %1"
13219  [(set_attr "type" "branch")])
13221 (define_insn "*restore_gpregs_<mode>_r1"
13222  [(match_parallel 0 "any_parallel_operand"
13223                   [(clobber (reg:P LR_REGNO))
13224                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13225                    (use (reg:P 1))
13226                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13227                         (match_operand:P 3 "memory_operand" "m"))])]
13228  ""
13229  "bl %1"
13230  [(set_attr "type" "branch")])
13232 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13233  [(match_parallel 0 "any_parallel_operand"
13234                   [(return)
13235                    (clobber (reg:P LR_REGNO))
13236                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13237                    (use (reg:P 11))
13238                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13239                         (match_operand:P 3 "memory_operand" "m"))])]
13240  ""
13241  "b %1"
13242  [(set_attr "type" "branch")])
13244 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13245  [(match_parallel 0 "any_parallel_operand"
13246                   [(return)
13247                    (clobber (reg:P LR_REGNO))
13248                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13249                    (use (reg:P 12))
13250                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13251                         (match_operand:P 3 "memory_operand" "m"))])]
13252  ""
13253  "b %1"
13254  [(set_attr "type" "branch")])
13256 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13257  [(match_parallel 0 "any_parallel_operand"
13258                   [(return)
13259                    (clobber (reg:P LR_REGNO))
13260                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13261                    (use (reg:P 1))
13262                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13263                         (match_operand:P 3 "memory_operand" "m"))])]
13264  ""
13265  "b %1"
13266  [(set_attr "type" "branch")])
13268 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13269  [(match_parallel 0 "any_parallel_operand"
13270                   [(return)
13271                    (clobber (reg:P LR_REGNO))
13272                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13273                    (use (reg:P 11))
13274                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13275                         (match_operand:DF 3 "memory_operand" "m"))])]
13276  ""
13277  "b %1"
13278  [(set_attr "type" "branch")])
13280 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13281  [(match_parallel 0 "any_parallel_operand"
13282                   [(return)
13283                    (clobber (reg:P LR_REGNO))
13284                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13285                    (use (reg:P 12))
13286                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13287                         (match_operand:DF 3 "memory_operand" "m"))])]
13288  ""
13289  "b %1"
13290  [(set_attr "type" "branch")])
13292 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13293  [(match_parallel 0 "any_parallel_operand"
13294                   [(return)
13295                    (clobber (reg:P LR_REGNO))
13296                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13297                    (use (reg:P 1))
13298                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13299                         (match_operand:DF 3 "memory_operand" "m"))])]
13300  ""
13301  "b %1"
13302  [(set_attr "type" "branch")])
13304 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13305  [(match_parallel 0 "any_parallel_operand"
13306                   [(return)
13307                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13308                    (use (reg:P 11))
13309                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13310                         (match_operand:DF 3 "memory_operand" "m"))])]
13311  ""
13312  "b %1"
13313  [(set_attr "type" "branch")])
13315 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13316  [(match_parallel 0 "any_parallel_operand"
13317                   [(return)
13318                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13319                    (use (reg:P 1))
13320                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13321                         (match_operand:DF 3 "memory_operand" "m"))])]
13322  ""
13323  "b %1"
13324  [(set_attr "type" "branch")])
13326 ; This is used in compiling the unwind routines.
13327 (define_expand "eh_return"
13328   [(use (match_operand 0 "general_operand"))]
13329   ""
13331   emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13332   DONE;
13335 ; We can't expand this before we know where the link register is stored.
13336 (define_insn_and_split "@eh_set_lr_<mode>"
13337   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13338    (clobber (match_scratch:P 1 "=&b"))]
13339   ""
13340   "#"
13341   "reload_completed"
13342   [(const_int 0)]
13344   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13345   DONE;
13348 (define_insn "prefetch"
13349   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13350              (match_operand:SI 1 "const_int_operand" "n")
13351              (match_operand:SI 2 "const_int_operand" "n"))]
13352   ""
13356   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13357      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13358      The AIX assembler does not support the three operand form of dcbt
13359      and dcbtst on Power 7 (-mpwr7).  */
13360   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13362   if (REG_P (operands[0]))
13363     {
13364       if (INTVAL (operands[1]) == 0)
13365         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13366       else
13367         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13368     }
13369   else
13370     {
13371       if (INTVAL (operands[1]) == 0)
13372         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13373       else
13374         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13375     }
13377   [(set_attr "type" "load")])
13379 ;; Handle -fsplit-stack.
13381 (define_expand "split_stack_prologue"
13382   [(const_int 0)]
13383   ""
13385   rs6000_expand_split_stack_prologue ();
13386   DONE;
13389 (define_expand "load_split_stack_limit"
13390   [(set (match_operand 0)
13391         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13392   ""
13394   emit_insn (gen_rtx_SET (operands[0],
13395                           gen_rtx_UNSPEC (Pmode,
13396                                           gen_rtvec (1, const0_rtx),
13397                                           UNSPEC_STACK_CHECK)));
13398   DONE;
13401 (define_insn "load_split_stack_limit_di"
13402   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13403         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13404   "TARGET_64BIT"
13405   "ld %0,-0x7040(13)"
13406   [(set_attr "type" "load")
13407    (set_attr "update" "no")
13408    (set_attr "indexed" "no")])
13410 (define_insn "load_split_stack_limit_si"
13411   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13412         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13413   "!TARGET_64BIT"
13414   "lwz %0,-0x7020(2)"
13415   [(set_attr "type" "load")
13416    (set_attr "update" "no")
13417    (set_attr "indexed" "no")])
13419 ;; A return instruction which the middle-end doesn't see.
13420 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13421 ;; after the call to __morestack.
13422 (define_insn "split_stack_return"
13423   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13424   ""
13425   "blr"
13426   [(set_attr "type" "jmpreg")])
13428 ;; If there are operand 0 bytes available on the stack, jump to
13429 ;; operand 1.
13430 (define_expand "split_stack_space_check"
13431   [(set (match_dup 2)
13432         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13433    (set (match_dup 3)
13434         (minus (reg STACK_POINTER_REGNUM)
13435                (match_operand 0)))
13436    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13437    (set (pc) (if_then_else
13438               (geu (match_dup 4) (const_int 0))
13439               (label_ref (match_operand 1))
13440               (pc)))]
13441   ""
13443   rs6000_split_stack_space_check (operands[0], operands[1]);
13444   DONE;
13447 (define_insn "bpermd_<mode>"
13448   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13449         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13450                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13451   "TARGET_POPCNTD"
13452   "bpermd %0,%1,%2"
13453   [(set_attr "type" "popcnt")])
13456 ;; Builtin fma support.  Handle 
13457 ;; Note that the conditions for expansion are in the FMA_F iterator.
13459 (define_expand "fma<mode>4"
13460   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13461         (fma:FMA_F
13462           (match_operand:FMA_F 1 "gpc_reg_operand")
13463           (match_operand:FMA_F 2 "gpc_reg_operand")
13464           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13465   ""
13466   "")
13468 (define_insn "*fma<mode>4_fpr"
13469   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13470         (fma:SFDF
13471           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13472           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13473           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13474   "TARGET_HARD_FLOAT"
13475   "@
13476    fmadd<s> %0,%1,%2,%3
13477    xsmadda<sd>p %x0,%x1,%x2
13478    xsmaddm<sd>p %x0,%x1,%x3"
13479   [(set_attr "type" "fp")
13480    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13482 ; Altivec only has fma and nfms.
13483 (define_expand "fms<mode>4"
13484   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13485         (fma:FMA_F
13486           (match_operand:FMA_F 1 "gpc_reg_operand")
13487           (match_operand:FMA_F 2 "gpc_reg_operand")
13488           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13489   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13490   "")
13492 (define_insn "*fms<mode>4_fpr"
13493   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13494         (fma:SFDF
13495          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13496          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13497          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13498   "TARGET_HARD_FLOAT"
13499   "@
13500    fmsub<s> %0,%1,%2,%3
13501    xsmsuba<sd>p %x0,%x1,%x2
13502    xsmsubm<sd>p %x0,%x1,%x3"
13503   [(set_attr "type" "fp")
13504    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13506 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13507 (define_expand "fnma<mode>4"
13508   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13509         (neg:FMA_F
13510           (fma:FMA_F
13511             (match_operand:FMA_F 1 "gpc_reg_operand")
13512             (match_operand:FMA_F 2 "gpc_reg_operand")
13513             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13514   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13515   "")
13517 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13518 (define_expand "fnms<mode>4"
13519   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13520         (neg:FMA_F
13521           (fma:FMA_F
13522             (match_operand:FMA_F 1 "gpc_reg_operand")
13523             (match_operand:FMA_F 2 "gpc_reg_operand")
13524             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13525   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13526   "")
13528 ; Not an official optab name, but used from builtins.
13529 (define_expand "nfma<mode>4"
13530   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13531         (neg:FMA_F
13532           (fma:FMA_F
13533             (match_operand:FMA_F 1 "gpc_reg_operand")
13534             (match_operand:FMA_F 2 "gpc_reg_operand")
13535             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13536   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13537   "")
13539 (define_insn "*nfma<mode>4_fpr"
13540   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13541         (neg:SFDF
13542          (fma:SFDF
13543           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13544           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13545           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13546   "TARGET_HARD_FLOAT"
13547   "@
13548    fnmadd<s> %0,%1,%2,%3
13549    xsnmadda<sd>p %x0,%x1,%x2
13550    xsnmaddm<sd>p %x0,%x1,%x3"
13551   [(set_attr "type" "fp")
13552    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13554 ; Not an official optab name, but used from builtins.
13555 (define_expand "nfms<mode>4"
13556   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13557         (neg:FMA_F
13558           (fma:FMA_F
13559             (match_operand:FMA_F 1 "gpc_reg_operand")
13560             (match_operand:FMA_F 2 "gpc_reg_operand")
13561             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13562   ""
13563   "")
13565 (define_insn "*nfmssf4_fpr"
13566   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13567         (neg:SFDF
13568          (fma:SFDF
13569           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13570           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13571           (neg:SFDF
13572            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13573   "TARGET_HARD_FLOAT"
13574   "@
13575    fnmsub<s> %0,%1,%2,%3
13576    xsnmsuba<sd>p %x0,%x1,%x2
13577    xsnmsubm<sd>p %x0,%x1,%x3"
13578   [(set_attr "type" "fp")
13579    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13581 (define_expand "rs6000_get_timebase"
13582   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13583   ""
13585   if (TARGET_POWERPC64)
13586     emit_insn (gen_rs6000_mftb_di (operands[0]));
13587   else
13588     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13589   DONE;
13592 (define_insn "rs6000_get_timebase_ppc32"
13593   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13594         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13595    (clobber (match_scratch:SI 1 "=r"))
13596    (clobber (match_scratch:CC 2 "=y"))]
13597   "!TARGET_POWERPC64"
13599   if (WORDS_BIG_ENDIAN)
13600     if (TARGET_MFCRF)
13601       {
13602         return "mfspr %0,269\;"
13603                "mfspr %L0,268\;"
13604                "mfspr %1,269\;"
13605                "cmpw %2,%0,%1\;"
13606                "bne- %2,$-16";
13607       }
13608     else
13609       {
13610         return "mftbu %0\;"
13611                "mftb %L0\;"
13612                "mftbu %1\;"
13613                "cmpw %2,%0,%1\;"
13614                "bne- %2,$-16";
13615       }
13616   else
13617     if (TARGET_MFCRF)
13618       {
13619         return "mfspr %L0,269\;"
13620                "mfspr %0,268\;"
13621                "mfspr %1,269\;"
13622                "cmpw %2,%L0,%1\;"
13623                "bne- %2,$-16";
13624       }
13625     else
13626       {
13627         return "mftbu %L0\;"
13628                "mftb %0\;"
13629                "mftbu %1\;"
13630                "cmpw %2,%L0,%1\;"
13631                "bne- %2,$-16";
13632       }
13634   [(set_attr "length" "20")])
13636 (define_insn "rs6000_mftb_<mode>"
13637   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13638         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13639   ""
13641   if (TARGET_MFCRF)
13642     return "mfspr %0,268";
13643   else
13644     return "mftb %0";
13648 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13649 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13650 (define_insn "rs6000_mffsl_hw"
13651   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13652         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13653   "TARGET_HARD_FLOAT"
13654   "mffsl %0")
13656 (define_expand "rs6000_mffsl"
13657   [(set (match_operand:DF 0 "gpc_reg_operand")
13658         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13659   "TARGET_HARD_FLOAT"
13661   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13662      otherwise fall back to the older mffs instruction to emulate the mffsl
13663      instruction.  */
13665   if (!TARGET_P9_MISC)
13666     {
13667        rtx tmp_di = gen_reg_rtx (DImode);
13668        rtx tmp_df = gen_reg_rtx (DFmode);
13670        /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13671           instruction using the mffs instruction and masking off the bits
13672           the mmsl instruciton actually reads.  */
13673        emit_insn (gen_rs6000_mffs (tmp_df));
13674        tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13675        emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13677        operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13678        DONE;
13679     }
13681     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13682     DONE;
13685 (define_insn "rs6000_mffs"
13686   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13687         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13688   "TARGET_HARD_FLOAT"
13689   "mffs %0")
13691 (define_insn "rs6000_mtfsf"
13692   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13693                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13694                     UNSPECV_MTFSF)]
13695   "TARGET_HARD_FLOAT"
13696   "mtfsf %0,%1")
13698 (define_insn "rs6000_mtfsf_hi"
13699   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13700                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13701                     UNSPECV_MTFSF_HI)]
13702   "TARGET_HARD_FLOAT"
13703   "mtfsf %0,%1,0,1")
13706 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13707 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13708 ;; register that is being loaded.  The fused ops must be physically adjacent.
13710 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13711 ;; peephole2 then gathers any other fused possibilities that it can find after
13712 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13713 ;; point loads/stores.
13715 ;; Find cases where the addis that feeds into a load instruction is either used
13716 ;; once or is the same as the target register, and replace it with the fusion
13717 ;; insn
13719 (define_peephole2
13720   [(set (match_operand:P 0 "base_reg_operand")
13721         (match_operand:P 1 "fusion_gpr_addis"))
13722    (set (match_operand:INT1 2 "base_reg_operand")
13723         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13724   "TARGET_P8_FUSION
13725    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13726                          operands[3])"
13727   [(const_int 0)]
13729   expand_fusion_gpr_load (operands);
13730   DONE;
13733 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13734 ;; reload)
13736 (define_insn "*fusion_gpr_load_<mode>"
13737   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13738         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13739                      UNSPEC_FUSION_GPR))]
13740   "TARGET_P8_FUSION"
13742   return emit_fusion_gpr_load (operands[0], operands[1]);
13744   [(set_attr "type" "load")
13745    (set_attr "length" "8")])
13748 ;; Optimize cases where we want to do a D-form load (register+offset) on
13749 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13750 ;; has generated:
13751 ;;      LFD 0,32(3)
13752 ;;      XXLOR 32,0,0
13754 ;; and we change this to:
13755 ;;      LI 0,32
13756 ;;      LXSDX 32,3,9
13758 (define_peephole2
13759   [(match_scratch:P 0 "b")
13760    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13761         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13762    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13763         (match_dup 1))]
13764   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13765   [(set (match_dup 0)
13766         (match_dup 4))
13767    (set (match_dup 3)
13768         (match_dup 5))]
13770   rtx tmp_reg = operands[0];
13771   rtx mem = operands[2];
13772   rtx addr = XEXP (mem, 0);
13773   rtx add_op0, add_op1, new_addr;
13775   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13776   add_op0 = XEXP (addr, 0);
13777   add_op1 = XEXP (addr, 1);
13778   gcc_assert (REG_P (add_op0));
13779   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13781   operands[4] = add_op1;
13782   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13785 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13786 ;; Altivec register, and the register allocator has generated:
13787 ;;      XXLOR 0,32,32
13788 ;;      STFD 0,32(3)
13790 ;; and we change this to:
13791 ;;      LI 0,32
13792 ;;      STXSDX 32,3,9
13794 (define_peephole2
13795   [(match_scratch:P 0 "b")
13796    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13797         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13798    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13799         (match_dup 1))]
13800   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13801   [(set (match_dup 0)
13802         (match_dup 4))
13803    (set (match_dup 5)
13804         (match_dup 2))]
13806   rtx tmp_reg = operands[0];
13807   rtx mem = operands[3];
13808   rtx addr = XEXP (mem, 0);
13809   rtx add_op0, add_op1, new_addr;
13811   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13812   add_op0 = XEXP (addr, 0);
13813   add_op1 = XEXP (addr, 1);
13814   gcc_assert (REG_P (add_op0));
13815   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13817   operands[4] = add_op1;
13818   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13820    
13822 ;; Miscellaneous ISA 2.06 (power7) instructions
13823 (define_insn "addg6s"
13824   [(set (match_operand:SI 0 "register_operand" "=r")
13825         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13826                     (match_operand:SI 2 "register_operand" "r")]
13827                    UNSPEC_ADDG6S))]
13828   "TARGET_POPCNTD"
13829   "addg6s %0,%1,%2"
13830   [(set_attr "type" "integer")])
13832 (define_insn "cdtbcd"
13833   [(set (match_operand:SI 0 "register_operand" "=r")
13834         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13835                    UNSPEC_CDTBCD))]
13836   "TARGET_POPCNTD"
13837   "cdtbcd %0,%1"
13838   [(set_attr "type" "integer")])
13840 (define_insn "cbcdtd"
13841   [(set (match_operand:SI 0 "register_operand" "=r")
13842         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13843                    UNSPEC_CBCDTD))]
13844   "TARGET_POPCNTD"
13845   "cbcdtd %0,%1"
13846   [(set_attr "type" "integer")])
13848 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13849                                         UNSPEC_DIVEU])
13851 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13852                              (UNSPEC_DIVEU      "eu")])
13854 (define_insn "div<div_extend>_<mode>"
13855   [(set (match_operand:GPR 0 "register_operand" "=r")
13856         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13857                      (match_operand:GPR 2 "register_operand" "r")]
13858                     UNSPEC_DIV_EXTEND))]
13859   "TARGET_POPCNTD"
13860   "div<wd><div_extend> %0,%1,%2"
13861   [(set_attr "type" "div")
13862    (set_attr "size" "<bits>")])
13865 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13867 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13868 (define_mode_attr FP128_64 [(TF "DF")
13869                             (IF "DF")
13870                             (TD "DI")
13871                             (KF "DI")])
13873 (define_expand "unpack<mode>"
13874   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13875         (unspec:<FP128_64>
13876          [(match_operand:FMOVE128 1 "register_operand")
13877           (match_operand:QI 2 "const_0_to_1_operand")]
13878          UNSPEC_UNPACK_128BIT))]
13879   "FLOAT128_2REG_P (<MODE>mode)"
13880   "")
13882 (define_insn_and_split "unpack<mode>_dm"
13883   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13884         (unspec:<FP128_64>
13885          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13886           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13887          UNSPEC_UNPACK_128BIT))]
13888   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13889   "#"
13890   "&& reload_completed"
13891   [(set (match_dup 0) (match_dup 3))]
13893   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13895   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13896     {
13897       emit_note (NOTE_INSN_DELETED);
13898       DONE;
13899     }
13901   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13903   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13905 (define_insn_and_split "unpack<mode>_nodm"
13906   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13907         (unspec:<FP128_64>
13908          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13909           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13910          UNSPEC_UNPACK_128BIT))]
13911   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13912   "#"
13913   "&& reload_completed"
13914   [(set (match_dup 0) (match_dup 3))]
13916   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13918   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13919     {
13920       emit_note (NOTE_INSN_DELETED);
13921       DONE;
13922     }
13924   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13926   [(set_attr "type" "fp,fpstore")])
13928 (define_insn_and_split "pack<mode>"
13929   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13930         (unspec:FMOVE128
13931          [(match_operand:<FP128_64> 1 "register_operand" "d")
13932           (match_operand:<FP128_64> 2 "register_operand" "d")]
13933          UNSPEC_PACK_128BIT))]
13934   "FLOAT128_2REG_P (<MODE>mode)"
13935   "#"
13936   "&& reload_completed"
13937   [(set (match_dup 3) (match_dup 1))
13938    (set (match_dup 4) (match_dup 2))]
13940   unsigned dest_hi = REGNO (operands[0]);
13941   unsigned dest_lo = dest_hi + 1;
13943   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13944   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13946   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13947   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13949   [(set_attr "type" "fp")
13950    (set_attr "length" "8")])
13952 (define_insn "unpack<mode>"
13953   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13954         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13955                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13956          UNSPEC_UNPACK_128BIT))]
13957   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13959   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13960     return ASM_COMMENT_START " xxpermdi to same register";
13962   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13963   return "xxpermdi %x0,%x1,%x1,%3";
13965   [(set_attr "type" "vecperm")])
13967 (define_insn "pack<mode>"
13968   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13969         (unspec:FMOVE128_VSX
13970          [(match_operand:DI 1 "register_operand" "wa")
13971           (match_operand:DI 2 "register_operand" "wa")]
13972          UNSPEC_PACK_128BIT))]
13973   "TARGET_VSX"
13974   "xxpermdi %x0,%x1,%x2,0"
13975   [(set_attr "type" "vecperm")])
13979 ;; ISA 2.08 IEEE 128-bit floating point support.
13981 (define_insn "add<mode>3"
13982   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13983         (plus:IEEE128
13984          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13985          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13986   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13987   "xsaddqp %0,%1,%2"
13988   [(set_attr "type" "vecfloat")
13989    (set_attr "size" "128")])
13991 (define_insn "sub<mode>3"
13992   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13993         (minus:IEEE128
13994          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13995          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13996   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13997   "xssubqp %0,%1,%2"
13998   [(set_attr "type" "vecfloat")
13999    (set_attr "size" "128")])
14001 (define_insn "mul<mode>3"
14002   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14003         (mult:IEEE128
14004          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14005          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14006   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14007   "xsmulqp %0,%1,%2"
14008   [(set_attr "type" "qmul")
14009    (set_attr "size" "128")])
14011 (define_insn "div<mode>3"
14012   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14013         (div:IEEE128
14014          (match_operand:IEEE128 1 "altivec_register_operand" "v")
14015          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14016   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14017   "xsdivqp %0,%1,%2"
14018   [(set_attr "type" "vecdiv")
14019    (set_attr "size" "128")])
14021 (define_insn "sqrt<mode>2"
14022   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14023         (sqrt:IEEE128
14024          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14025   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14026    "xssqrtqp %0,%1"
14027   [(set_attr "type" "vecdiv")
14028    (set_attr "size" "128")])
14030 (define_expand "copysign<mode>3"
14031   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14032    (use (match_operand:IEEE128 1 "altivec_register_operand"))
14033    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14034   "FLOAT128_IEEE_P (<MODE>mode)"
14036   if (TARGET_FLOAT128_HW)
14037     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14038                                          operands[2]));
14039   else
14040     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14041                                          operands[2]));
14042   DONE;
14045 (define_insn "copysign<mode>3_hard"
14046   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14047         (unspec:IEEE128
14048          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14049           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14050          UNSPEC_COPYSIGN))]
14051   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14052    "xscpsgnqp %0,%2,%1"
14053   [(set_attr "type" "vecmove")
14054    (set_attr "size" "128")])
14056 (define_insn "copysign<mode>3_soft"
14057   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14058         (unspec:IEEE128
14059          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14060           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14061          UNSPEC_COPYSIGN))
14062    (clobber (match_scratch:IEEE128 3 "=&v"))]
14063   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14064    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14065   [(set_attr "type" "veccomplex")
14066    (set_attr "length" "8")])
14068 (define_insn "@neg<mode>2_hw"
14069   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14070         (neg:IEEE128
14071          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14072   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14073   "xsnegqp %0,%1"
14074   [(set_attr "type" "vecmove")
14075    (set_attr "size" "128")])
14078 (define_insn "@abs<mode>2_hw"
14079   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14080         (abs:IEEE128
14081          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14082   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14083   "xsabsqp %0,%1"
14084   [(set_attr "type" "vecmove")
14085    (set_attr "size" "128")])
14088 (define_insn "*nabs<mode>2_hw"
14089   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14090         (neg:IEEE128
14091          (abs:IEEE128
14092           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14093   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14094   "xsnabsqp %0,%1"
14095   [(set_attr "type" "vecmove")
14096    (set_attr "size" "128")])
14098 ;; Initially don't worry about doing fusion
14099 (define_insn "fma<mode>4_hw"
14100   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14101         (fma:IEEE128
14102          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14103          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14104          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14105   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14106   "xsmaddqp %0,%1,%2"
14107   [(set_attr "type" "qmul")
14108    (set_attr "size" "128")])
14110 (define_insn "*fms<mode>4_hw"
14111   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14112         (fma:IEEE128
14113          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14114          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14115          (neg:IEEE128
14116           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14117   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14118   "xsmsubqp %0,%1,%2"
14119   [(set_attr "type" "qmul")
14120    (set_attr "size" "128")])
14122 (define_insn "*nfma<mode>4_hw"
14123   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14124         (neg:IEEE128
14125          (fma:IEEE128
14126           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14127           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14128           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14129   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14130   "xsnmaddqp %0,%1,%2"
14131   [(set_attr "type" "qmul")
14132    (set_attr "size" "128")])
14134 (define_insn "*nfms<mode>4_hw"
14135   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14136         (neg:IEEE128
14137          (fma:IEEE128
14138           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14139           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14140           (neg:IEEE128
14141            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14142   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14143   "xsnmsubqp %0,%1,%2"
14144   [(set_attr "type" "qmul")
14145    (set_attr "size" "128")])
14147 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14148   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14149         (float_extend:IEEE128
14150          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14151   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14152   "xscvdpqp %0,%1"
14153   [(set_attr "type" "vecfloat")
14154    (set_attr "size" "128")])
14156 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14157 ;; point is a simple copy.
14158 (define_insn_and_split "extendkftf2"
14159   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14160         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14161   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14162   "@
14163    #
14164    xxlor %x0,%x1,%x1"
14165   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14166   [(const_int 0)]
14168   emit_note (NOTE_INSN_DELETED);
14169   DONE;
14171   [(set_attr "type" "*,veclogical")
14172    (set_attr "length" "0,4")])
14174 (define_insn_and_split "trunctfkf2"
14175   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14176         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14177   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14178   "@
14179    #
14180    xxlor %x0,%x1,%x1"
14181   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14182   [(const_int 0)]
14184   emit_note (NOTE_INSN_DELETED);
14185   DONE;
14187   [(set_attr "type" "*,veclogical")
14188    (set_attr "length" "0,4")])
14190 (define_insn "trunc<mode>df2_hw"
14191   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14192         (float_truncate:DF
14193          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14194   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14195   "xscvqpdp %0,%1"
14196   [(set_attr "type" "vecfloat")
14197    (set_attr "size" "128")])
14199 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14200 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14201 ;; conversion
14202 (define_insn_and_split "trunc<mode>sf2_hw"
14203   [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14204         (float_truncate:SF
14205          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14206    (clobber (match_scratch:DF 2 "=v"))]
14207   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14208   "#"
14209   "&& 1"
14210   [(set (match_dup 2)
14211         (unspec:DF [(match_dup 1)]
14212                    UNSPEC_TRUNC_ROUND_TO_ODD))
14213    (set (match_dup 0)
14214         (float_truncate:SF (match_dup 2)))]
14216   if (GET_CODE (operands[2]) == SCRATCH)
14217     operands[2] = gen_reg_rtx (DFmode);
14219   [(set_attr "type" "vecfloat")
14220    (set_attr "length" "8")
14221    (set_attr "isa" "p8v")])
14223 ;; Conversion between IEEE 128-bit and integer types
14225 ;; The fix function for DImode and SImode was declared earlier as a
14226 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14227 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14228 ;; unless we have the IEEE 128-bit hardware.
14230 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14231 ;; to provide a GPR target that used direct move and a conversion in the GPR
14232 ;; which works around QImode/HImode not being allowed in vector registers in
14233 ;; ISA 2.07 (power8).
14234 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14235   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14236         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14237   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14238   "xscvqp<su><wd>z %0,%1"
14239   [(set_attr "type" "vecfloat")
14240    (set_attr "size" "128")])
14242 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14243   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14244         (any_fix:QHI
14245          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14246   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14247   "xscvqp<su>wz %0,%1"
14248   [(set_attr "type" "vecfloat")
14249    (set_attr "size" "128")])
14251 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14252 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14253 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14254   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14255         (any_fix:QHSI
14256          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14257    (clobber (match_scratch:QHSI 2 "=v"))]
14258   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14259   "#"
14260   "&& reload_completed"
14261   [(set (match_dup 2)
14262         (any_fix:QHSI (match_dup 1)))
14263    (set (match_dup 0)
14264         (match_dup 2))])
14266 (define_insn "float_<mode>di2_hw"
14267   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14268         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14269   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14270   "xscvsdqp %0,%1"
14271   [(set_attr "type" "vecfloat")
14272    (set_attr "size" "128")])
14274 (define_insn_and_split "float_<mode>si2_hw"
14275   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14276         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14277    (clobber (match_scratch:DI 2 "=v"))]
14278   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14279   "#"
14280   "&& 1"
14281   [(set (match_dup 2)
14282         (sign_extend:DI (match_dup 1)))
14283    (set (match_dup 0)
14284         (float:IEEE128 (match_dup 2)))]
14286   if (GET_CODE (operands[2]) == SCRATCH)
14287     operands[2] = gen_reg_rtx (DImode);
14289   if (MEM_P (operands[1]))
14290     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14293 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14294   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14295         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14296    (clobber (match_scratch:DI 2 "=X,r,X"))]
14297   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14298   "#"
14299   "&& reload_completed"
14300   [(const_int 0)]
14302   rtx dest = operands[0];
14303   rtx src = operands[1];
14304   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14306   if (altivec_register_operand (src, <QHI:MODE>mode))
14307     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14308   else if (int_reg_operand (src, <QHI:MODE>mode))
14309     {
14310       rtx ext_di = operands[2];
14311       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14312       emit_move_insn (dest_di, ext_di);
14313     }
14314   else if (MEM_P (src))
14315     {
14316       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14317       emit_move_insn (dest_qhi, src);
14318       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14319     }
14320   else
14321     gcc_unreachable ();
14323   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14324   DONE;
14326   [(set_attr "length" "8,12,12")
14327    (set_attr "type" "vecfloat")
14328    (set_attr "size" "128")])
14330 (define_insn "floatuns_<mode>di2_hw"
14331   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14332         (unsigned_float:IEEE128
14333          (match_operand:DI 1 "altivec_register_operand" "v")))]
14334   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14335   "xscvudqp %0,%1"
14336   [(set_attr "type" "vecfloat")
14337    (set_attr "size" "128")])
14339 (define_insn_and_split "floatuns_<mode>si2_hw"
14340   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14341         (unsigned_float:IEEE128
14342          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14343    (clobber (match_scratch:DI 2 "=v"))]
14344   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14345   "#"
14346   "&& 1"
14347   [(set (match_dup 2)
14348         (zero_extend:DI (match_dup 1)))
14349    (set (match_dup 0)
14350         (float:IEEE128 (match_dup 2)))]
14352   if (GET_CODE (operands[2]) == SCRATCH)
14353     operands[2] = gen_reg_rtx (DImode);
14355   if (MEM_P (operands[1]))
14356     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14359 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14360   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14361         (unsigned_float:IEEE128
14362          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14363    (clobber (match_scratch:DI 2 "=X,r,X"))]
14364   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14365   "#"
14366   "&& reload_completed"
14367   [(const_int 0)]
14369   rtx dest = operands[0];
14370   rtx src = operands[1];
14371   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14373   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14374     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14375   else if (int_reg_operand (src, <QHI:MODE>mode))
14376     {
14377       rtx ext_di = operands[2];
14378       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14379       emit_move_insn (dest_di, ext_di);
14380     }
14381   else
14382     gcc_unreachable ();
14384   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14385   DONE;
14387   [(set_attr "length" "8,12,8")
14388    (set_attr "type" "vecfloat")
14389    (set_attr "size" "128")])
14391 ;; IEEE 128-bit round to integer built-in functions
14392 (define_insn "floor<mode>2"
14393   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14394         (unspec:IEEE128
14395          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14396          UNSPEC_FRIM))]
14397   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14398   "xsrqpi 1,%0,%1,3"
14399   [(set_attr "type" "vecfloat")
14400    (set_attr "size" "128")])
14402 (define_insn "ceil<mode>2"
14403   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14404         (unspec:IEEE128
14405          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14406          UNSPEC_FRIP))]
14407   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14408   "xsrqpi 1,%0,%1,2"
14409   [(set_attr "type" "vecfloat")
14410    (set_attr "size" "128")])
14412 (define_insn "btrunc<mode>2"
14413   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14414         (unspec:IEEE128
14415          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14416          UNSPEC_FRIZ))]
14417   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14418   "xsrqpi 1,%0,%1,1"
14419   [(set_attr "type" "vecfloat")
14420    (set_attr "size" "128")])
14422 (define_insn "round<mode>2"
14423   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14424         (unspec:IEEE128
14425          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14426          UNSPEC_FRIN))]
14427   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14428   "xsrqpi 0,%0,%1,0"
14429   [(set_attr "type" "vecfloat")
14430    (set_attr "size" "128")])
14432 ;; IEEE 128-bit instructions with round to odd semantics
14433 (define_insn "add<mode>3_odd"
14434   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14435         (unspec:IEEE128
14436          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14437           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14438          UNSPEC_ADD_ROUND_TO_ODD))]
14439   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14440   "xsaddqpo %0,%1,%2"
14441   [(set_attr "type" "vecfloat")
14442    (set_attr "size" "128")])
14444 (define_insn "sub<mode>3_odd"
14445   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14446         (unspec:IEEE128
14447          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14448           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14449          UNSPEC_SUB_ROUND_TO_ODD))]
14450   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14451   "xssubqpo %0,%1,%2"
14452   [(set_attr "type" "vecfloat")
14453    (set_attr "size" "128")])
14455 (define_insn "mul<mode>3_odd"
14456   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14457         (unspec:IEEE128
14458          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14459           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14460          UNSPEC_MUL_ROUND_TO_ODD))]
14461   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14462   "xsmulqpo %0,%1,%2"
14463   [(set_attr "type" "qmul")
14464    (set_attr "size" "128")])
14466 (define_insn "div<mode>3_odd"
14467   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14468         (unspec:IEEE128
14469          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14470           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14471          UNSPEC_DIV_ROUND_TO_ODD))]
14472   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14473   "xsdivqpo %0,%1,%2"
14474   [(set_attr "type" "vecdiv")
14475    (set_attr "size" "128")])
14477 (define_insn "sqrt<mode>2_odd"
14478   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14479         (unspec:IEEE128
14480          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14481          UNSPEC_SQRT_ROUND_TO_ODD))]
14482   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14483    "xssqrtqpo %0,%1"
14484   [(set_attr "type" "vecdiv")
14485    (set_attr "size" "128")])
14487 (define_insn "fma<mode>4_odd"
14488   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14489         (unspec:IEEE128
14490          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14491           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14492           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14493          UNSPEC_FMA_ROUND_TO_ODD))]
14494   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14495   "xsmaddqpo %0,%1,%2"
14496   [(set_attr "type" "qmul")
14497    (set_attr "size" "128")])
14499 (define_insn "*fms<mode>4_odd"
14500   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14501         (unspec:IEEE128
14502          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14503           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14504           (neg:IEEE128
14505            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14506          UNSPEC_FMA_ROUND_TO_ODD))]
14507   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14508   "xsmsubqpo %0,%1,%2"
14509   [(set_attr "type" "qmul")
14510    (set_attr "size" "128")])
14512 (define_insn "*nfma<mode>4_odd"
14513   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14514         (neg:IEEE128
14515          (unspec:IEEE128
14516           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14517            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14518            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14519           UNSPEC_FMA_ROUND_TO_ODD)))]
14520   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14521   "xsnmaddqpo %0,%1,%2"
14522   [(set_attr "type" "qmul")
14523    (set_attr "size" "128")])
14525 (define_insn "*nfms<mode>4_odd"
14526   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14527         (neg:IEEE128
14528          (unspec:IEEE128
14529           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14530            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14531            (neg:IEEE128
14532             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14533           UNSPEC_FMA_ROUND_TO_ODD)))]
14534   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14535   "xsnmsubqpo %0,%1,%2"
14536   [(set_attr "type" "qmul")
14537    (set_attr "size" "128")])
14539 (define_insn "trunc<mode>df2_odd"
14540   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14541         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14542                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14543   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14544   "xscvqpdpo %0,%1"
14545   [(set_attr "type" "vecfloat")
14546    (set_attr "size" "128")])
14548 ;; IEEE 128-bit comparisons
14549 (define_insn "*cmp<mode>_hw"
14550   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14551         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14552                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14553   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14554    "xscmpuqp %0,%1,%2"
14555   [(set_attr "type" "veccmp")
14556    (set_attr "size" "128")])
14558 ;; Miscellaneous ISA 3.0 (power9) instructions
14560 (define_insn "darn_32"
14561   [(set (match_operand:SI 0 "register_operand" "=r")
14562         (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14563   "TARGET_P9_MISC"
14564   "darn %0,0"
14565   [(set_attr "type" "integer")])
14567 (define_insn "darn_raw"
14568   [(set (match_operand:DI 0 "register_operand" "=r")
14569         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14570   "TARGET_P9_MISC && TARGET_64BIT"
14571   "darn %0,2"
14572   [(set_attr "type" "integer")])
14574 (define_insn "darn"
14575   [(set (match_operand:DI 0 "register_operand" "=r")
14576         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14577   "TARGET_P9_MISC && TARGET_64BIT"
14578   "darn %0,1"
14579   [(set_attr "type" "integer")])
14581 ;; Test byte within range.
14583 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14584 ;; represents a byte whose value is ignored in this context and
14585 ;; vv, the least significant byte, holds the byte value that is to
14586 ;; be tested for membership within the range specified by operand 2.
14587 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14589 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14590 ;; vv <= hi.  Otherwise, set register operand 0 to 0.
14592 ;; Though the instructions to which this expansion maps operate on
14593 ;; 64-bit registers, the current implementation only operates on
14594 ;; SI-mode operands as the high-order bits provide no information
14595 ;; that is not already available in the low-order bits.  To avoid the
14596 ;; costs of data widening operations, future enhancements might allow
14597 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14598 (define_expand "cmprb"
14599   [(set (match_dup 3)
14600         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14601                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14602          UNSPEC_CMPRB))
14603    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14604         (if_then_else:SI (lt (match_dup 3)
14605                              (const_int 0))
14606                          (const_int -1)
14607                          (if_then_else (gt (match_dup 3)
14608                                            (const_int 0))
14609                                        (const_int 1)
14610                                        (const_int 0))))]
14611   "TARGET_P9_MISC"
14613   operands[3] = gen_reg_rtx (CCmode);
14616 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14617 ;; represents a byte whose value is ignored in this context and
14618 ;; vv, the least significant byte, holds the byte value that is to
14619 ;; be tested for membership within the range specified by operand 2.
14620 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14622 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14623 ;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
14624 ;; 3 bits of the target CR register are all set to 0.
14625 (define_insn "*cmprb_internal"
14626   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14627         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14628                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14629          UNSPEC_CMPRB))]
14630   "TARGET_P9_MISC"
14631   "cmprb %0,0,%1,%2"
14632   [(set_attr "type" "logical")])
14634 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14635 ;; register operand 1 is on.  Otherwise, set operand 0 register to 1
14636 ;; if the GT bit (0x4) of condition register operand 1 is on.
14637 ;; Otherwise, set operand 0 to 0.  Note that the result stored into
14638 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14639 ;; within condition register operand 1.
14640 (define_insn "setb_signed"
14641    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14642          (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14643                               (const_int 0))
14644                           (const_int -1)
14645                           (if_then_else (gt (match_dup 1)
14646                                             (const_int 0))
14647                                         (const_int 1)
14648                                         (const_int 0))))]
14649   "TARGET_P9_MISC"
14650   "setb %0,%1"
14651   [(set_attr "type" "logical")])
14653 (define_insn "setb_unsigned"
14654    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14655          (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14656                               (const_int 0))
14657                           (const_int -1)
14658                           (if_then_else (gtu (match_dup 1)
14659                                             (const_int 0))
14660                                         (const_int 1)
14661                                         (const_int 0))))]
14662   "TARGET_P9_MISC"
14663   "setb %0,%1"
14664   [(set_attr "type" "logical")])
14666 ;; Test byte within two ranges.
14668 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14669 ;; represents a byte whose value is ignored in this context and
14670 ;; vv, the least significant byte, holds the byte value that is to
14671 ;; be tested for membership within the range specified by operand 2.
14672 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14674 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14675 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
14676 ;; operand 0 to 0.
14678 ;; Though the instructions to which this expansion maps operate on
14679 ;; 64-bit registers, the current implementation only operates on
14680 ;; SI-mode operands as the high-order bits provide no information
14681 ;; that is not already available in the low-order bits.  To avoid the
14682 ;; costs of data widening operations, future enhancements might allow
14683 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14684 (define_expand "cmprb2"
14685   [(set (match_dup 3)
14686         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14687                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14688          UNSPEC_CMPRB2))
14689    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14690         (if_then_else:SI (lt (match_dup 3)
14691                              (const_int 0))
14692                          (const_int -1)
14693                          (if_then_else (gt (match_dup 3)
14694                                            (const_int 0))
14695                                        (const_int 1)
14696                                        (const_int 0))))]
14697   "TARGET_P9_MISC"
14699   operands[3] = gen_reg_rtx (CCmode);
14702 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14703 ;; represents a byte whose value is ignored in this context and
14704 ;; vv, the least significant byte, holds the byte value that is to
14705 ;; be tested for membership within the ranges specified by operand 2.
14706 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14708 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14709 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14710 ;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
14711 ;; CR register are all set to 0.
14712 (define_insn "*cmprb2_internal"
14713   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14714         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14715                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14716          UNSPEC_CMPRB2))]
14717   "TARGET_P9_MISC"
14718   "cmprb %0,1,%1,%2"
14719   [(set_attr "type" "logical")])
14721 ;; Test byte membership within set of 8 bytes.
14723 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14724 ;; represents a byte whose value is ignored in this context and
14725 ;; vv, the least significant byte, holds the byte value that is to
14726 ;; be tested for membership within the set specified by operand 2.
14727 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14729 ;; Return in target register operand 0 a value of 1 if vv equals one
14730 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
14731 ;; register operand 0 to 0.  Note that the 8 byte values held within
14732 ;; operand 2 need not be unique.
14734 ;; Though the instructions to which this expansion maps operate on
14735 ;; 64-bit registers, the current implementation requires that operands
14736 ;; 0 and 1 have mode SI as the high-order bits provide no information
14737 ;; that is not already available in the low-order bits.  To avoid the
14738 ;; costs of data widening operations, future enhancements might allow
14739 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14740 (define_expand "cmpeqb"
14741   [(set (match_dup 3)
14742         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14743                     (match_operand:DI 2 "gpc_reg_operand" "r")]
14744          UNSPEC_CMPEQB))
14745    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14746         (if_then_else:SI (lt (match_dup 3)
14747                              (const_int 0))
14748                          (const_int -1)
14749                          (if_then_else (gt (match_dup 3)
14750                                            (const_int 0))
14751                                        (const_int 1)
14752                                        (const_int 0))))]
14753   "TARGET_P9_MISC && TARGET_64BIT"
14755   operands[3] = gen_reg_rtx (CCmode);
14758 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14759 ;; represents a byte whose value is ignored in this context and
14760 ;; vv, the least significant byte, holds the byte value that is to
14761 ;; be tested for membership within the set specified by operand 2.
14762 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14764 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14765 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
14766 ;; set the GT bit to zero.  The other 3 bits of the target CR register
14767 ;; are all set to 0.
14768 (define_insn "*cmpeqb_internal"
14769   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14770          (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14771                      (match_operand:DI 2 "gpc_reg_operand" "r")]
14772           UNSPEC_CMPEQB))]
14773   "TARGET_P9_MISC && TARGET_64BIT"
14774   "cmpeqb %0,%1,%2"
14775   [(set_attr "type" "logical")])
14778 (include "sync.md")
14779 (include "vector.md")
14780 (include "vsx.md")
14781 (include "altivec.md")
14782 (include "dfp.md")
14783 (include "crypto.md")
14784 (include "htm.md")