[RS6000] Remove TARGET_TLS_MARKERS and require binutils 2.20
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob0fc0f952611cdb22ddeb6de1e79df195a5226d84
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_FIX_TRUNC_TF          ; fadd, rounding towards zero
90    UNSPEC_STFIWX
91    UNSPEC_POPCNTB
92    UNSPEC_FRES
93    UNSPEC_SP_SET
94    UNSPEC_SP_TEST
95    UNSPEC_SYNC
96    UNSPEC_LWSYNC
97    UNSPEC_SYNC_OP
98    UNSPEC_ATOMIC
99    UNSPEC_CMPXCHG
100    UNSPEC_XCHG
101    UNSPEC_AND
102    UNSPEC_DLMZB
103    UNSPEC_DLMZB_CR
104    UNSPEC_DLMZB_STRLEN
105    UNSPEC_RSQRT
106    UNSPEC_TOCREL
107    UNSPEC_MACHOPIC_OFFSET
108    UNSPEC_BPERM
109    UNSPEC_COPYSIGN
110    UNSPEC_PARITY
111    UNSPEC_CMPB
112    UNSPEC_FCTIW
113    UNSPEC_FCTID
114    UNSPEC_LFIWAX
115    UNSPEC_LFIWZX
116    UNSPEC_FCTIWUZ
117    UNSPEC_NOP
118    UNSPEC_GRP_END_NOP
119    UNSPEC_P8V_FMRGOW
120    UNSPEC_P8V_MTVSRWZ
121    UNSPEC_P8V_RELOAD_FROM_GPR
122    UNSPEC_P8V_MTVSRD
123    UNSPEC_P8V_XXPERMDI
124    UNSPEC_P8V_RELOAD_FROM_VSX
125    UNSPEC_ADDG6S
126    UNSPEC_CDTBCD
127    UNSPEC_CBCDTD
128    UNSPEC_DIVE
129    UNSPEC_DIVEU
130    UNSPEC_UNPACK_128BIT
131    UNSPEC_PACK_128BIT
132    UNSPEC_LSQ
133    UNSPEC_FUSION_GPR
134    UNSPEC_STACK_CHECK
135    UNSPEC_CMPRB
136    UNSPEC_CMPRB2
137    UNSPEC_CMPEQB
138    UNSPEC_ADD_ROUND_TO_ODD
139    UNSPEC_SUB_ROUND_TO_ODD
140    UNSPEC_MUL_ROUND_TO_ODD
141    UNSPEC_DIV_ROUND_TO_ODD
142    UNSPEC_FMA_ROUND_TO_ODD
143    UNSPEC_SQRT_ROUND_TO_ODD
144    UNSPEC_TRUNC_ROUND_TO_ODD
145    UNSPEC_SIGNBIT
146    UNSPEC_SF_FROM_SI
147    UNSPEC_SI_FROM_SF
148    UNSPEC_PLTSEQ
149    UNSPEC_PLT16_HA
150    UNSPEC_PLT16_LO
151    UNSPEC_PLT_PCREL
152   ])
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
159   [UNSPECV_BLOCK
160    UNSPECV_LL                   ; load-locked
161    UNSPECV_SC                   ; store-conditional
162    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
163    UNSPECV_EH_RR                ; eh_reg_restore
164    UNSPECV_ISYNC                ; isync instruction
165    UNSPECV_MFTB                 ; move from time base
166    UNSPECV_DARN                 ; darn 1 (deliver a random number)
167    UNSPECV_DARN_32              ; darn 2
168    UNSPECV_DARN_RAW             ; darn 0
169    UNSPECV_NLGR                 ; non-local goto receiver
170    UNSPECV_MFFS                 ; Move from FPSCR
171    UNSPECV_MFFSL                ; Move from FPSCR light instruction version
172    UNSPECV_MFFSCRN              ; Move from FPSCR float rounding mode
173    UNSPECV_MFFSCDRN             ; Move from FPSCR decimal float rounding mode
174    UNSPECV_MTFSF                ; Move to FPSCR Fields 8 to 15
175    UNSPECV_MTFSF_HI             ; Move to FPSCR Fields 0 to 7
176    UNSPECV_MTFSB0               ; Set FPSCR Field bit to 0
177    UNSPECV_MTFSB1               ; Set FPSCR Field bit to 1
178    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
179    UNSPECV_SPEC_BARRIER         ; Speculation barrier
180   ])
182 ; The three different kinds of epilogue.
183 (define_enum "epilogue_type" [normal sibcall eh_return])
185 ;; Define an insn type attribute.  This is used in function unit delay
186 ;; computations.
187 (define_attr "type"
188   "integer,two,three,
189    add,logical,shift,insert,
190    mul,halfmul,div,
191    exts,cntlz,popcnt,isel,
192    load,store,fpload,fpstore,vecload,vecstore,
193    cmp,
194    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
195    cr_logical,mfcr,mfcrf,mtcr,
196    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
197    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
198    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
199    veclogical,veccmpfx,vecexts,vecmove,
200    htm,htmsimple,dfp"
201   (const_string "integer"))
203 ;; What data size does this instruction work on?
204 ;; This is used for insert, mul and others as necessary.
205 (define_attr "size" "8,16,32,64,128" (const_string "32"))
207 ;; What is the insn_cost for this insn?  The target hook can still override
208 ;; this.  For optimizing for size the "length" attribute is used instead.
209 (define_attr "cost" "" (const_int 0))
211 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
212 ;; This is used for add, logical, shift, exts, mul.
213 (define_attr "dot" "no,yes" (const_string "no"))
215 ;; Does this instruction sign-extend its result?
216 ;; This is used for load insns.
217 (define_attr "sign_extend" "no,yes" (const_string "no"))
219 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
220 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
222 ;; Does this instruction use indexed (that is, reg+reg) addressing?
223 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
224 ;; it is automatically set based on that.  If a load or store instruction
225 ;; has fewer than two operands it needs to set this attribute manually
226 ;; or the compiler will crash.
227 (define_attr "indexed" "no,yes"
228   (if_then_else (ior (match_operand 0 "indexed_address_mem")
229                      (match_operand 1 "indexed_address_mem"))
230                 (const_string "yes")
231                 (const_string "no")))
233 ;; Does this instruction use update addressing?
234 ;; This is used for load and store insns.  See the comments for "indexed".
235 (define_attr "update" "no,yes"
236   (if_then_else (ior (match_operand 0 "update_address_mem")
237                      (match_operand 1 "update_address_mem"))
238                 (const_string "yes")
239                 (const_string "no")))
241 ;; Is this instruction using operands[2] as shift amount, and can that be a
242 ;; register?
243 ;; This is used for shift insns.
244 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
246 ;; Is this instruction using a shift amount from a register?
247 ;; This is used for shift insns.
248 (define_attr "var_shift" "no,yes"
249   (if_then_else (and (eq_attr "type" "shift")
250                      (eq_attr "maybe_var_shift" "yes"))
251                 (if_then_else (match_operand 2 "gpc_reg_operand")
252                               (const_string "yes")
253                               (const_string "no"))
254                 (const_string "no")))
256 ;; Is copying of this instruction disallowed?
257 (define_attr "cannot_copy" "no,yes" (const_string "no"))
260 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
261 ;; before the instruction.  A prefixed instruction has a prefix instruction
262 ;; word that extends the immediate value of the instructions from 12-16 bits to
263 ;; 34 bits.  The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
264 ;; insns.  The default "length" attribute will also be adjusted by default to
265 ;; be 12 bytes.
266 (define_attr "prefixed" "no,yes"
267   (cond [(ior (match_test "!TARGET_PREFIXED_ADDR")
268               (match_test "!NONJUMP_INSN_P (insn)"))
269          (const_string "no")
271          (eq_attr "type" "load,fpload,vecload")
272          (if_then_else (match_test "prefixed_load_p (insn)")
273                        (const_string "yes")
274                        (const_string "no"))
276          (eq_attr "type" "store,fpstore,vecstore")
277          (if_then_else (match_test "prefixed_store_p (insn)")
278                        (const_string "yes")
279                        (const_string "no"))
281          (eq_attr "type" "integer,add")
282          (if_then_else (match_test "prefixed_paddi_p (insn)")
283                        (const_string "yes")
284                        (const_string "no"))]
286         (const_string "no")))
288 ;; Return the number of real hardware instructions in a combined insn.  If it
289 ;; is 0, just use the length / 4.
290 (define_attr "num_insns" "" (const_int 0))
292 ;; If an insn is prefixed, return the maximum number of prefixed instructions
293 ;; in the insn.  The macro ADJUST_INSN_LENGTH uses this number to adjust the
294 ;; insn length.
295 (define_attr "max_prefixed_insns" "" (const_int 1))
297 ;; Length of the instruction (in bytes).  This length does not consider the
298 ;; length for prefixed instructions.  The macro ADJUST_INSN_LENGTH will adjust
299 ;; the length if there are prefixed instructions.
301 ;; While it might be tempting to use num_insns to calculate the length, it can
302 ;; be problematical unless all insn lengths are adjusted to use num_insns
303 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
304 ;; num_insns and recurse).
305 (define_attr "length" "" (const_int 4))
307 ;; Processor type -- this attribute must exactly match the processor_type
308 ;; enumeration in rs6000-opts.h.
309 (define_attr "cpu"
310   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
311    ppc750,ppc7400,ppc7450,
312    ppc403,ppc405,ppc440,ppc476,
313    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
314    power4,power5,power6,power7,power8,power9,future,
315    rs64a,mpccore,cell,ppca2,titan"
316   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
318 ;; The ISA we implement.
319 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
320   (const_string "any"))
322 ;; Is this alternative enabled for the current CPU/ISA/etc.?
323 (define_attr "enabled" ""
324   (cond
325     [(eq_attr "isa" "any")
326      (const_int 1)
328      (and (eq_attr "isa" "p5")
329           (match_test "TARGET_POPCNTB"))
330      (const_int 1)
332      (and (eq_attr "isa" "p6")
333           (match_test "TARGET_CMPB"))
334      (const_int 1)
336      (and (eq_attr "isa" "p7")
337           (match_test "TARGET_POPCNTD"))
338      (const_int 1)
340      (and (eq_attr "isa" "p7v")
341           (match_test "TARGET_VSX"))
342      (const_int 1)
344      (and (eq_attr "isa" "p8v")
345           (match_test "TARGET_P8_VECTOR"))
346      (const_int 1)
348      (and (eq_attr "isa" "p9v")
349           (match_test "TARGET_P9_VECTOR"))
350      (const_int 1)
352      (and (eq_attr "isa" "p9kf")
353           (match_test "TARGET_FLOAT128_TYPE"))
354      (const_int 1)
356      (and (eq_attr "isa" "p9tf")
357           (match_test "FLOAT128_VECTOR_P (TFmode)"))
358      (const_int 1)
360      (and (eq_attr "isa" "fut")
361           (match_test "TARGET_FUTURE"))
362      (const_int 1)
363     ] (const_int 0)))
365 ;; If this instruction is microcoded on the CELL processor
366 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
367 (define_attr "cell_micro" "not,conditional,always"
368   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
369                           (eq_attr "dot" "yes"))
370                      (and (eq_attr "type" "load")
371                           (eq_attr "sign_extend" "yes"))
372                      (and (eq_attr "type" "shift")
373                           (eq_attr "var_shift" "yes")))
374                 (const_string "always")
375                 (const_string "not")))
377 (automata_option "ndfa")
379 (include "rs64.md")
380 (include "mpc.md")
381 (include "40x.md")
382 (include "440.md")
383 (include "476.md")
384 (include "601.md")
385 (include "603.md")
386 (include "6xx.md")
387 (include "7xx.md")
388 (include "7450.md")
389 (include "8540.md")
390 (include "e300c2c3.md")
391 (include "e500mc.md")
392 (include "e500mc64.md")
393 (include "e5500.md")
394 (include "e6500.md")
395 (include "power4.md")
396 (include "power5.md")
397 (include "power6.md")
398 (include "power7.md")
399 (include "power8.md")
400 (include "power9.md")
401 (include "future.md")
402 (include "cell.md")
403 (include "a2.md")
404 (include "titan.md")
406 (include "predicates.md")
407 (include "constraints.md")
410 ;; Mode iterators
412 ; This mode iterator allows :GPR to be used to indicate the allowable size
413 ; of whole values in GPRs.
414 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
416 ; And again, for patterns that need two (potentially) different integer modes.
417 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
419 ; Any supported integer mode.
420 (define_mode_iterator INT [QI HI SI DI TI PTI])
422 ; Any supported integer mode that fits in one register.
423 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
425 ; Integer modes supported in VSX registers with ISA 3.0 instructions
426 (define_mode_iterator INT_ISA3 [QI HI SI DI])
428 ; Everything we can extend QImode to.
429 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
431 ; Everything we can extend HImode to.
432 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
434 ; Everything we can extend SImode to.
435 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
437 ; QImode or HImode for small integer moves and small atomic ops
438 (define_mode_iterator QHI [QI HI])
440 ; QImode, HImode, SImode for fused ops only for GPR loads
441 (define_mode_iterator QHSI [QI HI SI])
443 ; HImode or SImode for sign extended fusion ops
444 (define_mode_iterator HSI [HI SI])
446 ; SImode or DImode, even if DImode doesn't fit in GPRs.
447 (define_mode_iterator SDI [SI DI])
449 ; The size of a pointer.  Also, the size of the value that a record-condition
450 ; (one with a '.') will compare; and the size used for arithmetic carries.
451 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
453 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
454 ; PTImode is GPR only)
455 (define_mode_iterator TI2 [TI PTI])
457 ; Any hardware-supported floating-point mode
458 (define_mode_iterator FP [
459   (SF "TARGET_HARD_FLOAT")
460   (DF "TARGET_HARD_FLOAT")
461   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
462   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
463   (KF "TARGET_FLOAT128_TYPE")
464   (DD "TARGET_DFP")
465   (TD "TARGET_DFP")])
467 ; Any fma capable floating-point mode.
468 (define_mode_iterator FMA_F [
469   (SF "TARGET_HARD_FLOAT")
470   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
471   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
472   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
473   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
474   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
475   ])
477 ; Floating point move iterators to combine binary and decimal moves
478 (define_mode_iterator FMOVE32 [SF SD])
479 (define_mode_iterator FMOVE64 [DF DD])
480 (define_mode_iterator FMOVE64X [DI DF DD])
481 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
482                                 (IF "FLOAT128_IBM_P (IFmode)")
483                                 (TD "TARGET_HARD_FLOAT")])
485 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
486                                     (IF "FLOAT128_2REG_P (IFmode)")
487                                     (TD "TARGET_HARD_FLOAT")])
489 ; Iterators for 128 bit types for direct move
490 (define_mode_iterator FMOVE128_GPR [TI
491                                     V16QI
492                                     V8HI
493                                     V4SI
494                                     V4SF
495                                     V2DI
496                                     V2DF
497                                     V1TI
498                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
499                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
501 ; Iterator for 128-bit VSX types for pack/unpack
502 (define_mode_iterator FMOVE128_VSX [V1TI KF])
504 ; Iterators for converting to/from TFmode
505 (define_mode_iterator IFKF [IF KF])
507 ; Constraints for moving IF/KFmode.
508 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
510 ; Whether a floating point move is ok, don't allow SD without hardware FP
511 (define_mode_attr fmove_ok [(SF "")
512                             (DF "")
513                             (SD "TARGET_HARD_FLOAT")
514                             (DD "")])
516 ; Convert REAL_VALUE to the appropriate bits
517 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
518                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
519                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
520                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
522 ; Whether 0.0 has an all-zero bit pattern
523 (define_mode_attr zero_fp [(SF "j")
524                            (DF "j")
525                            (TF "j")
526                            (IF "j")
527                            (KF "j")
528                            (SD "wn")
529                            (DD "wn")
530                            (TD "wn")])
532 ; Definitions for 64-bit VSX
533 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
535 ; Definitions for 64-bit direct move
536 (define_mode_attr f64_dm  [(DF "wa") (DD "d")])
538 ; Definitions for 64-bit use of altivec registers
539 (define_mode_attr f64_av  [(DF "v") (DD "wn")])
541 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
542 (define_mode_attr f64_p9  [(DF "v") (DD "wn")])
544 ; These modes do not fit in integer registers in 32-bit mode.
545 (define_mode_iterator DIFD [DI DF DD])
547 ; Iterator for reciprocal estimate instructions
548 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
550 ; SFmode or DFmode.
551 (define_mode_iterator SFDF [SF DF])
553 ; And again, for when we need two FP modes in a pattern.
554 (define_mode_iterator SFDF2 [SF DF])
556 ; A generic s/d attribute, for sp/dp for example.
557 (define_mode_attr sd [(SF   "s") (DF   "d")
558                       (V4SF "s") (V2DF "d")])
560 ; "s" or nothing, for fmuls/fmul for example.
561 (define_mode_attr s [(SF "s") (DF "")])
563 ; Iterator for 128-bit floating point that uses the IBM double-double format
564 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
565                               (TF "FLOAT128_IBM_P (TFmode)")])
567 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
568 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
569                                (TF "FLOAT128_IEEE_P (TFmode)")])
571 ; Iterator for 128-bit floating point
572 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
573                                 (IF "TARGET_FLOAT128_TYPE")
574                                 (TF "TARGET_LONG_DOUBLE_128")])
576 ; Iterator for signbit on 64-bit machines with direct move
577 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
578                                (TF "FLOAT128_VECTOR_P (TFmode)")])
580 ; Iterator for ISA 3.0 supported floating point types
581 (define_mode_iterator FP_ISA3 [SF DF])
583 ; SF/DF constraint for arithmetic on traditional floating point registers
584 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
586 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
587 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
588 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
589 ; format.
590 (define_mode_attr Fv            [(SF "wa") (DF "wa") (DI "wa")])
592 ; Which isa is needed for those float instructions?
593 (define_mode_attr Fisa          [(SF "p8v")  (DF "*") (DI "*")])
595 ; FRE/FRES support
596 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
598 ; Conditional returns.
599 (define_code_iterator any_return [return simple_return])
600 (define_code_attr return_pred [(return "direct_return ()")
601                                (simple_return "1")])
602 (define_code_attr return_str [(return "") (simple_return "simple_")])
604 ; Logical operators.
605 (define_code_iterator iorxor            [ior xor])
606 (define_code_iterator and_ior_xor       [and ior xor])
608 ; Signed/unsigned variants of ops.
609 (define_code_iterator any_extend        [sign_extend zero_extend])
610 (define_code_iterator any_fix           [fix unsigned_fix])
611 (define_code_iterator any_float         [float unsigned_float])
613 (define_code_attr u  [(sign_extend      "")
614                       (zero_extend      "u")
615                       (fix              "")
616                       (unsigned_fix     "u")])
618 (define_code_attr su [(sign_extend      "s")
619                       (zero_extend      "u")
620                       (fix              "s")
621                       (unsigned_fix     "u")
622                       (float            "s")
623                       (unsigned_float   "u")])
625 (define_code_attr az [(sign_extend      "a")
626                       (zero_extend      "z")
627                       (fix              "a")
628                       (unsigned_fix     "z")
629                       (float            "a")
630                       (unsigned_float   "z")])
632 (define_code_attr uns [(fix             "")
633                        (unsigned_fix    "uns")
634                        (float           "")
635                        (unsigned_float  "uns")])
637 ; Various instructions that come in SI and DI forms.
638 ; A generic w/d attribute, for things like cmpw/cmpd.
639 (define_mode_attr wd [(QI    "b")
640                       (HI    "h")
641                       (SI    "w")
642                       (DI    "d")
643                       (V16QI "b")
644                       (V8HI  "h")
645                       (V4SI  "w")
646                       (V2DI  "d")
647                       (V1TI  "q")
648                       (TI    "q")])
650 ;; How many bits in this mode?
651 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
652                                            (SF "32") (DF "64")])
654 ; DImode bits
655 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
657 ;; Bitmask for shift instructions
658 (define_mode_attr hH [(SI "h") (DI "H")])
660 ;; A mode twice the size of the given mode
661 (define_mode_attr dmode [(SI "di") (DI "ti")])
662 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
664 ;; Suffix for reload patterns
665 (define_mode_attr ptrsize [(SI "32bit")
666                            (DI "64bit")])
668 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
669                             (DI "TARGET_64BIT")])
671 (define_mode_attr mptrsize [(SI "si")
672                             (DI "di")])
674 (define_mode_attr ptrload [(SI "lwz")
675                            (DI "ld")])
677 (define_mode_attr ptrm [(SI "m")
678                         (DI "Y")])
680 (define_mode_attr rreg [(SF   "f")
681                         (DF   "wa")
682                         (TF   "f")
683                         (TD   "f")
684                         (V4SF "wa")
685                         (V2DF "wa")])
687 (define_mode_attr rreg2 [(SF   "f")
688                          (DF   "d")])
690 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
691                                  (DF "TARGET_FCFID")])
693 ;; Mode iterator for logical operations on 128-bit types
694 (define_mode_iterator BOOL_128          [TI
695                                          PTI
696                                          (V16QI "TARGET_ALTIVEC")
697                                          (V8HI  "TARGET_ALTIVEC")
698                                          (V4SI  "TARGET_ALTIVEC")
699                                          (V4SF  "TARGET_ALTIVEC")
700                                          (V2DI  "TARGET_ALTIVEC")
701                                          (V2DF  "TARGET_ALTIVEC")
702                                          (V1TI  "TARGET_ALTIVEC")])
704 ;; For the GPRs we use 3 constraints for register outputs, two that are the
705 ;; same as the output register, and a third where the output register is an
706 ;; early clobber, so we don't have to deal with register overlaps.  For the
707 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
708 ;; either.
710 ;; Mode attribute for boolean operation register constraints for output
711 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wa,v")
712                                          (PTI   "&r,r,r")
713                                          (V16QI "wa,v,&?r,?r,?r")
714                                          (V8HI  "wa,v,&?r,?r,?r")
715                                          (V4SI  "wa,v,&?r,?r,?r")
716                                          (V4SF  "wa,v,&?r,?r,?r")
717                                          (V2DI  "wa,v,&?r,?r,?r")
718                                          (V2DF  "wa,v,&?r,?r,?r")
719                                          (V1TI  "wa,v,&?r,?r,?r")])
721 ;; Mode attribute for boolean operation register constraints for operand1
722 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wa,v")
723                                          (PTI   "r,0,r")
724                                          (V16QI "wa,v,r,0,r")
725                                          (V8HI  "wa,v,r,0,r")
726                                          (V4SI  "wa,v,r,0,r")
727                                          (V4SF  "wa,v,r,0,r")
728                                          (V2DI  "wa,v,r,0,r")
729                                          (V2DF  "wa,v,r,0,r")
730                                          (V1TI  "wa,v,r,0,r")])
732 ;; Mode attribute for boolean operation register constraints for operand2
733 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wa,v")
734                                          (PTI   "r,r,0")
735                                          (V16QI "wa,v,r,r,0")
736                                          (V8HI  "wa,v,r,r,0")
737                                          (V4SI  "wa,v,r,r,0")
738                                          (V4SF  "wa,v,r,r,0")
739                                          (V2DI  "wa,v,r,r,0")
740                                          (V2DF  "wa,v,r,r,0")
741                                          (V1TI  "wa,v,r,r,0")])
743 ;; Mode attribute for boolean operation register constraints for operand1
744 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
745 ;; is used for operand1 or operand2
746 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wa,v")
747                                          (PTI   "r,0,0")
748                                          (V16QI "wa,v,r,0,0")
749                                          (V8HI  "wa,v,r,0,0")
750                                          (V4SI  "wa,v,r,0,0")
751                                          (V4SF  "wa,v,r,0,0")
752                                          (V2DI  "wa,v,r,0,0")
753                                          (V2DF  "wa,v,r,0,0")
754                                          (V1TI  "wa,v,r,0,0")])
756 ;; Reload iterator for creating the function to allocate a base register to
757 ;; supplement addressing modes.
758 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
759                               SF SD SI DF DD DI TI PTI KF IF TF])
761 ;; Iterate over smin, smax
762 (define_code_iterator fp_minmax [smin smax])
764 (define_code_attr     minmax    [(smin "min")
765                                  (smax "max")])
767 (define_code_attr     SMINMAX   [(smin "SMIN")
768                                  (smax "SMAX")])
770 ;; Iterator to optimize the following cases:
771 ;;      D-form load to FPR register & move to Altivec register
772 ;;      Move Altivec register to FPR register and store
773 (define_mode_iterator ALTIVEC_DFORM [DF
774                                      (SF "TARGET_P8_VECTOR")
775                                      (DI "TARGET_POWERPC64")])
777 (include "darwin.md")
779 ;; Start with fixed-point load and store insns.  Here we put only the more
780 ;; complex forms.  Basic data transfer is done later.
782 (define_insn "zero_extendqi<mode>2"
783   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
784         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
785   ""
786   "@
787    lbz%U1%X1 %0,%1
788    rlwinm %0,%1,0,0xff
789    lxsibzx %x0,%y1
790    vextractub %0,%1,7"
791   [(set_attr "type" "load,shift,fpload,vecperm")
792    (set_attr "isa" "*,*,p9v,p9v")])
794 (define_insn_and_split "*zero_extendqi<mode>2_dot"
795   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
796         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
797                     (const_int 0)))
798    (clobber (match_scratch:EXTQI 0 "=r,r"))]
799   ""
800   "@
801    andi. %0,%1,0xff
802    #"
803   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
804   [(set (match_dup 0)
805         (zero_extend:EXTQI (match_dup 1)))
806    (set (match_dup 2)
807         (compare:CC (match_dup 0)
808                     (const_int 0)))]
809   ""
810   [(set_attr "type" "logical")
811    (set_attr "dot" "yes")
812    (set_attr "length" "4,8")])
814 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
815   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
816         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
817                     (const_int 0)))
818    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
819         (zero_extend:EXTQI (match_dup 1)))]
820   ""
821   "@
822    andi. %0,%1,0xff
823    #"
824   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
825   [(set (match_dup 0)
826         (zero_extend:EXTQI (match_dup 1)))
827    (set (match_dup 2)
828         (compare:CC (match_dup 0)
829                     (const_int 0)))]
830   ""
831   [(set_attr "type" "logical")
832    (set_attr "dot" "yes")
833    (set_attr "length" "4,8")])
836 (define_insn "zero_extendhi<mode>2"
837   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
838         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
839   ""
840   "@
841    lhz%U1%X1 %0,%1
842    rlwinm %0,%1,0,0xffff
843    lxsihzx %x0,%y1
844    vextractuh %0,%1,6"
845   [(set_attr "type" "load,shift,fpload,vecperm")
846    (set_attr "isa" "*,*,p9v,p9v")])
848 (define_insn_and_split "*zero_extendhi<mode>2_dot"
849   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
850         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
851                     (const_int 0)))
852    (clobber (match_scratch:EXTHI 0 "=r,r"))]
853   ""
854   "@
855    andi. %0,%1,0xffff
856    #"
857   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
858   [(set (match_dup 0)
859         (zero_extend:EXTHI (match_dup 1)))
860    (set (match_dup 2)
861         (compare:CC (match_dup 0)
862                     (const_int 0)))]
863   ""
864   [(set_attr "type" "logical")
865    (set_attr "dot" "yes")
866    (set_attr "length" "4,8")])
868 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
869   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
870         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
871                     (const_int 0)))
872    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
873         (zero_extend:EXTHI (match_dup 1)))]
874   ""
875   "@
876    andi. %0,%1,0xffff
877    #"
878   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
879   [(set (match_dup 0)
880         (zero_extend:EXTHI (match_dup 1)))
881    (set (match_dup 2)
882         (compare:CC (match_dup 0)
883                     (const_int 0)))]
884   ""
885   [(set_attr "type" "logical")
886    (set_attr "dot" "yes")
887    (set_attr "length" "4,8")])
890 (define_insn "zero_extendsi<mode>2"
891   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
892         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
893   ""
894   "@
895    lwz%U1%X1 %0,%1
896    rldicl %0,%1,0,32
897    lfiwzx %0,%y1
898    lxsiwzx %x0,%y1
899    mtvsrwz %x0,%1
900    mfvsrwz %0,%x1
901    xxextractuw %x0,%x1,4"
902   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
903    (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
905 (define_insn_and_split "*zero_extendsi<mode>2_dot"
906   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
907         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
908                     (const_int 0)))
909    (clobber (match_scratch:EXTSI 0 "=r,r"))]
910   ""
911   "@
912    rldicl. %0,%1,0,32
913    #"
914   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
915   [(set (match_dup 0)
916         (zero_extend:DI (match_dup 1)))
917    (set (match_dup 2)
918         (compare:CC (match_dup 0)
919                     (const_int 0)))]
920   ""
921   [(set_attr "type" "shift")
922    (set_attr "dot" "yes")
923    (set_attr "length" "4,8")])
925 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
926   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
927         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
928                     (const_int 0)))
929    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
930         (zero_extend:EXTSI (match_dup 1)))]
931   ""
932   "@
933    rldicl. %0,%1,0,32
934    #"
935   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
936   [(set (match_dup 0)
937         (zero_extend:EXTSI (match_dup 1)))
938    (set (match_dup 2)
939         (compare:CC (match_dup 0)
940                     (const_int 0)))]
941   ""
942   [(set_attr "type" "shift")
943    (set_attr "dot" "yes")
944    (set_attr "length" "4,8")])
947 (define_insn "extendqi<mode>2"
948   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
949         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
950   ""
951   "@
952    extsb %0,%1
953    vextsb2d %0,%1"
954   [(set_attr "type" "exts,vecperm")
955    (set_attr "isa" "*,p9v")])
957 (define_insn_and_split "*extendqi<mode>2_dot"
958   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
959         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
960                     (const_int 0)))
961    (clobber (match_scratch:EXTQI 0 "=r,r"))]
962   ""
963   "@
964    extsb. %0,%1
965    #"
966   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
967   [(set (match_dup 0)
968         (sign_extend:EXTQI (match_dup 1)))
969    (set (match_dup 2)
970         (compare:CC (match_dup 0)
971                     (const_int 0)))]
972   ""
973   [(set_attr "type" "exts")
974    (set_attr "dot" "yes")
975    (set_attr "length" "4,8")])
977 (define_insn_and_split "*extendqi<mode>2_dot2"
978   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
979         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
980                     (const_int 0)))
981    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
982         (sign_extend:EXTQI (match_dup 1)))]
983   ""
984   "@
985    extsb. %0,%1
986    #"
987   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
988   [(set (match_dup 0)
989         (sign_extend:EXTQI (match_dup 1)))
990    (set (match_dup 2)
991         (compare:CC (match_dup 0)
992                     (const_int 0)))]
993   ""
994   [(set_attr "type" "exts")
995    (set_attr "dot" "yes")
996    (set_attr "length" "4,8")])
999 (define_expand "extendhi<mode>2"
1000   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1001         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1002   ""
1003   "")
1005 (define_insn "*extendhi<mode>2"
1006   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1007         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1008   ""
1009   "@
1010    lha%U1%X1 %0,%1
1011    extsh %0,%1
1012    #
1013    vextsh2d %0,%1"
1014   [(set_attr "type" "load,exts,fpload,vecperm")
1015    (set_attr "sign_extend" "yes")
1016    (set_attr "length" "*,*,8,*")
1017    (set_attr "isa" "*,*,p9v,p9v")])
1019 (define_split
1020   [(set (match_operand:EXTHI 0 "altivec_register_operand")
1021         (sign_extend:EXTHI
1022          (match_operand:HI 1 "indexed_or_indirect_operand")))]
1023   "TARGET_P9_VECTOR && reload_completed"
1024   [(set (match_dup 2)
1025         (match_dup 1))
1026    (set (match_dup 0)
1027         (sign_extend:EXTHI (match_dup 2)))]
1029   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1032 (define_insn_and_split "*extendhi<mode>2_dot"
1033   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1034         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1035                     (const_int 0)))
1036    (clobber (match_scratch:EXTHI 0 "=r,r"))]
1037   ""
1038   "@
1039    extsh. %0,%1
1040    #"
1041   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1042   [(set (match_dup 0)
1043         (sign_extend:EXTHI (match_dup 1)))
1044    (set (match_dup 2)
1045         (compare:CC (match_dup 0)
1046                     (const_int 0)))]
1047   ""
1048   [(set_attr "type" "exts")
1049    (set_attr "dot" "yes")
1050    (set_attr "length" "4,8")])
1052 (define_insn_and_split "*extendhi<mode>2_dot2"
1053   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1054         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1055                     (const_int 0)))
1056    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1057         (sign_extend:EXTHI (match_dup 1)))]
1058   ""
1059   "@
1060    extsh. %0,%1
1061    #"
1062   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1063   [(set (match_dup 0)
1064         (sign_extend:EXTHI (match_dup 1)))
1065    (set (match_dup 2)
1066         (compare:CC (match_dup 0)
1067                     (const_int 0)))]
1068   ""
1069   [(set_attr "type" "exts")
1070    (set_attr "dot" "yes")
1071    (set_attr "length" "4,8")])
1074 (define_insn "extendsi<mode>2"
1075   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1076                      "=r, r,   d,     wa,    wa,    v,      v,     wr")
1077         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1078                      "YZ, r,   Z,     Z,     r,     v,      v,     ?wa")))]
1079   ""
1080   "@
1081    lwa%U1%X1 %0,%1
1082    extsw %0,%1
1083    lfiwax %0,%y1
1084    lxsiwax %x0,%y1
1085    mtvsrwa %x0,%1
1086    vextsw2d %0,%1
1087    #
1088    #"
1089   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1090    (set_attr "sign_extend" "yes")
1091    (set_attr "length" "*,*,*,*,*,*,8,8")
1092    (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1094 (define_split
1095   [(set (match_operand:EXTSI 0 "int_reg_operand")
1096         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1097   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1098   [(set (match_dup 2)
1099         (match_dup 1))
1100    (set (match_dup 0)
1101         (sign_extend:DI (match_dup 2)))]
1103   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1106 (define_split
1107   [(set (match_operand:DI 0 "altivec_register_operand")
1108         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1109   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1110   [(const_int 0)]
1112   rtx dest = operands[0];
1113   rtx src = operands[1];
1114   int dest_regno = REGNO (dest);
1115   int src_regno = REGNO (src);
1116   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1117   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1119   if (BYTES_BIG_ENDIAN)
1120     {
1121       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1122       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1123     }
1124   else
1125     {
1126       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1127       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1128     }
1129   DONE;
1132 (define_insn_and_split "*extendsi<mode>2_dot"
1133   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1134         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1135                     (const_int 0)))
1136    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1137   ""
1138   "@
1139    extsw. %0,%1
1140    #"
1141   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1142   [(set (match_dup 0)
1143         (sign_extend:EXTSI (match_dup 1)))
1144    (set (match_dup 2)
1145         (compare:CC (match_dup 0)
1146                     (const_int 0)))]
1147   ""
1148   [(set_attr "type" "exts")
1149    (set_attr "dot" "yes")
1150    (set_attr "length" "4,8")])
1152 (define_insn_and_split "*extendsi<mode>2_dot2"
1153   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1154         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1155                     (const_int 0)))
1156    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1157         (sign_extend:EXTSI (match_dup 1)))]
1158   ""
1159   "@
1160    extsw. %0,%1
1161    #"
1162   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1163   [(set (match_dup 0)
1164         (sign_extend:EXTSI (match_dup 1)))
1165    (set (match_dup 2)
1166         (compare:CC (match_dup 0)
1167                     (const_int 0)))]
1168   ""
1169   [(set_attr "type" "exts")
1170    (set_attr "dot" "yes")
1171    (set_attr "length" "4,8")])
1173 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1175 (define_insn "*macchwc"
1176   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1177         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1178                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1179                                        (const_int 16))
1180                                       (sign_extend:SI
1181                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1182                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1183                     (const_int 0)))
1184    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1185         (plus:SI (mult:SI (ashiftrt:SI
1186                            (match_dup 2)
1187                            (const_int 16))
1188                           (sign_extend:SI
1189                            (match_dup 1)))
1190                  (match_dup 4)))]
1191   "TARGET_MULHW"
1192   "macchw. %0,%1,%2"
1193   [(set_attr "type" "halfmul")])
1195 (define_insn "*macchw"
1196   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1197         (plus:SI (mult:SI (ashiftrt:SI
1198                            (match_operand:SI 2 "gpc_reg_operand" "r")
1199                            (const_int 16))
1200                           (sign_extend:SI
1201                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1202                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1203   "TARGET_MULHW"
1204   "macchw %0,%1,%2"
1205   [(set_attr "type" "halfmul")])
1207 (define_insn "*macchwuc"
1208   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1209         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1210                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1211                                        (const_int 16))
1212                                       (zero_extend:SI
1213                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1214                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1215                     (const_int 0)))
1216    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1217         (plus:SI (mult:SI (lshiftrt:SI
1218                            (match_dup 2)
1219                            (const_int 16))
1220                           (zero_extend:SI
1221                            (match_dup 1)))
1222                  (match_dup 4)))]
1223   "TARGET_MULHW"
1224   "macchwu. %0,%1,%2"
1225   [(set_attr "type" "halfmul")])
1227 (define_insn "*macchwu"
1228   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1229         (plus:SI (mult:SI (lshiftrt:SI
1230                            (match_operand:SI 2 "gpc_reg_operand" "r")
1231                            (const_int 16))
1232                           (zero_extend:SI
1233                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1234                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1235   "TARGET_MULHW"
1236   "macchwu %0,%1,%2"
1237   [(set_attr "type" "halfmul")])
1239 (define_insn "*machhwc"
1240   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1241         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1242                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1243                                        (const_int 16))
1244                                       (ashiftrt:SI
1245                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1246                                        (const_int 16)))
1247                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1248                     (const_int 0)))
1249    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1250         (plus:SI (mult:SI (ashiftrt:SI
1251                            (match_dup 1)
1252                            (const_int 16))
1253                           (ashiftrt:SI
1254                            (match_dup 2)
1255                            (const_int 16)))
1256                  (match_dup 4)))]
1257   "TARGET_MULHW"
1258   "machhw. %0,%1,%2"
1259   [(set_attr "type" "halfmul")])
1261 (define_insn "*machhw"
1262   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1263         (plus:SI (mult:SI (ashiftrt:SI
1264                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1265                            (const_int 16))
1266                           (ashiftrt:SI
1267                            (match_operand:SI 2 "gpc_reg_operand" "r")
1268                            (const_int 16)))
1269                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1270   "TARGET_MULHW"
1271   "machhw %0,%1,%2"
1272   [(set_attr "type" "halfmul")])
1274 (define_insn "*machhwuc"
1275   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1276         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1277                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1278                                        (const_int 16))
1279                                       (lshiftrt:SI
1280                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1281                                        (const_int 16)))
1282                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1283                     (const_int 0)))
1284    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1285         (plus:SI (mult:SI (lshiftrt:SI
1286                            (match_dup 1)
1287                            (const_int 16))
1288                           (lshiftrt:SI
1289                            (match_dup 2)
1290                            (const_int 16)))
1291                  (match_dup 4)))]
1292   "TARGET_MULHW"
1293   "machhwu. %0,%1,%2"
1294   [(set_attr "type" "halfmul")])
1296 (define_insn "*machhwu"
1297   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1298         (plus:SI (mult:SI (lshiftrt:SI
1299                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1300                            (const_int 16))
1301                           (lshiftrt:SI
1302                            (match_operand:SI 2 "gpc_reg_operand" "r")
1303                            (const_int 16)))
1304                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1305   "TARGET_MULHW"
1306   "machhwu %0,%1,%2"
1307   [(set_attr "type" "halfmul")])
1309 (define_insn "*maclhwc"
1310   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1311         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1312                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1313                                       (sign_extend:SI
1314                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1315                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1316                     (const_int 0)))
1317    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1318         (plus:SI (mult:SI (sign_extend:SI
1319                            (match_dup 1))
1320                           (sign_extend:SI
1321                            (match_dup 2)))
1322                  (match_dup 4)))]
1323   "TARGET_MULHW"
1324   "maclhw. %0,%1,%2"
1325   [(set_attr "type" "halfmul")])
1327 (define_insn "*maclhw"
1328   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329         (plus:SI (mult:SI (sign_extend:SI
1330                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1331                           (sign_extend:SI
1332                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1333                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1334   "TARGET_MULHW"
1335   "maclhw %0,%1,%2"
1336   [(set_attr "type" "halfmul")])
1338 (define_insn "*maclhwuc"
1339   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1340         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1341                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1342                                       (zero_extend:SI
1343                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1344                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1345                     (const_int 0)))
1346    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347         (plus:SI (mult:SI (zero_extend:SI
1348                            (match_dup 1))
1349                           (zero_extend:SI
1350                            (match_dup 2)))
1351                  (match_dup 4)))]
1352   "TARGET_MULHW"
1353   "maclhwu. %0,%1,%2"
1354   [(set_attr "type" "halfmul")])
1356 (define_insn "*maclhwu"
1357   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1358         (plus:SI (mult:SI (zero_extend:SI
1359                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1360                           (zero_extend:SI
1361                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1362                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1363   "TARGET_MULHW"
1364   "maclhwu %0,%1,%2"
1365   [(set_attr "type" "halfmul")])
1367 (define_insn "*nmacchwc"
1368   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1369         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1370                               (mult:SI (ashiftrt:SI
1371                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1372                                         (const_int 16))
1373                                        (sign_extend:SI
1374                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1375                     (const_int 0)))
1376    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377         (minus:SI (match_dup 4)
1378                   (mult:SI (ashiftrt:SI
1379                             (match_dup 2)
1380                             (const_int 16))
1381                            (sign_extend:SI
1382                             (match_dup 1)))))]
1383   "TARGET_MULHW"
1384   "nmacchw. %0,%1,%2"
1385   [(set_attr "type" "halfmul")])
1387 (define_insn "*nmacchw"
1388   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1390                   (mult:SI (ashiftrt:SI
1391                             (match_operand:SI 2 "gpc_reg_operand" "r")
1392                             (const_int 16))
1393                            (sign_extend:SI
1394                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1395   "TARGET_MULHW"
1396   "nmacchw %0,%1,%2"
1397   [(set_attr "type" "halfmul")])
1399 (define_insn "*nmachhwc"
1400   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1402                               (mult:SI (ashiftrt:SI
1403                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1404                                         (const_int 16))
1405                                        (ashiftrt:SI
1406                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1407                                         (const_int 16))))
1408                     (const_int 0)))
1409    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1410         (minus:SI (match_dup 4)
1411                   (mult:SI (ashiftrt:SI
1412                             (match_dup 1)
1413                             (const_int 16))
1414                            (ashiftrt:SI
1415                             (match_dup 2)
1416                             (const_int 16)))))]
1417   "TARGET_MULHW"
1418   "nmachhw. %0,%1,%2"
1419   [(set_attr "type" "halfmul")])
1421 (define_insn "*nmachhw"
1422   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1423         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1424                   (mult:SI (ashiftrt:SI
1425                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1426                             (const_int 16))
1427                            (ashiftrt:SI
1428                             (match_operand:SI 2 "gpc_reg_operand" "r")
1429                             (const_int 16)))))]
1430   "TARGET_MULHW"
1431   "nmachhw %0,%1,%2"
1432   [(set_attr "type" "halfmul")])
1434 (define_insn "*nmaclhwc"
1435   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1436         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1437                               (mult:SI (sign_extend:SI
1438                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1439                                        (sign_extend:SI
1440                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1441                     (const_int 0)))
1442    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1443         (minus:SI (match_dup 4)
1444                   (mult:SI (sign_extend:SI
1445                             (match_dup 1))
1446                            (sign_extend:SI
1447                             (match_dup 2)))))]
1448   "TARGET_MULHW"
1449   "nmaclhw. %0,%1,%2"
1450   [(set_attr "type" "halfmul")])
1452 (define_insn "*nmaclhw"
1453   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1455                   (mult:SI (sign_extend:SI
1456                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1457                            (sign_extend:SI
1458                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1459   "TARGET_MULHW"
1460   "nmaclhw %0,%1,%2"
1461   [(set_attr "type" "halfmul")])
1463 (define_insn "*mulchwc"
1464   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1465         (compare:CC (mult:SI (ashiftrt:SI
1466                               (match_operand:SI 2 "gpc_reg_operand" "r")
1467                               (const_int 16))
1468                              (sign_extend:SI
1469                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1470                     (const_int 0)))
1471    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1472         (mult:SI (ashiftrt:SI
1473                   (match_dup 2)
1474                   (const_int 16))
1475                  (sign_extend:SI
1476                   (match_dup 1))))]
1477   "TARGET_MULHW"
1478   "mulchw. %0,%1,%2"
1479   [(set_attr "type" "halfmul")])
1481 (define_insn "*mulchw"
1482   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1483         (mult:SI (ashiftrt:SI
1484                   (match_operand:SI 2 "gpc_reg_operand" "r")
1485                   (const_int 16))
1486                  (sign_extend:SI
1487                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1488   "TARGET_MULHW"
1489   "mulchw %0,%1,%2"
1490   [(set_attr "type" "halfmul")])
1492 (define_insn "*mulchwuc"
1493   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1494         (compare:CC (mult:SI (lshiftrt:SI
1495                               (match_operand:SI 2 "gpc_reg_operand" "r")
1496                               (const_int 16))
1497                              (zero_extend:SI
1498                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1499                     (const_int 0)))
1500    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1501         (mult:SI (lshiftrt:SI
1502                   (match_dup 2)
1503                   (const_int 16))
1504                  (zero_extend:SI
1505                   (match_dup 1))))]
1506   "TARGET_MULHW"
1507   "mulchwu. %0,%1,%2"
1508   [(set_attr "type" "halfmul")])
1510 (define_insn "*mulchwu"
1511   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1512         (mult:SI (lshiftrt:SI
1513                   (match_operand:SI 2 "gpc_reg_operand" "r")
1514                   (const_int 16))
1515                  (zero_extend:SI
1516                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1517   "TARGET_MULHW"
1518   "mulchwu %0,%1,%2"
1519   [(set_attr "type" "halfmul")])
1521 (define_insn "*mulhhwc"
1522   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1523         (compare:CC (mult:SI (ashiftrt:SI
1524                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1525                               (const_int 16))
1526                              (ashiftrt:SI
1527                               (match_operand:SI 2 "gpc_reg_operand" "r")
1528                               (const_int 16)))
1529                     (const_int 0)))
1530    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1531         (mult:SI (ashiftrt:SI
1532                   (match_dup 1)
1533                   (const_int 16))
1534                  (ashiftrt:SI
1535                   (match_dup 2)
1536                   (const_int 16))))]
1537   "TARGET_MULHW"
1538   "mulhhw. %0,%1,%2"
1539   [(set_attr "type" "halfmul")])
1541 (define_insn "*mulhhw"
1542   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1543         (mult:SI (ashiftrt:SI
1544                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1545                   (const_int 16))
1546                  (ashiftrt:SI
1547                   (match_operand:SI 2 "gpc_reg_operand" "r")
1548                   (const_int 16))))]
1549   "TARGET_MULHW"
1550   "mulhhw %0,%1,%2"
1551   [(set_attr "type" "halfmul")])
1553 (define_insn "*mulhhwuc"
1554   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1555         (compare:CC (mult:SI (lshiftrt:SI
1556                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1557                               (const_int 16))
1558                              (lshiftrt:SI
1559                               (match_operand:SI 2 "gpc_reg_operand" "r")
1560                               (const_int 16)))
1561                     (const_int 0)))
1562    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1563         (mult:SI (lshiftrt:SI
1564                   (match_dup 1)
1565                   (const_int 16))
1566                  (lshiftrt:SI
1567                   (match_dup 2)
1568                   (const_int 16))))]
1569   "TARGET_MULHW"
1570   "mulhhwu. %0,%1,%2"
1571   [(set_attr "type" "halfmul")])
1573 (define_insn "*mulhhwu"
1574   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1575         (mult:SI (lshiftrt:SI
1576                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1577                   (const_int 16))
1578                  (lshiftrt:SI
1579                   (match_operand:SI 2 "gpc_reg_operand" "r")
1580                   (const_int 16))))]
1581   "TARGET_MULHW"
1582   "mulhhwu %0,%1,%2"
1583   [(set_attr "type" "halfmul")])
1585 (define_insn "*mullhwc"
1586   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1587         (compare:CC (mult:SI (sign_extend:SI
1588                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1589                              (sign_extend:SI
1590                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1591                     (const_int 0)))
1592    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1593         (mult:SI (sign_extend:SI
1594                   (match_dup 1))
1595                  (sign_extend:SI
1596                   (match_dup 2))))]
1597   "TARGET_MULHW"
1598   "mullhw. %0,%1,%2"
1599   [(set_attr "type" "halfmul")])
1601 (define_insn "*mullhw"
1602   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1603         (mult:SI (sign_extend:SI
1604                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1605                  (sign_extend:SI
1606                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1607   "TARGET_MULHW"
1608   "mullhw %0,%1,%2"
1609   [(set_attr "type" "halfmul")])
1611 (define_insn "*mullhwuc"
1612   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1613         (compare:CC (mult:SI (zero_extend:SI
1614                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1615                              (zero_extend:SI
1616                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1617                     (const_int 0)))
1618    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1619         (mult:SI (zero_extend:SI
1620                   (match_dup 1))
1621                  (zero_extend:SI
1622                   (match_dup 2))))]
1623   "TARGET_MULHW"
1624   "mullhwu. %0,%1,%2"
1625   [(set_attr "type" "halfmul")])
1627 (define_insn "*mullhwu"
1628   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1629         (mult:SI (zero_extend:SI
1630                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1631                  (zero_extend:SI
1632                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1633   "TARGET_MULHW"
1634   "mullhwu %0,%1,%2"
1635   [(set_attr "type" "halfmul")])
1637 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1638 (define_insn "dlmzb"
1639   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1640         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1641                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1642                    UNSPEC_DLMZB_CR))
1643    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1644         (unspec:SI [(match_dup 1)
1645                     (match_dup 2)]
1646                    UNSPEC_DLMZB))]
1647   "TARGET_DLMZB"
1648   "dlmzb. %0,%1,%2")
1650 (define_expand "strlensi"
1651   [(set (match_operand:SI 0 "gpc_reg_operand")
1652         (unspec:SI [(match_operand:BLK 1 "general_operand")
1653                     (match_operand:QI 2 "const_int_operand")
1654                     (match_operand 3 "const_int_operand")]
1655                    UNSPEC_DLMZB_STRLEN))
1656    (clobber (match_scratch:CC 4))]
1657   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1659   rtx result = operands[0];
1660   rtx src = operands[1];
1661   rtx search_char = operands[2];
1662   rtx align = operands[3];
1663   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1664   rtx loop_label, end_label, mem, cr0, cond;
1665   if (search_char != const0_rtx
1666       || !CONST_INT_P (align)
1667       || INTVAL (align) < 8)
1668         FAIL;
1669   word1 = gen_reg_rtx (SImode);
1670   word2 = gen_reg_rtx (SImode);
1671   scratch_dlmzb = gen_reg_rtx (SImode);
1672   scratch_string = gen_reg_rtx (Pmode);
1673   loop_label = gen_label_rtx ();
1674   end_label = gen_label_rtx ();
1675   addr = force_reg (Pmode, XEXP (src, 0));
1676   emit_move_insn (scratch_string, addr);
1677   emit_label (loop_label);
1678   mem = change_address (src, SImode, scratch_string);
1679   emit_move_insn (word1, mem);
1680   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1681   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1682   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1683   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1684   emit_jump_insn (gen_rtx_SET (pc_rtx,
1685                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1686                                                      cond,
1687                                                      gen_rtx_LABEL_REF
1688                                                        (VOIDmode,
1689                                                         end_label),
1690                                                      pc_rtx)));
1691   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1692   emit_jump_insn (gen_rtx_SET (pc_rtx,
1693                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1694   emit_barrier ();
1695   emit_label (end_label);
1696   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1697   emit_insn (gen_subsi3 (result, scratch_string, addr));
1698   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1699   DONE;
1702 ;; Fixed-point arithmetic insns.
1704 (define_expand "add<mode>3"
1705   [(set (match_operand:SDI 0 "gpc_reg_operand")
1706         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1707                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1708   ""
1710   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1711     {
1712       rtx lo0 = gen_lowpart (SImode, operands[0]);
1713       rtx lo1 = gen_lowpart (SImode, operands[1]);
1714       rtx lo2 = gen_lowpart (SImode, operands[2]);
1715       rtx hi0 = gen_highpart (SImode, operands[0]);
1716       rtx hi1 = gen_highpart (SImode, operands[1]);
1717       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1719       if (!reg_or_short_operand (lo2, SImode))
1720         lo2 = force_reg (SImode, lo2);
1721       if (!adde_operand (hi2, SImode))
1722         hi2 = force_reg (SImode, hi2);
1724       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1725       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1726       DONE;
1727     }
1729   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1730     {
1731       rtx tmp = ((!can_create_pseudo_p ()
1732                   || rtx_equal_p (operands[0], operands[1]))
1733                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1735       /* Adding a constant to r0 is not a valid insn, so use a different
1736          strategy in that case.  */
1737       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1738         {
1739           if (operands[0] == operands[1])
1740             FAIL;
1741           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1742           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1743           DONE;
1744         }
1746       HOST_WIDE_INT val = INTVAL (operands[2]);
1747       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1748       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1750       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1751         FAIL;
1753       /* The ordering here is important for the prolog expander.
1754          When space is allocated from the stack, adding 'low' first may
1755          produce a temporary deallocation (which would be bad).  */
1756       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1757       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1758       DONE;
1759     }
1762 (define_insn "*add<mode>3"
1763   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1764         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1765                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1766   ""
1767   "@
1768    add %0,%1,%2
1769    addi %0,%1,%2
1770    addis %0,%1,%v2"
1771   [(set_attr "type" "add")])
1773 (define_insn "*addsi3_high"
1774   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1775         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1776                  (high:SI (match_operand 2 "" ""))))]
1777   "TARGET_MACHO && !TARGET_64BIT"
1778   "addis %0,%1,ha16(%2)"
1779   [(set_attr "type" "add")])
1781 (define_insn_and_split "*add<mode>3_dot"
1782   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1783         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1784                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1785                     (const_int 0)))
1786    (clobber (match_scratch:GPR 0 "=r,r"))]
1787   "<MODE>mode == Pmode"
1788   "@
1789    add. %0,%1,%2
1790    #"
1791   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1792   [(set (match_dup 0)
1793         (plus:GPR (match_dup 1)
1794                  (match_dup 2)))
1795    (set (match_dup 3)
1796         (compare:CC (match_dup 0)
1797                     (const_int 0)))]
1798   ""
1799   [(set_attr "type" "add")
1800    (set_attr "dot" "yes")
1801    (set_attr "length" "4,8")])
1803 (define_insn_and_split "*add<mode>3_dot2"
1804   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1805         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1806                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1807                     (const_int 0)))
1808    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1809         (plus:GPR (match_dup 1)
1810                   (match_dup 2)))]
1811   "<MODE>mode == Pmode"
1812   "@
1813    add. %0,%1,%2
1814    #"
1815   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1816   [(set (match_dup 0)
1817         (plus:GPR (match_dup 1)
1818                   (match_dup 2)))
1819    (set (match_dup 3)
1820         (compare:CC (match_dup 0)
1821                     (const_int 0)))]
1822   ""
1823   [(set_attr "type" "add")
1824    (set_attr "dot" "yes")
1825    (set_attr "length" "4,8")])
1827 (define_insn_and_split "*add<mode>3_imm_dot"
1828   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1829         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1830                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1831                     (const_int 0)))
1832    (clobber (match_scratch:GPR 0 "=r,r"))
1833    (clobber (reg:GPR CA_REGNO))]
1834   "<MODE>mode == Pmode"
1835   "@
1836    addic. %0,%1,%2
1837    #"
1838   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1839   [(set (match_dup 0)
1840         (plus:GPR (match_dup 1)
1841                   (match_dup 2)))
1842    (set (match_dup 3)
1843         (compare:CC (match_dup 0)
1844                     (const_int 0)))]
1845   ""
1846   [(set_attr "type" "add")
1847    (set_attr "dot" "yes")
1848    (set_attr "length" "4,8")])
1850 (define_insn_and_split "*add<mode>3_imm_dot2"
1851   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1852         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1853                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1854                     (const_int 0)))
1855    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1856         (plus:GPR (match_dup 1)
1857                   (match_dup 2)))
1858    (clobber (reg:GPR CA_REGNO))]
1859   "<MODE>mode == Pmode"
1860   "@
1861    addic. %0,%1,%2
1862    #"
1863   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1864   [(set (match_dup 0)
1865         (plus:GPR (match_dup 1)
1866                   (match_dup 2)))
1867    (set (match_dup 3)
1868         (compare:CC (match_dup 0)
1869                     (const_int 0)))]
1870   ""
1871   [(set_attr "type" "add")
1872    (set_attr "dot" "yes")
1873    (set_attr "length" "4,8")])
1875 ;; Split an add that we can't do in one insn into two insns, each of which
1876 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1877 ;; add should be last in case the result gets used in an address.
1879 (define_split
1880   [(set (match_operand:GPR 0 "gpc_reg_operand")
1881         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1882                   (match_operand:GPR 2 "non_add_cint_operand")))]
1883   ""
1884   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1885    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1887   HOST_WIDE_INT val = INTVAL (operands[2]);
1888   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1889   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1891   operands[4] = GEN_INT (low);
1892   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1893     operands[3] = GEN_INT (rest);
1894   else if (can_create_pseudo_p ())
1895     {
1896       operands[3] = gen_reg_rtx (DImode);
1897       emit_move_insn (operands[3], operands[2]);
1898       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1899       DONE;
1900     }
1901   else
1902     FAIL;
1906 (define_insn "add<mode>3_carry"
1907   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1908         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1909                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1910    (set (reg:P CA_REGNO)
1911         (ltu:P (plus:P (match_dup 1)
1912                        (match_dup 2))
1913                (match_dup 1)))]
1914   ""
1915   "add%I2c %0,%1,%2"
1916   [(set_attr "type" "add")])
1918 (define_insn "*add<mode>3_imm_carry_pos"
1919   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1920         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1921                 (match_operand:P 2 "short_cint_operand" "n")))
1922    (set (reg:P CA_REGNO)
1923         (geu:P (match_dup 1)
1924                (match_operand:P 3 "const_int_operand" "n")))]
1925   "INTVAL (operands[2]) > 0
1926    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1927   "addic %0,%1,%2"
1928   [(set_attr "type" "add")])
1930 (define_insn "*add<mode>3_imm_carry_0"
1931   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1932         (match_operand:P 1 "gpc_reg_operand" "r"))
1933    (set (reg:P CA_REGNO)
1934         (const_int 0))]
1935   ""
1936   "addic %0,%1,0"
1937   [(set_attr "type" "add")])
1939 (define_insn "*add<mode>3_imm_carry_m1"
1940   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1941         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1942                 (const_int -1)))
1943    (set (reg:P CA_REGNO)
1944         (ne:P (match_dup 1)
1945               (const_int 0)))]
1946   ""
1947   "addic %0,%1,-1"
1948   [(set_attr "type" "add")])
1950 (define_insn "*add<mode>3_imm_carry_neg"
1951   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1952         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1953                 (match_operand:P 2 "short_cint_operand" "n")))
1954    (set (reg:P CA_REGNO)
1955         (gtu:P (match_dup 1)
1956                (match_operand:P 3 "const_int_operand" "n")))]
1957   "INTVAL (operands[2]) < 0
1958    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1959   "addic %0,%1,%2"
1960   [(set_attr "type" "add")])
1963 (define_expand "add<mode>3_carry_in"
1964   [(parallel [
1965      (set (match_operand:GPR 0 "gpc_reg_operand")
1966           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1967                               (match_operand:GPR 2 "adde_operand"))
1968                     (reg:GPR CA_REGNO)))
1969      (clobber (reg:GPR CA_REGNO))])]
1970   ""
1972   if (operands[2] == const0_rtx)
1973     {
1974       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1975       DONE;
1976     }
1977   if (operands[2] == constm1_rtx)
1978     {
1979       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1980       DONE;
1981     }
1984 (define_insn "*add<mode>3_carry_in_internal"
1985   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1986         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1987                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1988                   (reg:GPR CA_REGNO)))
1989    (clobber (reg:GPR CA_REGNO))]
1990   ""
1991   "adde %0,%1,%2"
1992   [(set_attr "type" "add")])
1994 (define_insn "*add<mode>3_carry_in_internal2"
1995   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1996         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1997                             (reg:GPR CA_REGNO))
1998                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
1999    (clobber (reg:GPR CA_REGNO))]
2000   ""
2001   "adde %0,%1,%2"
2002   [(set_attr "type" "add")])
2004 (define_insn "add<mode>3_carry_in_0"
2005   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2006         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2007                   (reg:GPR CA_REGNO)))
2008    (clobber (reg:GPR CA_REGNO))]
2009   ""
2010   "addze %0,%1"
2011   [(set_attr "type" "add")])
2013 (define_insn "add<mode>3_carry_in_m1"
2014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2015         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2016                             (reg:GPR CA_REGNO))
2017                   (const_int -1)))
2018    (clobber (reg:GPR CA_REGNO))]
2019   ""
2020   "addme %0,%1"
2021   [(set_attr "type" "add")])
2024 (define_expand "one_cmpl<mode>2"
2025   [(set (match_operand:SDI 0 "gpc_reg_operand")
2026         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2027   ""
2029   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2030     {
2031       rs6000_split_logical (operands, NOT, false, false, false);
2032       DONE;
2033     }
2036 (define_insn "*one_cmpl<mode>2"
2037   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2038         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2039   ""
2040   "not %0,%1")
2042 (define_insn_and_split "*one_cmpl<mode>2_dot"
2043   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2044         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2045                     (const_int 0)))
2046    (clobber (match_scratch:GPR 0 "=r,r"))]
2047   "<MODE>mode == Pmode"
2048   "@
2049    not. %0,%1
2050    #"
2051   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2052   [(set (match_dup 0)
2053         (not:GPR (match_dup 1)))
2054    (set (match_dup 2)
2055         (compare:CC (match_dup 0)
2056                     (const_int 0)))]
2057   ""
2058   [(set_attr "type" "logical")
2059    (set_attr "dot" "yes")
2060    (set_attr "length" "4,8")])
2062 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2063   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2064         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2065                     (const_int 0)))
2066    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2067         (not:GPR (match_dup 1)))]
2068   "<MODE>mode == Pmode"
2069   "@
2070    not. %0,%1
2071    #"
2072   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2073   [(set (match_dup 0)
2074         (not:GPR (match_dup 1)))
2075    (set (match_dup 2)
2076         (compare:CC (match_dup 0)
2077                     (const_int 0)))]
2078   ""
2079   [(set_attr "type" "logical")
2080    (set_attr "dot" "yes")
2081    (set_attr "length" "4,8")])
2084 (define_expand "sub<mode>3"
2085   [(set (match_operand:SDI 0 "gpc_reg_operand")
2086         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2087                    (match_operand:SDI 2 "gpc_reg_operand")))]
2088   ""
2090   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2091     {
2092       rtx lo0 = gen_lowpart (SImode, operands[0]);
2093       rtx lo1 = gen_lowpart (SImode, operands[1]);
2094       rtx lo2 = gen_lowpart (SImode, operands[2]);
2095       rtx hi0 = gen_highpart (SImode, operands[0]);
2096       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2097       rtx hi2 = gen_highpart (SImode, operands[2]);
2099       if (!reg_or_short_operand (lo1, SImode))
2100         lo1 = force_reg (SImode, lo1);
2101       if (!adde_operand (hi1, SImode))
2102         hi1 = force_reg (SImode, hi1);
2104       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2105       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2106       DONE;
2107     }
2109   if (short_cint_operand (operands[1], <MODE>mode))
2110     {
2111       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2112       DONE;
2113     }
2116 (define_insn "*subf<mode>3"
2117   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2118         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2119                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2120   ""
2121   "subf %0,%1,%2"
2122   [(set_attr "type" "add")])
2124 (define_insn_and_split "*subf<mode>3_dot"
2125   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2126         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2127                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2128                     (const_int 0)))
2129    (clobber (match_scratch:GPR 0 "=r,r"))]
2130   "<MODE>mode == Pmode"
2131   "@
2132    subf. %0,%1,%2
2133    #"
2134   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2135   [(set (match_dup 0)
2136         (minus:GPR (match_dup 2)
2137                    (match_dup 1)))
2138    (set (match_dup 3)
2139         (compare:CC (match_dup 0)
2140                     (const_int 0)))]
2141   ""
2142   [(set_attr "type" "add")
2143    (set_attr "dot" "yes")
2144    (set_attr "length" "4,8")])
2146 (define_insn_and_split "*subf<mode>3_dot2"
2147   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2148         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2149                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2150                     (const_int 0)))
2151    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2152         (minus:GPR (match_dup 2)
2153                    (match_dup 1)))]
2154   "<MODE>mode == Pmode"
2155   "@
2156    subf. %0,%1,%2
2157    #"
2158   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2159   [(set (match_dup 0)
2160         (minus:GPR (match_dup 2)
2161                    (match_dup 1)))
2162    (set (match_dup 3)
2163         (compare:CC (match_dup 0)
2164                     (const_int 0)))]
2165   ""
2166   [(set_attr "type" "add")
2167    (set_attr "dot" "yes")
2168    (set_attr "length" "4,8")])
2170 (define_insn "subf<mode>3_imm"
2171   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2172         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2173                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2174    (clobber (reg:GPR CA_REGNO))]
2175   ""
2176   "subfic %0,%1,%2"
2177   [(set_attr "type" "add")])
2179 (define_insn_and_split "subf<mode>3_carry_dot2"
2180   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2181         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2182                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2183                     (const_int 0)))
2184    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2185         (minus:P (match_dup 2)
2186                    (match_dup 1)))
2187    (set (reg:P CA_REGNO)
2188         (leu:P (match_dup 1)
2189                (match_dup 2)))]
2190   "<MODE>mode == Pmode"
2191   "@
2192    subfc. %0,%1,%2
2193    #"
2194   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2195   [(parallel [(set (match_dup 0)
2196                    (minus:P (match_dup 2)
2197                             (match_dup 1)))
2198               (set (reg:P CA_REGNO)
2199                    (leu:P (match_dup 1)
2200                           (match_dup 2)))])
2201    (set (match_dup 3)
2202         (compare:CC (match_dup 0)
2203                     (const_int 0)))]
2204   ""
2205   [(set_attr "type" "add")
2206    (set_attr "dot" "yes")
2207    (set_attr "length" "4,8")])
2209 (define_insn "subf<mode>3_carry"
2210   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2211         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2212                  (match_operand:P 1 "gpc_reg_operand" "r")))
2213    (set (reg:P CA_REGNO)
2214         (leu:P (match_dup 1)
2215                (match_dup 2)))]
2216   ""
2217   "subf%I2c %0,%1,%2"
2218   [(set_attr "type" "add")])
2220 (define_insn "*subf<mode>3_imm_carry_0"
2221   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2222         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2223    (set (reg:P CA_REGNO)
2224         (eq:P (match_dup 1)
2225               (const_int 0)))]
2226   ""
2227   "subfic %0,%1,0"
2228   [(set_attr "type" "add")])
2230 (define_insn "*subf<mode>3_imm_carry_m1"
2231   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2232         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2233    (set (reg:P CA_REGNO)
2234         (const_int 1))]
2235   ""
2236   "subfic %0,%1,-1"
2237   [(set_attr "type" "add")])
2240 (define_expand "subf<mode>3_carry_in"
2241   [(parallel [
2242      (set (match_operand:GPR 0 "gpc_reg_operand")
2243           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2244                               (reg:GPR CA_REGNO))
2245                     (match_operand:GPR 2 "adde_operand")))
2246      (clobber (reg:GPR CA_REGNO))])]
2247   ""
2249   if (operands[2] == const0_rtx)
2250     {
2251       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2252       DONE;
2253     }
2254   if (operands[2] == constm1_rtx)
2255     {
2256       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2257       DONE;
2258     }
2261 (define_insn "*subf<mode>3_carry_in_internal"
2262   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2263         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2264                             (reg:GPR CA_REGNO))
2265                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2266    (clobber (reg:GPR CA_REGNO))]
2267   ""
2268   "subfe %0,%1,%2"
2269   [(set_attr "type" "add")])
2271 (define_insn "subf<mode>3_carry_in_0"
2272   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2273         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2274                   (reg:GPR CA_REGNO)))
2275    (clobber (reg:GPR CA_REGNO))]
2276   ""
2277   "subfze %0,%1"
2278   [(set_attr "type" "add")])
2280 (define_insn "subf<mode>3_carry_in_m1"
2281   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2282         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2283                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2284                   (const_int -2)))
2285    (clobber (reg:GPR CA_REGNO))]
2286   ""
2287   "subfme %0,%1"
2288   [(set_attr "type" "add")])
2290 (define_insn "subf<mode>3_carry_in_xx"
2291   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2292         (plus:GPR (reg:GPR CA_REGNO)
2293                   (const_int -1)))
2294    (clobber (reg:GPR CA_REGNO))]
2295   ""
2296   "subfe %0,%0,%0"
2297   [(set_attr "type" "add")])
2300 (define_insn "@neg<mode>2"
2301   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2302         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2303   ""
2304   "neg %0,%1"
2305   [(set_attr "type" "add")])
2307 (define_insn_and_split "*neg<mode>2_dot"
2308   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2309         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2310                     (const_int 0)))
2311    (clobber (match_scratch:GPR 0 "=r,r"))]
2312   "<MODE>mode == Pmode"
2313   "@
2314    neg. %0,%1
2315    #"
2316   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2317   [(set (match_dup 0)
2318         (neg:GPR (match_dup 1)))
2319    (set (match_dup 2)
2320         (compare:CC (match_dup 0)
2321                     (const_int 0)))]
2322   ""
2323   [(set_attr "type" "add")
2324    (set_attr "dot" "yes")
2325    (set_attr "length" "4,8")])
2327 (define_insn_and_split "*neg<mode>2_dot2"
2328   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2329         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2330                     (const_int 0)))
2331    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2332         (neg:GPR (match_dup 1)))]
2333   "<MODE>mode == Pmode"
2334   "@
2335    neg. %0,%1
2336    #"
2337   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2338   [(set (match_dup 0)
2339         (neg:GPR (match_dup 1)))
2340    (set (match_dup 2)
2341         (compare:CC (match_dup 0)
2342                     (const_int 0)))]
2343   ""
2344   [(set_attr "type" "add")
2345    (set_attr "dot" "yes")
2346    (set_attr "length" "4,8")])
2349 (define_insn "clz<mode>2"
2350   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2351         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2352   ""
2353   "cntlz<wd> %0,%1"
2354   [(set_attr "type" "cntlz")])
2356 (define_expand "ctz<mode>2"
2357    [(set (match_operand:GPR 0 "gpc_reg_operand")
2358          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2359   ""
2361   if (TARGET_CTZ)
2362     {
2363       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2364       DONE;
2365     }
2367   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2368   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2369   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2371   if (TARGET_POPCNTD)
2372     {
2373       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2374       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2375       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2376       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2377     }
2378   else
2379     {
2380       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2381       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2382       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2383       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2384     }
2386   DONE;
2389 (define_insn "ctz<mode>2_hw"
2390   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2391         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2392   "TARGET_CTZ"
2393   "cnttz<wd> %0,%1"
2394   [(set_attr "type" "cntlz")])
2396 (define_expand "ffs<mode>2"
2397   [(set (match_operand:GPR 0 "gpc_reg_operand")
2398         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2399   ""
2401   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2402   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2403   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2404   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2405   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2406   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2407   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2408   DONE;
2412 (define_expand "popcount<mode>2"
2413   [(set (match_operand:GPR 0 "gpc_reg_operand")
2414         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2415   "TARGET_POPCNTB || TARGET_POPCNTD"
2417   rs6000_emit_popcount (operands[0], operands[1]);
2418   DONE;
2421 (define_insn "popcntb<mode>2"
2422   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2423         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2424                     UNSPEC_POPCNTB))]
2425   "TARGET_POPCNTB"
2426   "popcntb %0,%1"
2427   [(set_attr "type" "popcnt")])
2429 (define_insn "popcntd<mode>2"
2430   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2431         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2432   "TARGET_POPCNTD"
2433   "popcnt<wd> %0,%1"
2434   [(set_attr "type" "popcnt")])
2437 (define_expand "parity<mode>2"
2438   [(set (match_operand:GPR 0 "gpc_reg_operand")
2439         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2440   "TARGET_POPCNTB"
2442   rs6000_emit_parity (operands[0], operands[1]);
2443   DONE;
2446 (define_insn "parity<mode>2_cmpb"
2447   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2448         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2449   "TARGET_CMPB && TARGET_POPCNTB"
2450   "prty<wd> %0,%1"
2451   [(set_attr "type" "popcnt")])
2453 (define_insn "cmpb<mode>3"
2454   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2455         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2456                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2457   "TARGET_CMPB"
2458   "cmpb %0,%1,%2"
2459   [(set_attr "type" "cmp")])
2461 ;; Since the hardware zeros the upper part of the register, save generating the
2462 ;; AND immediate if we are converting to unsigned
2463 (define_insn "*bswap<mode>2_extenddi"
2464   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2465         (zero_extend:DI
2466          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2467   "TARGET_POWERPC64"
2468   "l<wd>brx %0,%y1"
2469   [(set_attr "type" "load")])
2471 (define_insn "*bswaphi2_extendsi"
2472   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2473         (zero_extend:SI
2474          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2475   ""
2476   "lhbrx %0,%y1"
2477   [(set_attr "type" "load")])
2479 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2480 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2481 ;; load with byte swap, which can be slower than doing it in the registers.  It
2482 ;; also prevents certain failures with the RELOAD register allocator.
2484 (define_expand "bswap<mode>2"
2485   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2486    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2487   ""
2489   rtx dest = operands[0];
2490   rtx src = operands[1];
2492   if (!REG_P (dest) && !REG_P (src))
2493     src = force_reg (<MODE>mode, src);
2495   if (MEM_P (src))
2496     {
2497       src = rs6000_force_indexed_or_indirect_mem (src);
2498       emit_insn (gen_bswap<mode>2_load (dest, src));
2499     }
2500   else if (MEM_P (dest))
2501     {
2502       dest = rs6000_force_indexed_or_indirect_mem (dest);
2503       emit_insn (gen_bswap<mode>2_store (dest, src));
2504     }
2505   else
2506     emit_insn (gen_bswap<mode>2_reg (dest, src));
2507   DONE;
2510 (define_insn "bswap<mode>2_load"
2511   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2512         (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2513   ""
2514   "l<wd>brx %0,%y1"
2515   [(set_attr "type" "load")])
2517 (define_insn "bswap<mode>2_store"
2518   [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2519         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2520   ""
2521   "st<wd>brx %1,%y0"
2522   [(set_attr "type" "store")])
2524 (define_insn_and_split "bswaphi2_reg"
2525   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2526         (bswap:HI
2527          (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2528    (clobber (match_scratch:SI 2 "=&r,X"))]
2529   ""
2530   "@
2531    #
2532    xxbrh %x0,%x1"
2533   "reload_completed && int_reg_operand (operands[0], HImode)"
2534   [(set (match_dup 3)
2535         (and:SI (lshiftrt:SI (match_dup 4)
2536                              (const_int 8))
2537                 (const_int 255)))
2538    (set (match_dup 2)
2539         (and:SI (ashift:SI (match_dup 4)
2540                            (const_int 8))
2541                 (const_int 65280)))             ;; 0xff00
2542    (set (match_dup 3)
2543         (ior:SI (match_dup 3)
2544                 (match_dup 2)))]
2546   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2547   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2549   [(set_attr "length" "12,4")
2550    (set_attr "type" "*,vecperm")
2551    (set_attr "isa" "*,p9v")])
2553 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2554 ;; zero_extract insns do not change for -mlittle.
2555 (define_insn_and_split "bswapsi2_reg"
2556   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2557         (bswap:SI
2558          (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2559   ""
2560   "@
2561    #
2562    xxbrw %x0,%x1"
2563   "reload_completed && int_reg_operand (operands[0], SImode)"
2564   [(set (match_dup 0)                                   ; DABC
2565         (rotate:SI (match_dup 1)
2566                    (const_int 24)))
2567    (set (match_dup 0)                                   ; DCBC
2568         (ior:SI (and:SI (ashift:SI (match_dup 1)
2569                                    (const_int 8))
2570                         (const_int 16711680))
2571                 (and:SI (match_dup 0)
2572                         (const_int -16711681))))
2573    (set (match_dup 0)                                   ; DCBA
2574         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2575                                      (const_int 24))
2576                         (const_int 255))
2577                 (and:SI (match_dup 0)
2578                         (const_int -256))))]
2579   ""
2580   [(set_attr "length" "12,4")
2581    (set_attr "type" "*,vecperm")
2582    (set_attr "isa" "*,p9v")])
2584 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2585 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2586 ;; complex code.
2588 (define_expand "bswapdi2"
2589   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2590                    (bswap:DI
2591                     (match_operand:DI 1 "reg_or_mem_operand")))
2592               (clobber (match_scratch:DI 2))
2593               (clobber (match_scratch:DI 3))])]
2594   ""
2596   rtx dest = operands[0];
2597   rtx src = operands[1];
2599   if (!REG_P (dest) && !REG_P (src))
2600     operands[1] = src = force_reg (DImode, src);
2602   if (TARGET_POWERPC64 && TARGET_LDBRX)
2603     {
2604       if (MEM_P (src))
2605         {
2606           src = rs6000_force_indexed_or_indirect_mem (src);
2607           emit_insn (gen_bswapdi2_load (dest, src));
2608         }
2609       else if (MEM_P (dest))
2610         {
2611           dest = rs6000_force_indexed_or_indirect_mem (dest);
2612           emit_insn (gen_bswapdi2_store (dest, src));
2613         }
2614       else if (TARGET_P9_VECTOR)
2615         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2616       else
2617         emit_insn (gen_bswapdi2_reg (dest, src));
2618       DONE;
2619     }
2621   if (!TARGET_POWERPC64)
2622     {
2623       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2624          that uses 64-bit registers needs the same scratch registers as 64-bit
2625          mode.  */
2626       emit_insn (gen_bswapdi2_32bit (dest, src));
2627       DONE;
2628     }
2631 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2632 (define_insn "bswapdi2_load"
2633   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2634         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2635   "TARGET_POWERPC64 && TARGET_LDBRX"
2636   "ldbrx %0,%y1"
2637   [(set_attr "type" "load")])
2639 (define_insn "bswapdi2_store"
2640   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2641         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2642   "TARGET_POWERPC64 && TARGET_LDBRX"
2643   "stdbrx %1,%y0"
2644   [(set_attr "type" "store")])
2646 (define_insn "bswapdi2_xxbrd"
2647   [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2648         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2649   "TARGET_P9_VECTOR"
2650   "xxbrd %x0,%x1"
2651   [(set_attr "type" "vecperm")
2652    (set_attr "isa" "p9v")])
2654 (define_insn "bswapdi2_reg"
2655   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2656         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2657    (clobber (match_scratch:DI 2 "=&r"))
2658    (clobber (match_scratch:DI 3 "=&r"))]
2659   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2660   "#"
2661   [(set_attr "length" "36")])
2663 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2664 (define_insn "*bswapdi2_64bit"
2665   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2666         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2667    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2668    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2669   "TARGET_POWERPC64 && !TARGET_LDBRX
2670    && (REG_P (operands[0]) || REG_P (operands[1]))
2671    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2672    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2673   "#"
2674   [(set_attr "length" "16,12,36")])
2676 (define_split
2677   [(set (match_operand:DI 0 "gpc_reg_operand")
2678         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2679    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2680    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2681   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2682   [(const_int 0)]
2684   rtx dest   = operands[0];
2685   rtx src    = operands[1];
2686   rtx op2    = operands[2];
2687   rtx op3    = operands[3];
2688   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2689                                     BYTES_BIG_ENDIAN ? 4 : 0);
2690   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2691                                      BYTES_BIG_ENDIAN ? 4 : 0);
2692   rtx addr1;
2693   rtx addr2;
2694   rtx word1;
2695   rtx word2;
2697   addr1 = XEXP (src, 0);
2698   if (GET_CODE (addr1) == PLUS)
2699     {
2700       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2701       if (TARGET_AVOID_XFORM)
2702         {
2703           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2704           addr2 = op2;
2705         }
2706       else
2707         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2708     }
2709   else if (TARGET_AVOID_XFORM)
2710     {
2711       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2712       addr2 = op2;
2713     }
2714   else
2715     {
2716       emit_move_insn (op2, GEN_INT (4));
2717       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2718     }
2720   word1 = change_address (src, SImode, addr1);
2721   word2 = change_address (src, SImode, addr2);
2723   if (BYTES_BIG_ENDIAN)
2724     {
2725       emit_insn (gen_bswapsi2 (op3_32, word2));
2726       emit_insn (gen_bswapsi2 (dest_32, word1));
2727     }
2728   else
2729     {
2730       emit_insn (gen_bswapsi2 (op3_32, word1));
2731       emit_insn (gen_bswapsi2 (dest_32, word2));
2732     }
2734   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2735   emit_insn (gen_iordi3 (dest, dest, op3));
2736   DONE;
2739 (define_split
2740   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2741         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2742    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2743    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2744   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2745   [(const_int 0)]
2747   rtx dest   = operands[0];
2748   rtx src    = operands[1];
2749   rtx op2    = operands[2];
2750   rtx op3    = operands[3];
2751   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2752                                     BYTES_BIG_ENDIAN ? 4 : 0);
2753   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2754                                     BYTES_BIG_ENDIAN ? 4 : 0);
2755   rtx addr1;
2756   rtx addr2;
2757   rtx word1;
2758   rtx word2;
2760   addr1 = XEXP (dest, 0);
2761   if (GET_CODE (addr1) == PLUS)
2762     {
2763       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2764       if (TARGET_AVOID_XFORM)
2765         {
2766           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2767           addr2 = op2;
2768         }
2769       else
2770         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2771     }
2772   else if (TARGET_AVOID_XFORM)
2773     {
2774       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2775       addr2 = op2;
2776     }
2777   else
2778     {
2779       emit_move_insn (op2, GEN_INT (4));
2780       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2781     }
2783   word1 = change_address (dest, SImode, addr1);
2784   word2 = change_address (dest, SImode, addr2);
2786   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2788   if (BYTES_BIG_ENDIAN)
2789     {
2790       emit_insn (gen_bswapsi2 (word1, src_si));
2791       emit_insn (gen_bswapsi2 (word2, op3_si));
2792     }
2793   else
2794     {
2795       emit_insn (gen_bswapsi2 (word2, src_si));
2796       emit_insn (gen_bswapsi2 (word1, op3_si));
2797     }
2798   DONE;
2801 (define_split
2802   [(set (match_operand:DI 0 "gpc_reg_operand")
2803         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2804    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2805    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2806   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2807   [(const_int 0)]
2809   rtx dest    = operands[0];
2810   rtx src     = operands[1];
2811   rtx op2     = operands[2];
2812   rtx op3     = operands[3];
2813   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2814   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2815   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2816   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2817   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2819   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2820   emit_insn (gen_bswapsi2 (dest_si, src_si));
2821   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2822   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2823   emit_insn (gen_iordi3 (dest, dest, op3));
2824   DONE;
2827 (define_insn "bswapdi2_32bit"
2828   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2829         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2830    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2831   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2832   "#"
2833   [(set_attr "length" "16,12,36")])
2835 (define_split
2836   [(set (match_operand:DI 0 "gpc_reg_operand")
2837         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2838    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2839   "!TARGET_POWERPC64 && reload_completed"
2840   [(const_int 0)]
2842   rtx dest  = operands[0];
2843   rtx src   = operands[1];
2844   rtx op2   = operands[2];
2845   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2846   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2847   rtx addr1;
2848   rtx addr2;
2849   rtx word1;
2850   rtx word2;
2852   addr1 = XEXP (src, 0);
2853   if (GET_CODE (addr1) == PLUS)
2854     {
2855       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2856       if (TARGET_AVOID_XFORM
2857           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2858         {
2859           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2860           addr2 = op2;
2861         }
2862       else
2863         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2864     }
2865   else if (TARGET_AVOID_XFORM
2866            || REGNO (addr1) == REGNO (dest2))
2867     {
2868       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2869       addr2 = op2;
2870     }
2871   else
2872     {
2873       emit_move_insn (op2, GEN_INT (4));
2874       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2875     }
2877   word1 = change_address (src, SImode, addr1);
2878   word2 = change_address (src, SImode, addr2);
2880   emit_insn (gen_bswapsi2 (dest2, word1));
2881   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2882      thus allowing us to omit an early clobber on the output.  */
2883   emit_insn (gen_bswapsi2 (dest1, word2));
2884   DONE;
2887 (define_split
2888   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2889         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2890    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2891   "!TARGET_POWERPC64 && reload_completed"
2892   [(const_int 0)]
2894   rtx dest = operands[0];
2895   rtx src  = operands[1];
2896   rtx op2  = operands[2];
2897   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2898   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2899   rtx addr1;
2900   rtx addr2;
2901   rtx word1;
2902   rtx word2;
2904   addr1 = XEXP (dest, 0);
2905   if (GET_CODE (addr1) == PLUS)
2906     {
2907       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2908       if (TARGET_AVOID_XFORM)
2909         {
2910           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2911           addr2 = op2;
2912         }
2913       else
2914         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2915     }
2916   else if (TARGET_AVOID_XFORM)
2917     {
2918       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2919       addr2 = op2;
2920     }
2921   else
2922     {
2923       emit_move_insn (op2, GEN_INT (4));
2924       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2925     }
2927   word1 = change_address (dest, SImode, addr1);
2928   word2 = change_address (dest, SImode, addr2);
2930   emit_insn (gen_bswapsi2 (word2, src1));
2931   emit_insn (gen_bswapsi2 (word1, src2));
2932   DONE;
2935 (define_split
2936   [(set (match_operand:DI 0 "gpc_reg_operand")
2937         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2938    (clobber (match_operand:SI 2 ""))]
2939   "!TARGET_POWERPC64 && reload_completed"
2940   [(const_int 0)]
2942   rtx dest  = operands[0];
2943   rtx src   = operands[1];
2944   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2945   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2946   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2947   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2949   emit_insn (gen_bswapsi2 (dest1, src2));
2950   emit_insn (gen_bswapsi2 (dest2, src1));
2951   DONE;
2955 (define_insn "mul<mode>3"
2956   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2957         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2958                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2959   ""
2960   "@
2961    mull<wd> %0,%1,%2
2962    mulli %0,%1,%2"
2963    [(set_attr "type" "mul")
2964     (set (attr "size")
2965       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2966                 (const_string "8")
2967              (match_operand:GPR 2 "short_cint_operand")
2968                 (const_string "16")]
2969         (const_string "<bits>")))])
2971 (define_insn_and_split "*mul<mode>3_dot"
2972   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2973         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2974                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2975                     (const_int 0)))
2976    (clobber (match_scratch:GPR 0 "=r,r"))]
2977   "<MODE>mode == Pmode"
2978   "@
2979    mull<wd>. %0,%1,%2
2980    #"
2981   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2982   [(set (match_dup 0)
2983         (mult:GPR (match_dup 1)
2984                   (match_dup 2)))
2985    (set (match_dup 3)
2986         (compare:CC (match_dup 0)
2987                     (const_int 0)))]
2988   ""
2989   [(set_attr "type" "mul")
2990    (set_attr "size" "<bits>")
2991    (set_attr "dot" "yes")
2992    (set_attr "length" "4,8")])
2994 (define_insn_and_split "*mul<mode>3_dot2"
2995   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2996         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2997                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2998                     (const_int 0)))
2999    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3000         (mult:GPR (match_dup 1)
3001                   (match_dup 2)))]
3002   "<MODE>mode == Pmode"
3003   "@
3004    mull<wd>. %0,%1,%2
3005    #"
3006   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3007   [(set (match_dup 0)
3008         (mult:GPR (match_dup 1)
3009                   (match_dup 2)))
3010    (set (match_dup 3)
3011         (compare:CC (match_dup 0)
3012                     (const_int 0)))]
3013   ""
3014   [(set_attr "type" "mul")
3015    (set_attr "size" "<bits>")
3016    (set_attr "dot" "yes")
3017    (set_attr "length" "4,8")])
3020 (define_expand "<su>mul<mode>3_highpart"
3021   [(set (match_operand:GPR 0 "gpc_reg_operand")
3022         (subreg:GPR
3023           (mult:<DMODE> (any_extend:<DMODE>
3024                           (match_operand:GPR 1 "gpc_reg_operand"))
3025                         (any_extend:<DMODE>
3026                           (match_operand:GPR 2 "gpc_reg_operand")))
3027          0))]
3028   ""
3030   if (<MODE>mode == SImode && TARGET_POWERPC64)
3031     {
3032       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3033                                              operands[2]));
3034       DONE;
3035     }
3037   if (!WORDS_BIG_ENDIAN)
3038     {
3039       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3040                                                  operands[2]));
3041       DONE;
3042     }
3045 (define_insn "*<su>mul<mode>3_highpart"
3046   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3047         (subreg:GPR
3048           (mult:<DMODE> (any_extend:<DMODE>
3049                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
3050                         (any_extend:<DMODE>
3051                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
3052          0))]
3053   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3054   "mulh<wd><u> %0,%1,%2"
3055   [(set_attr "type" "mul")
3056    (set_attr "size" "<bits>")])
3058 (define_insn "<su>mulsi3_highpart_le"
3059   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3060         (subreg:SI
3061           (mult:DI (any_extend:DI
3062                      (match_operand:SI 1 "gpc_reg_operand" "r"))
3063                    (any_extend:DI
3064                      (match_operand:SI 2 "gpc_reg_operand" "r")))
3065          4))]
3066   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3067   "mulhw<u> %0,%1,%2"
3068   [(set_attr "type" "mul")])
3070 (define_insn "<su>muldi3_highpart_le"
3071   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3072         (subreg:DI
3073           (mult:TI (any_extend:TI
3074                      (match_operand:DI 1 "gpc_reg_operand" "r"))
3075                    (any_extend:TI
3076                      (match_operand:DI 2 "gpc_reg_operand" "r")))
3077          8))]
3078   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3079   "mulhd<u> %0,%1,%2"
3080   [(set_attr "type" "mul")
3081    (set_attr "size" "64")])
3083 (define_insn "<su>mulsi3_highpart_64"
3084   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3085         (truncate:SI
3086           (lshiftrt:DI
3087             (mult:DI (any_extend:DI
3088                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3089                      (any_extend:DI
3090                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3091             (const_int 32))))]
3092   "TARGET_POWERPC64"
3093   "mulhw<u> %0,%1,%2"
3094   [(set_attr "type" "mul")])
3096 (define_expand "<u>mul<mode><dmode>3"
3097   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3098         (mult:<DMODE> (any_extend:<DMODE>
3099                         (match_operand:GPR 1 "gpc_reg_operand"))
3100                       (any_extend:<DMODE>
3101                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3102   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3104   rtx l = gen_reg_rtx (<MODE>mode);
3105   rtx h = gen_reg_rtx (<MODE>mode);
3106   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3107   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3108   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3109   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3110   DONE;
3113 (define_insn "*maddld<mode>4"
3114   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3115         (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3116                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
3117                   (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3118   "TARGET_MADDLD"
3119   "maddld %0,%1,%2,%3"
3120   [(set_attr "type" "mul")])
3122 (define_insn "udiv<mode>3"
3123   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3124         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3125                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3126   ""
3127   "div<wd>u %0,%1,%2"
3128   [(set_attr "type" "div")
3129    (set_attr "size" "<bits>")])
3132 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3133 ;; modulus.  If it isn't a power of two, force operands into register and do
3134 ;; a normal divide.
3135 (define_expand "div<mode>3"
3136   [(set (match_operand:GPR 0 "gpc_reg_operand")
3137         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3138                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3139   ""
3141   if (CONST_INT_P (operands[2])
3142       && INTVAL (operands[2]) > 0
3143       && exact_log2 (INTVAL (operands[2])) >= 0)
3144     {
3145       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3146       DONE;
3147     }
3149   operands[2] = force_reg (<MODE>mode, operands[2]);
3152 (define_insn "*div<mode>3"
3153   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3154         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3155                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3156   ""
3157   "div<wd> %0,%1,%2"
3158   [(set_attr "type" "div")
3159    (set_attr "size" "<bits>")])
3161 (define_insn "div<mode>3_sra"
3162   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3163         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3164                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3165    (clobber (reg:GPR CA_REGNO))]
3166   ""
3167   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3168   [(set_attr "type" "two")
3169    (set_attr "length" "8")])
3171 (define_insn_and_split "*div<mode>3_sra_dot"
3172   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3173         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3174                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3175                     (const_int 0)))
3176    (clobber (match_scratch:GPR 0 "=r,r"))
3177    (clobber (reg:GPR CA_REGNO))]
3178   "<MODE>mode == Pmode"
3179   "@
3180    sra<wd>i %0,%1,%p2\;addze. %0,%0
3181    #"
3182   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3183   [(parallel [(set (match_dup 0)
3184                    (div:GPR (match_dup 1)
3185                             (match_dup 2)))
3186               (clobber (reg:GPR CA_REGNO))])
3187    (set (match_dup 3)
3188         (compare:CC (match_dup 0)
3189                     (const_int 0)))]
3190   ""
3191   [(set_attr "type" "two")
3192    (set_attr "length" "8,12")
3193    (set_attr "cell_micro" "not")])
3195 (define_insn_and_split "*div<mode>3_sra_dot2"
3196   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3197         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3198                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3199                     (const_int 0)))
3200    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3201         (div:GPR (match_dup 1)
3202                  (match_dup 2)))
3203    (clobber (reg:GPR CA_REGNO))]
3204   "<MODE>mode == Pmode"
3205   "@
3206    sra<wd>i %0,%1,%p2\;addze. %0,%0
3207    #"
3208   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3209   [(parallel [(set (match_dup 0)
3210                    (div:GPR (match_dup 1)
3211                             (match_dup 2)))
3212               (clobber (reg:GPR CA_REGNO))])
3213    (set (match_dup 3)
3214         (compare:CC (match_dup 0)
3215                     (const_int 0)))]
3216   ""
3217   [(set_attr "type" "two")
3218    (set_attr "length" "8,12")
3219    (set_attr "cell_micro" "not")])
3221 (define_expand "mod<mode>3"
3222   [(set (match_operand:GPR 0 "gpc_reg_operand")
3223         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3224                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3225   ""
3227   int i;
3228   rtx temp1;
3229   rtx temp2;
3231   if (!CONST_INT_P (operands[2])
3232       || INTVAL (operands[2]) <= 0
3233       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3234     {
3235       if (!TARGET_MODULO)
3236         FAIL;
3238       operands[2] = force_reg (<MODE>mode, operands[2]);
3239     }
3240   else
3241     {
3242       temp1 = gen_reg_rtx (<MODE>mode);
3243       temp2 = gen_reg_rtx (<MODE>mode);
3245       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3246       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3247       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3248       DONE;
3249     }
3252 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3253 ;; mod, prefer putting the result of mod into a different register
3254 (define_insn "*mod<mode>3"
3255   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3256         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3257                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3258   "TARGET_MODULO"
3259   "mods<wd> %0,%1,%2"
3260   [(set_attr "type" "div")
3261    (set_attr "size" "<bits>")])
3264 (define_insn "umod<mode>3"
3265   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3266         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3267                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3268   "TARGET_MODULO"
3269   "modu<wd> %0,%1,%2"
3270   [(set_attr "type" "div")
3271    (set_attr "size" "<bits>")])
3273 ;; On machines with modulo support, do a combined div/mod the old fashioned
3274 ;; method, since the multiply/subtract is faster than doing the mod instruction
3275 ;; after a divide.
3277 (define_peephole2
3278   [(set (match_operand:GPR 0 "gpc_reg_operand")
3279         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3280                  (match_operand:GPR 2 "gpc_reg_operand")))
3281    (set (match_operand:GPR 3 "gpc_reg_operand")
3282         (mod:GPR (match_dup 1)
3283                  (match_dup 2)))]
3284   "TARGET_MODULO
3285    && ! reg_mentioned_p (operands[0], operands[1])
3286    && ! reg_mentioned_p (operands[0], operands[2])
3287    && ! reg_mentioned_p (operands[3], operands[1])
3288    && ! reg_mentioned_p (operands[3], operands[2])"
3289   [(set (match_dup 0)
3290         (div:GPR (match_dup 1)
3291                  (match_dup 2)))
3292    (set (match_dup 3)
3293         (mult:GPR (match_dup 0)
3294                   (match_dup 2)))
3295    (set (match_dup 3)
3296         (minus:GPR (match_dup 1)
3297                    (match_dup 3)))])
3299 (define_peephole2
3300   [(set (match_operand:GPR 0 "gpc_reg_operand")
3301         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3302                   (match_operand:GPR 2 "gpc_reg_operand")))
3303    (set (match_operand:GPR 3 "gpc_reg_operand")
3304         (umod:GPR (match_dup 1)
3305                   (match_dup 2)))]
3306   "TARGET_MODULO
3307    && ! reg_mentioned_p (operands[0], operands[1])
3308    && ! reg_mentioned_p (operands[0], operands[2])
3309    && ! reg_mentioned_p (operands[3], operands[1])
3310    && ! reg_mentioned_p (operands[3], operands[2])"
3311   [(set (match_dup 0)
3312         (udiv:GPR (match_dup 1)
3313                   (match_dup 2)))
3314    (set (match_dup 3)
3315         (mult:GPR (match_dup 0)
3316                   (match_dup 2)))
3317    (set (match_dup 3)
3318         (minus:GPR (match_dup 1)
3319                    (match_dup 3)))])
3322 ;; Logical instructions
3323 ;; The logical instructions are mostly combined by using match_operator,
3324 ;; but the plain AND insns are somewhat different because there is no
3325 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3326 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3328 (define_expand "and<mode>3"
3329   [(set (match_operand:SDI 0 "gpc_reg_operand")
3330         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3331                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3332   ""
3334   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3335     {
3336       rs6000_split_logical (operands, AND, false, false, false);
3337       DONE;
3338     }
3340   if (CONST_INT_P (operands[2]))
3341     {
3342       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3343         {
3344           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3345           DONE;
3346         }
3348       if (logical_const_operand (operands[2], <MODE>mode))
3349         {
3350           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3351           DONE;
3352         }
3354       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3355         {
3356           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3357           DONE;
3358         }
3360       operands[2] = force_reg (<MODE>mode, operands[2]);
3361     }
3365 (define_insn "and<mode>3_imm"
3366   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3367         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3368                  (match_operand:GPR 2 "logical_const_operand" "n")))
3369    (clobber (match_scratch:CC 3 "=x"))]
3370   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3371   "andi%e2. %0,%1,%u2"
3372   [(set_attr "type" "logical")
3373    (set_attr "dot" "yes")])
3375 (define_insn_and_split "*and<mode>3_imm_dot"
3376   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3377         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3378                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3379                     (const_int 0)))
3380    (clobber (match_scratch:GPR 0 "=r,r"))
3381    (clobber (match_scratch:CC 4 "=X,x"))]
3382   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3383    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3384   "@
3385    andi%e2. %0,%1,%u2
3386    #"
3387   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3388   [(parallel [(set (match_dup 0)
3389                    (and:GPR (match_dup 1)
3390                             (match_dup 2)))
3391               (clobber (match_dup 4))])
3392    (set (match_dup 3)
3393         (compare:CC (match_dup 0)
3394                     (const_int 0)))]
3395   ""
3396   [(set_attr "type" "logical")
3397    (set_attr "dot" "yes")
3398    (set_attr "length" "4,8")])
3400 (define_insn_and_split "*and<mode>3_imm_dot2"
3401   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3402         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3403                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3404                     (const_int 0)))
3405    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3406         (and:GPR (match_dup 1)
3407                  (match_dup 2)))
3408    (clobber (match_scratch:CC 4 "=X,x"))]
3409   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3410    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3411   "@
3412    andi%e2. %0,%1,%u2
3413    #"
3414   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3415   [(parallel [(set (match_dup 0)
3416                    (and:GPR (match_dup 1)
3417                             (match_dup 2)))
3418               (clobber (match_dup 4))])
3419    (set (match_dup 3)
3420         (compare:CC (match_dup 0)
3421                     (const_int 0)))]
3422   ""
3423   [(set_attr "type" "logical")
3424    (set_attr "dot" "yes")
3425    (set_attr "length" "4,8")])
3427 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3428   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3429         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3430                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3431                     (const_int 0)))
3432    (clobber (match_scratch:GPR 0 "=r,r"))]
3433   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3434    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3435   "@
3436    andi%e2. %0,%1,%u2
3437    #"
3438   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3439   [(set (match_dup 0)
3440         (and:GPR (match_dup 1)
3441                  (match_dup 2)))
3442    (set (match_dup 3)
3443         (compare:CC (match_dup 0)
3444                     (const_int 0)))]
3445   ""
3446   [(set_attr "type" "logical")
3447    (set_attr "dot" "yes")
3448    (set_attr "length" "4,8")])
3450 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3451   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3452         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3453                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3454                     (const_int 0)))
3455    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3456         (and:GPR (match_dup 1)
3457                  (match_dup 2)))]
3458   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3459    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3460   "@
3461    andi%e2. %0,%1,%u2
3462    #"
3463   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3464   [(set (match_dup 0)
3465         (and:GPR (match_dup 1)
3466                  (match_dup 2)))
3467    (set (match_dup 3)
3468         (compare:CC (match_dup 0)
3469                     (const_int 0)))]
3470   ""
3471   [(set_attr "type" "logical")
3472    (set_attr "dot" "yes")
3473    (set_attr "length" "4,8")])
3475 (define_insn "*and<mode>3_imm_dot_shifted"
3476   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3477         (compare:CC
3478           (and:GPR
3479             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3480                           (match_operand:SI 4 "const_int_operand" "n"))
3481             (match_operand:GPR 2 "const_int_operand" "n"))
3482           (const_int 0)))
3483    (clobber (match_scratch:GPR 0 "=r"))]
3484   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3485                                    << INTVAL (operands[4])),
3486                           DImode)
3487    && (<MODE>mode == Pmode
3488        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3490   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3491   return "andi%e2. %0,%1,%u2";
3493   [(set_attr "type" "logical")
3494    (set_attr "dot" "yes")])
3497 (define_insn "and<mode>3_mask"
3498   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3499         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3500                  (match_operand:GPR 2 "const_int_operand" "n")))]
3501   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3503   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3505   [(set_attr "type" "shift")])
3507 (define_insn_and_split "*and<mode>3_mask_dot"
3508   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3509         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3510                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3511                     (const_int 0)))
3512    (clobber (match_scratch:GPR 0 "=r,r"))]
3513   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3514    && !logical_const_operand (operands[2], <MODE>mode)
3515    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3517   if (which_alternative == 0)
3518     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3519   else
3520     return "#";
3522   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3523   [(set (match_dup 0)
3524         (and:GPR (match_dup 1)
3525                  (match_dup 2)))
3526    (set (match_dup 3)
3527         (compare:CC (match_dup 0)
3528                     (const_int 0)))]
3529   ""
3530   [(set_attr "type" "shift")
3531    (set_attr "dot" "yes")
3532    (set_attr "length" "4,8")])
3534 (define_insn_and_split "*and<mode>3_mask_dot2"
3535   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3536         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3537                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3538                     (const_int 0)))
3539    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3540         (and:GPR (match_dup 1)
3541                  (match_dup 2)))]
3542   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3543    && !logical_const_operand (operands[2], <MODE>mode)
3544    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3546   if (which_alternative == 0)
3547     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3548   else
3549     return "#";
3551   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3552   [(set (match_dup 0)
3553         (and:GPR (match_dup 1)
3554                  (match_dup 2)))
3555    (set (match_dup 3)
3556         (compare:CC (match_dup 0)
3557                     (const_int 0)))]
3558   ""
3559   [(set_attr "type" "shift")
3560    (set_attr "dot" "yes")
3561    (set_attr "length" "4,8")])
3564 (define_insn_and_split "*and<mode>3_2insn"
3565   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3566         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3567                  (match_operand:GPR 2 "const_int_operand" "n")))]
3568   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3569    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3570         || logical_const_operand (operands[2], <MODE>mode))"
3571   "#"
3572   "&& 1"
3573   [(pc)]
3575   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3576   DONE;
3578   [(set_attr "type" "shift")
3579    (set_attr "length" "8")])
3581 (define_insn_and_split "*and<mode>3_2insn_dot"
3582   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3583         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3584                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3585                     (const_int 0)))
3586    (clobber (match_scratch:GPR 0 "=r,r"))]
3587   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3588    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3589    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3590         || logical_const_operand (operands[2], <MODE>mode))"
3591   "#"
3592   "&& reload_completed"
3593   [(pc)]
3595   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3596   DONE;
3598   [(set_attr "type" "shift")
3599    (set_attr "dot" "yes")
3600    (set_attr "length" "8,12")])
3602 (define_insn_and_split "*and<mode>3_2insn_dot2"
3603   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3604         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3605                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3606                     (const_int 0)))
3607    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3608         (and:GPR (match_dup 1)
3609                  (match_dup 2)))]
3610   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3611    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3612    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3613         || logical_const_operand (operands[2], <MODE>mode))"
3614   "#"
3615   "&& reload_completed"
3616   [(pc)]
3618   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3619   DONE;
3621   [(set_attr "type" "shift")
3622    (set_attr "dot" "yes")
3623    (set_attr "length" "8,12")])
3626 (define_expand "<code><mode>3"
3627   [(set (match_operand:SDI 0 "gpc_reg_operand")
3628         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3629                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3630   ""
3632   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3633     {
3634       rs6000_split_logical (operands, <CODE>, false, false, false);
3635       DONE;
3636     }
3638   if (non_logical_cint_operand (operands[2], <MODE>mode))
3639     {
3640       rtx tmp = ((!can_create_pseudo_p ()
3641                   || rtx_equal_p (operands[0], operands[1]))
3642                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3644       HOST_WIDE_INT value = INTVAL (operands[2]);
3645       HOST_WIDE_INT lo = value & 0xffff;
3646       HOST_WIDE_INT hi = value - lo;
3648       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3649       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3650       DONE;
3651     }
3653   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3654     operands[2] = force_reg (<MODE>mode, operands[2]);
3657 (define_split
3658   [(set (match_operand:GPR 0 "gpc_reg_operand")
3659         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3660                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3661   ""
3662   [(set (match_dup 3)
3663         (iorxor:GPR (match_dup 1)
3664                     (match_dup 4)))
3665    (set (match_dup 0)
3666         (iorxor:GPR (match_dup 3)
3667                     (match_dup 5)))]
3669   operands[3] = ((!can_create_pseudo_p ()
3670                   || rtx_equal_p (operands[0], operands[1]))
3671                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3673   HOST_WIDE_INT value = INTVAL (operands[2]);
3674   HOST_WIDE_INT lo = value & 0xffff;
3675   HOST_WIDE_INT hi = value - lo;
3677   operands[4] = GEN_INT (hi);
3678   operands[5] = GEN_INT (lo);
3681 (define_insn "*bool<mode>3_imm"
3682   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3683         (match_operator:GPR 3 "boolean_or_operator"
3684          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3685           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3686   ""
3687   "%q3i%e2 %0,%1,%u2"
3688   [(set_attr "type" "logical")])
3690 (define_insn "*bool<mode>3"
3691   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3692         (match_operator:GPR 3 "boolean_operator"
3693          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3694           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3695   ""
3696   "%q3 %0,%1,%2"
3697   [(set_attr "type" "logical")])
3699 (define_insn_and_split "*bool<mode>3_dot"
3700   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3701         (compare:CC (match_operator:GPR 3 "boolean_operator"
3702          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3703           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3704          (const_int 0)))
3705    (clobber (match_scratch:GPR 0 "=r,r"))]
3706   "<MODE>mode == Pmode"
3707   "@
3708    %q3. %0,%1,%2
3709    #"
3710   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3711   [(set (match_dup 0)
3712         (match_dup 3))
3713    (set (match_dup 4)
3714         (compare:CC (match_dup 0)
3715                     (const_int 0)))]
3716   ""
3717   [(set_attr "type" "logical")
3718    (set_attr "dot" "yes")
3719    (set_attr "length" "4,8")])
3721 (define_insn_and_split "*bool<mode>3_dot2"
3722   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3723         (compare:CC (match_operator:GPR 3 "boolean_operator"
3724          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3725           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3726          (const_int 0)))
3727    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3728         (match_dup 3))]
3729   "<MODE>mode == Pmode"
3730   "@
3731    %q3. %0,%1,%2
3732    #"
3733   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3734   [(set (match_dup 0)
3735         (match_dup 3))
3736    (set (match_dup 4)
3737         (compare:CC (match_dup 0)
3738                     (const_int 0)))]
3739   ""
3740   [(set_attr "type" "logical")
3741    (set_attr "dot" "yes")
3742    (set_attr "length" "4,8")])
3745 (define_insn "*boolc<mode>3"
3746   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3747         (match_operator:GPR 3 "boolean_operator"
3748          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3749           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3750   ""
3751   "%q3 %0,%1,%2"
3752   [(set_attr "type" "logical")])
3754 (define_insn_and_split "*boolc<mode>3_dot"
3755   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3756         (compare:CC (match_operator:GPR 3 "boolean_operator"
3757          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3758           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3759          (const_int 0)))
3760    (clobber (match_scratch:GPR 0 "=r,r"))]
3761   "<MODE>mode == Pmode"
3762   "@
3763    %q3. %0,%1,%2
3764    #"
3765   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3766   [(set (match_dup 0)
3767         (match_dup 3))
3768    (set (match_dup 4)
3769         (compare:CC (match_dup 0)
3770                     (const_int 0)))]
3771   ""
3772   [(set_attr "type" "logical")
3773    (set_attr "dot" "yes")
3774    (set_attr "length" "4,8")])
3776 (define_insn_and_split "*boolc<mode>3_dot2"
3777   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3778         (compare:CC (match_operator:GPR 3 "boolean_operator"
3779          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3780           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3781          (const_int 0)))
3782    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3783         (match_dup 3))]
3784   "<MODE>mode == Pmode"
3785   "@
3786    %q3. %0,%1,%2
3787    #"
3788   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3789   [(set (match_dup 0)
3790         (match_dup 3))
3791    (set (match_dup 4)
3792         (compare:CC (match_dup 0)
3793                     (const_int 0)))]
3794   ""
3795   [(set_attr "type" "logical")
3796    (set_attr "dot" "yes")
3797    (set_attr "length" "4,8")])
3800 (define_insn "*boolcc<mode>3"
3801   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3802         (match_operator:GPR 3 "boolean_operator"
3803          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3804           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3805   ""
3806   "%q3 %0,%1,%2"
3807   [(set_attr "type" "logical")])
3809 (define_insn_and_split "*boolcc<mode>3_dot"
3810   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3811         (compare:CC (match_operator:GPR 3 "boolean_operator"
3812          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3813           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3814          (const_int 0)))
3815    (clobber (match_scratch:GPR 0 "=r,r"))]
3816   "<MODE>mode == Pmode"
3817   "@
3818    %q3. %0,%1,%2
3819    #"
3820   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3821   [(set (match_dup 0)
3822         (match_dup 3))
3823    (set (match_dup 4)
3824         (compare:CC (match_dup 0)
3825                     (const_int 0)))]
3826   ""
3827   [(set_attr "type" "logical")
3828    (set_attr "dot" "yes")
3829    (set_attr "length" "4,8")])
3831 (define_insn_and_split "*boolcc<mode>3_dot2"
3832   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3833         (compare:CC (match_operator:GPR 3 "boolean_operator"
3834          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3835           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3836          (const_int 0)))
3837    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3838         (match_dup 3))]
3839   "<MODE>mode == Pmode"
3840   "@
3841    %q3. %0,%1,%2
3842    #"
3843   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3844   [(set (match_dup 0)
3845         (match_dup 3))
3846    (set (match_dup 4)
3847         (compare:CC (match_dup 0)
3848                     (const_int 0)))]
3849   ""
3850   [(set_attr "type" "logical")
3851    (set_attr "dot" "yes")
3852    (set_attr "length" "4,8")])
3855 ;; TODO: Should have dots of this as well.
3856 (define_insn "*eqv<mode>3"
3857   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3858         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3859                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3860   ""
3861   "eqv %0,%1,%2"
3862   [(set_attr "type" "logical")])
3864 ;; Rotate-and-mask and insert.
3866 (define_insn "*rotl<mode>3_mask"
3867   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3868         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3869                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3870                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3871                  (match_operand:GPR 3 "const_int_operand" "n")))]
3872   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3874   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3876   [(set_attr "type" "shift")
3877    (set_attr "maybe_var_shift" "yes")])
3879 (define_insn_and_split "*rotl<mode>3_mask_dot"
3880   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3881         (compare:CC
3882           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3883                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3884                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3885                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3886           (const_int 0)))
3887    (clobber (match_scratch:GPR 0 "=r,r"))]
3888   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3889    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3891   if (which_alternative == 0)
3892     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3893   else
3894     return "#";
3896   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3897   [(set (match_dup 0)
3898         (and:GPR (match_dup 4)
3899                  (match_dup 3)))
3900    (set (match_dup 5)
3901         (compare:CC (match_dup 0)
3902                     (const_int 0)))]
3903   ""
3904   [(set_attr "type" "shift")
3905    (set_attr "maybe_var_shift" "yes")
3906    (set_attr "dot" "yes")
3907    (set_attr "length" "4,8")])
3909 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3910   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3911         (compare:CC
3912           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3913                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3914                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3915                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3916           (const_int 0)))
3917    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3918         (and:GPR (match_dup 4)
3919                  (match_dup 3)))]
3920   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3921    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3923   if (which_alternative == 0)
3924     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3925   else
3926     return "#";
3928   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3929   [(set (match_dup 0)
3930         (and:GPR (match_dup 4)
3931                  (match_dup 3)))
3932    (set (match_dup 5)
3933         (compare:CC (match_dup 0)
3934                     (const_int 0)))]
3935   ""
3936   [(set_attr "type" "shift")
3937    (set_attr "maybe_var_shift" "yes")
3938    (set_attr "dot" "yes")
3939    (set_attr "length" "4,8")])
3941 ; Special case for less-than-0.  We can do it with just one machine
3942 ; instruction, but the generic optimizers do not realise it is cheap.
3943 (define_insn "*lt0_<mode>di"
3944   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3945         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3946                 (const_int 0)))]
3947   "TARGET_POWERPC64"
3948   "srdi %0,%1,63"
3949   [(set_attr "type" "shift")])
3951 (define_insn "*lt0_<mode>si"
3952   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3953         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3954                 (const_int 0)))]
3955   ""
3956   "rlwinm %0,%1,1,31,31"
3957   [(set_attr "type" "shift")])
3961 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3962 ; both are an AND so are the same precedence).
3963 (define_insn "*rotl<mode>3_insert"
3964   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3965         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3966                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3967                             (match_operand:SI 2 "const_int_operand" "n")])
3968                           (match_operand:GPR 3 "const_int_operand" "n"))
3969                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3970                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3971   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3972    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3974   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3976   [(set_attr "type" "insert")])
3977 ; FIXME: this needs an attr "size", so that the scheduler can see the
3978 ; difference between rlwimi and rldimi.  We also might want dot forms,
3979 ; but not for rlwimi on POWER4 and similar processors.
3981 (define_insn "*rotl<mode>3_insert_2"
3982   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3983         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3984                           (match_operand:GPR 6 "const_int_operand" "n"))
3985                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3986                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3987                             (match_operand:SI 2 "const_int_operand" "n")])
3988                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3989   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3990    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3992   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3994   [(set_attr "type" "insert")])
3996 ; There are also some forms without one of the ANDs.
3997 (define_insn "*rotl<mode>3_insert_3"
3998   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3999         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4000                           (match_operand:GPR 4 "const_int_operand" "n"))
4001                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4002                              (match_operand:SI 2 "const_int_operand" "n"))))]
4003   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4005   if (<MODE>mode == SImode)
4006     return "rlwimi %0,%1,%h2,0,31-%h2";
4007   else
4008     return "rldimi %0,%1,%H2,0";
4010   [(set_attr "type" "insert")])
4012 (define_insn "*rotl<mode>3_insert_4"
4013   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4014         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4015                           (match_operand:GPR 4 "const_int_operand" "n"))
4016                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4017                                (match_operand:SI 2 "const_int_operand" "n"))))]
4018   "<MODE>mode == SImode &&
4019    GET_MODE_PRECISION (<MODE>mode)
4020    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4022   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4023                          - INTVAL (operands[2]));
4024   if (<MODE>mode == SImode)
4025     return "rlwimi %0,%1,%h2,32-%h2,31";
4026   else
4027     return "rldimi %0,%1,%H2,64-%H2";
4029   [(set_attr "type" "insert")])
4031 (define_insn "*rotlsi3_insert_5"
4032   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4033         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4034                         (match_operand:SI 2 "const_int_operand" "n,n"))
4035                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4036                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
4037   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4038    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4039    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4040   "@
4041    rlwimi %0,%3,0,%4
4042    rlwimi %0,%1,0,%2"
4043   [(set_attr "type" "insert")])
4045 (define_insn "*rotldi3_insert_6"
4046   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4047         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4048                         (match_operand:DI 2 "const_int_operand" "n"))
4049                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4050                         (match_operand:DI 4 "const_int_operand" "n"))))]
4051   "exact_log2 (-UINTVAL (operands[2])) > 0
4052    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4054   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4055   return "rldimi %0,%3,0,%5";
4057   [(set_attr "type" "insert")
4058    (set_attr "size" "64")])
4060 (define_insn "*rotldi3_insert_7"
4061   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4062         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4063                         (match_operand:DI 4 "const_int_operand" "n"))
4064                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4065                         (match_operand:DI 2 "const_int_operand" "n"))))]
4066   "exact_log2 (-UINTVAL (operands[2])) > 0
4067    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4069   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4070   return "rldimi %0,%3,0,%5";
4072   [(set_attr "type" "insert")
4073    (set_attr "size" "64")])
4076 ; This handles the important case of multiple-precision shifts.  There is
4077 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4078 (define_split
4079   [(set (match_operand:GPR 0 "gpc_reg_operand")
4080         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4081                              (match_operand:SI 3 "const_int_operand"))
4082                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4083                                (match_operand:SI 4 "const_int_operand"))))]
4084   "can_create_pseudo_p ()
4085    && INTVAL (operands[3]) + INTVAL (operands[4])
4086       >= GET_MODE_PRECISION (<MODE>mode)"
4087   [(set (match_dup 5)
4088         (lshiftrt:GPR (match_dup 2)
4089                       (match_dup 4)))
4090    (set (match_dup 0)
4091         (ior:GPR (and:GPR (match_dup 5)
4092                           (match_dup 6))
4093                  (ashift:GPR (match_dup 1)
4094                              (match_dup 3))))]
4096   unsigned HOST_WIDE_INT mask = 1;
4097   mask = (mask << INTVAL (operands[3])) - 1;
4098   operands[5] = gen_reg_rtx (<MODE>mode);
4099   operands[6] = GEN_INT (mask);
4102 (define_split
4103   [(set (match_operand:GPR 0 "gpc_reg_operand")
4104         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4105                                (match_operand:SI 4 "const_int_operand"))
4106                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4107                              (match_operand:SI 3 "const_int_operand"))))]
4108   "can_create_pseudo_p ()
4109    && INTVAL (operands[3]) + INTVAL (operands[4])
4110       >= GET_MODE_PRECISION (<MODE>mode)"
4111   [(set (match_dup 5)
4112         (lshiftrt:GPR (match_dup 2)
4113                       (match_dup 4)))
4114    (set (match_dup 0)
4115         (ior:GPR (and:GPR (match_dup 5)
4116                           (match_dup 6))
4117                  (ashift:GPR (match_dup 1)
4118                              (match_dup 3))))]
4120   unsigned HOST_WIDE_INT mask = 1;
4121   mask = (mask << INTVAL (operands[3])) - 1;
4122   operands[5] = gen_reg_rtx (<MODE>mode);
4123   operands[6] = GEN_INT (mask);
4127 ; Another important case is setting some bits to 1; we can do that with
4128 ; an insert instruction, in many cases.
4129 (define_insn_and_split "*ior<mode>_mask"
4130   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4131         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4132                  (match_operand:GPR 2 "const_int_operand" "n")))
4133    (clobber (match_scratch:GPR 3 "=r"))]
4134   "!logical_const_operand (operands[2], <MODE>mode)
4135    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4136   "#"
4137   "&& 1"
4138   [(set (match_dup 3)
4139         (const_int -1))
4140    (set (match_dup 0)
4141         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4142                                       (match_dup 4))
4143                           (match_dup 2))
4144                  (and:GPR (match_dup 1)
4145                           (match_dup 5))))]
4147   int nb, ne;
4148   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4149   if (GET_CODE (operands[3]) == SCRATCH)
4150     operands[3] = gen_reg_rtx (<MODE>mode);
4151   operands[4] = GEN_INT (ne);
4152   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4154   [(set_attr "type" "two")
4155    (set_attr "length" "8")])
4158 ; Yet another case is an rldimi with the second value coming from memory.
4159 ; The zero_extend that should become part of the rldimi is merged into the
4160 ; load from memory instead.  Split things properly again.
4161 (define_split
4162   [(set (match_operand:DI 0 "gpc_reg_operand")
4163         (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4164                            (match_operand:SI 2 "const_int_operand"))
4165                 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4166   "INTVAL (operands[2]) == <bits>"
4167   [(set (match_dup 4)
4168         (zero_extend:DI (match_dup 3)))
4169    (set (match_dup 0)
4170         (ior:DI (and:DI (match_dup 4)
4171                         (match_dup 5))
4172                 (ashift:DI (match_dup 1)
4173                            (match_dup 2))))]
4175   operands[4] = gen_reg_rtx (DImode);
4176   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4179 ; rlwimi, too.
4180 (define_split
4181   [(set (match_operand:SI 0 "gpc_reg_operand")
4182         (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4183                            (match_operand:SI 2 "const_int_operand"))
4184                 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4185   "INTVAL (operands[2]) == <bits>"
4186   [(set (match_dup 4)
4187         (zero_extend:SI (match_dup 3)))
4188    (set (match_dup 0)
4189         (ior:SI (and:SI (match_dup 4)
4190                         (match_dup 5))
4191                 (ashift:SI (match_dup 1)
4192                            (match_dup 2))))]
4194   operands[4] = gen_reg_rtx (SImode);
4195   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4199 ;; Now the simple shifts.
4201 (define_insn "rotl<mode>3"
4202   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4203         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4204                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4205   ""
4206   "rotl<wd>%I2 %0,%1,%<hH>2"
4207   [(set_attr "type" "shift")
4208    (set_attr "maybe_var_shift" "yes")])
4210 (define_insn "*rotlsi3_64"
4211   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4212         (zero_extend:DI
4213             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4214                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4215   "TARGET_POWERPC64"
4216   "rotlw%I2 %0,%1,%h2"
4217   [(set_attr "type" "shift")
4218    (set_attr "maybe_var_shift" "yes")])
4220 (define_insn_and_split "*rotl<mode>3_dot"
4221   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4222         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4223                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4224                     (const_int 0)))
4225    (clobber (match_scratch:GPR 0 "=r,r"))]
4226   "<MODE>mode == Pmode"
4227   "@
4228    rotl<wd>%I2. %0,%1,%<hH>2
4229    #"
4230   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4231   [(set (match_dup 0)
4232         (rotate:GPR (match_dup 1)
4233                     (match_dup 2)))
4234    (set (match_dup 3)
4235         (compare:CC (match_dup 0)
4236                     (const_int 0)))]
4237   ""
4238   [(set_attr "type" "shift")
4239    (set_attr "maybe_var_shift" "yes")
4240    (set_attr "dot" "yes")
4241    (set_attr "length" "4,8")])
4243 (define_insn_and_split "*rotl<mode>3_dot2"
4244   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4245         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4246                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4247                     (const_int 0)))
4248    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4249         (rotate:GPR (match_dup 1)
4250                     (match_dup 2)))]
4251   "<MODE>mode == Pmode"
4252   "@
4253    rotl<wd>%I2. %0,%1,%<hH>2
4254    #"
4255   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4256   [(set (match_dup 0)
4257         (rotate:GPR (match_dup 1)
4258                     (match_dup 2)))
4259    (set (match_dup 3)
4260         (compare:CC (match_dup 0)
4261                     (const_int 0)))]
4262   ""
4263   [(set_attr "type" "shift")
4264    (set_attr "maybe_var_shift" "yes")
4265    (set_attr "dot" "yes")
4266    (set_attr "length" "4,8")])
4269 (define_insn "ashl<mode>3"
4270   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4271         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4272                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4273   ""
4274   "sl<wd>%I2 %0,%1,%<hH>2"
4275   [(set_attr "type" "shift")
4276    (set_attr "maybe_var_shift" "yes")])
4278 (define_insn "*ashlsi3_64"
4279   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4280         (zero_extend:DI
4281             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4282                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4283   "TARGET_POWERPC64"
4284   "slw%I2 %0,%1,%h2"
4285   [(set_attr "type" "shift")
4286    (set_attr "maybe_var_shift" "yes")])
4288 (define_insn_and_split "*ashl<mode>3_dot"
4289   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4290         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4291                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4292                     (const_int 0)))
4293    (clobber (match_scratch:GPR 0 "=r,r"))]
4294   "<MODE>mode == Pmode"
4295   "@
4296    sl<wd>%I2. %0,%1,%<hH>2
4297    #"
4298   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4299   [(set (match_dup 0)
4300         (ashift:GPR (match_dup 1)
4301                     (match_dup 2)))
4302    (set (match_dup 3)
4303         (compare:CC (match_dup 0)
4304                     (const_int 0)))]
4305   ""
4306   [(set_attr "type" "shift")
4307    (set_attr "maybe_var_shift" "yes")
4308    (set_attr "dot" "yes")
4309    (set_attr "length" "4,8")])
4311 (define_insn_and_split "*ashl<mode>3_dot2"
4312   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4313         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4314                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4315                     (const_int 0)))
4316    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4317         (ashift:GPR (match_dup 1)
4318                     (match_dup 2)))]
4319   "<MODE>mode == Pmode"
4320   "@
4321    sl<wd>%I2. %0,%1,%<hH>2
4322    #"
4323   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4324   [(set (match_dup 0)
4325         (ashift:GPR (match_dup 1)
4326                     (match_dup 2)))
4327    (set (match_dup 3)
4328         (compare:CC (match_dup 0)
4329                     (const_int 0)))]
4330   ""
4331   [(set_attr "type" "shift")
4332    (set_attr "maybe_var_shift" "yes")
4333    (set_attr "dot" "yes")
4334    (set_attr "length" "4,8")])
4336 ;; Pretend we have a memory form of extswsli until register allocation is done
4337 ;; so that we use LWZ to load the value from memory, instead of LWA.
4338 (define_insn_and_split "ashdi3_extswsli"
4339   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4340         (ashift:DI
4341          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4342          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4343   "TARGET_EXTSWSLI"
4344   "@
4345    extswsli %0,%1,%2
4346    #"
4347   "&& reload_completed && MEM_P (operands[1])"
4348   [(set (match_dup 3)
4349         (match_dup 1))
4350    (set (match_dup 0)
4351         (ashift:DI (sign_extend:DI (match_dup 3))
4352                    (match_dup 2)))]
4354   operands[3] = gen_lowpart (SImode, operands[0]);
4356   [(set_attr "type" "shift")
4357    (set_attr "maybe_var_shift" "no")])
4360 (define_insn_and_split "ashdi3_extswsli_dot"
4361   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4362         (compare:CC
4363          (ashift:DI
4364           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4365           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4366          (const_int 0)))
4367    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4368   "TARGET_EXTSWSLI"
4369   "@
4370    extswsli. %0,%1,%2
4371    #
4372    #
4373    #"
4374   "&& reload_completed
4375    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4376        || memory_operand (operands[1], SImode))"
4377   [(pc)]
4379   rtx dest = operands[0];
4380   rtx src = operands[1];
4381   rtx shift = operands[2];
4382   rtx cr = operands[3];
4383   rtx src2;
4385   if (!MEM_P (src))
4386     src2 = src;
4387   else
4388     {
4389       src2 = gen_lowpart (SImode, dest);
4390       emit_move_insn (src2, src);
4391     }
4393   if (REGNO (cr) == CR0_REGNO)
4394     {
4395       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4396       DONE;
4397     }
4399   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4400   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4401   DONE;
4403   [(set_attr "type" "shift")
4404    (set_attr "maybe_var_shift" "no")
4405    (set_attr "dot" "yes")
4406    (set_attr "length" "4,8,8,12")])
4408 (define_insn_and_split "ashdi3_extswsli_dot2"
4409   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4410         (compare:CC
4411          (ashift:DI
4412           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4413           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4414          (const_int 0)))
4415    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4416         (ashift:DI (sign_extend:DI (match_dup 1))
4417                    (match_dup 2)))]
4418   "TARGET_EXTSWSLI"
4419   "@
4420    extswsli. %0,%1,%2
4421    #
4422    #
4423    #"
4424   "&& reload_completed
4425    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4426        || memory_operand (operands[1], SImode))"
4427   [(pc)]
4429   rtx dest = operands[0];
4430   rtx src = operands[1];
4431   rtx shift = operands[2];
4432   rtx cr = operands[3];
4433   rtx src2;
4435   if (!MEM_P (src))
4436     src2 = src;
4437   else
4438     {
4439       src2 = gen_lowpart (SImode, dest);
4440       emit_move_insn (src2, src);
4441     }
4443   if (REGNO (cr) == CR0_REGNO)
4444     {
4445       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4446       DONE;
4447     }
4449   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4450   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4451   DONE;
4453   [(set_attr "type" "shift")
4454    (set_attr "maybe_var_shift" "no")
4455    (set_attr "dot" "yes")
4456    (set_attr "length" "4,8,8,12")])
4458 (define_insn "lshr<mode>3"
4459   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4460         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4461                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4462   ""
4463   "sr<wd>%I2 %0,%1,%<hH>2"
4464   [(set_attr "type" "shift")
4465    (set_attr "maybe_var_shift" "yes")])
4467 (define_insn "*lshrsi3_64"
4468   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4469         (zero_extend:DI
4470             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4471                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4472   "TARGET_POWERPC64"
4473   "srw%I2 %0,%1,%h2"
4474   [(set_attr "type" "shift")
4475    (set_attr "maybe_var_shift" "yes")])
4477 (define_insn_and_split "*lshr<mode>3_dot"
4478   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4479         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4480                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4481                     (const_int 0)))
4482    (clobber (match_scratch:GPR 0 "=r,r"))]
4483   "<MODE>mode == Pmode"
4484   "@
4485    sr<wd>%I2. %0,%1,%<hH>2
4486    #"
4487   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4488   [(set (match_dup 0)
4489         (lshiftrt:GPR (match_dup 1)
4490                       (match_dup 2)))
4491    (set (match_dup 3)
4492         (compare:CC (match_dup 0)
4493                     (const_int 0)))]
4494   ""
4495   [(set_attr "type" "shift")
4496    (set_attr "maybe_var_shift" "yes")
4497    (set_attr "dot" "yes")
4498    (set_attr "length" "4,8")])
4500 (define_insn_and_split "*lshr<mode>3_dot2"
4501   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4502         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4503                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4504                     (const_int 0)))
4505    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4506         (lshiftrt:GPR (match_dup 1)
4507                       (match_dup 2)))]
4508   "<MODE>mode == Pmode"
4509   "@
4510    sr<wd>%I2. %0,%1,%<hH>2
4511    #"
4512   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4513   [(set (match_dup 0)
4514         (lshiftrt:GPR (match_dup 1)
4515                       (match_dup 2)))
4516    (set (match_dup 3)
4517         (compare:CC (match_dup 0)
4518                     (const_int 0)))]
4519   ""
4520   [(set_attr "type" "shift")
4521    (set_attr "maybe_var_shift" "yes")
4522    (set_attr "dot" "yes")
4523    (set_attr "length" "4,8")])
4526 (define_insn "ashr<mode>3"
4527   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4528         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4529                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4530    (clobber (reg:GPR CA_REGNO))]
4531   ""
4532   "sra<wd>%I2 %0,%1,%<hH>2"
4533   [(set_attr "type" "shift")
4534    (set_attr "maybe_var_shift" "yes")])
4536 (define_insn "*ashrsi3_64"
4537   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4538         (sign_extend:DI
4539             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4540                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4541    (clobber (reg:SI CA_REGNO))]
4542   "TARGET_POWERPC64"
4543   "sraw%I2 %0,%1,%h2"
4544   [(set_attr "type" "shift")
4545    (set_attr "maybe_var_shift" "yes")])
4547 (define_insn_and_split "*ashr<mode>3_dot"
4548   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4549         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4550                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4551                     (const_int 0)))
4552    (clobber (match_scratch:GPR 0 "=r,r"))
4553    (clobber (reg:GPR CA_REGNO))]
4554   "<MODE>mode == Pmode"
4555   "@
4556    sra<wd>%I2. %0,%1,%<hH>2
4557    #"
4558   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4559   [(parallel [(set (match_dup 0)
4560                    (ashiftrt:GPR (match_dup 1)
4561                                  (match_dup 2)))
4562               (clobber (reg:GPR CA_REGNO))])
4563    (set (match_dup 3)
4564         (compare:CC (match_dup 0)
4565                     (const_int 0)))]
4566   ""
4567   [(set_attr "type" "shift")
4568    (set_attr "maybe_var_shift" "yes")
4569    (set_attr "dot" "yes")
4570    (set_attr "length" "4,8")])
4572 (define_insn_and_split "*ashr<mode>3_dot2"
4573   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4574         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4575                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4576                     (const_int 0)))
4577    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4578         (ashiftrt:GPR (match_dup 1)
4579                       (match_dup 2)))
4580    (clobber (reg:GPR CA_REGNO))]
4581   "<MODE>mode == Pmode"
4582   "@
4583    sra<wd>%I2. %0,%1,%<hH>2
4584    #"
4585   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4586   [(parallel [(set (match_dup 0)
4587                    (ashiftrt:GPR (match_dup 1)
4588                                  (match_dup 2)))
4589               (clobber (reg:GPR CA_REGNO))])
4590    (set (match_dup 3)
4591         (compare:CC (match_dup 0)
4592                     (const_int 0)))]
4593   ""
4594   [(set_attr "type" "shift")
4595    (set_attr "maybe_var_shift" "yes")
4596    (set_attr "dot" "yes")
4597    (set_attr "length" "4,8")])
4599 ;; Builtins to replace a division to generate FRE reciprocal estimate
4600 ;; instructions and the necessary fixup instructions
4601 (define_expand "recip<mode>3"
4602   [(match_operand:RECIPF 0 "gpc_reg_operand")
4603    (match_operand:RECIPF 1 "gpc_reg_operand")
4604    (match_operand:RECIPF 2 "gpc_reg_operand")]
4605   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4607    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4608    DONE;
4611 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4612 ;; hardware division.  This is only done before register allocation and with
4613 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4614 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4615 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4616 (define_split
4617   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4618         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4619                     (match_operand 2 "gpc_reg_operand")))]
4620   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4621    && can_create_pseudo_p () && flag_finite_math_only
4622    && !flag_trapping_math && flag_reciprocal_math"
4623   [(const_int 0)]
4625   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4626   DONE;
4629 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4630 ;; appropriate fixup.
4631 (define_expand "rsqrt<mode>2"
4632   [(match_operand:RECIPF 0 "gpc_reg_operand")
4633    (match_operand:RECIPF 1 "gpc_reg_operand")]
4634   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4636   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4637   DONE;
4640 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4641 ;; modes here, and also add in conditional vsx/power8-vector support to access
4642 ;; values in the traditional Altivec registers if the appropriate
4643 ;; -mupper-regs-{df,sf} option is enabled.
4645 (define_expand "abs<mode>2"
4646   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4647         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4648   "TARGET_HARD_FLOAT"
4649   "")
4651 (define_insn "*abs<mode>2_fpr"
4652   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4653         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4654   "TARGET_HARD_FLOAT"
4655   "@
4656    fabs %0,%1
4657    xsabsdp %x0,%x1"
4658   [(set_attr "type" "fpsimple")])
4660 (define_insn "*nabs<mode>2_fpr"
4661   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4662         (neg:SFDF
4663          (abs:SFDF
4664           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4665   "TARGET_HARD_FLOAT"
4666   "@
4667    fnabs %0,%1
4668    xsnabsdp %x0,%x1"
4669   [(set_attr "type" "fpsimple")])
4671 (define_expand "neg<mode>2"
4672   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4673         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4674   "TARGET_HARD_FLOAT"
4675   "")
4677 (define_insn "*neg<mode>2_fpr"
4678   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4679         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4680   "TARGET_HARD_FLOAT"
4681   "@
4682    fneg %0,%1
4683    xsnegdp %x0,%x1"
4684   [(set_attr "type" "fpsimple")])
4686 (define_expand "add<mode>3"
4687   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4688         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4689                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4690   "TARGET_HARD_FLOAT"
4691   "")
4693 (define_insn "*add<mode>3_fpr"
4694   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4695         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4696                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4697   "TARGET_HARD_FLOAT"
4698   "@
4699    fadd<s> %0,%1,%2
4700    xsadd<sd>p %x0,%x1,%x2"
4701   [(set_attr "type" "fp")
4702    (set_attr "isa" "*,<Fisa>")])
4704 (define_expand "sub<mode>3"
4705   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4706         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4707                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4708   "TARGET_HARD_FLOAT"
4709   "")
4711 (define_insn "*sub<mode>3_fpr"
4712   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4713         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4714                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4715   "TARGET_HARD_FLOAT"
4716   "@
4717    fsub<s> %0,%1,%2
4718    xssub<sd>p %x0,%x1,%x2"
4719   [(set_attr "type" "fp")
4720    (set_attr "isa" "*,<Fisa>")])
4722 (define_expand "mul<mode>3"
4723   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4724         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4725                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4726   "TARGET_HARD_FLOAT"
4727   "")
4729 (define_insn "*mul<mode>3_fpr"
4730   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4731         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4732                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4733   "TARGET_HARD_FLOAT"
4734   "@
4735    fmul<s> %0,%1,%2
4736    xsmul<sd>p %x0,%x1,%x2"
4737   [(set_attr "type" "dmul")
4738    (set_attr "isa" "*,<Fisa>")])
4740 (define_expand "div<mode>3"
4741   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4742         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4743                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4744   "TARGET_HARD_FLOAT"
4746   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4747       && can_create_pseudo_p () && flag_finite_math_only
4748       && !flag_trapping_math && flag_reciprocal_math)
4749     {
4750       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4751       DONE;
4752     }
4755 (define_insn "*div<mode>3_fpr"
4756   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4757         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4758                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4759   "TARGET_HARD_FLOAT"
4760   "@
4761    fdiv<s> %0,%1,%2
4762    xsdiv<sd>p %x0,%x1,%x2"
4763   [(set_attr "type" "<sd>div")
4764    (set_attr "isa" "*,<Fisa>")])
4766 (define_insn "*sqrt<mode>2_internal"
4767   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4768         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4769   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4770   "@
4771    fsqrt<s> %0,%1
4772    xssqrt<sd>p %x0,%x1"
4773   [(set_attr "type" "<sd>sqrt")
4774    (set_attr "isa" "*,<Fisa>")])
4776 (define_expand "sqrt<mode>2"
4777   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4778         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4779   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4781   if (<MODE>mode == SFmode
4782       && TARGET_RECIP_PRECISION
4783       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4784       && !optimize_function_for_size_p (cfun)
4785       && flag_finite_math_only && !flag_trapping_math
4786       && flag_unsafe_math_optimizations)
4787     {
4788       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4789       DONE;
4790     }
4793 ;; Floating point reciprocal approximation
4794 (define_insn "fre<sd>"
4795   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4796         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4797                      UNSPEC_FRES))]
4798   "TARGET_<FFRE>"
4799   "@
4800    fre<s> %0,%1
4801    xsre<sd>p %x0,%x1"
4802   [(set_attr "type" "fp")
4803    (set_attr "isa" "*,<Fisa>")])
4805 (define_insn "*rsqrt<mode>2"
4806   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4807         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4808                      UNSPEC_RSQRT))]
4809   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4810   "@
4811    frsqrte<s> %0,%1
4812    xsrsqrte<sd>p %x0,%x1"
4813   [(set_attr "type" "fp")
4814    (set_attr "isa" "*,<Fisa>")])
4816 ;; Floating point comparisons
4817 (define_insn "*cmp<mode>_fpr"
4818   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4819         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4820                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4821   "TARGET_HARD_FLOAT"
4822   "@
4823    fcmpu %0,%1,%2
4824    xscmpudp %0,%x1,%x2"
4825   [(set_attr "type" "fpcompare")
4826    (set_attr "isa" "*,<Fisa>")])
4828 ;; Floating point conversions
4829 (define_expand "extendsfdf2"
4830   [(set (match_operand:DF 0 "gpc_reg_operand")
4831         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4832   "TARGET_HARD_FLOAT"
4834   if (HONOR_SNANS (SFmode))
4835     operands[1] = force_reg (SFmode, operands[1]);
4838 (define_insn_and_split "*extendsfdf2_fpr"
4839   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4840         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4841   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4842   "@
4843    #
4844    fmr %0,%1
4845    lfs%U1%X1 %0,%1
4846    #
4847    xscpsgndp %x0,%x1,%x1
4848    lxsspx %x0,%y1
4849    lxssp %0,%1"
4850   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4851   [(const_int 0)]
4853   emit_note (NOTE_INSN_DELETED);
4854   DONE;
4856   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4857    (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4859 (define_insn "*extendsfdf2_snan"
4860   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4861         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4862   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4863   "@
4864    frsp %0,%1
4865    xsrsp %x0,%x1"
4866   [(set_attr "type" "fp")
4867    (set_attr "isa" "*,p8v")])
4869 (define_expand "truncdfsf2"
4870   [(set (match_operand:SF 0 "gpc_reg_operand")
4871         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4872   "TARGET_HARD_FLOAT"
4873   "")
4875 (define_insn "*truncdfsf2_fpr"
4876   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4877         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4878   "TARGET_HARD_FLOAT"
4879   "@
4880    frsp %0,%1
4881    xsrsp %x0,%x1"
4882   [(set_attr "type" "fp")
4883    (set_attr "isa" "*,p8v")])
4885 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4886 ;; builtins.c and optabs.c that are not correct for IBM long double
4887 ;; when little-endian.
4888 (define_expand "signbit<mode>2"
4889   [(set (match_dup 2)
4890         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4891    (set (match_dup 3)
4892         (subreg:DI (match_dup 2) 0))
4893    (set (match_dup 4)
4894         (match_dup 5))
4895    (set (match_operand:SI 0 "gpc_reg_operand")
4896         (match_dup 6))]
4897   "TARGET_HARD_FLOAT
4898    && (!FLOAT128_IEEE_P (<MODE>mode)
4899        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4901   if (FLOAT128_IEEE_P (<MODE>mode))
4902     {
4903       rtx dest = operands[0];
4904       rtx src = operands[1];
4905       rtx tmp = gen_reg_rtx (DImode);
4906       rtx dest_di = gen_lowpart (DImode, dest);
4908       emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4909       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4910       DONE;
4911     }
4912   operands[2] = gen_reg_rtx (DFmode);
4913   operands[3] = gen_reg_rtx (DImode);
4914   if (TARGET_POWERPC64)
4915     {
4916       operands[4] = gen_reg_rtx (DImode);
4917       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4918       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4919                                     WORDS_BIG_ENDIAN ? 4 : 0);
4920     }
4921   else
4922     {
4923       operands[4] = gen_reg_rtx (SImode);
4924       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4925                                     WORDS_BIG_ENDIAN ? 0 : 4);
4926       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4927     }
4930 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4931 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4932 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4933 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4935 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4936 ;; split allows the post reload phases to eliminate the move, and do the shift
4937 ;; directly with the register that contains the signbit.
4938 (define_insn_and_split "@signbit<mode>2_dm"
4939   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4940         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4941                    UNSPEC_SIGNBIT))]
4942   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4943   "@
4944    mfvsrd %0,%x1
4945    #"
4946   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4947   [(set (match_dup 0)
4948         (match_dup 2))]
4950   operands[2] = gen_highpart (DImode, operands[1]);
4952  [(set_attr "type" "mftgpr,*")])
4954 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4955 ;; register and then doing a direct move if the value comes from memory.  On
4956 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4957 (define_insn_and_split "*signbit<mode>2_dm_mem"
4958   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4959         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4960                    UNSPEC_SIGNBIT))]
4961   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4962   "#"
4963   "&& 1"
4964   [(set (match_dup 0)
4965         (match_dup 2))]
4967   rtx dest = operands[0];
4968   rtx src = operands[1];
4969   rtx addr = XEXP (src, 0);
4971   if (WORDS_BIG_ENDIAN)
4972     operands[2] = adjust_address (src, DImode, 0);
4974   else if (REG_P (addr) || SUBREG_P (addr))
4975     operands[2] = adjust_address (src, DImode, 8);
4977   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4978            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4979     operands[2] = adjust_address (src, DImode, 8);
4981   else
4982     {
4983       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4984       emit_insn (gen_rtx_SET (tmp, addr));
4985       operands[2] = change_address (src, DImode,
4986                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4987     }
4990 (define_expand "copysign<mode>3"
4991   [(set (match_dup 3)
4992         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4993    (set (match_dup 4)
4994         (neg:SFDF (abs:SFDF (match_dup 1))))
4995    (set (match_operand:SFDF 0 "gpc_reg_operand")
4996         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4997                                (match_dup 5))
4998                          (match_dup 3)
4999                          (match_dup 4)))]
5000   "TARGET_HARD_FLOAT
5001    && ((TARGET_PPC_GFXOPT
5002         && !HONOR_NANS (<MODE>mode)
5003         && !HONOR_SIGNED_ZEROS (<MODE>mode))
5004        || TARGET_CMPB
5005        || VECTOR_UNIT_VSX_P (<MODE>mode))"
5007   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5008     {
5009       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5010                                              operands[2]));
5011       DONE;
5012     }
5014    operands[3] = gen_reg_rtx (<MODE>mode);
5015    operands[4] = gen_reg_rtx (<MODE>mode);
5016    operands[5] = CONST0_RTX (<MODE>mode);
5017   })
5019 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5020 ;; compiler from optimizing -0.0
5021 (define_insn "copysign<mode>3_fcpsgn"
5022   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5023         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5024                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5025                      UNSPEC_COPYSIGN))]
5026   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5027   "@
5028    fcpsgn %0,%2,%1
5029    xscpsgndp %x0,%x2,%x1"
5030   [(set_attr "type" "fpsimple")])
5032 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5033 ;; fsel instruction and some auxiliary computations.  Then we just have a
5034 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5035 ;; combine.
5036 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5037 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5038 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
5039 ;; define_splits to make them if made by combine.  On VSX machines we have the
5040 ;; min/max instructions.
5042 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5043 ;; to allow either DF/SF to use only traditional registers.
5045 (define_expand "s<minmax><mode>3"
5046   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5047         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5048                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5049   "TARGET_MINMAX"
5051   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5052   DONE;
5055 (define_insn "*s<minmax><mode>3_vsx"
5056   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5057         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5058                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5059   "TARGET_VSX && TARGET_HARD_FLOAT"
5061   return (TARGET_P9_MINMAX
5062           ? "xs<minmax>cdp %x0,%x1,%x2"
5063           : "xs<minmax>dp %x0,%x1,%x2");
5065   [(set_attr "type" "fp")])
5067 ;; The conditional move instructions allow us to perform max and min operations
5068 ;; even when we don't have the appropriate max/min instruction using the FSEL
5069 ;; instruction.
5071 (define_insn_and_split "*s<minmax><mode>3_fpr"
5072   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5073         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5074                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5075   "!TARGET_VSX && TARGET_MINMAX"
5076   "#"
5077   "&& 1"
5078   [(const_int 0)]
5080   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5081   DONE;
5084 (define_expand "mov<mode>cc"
5085    [(set (match_operand:GPR 0 "gpc_reg_operand")
5086          (if_then_else:GPR (match_operand 1 "comparison_operator")
5087                            (match_operand:GPR 2 "gpc_reg_operand")
5088                            (match_operand:GPR 3 "gpc_reg_operand")))]
5089   "TARGET_ISEL"
5091   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5092     DONE;
5093   else
5094     FAIL;
5097 ;; We use the BASE_REGS for the isel input operands because, if rA is
5098 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5099 ;; because we may switch the operands and rB may end up being rA.
5101 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
5102 ;; leave out the mode in operand 4 and use one pattern, but reload can
5103 ;; change the mode underneath our feet and then gets confused trying
5104 ;; to reload the value.
5105 (define_mode_iterator CCEITHER [CC CCUNS])
5106 (define_mode_attr un [(CC "") (CCUNS "un")])
5107 (define_insn "isel_<un>signed_<GPR:mode>"
5108   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5109         (if_then_else:GPR
5110          (match_operator 1 "scc_comparison_operator"
5111                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5112                           (const_int 0)])
5113          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5114          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5115   "TARGET_ISEL"
5116   "isel %0,%2,%3,%j1"
5117   [(set_attr "type" "isel")])
5119 ;; These patterns can be useful for combine; they let combine know that
5120 ;; isel can handle reversed comparisons so long as the operands are
5121 ;; registers.
5123 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5124   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5125         (if_then_else:GPR
5126          (match_operator 1 "scc_rev_comparison_operator"
5127                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5128                           (const_int 0)])
5129          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5130          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5131   "TARGET_ISEL"
5133   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5134   return "isel %0,%3,%2,%j1";
5136   [(set_attr "type" "isel")])
5138 ;; Floating point conditional move
5139 (define_expand "mov<mode>cc"
5140    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5141          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5142                             (match_operand:SFDF 2 "gpc_reg_operand")
5143                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5144   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5146   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5147     DONE;
5148   else
5149     FAIL;
5152 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5153   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5154         (if_then_else:SFDF
5155          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5156              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5157          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5158          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5159   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5160   "fsel %0,%1,%2,%3"
5161   [(set_attr "type" "fp")])
5163 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5164   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5165         (if_then_else:SFDF
5166          (match_operator:CCFP 1 "fpmask_comparison_operator"
5167                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5168                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5169          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5170          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5171    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5172   "TARGET_P9_MINMAX"
5173   "#"
5174   ""
5175   [(set (match_dup 6)
5176         (if_then_else:V2DI (match_dup 1)
5177                            (match_dup 7)
5178                            (match_dup 8)))
5179    (set (match_dup 0)
5180         (if_then_else:SFDF (ne (match_dup 6)
5181                                (match_dup 8))
5182                            (match_dup 4)
5183                            (match_dup 5)))]
5185   if (GET_CODE (operands[6]) == SCRATCH)
5186     operands[6] = gen_reg_rtx (V2DImode);
5188   operands[7] = CONSTM1_RTX (V2DImode);
5189   operands[8] = CONST0_RTX (V2DImode);
5191  [(set_attr "length" "8")
5192   (set_attr "type" "vecperm")])
5194 ;; Handle inverting the fpmask comparisons.
5195 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5196   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5197         (if_then_else:SFDF
5198          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5199                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5200                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5201          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5202          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5203    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5204   "TARGET_P9_MINMAX"
5205   "#"
5206   "&& 1"
5207   [(set (match_dup 6)
5208         (if_then_else:V2DI (match_dup 9)
5209                            (match_dup 7)
5210                            (match_dup 8)))
5211    (set (match_dup 0)
5212         (if_then_else:SFDF (ne (match_dup 6)
5213                                (match_dup 8))
5214                            (match_dup 5)
5215                            (match_dup 4)))]
5217   rtx op1 = operands[1];
5218   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5220   if (GET_CODE (operands[6]) == SCRATCH)
5221     operands[6] = gen_reg_rtx (V2DImode);
5223   operands[7] = CONSTM1_RTX (V2DImode);
5224   operands[8] = CONST0_RTX (V2DImode);
5226   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5228  [(set_attr "length" "8")
5229   (set_attr "type" "vecperm")])
5231 (define_insn "*fpmask<mode>"
5232   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5233         (if_then_else:V2DI
5234          (match_operator:CCFP 1 "fpmask_comparison_operator"
5235                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5236                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5237          (match_operand:V2DI 4 "all_ones_constant" "")
5238          (match_operand:V2DI 5 "zero_constant" "")))]
5239   "TARGET_P9_MINMAX"
5240   "xscmp%V1dp %x0,%x2,%x3"
5241   [(set_attr "type" "fpcompare")])
5243 (define_insn "*xxsel<mode>"
5244   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5245         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5246                                (match_operand:V2DI 2 "zero_constant" ""))
5247                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5248                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5249   "TARGET_P9_MINMAX"
5250   "xxsel %x0,%x4,%x3,%x1"
5251   [(set_attr "type" "vecmove")])
5254 ;; Conversions to and from floating-point.
5256 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5257 ; don't want to support putting SImode in FPR registers.
5258 (define_insn "lfiwax"
5259   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5260         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5261                    UNSPEC_LFIWAX))]
5262   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5263   "@
5264    lfiwax %0,%y1
5265    lxsiwax %x0,%y1
5266    mtvsrwa %x0,%1
5267    vextsw2d %0,%1"
5268   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5269    (set_attr "isa" "*,p8v,p8v,p9v")])
5271 ; This split must be run before register allocation because it allocates the
5272 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5273 ; it earlier to allow for the combiner to merge insns together where it might
5274 ; not be needed and also in case the insns are deleted as dead code.
5276 (define_insn_and_split "floatsi<mode>2_lfiwax"
5277   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5278         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5279    (clobber (match_scratch:DI 2 "=d,wa"))]
5280   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5281    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5282   "#"
5283   ""
5284   [(pc)]
5286   rtx dest = operands[0];
5287   rtx src = operands[1];
5288   rtx tmp;
5290   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5291     tmp = convert_to_mode (DImode, src, false);
5292   else
5293     {
5294       tmp = operands[2];
5295       if (GET_CODE (tmp) == SCRATCH)
5296         tmp = gen_reg_rtx (DImode);
5297       if (MEM_P (src))
5298         {
5299           src = rs6000_force_indexed_or_indirect_mem (src);
5300           emit_insn (gen_lfiwax (tmp, src));
5301         }
5302       else
5303         {
5304           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5305           emit_move_insn (stack, src);
5306           emit_insn (gen_lfiwax (tmp, stack));
5307         }
5308     }
5309   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5310   DONE;
5312   [(set_attr "length" "12")
5313    (set_attr "type" "fpload")])
5315 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5316   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5317         (float:SFDF
5318          (sign_extend:DI
5319           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5320    (clobber (match_scratch:DI 2 "=d,wa"))]
5321   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5322   "#"
5323   ""
5324   [(pc)]
5326   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5327   if (GET_CODE (operands[2]) == SCRATCH)
5328     operands[2] = gen_reg_rtx (DImode);
5329   if (TARGET_P8_VECTOR)
5330     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5331   else
5332     emit_insn (gen_lfiwax (operands[2], operands[1]));
5333   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5334   DONE;
5336   [(set_attr "length" "8")
5337    (set_attr "type" "fpload")])
5339 (define_insn "lfiwzx"
5340   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5341         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5342                    UNSPEC_LFIWZX))]
5343   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5344   "@
5345    lfiwzx %0,%y1
5346    lxsiwzx %x0,%y1
5347    mtvsrwz %x0,%1
5348    xxextractuw %x0,%x1,4"
5349   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5350    (set_attr "isa" "*,p8v,p8v,p9v")])
5352 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5353   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5354         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5355    (clobber (match_scratch:DI 2 "=d,wa"))]
5356   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5357   "#"
5358   ""
5359   [(pc)]
5361   rtx dest = operands[0];
5362   rtx src = operands[1];
5363   rtx tmp;
5365   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5366     tmp = convert_to_mode (DImode, src, true);
5367   else
5368     {
5369       tmp = operands[2];
5370       if (GET_CODE (tmp) == SCRATCH)
5371         tmp = gen_reg_rtx (DImode);
5372       if (MEM_P (src))
5373         {
5374           src = rs6000_force_indexed_or_indirect_mem (src);
5375           emit_insn (gen_lfiwzx (tmp, src));
5376         }
5377       else
5378         {
5379           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5380           emit_move_insn (stack, src);
5381           emit_insn (gen_lfiwzx (tmp, stack));
5382         }
5383     }
5384   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5385   DONE;
5387   [(set_attr "length" "12")
5388    (set_attr "type" "fpload")])
5390 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5391   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5392         (unsigned_float:SFDF
5393          (zero_extend:DI
5394           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5395    (clobber (match_scratch:DI 2 "=d,wa"))]
5396   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5397   "#"
5398   ""
5399   [(pc)]
5401   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5402   if (GET_CODE (operands[2]) == SCRATCH)
5403     operands[2] = gen_reg_rtx (DImode);
5404   if (TARGET_P8_VECTOR)
5405     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5406   else
5407     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5408   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5409   DONE;
5411   [(set_attr "length" "8")
5412    (set_attr "type" "fpload")])
5414 ; For each of these conversions, there is a define_expand, a define_insn
5415 ; with a '#' template, and a define_split (with C code).  The idea is
5416 ; to allow constant folding with the template of the define_insn,
5417 ; then to have the insns split later (between sched1 and final).
5419 (define_expand "floatsidf2"
5420   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5421                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5422               (use (match_dup 2))
5423               (use (match_dup 3))
5424               (clobber (match_dup 4))
5425               (clobber (match_dup 5))
5426               (clobber (match_dup 6))])]
5427   "TARGET_HARD_FLOAT"
5429   if (TARGET_LFIWAX && TARGET_FCFID)
5430     {
5431       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5432       DONE;
5433     }
5434   else if (TARGET_FCFID)
5435     {
5436       rtx dreg = operands[1];
5437       if (!REG_P (dreg))
5438         dreg = force_reg (SImode, dreg);
5439       dreg = convert_to_mode (DImode, dreg, false);
5440       emit_insn (gen_floatdidf2 (operands[0], dreg));
5441       DONE;
5442     }
5444   if (!REG_P (operands[1]))
5445     operands[1] = force_reg (SImode, operands[1]);
5446   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5447   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5448   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5449   operands[5] = gen_reg_rtx (DFmode);
5450   operands[6] = gen_reg_rtx (SImode);
5453 (define_insn_and_split "*floatsidf2_internal"
5454   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5455         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5456    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5457    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5458    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5459    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5460    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5461   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5462   "#"
5463   ""
5464   [(pc)]
5466   rtx lowword, highword;
5467   gcc_assert (MEM_P (operands[4]));
5468   highword = adjust_address (operands[4], SImode, 0);
5469   lowword = adjust_address (operands[4], SImode, 4);
5470   if (! WORDS_BIG_ENDIAN)
5471     std::swap (lowword, highword);
5473   emit_insn (gen_xorsi3 (operands[6], operands[1],
5474                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5475   emit_move_insn (lowword, operands[6]);
5476   emit_move_insn (highword, operands[2]);
5477   emit_move_insn (operands[5], operands[4]);
5478   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5479   DONE;
5481   [(set_attr "length" "24")
5482    (set_attr "type" "fp")])
5484 ;; If we don't have a direct conversion to single precision, don't enable this
5485 ;; conversion for 32-bit without fast math, because we don't have the insn to
5486 ;; generate the fixup swizzle to avoid double rounding problems.
5487 (define_expand "floatunssisf2"
5488   [(set (match_operand:SF 0 "gpc_reg_operand")
5489         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5490   "TARGET_HARD_FLOAT
5491    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5492        || (TARGET_FCFID
5493            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5495   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5496     {
5497       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5498       DONE;
5499     }
5500   else
5501     {
5502       rtx dreg = operands[1];
5503       if (!REG_P (dreg))
5504         dreg = force_reg (SImode, dreg);
5505       dreg = convert_to_mode (DImode, dreg, true);
5506       emit_insn (gen_floatdisf2 (operands[0], dreg));
5507       DONE;
5508     }
5511 (define_expand "floatunssidf2"
5512   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5513                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5514               (use (match_dup 2))
5515               (use (match_dup 3))
5516               (clobber (match_dup 4))
5517               (clobber (match_dup 5))])]
5518   "TARGET_HARD_FLOAT"
5520   if (TARGET_LFIWZX && TARGET_FCFID)
5521     {
5522       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5523       DONE;
5524     }
5525   else if (TARGET_FCFID)
5526     {
5527       rtx dreg = operands[1];
5528       if (!REG_P (dreg))
5529         dreg = force_reg (SImode, dreg);
5530       dreg = convert_to_mode (DImode, dreg, true);
5531       emit_insn (gen_floatdidf2 (operands[0], dreg));
5532       DONE;
5533     }
5535   if (!REG_P (operands[1]))
5536     operands[1] = force_reg (SImode, operands[1]);
5537   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5538   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5539   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5540   operands[5] = gen_reg_rtx (DFmode);
5543 (define_insn_and_split "*floatunssidf2_internal"
5544   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5545         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5546    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5547    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5548    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5549    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5550   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5551    && !(TARGET_FCFID && TARGET_POWERPC64)"
5552   "#"
5553   ""
5554   [(pc)]
5556   rtx lowword, highword;
5557   gcc_assert (MEM_P (operands[4]));
5558   highword = adjust_address (operands[4], SImode, 0);
5559   lowword = adjust_address (operands[4], SImode, 4);
5560   if (! WORDS_BIG_ENDIAN)
5561     std::swap (lowword, highword);
5563   emit_move_insn (lowword, operands[1]);
5564   emit_move_insn (highword, operands[2]);
5565   emit_move_insn (operands[5], operands[4]);
5566   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5567   DONE;
5569   [(set_attr "length" "20")
5570    (set_attr "type" "fp")])
5572 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5573 ;; vector registers.  These insns favor doing the sign/zero extension in
5574 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5575 ;; extension and then a direct move.
5577 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5578   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5579                    (float:FP_ISA3
5580                     (match_operand:QHI 1 "input_operand")))
5581               (clobber (match_scratch:DI 2))
5582               (clobber (match_scratch:DI 3))
5583               (clobber (match_scratch:<QHI:MODE> 4))])]
5584   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5586   if (MEM_P (operands[1]))
5587     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5590 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5591   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5592         (float:FP_ISA3
5593          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5594    (clobber (match_scratch:DI 2 "=v,wa,v"))
5595    (clobber (match_scratch:DI 3 "=X,r,X"))
5596    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5597   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5598   "#"
5599   "&& reload_completed"
5600   [(const_int 0)]
5602   rtx result = operands[0];
5603   rtx input = operands[1];
5604   rtx di = operands[2];
5606   if (!MEM_P (input))
5607     {
5608       rtx tmp = operands[3];
5609       if (altivec_register_operand (input, <QHI:MODE>mode))
5610         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5611       else if (GET_CODE (tmp) == SCRATCH)
5612         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5613       else
5614         {
5615           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5616           emit_move_insn (di, tmp);
5617         }
5618     }
5619   else
5620     {
5621       rtx tmp = operands[4];
5622       emit_move_insn (tmp, input);
5623       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5624     }
5626   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5627   DONE;
5629   [(set_attr "isa" "p9v,*,p9v")])
5631 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5632   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5633                    (unsigned_float:FP_ISA3
5634                     (match_operand:QHI 1 "input_operand")))
5635               (clobber (match_scratch:DI 2))
5636               (clobber (match_scratch:DI 3))])]
5637   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5639   if (MEM_P (operands[1]))
5640     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5643 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5644   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5645         (unsigned_float:FP_ISA3
5646          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5647    (clobber (match_scratch:DI 2 "=v,wa,wa"))
5648    (clobber (match_scratch:DI 3 "=X,r,X"))]
5649   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5650   "#"
5651   "&& reload_completed"
5652   [(const_int 0)]
5654   rtx result = operands[0];
5655   rtx input = operands[1];
5656   rtx di = operands[2];
5658   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5659     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5660   else
5661     {
5662       rtx tmp = operands[3];
5663       if (GET_CODE (tmp) == SCRATCH)
5664         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5665       else
5666         {
5667           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5668           emit_move_insn (di, tmp);
5669         }
5670     }
5672   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5673   DONE;
5675   [(set_attr "isa" "p9v,*,p9v")])
5677 (define_expand "fix_trunc<mode>si2"
5678   [(set (match_operand:SI 0 "gpc_reg_operand")
5679         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5680   "TARGET_HARD_FLOAT"
5682   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5683     {
5684       rtx src = force_reg (<MODE>mode, operands[1]);
5686       if (TARGET_STFIWX)
5687         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5688       else
5689         {
5690           rtx tmp = gen_reg_rtx (DImode);
5691           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5692           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5693                                                       tmp, stack));
5694         }
5695       DONE;
5696     }
5699 ; Like the convert to float patterns, this insn must be split before
5700 ; register allocation so that it can allocate the memory slot if it
5701 ; needed
5702 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5703   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5704         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5705    (clobber (match_scratch:DI 2 "=d"))]
5706   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5707    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5708   "#"
5709   ""
5710   [(pc)]
5712   rtx dest = operands[0];
5713   rtx src = operands[1];
5714   rtx tmp = operands[2];
5716   if (GET_CODE (tmp) == SCRATCH)
5717     tmp = gen_reg_rtx (DImode);
5719   emit_insn (gen_fctiwz_<mode> (tmp, src));
5720   if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5721     {
5722       dest = rs6000_force_indexed_or_indirect_mem (dest);
5723       emit_insn (gen_stfiwx (dest, tmp));
5724       DONE;
5725     }
5726   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5727     {
5728       dest = gen_lowpart (DImode, dest);
5729       emit_move_insn (dest, tmp);
5730       DONE;
5731     }
5732   else
5733     {
5734       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5735       emit_insn (gen_stfiwx (stack, tmp));
5736       emit_move_insn (dest, stack);
5737       DONE;
5738     }
5740   [(set_attr "length" "12")
5741    (set_attr "type" "fp")])
5743 (define_insn_and_split "fix_trunc<mode>si2_internal"
5744   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5745         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5746    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5747    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5748   "TARGET_HARD_FLOAT
5749    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5750   "#"
5751   ""
5752   [(pc)]
5754   rtx lowword;
5755   gcc_assert (MEM_P (operands[3]));
5756   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5758   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5759   emit_move_insn (operands[3], operands[2]);
5760   emit_move_insn (operands[0], lowword);
5761   DONE;
5763   [(set_attr "length" "16")
5764    (set_attr "type" "fp")])
5766 (define_expand "fix_trunc<mode>di2"
5767   [(set (match_operand:DI 0 "gpc_reg_operand")
5768         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5769   "TARGET_HARD_FLOAT && TARGET_FCFID"
5770   "")
5772 (define_insn "*fix_trunc<mode>di2_fctidz"
5773   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5774         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5775   "TARGET_HARD_FLOAT && TARGET_FCFID"
5776   "@
5777    fctidz %0,%1
5778    xscvdpsxds %x0,%x1"
5779   [(set_attr "type" "fp")])
5781 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5782 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5783 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5784 ;; values can go in VSX registers.  Keeping the direct move part through
5785 ;; register allocation prevents the register allocator from doing a direct move
5786 ;; of the SImode value to a GPR, and then a store/load.
5787 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5788   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5789         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5790    (clobber (match_scratch:SI 2 "=X,X,wa"))]
5791   "TARGET_DIRECT_MOVE"
5792   "@
5793    fctiw<u>z %0,%1
5794    xscvdp<su>xws %x0,%x1
5795    #"
5796   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5797   [(set (match_dup 2)
5798         (any_fix:SI (match_dup 1)))
5799    (set (match_dup 3)
5800         (match_dup 2))]
5802   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5804   [(set_attr "type" "fp")
5805    (set_attr "length" "4,4,8")
5806    (set_attr "isa" "p9v,p9v,*")])
5808 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5809   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5810         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5811   "TARGET_DIRECT_MOVE"
5812   "@
5813    fctiw<u>z %0,%1
5814    xscvdp<su>xws %x0,%x1"
5815   [(set_attr "type" "fp")])
5817 ;; Keep the convert and store together through register allocation to prevent
5818 ;; the register allocator from getting clever and doing a direct move to a GPR
5819 ;; and then store for reg+offset stores.
5820 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5821   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5822         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5823    (clobber (match_scratch:SI 2 "=wa"))]
5824     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5825   "#"
5826   "&& reload_completed"
5827   [(set (match_dup 2)
5828         (any_fix:SI (match_dup 1)))
5829    (set (match_dup 0)
5830         (match_dup 3))]
5832   operands[3] = (<QHSI:MODE>mode == SImode
5833                  ? operands[2]
5834                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5837 (define_expand "fixuns_trunc<mode>si2"
5838   [(set (match_operand:SI 0 "gpc_reg_operand")
5839         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5840   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5842   if (!TARGET_P8_VECTOR)
5843     {
5844       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5845       DONE;
5846     }
5849 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5850   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5851         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5852    (clobber (match_scratch:DI 2 "=d"))]
5853   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5854    && TARGET_STFIWX && can_create_pseudo_p ()
5855    && !TARGET_P8_VECTOR"
5856   "#"
5857   ""
5858   [(pc)]
5860   rtx dest = operands[0];
5861   rtx src = operands[1];
5862   rtx tmp = operands[2];
5864   if (GET_CODE (tmp) == SCRATCH)
5865     tmp = gen_reg_rtx (DImode);
5867   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5868   if (MEM_P (dest))
5869     {
5870       dest = rs6000_force_indexed_or_indirect_mem (dest);
5871       emit_insn (gen_stfiwx (dest, tmp));
5872       DONE;
5873     }
5874   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5875     {
5876       dest = gen_lowpart (DImode, dest);
5877       emit_move_insn (dest, tmp);
5878       DONE;
5879     }
5880   else
5881     {
5882       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5883       emit_insn (gen_stfiwx (stack, tmp));
5884       emit_move_insn (dest, stack);
5885       DONE;
5886     }
5888   [(set_attr "length" "12")
5889    (set_attr "type" "fp")])
5891 (define_insn "fixuns_trunc<mode>di2"
5892   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5893         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5894   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5895   "@
5896    fctiduz %0,%1
5897    xscvdpuxds %x0,%x1"
5898   [(set_attr "type" "fp")])
5900 (define_insn "rs6000_mtfsb0"
5901   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5902                     UNSPECV_MTFSB0)]
5903   "TARGET_HARD_FLOAT"
5904   "mtfsb0 %0"
5905   [(set_attr "type" "fp")])
5907 (define_insn "rs6000_mtfsb1"
5908   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5909                     UNSPECV_MTFSB1)]
5910   "TARGET_HARD_FLOAT"
5911   "mtfsb1 %0"
5912   [(set_attr "type" "fp")])
5914 (define_insn "rs6000_mffscrn"
5915   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5916         (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5917                             UNSPECV_MFFSCRN))]
5918    "TARGET_P9_MISC"
5919    "mffscrn %0,%1"
5920   [(set_attr "type" "fp")])
5922 (define_insn "rs6000_mffscdrn"
5923   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5924    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5925    (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5926   "TARGET_P9_MISC"
5927   "mffscdrn %0,%1"
5928   [(set_attr "type" "fp")])
5930 (define_expand "rs6000_set_fpscr_rn"
5931  [(match_operand:DI 0 "reg_or_cint_operand")]
5932   "TARGET_HARD_FLOAT"
5934   rtx tmp_df = gen_reg_rtx (DFmode);
5936   /* The floating point rounding control bits are FPSCR[62:63]. Put the
5937      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5938   if (TARGET_P9_MISC)
5939     {
5940       rtx src_df = force_reg (DImode, operands[0]);
5941       src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5942       emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5943       DONE;
5944     }
5946   if (CONST_INT_P (operands[0]))
5947     {
5948       if ((INTVAL (operands[0]) & 0x1) == 0x1)
5949         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5950       else
5951         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5953       if ((INTVAL (operands[0]) & 0x2) == 0x2)
5954         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5955       else
5956         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5957     }
5958   else
5959     {
5960       rtx tmp_rn = gen_reg_rtx (DImode);
5961       rtx tmp_di = gen_reg_rtx (DImode);
5963       /* Extract new RN mode from operand.  */
5964       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5966       /* Insert new RN mode into FSCPR.  */
5967       emit_insn (gen_rs6000_mffs (tmp_df));
5968       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5969       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5970       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5972       /* Need to write to field k=15.  The fields are [0:15].  Hence with
5973          L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5974          8-bit field[0:7]. Need to set the bit that corresponds to the
5975          value of i that you want [0:7].  */
5976       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5977       emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5978     }
5979   DONE;
5982 (define_expand "rs6000_set_fpscr_drn"
5983   [(match_operand:DI 0  "gpc_reg_operand")]
5984   "TARGET_HARD_FLOAT"
5986   rtx tmp_df = gen_reg_rtx (DFmode);
5988   /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5989      new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5990   if (TARGET_P9_MISC)
5991     {
5992       rtx src_df = gen_reg_rtx (DFmode);
5994       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5995       src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5996       emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5997     }
5998   else
5999     {
6000       rtx tmp_rn = gen_reg_rtx (DImode);
6001       rtx tmp_di = gen_reg_rtx (DImode);
6003       /* Extract new DRN mode from operand.  */
6004       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6005       emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6007       /* Insert new RN mode into FSCPR.  */
6008       emit_insn (gen_rs6000_mffs (tmp_df));
6009       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6010       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
6011       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6013       /* Need to write to field 7.  The fields are [0:15].  The equation to
6014          select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6015          i to 0x1 to get field 7 where i selects the field.  */
6016       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6017       emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6018     }
6019   DONE;
6022 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6023 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6024 ;; because the first makes it clear that operand 0 is not live
6025 ;; before the instruction.
6026 (define_insn "fctiwz_<mode>"
6027   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6028         (unspec:DI [(fix:SI
6029                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6030                    UNSPEC_FCTIWZ))]
6031   "TARGET_HARD_FLOAT"
6032   "@
6033    fctiwz %0,%1
6034    xscvdpsxws %x0,%x1"
6035   [(set_attr "type" "fp")])
6037 (define_insn "fctiwuz_<mode>"
6038   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6039         (unspec:DI [(unsigned_fix:SI
6040                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6041                    UNSPEC_FCTIWUZ))]
6042   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6043   "@
6044    fctiwuz %0,%1
6045    xscvdpuxws %x0,%x1"
6046   [(set_attr "type" "fp")])
6048 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6049 ;; since the friz instruction does not truncate the value if the floating
6050 ;; point value is < LONG_MIN or > LONG_MAX.
6051 (define_insn "*friz"
6052   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6053         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6054   "TARGET_HARD_FLOAT && TARGET_FPRND
6055    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6056   "@
6057    friz %0,%1
6058    xsrdpiz %x0,%x1"
6059   [(set_attr "type" "fp")])
6061 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
6062 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6063 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6064 ;; extend it, store it back on the stack from the GPR, load it back into the
6065 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6066 ;; disable using store and load to sign/zero extend the value.
6067 (define_insn_and_split "*round32<mode>2_fprs"
6068   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6069         (float:SFDF
6070          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6071    (clobber (match_scratch:DI 2 "=d"))
6072    (clobber (match_scratch:DI 3 "=d"))]
6073   "TARGET_HARD_FLOAT
6074    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6075    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6076   "#"
6077   ""
6078   [(pc)]
6080   rtx dest = operands[0];
6081   rtx src = operands[1];
6082   rtx tmp1 = operands[2];
6083   rtx tmp2 = operands[3];
6084   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6086   if (GET_CODE (tmp1) == SCRATCH)
6087     tmp1 = gen_reg_rtx (DImode);
6088   if (GET_CODE (tmp2) == SCRATCH)
6089     tmp2 = gen_reg_rtx (DImode);
6091   emit_insn (gen_fctiwz_<mode> (tmp1, src));
6092   emit_insn (gen_stfiwx (stack, tmp1));
6093   emit_insn (gen_lfiwax (tmp2, stack));
6094   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6095   DONE;
6097   [(set_attr "type" "fpload")
6098    (set_attr "length" "16")])
6100 (define_insn_and_split "*roundu32<mode>2_fprs"
6101   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6102         (unsigned_float:SFDF
6103          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6104    (clobber (match_scratch:DI 2 "=d"))
6105    (clobber (match_scratch:DI 3 "=d"))]
6106   "TARGET_HARD_FLOAT
6107    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6108    && can_create_pseudo_p ()"
6109   "#"
6110   ""
6111   [(pc)]
6113   rtx dest = operands[0];
6114   rtx src = operands[1];
6115   rtx tmp1 = operands[2];
6116   rtx tmp2 = operands[3];
6117   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6119   if (GET_CODE (tmp1) == SCRATCH)
6120     tmp1 = gen_reg_rtx (DImode);
6121   if (GET_CODE (tmp2) == SCRATCH)
6122     tmp2 = gen_reg_rtx (DImode);
6124   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6125   emit_insn (gen_stfiwx (stack, tmp1));
6126   emit_insn (gen_lfiwzx (tmp2, stack));
6127   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6128   DONE;
6130   [(set_attr "type" "fpload")
6131    (set_attr "length" "16")])
6133 ;; No VSX equivalent to fctid
6134 (define_insn "lrint<mode>di2"
6135   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6136         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6137                    UNSPEC_FCTID))]
6138   "TARGET_HARD_FLOAT && TARGET_FPRND"
6139   "fctid %0,%1"
6140   [(set_attr "type" "fp")])
6142 (define_insn "btrunc<mode>2"
6143   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6144         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6145                      UNSPEC_FRIZ))]
6146   "TARGET_HARD_FLOAT && TARGET_FPRND"
6147   "@
6148    friz %0,%1
6149    xsrdpiz %x0,%x1"
6150   [(set_attr "type" "fp")])
6152 (define_insn "ceil<mode>2"
6153   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6154         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6155                      UNSPEC_FRIP))]
6156   "TARGET_HARD_FLOAT && TARGET_FPRND"
6157   "@
6158    frip %0,%1
6159    xsrdpip %x0,%x1"
6160   [(set_attr "type" "fp")])
6162 (define_insn "floor<mode>2"
6163   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6164         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6165                      UNSPEC_FRIM))]
6166   "TARGET_HARD_FLOAT && TARGET_FPRND"
6167   "@
6168    frim %0,%1
6169    xsrdpim %x0,%x1"
6170   [(set_attr "type" "fp")])
6172 ;; No VSX equivalent to frin
6173 (define_insn "round<mode>2"
6174   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6175         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6176                      UNSPEC_FRIN))]
6177   "TARGET_HARD_FLOAT && TARGET_FPRND"
6178   "frin %0,%1"
6179   [(set_attr "type" "fp")])
6181 (define_insn "*xsrdpi<mode>2"
6182   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6183         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6184                      UNSPEC_XSRDPI))]
6185   "TARGET_HARD_FLOAT && TARGET_VSX"
6186   "xsrdpi %x0,%x1"
6187   [(set_attr "type" "fp")])
6189 (define_expand "lround<mode>di2"
6190   [(set (match_dup 2)
6191         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6192                      UNSPEC_XSRDPI))
6193    (set (match_operand:DI 0 "gpc_reg_operand")
6194         (unspec:DI [(match_dup 2)]
6195                    UNSPEC_FCTID))]
6196   "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6198   operands[2] = gen_reg_rtx (<MODE>mode);
6201 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6202 (define_insn "stfiwx"
6203   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6204         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6205                    UNSPEC_STFIWX))]
6206   "TARGET_PPC_GFXOPT"
6207   "@
6208    stfiwx %1,%y0
6209    stxsiwx %x1,%y0"
6210   [(set_attr "type" "fpstore")
6211    (set_attr "isa" "*,p8v")])
6213 ;; If we don't have a direct conversion to single precision, don't enable this
6214 ;; conversion for 32-bit without fast math, because we don't have the insn to
6215 ;; generate the fixup swizzle to avoid double rounding problems.
6216 (define_expand "floatsisf2"
6217   [(set (match_operand:SF 0 "gpc_reg_operand")
6218         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6219   "TARGET_HARD_FLOAT
6220    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6221        || (TARGET_FCFID
6222            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6224   if (TARGET_FCFIDS && TARGET_LFIWAX)
6225     {
6226       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6227       DONE;
6228     }
6229   else if (TARGET_FCFID && TARGET_LFIWAX)
6230     {
6231       rtx dfreg = gen_reg_rtx (DFmode);
6232       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6233       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6234       DONE;
6235     }
6236   else
6237     {
6238       rtx dreg = operands[1];
6239       if (!REG_P (dreg))
6240         dreg = force_reg (SImode, dreg);
6241       dreg = convert_to_mode (DImode, dreg, false);
6242       emit_insn (gen_floatdisf2 (operands[0], dreg));
6243       DONE;
6244     }
6247 (define_insn "floatdidf2"
6248   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6249         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6250   "TARGET_FCFID && TARGET_HARD_FLOAT"
6251   "@
6252    fcfid %0,%1
6253    xscvsxddp %x0,%x1"
6254   [(set_attr "type" "fp")])
6256 ; Allow the combiner to merge source memory operands to the conversion so that
6257 ; the optimizer/register allocator doesn't try to load the value too early in a
6258 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6259 ; hit.  We will split after reload to avoid the trip through the GPRs
6261 (define_insn_and_split "*floatdidf2_mem"
6262   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6263         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6264    (clobber (match_scratch:DI 2 "=d,wa"))]
6265   "TARGET_HARD_FLOAT && TARGET_FCFID"
6266   "#"
6267   "&& reload_completed"
6268   [(set (match_dup 2) (match_dup 1))
6269    (set (match_dup 0) (float:DF (match_dup 2)))]
6270   ""
6271   [(set_attr "length" "8")
6272    (set_attr "type" "fpload")])
6274 (define_expand "floatunsdidf2"
6275   [(set (match_operand:DF 0 "gpc_reg_operand")
6276         (unsigned_float:DF
6277          (match_operand:DI 1 "gpc_reg_operand")))]
6278   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6279   "")
6281 (define_insn "*floatunsdidf2_fcfidu"
6282   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6283         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6284   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6285   "@
6286    fcfidu %0,%1
6287    xscvuxddp %x0,%x1"
6288   [(set_attr "type" "fp")])
6290 (define_insn_and_split "*floatunsdidf2_mem"
6291   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6292         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6293    (clobber (match_scratch:DI 2 "=d,wa"))]
6294   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6295   "#"
6296   "&& reload_completed"
6297   [(set (match_dup 2) (match_dup 1))
6298    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6299   ""
6300   [(set_attr "length" "8")
6301    (set_attr "type" "fpload")])
6303 (define_expand "floatdisf2"
6304   [(set (match_operand:SF 0 "gpc_reg_operand")
6305         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6306   "TARGET_FCFID && TARGET_HARD_FLOAT
6307    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6309   if (!TARGET_FCFIDS)
6310     {
6311       rtx val = operands[1];
6312       if (!flag_unsafe_math_optimizations)
6313         {
6314           rtx label = gen_label_rtx ();
6315           val = gen_reg_rtx (DImode);
6316           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6317           emit_label (label);
6318         }
6319       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6320       DONE;
6321     }
6324 (define_insn "floatdisf2_fcfids"
6325   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6326         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6327   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6328   "@
6329    fcfids %0,%1
6330    xscvsxdsp %x0,%x1"
6331   [(set_attr "type" "fp")
6332    (set_attr "isa" "*,p8v")])
6334 (define_insn_and_split "*floatdisf2_mem"
6335   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6336         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6337    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6338   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6339   "#"
6340   "&& reload_completed"
6341   [(pc)]
6343   emit_move_insn (operands[2], operands[1]);
6344   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6345   DONE;
6347   [(set_attr "length" "8")
6348    (set_attr "isa" "*,p8v,p8v")])
6350 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6351 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6352 ;; from double rounding.
6353 ;; Instead of creating a new cpu type for two FP operations, just use fp
6354 (define_insn_and_split "floatdisf2_internal1"
6355   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6356         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6357    (clobber (match_scratch:DF 2 "=d"))]
6358   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6359   "#"
6360   "&& reload_completed"
6361   [(set (match_dup 2)
6362         (float:DF (match_dup 1)))
6363    (set (match_dup 0)
6364         (float_truncate:SF (match_dup 2)))]
6365   ""
6366   [(set_attr "length" "8")
6367    (set_attr "type" "fp")])
6369 ;; Twiddles bits to avoid double rounding.
6370 ;; Bits that might be truncated when converting to DFmode are replaced
6371 ;; by a bit that won't be lost at that stage, but is below the SFmode
6372 ;; rounding position.
6373 (define_expand "floatdisf2_internal2"
6374   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6375                                               (const_int 53)))
6376               (clobber (reg:DI CA_REGNO))])
6377    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6378                                         (const_int 2047)))
6379    (set (match_dup 3) (plus:DI (match_dup 3)
6380                                (const_int 1)))
6381    (set (match_dup 0) (plus:DI (match_dup 0)
6382                                (const_int 2047)))
6383    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6384                                      (const_int 2)))
6385    (set (match_dup 0) (ior:DI (match_dup 0)
6386                               (match_dup 1)))
6387    (set (match_dup 0) (and:DI (match_dup 0)
6388                               (const_int -2048)))
6389    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6390                            (label_ref (match_operand:DI 2 ""))
6391                            (pc)))
6392    (set (match_dup 0) (match_dup 1))]
6393   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6395   operands[3] = gen_reg_rtx (DImode);
6396   operands[4] = gen_reg_rtx (CCUNSmode);
6399 (define_expand "floatunsdisf2"
6400   [(set (match_operand:SF 0 "gpc_reg_operand")
6401         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6402   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6403   "")
6405 (define_insn "floatunsdisf2_fcfidus"
6406   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6407         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6408   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6409   "@
6410    fcfidus %0,%1
6411    xscvuxdsp %x0,%x1"
6412   [(set_attr "type" "fp")
6413    (set_attr "isa" "*,p8v")])
6415 (define_insn_and_split "*floatunsdisf2_mem"
6416   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6417         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6418    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6419   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6420   "#"
6421   "&& reload_completed"
6422   [(pc)]
6424   emit_move_insn (operands[2], operands[1]);
6425   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6426   DONE;
6428   [(set_attr "type" "fpload")
6429    (set_attr "length" "8")
6430    (set_attr "isa" "*,p8v,p8v")])
6432 ;; Define the TImode operations that can be done in a small number
6433 ;; of instructions.  The & constraints are to prevent the register
6434 ;; allocator from allocating registers that overlap with the inputs
6435 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6436 ;; also allow for the output being the same as one of the inputs.
6438 (define_expand "addti3"
6439   [(set (match_operand:TI 0 "gpc_reg_operand")
6440         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6441                  (match_operand:TI 2 "reg_or_short_operand")))]
6442   "TARGET_64BIT"
6444   rtx lo0 = gen_lowpart (DImode, operands[0]);
6445   rtx lo1 = gen_lowpart (DImode, operands[1]);
6446   rtx lo2 = gen_lowpart (DImode, operands[2]);
6447   rtx hi0 = gen_highpart (DImode, operands[0]);
6448   rtx hi1 = gen_highpart (DImode, operands[1]);
6449   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6451   if (!reg_or_short_operand (lo2, DImode))
6452     lo2 = force_reg (DImode, lo2);
6453   if (!adde_operand (hi2, DImode))
6454     hi2 = force_reg (DImode, hi2);
6456   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6457   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6458   DONE;
6461 (define_expand "subti3"
6462   [(set (match_operand:TI 0 "gpc_reg_operand")
6463         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6464                   (match_operand:TI 2 "gpc_reg_operand")))]
6465   "TARGET_64BIT"
6467   rtx lo0 = gen_lowpart (DImode, operands[0]);
6468   rtx lo1 = gen_lowpart (DImode, operands[1]);
6469   rtx lo2 = gen_lowpart (DImode, operands[2]);
6470   rtx hi0 = gen_highpart (DImode, operands[0]);
6471   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6472   rtx hi2 = gen_highpart (DImode, operands[2]);
6474   if (!reg_or_short_operand (lo1, DImode))
6475     lo1 = force_reg (DImode, lo1);
6476   if (!adde_operand (hi1, DImode))
6477     hi1 = force_reg (DImode, hi1);
6479   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6480   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6481   DONE;
6484 ;; 128-bit logical operations expanders
6486 (define_expand "and<mode>3"
6487   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6488         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6489                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6490   ""
6491   "")
6493 (define_expand "ior<mode>3"
6494   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6495         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6496                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6497   ""
6498   "")
6500 (define_expand "xor<mode>3"
6501   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6502         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6503                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6504   ""
6505   "")
6507 (define_expand "nor<mode>3"
6508   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6509         (and:BOOL_128
6510          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6511          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6512   ""
6513   "")
6515 (define_expand "andc<mode>3"
6516   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6517         (and:BOOL_128
6518          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6519          (match_operand:BOOL_128 1 "vlogical_operand")))]
6520   ""
6521   "")
6523 ;; Power8 vector logical instructions.
6524 (define_expand "eqv<mode>3"
6525   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6526         (not:BOOL_128
6527          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6528                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6529   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6530   "")
6532 ;; Rewrite nand into canonical form
6533 (define_expand "nand<mode>3"
6534   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6535         (ior:BOOL_128
6536          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6537          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6538   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6539   "")
6541 ;; The canonical form is to have the negated element first, so we need to
6542 ;; reverse arguments.
6543 (define_expand "orc<mode>3"
6544   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6545         (ior:BOOL_128
6546          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6547          (match_operand:BOOL_128 1 "vlogical_operand")))]
6548   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6549   "")
6551 ;; 128-bit logical operations insns and split operations
6552 (define_insn_and_split "*and<mode>3_internal"
6553   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6554         (and:BOOL_128
6555          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6556          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6557   ""
6559   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6560     return "xxland %x0,%x1,%x2";
6562   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6563     return "vand %0,%1,%2";
6565   return "#";
6567   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6568   [(const_int 0)]
6570   rs6000_split_logical (operands, AND, false, false, false);
6571   DONE;
6573   [(set (attr "type")
6574       (if_then_else
6575         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6576         (const_string "veclogical")
6577         (const_string "integer")))
6578    (set (attr "length")
6579       (if_then_else
6580         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6581         (const_string "4")
6582         (if_then_else
6583          (match_test "TARGET_POWERPC64")
6584          (const_string "8")
6585          (const_string "16"))))])
6587 ;; 128-bit IOR/XOR
6588 (define_insn_and_split "*bool<mode>3_internal"
6589   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6590         (match_operator:BOOL_128 3 "boolean_or_operator"
6591          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6592           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6593   ""
6595   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6596     return "xxl%q3 %x0,%x1,%x2";
6598   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6599     return "v%q3 %0,%1,%2";
6601   return "#";
6603   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6604   [(const_int 0)]
6606   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6607   DONE;
6609   [(set (attr "type")
6610       (if_then_else
6611         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6612         (const_string "veclogical")
6613         (const_string "integer")))
6614    (set (attr "length")
6615       (if_then_else
6616         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6617         (const_string "4")
6618         (if_then_else
6619          (match_test "TARGET_POWERPC64")
6620          (const_string "8")
6621          (const_string "16"))))])
6623 ;; 128-bit ANDC/ORC
6624 (define_insn_and_split "*boolc<mode>3_internal1"
6625   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6626         (match_operator:BOOL_128 3 "boolean_operator"
6627          [(not:BOOL_128
6628            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6629           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6630   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6632   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6633     return "xxl%q3 %x0,%x1,%x2";
6635   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6636     return "v%q3 %0,%1,%2";
6638   return "#";
6640   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6641    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6642   [(const_int 0)]
6644   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6645   DONE;
6647   [(set (attr "type")
6648       (if_then_else
6649         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6650         (const_string "veclogical")
6651         (const_string "integer")))
6652    (set (attr "length")
6653       (if_then_else
6654         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6655         (const_string "4")
6656         (if_then_else
6657          (match_test "TARGET_POWERPC64")
6658          (const_string "8")
6659          (const_string "16"))))])
6661 (define_insn_and_split "*boolc<mode>3_internal2"
6662   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6663         (match_operator:TI2 3 "boolean_operator"
6664          [(not:TI2
6665            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6666           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6667   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6668   "#"
6669   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6670   [(const_int 0)]
6672   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6673   DONE;
6675   [(set_attr "type" "integer")
6676    (set (attr "length")
6677         (if_then_else
6678          (match_test "TARGET_POWERPC64")
6679          (const_string "8")
6680          (const_string "16")))])
6682 ;; 128-bit NAND/NOR
6683 (define_insn_and_split "*boolcc<mode>3_internal1"
6684   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6685         (match_operator:BOOL_128 3 "boolean_operator"
6686          [(not:BOOL_128
6687            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6688           (not:BOOL_128
6689            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6690   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6692   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6693     return "xxl%q3 %x0,%x1,%x2";
6695   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6696     return "v%q3 %0,%1,%2";
6698   return "#";
6700   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6701    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6702   [(const_int 0)]
6704   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6705   DONE;
6707   [(set (attr "type")
6708       (if_then_else
6709         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6710         (const_string "veclogical")
6711         (const_string "integer")))
6712    (set (attr "length")
6713       (if_then_else
6714         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6715         (const_string "4")
6716         (if_then_else
6717          (match_test "TARGET_POWERPC64")
6718          (const_string "8")
6719          (const_string "16"))))])
6721 (define_insn_and_split "*boolcc<mode>3_internal2"
6722   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6723         (match_operator:TI2 3 "boolean_operator"
6724          [(not:TI2
6725            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6726           (not:TI2
6727            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6728   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6729   "#"
6730   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6731   [(const_int 0)]
6733   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6734   DONE;
6736   [(set_attr "type" "integer")
6737    (set (attr "length")
6738         (if_then_else
6739          (match_test "TARGET_POWERPC64")
6740          (const_string "8")
6741          (const_string "16")))])
6744 ;; 128-bit EQV
6745 (define_insn_and_split "*eqv<mode>3_internal1"
6746   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6747         (not:BOOL_128
6748          (xor:BOOL_128
6749           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6750           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6751   "TARGET_P8_VECTOR"
6753   if (vsx_register_operand (operands[0], <MODE>mode))
6754     return "xxleqv %x0,%x1,%x2";
6756   return "#";
6758   "TARGET_P8_VECTOR && reload_completed
6759    && int_reg_operand (operands[0], <MODE>mode)"
6760   [(const_int 0)]
6762   rs6000_split_logical (operands, XOR, true, false, false);
6763   DONE;
6765   [(set (attr "type")
6766       (if_then_else
6767         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6768         (const_string "veclogical")
6769         (const_string "integer")))
6770    (set (attr "length")
6771       (if_then_else
6772         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6773         (const_string "4")
6774         (if_then_else
6775          (match_test "TARGET_POWERPC64")
6776          (const_string "8")
6777          (const_string "16"))))])
6779 (define_insn_and_split "*eqv<mode>3_internal2"
6780   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6781         (not:TI2
6782          (xor:TI2
6783           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6784           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6785   "!TARGET_P8_VECTOR"
6786   "#"
6787   "reload_completed && !TARGET_P8_VECTOR"
6788   [(const_int 0)]
6790   rs6000_split_logical (operands, XOR, true, false, false);
6791   DONE;
6793   [(set_attr "type" "integer")
6794    (set (attr "length")
6795         (if_then_else
6796          (match_test "TARGET_POWERPC64")
6797          (const_string "8")
6798          (const_string "16")))])
6800 ;; 128-bit one's complement
6801 (define_insn_and_split "one_cmpl<mode>2"
6802   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6803         (not:BOOL_128
6804           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6805   ""
6807   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6808     return "xxlnor %x0,%x1,%x1";
6810   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6811     return "vnor %0,%1,%1";
6813   return "#";
6815   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6816   [(const_int 0)]
6818   rs6000_split_logical (operands, NOT, false, false, false);
6819   DONE;
6821   [(set (attr "type")
6822       (if_then_else
6823         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6824         (const_string "veclogical")
6825         (const_string "integer")))
6826    (set (attr "length")
6827       (if_then_else
6828         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6829         (const_string "4")
6830         (if_then_else
6831          (match_test "TARGET_POWERPC64")
6832          (const_string "8")
6833          (const_string "16"))))])
6836 ;; Now define ways of moving data around.
6838 ;; Set up a register with a value from the GOT table
6840 (define_expand "movsi_got"
6841   [(set (match_operand:SI 0 "gpc_reg_operand")
6842         (unspec:SI [(match_operand:SI 1 "got_operand")
6843                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6844   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6846   if (GET_CODE (operands[1]) == CONST)
6847     {
6848       rtx offset = const0_rtx;
6849       HOST_WIDE_INT value;
6851       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6852       value = INTVAL (offset);
6853       if (value != 0)
6854         {
6855           rtx tmp = (!can_create_pseudo_p ()
6856                      ? operands[0]
6857                      : gen_reg_rtx (Pmode));
6858           emit_insn (gen_movsi_got (tmp, operands[1]));
6859           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6860           DONE;
6861         }
6862     }
6864   operands[2] = rs6000_got_register (operands[1]);
6867 (define_insn "*movsi_got_internal"
6868   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6869         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6870                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6871                    UNSPEC_MOVSI_GOT))]
6872   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6873   "lwz %0,%a1@got(%2)"
6874   [(set_attr "type" "load")])
6876 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6877 ;; didn't get allocated to a hard register.
6878 (define_split
6879   [(set (match_operand:SI 0 "gpc_reg_operand")
6880         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6881                     (match_operand:SI 2 "memory_operand")]
6882                    UNSPEC_MOVSI_GOT))]
6883   "DEFAULT_ABI == ABI_V4
6884     && flag_pic == 1
6885     && reload_completed"
6886   [(set (match_dup 0) (match_dup 2))
6887    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6888                                  UNSPEC_MOVSI_GOT))]
6889   "")
6891 ;;              MR           LA           LWZ          LFIWZX       LXSIWZX
6892 ;;              STW          STFIWX       STXSIWX      LI           LIS
6893 ;;              #            XXLOR        XXSPLTIB 0   XXSPLTIB -1  VSPLTISW
6894 ;;              XXLXOR 0     XXLORC -1    P9 const     MTVSRWZ      MFVSRWZ
6895 ;;              MF%1         MT%0         NOP
6896 (define_insn "*movsi_internal1"
6897   [(set (match_operand:SI 0 "nonimmediate_operand"
6898                 "=r,         r,           r,           d,           v,
6899                  m,          Z,           Z,           r,           r,
6900                  r,          wa,          wa,          wa,          v,
6901                  wa,         v,           v,           wa,          r,
6902                  r,          *h,          *h")
6903         (match_operand:SI 1 "input_operand"
6904                 "r,          U,           m,           Z,           Z,
6905                  r,          d,           v,           I,           L,
6906                  n,          wa,          O,           wM,          wB,
6907                  O,          wM,          wS,          r,           wa,
6908                  *h,         r,           0"))]
6909   "gpc_reg_operand (operands[0], SImode)
6910    || gpc_reg_operand (operands[1], SImode)"
6911   "@
6912    mr %0,%1
6913    la %0,%a1
6914    lwz%U1%X1 %0,%1
6915    lfiwzx %0,%y1
6916    lxsiwzx %x0,%y1
6917    stw%U0%X0 %1,%0
6918    stfiwx %1,%y0
6919    stxsiwx %x1,%y0
6920    li %0,%1
6921    lis %0,%v1
6922    #
6923    xxlor %x0,%x1,%x1
6924    xxspltib %x0,0
6925    xxspltib %x0,255
6926    vspltisw %0,%1
6927    xxlxor %x0,%x0,%x0
6928    xxlorc %x0,%x0,%x0
6929    #
6930    mtvsrwz %x0,%1
6931    mfvsrwz %0,%x1
6932    mf%1 %0
6933    mt%0 %1
6934    nop"
6935   [(set_attr "type"
6936                 "*,          *,           load,        fpload,      fpload,
6937                  store,      fpstore,     fpstore,     *,           *,
6938                  *,          veclogical,  vecsimple,   vecsimple,   vecsimple,
6939                  veclogical, veclogical,  vecsimple,   mffgpr,      mftgpr,
6940                  *,          *,           *")
6941    (set_attr "length"
6942                 "*,          *,           *,           *,           *,
6943                  *,          *,           *,           *,           *,
6944                  8,          *,           *,           *,           *,
6945                  *,          *,           8,           *,           *,
6946                  *,          *,           *")
6947    (set_attr "isa"
6948                 "*,          *,           *,           p8v,         p8v,
6949                  *,          p8v,         p8v,         *,           *,
6950                  *,          p8v,         p9v,         p9v,         p8v,
6951                  p9v,        p8v,         p9v,         p8v,         p8v,
6952                  *,          *,           *")])
6954 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6955 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6957 ;; Because SF values are actually stored as DF values within the vector
6958 ;; registers, we need to convert the value to the vector SF format when
6959 ;; we need to use the bits in a union or similar cases.  We only need
6960 ;; to do this transformation when the value is a vector register.  Loads,
6961 ;; stores, and transfers within GPRs are assumed to be safe.
6963 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6964 ;; no alternatives, because the call is created as part of secondary_reload,
6965 ;; and operand #2's register class is used to allocate the temporary register.
6966 ;; This function is called before reload, and it creates the temporary as
6967 ;; needed.
6969 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6970 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6971 ;;              MTVSRWZ
6973 (define_insn_and_split "movsi_from_sf"
6974   [(set (match_operand:SI 0 "nonimmediate_operand"
6975                 "=r,         r,           ?*d,         ?*v,      m,
6976                  m,          wY,          Z,           r,        ?*wa,
6977                  wa")
6978         (unspec:SI [(match_operand:SF 1 "input_operand"
6979                 "r,          m,           Z,           Z,        r,
6980                  f,          v,           wa,          wa,       wa,
6981                  r")]
6982                     UNSPEC_SI_FROM_SF))
6983    (clobber (match_scratch:V4SF 2
6984                 "=X,         X,           X,           X,        X,
6985                  X,          X,           X,           wa,       X,
6986                  X"))]
6987   "TARGET_NO_SF_SUBREG
6988    && (register_operand (operands[0], SImode)
6989        || register_operand (operands[1], SFmode))"
6990   "@
6991    mr %0,%1
6992    lwz%U1%X1 %0,%1
6993    lfiwzx %0,%y1
6994    lxsiwzx %x0,%y1
6995    stw%U0%X0 %1,%0
6996    stfs%U0%X0 %1,%0
6997    stxssp %1,%0
6998    stxsspx %x1,%y0
6999    #
7000    xscvdpspn %x0,%x1
7001    mtvsrwz %x0,%1"
7002   "&& reload_completed
7003    && int_reg_operand (operands[0], SImode)
7004    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7005   [(const_int 0)]
7007   rtx op0 = operands[0];
7008   rtx op1 = operands[1];
7009   rtx op2 = operands[2];
7010   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7011   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7013   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7014   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7015   DONE;
7017   [(set_attr "type"
7018                 "*,          load,        fpload,      fpload,   store,
7019                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
7020                  mffgpr")
7021    (set_attr "length"
7022                 "*,          *,           *,           *,        *,
7023                  *,          *,           *,           8,        *,
7024                  *")
7025    (set_attr "isa"
7026                 "*,          *,           p8v,         p8v,      *,
7027                  *,          p9v,         p8v,         p8v,      p8v,
7028                  p8v")])
7030 ;; movsi_from_sf with zero extension
7032 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
7033 ;;              VSX->VSX     MTVSRWZ
7035 (define_insn_and_split "*movdi_from_sf_zero_ext"
7036   [(set (match_operand:DI 0 "gpc_reg_operand"
7037                 "=r,         r,           ?*d,         ?*v,      r,
7038                  ?v,         wa")
7039         (zero_extend:DI
7040          (unspec:SI [(match_operand:SF 1 "input_operand"
7041                 "r,          m,           Z,           Z,        wa,
7042                  wa,         r")]
7043                     UNSPEC_SI_FROM_SF)))
7044    (clobber (match_scratch:V4SF 2
7045                 "=X,         X,           X,           X,        wa,
7046                  wa,         X"))]
7047   "TARGET_DIRECT_MOVE_64BIT
7048    && (register_operand (operands[0], DImode)
7049        || register_operand (operands[1], SImode))"
7050   "@
7051    rldicl %0,%1,0,32
7052    lwz%U1%X1 %0,%1
7053    lfiwzx %0,%y1
7054    lxsiwzx %x0,%y1
7055    #
7056    #
7057    mtvsrwz %x0,%1"
7058   "&& reload_completed
7059    && register_operand (operands[0], DImode)
7060    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7061   [(const_int 0)]
7063   rtx op0 = operands[0];
7064   rtx op1 = operands[1];
7065   rtx op2 = operands[2];
7066   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7068   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7069   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7070   DONE;
7072   [(set_attr "type"
7073                 "*,          load,        fpload,      fpload,   two,
7074                  two,        mffgpr")
7075    (set_attr "length"
7076                 "*,          *,           *,           *,        8,
7077                  8,          *")
7078    (set_attr "isa"
7079                 "*,          *,           p8v,         p8v,      p8v,
7080                  p9v,        p8v")])
7082 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7083 ;; moving it to SImode.  We cannot do a SFmode store without having to do the
7084 ;; conversion explicitly since that doesn't work in most cases if the input
7085 ;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7086 ;; former handles cases where the input will not fit in a SFmode, and the
7087 ;; latter assumes the value has already been rounded.
7088 (define_insn "*movsi_from_df"
7089   [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7090         (unspec:SI [(float_truncate:SF
7091                      (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7092                     UNSPEC_SI_FROM_SF))]
7093   "TARGET_NO_SF_SUBREG"
7094   "xscvdpsp %x0,%x1"
7095   [(set_attr "type" "fp")])
7097 ;; Split a load of a large constant into the appropriate two-insn
7098 ;; sequence.
7100 (define_split
7101   [(set (match_operand:SI 0 "gpc_reg_operand")
7102         (match_operand:SI 1 "const_int_operand"))]
7103   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7104    && (INTVAL (operands[1]) & 0xffff) != 0"
7105   [(set (match_dup 0)
7106         (match_dup 2))
7107    (set (match_dup 0)
7108         (ior:SI (match_dup 0)
7109                 (match_dup 3)))]
7111   if (rs6000_emit_set_const (operands[0], operands[1]))
7112     DONE;
7113   else
7114     FAIL;
7117 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7118 (define_split
7119   [(set (match_operand:DI 0 "altivec_register_operand")
7120         (match_operand:DI 1 "xxspltib_constant_split"))]
7121   "TARGET_P9_VECTOR && reload_completed"
7122   [(const_int 0)]
7124   rtx op0 = operands[0];
7125   rtx op1 = operands[1];
7126   int r = REGNO (op0);
7127   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7129   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7130   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7131   DONE;
7134 (define_insn "*mov<mode>_internal2"
7135   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7136         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7137                     (const_int 0)))
7138    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7139   ""
7140   "@
7141    cmp<wd>i %2,%0,0
7142    mr. %0,%1
7143    #"
7144   [(set_attr "type" "cmp,logical,cmp")
7145    (set_attr "dot" "yes")
7146    (set_attr "length" "4,4,8")])
7148 (define_split
7149   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7150         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7151                     (const_int 0)))
7152    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7153   "reload_completed"
7154   [(set (match_dup 0) (match_dup 1))
7155    (set (match_dup 2)
7156         (compare:CC (match_dup 0)
7157                     (const_int 0)))]
7158   "")
7160 (define_expand "mov<mode>"
7161   [(set (match_operand:INT 0 "general_operand")
7162         (match_operand:INT 1 "any_operand"))]
7163   ""
7165   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7166   DONE;
7169 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7170 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7171 ;;              MTVSRWZ     MF%1       MT%1       NOP
7172 (define_insn "*mov<mode>_internal"
7173   [(set (match_operand:QHI 0 "nonimmediate_operand"
7174                 "=r,        r,         wa,        m,         Z,         r,
7175                  wa,        wa,        wa,        v,         ?v,        r,
7176                  wa,        r,         *c*l,      *h")
7177         (match_operand:QHI 1 "input_operand"
7178                 "r,         m,         Z,         r,         wa,        i,
7179                  wa,        O,         wM,        wB,        wS,        wa,
7180                  r,         *h,        r,         0"))]
7181   "gpc_reg_operand (operands[0], <MODE>mode)
7182    || gpc_reg_operand (operands[1], <MODE>mode)"
7183   "@
7184    mr %0,%1
7185    l<wd>z%U1%X1 %0,%1
7186    lxsi<wd>zx %x0,%y1
7187    st<wd>%U0%X0 %1,%0
7188    stxsi<wd>x %x1,%y0
7189    li %0,%1
7190    xxlor %x0,%x1,%x1
7191    xxspltib %x0,0
7192    xxspltib %x0,255
7193    vspltis<wd> %0,%1
7194    #
7195    mfvsrwz %0,%x1
7196    mtvsrwz %x0,%1
7197    mf%1 %0
7198    mt%0 %1
7199    nop"
7200   [(set_attr "type"
7201                 "*,         load,      fpload,    store,     fpstore,   *,
7202                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7203                  mffgpr,    mfjmpr,    mtjmpr,    *")
7204    (set_attr "length"
7205                 "*,         *,         *,         *,         *,         *,
7206                  *,         *,         *,         *,         8,         *,
7207                  *,         *,         *,         *")
7208    (set_attr "isa"
7209                 "*,         *,         p9v,       *,         p9v,       *,
7210                  p9v,       p9v,       p9v,       p9v,       p9v,       p9v,
7211                  p9v,       *,         *,         *")])
7214 ;; Here is how to move condition codes around.  When we store CC data in
7215 ;; an integer register or memory, we store just the high-order 4 bits.
7216 ;; This lets us not shift in the most common case of CR0.
7217 (define_expand "movcc"
7218   [(set (match_operand:CC 0 "nonimmediate_operand")
7219         (match_operand:CC 1 "nonimmediate_operand"))]
7220   ""
7221   "")
7223 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7225 (define_insn "*movcc_<mode>"
7226   [(set (match_operand:CC_any 0 "nonimmediate_operand"
7227                                 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7228         (match_operand:CC_any 1 "general_operand"
7229                                 " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7230   "register_operand (operands[0], <MODE>mode)
7231    || register_operand (operands[1], <MODE>mode)"
7232   "@
7233    mcrf %0,%1
7234    mtcrf 128,%1
7235    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7236    crxor %0,%0,%0
7237    mfcr %0%Q1
7238    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7239    mr %0,%1
7240    li %0,%1
7241    mf%1 %0
7242    mt%0 %1
7243    lwz%U1%X1 %0,%1
7244    stw%U0%X0 %1,%0"
7245   [(set_attr_alternative "type"
7246      [(const_string "cr_logical")
7247       (const_string "mtcr")
7248       (const_string "mtcr")
7249       (const_string "cr_logical")
7250       (if_then_else (match_test "TARGET_MFCRF")
7251                     (const_string "mfcrf") (const_string "mfcr"))
7252       (if_then_else (match_test "TARGET_MFCRF")
7253                     (const_string "mfcrf") (const_string "mfcr"))
7254       (const_string "integer")
7255       (const_string "integer")
7256       (const_string "mfjmpr")
7257       (const_string "mtjmpr")
7258       (const_string "load")
7259       (const_string "store")])
7260    (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7262 ;; For floating-point, we normally deal with the floating-point registers
7263 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7264 ;; can produce floating-point values in fixed-point registers.  Unless the
7265 ;; value is a simple constant or already in memory, we deal with this by
7266 ;; allocating memory and copying the value explicitly via that memory location.
7268 ;; Move 32-bit binary/decimal floating point
7269 (define_expand "mov<mode>"
7270   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7271         (match_operand:FMOVE32 1 "any_operand"))]
7272   "<fmove_ok>"
7274   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7275   DONE;
7278 (define_split
7279   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7280         (match_operand:FMOVE32 1 "const_double_operand"))]
7281   "reload_completed
7282    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7283        || (SUBREG_P (operands[0])
7284            && REG_P (SUBREG_REG (operands[0]))
7285            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7286   [(set (match_dup 2) (match_dup 3))]
7288   long l;
7290   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7292   if (! TARGET_POWERPC64)
7293     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7294   else
7295     operands[2] = gen_lowpart (SImode, operands[0]);
7297   operands[3] = gen_int_mode (l, SImode);
7300 ;; Originally, we tried to keep movsf and movsd common, but the differences
7301 ;; addressing was making it rather difficult to hide with mode attributes.  In
7302 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7303 ;; before the VSX stores meant that the register allocator would tend to do a
7304 ;; direct move to the GPR (which involves conversion from scalar to
7305 ;; vector/memory formats) to save values in the traditional Altivec registers,
7306 ;; while SDmode had problems on power6 if the GPR store was not first due to
7307 ;; the power6 not having an integer store operation.
7309 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7310 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7311 ;;      MR           MT<x>      MF<x>       NOP
7313 (define_insn "movsf_hardfloat"
7314   [(set (match_operand:SF 0 "nonimmediate_operand"
7315          "=!r,       f,         v,          wa,        m,         wY,
7316           Z,         m,         wa,         !r,        f,         wa,
7317           !r,        *c*l,      !r,         *h")
7318         (match_operand:SF 1 "input_operand"
7319          "m,         m,         wY,         Z,         f,         v,
7320           wa,        r,         j,          j,         f,         wa,
7321           r,         r,         *h,         0"))]
7322   "(register_operand (operands[0], SFmode)
7323    || register_operand (operands[1], SFmode))
7324    && TARGET_HARD_FLOAT
7325    && (TARGET_ALLOW_SF_SUBREG
7326        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7327   "@
7328    lwz%U1%X1 %0,%1
7329    lfs%U1%X1 %0,%1
7330    lxssp %0,%1
7331    lxsspx %x0,%y1
7332    stfs%U0%X0 %1,%0
7333    stxssp %1,%0
7334    stxsspx %x1,%y0
7335    stw%U0%X0 %1,%0
7336    xxlxor %x0,%x0,%x0
7337    li %0,0
7338    fmr %0,%1
7339    xscpsgndp %x0,%x1,%x1
7340    mr %0,%1
7341    mt%0 %1
7342    mf%1 %0
7343    nop"
7344   [(set_attr "type"
7345         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7346          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7347          *,          mtjmpr,    mfjmpr,     *")
7348    (set_attr "isa"
7349         "*,          *,         p9v,        p8v,       *,         p9v,
7350          p8v,        *,         *,          *,         *,         *,
7351          *,          *,         *,          *")])
7353 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7354 ;;      FMR          MR         MT%0       MF%1       NOP
7355 (define_insn "movsd_hardfloat"
7356   [(set (match_operand:SD 0 "nonimmediate_operand"
7357          "=!r,       d,         m,         Z,         ?d,        ?r,
7358           f,         !r,        *c*l,      !r,        *h")
7359         (match_operand:SD 1 "input_operand"
7360          "m,         Z,         r,         wx,        r,         d,
7361           f,         r,         r,         *h,        0"))]
7362   "(register_operand (operands[0], SDmode)
7363    || register_operand (operands[1], SDmode))
7364    && TARGET_HARD_FLOAT"
7365   "@
7366    lwz%U1%X1 %0,%1
7367    lfiwzx %0,%y1
7368    stw%U0%X0 %1,%0
7369    stfiwx %1,%y0
7370    mtvsrwz %x0,%1
7371    mfvsrwz %0,%x1
7372    fmr %0,%1
7373    mr %0,%1
7374    mt%0 %1
7375    mf%1 %0
7376    nop"
7377   [(set_attr "type"
7378         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7379          fpsimple,   *,         mtjmpr,    mfjmpr,    *")
7380    (set_attr "isa"
7381         "*,          p7,        *,         *,         p8v,       p8v,
7382          *,          *,         *,         *,         *")])
7384 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7385 ;;      LIS          G-const.   F/n-const  NOP
7386 (define_insn "*mov<mode>_softfloat"
7387   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7388         "=r,         *c*l,      r,         r,         m,         r,
7389           r,         r,         r,         *h")
7391         (match_operand:FMOVE32 1 "input_operand"
7392          "r,         r,         *h,        m,         r,         I,
7393           L,         G,         Fn,        0"))]
7395   "(gpc_reg_operand (operands[0], <MODE>mode)
7396    || gpc_reg_operand (operands[1], <MODE>mode))
7397    && TARGET_SOFT_FLOAT"
7398   "@
7399    mr %0,%1
7400    mt%0 %1
7401    mf%1 %0
7402    lwz%U1%X1 %0,%1
7403    stw%U0%X0 %1,%0
7404    li %0,%1
7405    lis %0,%v1
7406    #
7407    #
7408    nop"
7409   [(set_attr "type"
7410         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7411          *,          *,         *,         *")
7413    (set_attr "length"
7414         "*,          *,         *,         *,         *,         *,
7415          *,          *,         8,         *")])
7417 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7418 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7420 ;; Because SF values are actually stored as DF values within the vector
7421 ;; registers, we need to convert the value to the vector SF format when
7422 ;; we need to use the bits in a union or similar cases.  We only need
7423 ;; to do this transformation when the value is a vector register.  Loads,
7424 ;; stores, and transfers within GPRs are assumed to be safe.
7426 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7427 ;; no alternatives, because the call is created as part of secondary_reload,
7428 ;; and operand #2's register class is used to allocate the temporary register.
7429 ;; This function is called before reload, and it creates the temporary as
7430 ;; needed.
7432 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7433 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7434 (define_insn_and_split "movsf_from_si"
7435   [(set (match_operand:SF 0 "nonimmediate_operand"
7436             "=!r,       f,         v,         wa,        m,         Z,
7437              Z,         wa,        ?r,        !r")
7438         (unspec:SF [(match_operand:SI 1 "input_operand" 
7439             "m,         m,         wY,        Z,         r,         f,
7440              wa,        r,         wa,        r")]
7441                    UNSPEC_SF_FROM_SI))
7442    (clobber (match_scratch:DI 2
7443             "=X,        X,         X,         X,         X,         X,
7444              X,         r,         X,         X"))]
7445   "TARGET_NO_SF_SUBREG
7446    && (register_operand (operands[0], SFmode)
7447        || register_operand (operands[1], SImode))"
7448   "@
7449    lwz%U1%X1 %0,%1
7450    lfs%U1%X1 %0,%1
7451    lxssp %0,%1
7452    lxsspx %x0,%y1
7453    stw%U0%X0 %1,%0
7454    stfiwx %1,%y0
7455    stxsiwx %x1,%y0
7456    #
7457    mfvsrwz %0,%x1
7458    mr %0,%1"
7460   "&& reload_completed
7461    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7462    && int_reg_operand_not_pseudo (operands[1], SImode)"
7463   [(const_int 0)]
7465   rtx op0 = operands[0];
7466   rtx op1 = operands[1];
7467   rtx op2 = operands[2];
7468   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7470   /* Move SF value to upper 32-bits for xscvspdpn.  */
7471   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7472   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7473   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7474   DONE;
7476   [(set_attr "length"
7477             "*,          *,         *,         *,         *,         *,
7478              *,          12,        *,         *")
7479    (set_attr "type"
7480             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7481              fpstore,    vecfloat,  mffgpr,    *")
7482    (set_attr "isa"
7483             "*,          *,         p9v,       p8v,       *,         *,
7484              p8v,        p8v,       p8v,       *")])
7487 ;; Move 64-bit binary/decimal floating point
7488 (define_expand "mov<mode>"
7489   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7490         (match_operand:FMOVE64 1 "any_operand"))]
7491   ""
7493   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7494   DONE;
7497 (define_split
7498   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7499         (match_operand:FMOVE64 1 "const_int_operand"))]
7500   "! TARGET_POWERPC64 && reload_completed
7501    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7502        || (SUBREG_P (operands[0])
7503            && REG_P (SUBREG_REG (operands[0]))
7504            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7505   [(set (match_dup 2) (match_dup 4))
7506    (set (match_dup 3) (match_dup 1))]
7508   int endian = (WORDS_BIG_ENDIAN == 0);
7509   HOST_WIDE_INT value = INTVAL (operands[1]);
7511   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7512   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7513   operands[4] = GEN_INT (value >> 32);
7514   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7517 (define_split
7518   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7519         (match_operand:FMOVE64 1 "const_double_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 5))]
7528   int endian = (WORDS_BIG_ENDIAN == 0);
7529   long l[2];
7531   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7533   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7534   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7535   operands[4] = gen_int_mode (l[endian], SImode);
7536   operands[5] = gen_int_mode (l[1 - endian], SImode);
7539 (define_split
7540   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7541         (match_operand:FMOVE64 1 "const_double_operand"))]
7542   "TARGET_POWERPC64 && reload_completed
7543    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7544        || (SUBREG_P (operands[0])
7545            && REG_P (SUBREG_REG (operands[0]))
7546            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7547   [(set (match_dup 2) (match_dup 3))]
7549   int endian = (WORDS_BIG_ENDIAN == 0);
7550   long l[2];
7551   HOST_WIDE_INT val;
7553   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7555   operands[2] = gen_lowpart (DImode, operands[0]);
7556   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7557   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7558          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7560   operands[3] = gen_int_mode (val, DImode);
7563 ;; Don't have reload use general registers to load a constant.  It is
7564 ;; less efficient than loading the constant into an FP register, since
7565 ;; it will probably be used there.
7567 ;; The move constraints are ordered to prefer floating point registers before
7568 ;; general purpose registers to avoid doing a store and a load to get the value
7569 ;; into a floating point register when it is needed for a floating point
7570 ;; operation.  Prefer traditional floating point registers over VSX registers,
7571 ;; since the D-form version of the memory instructions does not need a GPR for
7572 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7573 ;; registers.
7575 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7576 ;; except for 0.0 which can be created on VSX with an xor instruction.
7578 ;;           STFD         LFD         FMR         LXSD        STXSD
7579 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7580 ;;           LWZ          STW         MR
7583 (define_insn "*mov<mode>_hardfloat32"
7584   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7585             "=m,          d,          d,          <f64_p9>,   wY,
7586               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7587               Y,          r,          !r")
7588         (match_operand:FMOVE64 1 "input_operand"
7589              "d,          m,          d,          wY,         <f64_p9>,
7590               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7591               r,          Y,          r"))]
7592   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7593    && (gpc_reg_operand (operands[0], <MODE>mode)
7594        || gpc_reg_operand (operands[1], <MODE>mode))"
7595   "@
7596    stfd%U0%X0 %1,%0
7597    lfd%U1%X1 %0,%1
7598    fmr %0,%1
7599    lxsd %0,%1
7600    stxsd %1,%0
7601    lxsdx %x0,%y1
7602    stxsdx %x1,%y0
7603    xxlor %x0,%x1,%x1
7604    xxlxor %x0,%x0,%x0
7605    #
7606    #
7607    #
7608    #"
7609   [(set_attr "type"
7610             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7611              fpload,      fpstore,    veclogical, veclogical, two,
7612              store,       load,       two")
7613    (set_attr "size" "64")
7614    (set_attr "length"
7615             "*,           *,          *,          *,          *,
7616              *,           *,          *,          *,          8,
7617              8,           8,          8")
7618    (set_attr "isa"
7619             "*,           *,          *,          p9v,        p9v,
7620              p7v,         p7v,        *,          *,          *,
7621              *,           *,          *")])
7623 ;;           STW      LWZ     MR      G-const H-const F-const
7625 (define_insn "*mov<mode>_softfloat32"
7626   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7627            "=Y,       r,      r,      r,      r,      r")
7629         (match_operand:FMOVE64 1 "input_operand"
7630             "r,       Y,      r,      G,      H,      F"))]
7632   "!TARGET_POWERPC64
7633    && (gpc_reg_operand (operands[0], <MODE>mode)
7634        || gpc_reg_operand (operands[1], <MODE>mode))"
7635   "#"
7636   [(set_attr "type"
7637             "store,   load,   two,    *,      *,      *")
7639    (set_attr "length"
7640              "8,      8,      8,      8,      12,     16")])
7642 ; ld/std require word-aligned displacements -> 'Y' constraint.
7643 ; List Y->r and r->Y before r->r for reload.
7645 ;;           STFD         LFD         FMR         LXSD        STXSD
7646 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7647 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7648 ;;           NOP          MFVSRD      MTVSRD
7650 (define_insn "*mov<mode>_hardfloat64"
7651   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7652            "=m,           d,          d,          <f64_p9>,   wY,
7653              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7654              YZ,          r,          !r,         *c*l,       !r,
7655             *h,           r,          <f64_dm>")
7656         (match_operand:FMOVE64 1 "input_operand"
7657             "d,           m,          d,          wY,         <f64_p9>,
7658              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7659              r,           YZ,         r,          r,          *h,
7660              0,           <f64_dm>,   r"))]
7661   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7662    && (gpc_reg_operand (operands[0], <MODE>mode)
7663        || gpc_reg_operand (operands[1], <MODE>mode))"
7664   "@
7665    stfd%U0%X0 %1,%0
7666    lfd%U1%X1 %0,%1
7667    fmr %0,%1
7668    lxsd %0,%1
7669    stxsd %1,%0
7670    lxsdx %x0,%y1
7671    stxsdx %x1,%y0
7672    xxlor %x0,%x1,%x1
7673    xxlxor %x0,%x0,%x0
7674    li %0,0
7675    std%U0%X0 %1,%0
7676    ld%U1%X1 %0,%1
7677    mr %0,%1
7678    mt%0 %1
7679    mf%1 %0
7680    nop
7681    mfvsrd %0,%x1
7682    mtvsrd %x0,%1"
7683   [(set_attr "type"
7684             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7685              fpload,      fpstore,    veclogical, veclogical, integer,
7686              store,       load,       *,          mtjmpr,     mfjmpr,
7687              *,           mftgpr,     mffgpr")
7688    (set_attr "size" "64")
7689    (set_attr "isa"
7690             "*,           *,          *,          p9v,        p9v,
7691              p7v,         p7v,        *,          *,          *,
7692              *,           *,          *,          *,          *,
7693              *,           p8v,        p8v")])
7695 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7696 ;;           H-const  F-const  Special
7698 (define_insn "*mov<mode>_softfloat64"
7699   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7700            "=Y,       r,      r,      *c*l,   r,      r,
7701              r,       r,      *h")
7703         (match_operand:FMOVE64 1 "input_operand"
7704             "r,       Y,      r,      r,      *h,     G,
7705              H,       F,      0"))]
7707   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7708    && (gpc_reg_operand (operands[0], <MODE>mode)
7709        || gpc_reg_operand (operands[1], <MODE>mode))"
7710   "@
7711    std%U0%X0 %1,%0
7712    ld%U1%X1 %0,%1
7713    mr %0,%1
7714    mt%0 %1
7715    mf%1 %0
7716    #
7717    #
7718    #
7719    nop"
7720   [(set_attr "type"
7721             "store,   load,   *,      mtjmpr, mfjmpr, *,
7722              *,       *,      *")
7724    (set_attr "length"
7725             "*,       *,      *,      *,      *,      8,
7726              12,      16,     *")])
7728 (define_expand "mov<mode>"
7729   [(set (match_operand:FMOVE128 0 "general_operand")
7730         (match_operand:FMOVE128 1 "any_operand"))]
7731   ""
7733   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7734   DONE;
7737 ;; It's important to list Y->r and r->Y before r->r because otherwise
7738 ;; reload, given m->r, will try to pick r->r and reload it, which
7739 ;; doesn't make progress.
7741 ;; We can't split little endian direct moves of TDmode, because the words are
7742 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7743 ;; problematical.  Don't allow direct move for this case.
7745 ;;              FPR load    FPR store   FPR move    FPR zero    GPR load
7746 ;;              GPR zero    GPR store   GPR move    MFVSRD      MTVSRD
7748 (define_insn_and_split "*mov<mode>_64bit_dm"
7749   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7750                 "=m,        d,          d,          d,          Y,
7751                  r,         r,          r,          r,          d")
7753         (match_operand:FMOVE128_FPR 1 "input_operand"
7754                 "d,         m,          d,          <zero_fp>,  r,
7755                  <zero_fp>, Y,          r,          d,          r"))]
7757   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7758    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7759    && (gpc_reg_operand (operands[0], <MODE>mode)
7760        || gpc_reg_operand (operands[1], <MODE>mode))"
7761   "#"
7762   "&& reload_completed"
7763   [(pc)]
7765   rs6000_split_multireg_move (operands[0], operands[1]);
7766   DONE;
7768   [(set_attr "length" "8")
7769    (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7770    (set_attr "max_prefixed_insns" "2")
7771    (set_attr "num_insns" "2")])
7773 (define_insn_and_split "*movtd_64bit_nodm"
7774   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7775         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7776   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7777    && (gpc_reg_operand (operands[0], TDmode)
7778        || gpc_reg_operand (operands[1], TDmode))"
7779   "#"
7780   "&& reload_completed"
7781   [(pc)]
7783   rs6000_split_multireg_move (operands[0], operands[1]);
7784   DONE;
7786   [(set_attr "length" "8,8,8,12,12,8")
7787    (set_attr "max_prefixed_insns" "2")
7788    (set_attr "num_insns" "2,2,2,3,3,2")])
7790 (define_insn_and_split "*mov<mode>_32bit"
7791   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7792         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7793   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7794    && (FLOAT128_2REG_P (<MODE>mode)
7795        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7796        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7797    && (gpc_reg_operand (operands[0], <MODE>mode)
7798        || gpc_reg_operand (operands[1], <MODE>mode))"
7799   "#"
7800   "&& reload_completed"
7801   [(pc)]
7803   rs6000_split_multireg_move (operands[0], operands[1]);
7804   DONE;
7806   [(set_attr "length" "8,8,8,8,20,20,16")])
7808 (define_insn_and_split "*mov<mode>_softfloat"
7809   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7810         (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7811   "TARGET_SOFT_FLOAT
7812    && (gpc_reg_operand (operands[0], <MODE>mode)
7813        || gpc_reg_operand (operands[1], <MODE>mode))"
7814   "#"
7815   "&& reload_completed"
7816   [(pc)]
7818   rs6000_split_multireg_move (operands[0], operands[1]);
7819   DONE;
7821   [(set_attr_alternative "length"
7822        [(if_then_else (match_test "TARGET_POWERPC64")
7823             (const_string "8")
7824             (const_string "16"))
7825         (if_then_else (match_test "TARGET_POWERPC64")
7826             (const_string "8")
7827             (const_string "16"))
7828         (if_then_else (match_test "TARGET_POWERPC64")
7829             (const_string "16")
7830             (const_string "32"))
7831         (if_then_else (match_test "TARGET_POWERPC64")
7832             (const_string "8")
7833             (const_string "16"))])])
7835 (define_expand "@extenddf<mode>2"
7836   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7837         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7838   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7840   if (FLOAT128_IEEE_P (<MODE>mode))
7841     rs6000_expand_float128_convert (operands[0], operands[1], false);
7842   else if (TARGET_VSX)
7843     emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7844   else
7845     {
7846       rtx zero = gen_reg_rtx (DFmode);
7847       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7849       emit_insn (gen_extenddf2_fprs (<MODE>mode,
7850                                      operands[0], operands[1], zero));
7851     }
7852   DONE;
7855 ;; Allow memory operands for the source to be created by the combiner.
7856 (define_insn_and_split "@extenddf<mode>2_fprs"
7857   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7858         (float_extend:IBM128
7859          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7860    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7861   "!TARGET_VSX && TARGET_HARD_FLOAT
7862    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7863   "#"
7864   "&& reload_completed"
7865   [(set (match_dup 3) (match_dup 1))
7866    (set (match_dup 4) (match_dup 2))]
7868   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7869   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7871   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7872   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7875 (define_insn_and_split "@extenddf<mode>2_vsx"
7876   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7877         (float_extend:IBM128
7878          (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7879   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7880   "#"
7881   "&& reload_completed"
7882   [(set (match_dup 2) (match_dup 1))
7883    (set (match_dup 3) (match_dup 4))]
7885   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7886   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7888   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7889   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7890   operands[4] = CONST0_RTX (DFmode);
7893 (define_expand "extendsf<mode>2"
7894   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7895         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7896   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7898   if (FLOAT128_IEEE_P (<MODE>mode))
7899     rs6000_expand_float128_convert (operands[0], operands[1], false);
7900   else
7901     {
7902       rtx tmp = gen_reg_rtx (DFmode);
7903       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7904       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7905     }
7906   DONE;
7909 (define_expand "trunc<mode>df2"
7910   [(set (match_operand:DF 0 "gpc_reg_operand")
7911         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7912   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7914   if (FLOAT128_IEEE_P (<MODE>mode))
7915     {
7916       rs6000_expand_float128_convert (operands[0], operands[1], false);
7917       DONE;
7918     }
7921 (define_insn_and_split "trunc<mode>df2_internal1"
7922   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7923         (float_truncate:DF
7924          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7925   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7926    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7927   "@
7928    #
7929    fmr %0,%1"
7930   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7931   [(const_int 0)]
7933   emit_note (NOTE_INSN_DELETED);
7934   DONE;
7936   [(set_attr "type" "fpsimple")])
7938 (define_insn "trunc<mode>df2_internal2"
7939   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7940         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7941   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7942    && TARGET_LONG_DOUBLE_128"
7943   "fadd %0,%1,%L1"
7944   [(set_attr "type" "fp")])
7946 (define_expand "trunc<mode>sf2"
7947   [(set (match_operand:SF 0 "gpc_reg_operand")
7948         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7949   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7951   if (FLOAT128_IEEE_P (<MODE>mode))
7952     rs6000_expand_float128_convert (operands[0], operands[1], false);
7953   else
7954     {
7955       rtx tmp = gen_reg_rtx (DFmode);
7956       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7957       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7958     }
7959   DONE;
7962 (define_expand "floatsi<mode>2"
7963   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7964                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7965               (clobber (match_scratch:DI 2))])]
7966   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7968   rtx op0 = operands[0];
7969   rtx op1 = operands[1];
7971   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7972     ;
7973   else if (FLOAT128_IEEE_P (<MODE>mode))
7974     {
7975       rs6000_expand_float128_convert (op0, op1, false);
7976       DONE;
7977     }
7978   else
7979     {
7980       rtx tmp = gen_reg_rtx (DFmode);
7981       expand_float (tmp, op1, false);
7982       emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
7983       DONE;
7984     }
7987 ; fadd, but rounding towards zero.
7988 ; This is probably not the optimal code sequence.
7989 (define_insn "fix_trunc_helper<mode>"
7990   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7991         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7992                    UNSPEC_FIX_TRUNC_TF))
7993    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7994   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7995   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7996   [(set_attr "type" "fp")
7997    (set_attr "length" "20")])
7999 (define_expand "fix_trunc<mode>si2"
8000   [(set (match_operand:SI 0 "gpc_reg_operand")
8001         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8002   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8004   rtx op0 = operands[0];
8005   rtx op1 = operands[1];
8007   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8008     ;
8009   else
8010     {
8011       if (FLOAT128_IEEE_P (<MODE>mode))
8012         rs6000_expand_float128_convert (op0, op1, false);
8013       else
8014         emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8015       DONE;
8016     }
8019 (define_expand "@fix_trunc<mode>si2_fprs"
8020   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8021                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8022               (clobber (match_dup 2))
8023               (clobber (match_dup 3))
8024               (clobber (match_dup 4))
8025               (clobber (match_dup 5))])]
8026   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8028   operands[2] = gen_reg_rtx (DFmode);
8029   operands[3] = gen_reg_rtx (DFmode);
8030   operands[4] = gen_reg_rtx (DImode);
8031   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8034 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8035   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8036         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8037    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8038    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8039    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8040    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8041   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8042   "#"
8043   ""
8044   [(pc)]
8046   rtx lowword;
8047   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8048                                          operands[3]));
8050   gcc_assert (MEM_P (operands[5]));
8051   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8053   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8054   emit_move_insn (operands[5], operands[4]);
8055   emit_move_insn (operands[0], lowword);
8056   DONE;
8059 (define_expand "fix_trunc<mode>di2"
8060   [(set (match_operand:DI 0 "gpc_reg_operand")
8061         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8062   "TARGET_FLOAT128_TYPE"
8064   if (!TARGET_FLOAT128_HW)
8065     {
8066       rs6000_expand_float128_convert (operands[0], operands[1], false);
8067       DONE;
8068     }
8071 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8072   [(set (match_operand:SDI 0 "gpc_reg_operand")
8073         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8074   "TARGET_FLOAT128_TYPE"
8076   rs6000_expand_float128_convert (operands[0], operands[1], true);
8077   DONE;
8080 (define_expand "floatdi<mode>2"
8081   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8082         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8083   "TARGET_FLOAT128_TYPE"
8085   if (!TARGET_FLOAT128_HW)
8086     {
8087       rs6000_expand_float128_convert (operands[0], operands[1], false);
8088       DONE;
8089     }
8092 (define_expand "floatunsdi<IEEE128:mode>2"
8093   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8094         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8095   "TARGET_FLOAT128_TYPE"
8097   if (!TARGET_FLOAT128_HW)
8098     {
8099       rs6000_expand_float128_convert (operands[0], operands[1], true);
8100       DONE;
8101     }
8104 (define_expand "floatuns<IEEE128:mode>2"
8105   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8106         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8107   "TARGET_FLOAT128_TYPE"
8109   rtx op0 = operands[0];
8110   rtx op1 = operands[1];
8112   if (TARGET_FLOAT128_HW)
8113     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8114   else
8115     rs6000_expand_float128_convert (op0, op1, true);
8116   DONE;
8119 (define_expand "neg<mode>2"
8120   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8121         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8122   "FLOAT128_IEEE_P (<MODE>mode)
8123    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8125   if (FLOAT128_IEEE_P (<MODE>mode))
8126     {
8127       if (TARGET_FLOAT128_HW)
8128         emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8129       else if (TARGET_FLOAT128_TYPE)
8130         emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8131                                              operands[0], operands[1]));
8132       else
8133         {
8134           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8135           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8136                                                 <MODE>mode,
8137                                                 operands[1], <MODE>mode);
8139           if (target && !rtx_equal_p (target, operands[0]))
8140             emit_move_insn (operands[0], target);
8141         }
8142       DONE;
8143     }
8146 (define_insn "neg<mode>2_internal"
8147   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8148         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8149   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8151   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8152     return "fneg %L0,%L1\;fneg %0,%1";
8153   else
8154     return "fneg %0,%1\;fneg %L0,%L1";
8156   [(set_attr "type" "fpsimple")
8157    (set_attr "length" "8")])
8159 (define_expand "abs<mode>2"
8160   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8161         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8162   "FLOAT128_IEEE_P (<MODE>mode)
8163    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8165   rtx label;
8167   if (FLOAT128_IEEE_P (<MODE>mode))
8168     {
8169       if (TARGET_FLOAT128_HW)
8170         {
8171           emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8172           DONE;
8173         }
8174       else if (TARGET_FLOAT128_TYPE)
8175         {
8176           emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8177                                                operands[0], operands[1]));
8178           DONE;
8179         }
8180       else
8181         FAIL;
8182     }
8184   label = gen_label_rtx ();
8185   emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8186   emit_label (label);
8187   DONE;
8190 (define_expand "@abs<mode>2_internal"
8191   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8192         (match_operand:IBM128 1 "gpc_reg_operand"))
8193    (set (match_dup 3) (match_dup 5))
8194    (set (match_dup 5) (abs:DF (match_dup 5)))
8195    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8196    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8197                            (label_ref (match_operand 2 ""))
8198                            (pc)))
8199    (set (match_dup 6) (neg:DF (match_dup 6)))]
8200   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8202   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8203   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8204   operands[3] = gen_reg_rtx (DFmode);
8205   operands[4] = gen_reg_rtx (CCFPmode);
8206   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8207   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8211 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8212 ;; register
8214 (define_expand "ieee_128bit_negative_zero"
8215   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8216   "TARGET_FLOAT128_TYPE"
8218   rtvec v = rtvec_alloc (16);
8219   int i, high;
8221   for (i = 0; i < 16; i++)
8222     RTVEC_ELT (v, i) = const0_rtx;
8224   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8225   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8227   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8228   DONE;
8231 ;; IEEE 128-bit negate
8233 ;; We have 2 insns here for negate and absolute value.  The first uses
8234 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8235 ;; insns, and second insn after the first split pass loads up the bit to
8236 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8237 ;; neg/abs to create the constant just once.
8239 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8240   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8241         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8242    (clobber (match_scratch:V16QI 2 "=v"))]
8243   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8244   "#"
8245   "&& 1"
8246   [(parallel [(set (match_dup 0)
8247                    (neg:IEEE128 (match_dup 1)))
8248               (use (match_dup 2))])]
8250   if (GET_CODE (operands[2]) == SCRATCH)
8251     operands[2] = gen_reg_rtx (V16QImode);
8253   operands[3] = gen_reg_rtx (V16QImode);
8254   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8256   [(set_attr "length" "8")
8257    (set_attr "type" "vecsimple")])
8259 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8260   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8261         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8262    (use (match_operand:V16QI 2 "register_operand" "v"))]
8263   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8264   "xxlxor %x0,%x1,%x2"
8265   [(set_attr "type" "veclogical")])
8267 ;; IEEE 128-bit absolute value
8268 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8269   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8270         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8271    (clobber (match_scratch:V16QI 2 "=v"))]
8272   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8273   "#"
8274   "&& 1"
8275   [(parallel [(set (match_dup 0)
8276                    (abs:IEEE128 (match_dup 1)))
8277               (use (match_dup 2))])]
8279   if (GET_CODE (operands[2]) == SCRATCH)
8280     operands[2] = gen_reg_rtx (V16QImode);
8282   operands[3] = gen_reg_rtx (V16QImode);
8283   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8285   [(set_attr "length" "8")
8286    (set_attr "type" "vecsimple")])
8288 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8289   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8290         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8291    (use (match_operand:V16QI 2 "register_operand" "v"))]
8292   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8293   "xxlandc %x0,%x1,%x2"
8294   [(set_attr "type" "veclogical")])
8296 ;; IEEE 128-bit negative absolute value
8297 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8298   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8299         (neg:IEEE128
8300          (abs:IEEE128
8301           (match_operand:IEEE128 1 "register_operand" "wa"))))
8302    (clobber (match_scratch:V16QI 2 "=v"))]
8303   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8304    && FLOAT128_IEEE_P (<MODE>mode)"
8305   "#"
8306   "&& 1"
8307   [(parallel [(set (match_dup 0)
8308                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8309               (use (match_dup 2))])]
8311   if (GET_CODE (operands[2]) == SCRATCH)
8312     operands[2] = gen_reg_rtx (V16QImode);
8314   operands[3] = gen_reg_rtx (V16QImode);
8315   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8317   [(set_attr "length" "8")
8318    (set_attr "type" "vecsimple")])
8320 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8321   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8322         (neg:IEEE128
8323          (abs:IEEE128
8324           (match_operand:IEEE128 1 "register_operand" "wa"))))
8325    (use (match_operand:V16QI 2 "register_operand" "v"))]
8326   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8327   "xxlor %x0,%x1,%x2"
8328   [(set_attr "type" "veclogical")])
8330 ;; Float128 conversion functions.  These expand to library function calls.
8331 ;; We use expand to convert from IBM double double to IEEE 128-bit
8332 ;; and trunc for the opposite.
8333 (define_expand "extendiftf2"
8334   [(set (match_operand:TF 0 "gpc_reg_operand")
8335         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8336   "TARGET_FLOAT128_TYPE"
8338   rs6000_expand_float128_convert (operands[0], operands[1], false);
8339   DONE;
8342 (define_expand "extendifkf2"
8343   [(set (match_operand:KF 0 "gpc_reg_operand")
8344         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8345   "TARGET_FLOAT128_TYPE"
8347   rs6000_expand_float128_convert (operands[0], operands[1], false);
8348   DONE;
8351 (define_expand "extendtfkf2"
8352   [(set (match_operand:KF 0 "gpc_reg_operand")
8353         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8354   "TARGET_FLOAT128_TYPE"
8356   rs6000_expand_float128_convert (operands[0], operands[1], false);
8357   DONE;
8360 (define_expand "extendtfif2"
8361   [(set (match_operand:IF 0 "gpc_reg_operand")
8362         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8363   "TARGET_FLOAT128_TYPE"
8365   rs6000_expand_float128_convert (operands[0], operands[1], false);
8366   DONE;
8369 (define_expand "trunciftf2"
8370   [(set (match_operand:TF 0 "gpc_reg_operand")
8371         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8372   "TARGET_FLOAT128_TYPE"
8374   rs6000_expand_float128_convert (operands[0], operands[1], false);
8375   DONE;
8378 (define_expand "truncifkf2"
8379   [(set (match_operand:KF 0 "gpc_reg_operand")
8380         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8381   "TARGET_FLOAT128_TYPE"
8383   rs6000_expand_float128_convert (operands[0], operands[1], false);
8384   DONE;
8387 (define_expand "trunckftf2"
8388   [(set (match_operand:TF 0 "gpc_reg_operand")
8389         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8390   "TARGET_FLOAT128_TYPE"
8392   rs6000_expand_float128_convert (operands[0], operands[1], false);
8393   DONE;
8396 (define_expand "trunctfif2"
8397   [(set (match_operand:IF 0 "gpc_reg_operand")
8398         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8399   "TARGET_FLOAT128_TYPE"
8401   rs6000_expand_float128_convert (operands[0], operands[1], false);
8402   DONE;
8405 (define_insn_and_split "*extend<mode>tf2_internal"
8406   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8407         (float_extend:TF
8408          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8409    "TARGET_FLOAT128_TYPE
8410     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8411   "#"
8412   "&& reload_completed"
8413   [(set (match_dup 0) (match_dup 2))]
8415   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8418 (define_insn_and_split "*extendtf<mode>2_internal"
8419   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8420         (float_extend:IFKF
8421          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8422    "TARGET_FLOAT128_TYPE
8423     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8424   "#"
8425   "&& reload_completed"
8426   [(set (match_dup 0) (match_dup 2))]
8428   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8432 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8433 ;; must have 3 arguments, and scratch register constraint must be a single
8434 ;; constraint.
8436 ;; Reload patterns to support gpr load/store with misaligned mem.
8437 ;; and multiple gpr load/store at offset >= 0xfffc
8438 (define_expand "reload_<mode>_store"
8439   [(parallel [(match_operand 0 "memory_operand" "=m")
8440               (match_operand 1 "gpc_reg_operand" "r")
8441               (match_operand:GPR 2 "register_operand" "=&b")])]
8442   ""
8444   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8445   DONE;
8448 (define_expand "reload_<mode>_load"
8449   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8450               (match_operand 1 "memory_operand" "m")
8451               (match_operand:GPR 2 "register_operand" "=b")])]
8452   ""
8454   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8455   DONE;
8459 ;; Reload patterns for various types using the vector registers.  We may need
8460 ;; an additional base register to convert the reg+offset addressing to reg+reg
8461 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8462 ;; index register for gpr registers.
8463 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8464   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8465               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8466               (match_operand:P 2 "register_operand" "=b")])]
8467   "<P:tptrsize>"
8469   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8470   DONE;
8473 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8474   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8475               (match_operand:RELOAD 1 "memory_operand" "m")
8476               (match_operand:P 2 "register_operand" "=b")])]
8477   "<P:tptrsize>"
8479   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8480   DONE;
8484 ;; Reload sometimes tries to move the address to a GPR, and can generate
8485 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8486 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8488 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8489   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8490         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8491                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8492                (const_int -16)))]
8493   "TARGET_ALTIVEC && reload_completed"
8494   "#"
8495   "&& reload_completed"
8496   [(set (match_dup 0)
8497         (plus:P (match_dup 1)
8498                 (match_dup 2)))
8499    (set (match_dup 0)
8500         (and:P (match_dup 0)
8501                (const_int -16)))])
8503 ;; Power8 merge instructions to allow direct move to/from floating point
8504 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8505 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8506 ;; value, since it is allocated in reload and not all of the flow information
8507 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8508 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8509 ;; schedule other instructions between the two instructions.
8511 (define_insn "p8_fmrgow_<mode>"
8512   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8513         (unspec:FMOVE64X [
8514                 (match_operand:DF 1 "register_operand" "d")
8515                 (match_operand:DF 2 "register_operand" "d")]
8516                          UNSPEC_P8V_FMRGOW))]
8517   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8518   "fmrgow %0,%1,%2"
8519   [(set_attr "type" "fpsimple")])
8521 (define_insn "p8_mtvsrwz"
8522   [(set (match_operand:DF 0 "register_operand" "=d")
8523         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8524                    UNSPEC_P8V_MTVSRWZ))]
8525   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8526   "mtvsrwz %x0,%1"
8527   [(set_attr "type" "mftgpr")])
8529 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8530   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8531         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8532                          UNSPEC_P8V_RELOAD_FROM_GPR))
8533    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8534   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8535   "#"
8536   "&& reload_completed"
8537   [(const_int 0)]
8539   rtx dest = operands[0];
8540   rtx src = operands[1];
8541   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8542   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8543   rtx gpr_hi_reg = gen_highpart (SImode, src);
8544   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8546   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8547   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8548   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8549   DONE;
8551   [(set_attr "length" "12")
8552    (set_attr "type" "three")])
8554 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8555 (define_insn "p8_mtvsrd_df"
8556   [(set (match_operand:DF 0 "register_operand" "=wa")
8557         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8558                    UNSPEC_P8V_MTVSRD))]
8559   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8560   "mtvsrd %x0,%1"
8561   [(set_attr "type" "mftgpr")])
8563 (define_insn "p8_xxpermdi_<mode>"
8564   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8565         (unspec:FMOVE128_GPR [
8566                 (match_operand:DF 1 "register_operand" "wa")
8567                 (match_operand:DF 2 "register_operand" "wa")]
8568                 UNSPEC_P8V_XXPERMDI))]
8569   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8570   "xxpermdi %x0,%x1,%x2,0"
8571   [(set_attr "type" "vecperm")])
8573 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8574   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8575         (unspec:FMOVE128_GPR
8576          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8577          UNSPEC_P8V_RELOAD_FROM_GPR))
8578    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8579   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8580   "#"
8581   "&& reload_completed"
8582   [(const_int 0)]
8584   rtx dest = operands[0];
8585   rtx src = operands[1];
8586   /* You might think that we could use op0 as one temp and a DF clobber
8587      as op2, but you'd be wrong.  Secondary reload move patterns don't
8588      check for overlap of the clobber and the destination.  */
8589   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8590   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8591   rtx gpr_hi_reg = gen_highpart (DImode, src);
8592   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8594   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8595   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8596   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8597   DONE;
8599   [(set_attr "length" "12")
8600    (set_attr "type" "three")])
8602 (define_split
8603   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8604         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8605   "reload_completed
8606    && (int_reg_operand (operands[0], <MODE>mode)
8607        || int_reg_operand (operands[1], <MODE>mode))
8608    && (!TARGET_DIRECT_MOVE_128
8609        || (!vsx_register_operand (operands[0], <MODE>mode)
8610            && !vsx_register_operand (operands[1], <MODE>mode)))"
8611   [(pc)]
8613   rs6000_split_multireg_move (operands[0], operands[1]);
8614   DONE;
8617 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8618 ;; type is stored internally as double precision in the VSX registers, we have
8619 ;; to convert it from the vector format.
8620 (define_insn "p8_mtvsrd_sf"
8621   [(set (match_operand:SF 0 "register_operand" "=wa")
8622         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8623                    UNSPEC_P8V_MTVSRD))]
8624   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8625   "mtvsrd %x0,%1"
8626   [(set_attr "type" "mftgpr")])
8628 (define_insn_and_split "reload_vsx_from_gprsf"
8629   [(set (match_operand:SF 0 "register_operand" "=wa")
8630         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8631                    UNSPEC_P8V_RELOAD_FROM_GPR))
8632    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8633   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8634   "#"
8635   "&& reload_completed"
8636   [(const_int 0)]
8638   rtx op0 = operands[0];
8639   rtx op1 = operands[1];
8640   rtx op2 = operands[2];
8641   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8643   /* Move SF value to upper 32-bits for xscvspdpn.  */
8644   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8645   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8646   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8647   DONE;
8649   [(set_attr "length" "8")
8650    (set_attr "type" "two")])
8652 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8653 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8654 ;; and then doing a move of that.
8655 (define_insn "p8_mfvsrd_3_<mode>"
8656   [(set (match_operand:DF 0 "register_operand" "=r")
8657         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8658                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8659   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8660   "mfvsrd %0,%x1"
8661   [(set_attr "type" "mftgpr")])
8663 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8664   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8665         (unspec:FMOVE128_GPR
8666          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8667          UNSPEC_P8V_RELOAD_FROM_VSX))
8668    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8669   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8670   "#"
8671   "&& reload_completed"
8672   [(const_int 0)]
8674   rtx dest = operands[0];
8675   rtx src = operands[1];
8676   rtx tmp = operands[2];
8677   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8678   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8680   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8681   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8682   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8683   DONE;
8685   [(set_attr "length" "12")
8686    (set_attr "type" "three")])
8688 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8689 ;; type is stored internally as double precision, we have to convert it to the
8690 ;; vector format.
8692 (define_insn_and_split "reload_gpr_from_vsxsf"
8693   [(set (match_operand:SF 0 "register_operand" "=r")
8694         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8695                    UNSPEC_P8V_RELOAD_FROM_VSX))
8696    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8697   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8698   "#"
8699   "&& reload_completed"
8700   [(const_int 0)]
8702   rtx op0 = operands[0];
8703   rtx op1 = operands[1];
8704   rtx op2 = operands[2];
8705   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8706   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8708   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8709   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8710   DONE;
8712   [(set_attr "length" "8")
8713    (set_attr "type" "two")
8714    (set_attr "isa" "p8v")])
8716 ;; Next come the multi-word integer load and store and the load and store
8717 ;; multiple insns.
8719 ;; List r->r after r->Y, otherwise reload will try to reload a
8720 ;; non-offsettable address by using r->r which won't make progress.
8721 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8722 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8724 ;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8725 ;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8726 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8727 ;;        AVX const  
8729 (define_insn "*movdi_internal32"
8730   [(set (match_operand:DI 0 "nonimmediate_operand"
8731          "=Y,        r,         r,         m,         ^d,        ^d,
8732           r,         wY,        Z,         ^v,        $v,        ^wa,
8733           wa,        wa,        v,         wa,        *i,        v,
8734           v")
8735         (match_operand:DI 1 "input_operand"
8736          "r,         Y,         r,         ^d,        m,         ^d,
8737           IJKnF,     ^v,        $v,        wY,        Z,         ^wa,
8738           Oj,        wM,        OjwM,      Oj,        wM,        wS,
8739           wB"))]
8740   "! TARGET_POWERPC64
8741    && (gpc_reg_operand (operands[0], DImode)
8742        || gpc_reg_operand (operands[1], DImode))"
8743   "@
8744    #
8745    #
8746    #
8747    stfd%U0%X0 %1,%0
8748    lfd%U1%X1 %0,%1
8749    fmr %0,%1
8750    #
8751    stxsd %1,%0
8752    stxsdx %x1,%y0
8753    lxsd %0,%1
8754    lxsdx %x0,%y1
8755    xxlor %x0,%x1,%x1
8756    xxspltib %x0,0
8757    xxspltib %x0,255
8758    vspltisw %0,%1
8759    xxlxor %x0,%x0,%x0
8760    xxlorc %x0,%x0,%x0
8761    #
8762    #"
8763   [(set_attr "type"
8764          "store,     load,      *,         fpstore,   fpload,    fpsimple,
8765           *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8766           vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8767           vecsimple")
8768    (set_attr "size" "64")
8769    (set_attr "length"
8770          "8,         8,         8,         *,         *,         *,
8771           16,        *,         *,         *,         *,         *,
8772           *,         *,         *,         *,         *,         8,
8773           *")
8774    (set_attr "isa"
8775          "*,         *,         *,         *,         *,         *,
8776           *,         p9v,       p7v,       p9v,       p7v,       *,
8777           p9v,       p9v,       p7v,       *,         *,         p7v,
8778           p7v")])
8780 (define_split
8781   [(set (match_operand:DI 0 "gpc_reg_operand")
8782         (match_operand:DI 1 "const_int_operand"))]
8783   "! TARGET_POWERPC64 && reload_completed
8784    && gpr_or_gpr_p (operands[0], operands[1])
8785    && !direct_move_p (operands[0], operands[1])"
8786   [(set (match_dup 2) (match_dup 4))
8787    (set (match_dup 3) (match_dup 1))]
8789   HOST_WIDE_INT value = INTVAL (operands[1]);
8790   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8791                                        DImode);
8792   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8793                                        DImode);
8794   operands[4] = GEN_INT (value >> 32);
8795   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8798 (define_split
8799   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8800         (match_operand:DIFD 1 "input_operand"))]
8801   "reload_completed && !TARGET_POWERPC64
8802    && gpr_or_gpr_p (operands[0], operands[1])
8803    && !direct_move_p (operands[0], operands[1])"
8804   [(pc)]
8806   rs6000_split_multireg_move (operands[0], operands[1]);
8807   DONE;
8810 ;;              GPR store  GPR load   GPR move   GPR li     GPR lis     GPR #
8811 ;;              FPR store  FPR load   FPR move   AVX store  AVX store   AVX load
8812 ;;              AVX load   VSX move   P9 0       P9 -1      AVX 0/-1    VSX 0
8813 ;;              VSX -1     P9 const   AVX const  From SPR   To SPR      SPR<->SPR
8814 ;;              VSX->GPR   GPR->VSX
8815 (define_insn "*movdi_internal64"
8816   [(set (match_operand:DI 0 "nonimmediate_operand"
8817                "=YZ,       r,         r,         r,         r,          r,
8818                 m,         ^d,        ^d,        wY,        Z,          $v,
8819                 $v,        ^wa,       wa,        wa,        v,          wa,
8820                 wa,        v,         v,         r,         *h,         *h,
8821                 ?r,        ?wa")
8822         (match_operand:DI 1 "input_operand"
8823                "r,         YZ,        r,         I,         L,          nF,
8824                 ^d,        m,         ^d,        ^v,        $v,         wY,
8825                 Z,         ^wa,       Oj,        wM,        OjwM,       Oj,
8826                 wM,        wS,        wB,        *h,        r,          0,
8827                 wa,        r"))]
8828   "TARGET_POWERPC64
8829    && (gpc_reg_operand (operands[0], DImode)
8830        || gpc_reg_operand (operands[1], DImode))"
8831   "@
8832    std%U0%X0 %1,%0
8833    ld%U1%X1 %0,%1
8834    mr %0,%1
8835    li %0,%1
8836    lis %0,%v1
8837    #
8838    stfd%U0%X0 %1,%0
8839    lfd%U1%X1 %0,%1
8840    fmr %0,%1
8841    stxsd %1,%0
8842    stxsdx %x1,%y0
8843    lxsd %0,%1
8844    lxsdx %x0,%y1
8845    xxlor %x0,%x1,%x1
8846    xxspltib %x0,0
8847    xxspltib %x0,255
8848    #
8849    xxlxor %x0,%x0,%x0
8850    xxlorc %x0,%x0,%x0
8851    #
8852    #
8853    mf%1 %0
8854    mt%0 %1
8855    nop
8856    mfvsrd %0,%x1
8857    mtvsrd %x0,%1"
8858   [(set_attr "type"
8859                "store,      load,       *,         *,         *,         *,
8860                 fpstore,    fpload,     fpsimple,  fpstore,   fpstore,   fpload,
8861                 fpload,     veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8862                 veclogical, vecsimple,  vecsimple, mfjmpr,    mtjmpr,    *,
8863                 mftgpr,    mffgpr")
8864    (set_attr "size" "64")
8865    (set_attr "length"
8866                "*,         *,         *,         *,         *,          20,
8867                 *,         *,         *,         *,         *,          *,
8868                 *,         *,         *,         *,         *,          *,
8869                 *,         8,         *,         *,         *,          *,
8870                 *,         *")
8871    (set_attr "isa"
8872                "*,         *,         *,         *,         *,          *,
8873                 *,         *,         *,         p9v,       p7v,        p9v,
8874                 p7v,       *,         p9v,       p9v,       p7v,        *,
8875                 *,         p7v,       p7v,       *,         *,          *,
8876                 p8v,       p8v")])
8878 ; Some DImode loads are best done as a load of -1 followed by a mask
8879 ; instruction.
8880 (define_split
8881   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8882         (match_operand:DI 1 "const_int_operand"))]
8883   "TARGET_POWERPC64
8884    && num_insns_constant (operands[1], DImode) > 1
8885    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8886    && rs6000_is_valid_and_mask (operands[1], DImode)"
8887   [(set (match_dup 0)
8888         (const_int -1))
8889    (set (match_dup 0)
8890         (and:DI (match_dup 0)
8891                 (match_dup 1)))]
8892   "")
8894 ;; Split a load of a large constant into the appropriate five-instruction
8895 ;; sequence.  Handle anything in a constant number of insns.
8896 ;; When non-easy constants can go in the TOC, this should use
8897 ;; easy_fp_constant predicate.
8898 (define_split
8899   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8900         (match_operand:DI 1 "const_int_operand"))]
8901   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8902   [(set (match_dup 0) (match_dup 2))
8903    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8905   if (rs6000_emit_set_const (operands[0], operands[1]))
8906     DONE;
8907   else
8908     FAIL;
8911 (define_split
8912   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8913         (match_operand:DI 1 "const_scalar_int_operand"))]
8914   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8915   [(set (match_dup 0) (match_dup 2))
8916    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8918   if (rs6000_emit_set_const (operands[0], operands[1]))
8919     DONE;
8920   else
8921     FAIL;
8924 (define_split
8925   [(set (match_operand:DI 0 "altivec_register_operand")
8926         (match_operand:DI 1 "s5bit_cint_operand"))]
8927   "TARGET_VSX && reload_completed"
8928   [(const_int 0)]
8930   rtx op0 = operands[0];
8931   rtx op1 = operands[1];
8932   int r = REGNO (op0);
8933   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8935   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8936   if (op1 != const0_rtx && op1 != constm1_rtx)
8937     {
8938       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8939       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8940     }
8941   DONE;
8944 ;; Split integer constants that can be loaded with XXSPLTIB and a
8945 ;; sign extend operation.
8946 (define_split
8947   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8948         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8949   "TARGET_P9_VECTOR && reload_completed"
8950   [(const_int 0)]
8952   rtx op0 = operands[0];
8953   rtx op1 = operands[1];
8954   int r = REGNO (op0);
8955   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8957   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8958   if (<MODE>mode == DImode)
8959     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8960   else if (<MODE>mode == SImode)
8961     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8962   else if (<MODE>mode == HImode)
8963     {
8964       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8965       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8966     }
8967   DONE;
8971 ;; TImode/PTImode is similar, except that we usually want to compute the
8972 ;; address into a register and use lsi/stsi (the exception is during reload).
8974 (define_insn "*mov<mode>_string"
8975   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8976         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8977   "! TARGET_POWERPC64
8978    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8979    && (gpc_reg_operand (operands[0], <MODE>mode)
8980        || gpc_reg_operand (operands[1], <MODE>mode))"
8981   "#"
8982   [(set_attr "type" "store,store,load,load,*,*")
8983    (set_attr "update" "yes")
8984    (set_attr "indexed" "yes")
8985    (set_attr "cell_micro" "conditional")])
8987 (define_insn "*mov<mode>_ppc64"
8988   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8989         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8990   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8991    && (gpc_reg_operand (operands[0], <MODE>mode)
8992        || gpc_reg_operand (operands[1], <MODE>mode)))"
8994   return rs6000_output_move_128bit (operands);
8996   [(set_attr "type" "store,store,load,load,*,*")
8997    (set_attr "length" "8")
8998    (set_attr "max_prefixed_insns" "2")])
9000 (define_split
9001   [(set (match_operand:TI2 0 "int_reg_operand")
9002         (match_operand:TI2 1 "const_scalar_int_operand"))]
9003   "TARGET_POWERPC64
9004    && (VECTOR_MEM_NONE_P (<MODE>mode)
9005        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9006   [(set (match_dup 2) (match_dup 4))
9007    (set (match_dup 3) (match_dup 5))]
9009   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9010                                        <MODE>mode);
9011   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9012                                        <MODE>mode);
9013   if (CONST_WIDE_INT_P (operands[1]))
9014     {
9015       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9016       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9017     }
9018   else if (CONST_INT_P (operands[1]))
9019     {
9020       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9021       operands[5] = operands[1];
9022     }
9023   else
9024     FAIL;
9027 (define_split
9028   [(set (match_operand:TI2 0 "nonimmediate_operand")
9029         (match_operand:TI2 1 "input_operand"))]
9030   "reload_completed
9031    && gpr_or_gpr_p (operands[0], operands[1])
9032    && !direct_move_p (operands[0], operands[1])
9033    && !quad_load_store_p (operands[0], operands[1])"
9034   [(pc)]
9036   rs6000_split_multireg_move (operands[0], operands[1]);
9037   DONE;
9040 (define_expand "setmemsi"
9041   [(parallel [(set (match_operand:BLK 0 "")
9042                    (match_operand 2 "const_int_operand"))
9043               (use (match_operand:SI 1 ""))
9044               (use (match_operand:SI 3 ""))])]
9045   ""
9047   /* If value to set is not zero, use the library routine.  */
9048   if (operands[2] != const0_rtx)
9049     FAIL;
9051   if (expand_block_clear (operands))
9052     DONE;
9053   else
9054     FAIL;
9057 ;; String compare N insn.
9058 ;; Argument 0 is the target (result)
9059 ;; Argument 1 is the destination
9060 ;; Argument 2 is the source
9061 ;; Argument 3 is the length
9062 ;; Argument 4 is the alignment
9064 (define_expand "cmpstrnsi"
9065   [(parallel [(set (match_operand:SI 0)
9066                (compare:SI (match_operand:BLK 1)
9067                            (match_operand:BLK 2)))
9068               (use (match_operand:SI 3))
9069               (use (match_operand:SI 4))])]
9070   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9072   if (optimize_insn_for_size_p ())
9073     FAIL;
9075   if (expand_strn_compare (operands, 0))
9076     DONE;
9077   else  
9078     FAIL;
9081 ;; String compare insn.
9082 ;; Argument 0 is the target (result)
9083 ;; Argument 1 is the destination
9084 ;; Argument 2 is the source
9085 ;; Argument 3 is the alignment
9087 (define_expand "cmpstrsi"
9088   [(parallel [(set (match_operand:SI 0)
9089                (compare:SI (match_operand:BLK 1)
9090                            (match_operand:BLK 2)))
9091               (use (match_operand:SI 3))])]
9092   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9094   if (optimize_insn_for_size_p ())
9095     FAIL;
9097   if (expand_strn_compare (operands, 1))
9098     DONE;
9099   else  
9100     FAIL;
9103 ;; Block compare insn.
9104 ;; Argument 0 is the target (result)
9105 ;; Argument 1 is the destination
9106 ;; Argument 2 is the source
9107 ;; Argument 3 is the length
9108 ;; Argument 4 is the alignment
9110 (define_expand "cmpmemsi"
9111   [(parallel [(set (match_operand:SI 0)
9112                (compare:SI (match_operand:BLK 1)
9113                            (match_operand:BLK 2)))
9114               (use (match_operand:SI 3))
9115               (use (match_operand:SI 4))])]
9116   "TARGET_POPCNTD"
9118   if (expand_block_compare (operands))
9119     DONE;
9120   else
9121     FAIL;
9124 ;; String/block copy insn (source and destination must not overlap).
9125 ;; Argument 0 is the destination
9126 ;; Argument 1 is the source
9127 ;; Argument 2 is the length
9128 ;; Argument 3 is the alignment
9130 (define_expand "cpymemsi"
9131   [(parallel [(set (match_operand:BLK 0 "")
9132                    (match_operand:BLK 1 ""))
9133               (use (match_operand:SI 2 ""))
9134               (use (match_operand:SI 3 ""))])]
9135   ""
9137   if (expand_block_move (operands, false))
9138     DONE;
9139   else
9140     FAIL;
9143 ;; String/block move insn (source and destination may overlap).
9144 ;; Argument 0 is the destination
9145 ;; Argument 1 is the source
9146 ;; Argument 2 is the length
9147 ;; Argument 3 is the alignment
9149 (define_expand "movmemsi"
9150   [(parallel [(set (match_operand:BLK 0 "")
9151                    (match_operand:BLK 1 ""))
9152               (use (match_operand:SI 2 ""))
9153               (use (match_operand:SI 3 ""))])]
9154   ""
9156   if (expand_block_move (operands, true))
9157     DONE;
9158   else
9159     FAIL;
9163 ;; Define insns that do load or store with update.  Some of these we can
9164 ;; get by using pre-decrement or pre-increment, but the hardware can also
9165 ;; do cases where the increment is not the size of the object.
9167 ;; In all these cases, we use operands 0 and 1 for the register being
9168 ;; incremented because those are the operands that local-alloc will
9169 ;; tie and these are the pair most likely to be tieable (and the ones
9170 ;; that will benefit the most).
9172 (define_insn "*movdi_update1"
9173   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9174         (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9175                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9176    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9177         (plus:P (match_dup 1) (match_dup 2)))]
9178   "TARGET_POWERPC64 && TARGET_UPDATE
9179    && (!avoiding_indexed_address_p (DImode)
9180        || !gpc_reg_operand (operands[2], Pmode))"
9181   "@
9182    ldux %3,%0,%2
9183    ldu %3,%2(%0)"
9184   [(set_attr "type" "load")
9185    (set_attr "update" "yes")
9186    (set_attr "indexed" "yes,no")])
9188 (define_insn "movdi_<mode>_update"
9189   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9190                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9191         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9192    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9193         (plus:P (match_dup 1) (match_dup 2)))]
9194   "TARGET_POWERPC64 && TARGET_UPDATE
9195    && (!avoiding_indexed_address_p (DImode)
9196        || !gpc_reg_operand (operands[2], Pmode)
9197        || (REG_P (operands[0])
9198            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9199   "@
9200    stdux %3,%0,%2
9201    stdu %3,%2(%0)"
9202   [(set_attr "type" "store")
9203    (set_attr "update" "yes")
9204    (set_attr "indexed" "yes,no")])
9206 ;; This pattern is only conditional on TARGET_64BIT, as it is
9207 ;; needed for stack allocation, even if the user passes -mno-update.
9208 (define_insn "movdi_update_stack"
9209   [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9210                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9211         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9212    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9213         (plus:DI (match_dup 1) (match_dup 2)))]
9214   "TARGET_64BIT"
9215   "@
9216    stdux %3,%0,%2
9217    stdu %3,%2(%0)"
9218   [(set_attr "type" "store")
9219    (set_attr "update" "yes")
9220    (set_attr "indexed" "yes,no")])
9222 (define_insn "*movsi_update1"
9223   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9224         (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9225                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9226    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9227         (plus:P (match_dup 1) (match_dup 2)))]
9228   "TARGET_UPDATE
9229    && (!avoiding_indexed_address_p (SImode)
9230        || !gpc_reg_operand (operands[2], Pmode))"
9231   "@
9232    lwzux %3,%0,%2
9233    lwzu %3,%2(%0)"
9234   [(set_attr "type" "load")
9235    (set_attr "update" "yes")
9236    (set_attr "indexed" "yes,no")])
9238 (define_insn "*movsi_update2"
9239   [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9240         (sign_extend:EXTSI
9241          (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9242                          (match_operand:P 2 "gpc_reg_operand" "r")))))
9243    (set (match_operand:P 0 "gpc_reg_operand" "=b")
9244         (plus:P (match_dup 1) (match_dup 2)))]
9245   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9246   "lwaux %3,%0,%2"
9247   [(set_attr "type" "load")
9248    (set_attr "sign_extend" "yes")
9249    (set_attr "update" "yes")
9250    (set_attr "indexed" "yes")])
9252 (define_insn "movsi_<mode>_update"
9253   [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9254                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9255         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9256    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9257         (plus:P (match_dup 1) (match_dup 2)))]
9258   "TARGET_UPDATE
9259    && (!avoiding_indexed_address_p (SImode)
9260        || !gpc_reg_operand (operands[2], Pmode)
9261        || (REG_P (operands[0])
9262            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9263   "@
9264    stwux %3,%0,%2
9265    stwu %3,%2(%0)"
9266   [(set_attr "type" "store")
9267    (set_attr "update" "yes")
9268    (set_attr "indexed" "yes,no")])
9270 ;; This is an unconditional pattern; needed for stack allocation, even
9271 ;; if the user passes -mno-update.
9272 (define_insn "movsi_update_stack"
9273   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9274                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9275         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9276    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9277         (plus:SI (match_dup 1) (match_dup 2)))]
9278   "TARGET_32BIT"
9279   "@
9280    stwux %3,%0,%2
9281    stwu %3,%2(%0)"
9282   [(set_attr "type" "store")
9283    (set_attr "update" "yes")
9284    (set_attr "indexed" "yes,no")])
9286 (define_insn "*movhi_update1"
9287   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9288         (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9289                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9290    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9291         (plus:P (match_dup 1) (match_dup 2)))]
9292   "TARGET_UPDATE
9293    && (!avoiding_indexed_address_p (HImode)
9294        || !gpc_reg_operand (operands[2], SImode))"
9295   "@
9296    lhzux %3,%0,%2
9297    lhzu %3,%2(%0)"
9298   [(set_attr "type" "load")
9299    (set_attr "update" "yes")
9300    (set_attr "indexed" "yes,no")])
9302 (define_insn "*movhi_update2"
9303   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9304         (zero_extend:EXTHI
9305          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9306                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9307    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9308         (plus:P (match_dup 1) (match_dup 2)))]
9309   "TARGET_UPDATE
9310    && (!avoiding_indexed_address_p (HImode)
9311        || !gpc_reg_operand (operands[2], Pmode))"
9312   "@
9313    lhzux %3,%0,%2
9314    lhzu %3,%2(%0)"
9315   [(set_attr "type" "load")
9316    (set_attr "update" "yes")
9317    (set_attr "indexed" "yes,no")])
9319 (define_insn "*movhi_update3"
9320   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9321         (sign_extend:EXTHI
9322          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9323                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9324    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9325         (plus:P (match_dup 1) (match_dup 2)))]
9326   "TARGET_UPDATE
9327    && !(avoiding_indexed_address_p (HImode)
9328         && gpc_reg_operand (operands[2], Pmode))"
9329   "@
9330    lhaux %3,%0,%2
9331    lhau %3,%2(%0)"
9332   [(set_attr "type" "load")
9333    (set_attr "sign_extend" "yes")
9334    (set_attr "update" "yes")
9335    (set_attr "indexed" "yes,no")])
9337 (define_insn "*movhi_update4"
9338   [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9339                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9340         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9341    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9342         (plus:P (match_dup 1) (match_dup 2)))]
9343   "TARGET_UPDATE
9344    && (!avoiding_indexed_address_p (HImode)
9345        || !gpc_reg_operand (operands[2], Pmode))"
9346   "@
9347    sthux %3,%0,%2
9348    sthu %3,%2(%0)"
9349   [(set_attr "type" "store")
9350    (set_attr "update" "yes")
9351    (set_attr "indexed" "yes,no")])
9353 (define_insn "*movqi_update1"
9354   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9355         (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9356                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9357    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9358         (plus:P (match_dup 1) (match_dup 2)))]
9359   "TARGET_UPDATE
9360    && (!avoiding_indexed_address_p (QImode)
9361        || !gpc_reg_operand (operands[2], Pmode))"
9362   "@
9363    lbzux %3,%0,%2
9364    lbzu %3,%2(%0)"
9365   [(set_attr "type" "load")
9366    (set_attr "update" "yes")
9367    (set_attr "indexed" "yes,no")])
9369 (define_insn "*movqi_update2"
9370   [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9371         (zero_extend:EXTQI
9372          (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9373                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9374    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9375         (plus:P (match_dup 1) (match_dup 2)))]
9376   "TARGET_UPDATE
9377    && (!avoiding_indexed_address_p (QImode)
9378        || !gpc_reg_operand (operands[2], Pmode))"
9379   "@
9380    lbzux %3,%0,%2
9381    lbzu %3,%2(%0)"
9382   [(set_attr "type" "load")
9383    (set_attr "update" "yes")
9384    (set_attr "indexed" "yes,no")])
9386 (define_insn "*movqi_update3"
9387   [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9388                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9389         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9390    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9391         (plus:P (match_dup 1) (match_dup 2)))]
9392   "TARGET_UPDATE
9393    && (!avoiding_indexed_address_p (QImode)
9394        || !gpc_reg_operand (operands[2], Pmode))"
9395   "@
9396    stbux %3,%0,%2
9397    stbu %3,%2(%0)"
9398   [(set_attr "type" "store")
9399    (set_attr "update" "yes")
9400    (set_attr "indexed" "yes,no")])
9402 (define_insn "*mov<SFDF:mode>_update1"
9403   [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9404         (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9405                           (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9406    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9407         (plus:P (match_dup 1) (match_dup 2)))]
9408   "TARGET_HARD_FLOAT && TARGET_UPDATE
9409    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9410        || !gpc_reg_operand (operands[2], Pmode))"
9411   "@
9412    lf<sd>ux %3,%0,%2
9413    lf<sd>u %3,%2(%0)"
9414   [(set_attr "type" "fpload")
9415    (set_attr "update" "yes")
9416    (set_attr "indexed" "yes,no")
9417    (set_attr "size" "<SFDF:bits>")])
9419 (define_insn "*mov<SFDF:mode>_update2"
9420   [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9421                           (match_operand:P 2 "reg_or_short_operand" "r,I")))
9422         (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9423    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9424         (plus:P (match_dup 1) (match_dup 2)))]
9425   "TARGET_HARD_FLOAT && TARGET_UPDATE
9426    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9427        || !gpc_reg_operand (operands[2], Pmode))"
9428   "@
9429    stf<sd>ux %3,%0,%2
9430    stf<sd>u %3,%2(%0)"
9431   [(set_attr "type" "fpstore")
9432    (set_attr "update" "yes")
9433    (set_attr "indexed" "yes,no")
9434    (set_attr "size" "<SFDF:bits>")])
9436 (define_insn "*movsf_update3"
9437   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9438         (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9439                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9440    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9441         (plus:P (match_dup 1) (match_dup 2)))]
9442   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9443    && (!avoiding_indexed_address_p (SFmode)
9444        || !gpc_reg_operand (operands[2], Pmode))"
9445   "@
9446    lwzux %3,%0,%2
9447    lwzu %3,%2(%0)"
9448   [(set_attr "type" "load")
9449    (set_attr "update" "yes")
9450    (set_attr "indexed" "yes,no")])
9452 (define_insn "*movsf_update4"
9453   [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9454                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9455         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9456    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9457         (plus:P (match_dup 1) (match_dup 2)))]
9458   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9459    && (!avoiding_indexed_address_p (SFmode)
9460        || !gpc_reg_operand (operands[2], Pmode))"
9461   "@
9462    stwux %3,%0,%2
9463    stwu %3,%2(%0)"
9464   [(set_attr "type" "store")
9465    (set_attr "update" "yes")
9466    (set_attr "indexed" "yes,no")])
9469 ;; After inserting conditional returns we can sometimes have
9470 ;; unnecessary register moves.  Unfortunately we cannot have a
9471 ;; modeless peephole here, because some single SImode sets have early
9472 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9473 ;; sequences, using get_attr_length here will smash the operands
9474 ;; array.  Neither is there an early_cobbler_p predicate.
9475 ;; Also this optimization interferes with scalars going into
9476 ;; altivec registers (the code does reloading through the FPRs).
9477 (define_peephole2
9478   [(set (match_operand:DF 0 "gpc_reg_operand")
9479         (match_operand:DF 1 "any_operand"))
9480    (set (match_operand:DF 2 "gpc_reg_operand")
9481         (match_dup 0))]
9482   "!TARGET_VSX
9483    && peep2_reg_dead_p (2, operands[0])"
9484   [(set (match_dup 2) (match_dup 1))])
9486 (define_peephole2
9487   [(set (match_operand:SF 0 "gpc_reg_operand")
9488         (match_operand:SF 1 "any_operand"))
9489    (set (match_operand:SF 2 "gpc_reg_operand")
9490         (match_dup 0))]
9491   "!TARGET_P8_VECTOR
9492    && peep2_reg_dead_p (2, operands[0])"
9493   [(set (match_dup 2) (match_dup 1))])
9496 ;; TLS support.
9498 (define_insn_and_split "*tls_gd<bits>"
9499   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9500         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9501                    (match_operand:P 2 "gpc_reg_operand" "b")]
9502                   UNSPEC_TLSGD))]
9503   "HAVE_AS_TLS && TARGET_ELF"
9504   "addi %0,%2,%1@got@tlsgd"
9505   "&& TARGET_CMODEL != CMODEL_SMALL"
9506   [(set (match_dup 3)
9507         (high:P
9508             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9509    (set (match_dup 0)
9510         (lo_sum:P (match_dup 3)
9511             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9513   operands[3] = gen_reg_rtx (<MODE>mode);
9515   [(set (attr "length")
9516      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9517                    (const_int 8)
9518                    (const_int 4)))])
9520 (define_insn "*tls_gd_high<bits>"
9521   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9522      (high:P
9523        (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9524                   (match_operand:P 2 "gpc_reg_operand" "b")]
9525                  UNSPEC_TLSGD)))]
9526   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9527   "addis %0,%2,%1@got@tlsgd@ha")
9529 (define_insn "*tls_gd_low<bits>"
9530   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9531      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9532        (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9533                   (match_operand:P 3 "gpc_reg_operand" "b")]
9534                  UNSPEC_TLSGD)))]
9535   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9536   "addi %0,%1,%2@got@tlsgd@l")
9538 (define_insn_and_split "*tls_ld<bits>"
9539   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9540         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9541                   UNSPEC_TLSLD))]
9542   "HAVE_AS_TLS && TARGET_ELF"
9543   "addi %0,%1,%&@got@tlsld"
9544   "&& TARGET_CMODEL != CMODEL_SMALL"
9545   [(set (match_dup 2)
9546         (high:P
9547             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9548    (set (match_dup 0)
9549         (lo_sum:P (match_dup 2)
9550             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9552   operands[2] = gen_reg_rtx (<MODE>mode);
9554   [(set (attr "length")
9555      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9556                    (const_int 8)
9557                    (const_int 4)))])
9559 (define_insn "*tls_ld_high<bits>"
9560   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9561      (high:P
9562        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9563                  UNSPEC_TLSLD)))]
9564   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9565   "addis %0,%1,%&@got@tlsld@ha")
9567 (define_insn "*tls_ld_low<bits>"
9568   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9569      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9570        (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9571                  UNSPEC_TLSLD)))]
9572   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9573   "addi %0,%1,%&@got@tlsld@l")
9575 (define_insn "tls_dtprel_<bits>"
9576   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9577         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9578                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9579                   UNSPEC_TLSDTPREL))]
9580   "HAVE_AS_TLS"
9581   "addi %0,%1,%2@dtprel")
9583 (define_insn "tls_dtprel_ha_<bits>"
9584   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9585         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9586                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9587                   UNSPEC_TLSDTPRELHA))]
9588   "HAVE_AS_TLS"
9589   "addis %0,%1,%2@dtprel@ha")
9591 (define_insn "tls_dtprel_lo_<bits>"
9592   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9593         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9594                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9595                   UNSPEC_TLSDTPRELLO))]
9596   "HAVE_AS_TLS"
9597   "addi %0,%1,%2@dtprel@l")
9599 (define_insn_and_split "tls_got_dtprel_<bits>"
9600   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9601         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9602                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9603                   UNSPEC_TLSGOTDTPREL))]
9604   "HAVE_AS_TLS"
9605   "<ptrload> %0,%2@got@dtprel(%1)"
9606   "&& TARGET_CMODEL != CMODEL_SMALL"
9607   [(set (match_dup 3)
9608         (high:P
9609             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9610    (set (match_dup 0)
9611         (lo_sum:P (match_dup 3)
9612             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9614   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9616   [(set (attr "length")
9617      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9618                    (const_int 8)
9619                    (const_int 4)))])
9621 (define_insn "*tls_got_dtprel_high<bits>"
9622   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9623      (high:P
9624        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9625                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9626                  UNSPEC_TLSGOTDTPREL)))]
9627   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9628   "addis %0,%1,%2@got@dtprel@ha")
9630 (define_insn "*tls_got_dtprel_low<bits>"
9631   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9632      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9633          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9634                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9635                    UNSPEC_TLSGOTDTPREL)))]
9636   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9637   "<ptrload> %0,%2@got@dtprel@l(%1)")
9639 (define_insn "tls_tprel_<bits>"
9640   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9641         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9642                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9643                   UNSPEC_TLSTPREL))]
9644   "HAVE_AS_TLS"
9645   "addi %0,%1,%2@tprel")
9647 (define_insn "tls_tprel_ha_<bits>"
9648   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9649         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9650                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9651                   UNSPEC_TLSTPRELHA))]
9652   "HAVE_AS_TLS"
9653   "addis %0,%1,%2@tprel@ha")
9655 (define_insn "tls_tprel_lo_<bits>"
9656   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9657         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9658                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9659                   UNSPEC_TLSTPRELLO))]
9660   "HAVE_AS_TLS"
9661   "addi %0,%1,%2@tprel@l")
9663 ;; "b" output constraint here and on tls_tls input to support linker tls
9664 ;; optimization.  The linker may edit the instructions emitted by a
9665 ;; tls_got_tprel/tls_tls pair to addis,addi.
9666 (define_insn_and_split "tls_got_tprel_<bits>"
9667   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9668         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9669                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9670                   UNSPEC_TLSGOTTPREL))]
9671   "HAVE_AS_TLS"
9672   "<ptrload> %0,%2@got@tprel(%1)"
9673   "&& TARGET_CMODEL != CMODEL_SMALL"
9674   [(set (match_dup 3)
9675         (high:P
9676             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9677    (set (match_dup 0)
9678         (lo_sum:P (match_dup 3)
9679             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9681   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9683   [(set (attr "length")
9684      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9685                    (const_int 8)
9686                    (const_int 4)))])
9688 (define_insn "*tls_got_tprel_high<bits>"
9689   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9690      (high:P
9691        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9692                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9693                  UNSPEC_TLSGOTTPREL)))]
9694   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9695   "addis %0,%1,%2@got@tprel@ha")
9697 (define_insn "*tls_got_tprel_low<bits>"
9698   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9699      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9700          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9701                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9702                    UNSPEC_TLSGOTTPREL)))]
9703   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9704   "<ptrload> %0,%2@got@tprel@l(%1)")
9706 (define_insn "tls_tls_<bits>"
9707   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9708         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9709                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9710                   UNSPEC_TLSTLS))]
9711   "TARGET_ELF && HAVE_AS_TLS"
9712   "add %0,%1,%2@tls")
9714 (define_expand "tls_get_tpointer"
9715   [(set (match_operand:SI 0 "gpc_reg_operand")
9716         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9717   "TARGET_XCOFF && HAVE_AS_TLS"
9719   emit_insn (gen_tls_get_tpointer_internal ());
9720   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9721   DONE;
9724 (define_insn "tls_get_tpointer_internal"
9725   [(set (reg:SI 3)
9726         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9727    (clobber (reg:SI LR_REGNO))]
9728   "TARGET_XCOFF && HAVE_AS_TLS"
9729   "bla __get_tpointer")
9731 (define_expand "tls_get_addr<mode>"
9732   [(set (match_operand:P 0 "gpc_reg_operand")
9733         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9734                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9735   "TARGET_XCOFF && HAVE_AS_TLS"
9737   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9738   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9739   emit_insn (gen_tls_get_addr_internal<mode> ());
9740   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9741   DONE;
9744 (define_insn "tls_get_addr_internal<mode>"
9745   [(set (reg:P 3)
9746         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9747    (clobber (reg:P 0))
9748    (clobber (reg:P 4))
9749    (clobber (reg:P 5))
9750    (clobber (reg:P 11))
9751    (clobber (reg:CC CR0_REGNO))
9752    (clobber (reg:P LR_REGNO))]
9753   "TARGET_XCOFF && HAVE_AS_TLS"
9754   "bla __tls_get_addr")
9756 ;; Next come insns related to the calling sequence.
9758 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9759 ;; We move the back-chain and decrement the stack pointer.
9761 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9762 ;; constant alloca, using that predicate will force the generic code to put
9763 ;; the constant size into a register before calling the expander.
9765 ;; As a result the expander would not have the constant size information
9766 ;; in those cases and would have to generate less efficient code.
9768 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9769 ;; the constant size.  The value is forced into a register if necessary.
9771 (define_expand "allocate_stack"
9772   [(set (match_operand 0 "gpc_reg_operand")
9773         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9774    (set (reg 1)
9775         (minus (reg 1) (match_dup 1)))]
9776   ""
9778   rtx chain = gen_reg_rtx (Pmode);
9779   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9780   rtx neg_op0;
9781   rtx insn, par, set, mem;
9783   /* By allowing reg_or_cint_operand as the predicate we can get
9784      better code for stack-clash-protection because we do not lose
9785      size information.  But the rest of the code expects the operand
9786      to be reg_or_short_operand.  If it isn't, then force it into
9787      a register.  */
9788   rtx orig_op1 = operands[1];
9789   if (!reg_or_short_operand (operands[1], Pmode))
9790     operands[1] = force_reg (Pmode, operands[1]);
9792   emit_move_insn (chain, stack_bot);
9794   /* Check stack bounds if necessary.  */
9795   if (crtl->limit_stack)
9796     {
9797       rtx available;
9798       available = expand_binop (Pmode, sub_optab,
9799                                 stack_pointer_rtx, stack_limit_rtx,
9800                                 NULL_RTX, 1, OPTAB_WIDEN);
9801       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9802     }
9804   /* Allocate and probe if requested.
9805      This may look similar to the loop we use for prologue allocations,
9806      but it is critically different.  For the former we know the loop
9807      will iterate, but do not know that generally here.  The former
9808      uses that knowledge to rotate the loop.  Combining them would be
9809      possible with some performance cost.  */
9810   if (flag_stack_clash_protection)
9811     {
9812       rtx rounded_size, last_addr, residual;
9813       HOST_WIDE_INT probe_interval;
9814       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9815                                                 &residual, &probe_interval,
9816                                                 orig_op1);
9817       
9818       /* We do occasionally get in here with constant sizes, we might
9819          as well do a reasonable job when we obviously can.  */
9820       if (rounded_size != const0_rtx)
9821         {
9822           rtx loop_lab, end_loop;
9823           bool rotated = CONST_INT_P (rounded_size);
9824           rtx update = GEN_INT (-probe_interval);
9825           if (probe_interval > 32768)
9826             update = force_reg (Pmode, update);
9828           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9829                                                         last_addr, rotated);
9831           if (TARGET_32BIT)
9832             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9833                                                stack_pointer_rtx,
9834                                                update, chain));
9835           else
9836             emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9837                                                stack_pointer_rtx,
9838                                                update, chain));
9839           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9840                                                       last_addr, rotated);
9841         }
9843       /* Now handle residuals.  We just have to set operands[1] correctly
9844          and let the rest of the expander run.  */
9845       operands[1] = residual;
9846     }
9848   if (!(CONST_INT_P (operands[1])
9849         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9850     {
9851       operands[1] = force_reg (Pmode, operands[1]);
9852       neg_op0 = gen_reg_rtx (Pmode);
9853       emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9854     }
9855   else
9856     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9858   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9859                                        : gen_movdi_update_stack))
9860                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9861                          chain));
9862   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9863      it now and set the alias set/attributes. The above gen_*_update
9864      calls will generate a PARALLEL with the MEM set being the first
9865      operation. */
9866   par = PATTERN (insn);
9867   gcc_assert (GET_CODE (par) == PARALLEL);
9868   set = XVECEXP (par, 0, 0);
9869   gcc_assert (GET_CODE (set) == SET);
9870   mem = SET_DEST (set);
9871   gcc_assert (MEM_P (mem));
9872   MEM_NOTRAP_P (mem) = 1;
9873   set_mem_alias_set (mem, get_frame_alias_set ());
9875   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9876   DONE;
9879 ;; These patterns say how to save and restore the stack pointer.  We need not
9880 ;; save the stack pointer at function level since we are careful to
9881 ;; preserve the backchain.  At block level, we have to restore the backchain
9882 ;; when we restore the stack pointer.
9884 ;; For nonlocal gotos, we must save both the stack pointer and its
9885 ;; backchain and restore both.  Note that in the nonlocal case, the
9886 ;; save area is a memory location.
9888 (define_expand "save_stack_function"
9889   [(match_operand 0 "any_operand")
9890    (match_operand 1 "any_operand")]
9891   ""
9892   "DONE;")
9894 (define_expand "restore_stack_function"
9895   [(match_operand 0 "any_operand")
9896    (match_operand 1 "any_operand")]
9897   ""
9898   "DONE;")
9900 ;; Adjust stack pointer (op0) to a new value (op1).
9901 ;; First copy old stack backchain to new location, and ensure that the
9902 ;; scheduler won't reorder the sp assignment before the backchain write.
9903 (define_expand "restore_stack_block"
9904   [(set (match_dup 2) (match_dup 3))
9905    (set (match_dup 4) (match_dup 2))
9906    (match_dup 5)
9907    (set (match_operand 0 "register_operand")
9908         (match_operand 1 "register_operand"))]
9909   ""
9911   rtvec p;
9913   operands[1] = force_reg (Pmode, operands[1]);
9914   operands[2] = gen_reg_rtx (Pmode);
9915   operands[3] = gen_frame_mem (Pmode, operands[0]);
9916   operands[4] = gen_frame_mem (Pmode, operands[1]);
9917   p = rtvec_alloc (1);
9918   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9919                                   const0_rtx);
9920   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9923 (define_expand "save_stack_nonlocal"
9924   [(set (match_dup 3) (match_dup 4))
9925    (set (match_operand 0 "memory_operand") (match_dup 3))
9926    (set (match_dup 2) (match_operand 1 "register_operand"))]
9927   ""
9929   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9931   /* Copy the backchain to the first word, sp to the second.  */
9932   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9933   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9934   operands[3] = gen_reg_rtx (Pmode);
9935   operands[4] = gen_frame_mem (Pmode, operands[1]);
9938 (define_expand "restore_stack_nonlocal"
9939   [(set (match_dup 2) (match_operand 1 "memory_operand"))
9940    (set (match_dup 3) (match_dup 4))
9941    (set (match_dup 5) (match_dup 2))
9942    (match_dup 6)
9943    (set (match_operand 0 "register_operand") (match_dup 3))]
9944   ""
9946   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9947   rtvec p;
9949   /* Restore the backchain from the first word, sp from the second.  */
9950   operands[2] = gen_reg_rtx (Pmode);
9951   operands[3] = gen_reg_rtx (Pmode);
9952   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9953   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9954   operands[5] = gen_frame_mem (Pmode, operands[3]);
9955   p = rtvec_alloc (1);
9956   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9957                                   const0_rtx);
9958   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9961 ;; Load up a PC-relative address.  Print_operand_address will append a @pcrel
9962 ;; to the symbol or label.
9963 (define_insn "*pcrel_local_addr"
9964   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9965         (match_operand:DI 1 "pcrel_local_address"))]
9966   "TARGET_PCREL"
9967   "la %0,%a1"
9968   [(set_attr "prefixed" "yes")])
9970 ;; Load up a PC-relative address to an external symbol.  If the symbol and the
9971 ;; program are both defined in the main program, the linker will optimize this
9972 ;; to a PADDI.  Otherwise, it will create a GOT address that is relocated by
9973 ;; the dynamic linker and loaded up.  Print_operand_address will append a
9974 ;; @got@pcrel to the symbol.
9975 (define_insn "*pcrel_extern_addr"
9976   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9977         (match_operand:DI 1 "pcrel_external_address"))]
9978   "TARGET_PCREL"
9979   "ld %0,%a1"
9980   [(set_attr "prefixed" "yes")
9981    (set_attr "type" "load")])
9983 ;; TOC register handling.
9985 ;; Code to initialize the TOC register...
9987 (define_insn "load_toc_aix_si"
9988   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9989                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9990               (use (reg:SI 2))])]
9991   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9993   char buf[30];
9994   extern int need_toc_init;
9995   need_toc_init = 1;
9996   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9997   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9998   operands[2] = gen_rtx_REG (Pmode, 2);
9999   return "lwz %0,%1(%2)";
10001   [(set_attr "type" "load")
10002    (set_attr "update" "no")
10003    (set_attr "indexed" "no")])
10005 (define_insn "load_toc_aix_di"
10006   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10007                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10008               (use (reg:DI 2))])]
10009   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10011   char buf[30];
10012   extern int need_toc_init;
10013   need_toc_init = 1;
10014   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10015                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10016   if (TARGET_ELF)
10017     strcat (buf, "@toc");
10018   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10019   operands[2] = gen_rtx_REG (Pmode, 2);
10020   return "ld %0,%1(%2)";
10022   [(set_attr "type" "load")
10023    (set_attr "update" "no")
10024    (set_attr "indexed" "no")])
10026 (define_insn "load_toc_v4_pic_si"
10027   [(set (reg:SI LR_REGNO)
10028         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10029   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10030   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10031   [(set_attr "type" "branch")])
10033 (define_expand "load_toc_v4_PIC_1"
10034   [(parallel [(set (reg:SI LR_REGNO)
10035                    (match_operand:SI 0 "immediate_operand" "s"))
10036               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10037   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10038    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10039   "")
10041 (define_insn "load_toc_v4_PIC_1_normal"
10042   [(set (reg:SI LR_REGNO)
10043         (match_operand:SI 0 "immediate_operand" "s"))
10044    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10045   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10046    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10047   "bcl 20,31,%0\n%0:"
10048   [(set_attr "type" "branch")
10049    (set_attr "cannot_copy" "yes")])
10051 (define_insn "load_toc_v4_PIC_1_476"
10052   [(set (reg:SI LR_REGNO)
10053         (match_operand:SI 0 "immediate_operand" "s"))
10054    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10055   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10056    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10058   char name[32];
10059   static char templ[32];
10061   get_ppc476_thunk_name (name);
10062   sprintf (templ, "bl %s\n%%0:", name);
10063   return templ;
10065   [(set_attr "type" "branch")
10066    (set_attr "cannot_copy" "yes")])
10068 (define_expand "load_toc_v4_PIC_1b"
10069   [(parallel [(set (reg:SI LR_REGNO)
10070                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10071                                (label_ref (match_operand 1 ""))]
10072                            UNSPEC_TOCPTR))
10073               (match_dup 1)])]
10074   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10075   "")
10077 (define_insn "load_toc_v4_PIC_1b_normal"
10078   [(set (reg:SI LR_REGNO)
10079         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10080                     (label_ref (match_operand 1 "" ""))]
10081                 UNSPEC_TOCPTR))
10082    (match_dup 1)]
10083   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10084   "bcl 20,31,$+8\;.long %0-$"
10085   [(set_attr "type" "branch")
10086    (set_attr "length" "8")])
10088 (define_insn "load_toc_v4_PIC_1b_476"
10089   [(set (reg:SI LR_REGNO)
10090         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10091                     (label_ref (match_operand 1 "" ""))]
10092                 UNSPEC_TOCPTR))
10093    (match_dup 1)]
10094   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10096   char name[32];
10097   static char templ[32];
10099   get_ppc476_thunk_name (name);
10100   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10101   return templ;
10103   [(set_attr "type" "branch")
10104    (set_attr "length" "16")])
10106 (define_insn "load_toc_v4_PIC_2"
10107   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10108         (mem:SI (plus:SI
10109                   (match_operand:SI 1 "gpc_reg_operand" "b")
10110                   (const
10111                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10112                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10113   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10114   "lwz %0,%2-%3(%1)"
10115   [(set_attr "type" "load")])
10117 (define_insn "load_toc_v4_PIC_3b"
10118   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10119         (plus:SI
10120           (match_operand:SI 1 "gpc_reg_operand" "b")
10121           (high:SI
10122             (const
10123               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10124                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10125   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10126   "addis %0,%1,%2-%3@ha")
10128 (define_insn "load_toc_v4_PIC_3c"
10129   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10130         (lo_sum:SI
10131           (match_operand:SI 1 "gpc_reg_operand" "b")
10132           (const
10133             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10134                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10135   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10136   "addi %0,%1,%2-%3@l")
10138 ;; If the TOC is shared over a translation unit, as happens with all
10139 ;; the kinds of PIC that we support, we need to restore the TOC
10140 ;; pointer only when jumping over units of translation.
10141 ;; On Darwin, we need to reload the picbase.
10143 (define_expand "builtin_setjmp_receiver"
10144   [(use (label_ref (match_operand 0 "")))]
10145   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10146    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10147    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10149 #if TARGET_MACHO
10150   if (DEFAULT_ABI == ABI_DARWIN)
10151     {
10152       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10153       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10154       rtx tmplabrtx;
10155       char tmplab[20];
10157       crtl->uses_pic_offset_table = 1;
10158       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10159                                   CODE_LABEL_NUMBER (operands[0]));
10160       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10162       emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10163       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10164       emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10165                                         picrtx, tmplabrtx));
10166     }
10167   else
10168 #endif
10169     rs6000_emit_load_toc_table (FALSE);
10170   DONE;
10173 ;; Largetoc support
10174 (define_insn "*largetoc_high"
10175   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10176         (high:DI
10177           (unspec [(match_operand:DI 1 "" "")
10178                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10179                   UNSPEC_TOCREL)))]
10180    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10181    "addis %0,%2,%1@toc@ha")
10183 (define_insn "*largetoc_high_aix<mode>"
10184   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10185         (high:P
10186           (unspec [(match_operand:P 1 "" "")
10187                    (match_operand:P 2 "gpc_reg_operand" "b")]
10188                   UNSPEC_TOCREL)))]
10189    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10190    "addis %0,%1@u(%2)")
10192 (define_insn "*largetoc_high_plus"
10193   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10194         (high:DI
10195           (plus:DI
10196             (unspec [(match_operand:DI 1 "" "")
10197                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10198                     UNSPEC_TOCREL)
10199             (match_operand:DI 3 "add_cint_operand" "n"))))]
10200    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10201    "addis %0,%2,%1+%3@toc@ha")
10203 (define_insn "*largetoc_high_plus_aix<mode>"
10204   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10205         (high:P
10206           (plus:P
10207             (unspec [(match_operand:P 1 "" "")
10208                      (match_operand:P 2 "gpc_reg_operand" "b")]
10209                     UNSPEC_TOCREL)
10210             (match_operand:P 3 "add_cint_operand" "n"))))]
10211    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10212    "addis %0,%1+%3@u(%2)")
10214 (define_insn "*largetoc_low"
10215   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10216         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10217                    (match_operand:DI 2 "" "")))]
10218    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10219    "addi %0,%1,%2@l")
10221 (define_insn "*largetoc_low_aix<mode>"
10222   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10223         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10224                    (match_operand:P 2 "" "")))]
10225    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10226    "la %0,%2@l(%1)")
10228 (define_insn_and_split "*tocref<mode>"
10229   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10230         (match_operand:P 1 "small_toc_ref" "R"))]
10231    "TARGET_TOC"
10232    "la %0,%a1"
10233    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10234   [(set (match_dup 0) (high:P (match_dup 1)))
10235    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10237 ;; Elf specific ways of loading addresses for non-PIC code.
10238 ;; The output of this could be r0, but we make a very strong
10239 ;; preference for a base register because it will usually
10240 ;; be needed there.
10241 (define_insn "elf_high"
10242   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10243         (high:SI (match_operand 1 "" "")))]
10244   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10245   "lis %0,%1@ha")
10247 (define_insn "elf_low"
10248   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10249         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10250                    (match_operand 2 "" "")))]
10251    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10252    "la %0,%2@l(%1)")
10254 (define_insn "*pltseq_tocsave_<mode>"
10255   [(set (match_operand:P 0 "memory_operand" "=m")
10256         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10257                    (match_operand:P 2 "symbol_ref_operand" "s")
10258                    (match_operand:P 3 "" "")]
10259                   UNSPEC_PLTSEQ))]
10260   "TARGET_PLTSEQ
10261    && DEFAULT_ABI == ABI_ELFv2"
10263   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10266 (define_insn "*pltseq_plt16_ha_<mode>"
10267   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10268         (unspec:P [(match_operand:P 1 "" "")
10269                    (match_operand:P 2 "symbol_ref_operand" "s")
10270                    (match_operand:P 3 "" "")]
10271                   UNSPEC_PLT16_HA))]
10272   "TARGET_PLTSEQ"
10274   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10277 (define_insn "*pltseq_plt16_lo_<mode>"
10278   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10279         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10280                    (match_operand:P 2 "symbol_ref_operand" "s")
10281                    (match_operand:P 3 "" "")]
10282                   UNSPEC_PLT16_LO))]
10283   "TARGET_PLTSEQ"
10285   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10287   [(set_attr "type" "load")])
10289 (define_insn "*pltseq_mtctr_<mode>"
10290   [(set (match_operand:P 0 "register_operand" "=c")
10291         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10292                    (match_operand:P 2 "symbol_ref_operand" "s")
10293                    (match_operand:P 3 "" "")]
10294                   UNSPEC_PLTSEQ))]
10295   "TARGET_PLTSEQ"
10297   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10300 (define_insn "*pltseq_plt_pcrel<mode>"
10301   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10302         (unspec:P [(match_operand:P 1 "" "")
10303                    (match_operand:P 2 "symbol_ref_operand" "s")
10304                    (match_operand:P 3 "" "")]
10305                   UNSPEC_PLT_PCREL))]
10306   "HAVE_AS_PLTSEQ && TARGET_ELF
10307    && rs6000_pcrel_p (cfun)"
10309   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10311   [(set_attr "type" "load")
10312    (set_attr "length" "12")])
10314 ;; Call and call_value insns
10315 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10316 (define_expand "call"
10317   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10318                     (match_operand 1 ""))
10319               (use (match_operand 2 ""))
10320               (clobber (reg:SI LR_REGNO))])]
10321   ""
10323 #if TARGET_MACHO
10324   if (MACHOPIC_INDIRECT)
10325     operands[0] = machopic_indirect_call_target (operands[0]);
10326 #endif
10328   gcc_assert (MEM_P (operands[0]));
10330   operands[0] = XEXP (operands[0], 0);
10332   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10333     rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10334   else if (DEFAULT_ABI == ABI_V4)
10335     rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10336   else if (DEFAULT_ABI == ABI_DARWIN)
10337     rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10338   else
10339     gcc_unreachable ();
10341   DONE;
10344 (define_expand "call_value"
10345   [(parallel [(set (match_operand 0 "")
10346                    (call (mem:SI (match_operand 1 "address_operand"))
10347                          (match_operand 2 "")))
10348               (use (match_operand 3 ""))
10349               (clobber (reg:SI LR_REGNO))])]
10350   ""
10352 #if TARGET_MACHO
10353   if (MACHOPIC_INDIRECT)
10354     operands[1] = machopic_indirect_call_target (operands[1]);
10355 #endif
10357   gcc_assert (MEM_P (operands[1]));
10359   operands[1] = XEXP (operands[1], 0);
10361   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10362     rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10363   else if (DEFAULT_ABI == ABI_V4)
10364     rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10365   else if (DEFAULT_ABI == ABI_DARWIN)
10366     rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10367   else
10368     gcc_unreachable ();
10370   DONE;
10373 ;; Call to function in current module.  No TOC pointer reload needed.
10374 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10375 ;; either the function was not prototyped, or it was prototyped as a
10376 ;; variable argument function.  It is > 0 if FP registers were passed
10377 ;; and < 0 if they were not.
10379 (define_insn "*call_local32"
10380   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10381          (match_operand 1))
10382    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10383    (clobber (reg:SI LR_REGNO))]
10384   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10386   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10387     output_asm_insn ("crxor 6,6,6", operands);
10389   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10390     output_asm_insn ("creqv 6,6,6", operands);
10392   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10394   [(set_attr "type" "branch")
10395    (set_attr "length" "4,8")])
10397 (define_insn "*call_local64"
10398   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10399          (match_operand 1))
10400    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10401    (clobber (reg:DI LR_REGNO))]
10402   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10404   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10405     output_asm_insn ("crxor 6,6,6", operands);
10407   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10408     output_asm_insn ("creqv 6,6,6", operands);
10410   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10412   [(set_attr "type" "branch")
10413    (set_attr "length" "4,8")])
10415 (define_insn "*call_value_local32"
10416   [(set (match_operand 0 "" "")
10417         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10418               (match_operand 2)))
10419    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10420    (clobber (reg:SI LR_REGNO))]
10421   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10423   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10424     output_asm_insn ("crxor 6,6,6", operands);
10426   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10427     output_asm_insn ("creqv 6,6,6", operands);
10429   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10431   [(set_attr "type" "branch")
10432    (set_attr "length" "4,8")])
10435 (define_insn "*call_value_local64"
10436   [(set (match_operand 0 "" "")
10437         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10438               (match_operand 2)))
10439    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10440    (clobber (reg:DI LR_REGNO))]
10441   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10443   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10444     output_asm_insn ("crxor 6,6,6", operands);
10446   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10447     output_asm_insn ("creqv 6,6,6", operands);
10449   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10451   [(set_attr "type" "branch")
10452    (set_attr "length" "4,8")])
10455 ;; A function pointer under System V is just a normal pointer
10456 ;; operands[0] is the function pointer
10457 ;; operands[1] is the tls call arg
10458 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10459 ;; which indicates how to set cr1
10461 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10462   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10463          (match_operand 1))
10464    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10465    (clobber (reg:P LR_REGNO))]
10466   "DEFAULT_ABI == ABI_V4
10467    || DEFAULT_ABI == ABI_DARWIN"
10469   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10470     output_asm_insn ("crxor 6,6,6", operands);
10472   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10473     output_asm_insn ("creqv 6,6,6", operands);
10475   return rs6000_indirect_call_template (operands, 0);
10477   [(set_attr "type" "jmpreg")
10478    (set (attr "length")
10479         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10480                          (match_test "which_alternative != 1"))
10481                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10482                   (const_string "12")
10483                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10484                          (match_test "which_alternative != 1"))
10485                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10486                   (const_string "8")]
10487               (const_string "4")))])
10489 (define_insn "*call_nonlocal_sysv<mode>"
10490   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10491          (match_operand 1))
10492    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10493    (clobber (reg:P LR_REGNO))]
10494   "(DEFAULT_ABI == ABI_DARWIN
10495    || (DEFAULT_ABI == ABI_V4
10496        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10498   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10499     output_asm_insn ("crxor 6,6,6", operands);
10501   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10502     output_asm_insn ("creqv 6,6,6", operands);
10504   return rs6000_call_template (operands, 0);
10506   [(set_attr "type" "branch,branch")
10507    (set_attr "length" "4,8")])
10509 (define_insn "*call_nonlocal_sysv_secure<mode>"
10510   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10511          (match_operand 1))
10512    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10513    (use (match_operand:SI 3 "register_operand" "r,r"))
10514    (clobber (reg:P LR_REGNO))]
10515   "(DEFAULT_ABI == ABI_V4
10516     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10517     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10519   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10520     output_asm_insn ("crxor 6,6,6", operands);
10522   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10523     output_asm_insn ("creqv 6,6,6", operands);
10525   return rs6000_call_template (operands, 0);
10527   [(set_attr "type" "branch,branch")
10528    (set_attr "length" "4,8")])
10530 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10531   [(set (match_operand 0 "" "")
10532         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10533               (match_operand:P 2 "unspec_tls" "")))
10534    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10535    (clobber (reg:P LR_REGNO))]
10536   "DEFAULT_ABI == ABI_V4
10537    || DEFAULT_ABI == ABI_DARWIN"
10539   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10540     output_asm_insn ("crxor 6,6,6", operands);
10542   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10543     output_asm_insn ("creqv 6,6,6", operands);
10545   return rs6000_indirect_call_template (operands, 1);
10547   [(set_attr "type" "jmpreg")
10548    (set (attr "length")
10549         (plus
10550           (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10551             (const_int 4)
10552             (const_int 0))
10553           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10554                              (match_test "which_alternative != 1"))
10555             (const_int 8)
10556             (const_int 4))))])
10558 (define_insn "*call_value_nonlocal_sysv<mode>"
10559   [(set (match_operand 0 "" "")
10560         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10561               (match_operand:P 2 "unspec_tls" "")))
10562    (use (match_operand:SI 3 "immediate_operand" "n"))
10563    (clobber (reg:P LR_REGNO))]
10564   "(DEFAULT_ABI == ABI_DARWIN
10565     || (DEFAULT_ABI == ABI_V4
10566         && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10568   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10569     output_asm_insn ("crxor 6,6,6", operands);
10571   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10572     output_asm_insn ("creqv 6,6,6", operands);
10574   return rs6000_call_template (operands, 1);
10576   [(set_attr "type" "branch")
10577    (set (attr "length")
10578         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10579           (const_int 8)
10580           (const_int 4)))])
10582 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10583   [(set (match_operand 0 "" "")
10584         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10585               (match_operand:P 2 "unspec_tls" "")))
10586    (use (match_operand:SI 3 "immediate_operand" "n"))
10587    (use (match_operand:SI 4 "register_operand" "r"))
10588    (clobber (reg:P LR_REGNO))]
10589   "(DEFAULT_ABI == ABI_V4
10590     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10591     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10593   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10594     output_asm_insn ("crxor 6,6,6", operands);
10596   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10597     output_asm_insn ("creqv 6,6,6", operands);
10599   return rs6000_call_template (operands, 1);
10601   [(set_attr "type" "branch")
10602    (set (attr "length")
10603         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10604           (const_int 8)
10605           (const_int 4)))])
10607 ;; Call to AIX abi function in the same module.
10609 (define_insn "*call_local_aix<mode>"
10610   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10611          (match_operand 1))
10612    (clobber (reg:P LR_REGNO))]
10613   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10615   if (rs6000_pcrel_p (cfun))
10616     return "bl %z0@notoc";
10617   return "bl %z0";
10619   [(set_attr "type" "branch")])
10621 (define_insn "*call_value_local_aix<mode>"
10622   [(set (match_operand 0 "" "")
10623         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10624               (match_operand 2)))
10625    (clobber (reg:P LR_REGNO))]
10626   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10628   if (rs6000_pcrel_p (cfun))
10629     return "bl %z1@notoc";
10630   return "bl %z1";
10632   [(set_attr "type" "branch")])
10634 ;; Call to AIX abi function which may be in another module.
10635 ;; Restore the TOC pointer (r2) after the call.
10637 (define_insn "*call_nonlocal_aix<mode>"
10638   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10639          (match_operand 1))
10640    (clobber (reg:P LR_REGNO))]
10641   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10643   return rs6000_call_template (operands, 0);
10645   [(set_attr "type" "branch")
10646    (set (attr "length")
10647         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10648           (const_int 4)
10649           (const_int 8)))])
10651 (define_insn "*call_value_nonlocal_aix<mode>"
10652   [(set (match_operand 0 "" "")
10653         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10654               (match_operand:P 2 "unspec_tls" "")))
10655    (clobber (reg:P LR_REGNO))]
10656   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10658   return rs6000_call_template (operands, 1);
10660   [(set_attr "type" "branch")
10661    (set (attr "length")
10662         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10663             (const_int 4)
10664             (const_int 8)))])
10666 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10667 ;; Operand0 is the addresss of the function to call
10668 ;; Operand2 is the location in the function descriptor to load r2 from
10669 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10671 (define_insn "*call_indirect_aix<mode>"
10672   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10673          (match_operand 1))
10674    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10675    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10676    (clobber (reg:P LR_REGNO))]
10677   "DEFAULT_ABI == ABI_AIX"
10679   return rs6000_indirect_call_template (operands, 0);
10681   [(set_attr "type" "jmpreg")
10682    (set (attr "length")
10683         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10684                            (match_test "which_alternative != 1"))
10685                       (const_string "16")
10686                       (const_string "12")))])
10688 (define_insn "*call_value_indirect_aix<mode>"
10689   [(set (match_operand 0 "" "")
10690         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10691               (match_operand:P 2 "unspec_tls" "")))
10692    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10693    (set (reg:P TOC_REGNUM)
10694         (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10695                   UNSPEC_TOCSLOT))
10696    (clobber (reg:P LR_REGNO))]
10697   "DEFAULT_ABI == ABI_AIX"
10699   return rs6000_indirect_call_template (operands, 1);
10701   [(set_attr "type" "jmpreg")
10702    (set (attr "length")
10703         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10704                            (match_test "which_alternative != 1"))
10705             (const_string "16")
10706             (const_string "12")))])
10708 ;; Call to indirect functions with the ELFv2 ABI.
10709 ;; Operand0 is the addresss of the function to call
10710 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10712 (define_insn "*call_indirect_elfv2<mode>"
10713   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10714          (match_operand 1))
10715    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10716    (clobber (reg:P LR_REGNO))]
10717   "DEFAULT_ABI == ABI_ELFv2"
10719   return rs6000_indirect_call_template (operands, 0);
10721   [(set_attr "type" "jmpreg")
10722    (set (attr "length")
10723         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10724                            (match_test "which_alternative != 1"))
10725                       (const_string "12")
10726                       (const_string "8")))])
10728 (define_insn "*call_indirect_pcrel<mode>"
10729   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10730          (match_operand 1))
10731    (clobber (reg:P LR_REGNO))]
10732   "rs6000_pcrel_p (cfun)"
10734   return rs6000_indirect_call_template (operands, 0);
10736   [(set_attr "type" "jmpreg")
10737    (set (attr "length")
10738         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10739                            (match_test "which_alternative != 1"))
10740                       (const_string "8")
10741                       (const_string "4")))])
10743 (define_insn "*call_value_indirect_elfv2<mode>"
10744   [(set (match_operand 0 "" "")
10745         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10746               (match_operand:P 2 "unspec_tls" "")))
10747    (set (reg:P TOC_REGNUM)
10748         (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10749                   UNSPEC_TOCSLOT))
10750    (clobber (reg:P LR_REGNO))]
10751   "DEFAULT_ABI == ABI_ELFv2"
10753   return rs6000_indirect_call_template (operands, 1);
10755   [(set_attr "type" "jmpreg")
10756    (set (attr "length")
10757         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10758                            (match_test "which_alternative != 1"))
10759             (const_string "12")
10760             (const_string "8")))])
10762 (define_insn "*call_value_indirect_pcrel<mode>"
10763   [(set (match_operand 0 "" "")
10764         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10765               (match_operand:P 2 "unspec_tls" "")))
10766    (clobber (reg:P LR_REGNO))]
10767   "rs6000_pcrel_p (cfun)"
10769   return rs6000_indirect_call_template (operands, 1);
10771   [(set_attr "type" "jmpreg")
10772    (set (attr "length")
10773         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10774                            (match_test "which_alternative != 1"))
10775             (const_string "8")
10776             (const_string "4")))])
10778 ;; Call subroutine returning any type.
10779 (define_expand "untyped_call"
10780   [(parallel [(call (match_operand 0 "")
10781                     (const_int 0))
10782               (match_operand 1 "")
10783               (match_operand 2 "")])]
10784   ""
10786   int i;
10788   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10790   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10791     {
10792       rtx set = XVECEXP (operands[2], 0, i);
10793       emit_move_insn (SET_DEST (set), SET_SRC (set));
10794     }
10796   /* The optimizer does not know that the call sets the function value
10797      registers we stored in the result block.  We avoid problems by
10798      claiming that all hard registers are used and clobbered at this
10799      point.  */
10800   emit_insn (gen_blockage ());
10802   DONE;
10805 ;; sibling call patterns
10806 (define_expand "sibcall"
10807   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10808                     (match_operand 1 ""))
10809               (use (match_operand 2 ""))
10810               (simple_return)])]
10811   ""
10813 #if TARGET_MACHO
10814   if (MACHOPIC_INDIRECT)
10815     operands[0] = machopic_indirect_call_target (operands[0]);
10816 #endif
10818   gcc_assert (MEM_P (operands[0]));
10819   gcc_assert (CONST_INT_P (operands[1]));
10821   operands[0] = XEXP (operands[0], 0);
10823   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10824     rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10825   else if (DEFAULT_ABI == ABI_V4)
10826     rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10827   else if (DEFAULT_ABI == ABI_DARWIN)
10828     rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10829   else
10830     gcc_unreachable ();
10832   DONE;
10835 (define_expand "sibcall_value"
10836   [(parallel [(set (match_operand 0 "register_operand")
10837                 (call (mem:SI (match_operand 1 "address_operand"))
10838                       (match_operand 2 "")))
10839               (use (match_operand 3 ""))
10840               (simple_return)])]
10841   ""
10843 #if TARGET_MACHO
10844   if (MACHOPIC_INDIRECT)
10845     operands[1] = machopic_indirect_call_target (operands[1]);
10846 #endif
10848   gcc_assert (MEM_P (operands[1]));
10849   gcc_assert (CONST_INT_P (operands[2]));
10851   operands[1] = XEXP (operands[1], 0);
10853   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10854     rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10855   else if (DEFAULT_ABI == ABI_V4)
10856     rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10857   else if (DEFAULT_ABI == ABI_DARWIN)
10858     rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10859   else
10860     gcc_unreachable ();
10862   DONE;
10865 (define_insn "*sibcall_local32"
10866   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10867          (match_operand 1))
10868    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10869    (simple_return)]
10870   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10872   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10873     output_asm_insn ("crxor 6,6,6", operands);
10875   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10876     output_asm_insn ("creqv 6,6,6", operands);
10878   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10880   [(set_attr "type" "branch")
10881    (set_attr "length" "4,8")])
10883 (define_insn "*sibcall_local64"
10884   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10885          (match_operand 1))
10886    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10887    (simple_return)]
10888   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10890   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10891     output_asm_insn ("crxor 6,6,6", operands);
10893   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10894     output_asm_insn ("creqv 6,6,6", operands);
10896   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10898   [(set_attr "type" "branch")
10899    (set_attr "length" "4,8")])
10901 (define_insn "*sibcall_value_local32"
10902   [(set (match_operand 0 "" "")
10903         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10904               (match_operand 2)))
10905    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10906    (simple_return)]
10907   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10909   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10910     output_asm_insn ("crxor 6,6,6", operands);
10912   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10913     output_asm_insn ("creqv 6,6,6", operands);
10915   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10917   [(set_attr "type" "branch")
10918    (set_attr "length" "4,8")])
10920 (define_insn "*sibcall_value_local64"
10921   [(set (match_operand 0 "" "")
10922         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10923               (match_operand 2)))
10924    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10925    (simple_return)]
10926   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10928   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10929     output_asm_insn ("crxor 6,6,6", operands);
10931   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10932     output_asm_insn ("creqv 6,6,6", operands);
10934   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10936   [(set_attr "type" "branch")
10937    (set_attr "length" "4,8")])
10939 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10940   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10941          (match_operand 1))
10942    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10943    (simple_return)]
10944   "DEFAULT_ABI == ABI_V4
10945    || DEFAULT_ABI == ABI_DARWIN"
10947   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10948     output_asm_insn ("crxor 6,6,6", operands);
10950   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10951     output_asm_insn ("creqv 6,6,6", operands);
10953   return rs6000_indirect_sibcall_template (operands, 0);
10955   [(set_attr "type" "jmpreg")
10956    (set (attr "length")
10957         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10958                          (match_test "which_alternative != 1"))
10959                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10960                   (const_string "12")
10961                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10962                          (match_test "which_alternative != 1"))
10963                    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10964                   (const_string "8")]
10965               (const_string "4")))])
10967 (define_insn "*sibcall_nonlocal_sysv<mode>"
10968   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10969          (match_operand 1))
10970    (use (match_operand 2 "immediate_operand" "O,n"))
10971    (simple_return)]
10972   "(DEFAULT_ABI == ABI_DARWIN
10973     || DEFAULT_ABI == ABI_V4)
10974    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10976   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10977     output_asm_insn ("crxor 6,6,6", operands);
10979   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10980     output_asm_insn ("creqv 6,6,6", operands);
10982   return rs6000_sibcall_template (operands, 0);
10984   [(set_attr "type" "branch")
10985    (set_attr "length" "4,8")])
10987 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
10988   [(set (match_operand 0 "" "")
10989         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10990               (match_operand 2)))
10991    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10992    (simple_return)]
10993   "DEFAULT_ABI == ABI_V4
10994    || DEFAULT_ABI == ABI_DARWIN"
10996   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10997     output_asm_insn ("crxor 6,6,6", operands);
10999   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11000     output_asm_insn ("creqv 6,6,6", operands);
11002   return rs6000_indirect_sibcall_template (operands, 1);
11004   [(set_attr "type" "jmpreg")
11005    (set (attr "length")
11006         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11007                          (match_test "which_alternative != 1"))
11008                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11009                   (const_string "12")
11010                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11011                          (match_test "which_alternative != 1"))
11012                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11013                   (const_string "8")]
11014               (const_string "4")))])
11016 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11017   [(set (match_operand 0 "" "")
11018         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11019               (match_operand 2)))
11020    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11021    (simple_return)]
11022   "(DEFAULT_ABI == ABI_DARWIN
11023     || DEFAULT_ABI == ABI_V4)
11024    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11026   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11027     output_asm_insn ("crxor 6,6,6", operands);
11029   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11030     output_asm_insn ("creqv 6,6,6", operands);
11032   return rs6000_sibcall_template (operands, 1);
11034   [(set_attr "type" "branch")
11035    (set_attr "length" "4,8")])
11037 ;; AIX ABI sibling call patterns.
11039 (define_insn "*sibcall_aix<mode>"
11040   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11041          (match_operand 1))
11042    (simple_return)]
11043   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11045   if (which_alternative == 0)
11046     return rs6000_sibcall_template (operands, 0);
11047   else
11048     return "b%T0";
11050   [(set_attr "type" "branch")])
11052 (define_insn "*sibcall_value_aix<mode>"
11053   [(set (match_operand 0 "" "")
11054         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11055               (match_operand 2)))
11056    (simple_return)]
11057   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11059   if (which_alternative == 0)
11060     return rs6000_sibcall_template (operands, 1);
11061   else
11062     return "b%T1";
11064   [(set_attr "type" "branch")])
11066 (define_expand "sibcall_epilogue"
11067   [(use (const_int 0))]
11068   ""
11070   if (!TARGET_SCHED_PROLOG)
11071     emit_insn (gen_blockage ());
11072   rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11073   DONE;
11076 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11077 ;; all of memory.  This blocks insns from being moved across this point.
11079 (define_insn "blockage"
11080   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11081   ""
11082   ""
11083   [(set_attr "length" "0")])
11085 (define_expand "probe_stack_address"
11086   [(use (match_operand 0 "address_operand"))]
11087   ""
11089   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11090   MEM_VOLATILE_P (operands[0]) = 1;
11092   if (TARGET_64BIT)
11093     emit_insn (gen_probe_stack_di (operands[0]));
11094   else
11095     emit_insn (gen_probe_stack_si (operands[0]));
11096   DONE;
11099 (define_insn "probe_stack_<mode>"
11100   [(set (match_operand:P 0 "memory_operand" "=m")
11101         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11102   ""
11104   operands[1] = gen_rtx_REG (Pmode, 0);
11105   return "st<wd>%U0%X0 %1,%0";
11107   [(set_attr "type" "store")
11108    (set (attr "update")
11109         (if_then_else (match_operand 0 "update_address_mem")
11110                       (const_string "yes")
11111                       (const_string "no")))
11112    (set (attr "indexed")
11113         (if_then_else (match_operand 0 "indexed_address_mem")
11114                       (const_string "yes")
11115                       (const_string "no")))])
11117 (define_insn "probe_stack_range<P:mode>"
11118   [(set (match_operand:P 0 "register_operand" "=&r")
11119         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11120                             (match_operand:P 2 "register_operand" "r")
11121                             (match_operand:P 3 "register_operand" "r")]
11122                            UNSPECV_PROBE_STACK_RANGE))]
11123   ""
11124   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11125   [(set_attr "type" "three")])
11127 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11128 ;; signed & unsigned, and one type of branch.
11130 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11131 ;; insns, and branches.
11133 (define_expand "cbranch<mode>4"
11134   [(use (match_operator 0 "comparison_operator"
11135          [(match_operand:GPR 1 "gpc_reg_operand")
11136           (match_operand:GPR 2 "reg_or_short_operand")]))
11137    (use (match_operand 3))]
11138   ""
11140   /* Take care of the possibility that operands[2] might be negative but
11141      this might be a logical operation.  That insn doesn't exist.  */
11142   if (CONST_INT_P (operands[2])
11143       && INTVAL (operands[2]) < 0)
11144     {
11145       operands[2] = force_reg (<MODE>mode, operands[2]);
11146       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11147                                     GET_MODE (operands[0]),
11148                                     operands[1], operands[2]);
11149    }
11151   rs6000_emit_cbranch (<MODE>mode, operands);
11152   DONE;
11155 (define_expand "cbranch<mode>4"
11156   [(use (match_operator 0 "comparison_operator"
11157          [(match_operand:FP 1 "gpc_reg_operand")
11158           (match_operand:FP 2 "gpc_reg_operand")]))
11159    (use (match_operand 3))]
11160   ""
11162   rs6000_emit_cbranch (<MODE>mode, operands);
11163   DONE;
11166 (define_expand "cstore<mode>4_signed"
11167   [(use (match_operator 1 "signed_comparison_operator"
11168          [(match_operand:P 2 "gpc_reg_operand")
11169           (match_operand:P 3 "gpc_reg_operand")]))
11170    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11171   ""
11173   enum rtx_code cond_code = GET_CODE (operands[1]);
11175   rtx op0 = operands[0];
11176   rtx op1 = operands[2];
11177   rtx op2 = operands[3];
11179   if (cond_code == GE || cond_code == LT)
11180     {
11181       cond_code = swap_condition (cond_code);
11182       std::swap (op1, op2);
11183     }
11185   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11186   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11187   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11189   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11190   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11191   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11193   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11195   if (cond_code == LE)
11196     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11197   else
11198     {
11199       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11200       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11201       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11202     }
11204   DONE;
11207 (define_expand "cstore<mode>4_unsigned"
11208   [(use (match_operator 1 "unsigned_comparison_operator"
11209          [(match_operand:P 2 "gpc_reg_operand")
11210           (match_operand:P 3 "reg_or_short_operand")]))
11211    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11212   ""
11214   enum rtx_code cond_code = GET_CODE (operands[1]);
11216   rtx op0 = operands[0];
11217   rtx op1 = operands[2];
11218   rtx op2 = operands[3];
11220   if (cond_code == GEU || cond_code == LTU)
11221     {
11222       cond_code = swap_condition (cond_code);
11223       std::swap (op1, op2);
11224     }
11226   if (!gpc_reg_operand (op1, <MODE>mode))
11227     op1 = force_reg (<MODE>mode, op1);
11228   if (!reg_or_short_operand (op2, <MODE>mode))
11229     op2 = force_reg (<MODE>mode, op2);
11231   rtx tmp = gen_reg_rtx (<MODE>mode);
11232   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11234   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11235   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11237   if (cond_code == LEU)
11238     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11239   else
11240     emit_insn (gen_neg<mode>2 (op0, tmp2));
11242   DONE;
11245 (define_expand "cstore_si_as_di"
11246   [(use (match_operator 1 "unsigned_comparison_operator"
11247          [(match_operand:SI 2 "gpc_reg_operand")
11248           (match_operand:SI 3 "reg_or_short_operand")]))
11249    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11250   ""
11252   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11253   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11255   operands[2] = force_reg (SImode, operands[2]);
11256   operands[3] = force_reg (SImode, operands[3]);
11257   rtx op1 = gen_reg_rtx (DImode);
11258   rtx op2 = gen_reg_rtx (DImode);
11259   convert_move (op1, operands[2], uns_flag);
11260   convert_move (op2, operands[3], uns_flag);
11262   if (cond_code == GT || cond_code == LE)
11263     {
11264       cond_code = swap_condition (cond_code);
11265       std::swap (op1, op2);
11266     }
11268   rtx tmp = gen_reg_rtx (DImode);
11269   rtx tmp2 = gen_reg_rtx (DImode);
11270   emit_insn (gen_subdi3 (tmp, op1, op2));
11271   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11273   rtx tmp3;
11274   switch (cond_code)
11275     {
11276     default:
11277       gcc_unreachable ();
11278     case LT:
11279       tmp3 = tmp2;
11280       break;
11281     case GE:
11282       tmp3 = gen_reg_rtx (DImode);
11283       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11284       break;
11285     }
11287   convert_move (operands[0], tmp3, 1);
11289   DONE;
11292 (define_expand "cstore<mode>4_signed_imm"
11293   [(use (match_operator 1 "signed_comparison_operator"
11294          [(match_operand:GPR 2 "gpc_reg_operand")
11295           (match_operand:GPR 3 "immediate_operand")]))
11296    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11297   ""
11299   bool invert = false;
11301   enum rtx_code cond_code = GET_CODE (operands[1]);
11303   rtx op0 = operands[0];
11304   rtx op1 = operands[2];
11305   HOST_WIDE_INT val = INTVAL (operands[3]);
11307   if (cond_code == GE || cond_code == GT)
11308     {
11309       cond_code = reverse_condition (cond_code);
11310       invert = true;
11311     }
11313   if (cond_code == LE)
11314     val++;
11316   rtx tmp = gen_reg_rtx (<MODE>mode);
11317   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11318   rtx x = gen_reg_rtx (<MODE>mode);
11319   if (val < 0)
11320     emit_insn (gen_and<mode>3 (x, op1, tmp));
11321   else
11322     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11324   if (invert)
11325     {
11326       rtx tmp = gen_reg_rtx (<MODE>mode);
11327       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11328       x = tmp;
11329     }
11331   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11332   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11334   DONE;
11337 (define_expand "cstore<mode>4_unsigned_imm"
11338   [(use (match_operator 1 "unsigned_comparison_operator"
11339          [(match_operand:GPR 2 "gpc_reg_operand")
11340           (match_operand:GPR 3 "immediate_operand")]))
11341    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11342   ""
11344   bool invert = false;
11346   enum rtx_code cond_code = GET_CODE (operands[1]);
11348   rtx op0 = operands[0];
11349   rtx op1 = operands[2];
11350   HOST_WIDE_INT val = INTVAL (operands[3]);
11352   if (cond_code == GEU || cond_code == GTU)
11353     {
11354       cond_code = reverse_condition (cond_code);
11355       invert = true;
11356     }
11358   if (cond_code == LEU)
11359     val++;
11361   rtx tmp = gen_reg_rtx (<MODE>mode);
11362   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11363   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11364   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11365   rtx x = gen_reg_rtx (<MODE>mode);
11366   if (val < 0)
11367     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11368   else
11369     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11371   if (invert)
11372     {
11373       rtx tmp = gen_reg_rtx (<MODE>mode);
11374       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11375       x = tmp;
11376     }
11378   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11379   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11381   DONE;
11384 (define_expand "cstore<mode>4"
11385   [(use (match_operator 1 "comparison_operator"
11386          [(match_operand:GPR 2 "gpc_reg_operand")
11387           (match_operand:GPR 3 "reg_or_short_operand")]))
11388    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11389   ""
11391   /* Expanding EQ and NE directly to some machine instructions does not help
11392      but does hurt combine.  So don't.  */
11393   if (GET_CODE (operands[1]) == EQ)
11394     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11395   else if (<MODE>mode == Pmode
11396            && GET_CODE (operands[1]) == NE)
11397     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11398   else if (GET_CODE (operands[1]) == NE)
11399     {
11400       rtx tmp = gen_reg_rtx (<MODE>mode);
11401       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11402       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11403     }
11405   /* If ISEL is fast, expand to it.  */
11406   else if (TARGET_ISEL)
11407     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11409   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11410      etc. combinations magically work out just right.  */
11411   else if (<MODE>mode == Pmode
11412            && unsigned_comparison_operator (operands[1], VOIDmode))
11413     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11414                                            operands[2], operands[3]));
11416   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11417   else if (<MODE>mode == SImode && Pmode == DImode)
11418     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11419                                     operands[2], operands[3]));
11421   /* For signed comparisons against a constant, we can do some simple
11422      bit-twiddling.  */
11423   else if (signed_comparison_operator (operands[1], VOIDmode)
11424            && CONST_INT_P (operands[3]))
11425     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11426                                              operands[2], operands[3]));
11428   /* And similarly for unsigned comparisons.  */
11429   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11430            && CONST_INT_P (operands[3]))
11431     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11432                                                operands[2], operands[3]));
11434   /* We also do not want to use mfcr for signed comparisons.  */
11435   else if (<MODE>mode == Pmode
11436            && signed_comparison_operator (operands[1], VOIDmode))
11437     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11438                                          operands[2], operands[3]));
11440   /* Everything else, use the mfcr brute force.  */
11441   else
11442     rs6000_emit_sCOND (<MODE>mode, operands);
11444   DONE;
11447 (define_expand "cstore<mode>4"
11448   [(use (match_operator 1 "comparison_operator"
11449          [(match_operand:FP 2 "gpc_reg_operand")
11450           (match_operand:FP 3 "gpc_reg_operand")]))
11451    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11452   ""
11454   rs6000_emit_sCOND (<MODE>mode, operands);
11455   DONE;
11459 (define_expand "stack_protect_set"
11460   [(match_operand 0 "memory_operand")
11461    (match_operand 1 "memory_operand")]
11462   ""
11464   if (rs6000_stack_protector_guard == SSP_TLS)
11465     {
11466       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11467       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11468       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11469       operands[1] = gen_rtx_MEM (Pmode, addr);
11470     }
11472   if (TARGET_64BIT)
11473     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11474   else
11475     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11477   DONE;
11480 (define_insn "stack_protect_setsi"
11481   [(set (match_operand:SI 0 "memory_operand" "=m")
11482         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11483    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11484   "TARGET_32BIT"
11485   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11486   [(set_attr "type" "three")
11487    (set_attr "length" "12")])
11489 ;; We can't use the prefixed attribute here because there are two memory
11490 ;; instructions.  We can't split the insn due to the fact that this operation
11491 ;; needs to be done in one piece.
11492 (define_insn "stack_protect_setdi"
11493   [(set (match_operand:DI 0 "memory_operand" "=Y")
11494         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11495    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11496   "TARGET_64BIT"
11498   if (prefixed_memory (operands[1], DImode))
11499     output_asm_insn ("pld %2,%1", operands);
11500   else
11501     output_asm_insn ("ld%U1%X1 %2,%1", operands);
11503   if (prefixed_memory (operands[0], DImode))
11504     output_asm_insn ("pstd %2,%0", operands);
11505   else
11506     output_asm_insn ("std%U0%X0 %2,%0", operands);
11508   return "li %2,0";
11510   [(set_attr "type" "three")
11512   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11513   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in 4 bytes for
11514   ;; the LI 0 at the end.
11515    (set_attr "prefixed" "no")
11516    (set_attr "num_insns" "3")
11517    (set (attr "length")
11518         (cond [(and (match_operand 0 "prefixed_memory")
11519                     (match_operand 1 "prefixed_memory"))
11520                (const_int 24)
11522                (ior (match_operand 0 "prefixed_memory")
11523                     (match_operand 1 "prefixed_memory"))
11524                (const_int 20)]
11526               (const_int 12)))])
11528 (define_expand "stack_protect_test"
11529   [(match_operand 0 "memory_operand")
11530    (match_operand 1 "memory_operand")
11531    (match_operand 2 "")]
11532   ""
11534   rtx guard = operands[1];
11536   if (rs6000_stack_protector_guard == SSP_TLS)
11537     {
11538       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11539       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11540       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11541       guard = gen_rtx_MEM (Pmode, addr);
11542     }
11544   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11545   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11546   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11547   emit_jump_insn (jump);
11549   DONE;
11552 (define_insn "stack_protect_testsi"
11553   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11554         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11555                       (match_operand:SI 2 "memory_operand" "m,m")]
11556                      UNSPEC_SP_TEST))
11557    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11558    (clobber (match_scratch:SI 3 "=&r,&r"))]
11559   "TARGET_32BIT"
11560   "@
11561    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11562    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11563   [(set_attr "length" "16,20")])
11565 ;; We can't use the prefixed attribute here because there are two memory
11566 ;; instructions.  We can't split the insn due to the fact that this operation
11567 ;; needs to be done in one piece.
11568 (define_insn "stack_protect_testdi"
11569   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11570         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11571                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11572                      UNSPEC_SP_TEST))
11573    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11574    (clobber (match_scratch:DI 3 "=&r,&r"))]
11575   "TARGET_64BIT"
11577   if (prefixed_memory (operands[1], DImode))
11578     output_asm_insn ("pld %3,%1", operands);
11579   else
11580     output_asm_insn ("ld%U1%X1 %3,%1", operands);
11582   if (prefixed_memory (operands[2], DImode))
11583     output_asm_insn ("pld %4,%2", operands);
11584   else
11585     output_asm_insn ("ld%U2%X2 %4,%2", operands);
11587   if (which_alternative == 0)
11588     output_asm_insn ("xor. %3,%3,%4", operands);
11589   else
11590     output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11592   return "li %4,0";
11594   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11595   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in either 4 or
11596   ;; 8 bytes to do the test.
11597   [(set_attr "prefixed" "no")
11598    (set_attr "num_insns" "4,5")
11599    (set (attr "length")
11600         (cond [(and (match_operand 1 "prefixed_memory")
11601                     (match_operand 2 "prefixed_memory"))
11602                (if_then_else (eq_attr "alternative" "0")
11603                              (const_int 28)
11604                              (const_int 32))
11606                (ior (match_operand 1 "prefixed_memory")
11607                     (match_operand 2 "prefixed_memory"))
11608                (if_then_else (eq_attr "alternative" "0")
11609                              (const_int 20)
11610                              (const_int 24))]
11612               (if_then_else (eq_attr "alternative" "0")
11613                             (const_int 16)
11614                             (const_int 20))))])
11617 ;; Here are the actual compare insns.
11618 (define_insn "*cmp<mode>_signed"
11619   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11620         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11621                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11622   ""
11623   "cmp<wd>%I2 %0,%1,%2"
11624   [(set_attr "type" "cmp")])
11626 (define_insn "*cmp<mode>_unsigned"
11627   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11628         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11629                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11630   ""
11631   "cmpl<wd>%I2 %0,%1,%2"
11632   [(set_attr "type" "cmp")])
11634 ;; If we are comparing a register for equality with a large constant,
11635 ;; we can do this with an XOR followed by a compare.  But this is profitable
11636 ;; only if the large constant is only used for the comparison (and in this
11637 ;; case we already have a register to reuse as scratch).
11639 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11640 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11642 (define_peephole2
11643   [(set (match_operand:SI 0 "register_operand")
11644         (match_operand:SI 1 "logical_const_operand"))
11645    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11646                        [(match_dup 0)
11647                         (match_operand:SI 2 "logical_const_operand")]))
11648    (set (match_operand:CC 4 "cc_reg_operand")
11649         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11650                     (match_dup 0)))
11651    (set (pc)
11652         (if_then_else (match_operator 6 "equality_operator"
11653                        [(match_dup 4) (const_int 0)])
11654                       (match_operand 7 "")
11655                       (match_operand 8 "")))]
11656   "peep2_reg_dead_p (3, operands[0])
11657    && peep2_reg_dead_p (4, operands[4])
11658    && REGNO (operands[0]) != REGNO (operands[5])"
11659  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11660   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11661   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11664   /* Get the constant we are comparing against, and see what it looks like
11665      when sign-extended from 16 to 32 bits.  Then see what constant we could
11666      XOR with SEXTC to get the sign-extended value.  */
11667   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11668                                               SImode,
11669                                               operands[1], operands[2]);
11670   HOST_WIDE_INT c = INTVAL (cnst);
11671   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11672   HOST_WIDE_INT xorv = c ^ sextc;
11674   operands[9] = GEN_INT (xorv);
11675   operands[10] = GEN_INT (sextc);
11678 ;; Only need to compare second words if first words equal
11679 (define_insn "*cmp<mode>_internal1"
11680   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11681         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11682                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11683   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11684    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11685   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11686   [(set_attr "type" "fpcompare")
11687    (set_attr "length" "12")])
11689 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11690   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11691         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11692                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11693     (clobber (match_scratch:DF 3 "=d"))
11694     (clobber (match_scratch:DF 4 "=d"))
11695     (clobber (match_scratch:DF 5 "=d"))
11696     (clobber (match_scratch:DF 6 "=d"))
11697     (clobber (match_scratch:DF 7 "=d"))
11698     (clobber (match_scratch:DF 8 "=d"))
11699     (clobber (match_scratch:DF 9 "=d"))
11700     (clobber (match_scratch:DF 10 "=d"))
11701     (clobber (match_scratch:GPR 11 "=b"))]
11702   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11703    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11704   "#"
11705   "&& reload_completed"
11706   [(set (match_dup 3) (match_dup 14))
11707    (set (match_dup 4) (match_dup 15))
11708    (set (match_dup 9) (abs:DF (match_dup 5)))
11709    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11710    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11711                            (label_ref (match_dup 12))
11712                            (pc)))
11713    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11714    (set (pc) (label_ref (match_dup 13)))
11715    (match_dup 12)
11716    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11717    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11718    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11719    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11720    (match_dup 13)]
11722   REAL_VALUE_TYPE rv;
11723   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11724   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11726   operands[5] = simplify_gen_subreg (DFmode, operands[1],
11727                                      <IBM128:MODE>mode, hi_word);
11728   operands[6] = simplify_gen_subreg (DFmode, operands[1],
11729                                      <IBM128:MODE>mode, lo_word);
11730   operands[7] = simplify_gen_subreg (DFmode, operands[2],
11731                                      <IBM128:MODE>mode, hi_word);
11732   operands[8] = simplify_gen_subreg (DFmode, operands[2],
11733                                      <IBM128:MODE>mode, lo_word);
11734   operands[12] = gen_label_rtx ();
11735   operands[13] = gen_label_rtx ();
11736   real_inf (&rv);
11737   operands[14] = force_const_mem (DFmode,
11738                                   const_double_from_real_value (rv, DFmode));
11739   operands[15] = force_const_mem (DFmode,
11740                                   const_double_from_real_value (dconst0,
11741                                                                 DFmode));
11742   if (TARGET_TOC)
11743     {
11744       rtx tocref;
11745       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11746       operands[14] = gen_const_mem (DFmode, tocref);
11747       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11748       operands[15] = gen_const_mem (DFmode, tocref);
11749       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11750       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11751     }
11754 ;; Now we have the scc insns.  We can do some combinations because of the
11755 ;; way the machine works.
11757 ;; Note that this is probably faster if we can put an insn between the
11758 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11759 ;; cases the insns below which don't use an intermediate CR field will
11760 ;; be used instead.
11761 (define_insn ""
11762   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11763         (match_operator:GPR 1 "scc_comparison_operator"
11764                             [(match_operand 2 "cc_reg_operand" "y")
11765                              (const_int 0)]))]
11766   ""
11767   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11768   [(set (attr "type")
11769      (cond [(match_test "TARGET_MFCRF")
11770                 (const_string "mfcrf")
11771            ]
11772         (const_string "mfcr")))
11773    (set_attr "length" "8")])
11775 (define_insn_and_split ""
11776   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11777         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11778                                        [(match_operand 2 "cc_reg_operand" "y,y")
11779                                         (const_int 0)])
11780                     (const_int 0)))
11781    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11782         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11783   "TARGET_32BIT"
11784   "@
11785    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11786    #"
11787   "&& reload_completed"
11788   [(set (match_dup 3)
11789         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11790    (set (match_dup 0)
11791         (compare:CC (match_dup 3)
11792                     (const_int 0)))]
11793   ""
11794   [(set_attr "type" "shift")
11795    (set_attr "dot" "yes")
11796    (set_attr "length" "8,16")])
11798 (define_insn ""
11799   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11800         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11801                                       [(match_operand 2 "cc_reg_operand" "y")
11802                                        (const_int 0)])
11803                    (match_operand:SI 3 "const_int_operand" "n")))]
11804   ""
11806   int is_bit = ccr_bit (operands[1], 1);
11807   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11808   int count;
11810   gcc_assert (is_bit != -1);
11811   if (is_bit >= put_bit)
11812     count = is_bit - put_bit;
11813   else
11814     count = 32 - (put_bit - is_bit);
11816   operands[4] = GEN_INT (count);
11817   operands[5] = GEN_INT (put_bit);
11819   return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11821   [(set (attr "type")
11822      (cond [(match_test "TARGET_MFCRF")
11823                 (const_string "mfcrf")
11824            ]
11825         (const_string "mfcr")))
11826    (set_attr "length" "8")])
11828 (define_insn ""
11829   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11830         (compare:CC
11831          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11832                                        [(match_operand 2 "cc_reg_operand" "y,y")
11833                                         (const_int 0)])
11834                     (match_operand:SI 3 "const_int_operand" "n,n"))
11835          (const_int 0)))
11836    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11837         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11838                    (match_dup 3)))]
11839   ""
11841   int is_bit = ccr_bit (operands[1], 1);
11842   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11843   int count;
11845   gcc_assert (is_bit != -1);
11846   /* Force split for non-cc0 compare.  */
11847   if (which_alternative == 1)
11848      return "#";
11850   if (is_bit >= put_bit)
11851     count = is_bit - put_bit;
11852   else
11853     count = 32 - (put_bit - is_bit);
11855   operands[5] = GEN_INT (count);
11856   operands[6] = GEN_INT (put_bit);
11858   return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11860   [(set_attr "type" "shift")
11861    (set_attr "dot" "yes")
11862    (set_attr "length" "8,16")])
11864 (define_split
11865   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11866         (compare:CC
11867          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11868                                        [(match_operand 2 "cc_reg_operand")
11869                                         (const_int 0)])
11870                     (match_operand:SI 3 "const_int_operand"))
11871          (const_int 0)))
11872    (set (match_operand:SI 4 "gpc_reg_operand")
11873         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11874                    (match_dup 3)))]
11875   "reload_completed"
11876   [(set (match_dup 4)
11877         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11878                    (match_dup 3)))
11879    (set (match_dup 0)
11880         (compare:CC (match_dup 4)
11881                     (const_int 0)))]
11882   "")
11885 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11886 (define_code_attr UNS [(eq "CC")
11887                        (ne "CC")
11888                        (lt "CC") (ltu "CCUNS")
11889                        (gt "CC") (gtu "CCUNS")
11890                        (le "CC") (leu "CCUNS")
11891                        (ge "CC") (geu "CCUNS")])
11892 (define_code_attr UNSu_ [(eq "")
11893                          (ne "")
11894                          (lt "") (ltu "u_")
11895                          (gt "") (gtu "u_")
11896                          (le "") (leu "u_")
11897                          (ge "") (geu "u_")])
11898 (define_code_attr UNSIK [(eq "I")
11899                          (ne "I")
11900                          (lt "I") (ltu "K")
11901                          (gt "I") (gtu "K")
11902                          (le "I") (leu "K")
11903                          (ge "I") (geu "K")])
11905 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11906   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11907         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11908                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11909    (clobber (match_scratch:GPR 3 "=r"))
11910    (clobber (match_scratch:GPR 4 "=r"))
11911    (clobber (match_scratch:<UNS> 5 "=y"))]
11912   "TARGET_ISEL
11913    && !(<CODE> == EQ && operands[2] == const0_rtx)
11914    && !(<CODE> == NE && operands[2] == const0_rtx
11915         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11916   "#"
11917   "&& 1"
11918   [(pc)]
11920   rtx_code code = <CODE>;
11921   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11922     {
11923       HOST_WIDE_INT val = INTVAL (operands[2]);
11924       if (code == LT && val != -0x8000)
11925         {
11926           code = LE;
11927           val--;
11928         }
11929       if (code == GT && val != 0x7fff)
11930         {
11931           code = GE;
11932           val++;
11933         }
11934       if (code == LTU && val != 0)
11935         {
11936           code = LEU;
11937           val--;
11938         }
11939       if (code == GTU && val != 0xffff)
11940         {
11941           code = GEU;
11942           val++;
11943         }
11944       operands[2] = GEN_INT (val);
11945     }
11947   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11948     operands[3] = const0_rtx;
11949   else
11950     {
11951       if (GET_CODE (operands[3]) == SCRATCH)
11952         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11953       emit_move_insn (operands[3], const0_rtx);
11954     }
11956   if (GET_CODE (operands[4]) == SCRATCH)
11957     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11958   emit_move_insn (operands[4], const1_rtx);
11960   if (GET_CODE (operands[5]) == SCRATCH)
11961     operands[5] = gen_reg_rtx (<UNS>mode);
11963   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11964   emit_insn (gen_rtx_SET (operands[5], c1));
11966   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11967   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11968   emit_move_insn (operands[0], x);
11970   DONE;
11972   [(set (attr "cost")
11973         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11974                                    || <CODE> == NE
11975                                    || <CODE> == LE || <CODE> == GE
11976                                    || <CODE> == LEU || <CODE> == GEU")
11977                       (const_string "9")
11978                       (const_string "10")))])
11980 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11981                               (DI "rKJI")])
11983 (define_expand "eq<mode>3"
11984   [(parallel [
11985      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11986           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11987                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11988      (clobber (match_scratch:GPR 3 "=r"))
11989      (clobber (match_scratch:GPR 4 "=r"))])]
11990   ""
11992   if (TARGET_ISEL && operands[2] != const0_rtx)
11993     {
11994       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11995                                            operands[2]));
11996       DONE;
11997     }
12000 (define_insn_and_split "*eq<mode>3"
12001   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12002         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12003                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12004    (clobber (match_scratch:GPR 3 "=r"))
12005    (clobber (match_scratch:GPR 4 "=r"))]
12006   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12007   "#"
12008   "&& 1"
12009   [(set (match_dup 4)
12010         (clz:GPR (match_dup 3)))
12011    (set (match_dup 0)
12012         (lshiftrt:GPR (match_dup 4)
12013                       (match_dup 5)))]
12015   operands[3] = rs6000_emit_eqne (<MODE>mode,
12016                                   operands[1], operands[2], operands[3]);
12018   if (GET_CODE (operands[4]) == SCRATCH)
12019     operands[4] = gen_reg_rtx (<MODE>mode);
12021   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12023   [(set (attr "length")
12024         (if_then_else (match_test "operands[2] == const0_rtx")
12025                       (const_string "8")
12026                       (const_string "12")))])
12028 (define_expand "ne<mode>3"
12029   [(parallel [
12030      (set (match_operand:P 0 "gpc_reg_operand" "=r")
12031           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12032                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12033      (clobber (match_scratch:P 3 "=r"))
12034      (clobber (match_scratch:P 4 "=r"))
12035      (clobber (reg:P CA_REGNO))])]
12036   ""
12038   if (TARGET_ISEL && operands[2] != const0_rtx)
12039     {
12040       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12041                                            operands[2]));
12042       DONE;
12043     }
12046 (define_insn_and_split "*ne<mode>3"
12047   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12048         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12049               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12050    (clobber (match_scratch:P 3 "=r"))
12051    (clobber (match_scratch:P 4 "=r"))
12052    (clobber (reg:P CA_REGNO))]
12053   "!(TARGET_ISEL && operands[2] != const0_rtx)"
12054   "#"
12055   "&& 1"
12056   [(parallel [(set (match_dup 4)
12057                    (plus:P (match_dup 3)
12058                            (const_int -1)))
12059               (set (reg:P CA_REGNO)
12060                    (ne:P (match_dup 3)
12061                          (const_int 0)))])
12062    (parallel [(set (match_dup 0)
12063                    (plus:P (plus:P (not:P (match_dup 4))
12064                                    (reg:P CA_REGNO))
12065                            (match_dup 3)))
12066               (clobber (reg:P CA_REGNO))])]
12068   operands[3] = rs6000_emit_eqne (<MODE>mode,
12069                                   operands[1], operands[2], operands[3]);
12071   if (GET_CODE (operands[4]) == SCRATCH)
12072     operands[4] = gen_reg_rtx (<MODE>mode);
12074   [(set (attr "length")
12075         (if_then_else (match_test "operands[2] == const0_rtx")
12076                       (const_string "8")
12077                       (const_string "12")))])
12079 (define_insn_and_split "*neg_eq_<mode>"
12080   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12081         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12082                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12083    (clobber (match_scratch:P 3 "=r"))
12084    (clobber (match_scratch:P 4 "=r"))
12085    (clobber (reg:P CA_REGNO))]
12086   ""
12087   "#"
12088   ""
12089   [(parallel [(set (match_dup 4)
12090                    (plus:P (match_dup 3)
12091                            (const_int -1)))
12092               (set (reg:P CA_REGNO)
12093                    (ne:P (match_dup 3)
12094                          (const_int 0)))])
12095    (parallel [(set (match_dup 0)
12096                    (plus:P (reg:P CA_REGNO)
12097                            (const_int -1)))
12098               (clobber (reg:P CA_REGNO))])]
12100   operands[3] = rs6000_emit_eqne (<MODE>mode,
12101                                   operands[1], operands[2], operands[3]);
12103   if (GET_CODE (operands[4]) == SCRATCH)
12104     operands[4] = gen_reg_rtx (<MODE>mode);
12106   [(set (attr "length")
12107         (if_then_else (match_test "operands[2] == const0_rtx")
12108                       (const_string "8")
12109                       (const_string "12")))])
12111 (define_insn_and_split "*neg_ne_<mode>"
12112   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12113         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12114                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12115    (clobber (match_scratch:P 3 "=r"))
12116    (clobber (match_scratch:P 4 "=r"))
12117    (clobber (reg:P CA_REGNO))]
12118   ""
12119   "#"
12120   ""
12121   [(parallel [(set (match_dup 4)
12122                    (neg:P (match_dup 3)))
12123               (set (reg:P CA_REGNO)
12124                    (eq:P (match_dup 3)
12125                          (const_int 0)))])
12126    (parallel [(set (match_dup 0)
12127                    (plus:P (reg:P CA_REGNO)
12128                            (const_int -1)))
12129               (clobber (reg:P CA_REGNO))])]
12131   operands[3] = rs6000_emit_eqne (<MODE>mode,
12132                                   operands[1], operands[2], operands[3]);
12134   if (GET_CODE (operands[4]) == SCRATCH)
12135     operands[4] = gen_reg_rtx (<MODE>mode);
12137   [(set (attr "length")
12138         (if_then_else (match_test "operands[2] == const0_rtx")
12139                       (const_string "8")
12140                       (const_string "12")))])
12142 (define_insn_and_split "*plus_eq_<mode>"
12143   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12144         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12145                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12146                 (match_operand:P 3 "gpc_reg_operand" "r")))
12147    (clobber (match_scratch:P 4 "=r"))
12148    (clobber (match_scratch:P 5 "=r"))
12149    (clobber (reg:P CA_REGNO))]
12150   ""
12151   "#"
12152   ""
12153   [(parallel [(set (match_dup 5)
12154                    (neg:P (match_dup 4)))
12155               (set (reg:P CA_REGNO)
12156                    (eq:P (match_dup 4)
12157                          (const_int 0)))])
12158    (parallel [(set (match_dup 0)
12159                    (plus:P (match_dup 3)
12160                            (reg:P CA_REGNO)))
12161               (clobber (reg:P CA_REGNO))])]
12163   operands[4] = rs6000_emit_eqne (<MODE>mode,
12164                                   operands[1], operands[2], operands[4]);
12166   if (GET_CODE (operands[5]) == SCRATCH)
12167     operands[5] = gen_reg_rtx (<MODE>mode);
12169   [(set (attr "length")
12170         (if_then_else (match_test "operands[2] == const0_rtx")
12171                       (const_string "8")
12172                       (const_string "12")))])
12174 (define_insn_and_split "*plus_ne_<mode>"
12175   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12176         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12177                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12178                 (match_operand:P 3 "gpc_reg_operand" "r")))
12179    (clobber (match_scratch:P 4 "=r"))
12180    (clobber (match_scratch:P 5 "=r"))
12181    (clobber (reg:P CA_REGNO))]
12182   ""
12183   "#"
12184   ""
12185   [(parallel [(set (match_dup 5)
12186                    (plus:P (match_dup 4)
12187                            (const_int -1)))
12188               (set (reg:P CA_REGNO)
12189                    (ne:P (match_dup 4)
12190                          (const_int 0)))])
12191    (parallel [(set (match_dup 0)
12192                    (plus:P (match_dup 3)
12193                            (reg:P CA_REGNO)))
12194               (clobber (reg:P CA_REGNO))])]
12196   operands[4] = rs6000_emit_eqne (<MODE>mode,
12197                                   operands[1], operands[2], operands[4]);
12199   if (GET_CODE (operands[5]) == SCRATCH)
12200     operands[5] = gen_reg_rtx (<MODE>mode);
12202   [(set (attr "length")
12203         (if_then_else (match_test "operands[2] == const0_rtx")
12204                       (const_string "8")
12205                       (const_string "12")))])
12207 (define_insn_and_split "*minus_eq_<mode>"
12208   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12209         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12210                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12211                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12212    (clobber (match_scratch:P 4 "=r"))
12213    (clobber (match_scratch:P 5 "=r"))
12214    (clobber (reg:P CA_REGNO))]
12215   ""
12216   "#"
12217   ""
12218   [(parallel [(set (match_dup 5)
12219                    (plus:P (match_dup 4)
12220                            (const_int -1)))
12221               (set (reg:P CA_REGNO)
12222                    (ne:P (match_dup 4)
12223                          (const_int 0)))])
12224    (parallel [(set (match_dup 0)
12225                    (plus:P (plus:P (match_dup 3)
12226                                    (reg:P CA_REGNO))
12227                            (const_int -1)))
12228               (clobber (reg:P CA_REGNO))])]
12230   operands[4] = rs6000_emit_eqne (<MODE>mode,
12231                                   operands[1], operands[2], operands[4]);
12233   if (GET_CODE (operands[5]) == SCRATCH)
12234     operands[5] = gen_reg_rtx (<MODE>mode);
12236   [(set (attr "length")
12237         (if_then_else (match_test "operands[2] == const0_rtx")
12238                       (const_string "8")
12239                       (const_string "12")))])
12241 (define_insn_and_split "*minus_ne_<mode>"
12242   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12243         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12244                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12245                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12246    (clobber (match_scratch:P 4 "=r"))
12247    (clobber (match_scratch:P 5 "=r"))
12248    (clobber (reg:P CA_REGNO))]
12249   ""
12250   "#"
12251   ""
12252   [(parallel [(set (match_dup 5)
12253                    (neg:P (match_dup 4)))
12254               (set (reg:P CA_REGNO)
12255                    (eq:P (match_dup 4)
12256                          (const_int 0)))])
12257    (parallel [(set (match_dup 0)
12258                    (plus:P (plus:P (match_dup 3)
12259                                    (reg:P CA_REGNO))
12260                            (const_int -1)))
12261               (clobber (reg:P CA_REGNO))])]
12263   operands[4] = rs6000_emit_eqne (<MODE>mode,
12264                                   operands[1], operands[2], operands[4]);
12266   if (GET_CODE (operands[5]) == SCRATCH)
12267     operands[5] = gen_reg_rtx (<MODE>mode);
12269   [(set (attr "length")
12270         (if_then_else (match_test "operands[2] == const0_rtx")
12271                       (const_string "8")
12272                       (const_string "12")))])
12274 (define_insn_and_split "*eqsi3_ext<mode>"
12275   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12276         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12277                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12278    (clobber (match_scratch:SI 3 "=r"))
12279    (clobber (match_scratch:SI 4 "=r"))]
12280   ""
12281   "#"
12282   ""
12283   [(set (match_dup 4)
12284         (clz:SI (match_dup 3)))
12285    (set (match_dup 0)
12286         (zero_extend:EXTSI
12287           (lshiftrt:SI (match_dup 4)
12288                        (const_int 5))))]
12290   operands[3] = rs6000_emit_eqne (SImode,
12291                                   operands[1], operands[2], operands[3]);
12293   if (GET_CODE (operands[4]) == SCRATCH)
12294     operands[4] = gen_reg_rtx (SImode);
12296   [(set (attr "length")
12297         (if_then_else (match_test "operands[2] == const0_rtx")
12298                       (const_string "8")
12299                       (const_string "12")))])
12301 (define_insn_and_split "*nesi3_ext<mode>"
12302   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12303         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12304                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12305    (clobber (match_scratch:SI 3 "=r"))
12306    (clobber (match_scratch:SI 4 "=r"))
12307    (clobber (match_scratch:EXTSI 5 "=r"))]
12308   "!TARGET_ISEL"
12309   "#"
12310   "&& 1"
12311   [(set (match_dup 4)
12312         (clz:SI (match_dup 3)))
12313    (set (match_dup 5)
12314         (zero_extend:EXTSI
12315           (lshiftrt:SI (match_dup 4)
12316                        (const_int 5))))
12317    (set (match_dup 0)
12318         (xor:EXTSI (match_dup 5)
12319                    (const_int 1)))]
12321   operands[3] = rs6000_emit_eqne (SImode,
12322                                   operands[1], operands[2], operands[3]);
12324   if (GET_CODE (operands[4]) == SCRATCH)
12325     operands[4] = gen_reg_rtx (SImode);
12326   if (GET_CODE (operands[5]) == SCRATCH)
12327     operands[5] = gen_reg_rtx (<MODE>mode);
12329   [(set (attr "length")
12330         (if_then_else (match_test "operands[2] == const0_rtx")
12331                       (const_string "12")
12332                       (const_string "16")))])
12334 ;; Conditional branches.
12335 ;; These either are a single bc insn, or a bc around a b.
12337 (define_insn "*cbranch"
12338   [(set (pc)
12339         (if_then_else (match_operator 1 "branch_comparison_operator"
12340                                       [(match_operand 2 "cc_reg_operand" "y")
12341                                        (const_int 0)])
12342                       (label_ref (match_operand 0))
12343                       (pc)))]
12344   ""
12346   return output_cbranch (operands[1], "%l0", 0, insn);
12348   [(set_attr "type" "branch")
12349    (set (attr "length")
12350         (if_then_else (and (ge (minus (match_dup 0) (pc))
12351                                (const_int -32768))
12352                            (lt (minus (match_dup 0) (pc))
12353                                (const_int 32764)))
12354                       (const_int 4)
12355                       (const_int 8)))])
12357 ;; Conditional return.
12358 (define_insn "*creturn"
12359   [(set (pc)
12360         (if_then_else (match_operator 0 "branch_comparison_operator"
12361                                       [(match_operand 1 "cc_reg_operand" "y")
12362                                        (const_int 0)])
12363                       (any_return)
12364                       (pc)))]
12365   "<return_pred>"
12367   return output_cbranch (operands[0], NULL, 0, insn);
12369   [(set_attr "type" "jmpreg")])
12371 ;; Logic on condition register values.
12373 ; This pattern matches things like
12374 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12375 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12376 ;                                  (const_int 1)))
12377 ; which are generated by the branch logic.
12378 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12380 (define_insn "cceq_ior_compare"
12381   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12382         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12383                         [(match_operator:SI 2
12384                                       "branch_positive_comparison_operator"
12385                                       [(match_operand 3
12386                                                       "cc_reg_operand" "y,y")
12387                                        (const_int 0)])
12388                          (match_operator:SI 4
12389                                       "branch_positive_comparison_operator"
12390                                       [(match_operand 5
12391                                                       "cc_reg_operand" "0,y")
12392                                        (const_int 0)])])
12393                       (const_int 1)))]
12394   ""
12395   "cr%q1 %E0,%j2,%j4"
12396   [(set_attr "type" "cr_logical")
12397    (set_attr "cr_logical_3op" "no,yes")])
12399 ; Why is the constant -1 here, but 1 in the previous pattern?
12400 ; Because ~1 has all but the low bit set.
12401 (define_insn "cceq_ior_compare_complement"
12402   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12403         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12404                         [(not:SI (match_operator:SI 2
12405                                       "branch_positive_comparison_operator"
12406                                       [(match_operand 3
12407                                                       "cc_reg_operand" "y,y")
12408                                        (const_int 0)]))
12409                          (match_operator:SI 4
12410                                 "branch_positive_comparison_operator"
12411                                 [(match_operand 5
12412                                                 "cc_reg_operand" "0,y")
12413                                  (const_int 0)])])
12414                       (const_int -1)))]
12415   ""
12416   "cr%q1 %E0,%j2,%j4"
12417   [(set_attr "type" "cr_logical")
12418    (set_attr "cr_logical_3op" "no,yes")])
12420 (define_insn "*cceq_rev_compare"
12421   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12422         (compare:CCEQ (match_operator:SI 1
12423                                       "branch_positive_comparison_operator"
12424                                       [(match_operand 2
12425                                                       "cc_reg_operand" "0,y")
12426                                        (const_int 0)])
12427                       (const_int 0)))]
12428   ""
12429   "crnot %E0,%j1"
12430   [(set_attr "type" "cr_logical")
12431    (set_attr "cr_logical_3op" "no,yes")])
12433 ;; If we are comparing the result of two comparisons, this can be done
12434 ;; using creqv or crxor.
12436 (define_insn_and_split ""
12437   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12438         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12439                               [(match_operand 2 "cc_reg_operand" "y")
12440                                (const_int 0)])
12441                       (match_operator 3 "branch_comparison_operator"
12442                               [(match_operand 4 "cc_reg_operand" "y")
12443                                (const_int 0)])))]
12444   ""
12445   "#"
12446   ""
12447   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12448                                     (match_dup 5)))]
12450   int positive_1, positive_2;
12452   positive_1 = branch_positive_comparison_operator (operands[1],
12453                                                     GET_MODE (operands[1]));
12454   positive_2 = branch_positive_comparison_operator (operands[3],
12455                                                     GET_MODE (operands[3]));
12457   if (! positive_1)
12458     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12459                                                             GET_CODE (operands[1])),
12460                                   SImode,
12461                                   operands[2], const0_rtx);
12462   else if (GET_MODE (operands[1]) != SImode)
12463     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12464                                   operands[2], const0_rtx);
12466   if (! positive_2)
12467     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12468                                                             GET_CODE (operands[3])),
12469                                   SImode,
12470                                   operands[4], const0_rtx);
12471   else if (GET_MODE (operands[3]) != SImode)
12472     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12473                                   operands[4], const0_rtx);
12475   if (positive_1 == positive_2)
12476     {
12477       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12478       operands[5] = constm1_rtx;
12479     }
12480   else
12481     {
12482       operands[5] = const1_rtx;
12483     }
12486 ;; Unconditional branch and return.
12488 (define_insn "jump"
12489   [(set (pc)
12490         (label_ref (match_operand 0)))]
12491   ""
12492   "b %l0"
12493   [(set_attr "type" "branch")])
12495 (define_insn "<return_str>return"
12496   [(any_return)]
12497   "<return_pred>"
12498   "blr"
12499   [(set_attr "type" "jmpreg")])
12501 (define_expand "indirect_jump"
12502   [(set (pc) (match_operand 0 "register_operand"))]
12503  ""
12505   if (!rs6000_speculate_indirect_jumps) {
12506     rtx ccreg = gen_reg_rtx (CCmode);
12507     emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12508     DONE;
12509   }
12512 (define_insn "*indirect_jump<mode>"
12513   [(set (pc)
12514         (match_operand:P 0 "register_operand" "c,*l"))]
12515   "rs6000_speculate_indirect_jumps"
12516   "b%T0"
12517   [(set_attr "type" "jmpreg")])
12519 (define_insn "@indirect_jump<mode>_nospec"
12520   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12521    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12522   "!rs6000_speculate_indirect_jumps"
12523   "crset %E1\;beq%T0- %1\;b $"
12524   [(set_attr "type" "jmpreg")
12525    (set_attr "length" "12")])
12527 ;; Table jump for switch statements:
12528 (define_expand "tablejump"
12529   [(use (match_operand 0))
12530    (use (label_ref (match_operand 1)))]
12531   ""
12533   if (rs6000_speculate_indirect_jumps)
12534     {
12535       if (TARGET_32BIT)
12536         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12537       else
12538         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12539     }
12540   else
12541     {
12542       rtx ccreg = gen_reg_rtx (CCmode);
12543       rtx jump;
12544       if (TARGET_32BIT)
12545         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12546       else
12547         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12548       emit_jump_insn (jump);
12549     }
12550   DONE;
12553 (define_expand "tablejumpsi"
12554   [(set (match_dup 3)
12555         (plus:SI (match_operand:SI 0)
12556                  (match_dup 2)))
12557    (parallel [(set (pc)
12558                    (match_dup 3))
12559               (use (label_ref (match_operand 1)))])]
12560   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12562   operands[0] = force_reg (SImode, operands[0]);
12563   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12564   operands[3] = gen_reg_rtx (SImode);
12567 (define_expand "tablejumpsi_nospec"
12568   [(set (match_dup 4)
12569         (plus:SI (match_operand:SI 0)
12570                  (match_dup 3)))
12571    (parallel [(set (pc)
12572                    (match_dup 4))
12573               (use (label_ref (match_operand 1)))
12574               (clobber (match_operand 2))])]
12575   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12577   operands[0] = force_reg (SImode, operands[0]);
12578   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12579   operands[4] = gen_reg_rtx (SImode);
12582 (define_expand "tablejumpdi"
12583   [(set (match_dup 4)
12584         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12585    (set (match_dup 3)
12586         (plus:DI (match_dup 4)
12587                  (match_dup 2)))
12588    (parallel [(set (pc)
12589                    (match_dup 3))
12590               (use (label_ref (match_operand 1)))])]
12591   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12593   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12594   operands[3] = gen_reg_rtx (DImode);
12595   operands[4] = gen_reg_rtx (DImode);
12598 (define_expand "tablejumpdi_nospec"
12599   [(set (match_dup 5)
12600         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12601    (set (match_dup 4)
12602         (plus:DI (match_dup 5)
12603                  (match_dup 3)))
12604    (parallel [(set (pc)
12605                    (match_dup 4))
12606               (use (label_ref (match_operand 1)))
12607               (clobber (match_operand 2))])]
12608   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12610   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12611   operands[4] = gen_reg_rtx (DImode);
12612   operands[5] = gen_reg_rtx (DImode);
12615 (define_insn "*tablejump<mode>_internal1"
12616   [(set (pc)
12617         (match_operand:P 0 "register_operand" "c,*l"))
12618    (use (label_ref (match_operand 1)))]
12619   "rs6000_speculate_indirect_jumps"
12620   "b%T0"
12621   [(set_attr "type" "jmpreg")])
12623 (define_insn "*tablejump<mode>_internal1_nospec"
12624   [(set (pc)
12625         (match_operand:P 0 "register_operand" "c,*l"))
12626    (use (label_ref (match_operand 1)))
12627    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12628   "!rs6000_speculate_indirect_jumps"
12629   "crset %E2\;beq%T0- %2\;b $"
12630   [(set_attr "type" "jmpreg")
12631    (set_attr "length" "12")])
12633 (define_insn "nop"
12634   [(unspec [(const_int 0)] UNSPEC_NOP)]
12635   ""
12636   "nop")
12638 (define_insn "group_ending_nop"
12639   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12640   ""
12642   operands[0] = gen_rtx_REG (Pmode,
12643                              rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12644   return "ori %0,%0,0";
12647 (define_insn "speculation_barrier"
12648   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12649   ""
12651   operands[0] = gen_rtx_REG (Pmode, 31);
12652   return "ori %0,%0,0";
12655 ;; Define the subtract-one-and-jump insns, starting with the template
12656 ;; so loop.c knows what to generate.
12658 (define_expand "doloop_end"
12659   [(use (match_operand 0))      ; loop pseudo
12660    (use (match_operand 1))]     ; label
12661   ""
12663   if (GET_MODE (operands[0]) != Pmode)
12664     FAIL;
12666   emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12667   DONE;
12670 (define_expand "@ctr<mode>"
12671   [(parallel [(set (pc)
12672                    (if_then_else (ne (match_operand:P 0 "register_operand")
12673                                      (const_int 1))
12674                                  (label_ref (match_operand 1))
12675                                  (pc)))
12676               (set (match_dup 0)
12677                    (plus:P (match_dup 0)
12678                             (const_int -1)))
12679               (clobber (match_scratch:CC 2))
12680               (clobber (match_scratch:P 3))])]
12681   ""
12682   "")
12684 ;; We need to be able to do this for any operand, including MEM, or we
12685 ;; will cause reload to blow up since we don't allow output reloads on
12686 ;; JUMP_INSNs.
12687 ;; For the length attribute to be calculated correctly, the
12688 ;; label MUST be operand 0.
12689 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12690 ;; the ctr<mode> insns.
12692 (define_code_iterator eqne [eq ne])
12693 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12694 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12696 (define_insn "<bd>_<mode>"
12697   [(set (pc)
12698         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12699                           (const_int 1))
12700                       (label_ref (match_operand 0))
12701                       (pc)))
12702    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12703         (plus:P (match_dup 1)
12704                 (const_int -1)))
12705    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12706    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12707   ""
12709   if (which_alternative != 0)
12710     return "#";
12711   else if (get_attr_length (insn) == 4)
12712     return "<bd> %l0";
12713   else
12714     return "<bd_neg> $+8\;b %l0";
12716   [(set_attr "type" "branch")
12717    (set_attr_alternative "length"
12718      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12719                              (const_int -32768))
12720                          (lt (minus (match_dup 0) (pc))
12721                              (const_int 32764)))
12722                     (const_int 4)
12723                     (const_int 8))
12724       (const_string "16")
12725       (const_string "20")
12726       (const_string "20")])])
12728 ;; Now the splitter if we could not allocate the CTR register
12729 (define_split
12730   [(set (pc)
12731         (if_then_else (match_operator 2 "comparison_operator"
12732                                       [(match_operand:P 1 "gpc_reg_operand")
12733                                        (const_int 1)])
12734                       (match_operand 5)
12735                       (match_operand 6)))
12736    (set (match_operand:P 0 "nonimmediate_operand")
12737         (plus:P (match_dup 1)
12738                 (const_int -1)))
12739    (clobber (match_scratch:CC 3))
12740    (clobber (match_scratch:P 4))]
12741   "reload_completed"
12742   [(set (pc)
12743         (if_then_else (match_dup 7)
12744                       (match_dup 5)
12745                       (match_dup 6)))]
12747   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12748                                 const0_rtx);
12749   emit_insn (gen_rtx_SET (operands[3],
12750                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12751   if (int_reg_operand (operands[0], <MODE>mode))
12752     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12753   else
12754     {
12755       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12756       emit_move_insn (operands[0], operands[4]);
12757     } 
12758     /* No DONE so branch comes from the pattern.  */
12761 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12762 ;; Note that in the case of long branches we have to decompose this into
12763 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12764 ;; and the CR bit, which means there is no way to conveniently invert the
12765 ;; comparison as is done with plain bdnz/bdz.
12767 (define_insn "<bd>tf_<mode>"
12768   [(set (pc)
12769         (if_then_else
12770           (and
12771              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12772                    (const_int 1))
12773              (match_operator 3 "branch_comparison_operator"
12774                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12775                        (const_int 0)]))
12776           (label_ref (match_operand 0))
12777           (pc)))
12778    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12779         (plus:P (match_dup 1)
12780                 (const_int -1)))
12781    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12782    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12783    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12784   ""
12786   if (which_alternative != 0)
12787     return "#";
12788   else if (get_attr_length (insn) == 4)
12789     {
12790       if (branch_positive_comparison_operator (operands[3],
12791                                                GET_MODE (operands[3])))
12792         return "<bd>t %j3,%l0";
12793       else
12794         return "<bd>f %j3,%l0";
12795     }
12796   else
12797     {
12798       static char seq[96];
12799       char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12800       sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12801       return seq;
12802     }
12804   [(set_attr "type" "branch")
12805    (set_attr_alternative "length"
12806      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12807                              (const_int -32768))
12808                          (lt (minus (match_dup 0) (pc))
12809                              (const_int 32764)))
12810                     (const_int 4)
12811                     (const_int 8))
12812       (const_string "16")
12813       (const_string "20")
12814       (const_string "20")])])
12816 ;; Now the splitter if we could not allocate the CTR register
12817 (define_split
12818   [(set (pc)
12819         (if_then_else
12820           (and
12821              (match_operator 1 "comparison_operator"
12822                              [(match_operand:P 0 "gpc_reg_operand")
12823                               (const_int 1)])
12824              (match_operator 3 "branch_comparison_operator"
12825                       [(match_operand 2 "cc_reg_operand")
12826                        (const_int 0)]))
12827           (match_operand 4)
12828           (match_operand 5)))
12829    (set (match_operand:P 6 "nonimmediate_operand")
12830         (plus:P (match_dup 0)
12831                 (const_int -1)))
12832    (clobber (match_scratch:P 7))
12833    (clobber (match_scratch:CC 8))
12834    (clobber (match_scratch:CCEQ 9))]
12835   "reload_completed"
12836 [(pc)]
12838   rtx ctr = operands[0];
12839   rtx ctrcmp = operands[1];
12840   rtx ccin = operands[2];
12841   rtx cccmp = operands[3];
12842   rtx dst1 = operands[4];
12843   rtx dst2 = operands[5];
12844   rtx ctrout = operands[6];
12845   rtx ctrtmp = operands[7];
12846   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12847   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12848   if (!ispos)
12849     cmpcode = reverse_condition (cmpcode);
12850   /* Generate crand/crandc here.  */
12851   emit_insn (gen_rtx_SET (operands[8],
12852                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12853   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12855   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12856   if (ispos)
12857      emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12858                                       operands[8], cccmp, ccin));
12859   else
12860      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12861                                                  operands[8], cccmp, ccin));
12862   if (int_reg_operand (ctrout, <MODE>mode))
12863      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12864   else
12865     {
12866       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12867       emit_move_insn (ctrout, ctrtmp);
12868     }
12869   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12870   emit_jump_insn (gen_rtx_SET (pc_rtx,
12871                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12872                                                      dst1, dst2)));
12873   DONE;
12877 (define_insn "trap"
12878   [(trap_if (const_int 1) (const_int 0))]
12879   ""
12880   "trap"
12881   [(set_attr "type" "trap")])
12883 (define_expand "ctrap<mode>4"
12884   [(trap_if (match_operator 0 "ordered_comparison_operator"
12885                             [(match_operand:GPR 1 "register_operand")
12886                              (match_operand:GPR 2 "reg_or_short_operand")])
12887             (match_operand 3 "zero_constant" ""))]
12888   ""
12889   "")
12891 (define_insn ""
12892   [(trap_if (match_operator 0 "ordered_comparison_operator"
12893                             [(match_operand:GPR 1 "register_operand" "r")
12894                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12895             (const_int 0))]
12896   ""
12897   "t<wd>%V0%I2 %1,%2"
12898   [(set_attr "type" "trap")])
12900 ;; Insns related to generating the function prologue and epilogue.
12902 (define_expand "prologue"
12903   [(use (const_int 0))]
12904   ""
12906   rs6000_emit_prologue ();
12907   if (!TARGET_SCHED_PROLOG)
12908     emit_insn (gen_blockage ());
12909   DONE;
12912 (define_insn "*movesi_from_cr_one"
12913   [(match_parallel 0 "mfcr_operation"
12914                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12915                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12916                                      (match_operand 3 "immediate_operand" "n")]
12917                           UNSPEC_MOVESI_FROM_CR))])]
12918   "TARGET_MFCRF"
12920   int mask = 0;
12921   int i;
12922   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12923   {
12924     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12925     operands[4] = GEN_INT (mask);
12926     output_asm_insn ("mfcr %1,%4", operands);
12927   }
12928   return "";
12930   [(set_attr "type" "mfcrf")])
12932 ;; Don't include the volatile CRs since their values are not used wrt CR save
12933 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12934 ;; prologue past an insn (early exit test) that defines a register used in the
12935 ;; prologue.
12936 (define_insn "prologue_movesi_from_cr"
12937   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12938         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12939                     (reg:CC CR4_REGNO)]
12940                    UNSPEC_MOVESI_FROM_CR))]
12941   ""
12942   "mfcr %0"
12943   [(set_attr "type" "mfcr")])
12945 (define_insn "*crsave"
12946   [(match_parallel 0 "crsave_operation"
12947                    [(set (match_operand:SI 1 "memory_operand" "=m")
12948                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12949   ""
12950   "stw %2,%1"
12951   [(set_attr "type" "store")])
12953 (define_insn "*stmw"
12954   [(match_parallel 0 "stmw_operation"
12955                    [(set (match_operand:SI 1 "memory_operand" "=m")
12956                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12957   "TARGET_MULTIPLE"
12958   "stmw %2,%1"
12959   [(set_attr "type" "store")
12960    (set_attr "update" "yes")
12961    (set_attr "indexed" "yes")])
12963 ; The following comment applies to:
12964 ;     save_gpregs_*
12965 ;     save_fpregs_*
12966 ;     restore_gpregs*
12967 ;     return_and_restore_gpregs*
12968 ;     return_and_restore_fpregs*
12969 ;     return_and_restore_fpregs_aix*
12971 ; The out-of-line save / restore functions expects one input argument.
12972 ; Since those are not standard call_insn's, we must avoid using
12973 ; MATCH_OPERAND for that argument. That way the register rename
12974 ; optimization will not try to rename this register.
12975 ; Each pattern is repeated for each possible register number used in 
12976 ; various ABIs (r11, r1, and for some functions r12)
12978 (define_insn "*save_gpregs_<mode>_r11"
12979   [(match_parallel 0 "any_parallel_operand"
12980                    [(clobber (reg:P LR_REGNO))
12981                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12982                     (use (reg:P 11))
12983                     (set (match_operand:P 2 "memory_operand" "=m")
12984                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12985   ""
12986   "bl %1"
12987   [(set_attr "type" "branch")])
12989 (define_insn "*save_gpregs_<mode>_r12"
12990   [(match_parallel 0 "any_parallel_operand"
12991                    [(clobber (reg:P LR_REGNO))
12992                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12993                     (use (reg:P 12))
12994                     (set (match_operand:P 2 "memory_operand" "=m")
12995                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12996   ""
12997   "bl %1"
12998   [(set_attr "type" "branch")])
13000 (define_insn "*save_gpregs_<mode>_r1"
13001   [(match_parallel 0 "any_parallel_operand"
13002                    [(clobber (reg:P LR_REGNO))
13003                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13004                     (use (reg:P 1))
13005                     (set (match_operand:P 2 "memory_operand" "=m")
13006                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13007   ""
13008   "bl %1"
13009   [(set_attr "type" "branch")])
13011 (define_insn "*save_fpregs_<mode>_r11"
13012   [(match_parallel 0 "any_parallel_operand"
13013                    [(clobber (reg:P LR_REGNO))
13014                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13015                     (use (reg:P 11))
13016                     (set (match_operand:DF 2 "memory_operand" "=m")
13017                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13018   ""
13019   "bl %1"
13020   [(set_attr "type" "branch")])
13022 (define_insn "*save_fpregs_<mode>_r12"
13023   [(match_parallel 0 "any_parallel_operand"
13024                    [(clobber (reg:P LR_REGNO))
13025                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13026                     (use (reg:P 12))
13027                     (set (match_operand:DF 2 "memory_operand" "=m")
13028                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13029   ""
13030   "bl %1"
13031   [(set_attr "type" "branch")])
13033 (define_insn "*save_fpregs_<mode>_r1"
13034   [(match_parallel 0 "any_parallel_operand"
13035                    [(clobber (reg:P LR_REGNO))
13036                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13037                     (use (reg:P 1))
13038                     (set (match_operand:DF 2 "memory_operand" "=m")
13039                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13040   ""
13041   "bl %1"
13042   [(set_attr "type" "branch")])
13044 ; This is to explain that changes to the stack pointer should
13045 ; not be moved over loads from or stores to stack memory.
13046 (define_insn "stack_tie"
13047   [(match_parallel 0 "tie_operand"
13048                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13049   ""
13050   ""
13051   [(set_attr "length" "0")])
13053 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13054 ; stay behind all restores from the stack, it cannot be reordered to before
13055 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13056 (define_insn "stack_restore_tie"
13057   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13058         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13059                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13060    (set (mem:BLK (scratch)) (const_int 0))]
13061   "TARGET_32BIT"
13062   "@
13063    mr %0,%1
13064    add%I2 %0,%1,%2"
13065   [(set_attr "type" "*,add")])
13067 (define_expand "epilogue"
13068   [(use (const_int 0))]
13069   ""
13071   if (!TARGET_SCHED_PROLOG)
13072     emit_insn (gen_blockage ());
13073   rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13074   DONE;
13077 ; On some processors, doing the mtcrf one CC register at a time is
13078 ; faster (like on the 604e).  On others, doing them all at once is
13079 ; faster; for instance, on the 601 and 750.
13081 (define_expand "movsi_to_cr_one"
13082   [(set (match_operand:CC 0 "cc_reg_operand")
13083         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13084                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13085   ""
13086   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13088 (define_insn "*movsi_to_cr"
13089   [(match_parallel 0 "mtcrf_operation"
13090                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13091                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13092                                      (match_operand 3 "immediate_operand" "n")]
13093                                     UNSPEC_MOVESI_TO_CR))])]
13094  ""
13096   int mask = 0;
13097   int i;
13098   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13099     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13100   operands[4] = GEN_INT (mask);
13101   return "mtcrf %4,%2";
13103   [(set_attr "type" "mtcr")])
13105 (define_insn "*mtcrfsi"
13106   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13107         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13108                     (match_operand 2 "immediate_operand" "n")]
13109                    UNSPEC_MOVESI_TO_CR))]
13110   "REG_P (operands[0])
13111    && CR_REGNO_P (REGNO (operands[0]))
13112    && CONST_INT_P (operands[2])
13113    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13114   "mtcrf %R0,%1"
13115   [(set_attr "type" "mtcr")])
13117 ; The load-multiple instructions have similar properties.
13118 ; Note that "load_multiple" is a name known to the machine-independent
13119 ; code that actually corresponds to the PowerPC load-string.
13121 (define_insn "*lmw"
13122   [(match_parallel 0 "lmw_operation"
13123                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13124                          (match_operand:SI 2 "memory_operand" "m"))])]
13125   "TARGET_MULTIPLE"
13126   "lmw %1,%2"
13127   [(set_attr "type" "load")
13128    (set_attr "update" "yes")
13129    (set_attr "indexed" "yes")
13130    (set_attr "cell_micro" "always")])
13132 ; FIXME: "any_parallel_operand" is a bit flexible...
13134 ; The following comment applies to:
13135 ;     save_gpregs_*
13136 ;     save_fpregs_*
13137 ;     restore_gpregs*
13138 ;     return_and_restore_gpregs*
13139 ;     return_and_restore_fpregs*
13140 ;     return_and_restore_fpregs_aix*
13142 ; The out-of-line save / restore functions expects one input argument.
13143 ; Since those are not standard call_insn's, we must avoid using
13144 ; MATCH_OPERAND for that argument. That way the register rename
13145 ; optimization will not try to rename this register.
13146 ; Each pattern is repeated for each possible register number used in 
13147 ; various ABIs (r11, r1, and for some functions r12)
13149 (define_insn "*restore_gpregs_<mode>_r11"
13150  [(match_parallel 0 "any_parallel_operand"
13151                   [(clobber (reg:P LR_REGNO))
13152                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13153                    (use (reg:P 11))
13154                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13155                         (match_operand:P 3 "memory_operand" "m"))])]
13156  ""
13157  "bl %1"
13158  [(set_attr "type" "branch")])
13160 (define_insn "*restore_gpregs_<mode>_r12"
13161  [(match_parallel 0 "any_parallel_operand"
13162                   [(clobber (reg:P LR_REGNO))
13163                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13164                    (use (reg:P 12))
13165                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13166                         (match_operand:P 3 "memory_operand" "m"))])]
13167  ""
13168  "bl %1"
13169  [(set_attr "type" "branch")])
13171 (define_insn "*restore_gpregs_<mode>_r1"
13172  [(match_parallel 0 "any_parallel_operand"
13173                   [(clobber (reg:P LR_REGNO))
13174                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13175                    (use (reg:P 1))
13176                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13177                         (match_operand:P 3 "memory_operand" "m"))])]
13178  ""
13179  "bl %1"
13180  [(set_attr "type" "branch")])
13182 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13183  [(match_parallel 0 "any_parallel_operand"
13184                   [(return)
13185                    (clobber (reg:P LR_REGNO))
13186                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13187                    (use (reg:P 11))
13188                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13189                         (match_operand:P 3 "memory_operand" "m"))])]
13190  ""
13191  "b %1"
13192  [(set_attr "type" "branch")])
13194 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13195  [(match_parallel 0 "any_parallel_operand"
13196                   [(return)
13197                    (clobber (reg:P LR_REGNO))
13198                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13199                    (use (reg:P 12))
13200                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13201                         (match_operand:P 3 "memory_operand" "m"))])]
13202  ""
13203  "b %1"
13204  [(set_attr "type" "branch")])
13206 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13207  [(match_parallel 0 "any_parallel_operand"
13208                   [(return)
13209                    (clobber (reg:P LR_REGNO))
13210                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13211                    (use (reg:P 1))
13212                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13213                         (match_operand:P 3 "memory_operand" "m"))])]
13214  ""
13215  "b %1"
13216  [(set_attr "type" "branch")])
13218 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13219  [(match_parallel 0 "any_parallel_operand"
13220                   [(return)
13221                    (clobber (reg:P LR_REGNO))
13222                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13223                    (use (reg:P 11))
13224                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13225                         (match_operand:DF 3 "memory_operand" "m"))])]
13226  ""
13227  "b %1"
13228  [(set_attr "type" "branch")])
13230 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13231  [(match_parallel 0 "any_parallel_operand"
13232                   [(return)
13233                    (clobber (reg:P LR_REGNO))
13234                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13235                    (use (reg:P 12))
13236                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13237                         (match_operand:DF 3 "memory_operand" "m"))])]
13238  ""
13239  "b %1"
13240  [(set_attr "type" "branch")])
13242 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13243  [(match_parallel 0 "any_parallel_operand"
13244                   [(return)
13245                    (clobber (reg:P LR_REGNO))
13246                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13247                    (use (reg:P 1))
13248                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13249                         (match_operand:DF 3 "memory_operand" "m"))])]
13250  ""
13251  "b %1"
13252  [(set_attr "type" "branch")])
13254 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13255  [(match_parallel 0 "any_parallel_operand"
13256                   [(return)
13257                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13258                    (use (reg:P 11))
13259                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13260                         (match_operand:DF 3 "memory_operand" "m"))])]
13261  ""
13262  "b %1"
13263  [(set_attr "type" "branch")])
13265 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13266  [(match_parallel 0 "any_parallel_operand"
13267                   [(return)
13268                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13269                    (use (reg:P 1))
13270                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13271                         (match_operand:DF 3 "memory_operand" "m"))])]
13272  ""
13273  "b %1"
13274  [(set_attr "type" "branch")])
13276 ; This is used in compiling the unwind routines.
13277 (define_expand "eh_return"
13278   [(use (match_operand 0 "general_operand"))]
13279   ""
13281   emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13282   DONE;
13285 ; We can't expand this before we know where the link register is stored.
13286 (define_insn_and_split "@eh_set_lr_<mode>"
13287   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13288    (clobber (match_scratch:P 1 "=&b"))]
13289   ""
13290   "#"
13291   "reload_completed"
13292   [(const_int 0)]
13294   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13295   DONE;
13298 (define_insn "prefetch"
13299   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13300              (match_operand:SI 1 "const_int_operand" "n")
13301              (match_operand:SI 2 "const_int_operand" "n"))]
13302   ""
13306   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13307      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13308      The AIX assembler does not support the three operand form of dcbt
13309      and dcbtst on Power 7 (-mpwr7).  */
13310   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13312   if (REG_P (operands[0]))
13313     {
13314       if (INTVAL (operands[1]) == 0)
13315         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13316       else
13317         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13318     }
13319   else
13320     {
13321       if (INTVAL (operands[1]) == 0)
13322         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13323       else
13324         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13325     }
13327   [(set_attr "type" "load")])
13329 ;; Handle -fsplit-stack.
13331 (define_expand "split_stack_prologue"
13332   [(const_int 0)]
13333   ""
13335   rs6000_expand_split_stack_prologue ();
13336   DONE;
13339 (define_expand "load_split_stack_limit"
13340   [(set (match_operand 0)
13341         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13342   ""
13344   emit_insn (gen_rtx_SET (operands[0],
13345                           gen_rtx_UNSPEC (Pmode,
13346                                           gen_rtvec (1, const0_rtx),
13347                                           UNSPEC_STACK_CHECK)));
13348   DONE;
13351 (define_insn "load_split_stack_limit_di"
13352   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13353         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13354   "TARGET_64BIT"
13355   "ld %0,-0x7040(13)"
13356   [(set_attr "type" "load")
13357    (set_attr "update" "no")
13358    (set_attr "indexed" "no")])
13360 (define_insn "load_split_stack_limit_si"
13361   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13362         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13363   "!TARGET_64BIT"
13364   "lwz %0,-0x7020(2)"
13365   [(set_attr "type" "load")
13366    (set_attr "update" "no")
13367    (set_attr "indexed" "no")])
13369 ;; A return instruction which the middle-end doesn't see.
13370 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13371 ;; after the call to __morestack.
13372 (define_insn "split_stack_return"
13373   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13374   ""
13375   "blr"
13376   [(set_attr "type" "jmpreg")])
13378 ;; If there are operand 0 bytes available on the stack, jump to
13379 ;; operand 1.
13380 (define_expand "split_stack_space_check"
13381   [(set (match_dup 2)
13382         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13383    (set (match_dup 3)
13384         (minus (reg STACK_POINTER_REGNUM)
13385                (match_operand 0)))
13386    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13387    (set (pc) (if_then_else
13388               (geu (match_dup 4) (const_int 0))
13389               (label_ref (match_operand 1))
13390               (pc)))]
13391   ""
13393   rs6000_split_stack_space_check (operands[0], operands[1]);
13394   DONE;
13397 (define_insn "bpermd_<mode>"
13398   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13399         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13400                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13401   "TARGET_POPCNTD"
13402   "bpermd %0,%1,%2"
13403   [(set_attr "type" "popcnt")])
13406 ;; Builtin fma support.  Handle 
13407 ;; Note that the conditions for expansion are in the FMA_F iterator.
13409 (define_expand "fma<mode>4"
13410   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13411         (fma:FMA_F
13412           (match_operand:FMA_F 1 "gpc_reg_operand")
13413           (match_operand:FMA_F 2 "gpc_reg_operand")
13414           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13415   ""
13416   "")
13418 (define_insn "*fma<mode>4_fpr"
13419   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13420         (fma:SFDF
13421           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13422           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13423           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13424   "TARGET_HARD_FLOAT"
13425   "@
13426    fmadd<s> %0,%1,%2,%3
13427    xsmadda<sd>p %x0,%x1,%x2
13428    xsmaddm<sd>p %x0,%x1,%x3"
13429   [(set_attr "type" "fp")
13430    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13432 ; Altivec only has fma and nfms.
13433 (define_expand "fms<mode>4"
13434   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13435         (fma:FMA_F
13436           (match_operand:FMA_F 1 "gpc_reg_operand")
13437           (match_operand:FMA_F 2 "gpc_reg_operand")
13438           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13439   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13440   "")
13442 (define_insn "*fms<mode>4_fpr"
13443   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13444         (fma:SFDF
13445          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13446          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13447          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13448   "TARGET_HARD_FLOAT"
13449   "@
13450    fmsub<s> %0,%1,%2,%3
13451    xsmsuba<sd>p %x0,%x1,%x2
13452    xsmsubm<sd>p %x0,%x1,%x3"
13453   [(set_attr "type" "fp")
13454    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13456 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13457 (define_expand "fnma<mode>4"
13458   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13459         (neg:FMA_F
13460           (fma:FMA_F
13461             (match_operand:FMA_F 1 "gpc_reg_operand")
13462             (match_operand:FMA_F 2 "gpc_reg_operand")
13463             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13464   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13465   "")
13467 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13468 (define_expand "fnms<mode>4"
13469   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13470         (neg:FMA_F
13471           (fma:FMA_F
13472             (match_operand:FMA_F 1 "gpc_reg_operand")
13473             (match_operand:FMA_F 2 "gpc_reg_operand")
13474             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13475   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13476   "")
13478 ; Not an official optab name, but used from builtins.
13479 (define_expand "nfma<mode>4"
13480   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13481         (neg:FMA_F
13482           (fma:FMA_F
13483             (match_operand:FMA_F 1 "gpc_reg_operand")
13484             (match_operand:FMA_F 2 "gpc_reg_operand")
13485             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13486   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13487   "")
13489 (define_insn "*nfma<mode>4_fpr"
13490   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13491         (neg:SFDF
13492          (fma:SFDF
13493           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13494           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13495           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13496   "TARGET_HARD_FLOAT"
13497   "@
13498    fnmadd<s> %0,%1,%2,%3
13499    xsnmadda<sd>p %x0,%x1,%x2
13500    xsnmaddm<sd>p %x0,%x1,%x3"
13501   [(set_attr "type" "fp")
13502    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13504 ; Not an official optab name, but used from builtins.
13505 (define_expand "nfms<mode>4"
13506   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13507         (neg:FMA_F
13508           (fma:FMA_F
13509             (match_operand:FMA_F 1 "gpc_reg_operand")
13510             (match_operand:FMA_F 2 "gpc_reg_operand")
13511             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13512   ""
13513   "")
13515 (define_insn "*nfmssf4_fpr"
13516   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13517         (neg:SFDF
13518          (fma:SFDF
13519           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13520           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13521           (neg:SFDF
13522            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13523   "TARGET_HARD_FLOAT"
13524   "@
13525    fnmsub<s> %0,%1,%2,%3
13526    xsnmsuba<sd>p %x0,%x1,%x2
13527    xsnmsubm<sd>p %x0,%x1,%x3"
13528   [(set_attr "type" "fp")
13529    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13531 (define_expand "rs6000_get_timebase"
13532   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13533   ""
13535   if (TARGET_POWERPC64)
13536     emit_insn (gen_rs6000_mftb_di (operands[0]));
13537   else
13538     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13539   DONE;
13542 (define_insn "rs6000_get_timebase_ppc32"
13543   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13544         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13545    (clobber (match_scratch:SI 1 "=r"))
13546    (clobber (match_scratch:CC 2 "=y"))]
13547   "!TARGET_POWERPC64"
13549   if (WORDS_BIG_ENDIAN)
13550     if (TARGET_MFCRF)
13551       {
13552         return "mfspr %0,269\;"
13553                "mfspr %L0,268\;"
13554                "mfspr %1,269\;"
13555                "cmpw %2,%0,%1\;"
13556                "bne- %2,$-16";
13557       }
13558     else
13559       {
13560         return "mftbu %0\;"
13561                "mftb %L0\;"
13562                "mftbu %1\;"
13563                "cmpw %2,%0,%1\;"
13564                "bne- %2,$-16";
13565       }
13566   else
13567     if (TARGET_MFCRF)
13568       {
13569         return "mfspr %L0,269\;"
13570                "mfspr %0,268\;"
13571                "mfspr %1,269\;"
13572                "cmpw %2,%L0,%1\;"
13573                "bne- %2,$-16";
13574       }
13575     else
13576       {
13577         return "mftbu %L0\;"
13578                "mftb %0\;"
13579                "mftbu %1\;"
13580                "cmpw %2,%L0,%1\;"
13581                "bne- %2,$-16";
13582       }
13584   [(set_attr "length" "20")])
13586 (define_insn "rs6000_mftb_<mode>"
13587   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13588         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13589   ""
13591   if (TARGET_MFCRF)
13592     return "mfspr %0,268";
13593   else
13594     return "mftb %0";
13598 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13599 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13600 (define_insn "rs6000_mffsl_hw"
13601   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13602         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13603   "TARGET_HARD_FLOAT"
13604   "mffsl %0")
13606 (define_expand "rs6000_mffsl"
13607   [(set (match_operand:DF 0 "gpc_reg_operand")
13608         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13609   "TARGET_HARD_FLOAT"
13611   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13612      otherwise fall back to the older mffs instruction to emulate the mffsl
13613      instruction.  */
13615   if (!TARGET_P9_MISC)
13616     {
13617        rtx tmp_di = gen_reg_rtx (DImode);
13618        rtx tmp_df = gen_reg_rtx (DFmode);
13620        /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13621           instruction using the mffs instruction and masking off the bits
13622           the mmsl instruciton actually reads.  */
13623        emit_insn (gen_rs6000_mffs (tmp_df));
13624        tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13625        emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13627        operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13628        DONE;
13629     }
13631     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13632     DONE;
13635 (define_insn "rs6000_mffs"
13636   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13637         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13638   "TARGET_HARD_FLOAT"
13639   "mffs %0")
13641 (define_insn "rs6000_mtfsf"
13642   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13643                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13644                     UNSPECV_MTFSF)]
13645   "TARGET_HARD_FLOAT"
13646   "mtfsf %0,%1")
13648 (define_insn "rs6000_mtfsf_hi"
13649   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13650                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13651                     UNSPECV_MTFSF_HI)]
13652   "TARGET_HARD_FLOAT"
13653   "mtfsf %0,%1,0,1")
13656 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13657 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13658 ;; register that is being loaded.  The fused ops must be physically adjacent.
13660 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13661 ;; peephole2 then gathers any other fused possibilities that it can find after
13662 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13663 ;; point loads/stores.
13665 ;; Find cases where the addis that feeds into a load instruction is either used
13666 ;; once or is the same as the target register, and replace it with the fusion
13667 ;; insn
13669 (define_peephole2
13670   [(set (match_operand:P 0 "base_reg_operand")
13671         (match_operand:P 1 "fusion_gpr_addis"))
13672    (set (match_operand:INT1 2 "base_reg_operand")
13673         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13674   "TARGET_P8_FUSION
13675    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13676                          operands[3])"
13677   [(const_int 0)]
13679   expand_fusion_gpr_load (operands);
13680   DONE;
13683 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13684 ;; reload)
13686 (define_insn "*fusion_gpr_load_<mode>"
13687   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13688         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13689                      UNSPEC_FUSION_GPR))]
13690   "TARGET_P8_FUSION"
13692   return emit_fusion_gpr_load (operands[0], operands[1]);
13694   [(set_attr "type" "load")
13695    (set_attr "length" "8")])
13698 ;; Optimize cases where we want to do a D-form load (register+offset) on
13699 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13700 ;; has generated:
13701 ;;      LFD 0,32(3)
13702 ;;      XXLOR 32,0,0
13704 ;; and we change this to:
13705 ;;      LI 0,32
13706 ;;      LXSDX 32,3,9
13708 (define_peephole2
13709   [(match_scratch:P 0 "b")
13710    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13711         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13712    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13713         (match_dup 1))]
13714   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13715   [(set (match_dup 0)
13716         (match_dup 4))
13717    (set (match_dup 3)
13718         (match_dup 5))]
13720   rtx tmp_reg = operands[0];
13721   rtx mem = operands[2];
13722   rtx addr = XEXP (mem, 0);
13723   rtx add_op0, add_op1, new_addr;
13725   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13726   add_op0 = XEXP (addr, 0);
13727   add_op1 = XEXP (addr, 1);
13728   gcc_assert (REG_P (add_op0));
13729   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13731   operands[4] = add_op1;
13732   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13735 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13736 ;; Altivec register, and the register allocator has generated:
13737 ;;      XXLOR 0,32,32
13738 ;;      STFD 0,32(3)
13740 ;; and we change this to:
13741 ;;      LI 0,32
13742 ;;      STXSDX 32,3,9
13744 (define_peephole2
13745   [(match_scratch:P 0 "b")
13746    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13747         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13748    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13749         (match_dup 1))]
13750   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13751   [(set (match_dup 0)
13752         (match_dup 4))
13753    (set (match_dup 5)
13754         (match_dup 2))]
13756   rtx tmp_reg = operands[0];
13757   rtx mem = operands[3];
13758   rtx addr = XEXP (mem, 0);
13759   rtx add_op0, add_op1, new_addr;
13761   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13762   add_op0 = XEXP (addr, 0);
13763   add_op1 = XEXP (addr, 1);
13764   gcc_assert (REG_P (add_op0));
13765   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13767   operands[4] = add_op1;
13768   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13770    
13772 ;; Miscellaneous ISA 2.06 (power7) instructions
13773 (define_insn "addg6s"
13774   [(set (match_operand:SI 0 "register_operand" "=r")
13775         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13776                     (match_operand:SI 2 "register_operand" "r")]
13777                    UNSPEC_ADDG6S))]
13778   "TARGET_POPCNTD"
13779   "addg6s %0,%1,%2"
13780   [(set_attr "type" "integer")])
13782 (define_insn "cdtbcd"
13783   [(set (match_operand:SI 0 "register_operand" "=r")
13784         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13785                    UNSPEC_CDTBCD))]
13786   "TARGET_POPCNTD"
13787   "cdtbcd %0,%1"
13788   [(set_attr "type" "integer")])
13790 (define_insn "cbcdtd"
13791   [(set (match_operand:SI 0 "register_operand" "=r")
13792         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13793                    UNSPEC_CBCDTD))]
13794   "TARGET_POPCNTD"
13795   "cbcdtd %0,%1"
13796   [(set_attr "type" "integer")])
13798 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13799                                         UNSPEC_DIVEU])
13801 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13802                              (UNSPEC_DIVEU      "eu")])
13804 (define_insn "div<div_extend>_<mode>"
13805   [(set (match_operand:GPR 0 "register_operand" "=r")
13806         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13807                      (match_operand:GPR 2 "register_operand" "r")]
13808                     UNSPEC_DIV_EXTEND))]
13809   "TARGET_POPCNTD"
13810   "div<wd><div_extend> %0,%1,%2"
13811   [(set_attr "type" "div")
13812    (set_attr "size" "<bits>")])
13815 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13817 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13818 (define_mode_attr FP128_64 [(TF "DF")
13819                             (IF "DF")
13820                             (TD "DI")
13821                             (KF "DI")])
13823 (define_expand "unpack<mode>"
13824   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13825         (unspec:<FP128_64>
13826          [(match_operand:FMOVE128 1 "register_operand")
13827           (match_operand:QI 2 "const_0_to_1_operand")]
13828          UNSPEC_UNPACK_128BIT))]
13829   "FLOAT128_2REG_P (<MODE>mode)"
13830   "")
13832 (define_insn_and_split "unpack<mode>_dm"
13833   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13834         (unspec:<FP128_64>
13835          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13836           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13837          UNSPEC_UNPACK_128BIT))]
13838   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13839   "#"
13840   "&& reload_completed"
13841   [(set (match_dup 0) (match_dup 3))]
13843   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13845   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13846     {
13847       emit_note (NOTE_INSN_DELETED);
13848       DONE;
13849     }
13851   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13853   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13855 (define_insn_and_split "unpack<mode>_nodm"
13856   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13857         (unspec:<FP128_64>
13858          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13859           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13860          UNSPEC_UNPACK_128BIT))]
13861   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13862   "#"
13863   "&& reload_completed"
13864   [(set (match_dup 0) (match_dup 3))]
13866   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13868   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13869     {
13870       emit_note (NOTE_INSN_DELETED);
13871       DONE;
13872     }
13874   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13876   [(set_attr "type" "fp,fpstore")])
13878 (define_insn_and_split "pack<mode>"
13879   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13880         (unspec:FMOVE128
13881          [(match_operand:<FP128_64> 1 "register_operand" "d")
13882           (match_operand:<FP128_64> 2 "register_operand" "d")]
13883          UNSPEC_PACK_128BIT))]
13884   "FLOAT128_2REG_P (<MODE>mode)"
13885   "#"
13886   "&& reload_completed"
13887   [(set (match_dup 3) (match_dup 1))
13888    (set (match_dup 4) (match_dup 2))]
13890   unsigned dest_hi = REGNO (operands[0]);
13891   unsigned dest_lo = dest_hi + 1;
13893   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13894   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13896   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13897   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13899   [(set_attr "type" "fp")
13900    (set_attr "length" "8")])
13902 (define_insn "unpack<mode>"
13903   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13904         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13905                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13906          UNSPEC_UNPACK_128BIT))]
13907   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13909   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13910     return ASM_COMMENT_START " xxpermdi to same register";
13912   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13913   return "xxpermdi %x0,%x1,%x1,%3";
13915   [(set_attr "type" "vecperm")])
13917 (define_insn "pack<mode>"
13918   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13919         (unspec:FMOVE128_VSX
13920          [(match_operand:DI 1 "register_operand" "wa")
13921           (match_operand:DI 2 "register_operand" "wa")]
13922          UNSPEC_PACK_128BIT))]
13923   "TARGET_VSX"
13924   "xxpermdi %x0,%x1,%x2,0"
13925   [(set_attr "type" "vecperm")])
13929 ;; ISA 2.08 IEEE 128-bit floating point support.
13931 (define_insn "add<mode>3"
13932   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13933         (plus:IEEE128
13934          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13935          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13936   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13937   "xsaddqp %0,%1,%2"
13938   [(set_attr "type" "vecfloat")
13939    (set_attr "size" "128")])
13941 (define_insn "sub<mode>3"
13942   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13943         (minus:IEEE128
13944          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13945          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13946   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13947   "xssubqp %0,%1,%2"
13948   [(set_attr "type" "vecfloat")
13949    (set_attr "size" "128")])
13951 (define_insn "mul<mode>3"
13952   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13953         (mult:IEEE128
13954          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13955          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13956   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13957   "xsmulqp %0,%1,%2"
13958   [(set_attr "type" "qmul")
13959    (set_attr "size" "128")])
13961 (define_insn "div<mode>3"
13962   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13963         (div:IEEE128
13964          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13965          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13966   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13967   "xsdivqp %0,%1,%2"
13968   [(set_attr "type" "vecdiv")
13969    (set_attr "size" "128")])
13971 (define_insn "sqrt<mode>2"
13972   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13973         (sqrt:IEEE128
13974          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13975   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13976    "xssqrtqp %0,%1"
13977   [(set_attr "type" "vecdiv")
13978    (set_attr "size" "128")])
13980 (define_expand "copysign<mode>3"
13981   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13982    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13983    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13984   "FLOAT128_IEEE_P (<MODE>mode)"
13986   if (TARGET_FLOAT128_HW)
13987     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13988                                          operands[2]));
13989   else
13990     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13991                                          operands[2]));
13992   DONE;
13995 (define_insn "copysign<mode>3_hard"
13996   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13997         (unspec:IEEE128
13998          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13999           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14000          UNSPEC_COPYSIGN))]
14001   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14002    "xscpsgnqp %0,%2,%1"
14003   [(set_attr "type" "vecmove")
14004    (set_attr "size" "128")])
14006 (define_insn "copysign<mode>3_soft"
14007   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14008         (unspec:IEEE128
14009          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14010           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14011          UNSPEC_COPYSIGN))
14012    (clobber (match_scratch:IEEE128 3 "=&v"))]
14013   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14014    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14015   [(set_attr "type" "veccomplex")
14016    (set_attr "length" "8")])
14018 (define_insn "@neg<mode>2_hw"
14019   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14020         (neg:IEEE128
14021          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14022   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14023   "xsnegqp %0,%1"
14024   [(set_attr "type" "vecmove")
14025    (set_attr "size" "128")])
14028 (define_insn "@abs<mode>2_hw"
14029   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14030         (abs:IEEE128
14031          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14032   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14033   "xsabsqp %0,%1"
14034   [(set_attr "type" "vecmove")
14035    (set_attr "size" "128")])
14038 (define_insn "*nabs<mode>2_hw"
14039   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14040         (neg:IEEE128
14041          (abs:IEEE128
14042           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14043   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14044   "xsnabsqp %0,%1"
14045   [(set_attr "type" "vecmove")
14046    (set_attr "size" "128")])
14048 ;; Initially don't worry about doing fusion
14049 (define_insn "fma<mode>4_hw"
14050   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14051         (fma:IEEE128
14052          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14053          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14054          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14055   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14056   "xsmaddqp %0,%1,%2"
14057   [(set_attr "type" "qmul")
14058    (set_attr "size" "128")])
14060 (define_insn "*fms<mode>4_hw"
14061   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14062         (fma:IEEE128
14063          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14064          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14065          (neg:IEEE128
14066           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14067   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14068   "xsmsubqp %0,%1,%2"
14069   [(set_attr "type" "qmul")
14070    (set_attr "size" "128")])
14072 (define_insn "*nfma<mode>4_hw"
14073   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14074         (neg:IEEE128
14075          (fma:IEEE128
14076           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14077           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14078           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14079   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14080   "xsnmaddqp %0,%1,%2"
14081   [(set_attr "type" "qmul")
14082    (set_attr "size" "128")])
14084 (define_insn "*nfms<mode>4_hw"
14085   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14086         (neg:IEEE128
14087          (fma:IEEE128
14088           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14089           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14090           (neg:IEEE128
14091            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14092   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14093   "xsnmsubqp %0,%1,%2"
14094   [(set_attr "type" "qmul")
14095    (set_attr "size" "128")])
14097 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14098   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14099         (float_extend:IEEE128
14100          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14101   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14102   "xscvdpqp %0,%1"
14103   [(set_attr "type" "vecfloat")
14104    (set_attr "size" "128")])
14106 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14107 ;; point is a simple copy.
14108 (define_insn_and_split "extendkftf2"
14109   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14110         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14111   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14112   "@
14113    #
14114    xxlor %x0,%x1,%x1"
14115   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14116   [(const_int 0)]
14118   emit_note (NOTE_INSN_DELETED);
14119   DONE;
14121   [(set_attr "type" "*,veclogical")
14122    (set_attr "length" "0,4")])
14124 (define_insn_and_split "trunctfkf2"
14125   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14126         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14127   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14128   "@
14129    #
14130    xxlor %x0,%x1,%x1"
14131   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14132   [(const_int 0)]
14134   emit_note (NOTE_INSN_DELETED);
14135   DONE;
14137   [(set_attr "type" "*,veclogical")
14138    (set_attr "length" "0,4")])
14140 (define_insn "trunc<mode>df2_hw"
14141   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14142         (float_truncate:DF
14143          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14144   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14145   "xscvqpdp %0,%1"
14146   [(set_attr "type" "vecfloat")
14147    (set_attr "size" "128")])
14149 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14150 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14151 ;; conversion
14152 (define_insn_and_split "trunc<mode>sf2_hw"
14153   [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14154         (float_truncate:SF
14155          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14156    (clobber (match_scratch:DF 2 "=v"))]
14157   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14158   "#"
14159   "&& 1"
14160   [(set (match_dup 2)
14161         (unspec:DF [(match_dup 1)]
14162                    UNSPEC_TRUNC_ROUND_TO_ODD))
14163    (set (match_dup 0)
14164         (float_truncate:SF (match_dup 2)))]
14166   if (GET_CODE (operands[2]) == SCRATCH)
14167     operands[2] = gen_reg_rtx (DFmode);
14169   [(set_attr "type" "vecfloat")
14170    (set_attr "length" "8")
14171    (set_attr "isa" "p8v")])
14173 ;; Conversion between IEEE 128-bit and integer types
14175 ;; The fix function for DImode and SImode was declared earlier as a
14176 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14177 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14178 ;; unless we have the IEEE 128-bit hardware.
14180 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14181 ;; to provide a GPR target that used direct move and a conversion in the GPR
14182 ;; which works around QImode/HImode not being allowed in vector registers in
14183 ;; ISA 2.07 (power8).
14184 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14185   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14186         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14187   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14188   "xscvqp<su><wd>z %0,%1"
14189   [(set_attr "type" "vecfloat")
14190    (set_attr "size" "128")])
14192 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14193   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14194         (any_fix:QHI
14195          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14196   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14197   "xscvqp<su>wz %0,%1"
14198   [(set_attr "type" "vecfloat")
14199    (set_attr "size" "128")])
14201 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14202 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14203 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14204   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14205         (any_fix:QHSI
14206          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14207    (clobber (match_scratch:QHSI 2 "=v"))]
14208   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14209   "#"
14210   "&& reload_completed"
14211   [(set (match_dup 2)
14212         (any_fix:QHSI (match_dup 1)))
14213    (set (match_dup 0)
14214         (match_dup 2))])
14216 (define_insn "float_<mode>di2_hw"
14217   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14218         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14219   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14220   "xscvsdqp %0,%1"
14221   [(set_attr "type" "vecfloat")
14222    (set_attr "size" "128")])
14224 (define_insn_and_split "float_<mode>si2_hw"
14225   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14226         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14227    (clobber (match_scratch:DI 2 "=v"))]
14228   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14229   "#"
14230   "&& 1"
14231   [(set (match_dup 2)
14232         (sign_extend:DI (match_dup 1)))
14233    (set (match_dup 0)
14234         (float:IEEE128 (match_dup 2)))]
14236   if (GET_CODE (operands[2]) == SCRATCH)
14237     operands[2] = gen_reg_rtx (DImode);
14239   if (MEM_P (operands[1]))
14240     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14243 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14244   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14245         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14246    (clobber (match_scratch:DI 2 "=X,r,X"))]
14247   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14248   "#"
14249   "&& reload_completed"
14250   [(const_int 0)]
14252   rtx dest = operands[0];
14253   rtx src = operands[1];
14254   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14256   if (altivec_register_operand (src, <QHI:MODE>mode))
14257     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14258   else if (int_reg_operand (src, <QHI:MODE>mode))
14259     {
14260       rtx ext_di = operands[2];
14261       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14262       emit_move_insn (dest_di, ext_di);
14263     }
14264   else if (MEM_P (src))
14265     {
14266       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14267       emit_move_insn (dest_qhi, src);
14268       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14269     }
14270   else
14271     gcc_unreachable ();
14273   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14274   DONE;
14276   [(set_attr "length" "8,12,12")
14277    (set_attr "type" "vecfloat")
14278    (set_attr "size" "128")])
14280 (define_insn "floatuns_<mode>di2_hw"
14281   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14282         (unsigned_float:IEEE128
14283          (match_operand:DI 1 "altivec_register_operand" "v")))]
14284   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14285   "xscvudqp %0,%1"
14286   [(set_attr "type" "vecfloat")
14287    (set_attr "size" "128")])
14289 (define_insn_and_split "floatuns_<mode>si2_hw"
14290   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14291         (unsigned_float:IEEE128
14292          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14293    (clobber (match_scratch:DI 2 "=v"))]
14294   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14295   "#"
14296   "&& 1"
14297   [(set (match_dup 2)
14298         (zero_extend:DI (match_dup 1)))
14299    (set (match_dup 0)
14300         (float:IEEE128 (match_dup 2)))]
14302   if (GET_CODE (operands[2]) == SCRATCH)
14303     operands[2] = gen_reg_rtx (DImode);
14305   if (MEM_P (operands[1]))
14306     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14309 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14310   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14311         (unsigned_float:IEEE128
14312          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14313    (clobber (match_scratch:DI 2 "=X,r,X"))]
14314   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14315   "#"
14316   "&& reload_completed"
14317   [(const_int 0)]
14319   rtx dest = operands[0];
14320   rtx src = operands[1];
14321   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14323   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14324     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14325   else if (int_reg_operand (src, <QHI:MODE>mode))
14326     {
14327       rtx ext_di = operands[2];
14328       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14329       emit_move_insn (dest_di, ext_di);
14330     }
14331   else
14332     gcc_unreachable ();
14334   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14335   DONE;
14337   [(set_attr "length" "8,12,8")
14338    (set_attr "type" "vecfloat")
14339    (set_attr "size" "128")])
14341 ;; IEEE 128-bit round to integer built-in functions
14342 (define_insn "floor<mode>2"
14343   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14344         (unspec:IEEE128
14345          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14346          UNSPEC_FRIM))]
14347   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14348   "xsrqpi 1,%0,%1,3"
14349   [(set_attr "type" "vecfloat")
14350    (set_attr "size" "128")])
14352 (define_insn "ceil<mode>2"
14353   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14354         (unspec:IEEE128
14355          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14356          UNSPEC_FRIP))]
14357   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14358   "xsrqpi 1,%0,%1,2"
14359   [(set_attr "type" "vecfloat")
14360    (set_attr "size" "128")])
14362 (define_insn "btrunc<mode>2"
14363   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14364         (unspec:IEEE128
14365          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14366          UNSPEC_FRIZ))]
14367   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14368   "xsrqpi 1,%0,%1,1"
14369   [(set_attr "type" "vecfloat")
14370    (set_attr "size" "128")])
14372 (define_insn "round<mode>2"
14373   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14374         (unspec:IEEE128
14375          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14376          UNSPEC_FRIN))]
14377   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14378   "xsrqpi 0,%0,%1,0"
14379   [(set_attr "type" "vecfloat")
14380    (set_attr "size" "128")])
14382 ;; IEEE 128-bit instructions with round to odd semantics
14383 (define_insn "add<mode>3_odd"
14384   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14385         (unspec:IEEE128
14386          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14387           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14388          UNSPEC_ADD_ROUND_TO_ODD))]
14389   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14390   "xsaddqpo %0,%1,%2"
14391   [(set_attr "type" "vecfloat")
14392    (set_attr "size" "128")])
14394 (define_insn "sub<mode>3_odd"
14395   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14396         (unspec:IEEE128
14397          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14398           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14399          UNSPEC_SUB_ROUND_TO_ODD))]
14400   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14401   "xssubqpo %0,%1,%2"
14402   [(set_attr "type" "vecfloat")
14403    (set_attr "size" "128")])
14405 (define_insn "mul<mode>3_odd"
14406   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14407         (unspec:IEEE128
14408          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14409           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14410          UNSPEC_MUL_ROUND_TO_ODD))]
14411   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14412   "xsmulqpo %0,%1,%2"
14413   [(set_attr "type" "qmul")
14414    (set_attr "size" "128")])
14416 (define_insn "div<mode>3_odd"
14417   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14418         (unspec:IEEE128
14419          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14420           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14421          UNSPEC_DIV_ROUND_TO_ODD))]
14422   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14423   "xsdivqpo %0,%1,%2"
14424   [(set_attr "type" "vecdiv")
14425    (set_attr "size" "128")])
14427 (define_insn "sqrt<mode>2_odd"
14428   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14429         (unspec:IEEE128
14430          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14431          UNSPEC_SQRT_ROUND_TO_ODD))]
14432   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14433    "xssqrtqpo %0,%1"
14434   [(set_attr "type" "vecdiv")
14435    (set_attr "size" "128")])
14437 (define_insn "fma<mode>4_odd"
14438   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14439         (unspec:IEEE128
14440          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14441           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14442           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14443          UNSPEC_FMA_ROUND_TO_ODD))]
14444   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14445   "xsmaddqpo %0,%1,%2"
14446   [(set_attr "type" "qmul")
14447    (set_attr "size" "128")])
14449 (define_insn "*fms<mode>4_odd"
14450   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14451         (unspec:IEEE128
14452          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14453           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14454           (neg:IEEE128
14455            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14456          UNSPEC_FMA_ROUND_TO_ODD))]
14457   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14458   "xsmsubqpo %0,%1,%2"
14459   [(set_attr "type" "qmul")
14460    (set_attr "size" "128")])
14462 (define_insn "*nfma<mode>4_odd"
14463   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14464         (neg:IEEE128
14465          (unspec:IEEE128
14466           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14467            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14468            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14469           UNSPEC_FMA_ROUND_TO_ODD)))]
14470   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14471   "xsnmaddqpo %0,%1,%2"
14472   [(set_attr "type" "qmul")
14473    (set_attr "size" "128")])
14475 (define_insn "*nfms<mode>4_odd"
14476   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14477         (neg:IEEE128
14478          (unspec:IEEE128
14479           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14480            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14481            (neg:IEEE128
14482             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14483           UNSPEC_FMA_ROUND_TO_ODD)))]
14484   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14485   "xsnmsubqpo %0,%1,%2"
14486   [(set_attr "type" "qmul")
14487    (set_attr "size" "128")])
14489 (define_insn "trunc<mode>df2_odd"
14490   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14491         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14492                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14493   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14494   "xscvqpdpo %0,%1"
14495   [(set_attr "type" "vecfloat")
14496    (set_attr "size" "128")])
14498 ;; IEEE 128-bit comparisons
14499 (define_insn "*cmp<mode>_hw"
14500   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14501         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14502                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14503   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14504    "xscmpuqp %0,%1,%2"
14505   [(set_attr "type" "veccmp")
14506    (set_attr "size" "128")])
14508 ;; Miscellaneous ISA 3.0 (power9) instructions
14510 (define_insn "darn_32"
14511   [(set (match_operand:SI 0 "register_operand" "=r")
14512         (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14513   "TARGET_P9_MISC"
14514   "darn %0,0"
14515   [(set_attr "type" "integer")])
14517 (define_insn "darn_raw"
14518   [(set (match_operand:DI 0 "register_operand" "=r")
14519         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14520   "TARGET_P9_MISC && TARGET_64BIT"
14521   "darn %0,2"
14522   [(set_attr "type" "integer")])
14524 (define_insn "darn"
14525   [(set (match_operand:DI 0 "register_operand" "=r")
14526         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14527   "TARGET_P9_MISC && TARGET_64BIT"
14528   "darn %0,1"
14529   [(set_attr "type" "integer")])
14531 ;; Test byte within range.
14533 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14534 ;; represents a byte whose value is ignored in this context and
14535 ;; vv, the least significant byte, holds the byte value that is to
14536 ;; be tested for membership within the range specified by operand 2.
14537 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14539 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14540 ;; vv <= hi.  Otherwise, set register operand 0 to 0.
14542 ;; Though the instructions to which this expansion maps operate on
14543 ;; 64-bit registers, the current implementation only operates on
14544 ;; SI-mode operands as the high-order bits provide no information
14545 ;; that is not already available in the low-order bits.  To avoid the
14546 ;; costs of data widening operations, future enhancements might allow
14547 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14548 (define_expand "cmprb"
14549   [(set (match_dup 3)
14550         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14551                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14552          UNSPEC_CMPRB))
14553    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14554         (if_then_else:SI (lt (match_dup 3)
14555                              (const_int 0))
14556                          (const_int -1)
14557                          (if_then_else (gt (match_dup 3)
14558                                            (const_int 0))
14559                                        (const_int 1)
14560                                        (const_int 0))))]
14561   "TARGET_P9_MISC"
14563   operands[3] = gen_reg_rtx (CCmode);
14566 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14567 ;; represents a byte whose value is ignored in this context and
14568 ;; vv, the least significant byte, holds the byte value that is to
14569 ;; be tested for membership within the range specified by operand 2.
14570 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14572 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14573 ;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
14574 ;; 3 bits of the target CR register are all set to 0.
14575 (define_insn "*cmprb_internal"
14576   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14577         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14578                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14579          UNSPEC_CMPRB))]
14580   "TARGET_P9_MISC"
14581   "cmprb %0,0,%1,%2"
14582   [(set_attr "type" "logical")])
14584 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14585 ;; register operand 1 is on.  Otherwise, set operand 0 register to 1
14586 ;; if the GT bit (0x4) of condition register operand 1 is on.
14587 ;; Otherwise, set operand 0 to 0.  Note that the result stored into
14588 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14589 ;; within condition register operand 1.
14590 (define_insn "setb_signed"
14591    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14592          (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14593                               (const_int 0))
14594                           (const_int -1)
14595                           (if_then_else (gt (match_dup 1)
14596                                             (const_int 0))
14597                                         (const_int 1)
14598                                         (const_int 0))))]
14599   "TARGET_P9_MISC"
14600   "setb %0,%1"
14601   [(set_attr "type" "logical")])
14603 (define_insn "setb_unsigned"
14604    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14605          (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14606                               (const_int 0))
14607                           (const_int -1)
14608                           (if_then_else (gtu (match_dup 1)
14609                                             (const_int 0))
14610                                         (const_int 1)
14611                                         (const_int 0))))]
14612   "TARGET_P9_MISC"
14613   "setb %0,%1"
14614   [(set_attr "type" "logical")])
14616 ;; Test byte within two ranges.
14618 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14619 ;; represents a byte whose value is ignored in this context and
14620 ;; vv, the least significant byte, holds the byte value that is to
14621 ;; be tested for membership within the range specified by operand 2.
14622 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14624 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14625 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
14626 ;; operand 0 to 0.
14628 ;; Though the instructions to which this expansion maps operate on
14629 ;; 64-bit registers, the current implementation only operates on
14630 ;; SI-mode operands as the high-order bits provide no information
14631 ;; that is not already available in the low-order bits.  To avoid the
14632 ;; costs of data widening operations, future enhancements might allow
14633 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14634 (define_expand "cmprb2"
14635   [(set (match_dup 3)
14636         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14637                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14638          UNSPEC_CMPRB2))
14639    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14640         (if_then_else:SI (lt (match_dup 3)
14641                              (const_int 0))
14642                          (const_int -1)
14643                          (if_then_else (gt (match_dup 3)
14644                                            (const_int 0))
14645                                        (const_int 1)
14646                                        (const_int 0))))]
14647   "TARGET_P9_MISC"
14649   operands[3] = gen_reg_rtx (CCmode);
14652 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14653 ;; represents a byte whose value is ignored in this context and
14654 ;; vv, the least significant byte, holds the byte value that is to
14655 ;; be tested for membership within the ranges specified by operand 2.
14656 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14658 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14659 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14660 ;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
14661 ;; CR register are all set to 0.
14662 (define_insn "*cmprb2_internal"
14663   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14664         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14665                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14666          UNSPEC_CMPRB2))]
14667   "TARGET_P9_MISC"
14668   "cmprb %0,1,%1,%2"
14669   [(set_attr "type" "logical")])
14671 ;; Test byte membership within set of 8 bytes.
14673 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14674 ;; represents a byte whose value is ignored in this context and
14675 ;; vv, the least significant byte, holds the byte value that is to
14676 ;; be tested for membership within the set specified by operand 2.
14677 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14679 ;; Return in target register operand 0 a value of 1 if vv equals one
14680 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
14681 ;; register operand 0 to 0.  Note that the 8 byte values held within
14682 ;; operand 2 need not be unique.
14684 ;; Though the instructions to which this expansion maps operate on
14685 ;; 64-bit registers, the current implementation requires that operands
14686 ;; 0 and 1 have mode SI as the high-order bits provide no information
14687 ;; that is not already available in the low-order bits.  To avoid the
14688 ;; costs of data widening operations, future enhancements might allow
14689 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14690 (define_expand "cmpeqb"
14691   [(set (match_dup 3)
14692         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14693                     (match_operand:DI 2 "gpc_reg_operand" "r")]
14694          UNSPEC_CMPEQB))
14695    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14696         (if_then_else:SI (lt (match_dup 3)
14697                              (const_int 0))
14698                          (const_int -1)
14699                          (if_then_else (gt (match_dup 3)
14700                                            (const_int 0))
14701                                        (const_int 1)
14702                                        (const_int 0))))]
14703   "TARGET_P9_MISC && TARGET_64BIT"
14705   operands[3] = gen_reg_rtx (CCmode);
14708 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14709 ;; represents a byte whose value is ignored in this context and
14710 ;; vv, the least significant byte, holds the byte value that is to
14711 ;; be tested for membership within the set specified by operand 2.
14712 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14714 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14715 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
14716 ;; set the GT bit to zero.  The other 3 bits of the target CR register
14717 ;; are all set to 0.
14718 (define_insn "*cmpeqb_internal"
14719   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14720          (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14721                      (match_operand:DI 2 "gpc_reg_operand" "r")]
14722           UNSPEC_CMPEQB))]
14723   "TARGET_P9_MISC && TARGET_64BIT"
14724   "cmpeqb %0,%1,%2"
14725   [(set_attr "type" "logical")])
14728 (include "sync.md")
14729 (include "vector.md")
14730 (include "vsx.md")
14731 (include "altivec.md")
14732 (include "dfp.md")
14733 (include "crypto.md")
14734 (include "htm.md")