[rs6000] fix mffsl emulation
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blob6173994797c524674088eefac689fc8f98bb73d6
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2020 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (FIRST_ALTIVEC_REGNO         64)
37    (LAST_ALTIVEC_REGNO          95)
38    (LR_REGNO                    96)
39    (CTR_REGNO                   97)
40    (CA_REGNO                    98)
41    (ARG_POINTER_REGNUM          99)
42    (CR0_REGNO                   100)
43    (CR1_REGNO                   101)
44    (CR2_REGNO                   102)
45    (CR3_REGNO                   103)
46    (CR4_REGNO                   104)
47    (CR5_REGNO                   105)
48    (CR6_REGNO                   106)
49    (CR7_REGNO                   107)
50    (MAX_CR_REGNO                107)
51    (VRSAVE_REGNO                108)
52    (VSCR_REGNO                  109)
53    (FRAME_POINTER_REGNUM        110)
54   ])
57 ;; UNSPEC usage
60 (define_c_enum "unspec"
61   [UNSPEC_PROBE_STACK           ; probe stack memory reference
62    UNSPEC_TOCPTR                ; address of a word pointing to the TOC
63    UNSPEC_TOC                   ; address of the TOC (more-or-less)
64    UNSPEC_TOCSLOT               ; offset from r1 of toc pointer save slot
65    UNSPEC_MOVSI_GOT
66    UNSPEC_FCTIWZ
67    UNSPEC_FRIM
68    UNSPEC_FRIN
69    UNSPEC_FRIP
70    UNSPEC_FRIZ
71    UNSPEC_XSRDPI
72    UNSPEC_LD_MPIC               ; load_macho_picbase
73    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
74    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
75    UNSPEC_TLSGD
76    UNSPEC_TLSLD
77    UNSPEC_TLS_GET_ADDR
78    UNSPEC_MOVESI_FROM_CR
79    UNSPEC_MOVESI_TO_CR
80    UNSPEC_TLSDTPREL
81    UNSPEC_TLSDTPRELHA
82    UNSPEC_TLSDTPRELLO
83    UNSPEC_TLSGOTDTPREL
84    UNSPEC_TLSTPREL
85    UNSPEC_TLSTPRELHA
86    UNSPEC_TLSTPRELLO
87    UNSPEC_TLSGOTTPREL
88    UNSPEC_TLSTLS
89    UNSPEC_TLSTLS_PCREL
90    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
91    UNSPEC_STFIWX
92    UNSPEC_POPCNTB
93    UNSPEC_FRES
94    UNSPEC_SP_SET
95    UNSPEC_SP_TEST
96    UNSPEC_SYNC
97    UNSPEC_LWSYNC
98    UNSPEC_SYNC_OP
99    UNSPEC_ATOMIC
100    UNSPEC_CMPXCHG
101    UNSPEC_XCHG
102    UNSPEC_AND
103    UNSPEC_DLMZB
104    UNSPEC_DLMZB_CR
105    UNSPEC_DLMZB_STRLEN
106    UNSPEC_RSQRT
107    UNSPEC_TOCREL
108    UNSPEC_MACHOPIC_OFFSET
109    UNSPEC_BPERM
110    UNSPEC_COPYSIGN
111    UNSPEC_PARITY
112    UNSPEC_CMPB
113    UNSPEC_FCTIW
114    UNSPEC_FCTID
115    UNSPEC_LFIWAX
116    UNSPEC_LFIWZX
117    UNSPEC_FCTIWUZ
118    UNSPEC_NOP
119    UNSPEC_GRP_END_NOP
120    UNSPEC_P8V_FMRGOW
121    UNSPEC_P8V_MTVSRWZ
122    UNSPEC_P8V_RELOAD_FROM_GPR
123    UNSPEC_P8V_MTVSRD
124    UNSPEC_P8V_XXPERMDI
125    UNSPEC_P8V_RELOAD_FROM_VSX
126    UNSPEC_ADDG6S
127    UNSPEC_CDTBCD
128    UNSPEC_CBCDTD
129    UNSPEC_DIVE
130    UNSPEC_DIVEU
131    UNSPEC_UNPACK_128BIT
132    UNSPEC_PACK_128BIT
133    UNSPEC_LSQ
134    UNSPEC_FUSION_GPR
135    UNSPEC_STACK_CHECK
136    UNSPEC_CMPRB
137    UNSPEC_CMPRB2
138    UNSPEC_CMPEQB
139    UNSPEC_ADD_ROUND_TO_ODD
140    UNSPEC_SUB_ROUND_TO_ODD
141    UNSPEC_MUL_ROUND_TO_ODD
142    UNSPEC_DIV_ROUND_TO_ODD
143    UNSPEC_FMA_ROUND_TO_ODD
144    UNSPEC_SQRT_ROUND_TO_ODD
145    UNSPEC_TRUNC_ROUND_TO_ODD
146    UNSPEC_SIGNBIT
147    UNSPEC_SF_FROM_SI
148    UNSPEC_SI_FROM_SF
149    UNSPEC_PLTSEQ
150    UNSPEC_PLT16_HA
151   ])
154 ;; UNSPEC_VOLATILE usage
157 (define_c_enum "unspecv"
158   [UNSPECV_BLOCK
159    UNSPECV_LL                   ; load-locked
160    UNSPECV_SC                   ; store-conditional
161    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
162    UNSPECV_EH_RR                ; eh_reg_restore
163    UNSPECV_ISYNC                ; isync instruction
164    UNSPECV_MFTB                 ; move from time base
165    UNSPECV_DARN                 ; darn 1 (deliver a random number)
166    UNSPECV_DARN_32              ; darn 2
167    UNSPECV_DARN_RAW             ; darn 0
168    UNSPECV_NLGR                 ; non-local goto receiver
169    UNSPECV_MFFS                 ; Move from FPSCR
170    UNSPECV_MFFSL                ; Move from FPSCR light instruction version
171    UNSPECV_MFFSCRN              ; Move from FPSCR float rounding mode
172    UNSPECV_MFFSCDRN             ; Move from FPSCR decimal float rounding mode
173    UNSPECV_MTFSF                ; Move to FPSCR Fields 8 to 15
174    UNSPECV_MTFSF_HI             ; Move to FPSCR Fields 0 to 7
175    UNSPECV_MTFSB0               ; Set FPSCR Field bit to 0
176    UNSPECV_MTFSB1               ; Set FPSCR Field bit to 1
177    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
178    UNSPECV_SPEC_BARRIER         ; Speculation barrier
179    UNSPECV_PLT16_LO
180    UNSPECV_PLT_PCREL
181   ])
183 ; The three different kinds of epilogue.
184 (define_enum "epilogue_type" [normal sibcall eh_return])
186 ;; Define an insn type attribute.  This is used in function unit delay
187 ;; computations.
188 (define_attr "type"
189   "integer,two,three,
190    add,logical,shift,insert,
191    mul,halfmul,div,
192    exts,cntlz,popcnt,isel,
193    load,store,fpload,fpstore,vecload,vecstore,
194    cmp,
195    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
196    cr_logical,mfcr,mfcrf,mtcr,
197    fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
198    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
199    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
200    veclogical,veccmpfx,vecexts,vecmove,
201    htm,htmsimple,dfp"
202   (const_string "integer"))
204 ;; What data size does this instruction work on?
205 ;; This is used for insert, mul and others as necessary.
206 (define_attr "size" "8,16,32,64,128" (const_string "32"))
208 ;; What is the insn_cost for this insn?  The target hook can still override
209 ;; this.  For optimizing for size the "length" attribute is used instead.
210 (define_attr "cost" "" (const_int 0))
212 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
213 ;; This is used for add, logical, shift, exts, mul.
214 (define_attr "dot" "no,yes" (const_string "no"))
216 ;; Does this instruction sign-extend its result?
217 ;; This is used for load insns.
218 (define_attr "sign_extend" "no,yes" (const_string "no"))
220 ;; Does this cr_logical instruction have three operands?  That is, BT != BB.
221 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
223 ;; Does this instruction use indexed (that is, reg+reg) addressing?
224 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
225 ;; it is automatically set based on that.  If a load or store instruction
226 ;; has fewer than two operands it needs to set this attribute manually
227 ;; or the compiler will crash.
228 (define_attr "indexed" "no,yes"
229   (if_then_else (ior (match_operand 0 "indexed_address_mem")
230                      (match_operand 1 "indexed_address_mem"))
231                 (const_string "yes")
232                 (const_string "no")))
234 ;; Does this instruction use update addressing?
235 ;; This is used for load and store insns.  See the comments for "indexed".
236 (define_attr "update" "no,yes"
237   (if_then_else (ior (match_operand 0 "update_address_mem")
238                      (match_operand 1 "update_address_mem"))
239                 (const_string "yes")
240                 (const_string "no")))
242 ;; Is this instruction using operands[2] as shift amount, and can that be a
243 ;; register?
244 ;; This is used for shift insns.
245 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
247 ;; Is this instruction using a shift amount from a register?
248 ;; This is used for shift insns.
249 (define_attr "var_shift" "no,yes"
250   (if_then_else (and (eq_attr "type" "shift")
251                      (eq_attr "maybe_var_shift" "yes"))
252                 (if_then_else (match_operand 2 "gpc_reg_operand")
253                               (const_string "yes")
254                               (const_string "no"))
255                 (const_string "no")))
257 ;; Is copying of this instruction disallowed?
258 (define_attr "cannot_copy" "no,yes" (const_string "no"))
261 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
262 ;; before the instruction.  A prefixed instruction has a prefix instruction
263 ;; word that extends the immediate value of the instructions from 12-16 bits to
264 ;; 34 bits.  The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
265 ;; insns.  The default "length" attribute will also be adjusted by default to
266 ;; be 12 bytes.
267 (define_attr "prefixed" "no,yes"
268   (cond [(ior (match_test "!TARGET_PREFIXED")
269               (match_test "!NONJUMP_INSN_P (insn)"))
270          (const_string "no")
272          (eq_attr "type" "load,fpload,vecload")
273          (if_then_else (match_test "prefixed_load_p (insn)")
274                        (const_string "yes")
275                        (const_string "no"))
277          (eq_attr "type" "store,fpstore,vecstore")
278          (if_then_else (match_test "prefixed_store_p (insn)")
279                        (const_string "yes")
280                        (const_string "no"))
282          (eq_attr "type" "integer,add")
283          (if_then_else (match_test "prefixed_paddi_p (insn)")
284                        (const_string "yes")
285                        (const_string "no"))]
287         (const_string "no")))
289 ;; Return the number of real hardware instructions in a combined insn.  If it
290 ;; is 0, just use the length / 4.
291 (define_attr "num_insns" "" (const_int 0))
293 ;; If an insn is prefixed, return the maximum number of prefixed instructions
294 ;; in the insn.  The macro ADJUST_INSN_LENGTH uses this number to adjust the
295 ;; insn length.
296 (define_attr "max_prefixed_insns" "" (const_int 1))
298 ;; Length of the instruction (in bytes).  This length does not consider the
299 ;; length for prefixed instructions.  The macro ADJUST_INSN_LENGTH will adjust
300 ;; the length if there are prefixed instructions.
302 ;; While it might be tempting to use num_insns to calculate the length, it can
303 ;; be problematical unless all insn lengths are adjusted to use num_insns
304 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
305 ;; num_insns and recurse).
306 (define_attr "length" "" (const_int 4))
308 ;; Processor type -- this attribute must exactly match the processor_type
309 ;; enumeration in rs6000-opts.h.
310 (define_attr "cpu"
311   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
312    ppc750,ppc7400,ppc7450,
313    ppc403,ppc405,ppc440,ppc476,
314    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
315    power4,power5,power6,power7,power8,power9,future,
316    rs64a,mpccore,cell,ppca2,titan"
317   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
319 ;; The ISA we implement.
320 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
321   (const_string "any"))
323 ;; Is this alternative enabled for the current CPU/ISA/etc.?
324 (define_attr "enabled" ""
325   (cond
326     [(eq_attr "isa" "any")
327      (const_int 1)
329      (and (eq_attr "isa" "p5")
330           (match_test "TARGET_POPCNTB"))
331      (const_int 1)
333      (and (eq_attr "isa" "p6")
334           (match_test "TARGET_CMPB"))
335      (const_int 1)
337      (and (eq_attr "isa" "p7")
338           (match_test "TARGET_POPCNTD"))
339      (const_int 1)
341      (and (eq_attr "isa" "p7v")
342           (match_test "TARGET_VSX"))
343      (const_int 1)
345      (and (eq_attr "isa" "p8v")
346           (match_test "TARGET_P8_VECTOR"))
347      (const_int 1)
349      (and (eq_attr "isa" "p9v")
350           (match_test "TARGET_P9_VECTOR"))
351      (const_int 1)
353      (and (eq_attr "isa" "p9kf")
354           (match_test "TARGET_FLOAT128_TYPE"))
355      (const_int 1)
357      (and (eq_attr "isa" "p9tf")
358           (match_test "FLOAT128_VECTOR_P (TFmode)"))
359      (const_int 1)
361      (and (eq_attr "isa" "fut")
362           (match_test "TARGET_FUTURE"))
363      (const_int 1)
364     ] (const_int 0)))
366 ;; If this instruction is microcoded on the CELL processor
367 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
368 (define_attr "cell_micro" "not,conditional,always"
369   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
370                           (eq_attr "dot" "yes"))
371                      (and (eq_attr "type" "load")
372                           (eq_attr "sign_extend" "yes"))
373                      (and (eq_attr "type" "shift")
374                           (eq_attr "var_shift" "yes")))
375                 (const_string "always")
376                 (const_string "not")))
378 (automata_option "ndfa")
380 (include "rs64.md")
381 (include "mpc.md")
382 (include "40x.md")
383 (include "440.md")
384 (include "476.md")
385 (include "601.md")
386 (include "603.md")
387 (include "6xx.md")
388 (include "7xx.md")
389 (include "7450.md")
390 (include "8540.md")
391 (include "e300c2c3.md")
392 (include "e500mc.md")
393 (include "e500mc64.md")
394 (include "e5500.md")
395 (include "e6500.md")
396 (include "power4.md")
397 (include "power5.md")
398 (include "power6.md")
399 (include "power7.md")
400 (include "power8.md")
401 (include "power9.md")
402 (include "future.md")
403 (include "cell.md")
404 (include "a2.md")
405 (include "titan.md")
407 (include "predicates.md")
408 (include "constraints.md")
411 ;; Mode iterators
413 ; This mode iterator allows :GPR to be used to indicate the allowable size
414 ; of whole values in GPRs.
415 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
417 ; And again, for patterns that need two (potentially) different integer modes.
418 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
420 ; Any supported integer mode.
421 (define_mode_iterator INT [QI HI SI DI TI PTI])
423 ; Any supported integer mode that fits in one register.
424 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
426 ; Integer modes supported in VSX registers with ISA 3.0 instructions
427 (define_mode_iterator INT_ISA3 [QI HI SI DI])
429 ; Everything we can extend QImode to.
430 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
432 ; Everything we can extend HImode to.
433 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
435 ; Everything we can extend SImode to.
436 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
438 ; QImode or HImode for small integer moves and small atomic ops
439 (define_mode_iterator QHI [QI HI])
441 ; QImode, HImode, SImode for fused ops only for GPR loads
442 (define_mode_iterator QHSI [QI HI SI])
444 ; HImode or SImode for sign extended fusion ops
445 (define_mode_iterator HSI [HI SI])
447 ; SImode or DImode, even if DImode doesn't fit in GPRs.
448 (define_mode_iterator SDI [SI DI])
450 ; The size of a pointer.  Also, the size of the value that a record-condition
451 ; (one with a '.') will compare; and the size used for arithmetic carries.
452 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
454 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
455 ; PTImode is GPR only)
456 (define_mode_iterator TI2 [TI PTI])
458 ; Any hardware-supported floating-point mode
459 (define_mode_iterator FP [
460   (SF "TARGET_HARD_FLOAT")
461   (DF "TARGET_HARD_FLOAT")
462   (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
463   (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
464   (KF "TARGET_FLOAT128_TYPE")
465   (DD "TARGET_DFP")
466   (TD "TARGET_DFP")])
468 ; Any fma capable floating-point mode.
469 (define_mode_iterator FMA_F [
470   (SF "TARGET_HARD_FLOAT")
471   (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
472   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
473   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
474   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
475   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
476   ])
478 ; Floating point move iterators to combine binary and decimal moves
479 (define_mode_iterator FMOVE32 [SF SD])
480 (define_mode_iterator FMOVE64 [DF DD])
481 (define_mode_iterator FMOVE64X [DI DF DD])
482 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
483                                 (IF "FLOAT128_IBM_P (IFmode)")
484                                 (TD "TARGET_HARD_FLOAT")])
486 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
487                                     (IF "FLOAT128_2REG_P (IFmode)")
488                                     (TD "TARGET_HARD_FLOAT")])
490 ; Iterators for 128 bit types for direct move
491 (define_mode_iterator FMOVE128_GPR [TI
492                                     V16QI
493                                     V8HI
494                                     V4SI
495                                     V4SF
496                                     V2DI
497                                     V2DF
498                                     V1TI
499                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
500                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
502 ; Iterator for 128-bit VSX types for pack/unpack
503 (define_mode_iterator FMOVE128_VSX [V1TI KF])
505 ; Iterators for converting to/from TFmode
506 (define_mode_iterator IFKF [IF KF])
508 ; Constraints for moving IF/KFmode.
509 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
511 ; Whether a floating point move is ok, don't allow SD without hardware FP
512 (define_mode_attr fmove_ok [(SF "")
513                             (DF "")
514                             (SD "TARGET_HARD_FLOAT")
515                             (DD "")])
517 ; Convert REAL_VALUE to the appropriate bits
518 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
519                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
520                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
521                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
523 ; Whether 0.0 has an all-zero bit pattern
524 (define_mode_attr zero_fp [(SF "j")
525                            (DF "j")
526                            (TF "j")
527                            (IF "j")
528                            (KF "j")
529                            (SD "wn")
530                            (DD "wn")
531                            (TD "wn")])
533 ; Definitions for 64-bit VSX
534 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
536 ; Definitions for 64-bit direct move
537 (define_mode_attr f64_dm  [(DF "wa") (DD "d")])
539 ; Definitions for 64-bit use of altivec registers
540 (define_mode_attr f64_av  [(DF "v") (DD "wn")])
542 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
543 (define_mode_attr f64_p9  [(DF "v") (DD "wn")])
545 ; These modes do not fit in integer registers in 32-bit mode.
546 (define_mode_iterator DIFD [DI DF DD])
548 ; Iterator for reciprocal estimate instructions
549 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
551 ; SFmode or DFmode.
552 (define_mode_iterator SFDF [SF DF])
554 ; And again, for when we need two FP modes in a pattern.
555 (define_mode_iterator SFDF2 [SF DF])
557 ; A generic s/d attribute, for sp/dp for example.
558 (define_mode_attr sd [(SF   "s") (DF   "d")
559                       (V4SF "s") (V2DF "d")])
561 ; "s" or nothing, for fmuls/fmul for example.
562 (define_mode_attr s [(SF "s") (DF "")])
564 ; Iterator for 128-bit floating point that uses the IBM double-double format
565 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
566                               (TF "FLOAT128_IBM_P (TFmode)")])
568 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
569 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
570                                (TF "FLOAT128_IEEE_P (TFmode)")])
572 ; Iterator for 128-bit floating point
573 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
574                                 (IF "TARGET_FLOAT128_TYPE")
575                                 (TF "TARGET_LONG_DOUBLE_128")])
577 ; Iterator for signbit on 64-bit machines with direct move
578 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
579                                (TF "FLOAT128_VECTOR_P (TFmode)")])
581 ; Iterator for ISA 3.0 supported floating point types
582 (define_mode_iterator FP_ISA3 [SF DF])
584 ; SF/DF constraint for arithmetic on traditional floating point registers
585 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
587 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
588 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
589 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
590 ; format.
591 (define_mode_attr Fv            [(SF "wa") (DF "wa") (DI "wa")])
593 ; Which isa is needed for those float instructions?
594 (define_mode_attr Fisa          [(SF "p8v")  (DF "*") (DI "*")])
596 ; FRE/FRES support
597 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
599 ; Conditional returns.
600 (define_code_iterator any_return [return simple_return])
601 (define_code_attr return_pred [(return "direct_return ()")
602                                (simple_return "1")])
603 (define_code_attr return_str [(return "") (simple_return "simple_")])
605 ; Logical operators.
606 (define_code_iterator iorxor            [ior xor])
607 (define_code_iterator and_ior_xor       [and ior xor])
609 ; Signed/unsigned variants of ops.
610 (define_code_iterator any_extend        [sign_extend zero_extend])
611 (define_code_iterator any_fix           [fix unsigned_fix])
612 (define_code_iterator any_float         [float unsigned_float])
614 (define_code_attr u  [(sign_extend      "")
615                       (zero_extend      "u")
616                       (fix              "")
617                       (unsigned_fix     "u")])
619 (define_code_attr su [(sign_extend      "s")
620                       (zero_extend      "u")
621                       (fix              "s")
622                       (unsigned_fix     "u")
623                       (float            "s")
624                       (unsigned_float   "u")])
626 (define_code_attr az [(sign_extend      "a")
627                       (zero_extend      "z")
628                       (fix              "a")
629                       (unsigned_fix     "z")
630                       (float            "a")
631                       (unsigned_float   "z")])
633 (define_code_attr uns [(fix             "")
634                        (unsigned_fix    "uns")
635                        (float           "")
636                        (unsigned_float  "uns")])
638 ; Various instructions that come in SI and DI forms.
639 ; A generic w/d attribute, for things like cmpw/cmpd.
640 (define_mode_attr wd [(QI    "b")
641                       (HI    "h")
642                       (SI    "w")
643                       (DI    "d")
644                       (V16QI "b")
645                       (V8HI  "h")
646                       (V4SI  "w")
647                       (V2DI  "d")
648                       (V1TI  "q")
649                       (TI    "q")])
651 ;; How many bits in this mode?
652 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
653                                            (SF "32") (DF "64")])
655 ; DImode bits
656 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
658 ;; Bitmask for shift instructions
659 (define_mode_attr hH [(SI "h") (DI "H")])
661 ;; A mode twice the size of the given mode
662 (define_mode_attr dmode [(SI "di") (DI "ti")])
663 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
665 ;; Suffix for reload patterns
666 (define_mode_attr ptrsize [(SI "32bit")
667                            (DI "64bit")])
669 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
670                             (DI "TARGET_64BIT")])
672 (define_mode_attr mptrsize [(SI "si")
673                             (DI "di")])
675 (define_mode_attr ptrload [(SI "lwz")
676                            (DI "ld")])
678 (define_mode_attr ptrm [(SI "m")
679                         (DI "Y")])
681 (define_mode_attr rreg [(SF   "f")
682                         (DF   "wa")
683                         (TF   "f")
684                         (TD   "f")
685                         (V4SF "wa")
686                         (V2DF "wa")])
688 (define_mode_attr rreg2 [(SF   "f")
689                          (DF   "d")])
691 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
692                                  (DF "TARGET_FCFID")])
694 ;; Mode iterator for logical operations on 128-bit types
695 (define_mode_iterator BOOL_128          [TI
696                                          PTI
697                                          (V16QI "TARGET_ALTIVEC")
698                                          (V8HI  "TARGET_ALTIVEC")
699                                          (V4SI  "TARGET_ALTIVEC")
700                                          (V4SF  "TARGET_ALTIVEC")
701                                          (V2DI  "TARGET_ALTIVEC")
702                                          (V2DF  "TARGET_ALTIVEC")
703                                          (V1TI  "TARGET_ALTIVEC")])
705 ;; For the GPRs we use 3 constraints for register outputs, two that are the
706 ;; same as the output register, and a third where the output register is an
707 ;; early clobber, so we don't have to deal with register overlaps.  For the
708 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
709 ;; either.
711 ;; Mode attribute for boolean operation register constraints for output
712 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wa,v")
713                                          (PTI   "&r,r,r")
714                                          (V16QI "wa,v,&?r,?r,?r")
715                                          (V8HI  "wa,v,&?r,?r,?r")
716                                          (V4SI  "wa,v,&?r,?r,?r")
717                                          (V4SF  "wa,v,&?r,?r,?r")
718                                          (V2DI  "wa,v,&?r,?r,?r")
719                                          (V2DF  "wa,v,&?r,?r,?r")
720                                          (V1TI  "wa,v,&?r,?r,?r")])
722 ;; Mode attribute for boolean operation register constraints for operand1
723 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wa,v")
724                                          (PTI   "r,0,r")
725                                          (V16QI "wa,v,r,0,r")
726                                          (V8HI  "wa,v,r,0,r")
727                                          (V4SI  "wa,v,r,0,r")
728                                          (V4SF  "wa,v,r,0,r")
729                                          (V2DI  "wa,v,r,0,r")
730                                          (V2DF  "wa,v,r,0,r")
731                                          (V1TI  "wa,v,r,0,r")])
733 ;; Mode attribute for boolean operation register constraints for operand2
734 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wa,v")
735                                          (PTI   "r,r,0")
736                                          (V16QI "wa,v,r,r,0")
737                                          (V8HI  "wa,v,r,r,0")
738                                          (V4SI  "wa,v,r,r,0")
739                                          (V4SF  "wa,v,r,r,0")
740                                          (V2DI  "wa,v,r,r,0")
741                                          (V2DF  "wa,v,r,r,0")
742                                          (V1TI  "wa,v,r,r,0")])
744 ;; Mode attribute for boolean operation register constraints for operand1
745 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
746 ;; is used for operand1 or operand2
747 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wa,v")
748                                          (PTI   "r,0,0")
749                                          (V16QI "wa,v,r,0,0")
750                                          (V8HI  "wa,v,r,0,0")
751                                          (V4SI  "wa,v,r,0,0")
752                                          (V4SF  "wa,v,r,0,0")
753                                          (V2DI  "wa,v,r,0,0")
754                                          (V2DF  "wa,v,r,0,0")
755                                          (V1TI  "wa,v,r,0,0")])
757 ;; Reload iterator for creating the function to allocate a base register to
758 ;; supplement addressing modes.
759 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
760                               SF SD SI DF DD DI TI PTI KF IF TF])
762 ;; Iterate over smin, smax
763 (define_code_iterator fp_minmax [smin smax])
765 (define_code_attr     minmax    [(smin "min")
766                                  (smax "max")])
768 (define_code_attr     SMINMAX   [(smin "SMIN")
769                                  (smax "SMAX")])
771 ;; Iterator to optimize the following cases:
772 ;;      D-form load to FPR register & move to Altivec register
773 ;;      Move Altivec register to FPR register and store
774 (define_mode_iterator ALTIVEC_DFORM [DF
775                                      (SF "TARGET_P8_VECTOR")
776                                      (DI "TARGET_POWERPC64")])
778 (include "darwin.md")
780 ;; Start with fixed-point load and store insns.  Here we put only the more
781 ;; complex forms.  Basic data transfer is done later.
783 (define_insn "zero_extendqi<mode>2"
784   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
785         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
786   ""
787   "@
788    lbz%U1%X1 %0,%1
789    rlwinm %0,%1,0,0xff
790    lxsibzx %x0,%y1
791    vextractub %0,%1,7"
792   [(set_attr "type" "load,shift,fpload,vecperm")
793    (set_attr "isa" "*,*,p9v,p9v")])
795 (define_insn_and_split "*zero_extendqi<mode>2_dot"
796   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
797         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
798                     (const_int 0)))
799    (clobber (match_scratch:EXTQI 0 "=r,r"))]
800   ""
801   "@
802    andi. %0,%1,0xff
803    #"
804   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
805   [(set (match_dup 0)
806         (zero_extend:EXTQI (match_dup 1)))
807    (set (match_dup 2)
808         (compare:CC (match_dup 0)
809                     (const_int 0)))]
810   ""
811   [(set_attr "type" "logical")
812    (set_attr "dot" "yes")
813    (set_attr "length" "4,8")])
815 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
816   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
817         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
818                     (const_int 0)))
819    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
820         (zero_extend:EXTQI (match_dup 1)))]
821   ""
822   "@
823    andi. %0,%1,0xff
824    #"
825   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
826   [(set (match_dup 0)
827         (zero_extend:EXTQI (match_dup 1)))
828    (set (match_dup 2)
829         (compare:CC (match_dup 0)
830                     (const_int 0)))]
831   ""
832   [(set_attr "type" "logical")
833    (set_attr "dot" "yes")
834    (set_attr "length" "4,8")])
837 (define_insn "zero_extendhi<mode>2"
838   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
839         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
840   ""
841   "@
842    lhz%U1%X1 %0,%1
843    rlwinm %0,%1,0,0xffff
844    lxsihzx %x0,%y1
845    vextractuh %0,%1,6"
846   [(set_attr "type" "load,shift,fpload,vecperm")
847    (set_attr "isa" "*,*,p9v,p9v")])
849 (define_insn_and_split "*zero_extendhi<mode>2_dot"
850   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
851         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
852                     (const_int 0)))
853    (clobber (match_scratch:EXTHI 0 "=r,r"))]
854   ""
855   "@
856    andi. %0,%1,0xffff
857    #"
858   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
859   [(set (match_dup 0)
860         (zero_extend:EXTHI (match_dup 1)))
861    (set (match_dup 2)
862         (compare:CC (match_dup 0)
863                     (const_int 0)))]
864   ""
865   [(set_attr "type" "logical")
866    (set_attr "dot" "yes")
867    (set_attr "length" "4,8")])
869 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
870   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
871         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
872                     (const_int 0)))
873    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
874         (zero_extend:EXTHI (match_dup 1)))]
875   ""
876   "@
877    andi. %0,%1,0xffff
878    #"
879   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
880   [(set (match_dup 0)
881         (zero_extend:EXTHI (match_dup 1)))
882    (set (match_dup 2)
883         (compare:CC (match_dup 0)
884                     (const_int 0)))]
885   ""
886   [(set_attr "type" "logical")
887    (set_attr "dot" "yes")
888    (set_attr "length" "4,8")])
891 (define_insn "zero_extendsi<mode>2"
892   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
893         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
894   ""
895   "@
896    lwz%U1%X1 %0,%1
897    rldicl %0,%1,0,32
898    lfiwzx %0,%y1
899    lxsiwzx %x0,%y1
900    mtvsrwz %x0,%1
901    mfvsrwz %0,%x1
902    xxextractuw %x0,%x1,4"
903   [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
904    (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
906 (define_insn_and_split "*zero_extendsi<mode>2_dot"
907   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
909                     (const_int 0)))
910    (clobber (match_scratch:EXTSI 0 "=r,r"))]
911   ""
912   "@
913    rldicl. %0,%1,0,32
914    #"
915   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
916   [(set (match_dup 0)
917         (zero_extend:DI (match_dup 1)))
918    (set (match_dup 2)
919         (compare:CC (match_dup 0)
920                     (const_int 0)))]
921   ""
922   [(set_attr "type" "shift")
923    (set_attr "dot" "yes")
924    (set_attr "length" "4,8")])
926 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
927   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
928         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
929                     (const_int 0)))
930    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
931         (zero_extend:EXTSI (match_dup 1)))]
932   ""
933   "@
934    rldicl. %0,%1,0,32
935    #"
936   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
937   [(set (match_dup 0)
938         (zero_extend:EXTSI (match_dup 1)))
939    (set (match_dup 2)
940         (compare:CC (match_dup 0)
941                     (const_int 0)))]
942   ""
943   [(set_attr "type" "shift")
944    (set_attr "dot" "yes")
945    (set_attr "length" "4,8")])
948 (define_insn "extendqi<mode>2"
949   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
950         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
951   ""
952   "@
953    extsb %0,%1
954    vextsb2d %0,%1"
955   [(set_attr "type" "exts,vecperm")
956    (set_attr "isa" "*,p9v")])
958 (define_insn_and_split "*extendqi<mode>2_dot"
959   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
960         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
961                     (const_int 0)))
962    (clobber (match_scratch:EXTQI 0 "=r,r"))]
963   ""
964   "@
965    extsb. %0,%1
966    #"
967   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
968   [(set (match_dup 0)
969         (sign_extend:EXTQI (match_dup 1)))
970    (set (match_dup 2)
971         (compare:CC (match_dup 0)
972                     (const_int 0)))]
973   ""
974   [(set_attr "type" "exts")
975    (set_attr "dot" "yes")
976    (set_attr "length" "4,8")])
978 (define_insn_and_split "*extendqi<mode>2_dot2"
979   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
981                     (const_int 0)))
982    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
983         (sign_extend:EXTQI (match_dup 1)))]
984   ""
985   "@
986    extsb. %0,%1
987    #"
988   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
989   [(set (match_dup 0)
990         (sign_extend:EXTQI (match_dup 1)))
991    (set (match_dup 2)
992         (compare:CC (match_dup 0)
993                     (const_int 0)))]
994   ""
995   [(set_attr "type" "exts")
996    (set_attr "dot" "yes")
997    (set_attr "length" "4,8")])
1000 (define_expand "extendhi<mode>2"
1001   [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1002         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1003   ""
1004   "")
1006 (define_insn "*extendhi<mode>2"
1007   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1008         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1009   ""
1010   "@
1011    lha%U1%X1 %0,%1
1012    extsh %0,%1
1013    #
1014    vextsh2d %0,%1"
1015   [(set_attr "type" "load,exts,fpload,vecperm")
1016    (set_attr "sign_extend" "yes")
1017    (set_attr "length" "*,*,8,*")
1018    (set_attr "isa" "*,*,p9v,p9v")])
1020 (define_split
1021   [(set (match_operand:EXTHI 0 "altivec_register_operand")
1022         (sign_extend:EXTHI
1023          (match_operand:HI 1 "indexed_or_indirect_operand")))]
1024   "TARGET_P9_VECTOR && reload_completed"
1025   [(set (match_dup 2)
1026         (match_dup 1))
1027    (set (match_dup 0)
1028         (sign_extend:EXTHI (match_dup 2)))]
1030   operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1033 (define_insn_and_split "*extendhi<mode>2_dot"
1034   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1035         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1036                     (const_int 0)))
1037    (clobber (match_scratch:EXTHI 0 "=r,r"))]
1038   ""
1039   "@
1040    extsh. %0,%1
1041    #"
1042   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1043   [(set (match_dup 0)
1044         (sign_extend:EXTHI (match_dup 1)))
1045    (set (match_dup 2)
1046         (compare:CC (match_dup 0)
1047                     (const_int 0)))]
1048   ""
1049   [(set_attr "type" "exts")
1050    (set_attr "dot" "yes")
1051    (set_attr "length" "4,8")])
1053 (define_insn_and_split "*extendhi<mode>2_dot2"
1054   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1055         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1056                     (const_int 0)))
1057    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1058         (sign_extend:EXTHI (match_dup 1)))]
1059   ""
1060   "@
1061    extsh. %0,%1
1062    #"
1063   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1064   [(set (match_dup 0)
1065         (sign_extend:EXTHI (match_dup 1)))
1066    (set (match_dup 2)
1067         (compare:CC (match_dup 0)
1068                     (const_int 0)))]
1069   ""
1070   [(set_attr "type" "exts")
1071    (set_attr "dot" "yes")
1072    (set_attr "length" "4,8")])
1075 (define_insn "extendsi<mode>2"
1076   [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1077                      "=r, r,   d,     wa,    wa,    v,      v,     wr")
1078         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1079                      "YZ, r,   Z,     Z,     r,     v,      v,     ?wa")))]
1080   ""
1081   "@
1082    lwa%U1%X1 %0,%1
1083    extsw %0,%1
1084    lfiwax %0,%y1
1085    lxsiwax %x0,%y1
1086    mtvsrwa %x0,%1
1087    vextsw2d %0,%1
1088    #
1089    #"
1090   [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1091    (set_attr "sign_extend" "yes")
1092    (set_attr "length" "*,*,*,*,*,*,8,8")
1093    (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1095 (define_split
1096   [(set (match_operand:EXTSI 0 "int_reg_operand")
1097         (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1098   "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1099   [(set (match_dup 2)
1100         (match_dup 1))
1101    (set (match_dup 0)
1102         (sign_extend:DI (match_dup 2)))]
1104   operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1107 (define_split
1108   [(set (match_operand:DI 0 "altivec_register_operand")
1109         (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1110   "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1111   [(const_int 0)]
1113   rtx dest = operands[0];
1114   rtx src = operands[1];
1115   int dest_regno = REGNO (dest);
1116   int src_regno = REGNO (src);
1117   rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1118   rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1120   if (BYTES_BIG_ENDIAN)
1121     {
1122       emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1123       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1124     }
1125   else
1126     {
1127       emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1128       emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1129     }
1130   DONE;
1133 (define_insn_and_split "*extendsi<mode>2_dot"
1134   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1135         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1136                     (const_int 0)))
1137    (clobber (match_scratch:EXTSI 0 "=r,r"))]
1138   ""
1139   "@
1140    extsw. %0,%1
1141    #"
1142   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1143   [(set (match_dup 0)
1144         (sign_extend:EXTSI (match_dup 1)))
1145    (set (match_dup 2)
1146         (compare:CC (match_dup 0)
1147                     (const_int 0)))]
1148   ""
1149   [(set_attr "type" "exts")
1150    (set_attr "dot" "yes")
1151    (set_attr "length" "4,8")])
1153 (define_insn_and_split "*extendsi<mode>2_dot2"
1154   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1155         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1156                     (const_int 0)))
1157    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1158         (sign_extend:EXTSI (match_dup 1)))]
1159   ""
1160   "@
1161    extsw. %0,%1
1162    #"
1163   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1164   [(set (match_dup 0)
1165         (sign_extend:EXTSI (match_dup 1)))
1166    (set (match_dup 2)
1167         (compare:CC (match_dup 0)
1168                     (const_int 0)))]
1169   ""
1170   [(set_attr "type" "exts")
1171    (set_attr "dot" "yes")
1172    (set_attr "length" "4,8")])
1174 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1176 (define_insn "*macchwc"
1177   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1178         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1179                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1180                                        (const_int 16))
1181                                       (sign_extend:SI
1182                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1183                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1184                     (const_int 0)))
1185    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186         (plus:SI (mult:SI (ashiftrt:SI
1187                            (match_dup 2)
1188                            (const_int 16))
1189                           (sign_extend:SI
1190                            (match_dup 1)))
1191                  (match_dup 4)))]
1192   "TARGET_MULHW"
1193   "macchw. %0,%1,%2"
1194   [(set_attr "type" "halfmul")])
1196 (define_insn "*macchw"
1197   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1198         (plus:SI (mult:SI (ashiftrt:SI
1199                            (match_operand:SI 2 "gpc_reg_operand" "r")
1200                            (const_int 16))
1201                           (sign_extend:SI
1202                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1203                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1204   "TARGET_MULHW"
1205   "macchw %0,%1,%2"
1206   [(set_attr "type" "halfmul")])
1208 (define_insn "*macchwuc"
1209   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1210         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1211                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1212                                        (const_int 16))
1213                                       (zero_extend:SI
1214                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1215                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1216                     (const_int 0)))
1217    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1218         (plus:SI (mult:SI (lshiftrt:SI
1219                            (match_dup 2)
1220                            (const_int 16))
1221                           (zero_extend:SI
1222                            (match_dup 1)))
1223                  (match_dup 4)))]
1224   "TARGET_MULHW"
1225   "macchwu. %0,%1,%2"
1226   [(set_attr "type" "halfmul")])
1228 (define_insn "*macchwu"
1229   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1230         (plus:SI (mult:SI (lshiftrt:SI
1231                            (match_operand:SI 2 "gpc_reg_operand" "r")
1232                            (const_int 16))
1233                           (zero_extend:SI
1234                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1235                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1236   "TARGET_MULHW"
1237   "macchwu %0,%1,%2"
1238   [(set_attr "type" "halfmul")])
1240 (define_insn "*machhwc"
1241   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1242         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1243                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1244                                        (const_int 16))
1245                                       (ashiftrt:SI
1246                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1247                                        (const_int 16)))
1248                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1249                     (const_int 0)))
1250    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251         (plus:SI (mult:SI (ashiftrt:SI
1252                            (match_dup 1)
1253                            (const_int 16))
1254                           (ashiftrt:SI
1255                            (match_dup 2)
1256                            (const_int 16)))
1257                  (match_dup 4)))]
1258   "TARGET_MULHW"
1259   "machhw. %0,%1,%2"
1260   [(set_attr "type" "halfmul")])
1262 (define_insn "*machhw"
1263   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264         (plus:SI (mult:SI (ashiftrt:SI
1265                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1266                            (const_int 16))
1267                           (ashiftrt:SI
1268                            (match_operand:SI 2 "gpc_reg_operand" "r")
1269                            (const_int 16)))
1270                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1271   "TARGET_MULHW"
1272   "machhw %0,%1,%2"
1273   [(set_attr "type" "halfmul")])
1275 (define_insn "*machhwuc"
1276   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1277         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1278                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1279                                        (const_int 16))
1280                                       (lshiftrt:SI
1281                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1282                                        (const_int 16)))
1283                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1284                     (const_int 0)))
1285    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1286         (plus:SI (mult:SI (lshiftrt:SI
1287                            (match_dup 1)
1288                            (const_int 16))
1289                           (lshiftrt:SI
1290                            (match_dup 2)
1291                            (const_int 16)))
1292                  (match_dup 4)))]
1293   "TARGET_MULHW"
1294   "machhwu. %0,%1,%2"
1295   [(set_attr "type" "halfmul")])
1297 (define_insn "*machhwu"
1298   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299         (plus:SI (mult:SI (lshiftrt:SI
1300                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1301                            (const_int 16))
1302                           (lshiftrt:SI
1303                            (match_operand:SI 2 "gpc_reg_operand" "r")
1304                            (const_int 16)))
1305                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1306   "TARGET_MULHW"
1307   "machhwu %0,%1,%2"
1308   [(set_attr "type" "halfmul")])
1310 (define_insn "*maclhwc"
1311   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1312         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1313                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1314                                       (sign_extend:SI
1315                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1316                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1317                     (const_int 0)))
1318    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1319         (plus:SI (mult:SI (sign_extend:SI
1320                            (match_dup 1))
1321                           (sign_extend:SI
1322                            (match_dup 2)))
1323                  (match_dup 4)))]
1324   "TARGET_MULHW"
1325   "maclhw. %0,%1,%2"
1326   [(set_attr "type" "halfmul")])
1328 (define_insn "*maclhw"
1329   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330         (plus:SI (mult:SI (sign_extend:SI
1331                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1332                           (sign_extend:SI
1333                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1334                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1335   "TARGET_MULHW"
1336   "maclhw %0,%1,%2"
1337   [(set_attr "type" "halfmul")])
1339 (define_insn "*maclhwuc"
1340   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1341         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1342                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1343                                       (zero_extend:SI
1344                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1345                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1346                     (const_int 0)))
1347    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1348         (plus:SI (mult:SI (zero_extend:SI
1349                            (match_dup 1))
1350                           (zero_extend:SI
1351                            (match_dup 2)))
1352                  (match_dup 4)))]
1353   "TARGET_MULHW"
1354   "maclhwu. %0,%1,%2"
1355   [(set_attr "type" "halfmul")])
1357 (define_insn "*maclhwu"
1358   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359         (plus:SI (mult:SI (zero_extend:SI
1360                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1361                           (zero_extend:SI
1362                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1363                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1364   "TARGET_MULHW"
1365   "maclhwu %0,%1,%2"
1366   [(set_attr "type" "halfmul")])
1368 (define_insn "*nmacchwc"
1369   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1370         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1371                               (mult:SI (ashiftrt:SI
1372                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1373                                         (const_int 16))
1374                                        (sign_extend:SI
1375                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1376                     (const_int 0)))
1377    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1378         (minus:SI (match_dup 4)
1379                   (mult:SI (ashiftrt:SI
1380                             (match_dup 2)
1381                             (const_int 16))
1382                            (sign_extend:SI
1383                             (match_dup 1)))))]
1384   "TARGET_MULHW"
1385   "nmacchw. %0,%1,%2"
1386   [(set_attr "type" "halfmul")])
1388 (define_insn "*nmacchw"
1389   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1391                   (mult:SI (ashiftrt:SI
1392                             (match_operand:SI 2 "gpc_reg_operand" "r")
1393                             (const_int 16))
1394                            (sign_extend:SI
1395                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1396   "TARGET_MULHW"
1397   "nmacchw %0,%1,%2"
1398   [(set_attr "type" "halfmul")])
1400 (define_insn "*nmachhwc"
1401   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1402         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1403                               (mult:SI (ashiftrt:SI
1404                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1405                                         (const_int 16))
1406                                        (ashiftrt:SI
1407                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1408                                         (const_int 16))))
1409                     (const_int 0)))
1410    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411         (minus:SI (match_dup 4)
1412                   (mult:SI (ashiftrt:SI
1413                             (match_dup 1)
1414                             (const_int 16))
1415                            (ashiftrt:SI
1416                             (match_dup 2)
1417                             (const_int 16)))))]
1418   "TARGET_MULHW"
1419   "nmachhw. %0,%1,%2"
1420   [(set_attr "type" "halfmul")])
1422 (define_insn "*nmachhw"
1423   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1425                   (mult:SI (ashiftrt:SI
1426                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1427                             (const_int 16))
1428                            (ashiftrt:SI
1429                             (match_operand:SI 2 "gpc_reg_operand" "r")
1430                             (const_int 16)))))]
1431   "TARGET_MULHW"
1432   "nmachhw %0,%1,%2"
1433   [(set_attr "type" "halfmul")])
1435 (define_insn "*nmaclhwc"
1436   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1437         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1438                               (mult:SI (sign_extend:SI
1439                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1440                                        (sign_extend:SI
1441                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1442                     (const_int 0)))
1443    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444         (minus:SI (match_dup 4)
1445                   (mult:SI (sign_extend:SI
1446                             (match_dup 1))
1447                            (sign_extend:SI
1448                             (match_dup 2)))))]
1449   "TARGET_MULHW"
1450   "nmaclhw. %0,%1,%2"
1451   [(set_attr "type" "halfmul")])
1453 (define_insn "*nmaclhw"
1454   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1455         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1456                   (mult:SI (sign_extend:SI
1457                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1458                            (sign_extend:SI
1459                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1460   "TARGET_MULHW"
1461   "nmaclhw %0,%1,%2"
1462   [(set_attr "type" "halfmul")])
1464 (define_insn "*mulchwc"
1465   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1466         (compare:CC (mult:SI (ashiftrt:SI
1467                               (match_operand:SI 2 "gpc_reg_operand" "r")
1468                               (const_int 16))
1469                              (sign_extend:SI
1470                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1471                     (const_int 0)))
1472    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1473         (mult:SI (ashiftrt:SI
1474                   (match_dup 2)
1475                   (const_int 16))
1476                  (sign_extend:SI
1477                   (match_dup 1))))]
1478   "TARGET_MULHW"
1479   "mulchw. %0,%1,%2"
1480   [(set_attr "type" "halfmul")])
1482 (define_insn "*mulchw"
1483   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1484         (mult:SI (ashiftrt:SI
1485                   (match_operand:SI 2 "gpc_reg_operand" "r")
1486                   (const_int 16))
1487                  (sign_extend:SI
1488                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1489   "TARGET_MULHW"
1490   "mulchw %0,%1,%2"
1491   [(set_attr "type" "halfmul")])
1493 (define_insn "*mulchwuc"
1494   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1495         (compare:CC (mult:SI (lshiftrt:SI
1496                               (match_operand:SI 2 "gpc_reg_operand" "r")
1497                               (const_int 16))
1498                              (zero_extend:SI
1499                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1500                     (const_int 0)))
1501    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1502         (mult:SI (lshiftrt:SI
1503                   (match_dup 2)
1504                   (const_int 16))
1505                  (zero_extend:SI
1506                   (match_dup 1))))]
1507   "TARGET_MULHW"
1508   "mulchwu. %0,%1,%2"
1509   [(set_attr "type" "halfmul")])
1511 (define_insn "*mulchwu"
1512   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1513         (mult:SI (lshiftrt:SI
1514                   (match_operand:SI 2 "gpc_reg_operand" "r")
1515                   (const_int 16))
1516                  (zero_extend:SI
1517                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1518   "TARGET_MULHW"
1519   "mulchwu %0,%1,%2"
1520   [(set_attr "type" "halfmul")])
1522 (define_insn "*mulhhwc"
1523   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1524         (compare:CC (mult:SI (ashiftrt:SI
1525                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1526                               (const_int 16))
1527                              (ashiftrt:SI
1528                               (match_operand:SI 2 "gpc_reg_operand" "r")
1529                               (const_int 16)))
1530                     (const_int 0)))
1531    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532         (mult:SI (ashiftrt:SI
1533                   (match_dup 1)
1534                   (const_int 16))
1535                  (ashiftrt:SI
1536                   (match_dup 2)
1537                   (const_int 16))))]
1538   "TARGET_MULHW"
1539   "mulhhw. %0,%1,%2"
1540   [(set_attr "type" "halfmul")])
1542 (define_insn "*mulhhw"
1543   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1544         (mult:SI (ashiftrt:SI
1545                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1546                   (const_int 16))
1547                  (ashiftrt:SI
1548                   (match_operand:SI 2 "gpc_reg_operand" "r")
1549                   (const_int 16))))]
1550   "TARGET_MULHW"
1551   "mulhhw %0,%1,%2"
1552   [(set_attr "type" "halfmul")])
1554 (define_insn "*mulhhwuc"
1555   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1556         (compare:CC (mult:SI (lshiftrt:SI
1557                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1558                               (const_int 16))
1559                              (lshiftrt:SI
1560                               (match_operand:SI 2 "gpc_reg_operand" "r")
1561                               (const_int 16)))
1562                     (const_int 0)))
1563    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1564         (mult:SI (lshiftrt:SI
1565                   (match_dup 1)
1566                   (const_int 16))
1567                  (lshiftrt:SI
1568                   (match_dup 2)
1569                   (const_int 16))))]
1570   "TARGET_MULHW"
1571   "mulhhwu. %0,%1,%2"
1572   [(set_attr "type" "halfmul")])
1574 (define_insn "*mulhhwu"
1575   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1576         (mult:SI (lshiftrt:SI
1577                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1578                   (const_int 16))
1579                  (lshiftrt:SI
1580                   (match_operand:SI 2 "gpc_reg_operand" "r")
1581                   (const_int 16))))]
1582   "TARGET_MULHW"
1583   "mulhhwu %0,%1,%2"
1584   [(set_attr "type" "halfmul")])
1586 (define_insn "*mullhwc"
1587   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1588         (compare:CC (mult:SI (sign_extend:SI
1589                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1590                              (sign_extend:SI
1591                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1592                     (const_int 0)))
1593    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1594         (mult:SI (sign_extend:SI
1595                   (match_dup 1))
1596                  (sign_extend:SI
1597                   (match_dup 2))))]
1598   "TARGET_MULHW"
1599   "mullhw. %0,%1,%2"
1600   [(set_attr "type" "halfmul")])
1602 (define_insn "*mullhw"
1603   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1604         (mult:SI (sign_extend:SI
1605                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1606                  (sign_extend:SI
1607                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1608   "TARGET_MULHW"
1609   "mullhw %0,%1,%2"
1610   [(set_attr "type" "halfmul")])
1612 (define_insn "*mullhwuc"
1613   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1614         (compare:CC (mult:SI (zero_extend:SI
1615                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1616                              (zero_extend:SI
1617                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1618                     (const_int 0)))
1619    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1620         (mult:SI (zero_extend:SI
1621                   (match_dup 1))
1622                  (zero_extend:SI
1623                   (match_dup 2))))]
1624   "TARGET_MULHW"
1625   "mullhwu. %0,%1,%2"
1626   [(set_attr "type" "halfmul")])
1628 (define_insn "*mullhwu"
1629   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1630         (mult:SI (zero_extend:SI
1631                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1632                  (zero_extend:SI
1633                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1634   "TARGET_MULHW"
1635   "mullhwu %0,%1,%2"
1636   [(set_attr "type" "halfmul")])
1638 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1639 (define_insn "dlmzb"
1640   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1641         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1642                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1643                    UNSPEC_DLMZB_CR))
1644    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1645         (unspec:SI [(match_dup 1)
1646                     (match_dup 2)]
1647                    UNSPEC_DLMZB))]
1648   "TARGET_DLMZB"
1649   "dlmzb. %0,%1,%2")
1651 (define_expand "strlensi"
1652   [(set (match_operand:SI 0 "gpc_reg_operand")
1653         (unspec:SI [(match_operand:BLK 1 "general_operand")
1654                     (match_operand:QI 2 "const_int_operand")
1655                     (match_operand 3 "const_int_operand")]
1656                    UNSPEC_DLMZB_STRLEN))
1657    (clobber (match_scratch:CC 4))]
1658   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1660   rtx result = operands[0];
1661   rtx src = operands[1];
1662   rtx search_char = operands[2];
1663   rtx align = operands[3];
1664   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1665   rtx loop_label, end_label, mem, cr0, cond;
1666   if (search_char != const0_rtx
1667       || !CONST_INT_P (align)
1668       || INTVAL (align) < 8)
1669         FAIL;
1670   word1 = gen_reg_rtx (SImode);
1671   word2 = gen_reg_rtx (SImode);
1672   scratch_dlmzb = gen_reg_rtx (SImode);
1673   scratch_string = gen_reg_rtx (Pmode);
1674   loop_label = gen_label_rtx ();
1675   end_label = gen_label_rtx ();
1676   addr = force_reg (Pmode, XEXP (src, 0));
1677   emit_move_insn (scratch_string, addr);
1678   emit_label (loop_label);
1679   mem = change_address (src, SImode, scratch_string);
1680   emit_move_insn (word1, mem);
1681   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1682   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1683   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1684   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1685   emit_jump_insn (gen_rtx_SET (pc_rtx,
1686                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1687                                                      cond,
1688                                                      gen_rtx_LABEL_REF
1689                                                        (VOIDmode,
1690                                                         end_label),
1691                                                      pc_rtx)));
1692   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1693   emit_jump_insn (gen_rtx_SET (pc_rtx,
1694                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1695   emit_barrier ();
1696   emit_label (end_label);
1697   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1698   emit_insn (gen_subsi3 (result, scratch_string, addr));
1699   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1700   DONE;
1703 ;; Fixed-point arithmetic insns.
1705 (define_expand "add<mode>3"
1706   [(set (match_operand:SDI 0 "gpc_reg_operand")
1707         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1708                   (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1709   ""
1711   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1712     {
1713       rtx lo0 = gen_lowpart (SImode, operands[0]);
1714       rtx lo1 = gen_lowpart (SImode, operands[1]);
1715       rtx lo2 = gen_lowpart (SImode, operands[2]);
1716       rtx hi0 = gen_highpart (SImode, operands[0]);
1717       rtx hi1 = gen_highpart (SImode, operands[1]);
1718       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1720       if (!reg_or_short_operand (lo2, SImode))
1721         lo2 = force_reg (SImode, lo2);
1722       if (!adde_operand (hi2, SImode))
1723         hi2 = force_reg (SImode, hi2);
1725       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1726       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1727       DONE;
1728     }
1730   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1731     {
1732       rtx tmp = ((!can_create_pseudo_p ()
1733                   || rtx_equal_p (operands[0], operands[1]))
1734                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1736       /* Adding a constant to r0 is not a valid insn, so use a different
1737          strategy in that case.  */
1738       if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1739         {
1740           if (operands[0] == operands[1])
1741             FAIL;
1742           rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1743           emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1744           DONE;
1745         }
1747       HOST_WIDE_INT val = INTVAL (operands[2]);
1748       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1749       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1751       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1752         FAIL;
1754       /* The ordering here is important for the prolog expander.
1755          When space is allocated from the stack, adding 'low' first may
1756          produce a temporary deallocation (which would be bad).  */
1757       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1758       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1759       DONE;
1760     }
1763 (define_insn "*add<mode>3"
1764   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1765         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1766                   (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1767   ""
1768   "@
1769    add %0,%1,%2
1770    addi %0,%1,%2
1771    addis %0,%1,%v2
1772    addi %0,%1,%2"
1773   [(set_attr "type" "add")
1774    (set_attr "isa" "*,*,*,fut")])
1776 (define_insn "*addsi3_high"
1777   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1778         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1779                  (high:SI (match_operand 2 "" ""))))]
1780   "TARGET_MACHO && !TARGET_64BIT"
1781   "addis %0,%1,ha16(%2)"
1782   [(set_attr "type" "add")])
1784 (define_insn_and_split "*add<mode>3_dot"
1785   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1786         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1787                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1788                     (const_int 0)))
1789    (clobber (match_scratch:GPR 0 "=r,r"))]
1790   "<MODE>mode == Pmode"
1791   "@
1792    add. %0,%1,%2
1793    #"
1794   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1795   [(set (match_dup 0)
1796         (plus:GPR (match_dup 1)
1797                  (match_dup 2)))
1798    (set (match_dup 3)
1799         (compare:CC (match_dup 0)
1800                     (const_int 0)))]
1801   ""
1802   [(set_attr "type" "add")
1803    (set_attr "dot" "yes")
1804    (set_attr "length" "4,8")])
1806 (define_insn_and_split "*add<mode>3_dot2"
1807   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1808         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1809                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1810                     (const_int 0)))
1811    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1812         (plus:GPR (match_dup 1)
1813                   (match_dup 2)))]
1814   "<MODE>mode == Pmode"
1815   "@
1816    add. %0,%1,%2
1817    #"
1818   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1819   [(set (match_dup 0)
1820         (plus:GPR (match_dup 1)
1821                   (match_dup 2)))
1822    (set (match_dup 3)
1823         (compare:CC (match_dup 0)
1824                     (const_int 0)))]
1825   ""
1826   [(set_attr "type" "add")
1827    (set_attr "dot" "yes")
1828    (set_attr "length" "4,8")])
1830 (define_insn_and_split "*add<mode>3_imm_dot"
1831   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1832         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1833                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1834                     (const_int 0)))
1835    (clobber (match_scratch:GPR 0 "=r,r"))
1836    (clobber (reg:GPR CA_REGNO))]
1837   "<MODE>mode == Pmode"
1838   "@
1839    addic. %0,%1,%2
1840    #"
1841   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1842   [(set (match_dup 0)
1843         (plus:GPR (match_dup 1)
1844                   (match_dup 2)))
1845    (set (match_dup 3)
1846         (compare:CC (match_dup 0)
1847                     (const_int 0)))]
1848   ""
1849   [(set_attr "type" "add")
1850    (set_attr "dot" "yes")
1851    (set_attr "length" "4,8")])
1853 (define_insn_and_split "*add<mode>3_imm_dot2"
1854   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1855         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1856                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1857                     (const_int 0)))
1858    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1859         (plus:GPR (match_dup 1)
1860                   (match_dup 2)))
1861    (clobber (reg:GPR CA_REGNO))]
1862   "<MODE>mode == Pmode"
1863   "@
1864    addic. %0,%1,%2
1865    #"
1866   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1867   [(set (match_dup 0)
1868         (plus:GPR (match_dup 1)
1869                   (match_dup 2)))
1870    (set (match_dup 3)
1871         (compare:CC (match_dup 0)
1872                     (const_int 0)))]
1873   ""
1874   [(set_attr "type" "add")
1875    (set_attr "dot" "yes")
1876    (set_attr "length" "4,8")])
1878 ;; Split an add that we can't do in one insn into two insns, each of which
1879 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1880 ;; add should be last in case the result gets used in an address.
1882 (define_split
1883   [(set (match_operand:GPR 0 "gpc_reg_operand")
1884         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1885                   (match_operand:GPR 2 "non_add_cint_operand")))]
1886   ""
1887   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1888    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1890   HOST_WIDE_INT val = INTVAL (operands[2]);
1891   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1892   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1894   operands[4] = GEN_INT (low);
1895   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1896     operands[3] = GEN_INT (rest);
1897   else if (can_create_pseudo_p ())
1898     {
1899       operands[3] = gen_reg_rtx (DImode);
1900       emit_move_insn (operands[3], operands[2]);
1901       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1902       DONE;
1903     }
1904   else
1905     FAIL;
1909 (define_insn "add<mode>3_carry"
1910   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1911         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1912                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1913    (set (reg:P CA_REGNO)
1914         (ltu:P (plus:P (match_dup 1)
1915                        (match_dup 2))
1916                (match_dup 1)))]
1917   ""
1918   "add%I2c %0,%1,%2"
1919   [(set_attr "type" "add")])
1921 (define_insn "*add<mode>3_imm_carry_pos"
1922   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1923         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1924                 (match_operand:P 2 "short_cint_operand" "n")))
1925    (set (reg:P CA_REGNO)
1926         (geu:P (match_dup 1)
1927                (match_operand:P 3 "const_int_operand" "n")))]
1928   "INTVAL (operands[2]) > 0
1929    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1930   "addic %0,%1,%2"
1931   [(set_attr "type" "add")])
1933 (define_insn "*add<mode>3_imm_carry_0"
1934   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1935         (match_operand:P 1 "gpc_reg_operand" "r"))
1936    (set (reg:P CA_REGNO)
1937         (const_int 0))]
1938   ""
1939   "addic %0,%1,0"
1940   [(set_attr "type" "add")])
1942 (define_insn "*add<mode>3_imm_carry_m1"
1943   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1944         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1945                 (const_int -1)))
1946    (set (reg:P CA_REGNO)
1947         (ne:P (match_dup 1)
1948               (const_int 0)))]
1949   ""
1950   "addic %0,%1,-1"
1951   [(set_attr "type" "add")])
1953 (define_insn "*add<mode>3_imm_carry_neg"
1954   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1955         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1956                 (match_operand:P 2 "short_cint_operand" "n")))
1957    (set (reg:P CA_REGNO)
1958         (gtu:P (match_dup 1)
1959                (match_operand:P 3 "const_int_operand" "n")))]
1960   "INTVAL (operands[2]) < 0
1961    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1962   "addic %0,%1,%2"
1963   [(set_attr "type" "add")])
1966 (define_expand "add<mode>3_carry_in"
1967   [(parallel [
1968      (set (match_operand:GPR 0 "gpc_reg_operand")
1969           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1970                               (match_operand:GPR 2 "adde_operand"))
1971                     (reg:GPR CA_REGNO)))
1972      (clobber (reg:GPR CA_REGNO))])]
1973   ""
1975   if (operands[2] == const0_rtx)
1976     {
1977       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1978       DONE;
1979     }
1980   if (operands[2] == constm1_rtx)
1981     {
1982       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1983       DONE;
1984     }
1987 (define_insn "*add<mode>3_carry_in_internal"
1988   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1989         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1990                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1991                   (reg:GPR CA_REGNO)))
1992    (clobber (reg:GPR CA_REGNO))]
1993   ""
1994   "adde %0,%1,%2"
1995   [(set_attr "type" "add")])
1997 (define_insn "*add<mode>3_carry_in_internal2"
1998   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1999         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2000                             (reg:GPR CA_REGNO))
2001                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2002    (clobber (reg:GPR CA_REGNO))]
2003   ""
2004   "adde %0,%1,%2"
2005   [(set_attr "type" "add")])
2007 (define_insn "add<mode>3_carry_in_0"
2008   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2009         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2010                   (reg:GPR CA_REGNO)))
2011    (clobber (reg:GPR CA_REGNO))]
2012   ""
2013   "addze %0,%1"
2014   [(set_attr "type" "add")])
2016 (define_insn "add<mode>3_carry_in_m1"
2017   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2018         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2019                             (reg:GPR CA_REGNO))
2020                   (const_int -1)))
2021    (clobber (reg:GPR CA_REGNO))]
2022   ""
2023   "addme %0,%1"
2024   [(set_attr "type" "add")])
2027 (define_expand "one_cmpl<mode>2"
2028   [(set (match_operand:SDI 0 "gpc_reg_operand")
2029         (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2030   ""
2032   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2033     {
2034       rs6000_split_logical (operands, NOT, false, false, false);
2035       DONE;
2036     }
2039 (define_insn "*one_cmpl<mode>2"
2040   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2041         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2042   ""
2043   "not %0,%1")
2045 (define_insn_and_split "*one_cmpl<mode>2_dot"
2046   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2047         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2048                     (const_int 0)))
2049    (clobber (match_scratch:GPR 0 "=r,r"))]
2050   "<MODE>mode == Pmode"
2051   "@
2052    not. %0,%1
2053    #"
2054   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2055   [(set (match_dup 0)
2056         (not:GPR (match_dup 1)))
2057    (set (match_dup 2)
2058         (compare:CC (match_dup 0)
2059                     (const_int 0)))]
2060   ""
2061   [(set_attr "type" "logical")
2062    (set_attr "dot" "yes")
2063    (set_attr "length" "4,8")])
2065 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2066   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2067         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2068                     (const_int 0)))
2069    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2070         (not:GPR (match_dup 1)))]
2071   "<MODE>mode == Pmode"
2072   "@
2073    not. %0,%1
2074    #"
2075   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2076   [(set (match_dup 0)
2077         (not:GPR (match_dup 1)))
2078    (set (match_dup 2)
2079         (compare:CC (match_dup 0)
2080                     (const_int 0)))]
2081   ""
2082   [(set_attr "type" "logical")
2083    (set_attr "dot" "yes")
2084    (set_attr "length" "4,8")])
2087 (define_expand "sub<mode>3"
2088   [(set (match_operand:SDI 0 "gpc_reg_operand")
2089         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2090                    (match_operand:SDI 2 "gpc_reg_operand")))]
2091   ""
2093   if (<MODE>mode == DImode && !TARGET_POWERPC64)
2094     {
2095       rtx lo0 = gen_lowpart (SImode, operands[0]);
2096       rtx lo1 = gen_lowpart (SImode, operands[1]);
2097       rtx lo2 = gen_lowpart (SImode, operands[2]);
2098       rtx hi0 = gen_highpart (SImode, operands[0]);
2099       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2100       rtx hi2 = gen_highpart (SImode, operands[2]);
2102       if (!reg_or_short_operand (lo1, SImode))
2103         lo1 = force_reg (SImode, lo1);
2104       if (!adde_operand (hi1, SImode))
2105         hi1 = force_reg (SImode, hi1);
2107       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2108       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2109       DONE;
2110     }
2112   if (short_cint_operand (operands[1], <MODE>mode))
2113     {
2114       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2115       DONE;
2116     }
2119 (define_insn "*subf<mode>3"
2120   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2121         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2122                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2123   ""
2124   "subf %0,%1,%2"
2125   [(set_attr "type" "add")])
2127 (define_insn_and_split "*subf<mode>3_dot"
2128   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2129         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2130                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2131                     (const_int 0)))
2132    (clobber (match_scratch:GPR 0 "=r,r"))]
2133   "<MODE>mode == Pmode"
2134   "@
2135    subf. %0,%1,%2
2136    #"
2137   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2138   [(set (match_dup 0)
2139         (minus:GPR (match_dup 2)
2140                    (match_dup 1)))
2141    (set (match_dup 3)
2142         (compare:CC (match_dup 0)
2143                     (const_int 0)))]
2144   ""
2145   [(set_attr "type" "add")
2146    (set_attr "dot" "yes")
2147    (set_attr "length" "4,8")])
2149 (define_insn_and_split "*subf<mode>3_dot2"
2150   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2151         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2152                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2153                     (const_int 0)))
2154    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2155         (minus:GPR (match_dup 2)
2156                    (match_dup 1)))]
2157   "<MODE>mode == Pmode"
2158   "@
2159    subf. %0,%1,%2
2160    #"
2161   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2162   [(set (match_dup 0)
2163         (minus:GPR (match_dup 2)
2164                    (match_dup 1)))
2165    (set (match_dup 3)
2166         (compare:CC (match_dup 0)
2167                     (const_int 0)))]
2168   ""
2169   [(set_attr "type" "add")
2170    (set_attr "dot" "yes")
2171    (set_attr "length" "4,8")])
2173 (define_insn "subf<mode>3_imm"
2174   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2175         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2176                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
2177    (clobber (reg:GPR CA_REGNO))]
2178   ""
2179   "subfic %0,%1,%2"
2180   [(set_attr "type" "add")])
2182 (define_insn_and_split "subf<mode>3_carry_dot2"
2183   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2184         (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2185                                (match_operand:P 1 "gpc_reg_operand" "r,r"))
2186                     (const_int 0)))
2187    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2188         (minus:P (match_dup 2)
2189                    (match_dup 1)))
2190    (set (reg:P CA_REGNO)
2191         (leu:P (match_dup 1)
2192                (match_dup 2)))]
2193   "<MODE>mode == Pmode"
2194   "@
2195    subfc. %0,%1,%2
2196    #"
2197   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2198   [(parallel [(set (match_dup 0)
2199                    (minus:P (match_dup 2)
2200                             (match_dup 1)))
2201               (set (reg:P CA_REGNO)
2202                    (leu:P (match_dup 1)
2203                           (match_dup 2)))])
2204    (set (match_dup 3)
2205         (compare:CC (match_dup 0)
2206                     (const_int 0)))]
2207   ""
2208   [(set_attr "type" "add")
2209    (set_attr "dot" "yes")
2210    (set_attr "length" "4,8")])
2212 (define_insn "subf<mode>3_carry"
2213   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2214         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2215                  (match_operand:P 1 "gpc_reg_operand" "r")))
2216    (set (reg:P CA_REGNO)
2217         (leu:P (match_dup 1)
2218                (match_dup 2)))]
2219   ""
2220   "subf%I2c %0,%1,%2"
2221   [(set_attr "type" "add")])
2223 (define_insn "*subf<mode>3_imm_carry_0"
2224   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2225         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2226    (set (reg:P CA_REGNO)
2227         (eq:P (match_dup 1)
2228               (const_int 0)))]
2229   ""
2230   "subfic %0,%1,0"
2231   [(set_attr "type" "add")])
2233 (define_insn "*subf<mode>3_imm_carry_m1"
2234   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2235         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2236    (set (reg:P CA_REGNO)
2237         (const_int 1))]
2238   ""
2239   "subfic %0,%1,-1"
2240   [(set_attr "type" "add")])
2243 (define_expand "subf<mode>3_carry_in"
2244   [(parallel [
2245      (set (match_operand:GPR 0 "gpc_reg_operand")
2246           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2247                               (reg:GPR CA_REGNO))
2248                     (match_operand:GPR 2 "adde_operand")))
2249      (clobber (reg:GPR CA_REGNO))])]
2250   ""
2252   if (operands[2] == const0_rtx)
2253     {
2254       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2255       DONE;
2256     }
2257   if (operands[2] == constm1_rtx)
2258     {
2259       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2260       DONE;
2261     }
2264 (define_insn "*subf<mode>3_carry_in_internal"
2265   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2266         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2267                             (reg:GPR CA_REGNO))
2268                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2269    (clobber (reg:GPR CA_REGNO))]
2270   ""
2271   "subfe %0,%1,%2"
2272   [(set_attr "type" "add")])
2274 (define_insn "subf<mode>3_carry_in_0"
2275   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2276         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2277                   (reg:GPR CA_REGNO)))
2278    (clobber (reg:GPR CA_REGNO))]
2279   ""
2280   "subfze %0,%1"
2281   [(set_attr "type" "add")])
2283 (define_insn "subf<mode>3_carry_in_m1"
2284   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2285         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2286                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2287                   (const_int -2)))
2288    (clobber (reg:GPR CA_REGNO))]
2289   ""
2290   "subfme %0,%1"
2291   [(set_attr "type" "add")])
2293 (define_insn "subf<mode>3_carry_in_xx"
2294   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295         (plus:GPR (reg:GPR CA_REGNO)
2296                   (const_int -1)))
2297    (clobber (reg:GPR CA_REGNO))]
2298   ""
2299   "subfe %0,%0,%0"
2300   [(set_attr "type" "add")])
2303 (define_insn "@neg<mode>2"
2304   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2305         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2306   ""
2307   "neg %0,%1"
2308   [(set_attr "type" "add")])
2310 (define_insn_and_split "*neg<mode>2_dot"
2311   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2312         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2313                     (const_int 0)))
2314    (clobber (match_scratch:GPR 0 "=r,r"))]
2315   "<MODE>mode == Pmode"
2316   "@
2317    neg. %0,%1
2318    #"
2319   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2320   [(set (match_dup 0)
2321         (neg:GPR (match_dup 1)))
2322    (set (match_dup 2)
2323         (compare:CC (match_dup 0)
2324                     (const_int 0)))]
2325   ""
2326   [(set_attr "type" "add")
2327    (set_attr "dot" "yes")
2328    (set_attr "length" "4,8")])
2330 (define_insn_and_split "*neg<mode>2_dot2"
2331   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2332         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2333                     (const_int 0)))
2334    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2335         (neg:GPR (match_dup 1)))]
2336   "<MODE>mode == Pmode"
2337   "@
2338    neg. %0,%1
2339    #"
2340   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2341   [(set (match_dup 0)
2342         (neg:GPR (match_dup 1)))
2343    (set (match_dup 2)
2344         (compare:CC (match_dup 0)
2345                     (const_int 0)))]
2346   ""
2347   [(set_attr "type" "add")
2348    (set_attr "dot" "yes")
2349    (set_attr "length" "4,8")])
2352 (define_insn "clz<mode>2"
2353   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2354         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2355   ""
2356   "cntlz<wd> %0,%1"
2357   [(set_attr "type" "cntlz")])
2359 (define_expand "ctz<mode>2"
2360    [(set (match_operand:GPR 0 "gpc_reg_operand")
2361          (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2362   ""
2364   if (TARGET_CTZ)
2365     {
2366       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2367       DONE;
2368     }
2370   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2371   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2372   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2374   if (TARGET_POPCNTD)
2375     {
2376       emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2377       emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2378       emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2379       emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2380     }
2381   else
2382     {
2383       emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2384       emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2385       emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2386       emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2387     }
2389   DONE;
2392 (define_insn "ctz<mode>2_hw"
2393   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2394         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2395   "TARGET_CTZ"
2396   "cnttz<wd> %0,%1"
2397   [(set_attr "type" "cntlz")])
2399 (define_expand "ffs<mode>2"
2400   [(set (match_operand:GPR 0 "gpc_reg_operand")
2401         (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2402   ""
2404   rtx tmp1 = gen_reg_rtx (<MODE>mode);
2405   rtx tmp2 = gen_reg_rtx (<MODE>mode);
2406   rtx tmp3 = gen_reg_rtx (<MODE>mode);
2407   emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2408   emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2409   emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2410   emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2411   DONE;
2415 (define_expand "popcount<mode>2"
2416   [(set (match_operand:GPR 0 "gpc_reg_operand")
2417         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2418   "TARGET_POPCNTB || TARGET_POPCNTD"
2420   rs6000_emit_popcount (operands[0], operands[1]);
2421   DONE;
2424 (define_insn "popcntb<mode>2"
2425   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2426         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2427                     UNSPEC_POPCNTB))]
2428   "TARGET_POPCNTB"
2429   "popcntb %0,%1"
2430   [(set_attr "type" "popcnt")])
2432 (define_insn "popcntd<mode>2"
2433   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2434         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2435   "TARGET_POPCNTD"
2436   "popcnt<wd> %0,%1"
2437   [(set_attr "type" "popcnt")])
2440 (define_expand "parity<mode>2"
2441   [(set (match_operand:GPR 0 "gpc_reg_operand")
2442         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2443   "TARGET_POPCNTB"
2445   rs6000_emit_parity (operands[0], operands[1]);
2446   DONE;
2449 (define_insn "parity<mode>2_cmpb"
2450   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2451         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2452   "TARGET_CMPB && TARGET_POPCNTB"
2453   "prty<wd> %0,%1"
2454   [(set_attr "type" "popcnt")])
2456 (define_insn "cmpb<mode>3"
2457   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2458         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2459                      (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2460   "TARGET_CMPB"
2461   "cmpb %0,%1,%2"
2462   [(set_attr "type" "cmp")])
2464 ;; Since the hardware zeros the upper part of the register, save generating the
2465 ;; AND immediate if we are converting to unsigned
2466 (define_insn "*bswap<mode>2_extenddi"
2467   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2468         (zero_extend:DI
2469          (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2470   "TARGET_POWERPC64"
2471   "l<wd>brx %0,%y1"
2472   [(set_attr "type" "load")])
2474 (define_insn "*bswaphi2_extendsi"
2475   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2476         (zero_extend:SI
2477          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2478   ""
2479   "lhbrx %0,%y1"
2480   [(set_attr "type" "load")])
2482 ;; Separate the bswap patterns into load, store, and gpr<-gpr.  This prevents
2483 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2484 ;; load with byte swap, which can be slower than doing it in the registers.  It
2485 ;; also prevents certain failures with the RELOAD register allocator.
2487 (define_expand "bswap<mode>2"
2488   [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2489    (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2490   ""
2492   rtx dest = operands[0];
2493   rtx src = operands[1];
2495   if (!REG_P (dest) && !REG_P (src))
2496     src = force_reg (<MODE>mode, src);
2498   if (MEM_P (src))
2499     {
2500       src = rs6000_force_indexed_or_indirect_mem (src);
2501       emit_insn (gen_bswap<mode>2_load (dest, src));
2502     }
2503   else if (MEM_P (dest))
2504     {
2505       dest = rs6000_force_indexed_or_indirect_mem (dest);
2506       emit_insn (gen_bswap<mode>2_store (dest, src));
2507     }
2508   else
2509     emit_insn (gen_bswap<mode>2_reg (dest, src));
2510   DONE;
2513 (define_insn "bswap<mode>2_load"
2514   [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2515         (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2516   ""
2517   "l<wd>brx %0,%y1"
2518   [(set_attr "type" "load")])
2520 (define_insn "bswap<mode>2_store"
2521   [(set (match_operand:HSI 0 "memory_operand" "=Z")
2522         (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2523   ""
2524   "st<wd>brx %1,%y0"
2525   [(set_attr "type" "store")])
2527 (define_insn_and_split "bswaphi2_reg"
2528   [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2529         (bswap:HI
2530          (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2531    (clobber (match_scratch:SI 2 "=&r,X"))]
2532   ""
2533   "@
2534    #
2535    xxbrh %x0,%x1"
2536   "reload_completed && int_reg_operand (operands[0], HImode)"
2537   [(set (match_dup 3)
2538         (and:SI (lshiftrt:SI (match_dup 4)
2539                              (const_int 8))
2540                 (const_int 255)))
2541    (set (match_dup 2)
2542         (and:SI (ashift:SI (match_dup 4)
2543                            (const_int 8))
2544                 (const_int 65280)))             ;; 0xff00
2545    (set (match_dup 3)
2546         (ior:SI (match_dup 3)
2547                 (match_dup 2)))]
2549   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2550   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2552   [(set_attr "length" "12,4")
2553    (set_attr "type" "*,vecperm")
2554    (set_attr "isa" "*,p9v")])
2556 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2557 ;; zero_extract insns do not change for -mlittle.
2558 (define_insn_and_split "bswapsi2_reg"
2559   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2560         (bswap:SI
2561          (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2562   ""
2563   "@
2564    #
2565    xxbrw %x0,%x1"
2566   "reload_completed && int_reg_operand (operands[0], SImode)"
2567   [(set (match_dup 0)                                   ; DABC
2568         (rotate:SI (match_dup 1)
2569                    (const_int 24)))
2570    (set (match_dup 0)                                   ; DCBC
2571         (ior:SI (and:SI (ashift:SI (match_dup 1)
2572                                    (const_int 8))
2573                         (const_int 16711680))
2574                 (and:SI (match_dup 0)
2575                         (const_int -16711681))))
2576    (set (match_dup 0)                                   ; DCBA
2577         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2578                                      (const_int 24))
2579                         (const_int 255))
2580                 (and:SI (match_dup 0)
2581                         (const_int -256))))]
2582   ""
2583   [(set_attr "length" "12,4")
2584    (set_attr "type" "*,vecperm")
2585    (set_attr "isa" "*,p9v")])
2587 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2588 ;; we do for L{H,W}BRX and ST{H,W}BRX above.  If not, we have to generate more
2589 ;; complex code.
2591 (define_expand "bswapdi2"
2592   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2593                    (bswap:DI
2594                     (match_operand:DI 1 "reg_or_mem_operand")))
2595               (clobber (match_scratch:DI 2))
2596               (clobber (match_scratch:DI 3))])]
2597   ""
2599   rtx dest = operands[0];
2600   rtx src = operands[1];
2602   if (!REG_P (dest) && !REG_P (src))
2603     operands[1] = src = force_reg (DImode, src);
2605   if (TARGET_POWERPC64 && TARGET_LDBRX)
2606     {
2607       if (MEM_P (src))
2608         {
2609           src = rs6000_force_indexed_or_indirect_mem (src);
2610           emit_insn (gen_bswapdi2_load (dest, src));
2611         }
2612       else if (MEM_P (dest))
2613         {
2614           dest = rs6000_force_indexed_or_indirect_mem (dest);
2615           emit_insn (gen_bswapdi2_store (dest, src));
2616         }
2617       else if (TARGET_P9_VECTOR)
2618         emit_insn (gen_bswapdi2_xxbrd (dest, src));
2619       else
2620         emit_insn (gen_bswapdi2_reg (dest, src));
2621       DONE;
2622     }
2624   if (!TARGET_POWERPC64)
2625     {
2626       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2627          that uses 64-bit registers needs the same scratch registers as 64-bit
2628          mode.  */
2629       emit_insn (gen_bswapdi2_32bit (dest, src));
2630       DONE;
2631     }
2634 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2635 (define_insn "bswapdi2_load"
2636   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2637         (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2638   "TARGET_POWERPC64 && TARGET_LDBRX"
2639   "ldbrx %0,%y1"
2640   [(set_attr "type" "load")])
2642 (define_insn "bswapdi2_store"
2643   [(set (match_operand:DI 0 "memory_operand" "=Z")
2644         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2645   "TARGET_POWERPC64 && TARGET_LDBRX"
2646   "stdbrx %1,%y0"
2647   [(set_attr "type" "store")])
2649 (define_insn "bswapdi2_xxbrd"
2650   [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2651         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2652   "TARGET_P9_VECTOR"
2653   "xxbrd %x0,%x1"
2654   [(set_attr "type" "vecperm")
2655    (set_attr "isa" "p9v")])
2657 (define_insn "bswapdi2_reg"
2658   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2659         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2660    (clobber (match_scratch:DI 2 "=&r"))
2661    (clobber (match_scratch:DI 3 "=&r"))]
2662   "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2663   "#"
2664   [(set_attr "length" "36")])
2666 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2667 (define_insn "*bswapdi2_64bit"
2668   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2669         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2670    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2671    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2672   "TARGET_POWERPC64 && !TARGET_LDBRX
2673    && (REG_P (operands[0]) || REG_P (operands[1]))
2674    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2675    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2676   "#"
2677   [(set_attr "length" "16,12,36")])
2679 (define_split
2680   [(set (match_operand:DI 0 "gpc_reg_operand")
2681         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2682    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2683    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2684   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2685   [(const_int 0)]
2687   rtx dest   = operands[0];
2688   rtx src    = operands[1];
2689   rtx op2    = operands[2];
2690   rtx op3    = operands[3];
2691   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2692                                     BYTES_BIG_ENDIAN ? 4 : 0);
2693   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2694                                      BYTES_BIG_ENDIAN ? 4 : 0);
2695   rtx addr1;
2696   rtx addr2;
2697   rtx word1;
2698   rtx word2;
2700   addr1 = XEXP (src, 0);
2701   if (GET_CODE (addr1) == PLUS)
2702     {
2703       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2704       if (TARGET_AVOID_XFORM)
2705         {
2706           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2707           addr2 = op2;
2708         }
2709       else
2710         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2711     }
2712   else if (TARGET_AVOID_XFORM)
2713     {
2714       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2715       addr2 = op2;
2716     }
2717   else
2718     {
2719       emit_move_insn (op2, GEN_INT (4));
2720       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2721     }
2723   word1 = change_address (src, SImode, addr1);
2724   word2 = change_address (src, SImode, addr2);
2726   if (BYTES_BIG_ENDIAN)
2727     {
2728       emit_insn (gen_bswapsi2 (op3_32, word2));
2729       emit_insn (gen_bswapsi2 (dest_32, word1));
2730     }
2731   else
2732     {
2733       emit_insn (gen_bswapsi2 (op3_32, word1));
2734       emit_insn (gen_bswapsi2 (dest_32, word2));
2735     }
2737   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2738   emit_insn (gen_iordi3 (dest, dest, op3));
2739   DONE;
2742 (define_split
2743   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2744         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2745    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2746    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2747   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2748   [(const_int 0)]
2750   rtx dest   = operands[0];
2751   rtx src    = operands[1];
2752   rtx op2    = operands[2];
2753   rtx op3    = operands[3];
2754   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2755                                     BYTES_BIG_ENDIAN ? 4 : 0);
2756   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2757                                     BYTES_BIG_ENDIAN ? 4 : 0);
2758   rtx addr1;
2759   rtx addr2;
2760   rtx word1;
2761   rtx word2;
2763   addr1 = XEXP (dest, 0);
2764   if (GET_CODE (addr1) == PLUS)
2765     {
2766       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2767       if (TARGET_AVOID_XFORM)
2768         {
2769           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2770           addr2 = op2;
2771         }
2772       else
2773         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2774     }
2775   else if (TARGET_AVOID_XFORM)
2776     {
2777       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2778       addr2 = op2;
2779     }
2780   else
2781     {
2782       emit_move_insn (op2, GEN_INT (4));
2783       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2784     }
2786   word1 = change_address (dest, SImode, addr1);
2787   word2 = change_address (dest, SImode, addr2);
2789   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2791   if (BYTES_BIG_ENDIAN)
2792     {
2793       emit_insn (gen_bswapsi2 (word1, src_si));
2794       emit_insn (gen_bswapsi2 (word2, op3_si));
2795     }
2796   else
2797     {
2798       emit_insn (gen_bswapsi2 (word2, src_si));
2799       emit_insn (gen_bswapsi2 (word1, op3_si));
2800     }
2801   DONE;
2804 (define_split
2805   [(set (match_operand:DI 0 "gpc_reg_operand")
2806         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2807    (clobber (match_operand:DI 2 "gpc_reg_operand"))
2808    (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2809   "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2810   [(const_int 0)]
2812   rtx dest    = operands[0];
2813   rtx src     = operands[1];
2814   rtx op2     = operands[2];
2815   rtx op3     = operands[3];
2816   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2817   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2818   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2819   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2820   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2822   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2823   emit_insn (gen_bswapsi2 (dest_si, src_si));
2824   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2825   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2826   emit_insn (gen_iordi3 (dest, dest, op3));
2827   DONE;
2830 (define_insn "bswapdi2_32bit"
2831   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2832         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2833    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2834   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2835   "#"
2836   [(set_attr "length" "16,12,36")])
2838 (define_split
2839   [(set (match_operand:DI 0 "gpc_reg_operand")
2840         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2841    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2842   "!TARGET_POWERPC64 && reload_completed"
2843   [(const_int 0)]
2845   rtx dest  = operands[0];
2846   rtx src   = operands[1];
2847   rtx op2   = operands[2];
2848   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2849   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2850   rtx addr1;
2851   rtx addr2;
2852   rtx word1;
2853   rtx word2;
2855   addr1 = XEXP (src, 0);
2856   if (GET_CODE (addr1) == PLUS)
2857     {
2858       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2859       if (TARGET_AVOID_XFORM
2860           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2861         {
2862           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2863           addr2 = op2;
2864         }
2865       else
2866         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2867     }
2868   else if (TARGET_AVOID_XFORM
2869            || REGNO (addr1) == REGNO (dest2))
2870     {
2871       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2872       addr2 = op2;
2873     }
2874   else
2875     {
2876       emit_move_insn (op2, GEN_INT (4));
2877       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2878     }
2880   word1 = change_address (src, SImode, addr1);
2881   word2 = change_address (src, SImode, addr2);
2883   emit_insn (gen_bswapsi2 (dest2, word1));
2884   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2885      thus allowing us to omit an early clobber on the output.  */
2886   emit_insn (gen_bswapsi2 (dest1, word2));
2887   DONE;
2890 (define_split
2891   [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2892         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2893    (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2894   "!TARGET_POWERPC64 && reload_completed"
2895   [(const_int 0)]
2897   rtx dest = operands[0];
2898   rtx src  = operands[1];
2899   rtx op2  = operands[2];
2900   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2901   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2902   rtx addr1;
2903   rtx addr2;
2904   rtx word1;
2905   rtx word2;
2907   addr1 = XEXP (dest, 0);
2908   if (GET_CODE (addr1) == PLUS)
2909     {
2910       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2911       if (TARGET_AVOID_XFORM)
2912         {
2913           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2914           addr2 = op2;
2915         }
2916       else
2917         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2918     }
2919   else if (TARGET_AVOID_XFORM)
2920     {
2921       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2922       addr2 = op2;
2923     }
2924   else
2925     {
2926       emit_move_insn (op2, GEN_INT (4));
2927       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2928     }
2930   word1 = change_address (dest, SImode, addr1);
2931   word2 = change_address (dest, SImode, addr2);
2933   emit_insn (gen_bswapsi2 (word2, src1));
2934   emit_insn (gen_bswapsi2 (word1, src2));
2935   DONE;
2938 (define_split
2939   [(set (match_operand:DI 0 "gpc_reg_operand")
2940         (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2941    (clobber (match_operand:SI 2 ""))]
2942   "!TARGET_POWERPC64 && reload_completed"
2943   [(const_int 0)]
2945   rtx dest  = operands[0];
2946   rtx src   = operands[1];
2947   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2948   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2949   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2950   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2952   emit_insn (gen_bswapsi2 (dest1, src2));
2953   emit_insn (gen_bswapsi2 (dest2, src1));
2954   DONE;
2958 (define_insn "mul<mode>3"
2959   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2960         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2961                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2962   ""
2963   "@
2964    mull<wd> %0,%1,%2
2965    mulli %0,%1,%2"
2966    [(set_attr "type" "mul")
2967     (set (attr "size")
2968       (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2969                 (const_string "8")
2970              (match_operand:GPR 2 "short_cint_operand")
2971                 (const_string "16")]
2972         (const_string "<bits>")))])
2974 (define_insn_and_split "*mul<mode>3_dot"
2975   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2976         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2977                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2978                     (const_int 0)))
2979    (clobber (match_scratch:GPR 0 "=r,r"))]
2980   "<MODE>mode == Pmode"
2981   "@
2982    mull<wd>. %0,%1,%2
2983    #"
2984   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2985   [(set (match_dup 0)
2986         (mult:GPR (match_dup 1)
2987                   (match_dup 2)))
2988    (set (match_dup 3)
2989         (compare:CC (match_dup 0)
2990                     (const_int 0)))]
2991   ""
2992   [(set_attr "type" "mul")
2993    (set_attr "size" "<bits>")
2994    (set_attr "dot" "yes")
2995    (set_attr "length" "4,8")])
2997 (define_insn_and_split "*mul<mode>3_dot2"
2998   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2999         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3000                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3001                     (const_int 0)))
3002    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3003         (mult:GPR (match_dup 1)
3004                   (match_dup 2)))]
3005   "<MODE>mode == Pmode"
3006   "@
3007    mull<wd>. %0,%1,%2
3008    #"
3009   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3010   [(set (match_dup 0)
3011         (mult:GPR (match_dup 1)
3012                   (match_dup 2)))
3013    (set (match_dup 3)
3014         (compare:CC (match_dup 0)
3015                     (const_int 0)))]
3016   ""
3017   [(set_attr "type" "mul")
3018    (set_attr "size" "<bits>")
3019    (set_attr "dot" "yes")
3020    (set_attr "length" "4,8")])
3023 (define_expand "<su>mul<mode>3_highpart"
3024   [(set (match_operand:GPR 0 "gpc_reg_operand")
3025         (subreg:GPR
3026           (mult:<DMODE> (any_extend:<DMODE>
3027                           (match_operand:GPR 1 "gpc_reg_operand"))
3028                         (any_extend:<DMODE>
3029                           (match_operand:GPR 2 "gpc_reg_operand")))
3030          0))]
3031   ""
3033   if (<MODE>mode == SImode && TARGET_POWERPC64)
3034     {
3035       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3036                                              operands[2]));
3037       DONE;
3038     }
3040   if (!WORDS_BIG_ENDIAN)
3041     {
3042       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3043                                                  operands[2]));
3044       DONE;
3045     }
3048 (define_insn "*<su>mul<mode>3_highpart"
3049   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3050         (subreg:GPR
3051           (mult:<DMODE> (any_extend:<DMODE>
3052                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
3053                         (any_extend:<DMODE>
3054                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
3055          0))]
3056   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3057   "mulh<wd><u> %0,%1,%2"
3058   [(set_attr "type" "mul")
3059    (set_attr "size" "<bits>")])
3061 (define_insn "<su>mulsi3_highpart_le"
3062   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3063         (subreg:SI
3064           (mult:DI (any_extend:DI
3065                      (match_operand:SI 1 "gpc_reg_operand" "r"))
3066                    (any_extend:DI
3067                      (match_operand:SI 2 "gpc_reg_operand" "r")))
3068          4))]
3069   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3070   "mulhw<u> %0,%1,%2"
3071   [(set_attr "type" "mul")])
3073 (define_insn "<su>muldi3_highpart_le"
3074   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3075         (subreg:DI
3076           (mult:TI (any_extend:TI
3077                      (match_operand:DI 1 "gpc_reg_operand" "r"))
3078                    (any_extend:TI
3079                      (match_operand:DI 2 "gpc_reg_operand" "r")))
3080          8))]
3081   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3082   "mulhd<u> %0,%1,%2"
3083   [(set_attr "type" "mul")
3084    (set_attr "size" "64")])
3086 (define_insn "<su>mulsi3_highpart_64"
3087   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3088         (truncate:SI
3089           (lshiftrt:DI
3090             (mult:DI (any_extend:DI
3091                        (match_operand:SI 1 "gpc_reg_operand" "r"))
3092                      (any_extend:DI
3093                        (match_operand:SI 2 "gpc_reg_operand" "r")))
3094             (const_int 32))))]
3095   "TARGET_POWERPC64"
3096   "mulhw<u> %0,%1,%2"
3097   [(set_attr "type" "mul")])
3099 (define_expand "<u>mul<mode><dmode>3"
3100   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3101         (mult:<DMODE> (any_extend:<DMODE>
3102                         (match_operand:GPR 1 "gpc_reg_operand"))
3103                       (any_extend:<DMODE>
3104                         (match_operand:GPR 2 "gpc_reg_operand"))))]
3105   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3107   rtx l = gen_reg_rtx (<MODE>mode);
3108   rtx h = gen_reg_rtx (<MODE>mode);
3109   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3110   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3111   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3112   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3113   DONE;
3116 (define_insn "*maddld<mode>4"
3117   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3118         (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3119                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
3120                   (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3121   "TARGET_MADDLD"
3122   "maddld %0,%1,%2,%3"
3123   [(set_attr "type" "mul")])
3125 (define_insn "udiv<mode>3"
3126   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3127         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3128                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3129   ""
3130   "div<wd>u %0,%1,%2"
3131   [(set_attr "type" "div")
3132    (set_attr "size" "<bits>")])
3135 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3136 ;; modulus.  If it isn't a power of two, force operands into register and do
3137 ;; a normal divide.
3138 (define_expand "div<mode>3"
3139   [(set (match_operand:GPR 0 "gpc_reg_operand")
3140         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3141                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3142   ""
3144   if (CONST_INT_P (operands[2])
3145       && INTVAL (operands[2]) > 0
3146       && exact_log2 (INTVAL (operands[2])) >= 0)
3147     {
3148       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3149       DONE;
3150     }
3152   operands[2] = force_reg (<MODE>mode, operands[2]);
3155 (define_insn "*div<mode>3"
3156   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3157         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3158                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3159   ""
3160   "div<wd> %0,%1,%2"
3161   [(set_attr "type" "div")
3162    (set_attr "size" "<bits>")])
3164 (define_insn "div<mode>3_sra"
3165   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3166         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3167                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3168    (clobber (reg:GPR CA_REGNO))]
3169   ""
3170   "sra<wd>i %0,%1,%p2\;addze %0,%0"
3171   [(set_attr "type" "two")
3172    (set_attr "length" "8")])
3174 (define_insn_and_split "*div<mode>3_sra_dot"
3175   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3176         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3177                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3178                     (const_int 0)))
3179    (clobber (match_scratch:GPR 0 "=r,r"))
3180    (clobber (reg:GPR CA_REGNO))]
3181   "<MODE>mode == Pmode"
3182   "@
3183    sra<wd>i %0,%1,%p2\;addze. %0,%0
3184    #"
3185   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3186   [(parallel [(set (match_dup 0)
3187                    (div:GPR (match_dup 1)
3188                             (match_dup 2)))
3189               (clobber (reg:GPR CA_REGNO))])
3190    (set (match_dup 3)
3191         (compare:CC (match_dup 0)
3192                     (const_int 0)))]
3193   ""
3194   [(set_attr "type" "two")
3195    (set_attr "length" "8,12")
3196    (set_attr "cell_micro" "not")])
3198 (define_insn_and_split "*div<mode>3_sra_dot2"
3199   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3200         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3201                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3202                     (const_int 0)))
3203    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3204         (div:GPR (match_dup 1)
3205                  (match_dup 2)))
3206    (clobber (reg:GPR CA_REGNO))]
3207   "<MODE>mode == Pmode"
3208   "@
3209    sra<wd>i %0,%1,%p2\;addze. %0,%0
3210    #"
3211   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3212   [(parallel [(set (match_dup 0)
3213                    (div:GPR (match_dup 1)
3214                             (match_dup 2)))
3215               (clobber (reg:GPR CA_REGNO))])
3216    (set (match_dup 3)
3217         (compare:CC (match_dup 0)
3218                     (const_int 0)))]
3219   ""
3220   [(set_attr "type" "two")
3221    (set_attr "length" "8,12")
3222    (set_attr "cell_micro" "not")])
3224 (define_expand "mod<mode>3"
3225   [(set (match_operand:GPR 0 "gpc_reg_operand")
3226         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3227                  (match_operand:GPR 2 "reg_or_cint_operand")))]
3228   ""
3230   int i;
3231   rtx temp1;
3232   rtx temp2;
3234   if (!CONST_INT_P (operands[2])
3235       || INTVAL (operands[2]) <= 0
3236       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3237     {
3238       if (!TARGET_MODULO)
3239         FAIL;
3241       operands[2] = force_reg (<MODE>mode, operands[2]);
3242     }
3243   else
3244     {
3245       temp1 = gen_reg_rtx (<MODE>mode);
3246       temp2 = gen_reg_rtx (<MODE>mode);
3248       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3249       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3250       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3251       DONE;
3252     }
3255 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3256 ;; mod, prefer putting the result of mod into a different register
3257 (define_insn "*mod<mode>3"
3258   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3259         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3260                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3261   "TARGET_MODULO"
3262   "mods<wd> %0,%1,%2"
3263   [(set_attr "type" "div")
3264    (set_attr "size" "<bits>")])
3267 (define_insn "umod<mode>3"
3268   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3269         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3270                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3271   "TARGET_MODULO"
3272   "modu<wd> %0,%1,%2"
3273   [(set_attr "type" "div")
3274    (set_attr "size" "<bits>")])
3276 ;; On machines with modulo support, do a combined div/mod the old fashioned
3277 ;; method, since the multiply/subtract is faster than doing the mod instruction
3278 ;; after a divide.
3280 (define_peephole2
3281   [(set (match_operand:GPR 0 "gpc_reg_operand")
3282         (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3283                  (match_operand:GPR 2 "gpc_reg_operand")))
3284    (set (match_operand:GPR 3 "gpc_reg_operand")
3285         (mod:GPR (match_dup 1)
3286                  (match_dup 2)))]
3287   "TARGET_MODULO
3288    && ! reg_mentioned_p (operands[0], operands[1])
3289    && ! reg_mentioned_p (operands[0], operands[2])
3290    && ! reg_mentioned_p (operands[3], operands[1])
3291    && ! reg_mentioned_p (operands[3], operands[2])"
3292   [(set (match_dup 0)
3293         (div:GPR (match_dup 1)
3294                  (match_dup 2)))
3295    (set (match_dup 3)
3296         (mult:GPR (match_dup 0)
3297                   (match_dup 2)))
3298    (set (match_dup 3)
3299         (minus:GPR (match_dup 1)
3300                    (match_dup 3)))])
3302 (define_peephole2
3303   [(set (match_operand:GPR 0 "gpc_reg_operand")
3304         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3305                   (match_operand:GPR 2 "gpc_reg_operand")))
3306    (set (match_operand:GPR 3 "gpc_reg_operand")
3307         (umod:GPR (match_dup 1)
3308                   (match_dup 2)))]
3309   "TARGET_MODULO
3310    && ! reg_mentioned_p (operands[0], operands[1])
3311    && ! reg_mentioned_p (operands[0], operands[2])
3312    && ! reg_mentioned_p (operands[3], operands[1])
3313    && ! reg_mentioned_p (operands[3], operands[2])"
3314   [(set (match_dup 0)
3315         (udiv:GPR (match_dup 1)
3316                   (match_dup 2)))
3317    (set (match_dup 3)
3318         (mult:GPR (match_dup 0)
3319                   (match_dup 2)))
3320    (set (match_dup 3)
3321         (minus:GPR (match_dup 1)
3322                    (match_dup 3)))])
3325 ;; Logical instructions
3326 ;; The logical instructions are mostly combined by using match_operator,
3327 ;; but the plain AND insns are somewhat different because there is no
3328 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3329 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3331 (define_expand "and<mode>3"
3332   [(set (match_operand:SDI 0 "gpc_reg_operand")
3333         (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3334                  (match_operand:SDI 2 "reg_or_cint_operand")))]
3335   ""
3337   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3338     {
3339       rs6000_split_logical (operands, AND, false, false, false);
3340       DONE;
3341     }
3343   if (CONST_INT_P (operands[2]))
3344     {
3345       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3346         {
3347           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3348           DONE;
3349         }
3351       if (logical_const_operand (operands[2], <MODE>mode))
3352         {
3353           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3354           DONE;
3355         }
3357       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3358         {
3359           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3360           DONE;
3361         }
3363       operands[2] = force_reg (<MODE>mode, operands[2]);
3364     }
3368 (define_insn "and<mode>3_imm"
3369   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3370         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3371                  (match_operand:GPR 2 "logical_const_operand" "n")))
3372    (clobber (match_scratch:CC 3 "=x"))]
3373   "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3374   "andi%e2. %0,%1,%u2"
3375   [(set_attr "type" "logical")
3376    (set_attr "dot" "yes")])
3378 (define_insn_and_split "*and<mode>3_imm_dot"
3379   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3380         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3381                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3382                     (const_int 0)))
3383    (clobber (match_scratch:GPR 0 "=r,r"))
3384    (clobber (match_scratch:CC 4 "=X,x"))]
3385   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3386    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3387   "@
3388    andi%e2. %0,%1,%u2
3389    #"
3390   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3391   [(parallel [(set (match_dup 0)
3392                    (and:GPR (match_dup 1)
3393                             (match_dup 2)))
3394               (clobber (match_dup 4))])
3395    (set (match_dup 3)
3396         (compare:CC (match_dup 0)
3397                     (const_int 0)))]
3398   ""
3399   [(set_attr "type" "logical")
3400    (set_attr "dot" "yes")
3401    (set_attr "length" "4,8")])
3403 (define_insn_and_split "*and<mode>3_imm_dot2"
3404   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3405         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3406                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3407                     (const_int 0)))
3408    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3409         (and:GPR (match_dup 1)
3410                  (match_dup 2)))
3411    (clobber (match_scratch:CC 4 "=X,x"))]
3412   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3413    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3414   "@
3415    andi%e2. %0,%1,%u2
3416    #"
3417   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3418   [(parallel [(set (match_dup 0)
3419                    (and:GPR (match_dup 1)
3420                             (match_dup 2)))
3421               (clobber (match_dup 4))])
3422    (set (match_dup 3)
3423         (compare:CC (match_dup 0)
3424                     (const_int 0)))]
3425   ""
3426   [(set_attr "type" "logical")
3427    (set_attr "dot" "yes")
3428    (set_attr "length" "4,8")])
3430 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3431   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3432         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3433                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3434                     (const_int 0)))
3435    (clobber (match_scratch:GPR 0 "=r,r"))]
3436   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3437    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3438   "@
3439    andi%e2. %0,%1,%u2
3440    #"
3441   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3442   [(set (match_dup 0)
3443         (and:GPR (match_dup 1)
3444                  (match_dup 2)))
3445    (set (match_dup 3)
3446         (compare:CC (match_dup 0)
3447                     (const_int 0)))]
3448   ""
3449   [(set_attr "type" "logical")
3450    (set_attr "dot" "yes")
3451    (set_attr "length" "4,8")])
3453 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3454   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3455         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3456                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3457                     (const_int 0)))
3458    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3459         (and:GPR (match_dup 1)
3460                  (match_dup 2)))]
3461   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3462    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3463   "@
3464    andi%e2. %0,%1,%u2
3465    #"
3466   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3467   [(set (match_dup 0)
3468         (and:GPR (match_dup 1)
3469                  (match_dup 2)))
3470    (set (match_dup 3)
3471         (compare:CC (match_dup 0)
3472                     (const_int 0)))]
3473   ""
3474   [(set_attr "type" "logical")
3475    (set_attr "dot" "yes")
3476    (set_attr "length" "4,8")])
3478 (define_insn "*and<mode>3_imm_dot_shifted"
3479   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3480         (compare:CC
3481           (and:GPR
3482             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3483                           (match_operand:SI 4 "const_int_operand" "n"))
3484             (match_operand:GPR 2 "const_int_operand" "n"))
3485           (const_int 0)))
3486    (clobber (match_scratch:GPR 0 "=r"))]
3487   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3488                                    << INTVAL (operands[4])),
3489                           DImode)
3490    && (<MODE>mode == Pmode
3491        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3493   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3494   return "andi%e2. %0,%1,%u2";
3496   [(set_attr "type" "logical")
3497    (set_attr "dot" "yes")])
3500 (define_insn "and<mode>3_mask"
3501   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3502         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3503                  (match_operand:GPR 2 "const_int_operand" "n")))]
3504   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3506   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3508   [(set_attr "type" "shift")])
3510 (define_insn_and_split "*and<mode>3_mask_dot"
3511   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3512         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3513                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3514                     (const_int 0)))
3515    (clobber (match_scratch:GPR 0 "=r,r"))]
3516   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3517    && !logical_const_operand (operands[2], <MODE>mode)
3518    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3520   if (which_alternative == 0)
3521     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3522   else
3523     return "#";
3525   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3526   [(set (match_dup 0)
3527         (and:GPR (match_dup 1)
3528                  (match_dup 2)))
3529    (set (match_dup 3)
3530         (compare:CC (match_dup 0)
3531                     (const_int 0)))]
3532   ""
3533   [(set_attr "type" "shift")
3534    (set_attr "dot" "yes")
3535    (set_attr "length" "4,8")])
3537 (define_insn_and_split "*and<mode>3_mask_dot2"
3538   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3539         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3540                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3541                     (const_int 0)))
3542    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3543         (and:GPR (match_dup 1)
3544                  (match_dup 2)))]
3545   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3546    && !logical_const_operand (operands[2], <MODE>mode)
3547    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3549   if (which_alternative == 0)
3550     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3551   else
3552     return "#";
3554   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3555   [(set (match_dup 0)
3556         (and:GPR (match_dup 1)
3557                  (match_dup 2)))
3558    (set (match_dup 3)
3559         (compare:CC (match_dup 0)
3560                     (const_int 0)))]
3561   ""
3562   [(set_attr "type" "shift")
3563    (set_attr "dot" "yes")
3564    (set_attr "length" "4,8")])
3567 (define_insn_and_split "*and<mode>3_2insn"
3568   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3569         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3570                  (match_operand:GPR 2 "const_int_operand" "n")))]
3571   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3572    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3573         || logical_const_operand (operands[2], <MODE>mode))"
3574   "#"
3575   "&& 1"
3576   [(pc)]
3578   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3579   DONE;
3581   [(set_attr "type" "shift")
3582    (set_attr "length" "8")])
3584 (define_insn_and_split "*and<mode>3_2insn_dot"
3585   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3586         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3587                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3588                     (const_int 0)))
3589    (clobber (match_scratch:GPR 0 "=r,r"))]
3590   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3591    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3592    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3593         || logical_const_operand (operands[2], <MODE>mode))"
3594   "#"
3595   "&& reload_completed"
3596   [(pc)]
3598   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3599   DONE;
3601   [(set_attr "type" "shift")
3602    (set_attr "dot" "yes")
3603    (set_attr "length" "8,12")])
3605 (define_insn_and_split "*and<mode>3_2insn_dot2"
3606   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3607         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3608                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3609                     (const_int 0)))
3610    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3611         (and:GPR (match_dup 1)
3612                  (match_dup 2)))]
3613   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3614    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3615    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3616         || logical_const_operand (operands[2], <MODE>mode))"
3617   "#"
3618   "&& reload_completed"
3619   [(pc)]
3621   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3622   DONE;
3624   [(set_attr "type" "shift")
3625    (set_attr "dot" "yes")
3626    (set_attr "length" "8,12")])
3629 (define_expand "<code><mode>3"
3630   [(set (match_operand:SDI 0 "gpc_reg_operand")
3631         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3632                     (match_operand:SDI 2 "reg_or_cint_operand")))]
3633   ""
3635   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3636     {
3637       rs6000_split_logical (operands, <CODE>, false, false, false);
3638       DONE;
3639     }
3641   if (non_logical_cint_operand (operands[2], <MODE>mode))
3642     {
3643       rtx tmp = ((!can_create_pseudo_p ()
3644                   || rtx_equal_p (operands[0], operands[1]))
3645                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3647       HOST_WIDE_INT value = INTVAL (operands[2]);
3648       HOST_WIDE_INT lo = value & 0xffff;
3649       HOST_WIDE_INT hi = value - lo;
3651       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3652       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3653       DONE;
3654     }
3656   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3657     operands[2] = force_reg (<MODE>mode, operands[2]);
3660 (define_split
3661   [(set (match_operand:GPR 0 "gpc_reg_operand")
3662         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3663                     (match_operand:GPR 2 "non_logical_cint_operand")))]
3664   ""
3665   [(set (match_dup 3)
3666         (iorxor:GPR (match_dup 1)
3667                     (match_dup 4)))
3668    (set (match_dup 0)
3669         (iorxor:GPR (match_dup 3)
3670                     (match_dup 5)))]
3672   operands[3] = ((!can_create_pseudo_p ()
3673                   || rtx_equal_p (operands[0], operands[1]))
3674                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3676   HOST_WIDE_INT value = INTVAL (operands[2]);
3677   HOST_WIDE_INT lo = value & 0xffff;
3678   HOST_WIDE_INT hi = value - lo;
3680   operands[4] = GEN_INT (hi);
3681   operands[5] = GEN_INT (lo);
3684 (define_insn "*bool<mode>3_imm"
3685   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3686         (match_operator:GPR 3 "boolean_or_operator"
3687          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3688           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3689   ""
3690   "%q3i%e2 %0,%1,%u2"
3691   [(set_attr "type" "logical")])
3693 (define_insn "*bool<mode>3"
3694   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3695         (match_operator:GPR 3 "boolean_operator"
3696          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3697           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3698   ""
3699   "%q3 %0,%1,%2"
3700   [(set_attr "type" "logical")])
3702 (define_insn_and_split "*bool<mode>3_dot"
3703   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3704         (compare:CC (match_operator:GPR 3 "boolean_operator"
3705          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3706           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3707          (const_int 0)))
3708    (clobber (match_scratch:GPR 0 "=r,r"))]
3709   "<MODE>mode == Pmode"
3710   "@
3711    %q3. %0,%1,%2
3712    #"
3713   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3714   [(set (match_dup 0)
3715         (match_dup 3))
3716    (set (match_dup 4)
3717         (compare:CC (match_dup 0)
3718                     (const_int 0)))]
3719   ""
3720   [(set_attr "type" "logical")
3721    (set_attr "dot" "yes")
3722    (set_attr "length" "4,8")])
3724 (define_insn_and_split "*bool<mode>3_dot2"
3725   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3726         (compare:CC (match_operator:GPR 3 "boolean_operator"
3727          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3728           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3729          (const_int 0)))
3730    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3731         (match_dup 3))]
3732   "<MODE>mode == Pmode"
3733   "@
3734    %q3. %0,%1,%2
3735    #"
3736   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3737   [(set (match_dup 0)
3738         (match_dup 3))
3739    (set (match_dup 4)
3740         (compare:CC (match_dup 0)
3741                     (const_int 0)))]
3742   ""
3743   [(set_attr "type" "logical")
3744    (set_attr "dot" "yes")
3745    (set_attr "length" "4,8")])
3748 (define_insn "*boolc<mode>3"
3749   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3750         (match_operator:GPR 3 "boolean_operator"
3751          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3752           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3753   ""
3754   "%q3 %0,%1,%2"
3755   [(set_attr "type" "logical")])
3757 (define_insn_and_split "*boolc<mode>3_dot"
3758   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3759         (compare:CC (match_operator:GPR 3 "boolean_operator"
3760          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3761           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3762          (const_int 0)))
3763    (clobber (match_scratch:GPR 0 "=r,r"))]
3764   "<MODE>mode == Pmode"
3765   "@
3766    %q3. %0,%1,%2
3767    #"
3768   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3769   [(set (match_dup 0)
3770         (match_dup 3))
3771    (set (match_dup 4)
3772         (compare:CC (match_dup 0)
3773                     (const_int 0)))]
3774   ""
3775   [(set_attr "type" "logical")
3776    (set_attr "dot" "yes")
3777    (set_attr "length" "4,8")])
3779 (define_insn_and_split "*boolc<mode>3_dot2"
3780   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3781         (compare:CC (match_operator:GPR 3 "boolean_operator"
3782          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3783           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3784          (const_int 0)))
3785    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3786         (match_dup 3))]
3787   "<MODE>mode == Pmode"
3788   "@
3789    %q3. %0,%1,%2
3790    #"
3791   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3792   [(set (match_dup 0)
3793         (match_dup 3))
3794    (set (match_dup 4)
3795         (compare:CC (match_dup 0)
3796                     (const_int 0)))]
3797   ""
3798   [(set_attr "type" "logical")
3799    (set_attr "dot" "yes")
3800    (set_attr "length" "4,8")])
3803 (define_insn "*boolcc<mode>3"
3804   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3805         (match_operator:GPR 3 "boolean_operator"
3806          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3807           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3808   ""
3809   "%q3 %0,%1,%2"
3810   [(set_attr "type" "logical")])
3812 (define_insn_and_split "*boolcc<mode>3_dot"
3813   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3814         (compare:CC (match_operator:GPR 3 "boolean_operator"
3815          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3816           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3817          (const_int 0)))
3818    (clobber (match_scratch:GPR 0 "=r,r"))]
3819   "<MODE>mode == Pmode"
3820   "@
3821    %q3. %0,%1,%2
3822    #"
3823   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3824   [(set (match_dup 0)
3825         (match_dup 3))
3826    (set (match_dup 4)
3827         (compare:CC (match_dup 0)
3828                     (const_int 0)))]
3829   ""
3830   [(set_attr "type" "logical")
3831    (set_attr "dot" "yes")
3832    (set_attr "length" "4,8")])
3834 (define_insn_and_split "*boolcc<mode>3_dot2"
3835   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3836         (compare:CC (match_operator:GPR 3 "boolean_operator"
3837          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3838           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3839          (const_int 0)))
3840    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3841         (match_dup 3))]
3842   "<MODE>mode == Pmode"
3843   "@
3844    %q3. %0,%1,%2
3845    #"
3846   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3847   [(set (match_dup 0)
3848         (match_dup 3))
3849    (set (match_dup 4)
3850         (compare:CC (match_dup 0)
3851                     (const_int 0)))]
3852   ""
3853   [(set_attr "type" "logical")
3854    (set_attr "dot" "yes")
3855    (set_attr "length" "4,8")])
3858 ;; TODO: Should have dots of this as well.
3859 (define_insn "*eqv<mode>3"
3860   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3861         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3862                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3863   ""
3864   "eqv %0,%1,%2"
3865   [(set_attr "type" "logical")])
3867 ;; Rotate-and-mask and insert.
3869 (define_insn "*rotl<mode>3_mask"
3870   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3871         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3872                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3873                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3874                  (match_operand:GPR 3 "const_int_operand" "n")))]
3875   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3877   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3879   [(set_attr "type" "shift")
3880    (set_attr "maybe_var_shift" "yes")])
3882 (define_insn_and_split "*rotl<mode>3_mask_dot"
3883   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3884         (compare:CC
3885           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3886                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3887                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3888                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3889           (const_int 0)))
3890    (clobber (match_scratch:GPR 0 "=r,r"))]
3891   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3892    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3894   if (which_alternative == 0)
3895     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3896   else
3897     return "#";
3899   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3900   [(set (match_dup 0)
3901         (and:GPR (match_dup 4)
3902                  (match_dup 3)))
3903    (set (match_dup 5)
3904         (compare:CC (match_dup 0)
3905                     (const_int 0)))]
3906   ""
3907   [(set_attr "type" "shift")
3908    (set_attr "maybe_var_shift" "yes")
3909    (set_attr "dot" "yes")
3910    (set_attr "length" "4,8")])
3912 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3913   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3914         (compare:CC
3915           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3916                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3917                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3918                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3919           (const_int 0)))
3920    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3921         (and:GPR (match_dup 4)
3922                  (match_dup 3)))]
3923   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3924    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3926   if (which_alternative == 0)
3927     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3928   else
3929     return "#";
3931   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3932   [(set (match_dup 0)
3933         (and:GPR (match_dup 4)
3934                  (match_dup 3)))
3935    (set (match_dup 5)
3936         (compare:CC (match_dup 0)
3937                     (const_int 0)))]
3938   ""
3939   [(set_attr "type" "shift")
3940    (set_attr "maybe_var_shift" "yes")
3941    (set_attr "dot" "yes")
3942    (set_attr "length" "4,8")])
3944 ; Special case for less-than-0.  We can do it with just one machine
3945 ; instruction, but the generic optimizers do not realise it is cheap.
3946 (define_insn "*lt0_<mode>di"
3947   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3948         (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3949                 (const_int 0)))]
3950   "TARGET_POWERPC64"
3951   "srdi %0,%1,63"
3952   [(set_attr "type" "shift")])
3954 (define_insn "*lt0_<mode>si"
3955   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3956         (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3957                 (const_int 0)))]
3958   ""
3959   "rlwinm %0,%1,1,31,31"
3960   [(set_attr "type" "shift")])
3964 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3965 ; both are an AND so are the same precedence).
3966 (define_insn "*rotl<mode>3_insert"
3967   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3968         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3969                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3970                             (match_operand:SI 2 "const_int_operand" "n")])
3971                           (match_operand:GPR 3 "const_int_operand" "n"))
3972                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3973                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3974   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3975    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3977   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3979   [(set_attr "type" "insert")])
3980 ; FIXME: this needs an attr "size", so that the scheduler can see the
3981 ; difference between rlwimi and rldimi.  We also might want dot forms,
3982 ; but not for rlwimi on POWER4 and similar processors.
3984 (define_insn "*rotl<mode>3_insert_2"
3985   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3986         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3987                           (match_operand:GPR 6 "const_int_operand" "n"))
3988                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3989                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3990                             (match_operand:SI 2 "const_int_operand" "n")])
3991                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3992   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3993    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3995   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3997   [(set_attr "type" "insert")])
3999 ; There are also some forms without one of the ANDs.
4000 (define_insn "*rotl<mode>3_insert_3"
4001   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4002         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4003                           (match_operand:GPR 4 "const_int_operand" "n"))
4004                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4005                              (match_operand:SI 2 "const_int_operand" "n"))))]
4006   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4008   if (<MODE>mode == SImode)
4009     return "rlwimi %0,%1,%h2,0,31-%h2";
4010   else
4011     return "rldimi %0,%1,%H2,0";
4013   [(set_attr "type" "insert")])
4015 (define_insn "*rotl<mode>3_insert_4"
4016   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4017         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4018                           (match_operand:GPR 4 "const_int_operand" "n"))
4019                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4020                                (match_operand:SI 2 "const_int_operand" "n"))))]
4021   "<MODE>mode == SImode &&
4022    GET_MODE_PRECISION (<MODE>mode)
4023    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4025   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4026                          - INTVAL (operands[2]));
4027   if (<MODE>mode == SImode)
4028     return "rlwimi %0,%1,%h2,32-%h2,31";
4029   else
4030     return "rldimi %0,%1,%H2,64-%H2";
4032   [(set_attr "type" "insert")])
4034 (define_insn "*rotlsi3_insert_5"
4035   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4036         (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4037                         (match_operand:SI 2 "const_int_operand" "n,n"))
4038                 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4039                         (match_operand:SI 4 "const_int_operand" "n,n"))))]
4040   "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4041    && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4042    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4043   "@
4044    rlwimi %0,%3,0,%4
4045    rlwimi %0,%1,0,%2"
4046   [(set_attr "type" "insert")])
4048 (define_insn "*rotldi3_insert_6"
4049   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4050         (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4051                         (match_operand:DI 2 "const_int_operand" "n"))
4052                 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4053                         (match_operand:DI 4 "const_int_operand" "n"))))]
4054   "exact_log2 (-UINTVAL (operands[2])) > 0
4055    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4057   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4058   return "rldimi %0,%3,0,%5";
4060   [(set_attr "type" "insert")
4061    (set_attr "size" "64")])
4063 (define_insn "*rotldi3_insert_7"
4064   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4065         (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4066                         (match_operand:DI 4 "const_int_operand" "n"))
4067                 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4068                         (match_operand:DI 2 "const_int_operand" "n"))))]
4069   "exact_log2 (-UINTVAL (operands[2])) > 0
4070    && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4072   operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4073   return "rldimi %0,%3,0,%5";
4075   [(set_attr "type" "insert")
4076    (set_attr "size" "64")])
4079 ; This handles the important case of multiple-precision shifts.  There is
4080 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4081 (define_split
4082   [(set (match_operand:GPR 0 "gpc_reg_operand")
4083         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4084                              (match_operand:SI 3 "const_int_operand"))
4085                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4086                                (match_operand:SI 4 "const_int_operand"))))]
4087   "can_create_pseudo_p ()
4088    && INTVAL (operands[3]) + INTVAL (operands[4])
4089       >= GET_MODE_PRECISION (<MODE>mode)"
4090   [(set (match_dup 5)
4091         (lshiftrt:GPR (match_dup 2)
4092                       (match_dup 4)))
4093    (set (match_dup 0)
4094         (ior:GPR (and:GPR (match_dup 5)
4095                           (match_dup 6))
4096                  (ashift:GPR (match_dup 1)
4097                              (match_dup 3))))]
4099   unsigned HOST_WIDE_INT mask = 1;
4100   mask = (mask << INTVAL (operands[3])) - 1;
4101   operands[5] = gen_reg_rtx (<MODE>mode);
4102   operands[6] = GEN_INT (mask);
4105 (define_split
4106   [(set (match_operand:GPR 0 "gpc_reg_operand")
4107         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4108                                (match_operand:SI 4 "const_int_operand"))
4109                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4110                              (match_operand:SI 3 "const_int_operand"))))]
4111   "can_create_pseudo_p ()
4112    && INTVAL (operands[3]) + INTVAL (operands[4])
4113       >= GET_MODE_PRECISION (<MODE>mode)"
4114   [(set (match_dup 5)
4115         (lshiftrt:GPR (match_dup 2)
4116                       (match_dup 4)))
4117    (set (match_dup 0)
4118         (ior:GPR (and:GPR (match_dup 5)
4119                           (match_dup 6))
4120                  (ashift:GPR (match_dup 1)
4121                              (match_dup 3))))]
4123   unsigned HOST_WIDE_INT mask = 1;
4124   mask = (mask << INTVAL (operands[3])) - 1;
4125   operands[5] = gen_reg_rtx (<MODE>mode);
4126   operands[6] = GEN_INT (mask);
4130 ; Another important case is setting some bits to 1; we can do that with
4131 ; an insert instruction, in many cases.
4132 (define_insn_and_split "*ior<mode>_mask"
4133   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4134         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4135                  (match_operand:GPR 2 "const_int_operand" "n")))
4136    (clobber (match_scratch:GPR 3 "=r"))]
4137   "!logical_const_operand (operands[2], <MODE>mode)
4138    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4139   "#"
4140   "&& 1"
4141   [(set (match_dup 3)
4142         (const_int -1))
4143    (set (match_dup 0)
4144         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4145                                       (match_dup 4))
4146                           (match_dup 2))
4147                  (and:GPR (match_dup 1)
4148                           (match_dup 5))))]
4150   int nb, ne;
4151   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4152   if (GET_CODE (operands[3]) == SCRATCH)
4153     operands[3] = gen_reg_rtx (<MODE>mode);
4154   operands[4] = GEN_INT (ne);
4155   operands[5] = GEN_INT (~UINTVAL (operands[2]));
4157   [(set_attr "type" "two")
4158    (set_attr "length" "8")])
4161 ; Yet another case is an rldimi with the second value coming from memory.
4162 ; The zero_extend that should become part of the rldimi is merged into the
4163 ; load from memory instead.  Split things properly again.
4164 (define_split
4165   [(set (match_operand:DI 0 "gpc_reg_operand")
4166         (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4167                            (match_operand:SI 2 "const_int_operand"))
4168                 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4169   "INTVAL (operands[2]) == <bits>"
4170   [(set (match_dup 4)
4171         (zero_extend:DI (match_dup 3)))
4172    (set (match_dup 0)
4173         (ior:DI (and:DI (match_dup 4)
4174                         (match_dup 5))
4175                 (ashift:DI (match_dup 1)
4176                            (match_dup 2))))]
4178   operands[4] = gen_reg_rtx (DImode);
4179   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4182 ; rlwimi, too.
4183 (define_split
4184   [(set (match_operand:SI 0 "gpc_reg_operand")
4185         (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4186                            (match_operand:SI 2 "const_int_operand"))
4187                 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4188   "INTVAL (operands[2]) == <bits>"
4189   [(set (match_dup 4)
4190         (zero_extend:SI (match_dup 3)))
4191    (set (match_dup 0)
4192         (ior:SI (and:SI (match_dup 4)
4193                         (match_dup 5))
4194                 (ashift:SI (match_dup 1)
4195                            (match_dup 2))))]
4197   operands[4] = gen_reg_rtx (SImode);
4198   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4202 ;; Now the simple shifts.
4204 (define_insn "rotl<mode>3"
4205   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4206         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4207                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4208   ""
4209   "rotl<wd>%I2 %0,%1,%<hH>2"
4210   [(set_attr "type" "shift")
4211    (set_attr "maybe_var_shift" "yes")])
4213 (define_insn "*rotlsi3_64"
4214   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4215         (zero_extend:DI
4216             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4217                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4218   "TARGET_POWERPC64"
4219   "rotlw%I2 %0,%1,%h2"
4220   [(set_attr "type" "shift")
4221    (set_attr "maybe_var_shift" "yes")])
4223 (define_insn_and_split "*rotl<mode>3_dot"
4224   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4225         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4226                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4227                     (const_int 0)))
4228    (clobber (match_scratch:GPR 0 "=r,r"))]
4229   "<MODE>mode == Pmode"
4230   "@
4231    rotl<wd>%I2. %0,%1,%<hH>2
4232    #"
4233   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4234   [(set (match_dup 0)
4235         (rotate:GPR (match_dup 1)
4236                     (match_dup 2)))
4237    (set (match_dup 3)
4238         (compare:CC (match_dup 0)
4239                     (const_int 0)))]
4240   ""
4241   [(set_attr "type" "shift")
4242    (set_attr "maybe_var_shift" "yes")
4243    (set_attr "dot" "yes")
4244    (set_attr "length" "4,8")])
4246 (define_insn_and_split "*rotl<mode>3_dot2"
4247   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4248         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4249                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4250                     (const_int 0)))
4251    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4252         (rotate:GPR (match_dup 1)
4253                     (match_dup 2)))]
4254   "<MODE>mode == Pmode"
4255   "@
4256    rotl<wd>%I2. %0,%1,%<hH>2
4257    #"
4258   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4259   [(set (match_dup 0)
4260         (rotate:GPR (match_dup 1)
4261                     (match_dup 2)))
4262    (set (match_dup 3)
4263         (compare:CC (match_dup 0)
4264                     (const_int 0)))]
4265   ""
4266   [(set_attr "type" "shift")
4267    (set_attr "maybe_var_shift" "yes")
4268    (set_attr "dot" "yes")
4269    (set_attr "length" "4,8")])
4272 (define_insn "ashl<mode>3"
4273   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4274         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4275                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4276   ""
4277   "sl<wd>%I2 %0,%1,%<hH>2"
4278   [(set_attr "type" "shift")
4279    (set_attr "maybe_var_shift" "yes")])
4281 (define_insn "*ashlsi3_64"
4282   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4283         (zero_extend:DI
4284             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4285                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4286   "TARGET_POWERPC64"
4287   "slw%I2 %0,%1,%h2"
4288   [(set_attr "type" "shift")
4289    (set_attr "maybe_var_shift" "yes")])
4291 (define_insn_and_split "*ashl<mode>3_dot"
4292   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4293         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4294                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4295                     (const_int 0)))
4296    (clobber (match_scratch:GPR 0 "=r,r"))]
4297   "<MODE>mode == Pmode"
4298   "@
4299    sl<wd>%I2. %0,%1,%<hH>2
4300    #"
4301   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4302   [(set (match_dup 0)
4303         (ashift:GPR (match_dup 1)
4304                     (match_dup 2)))
4305    (set (match_dup 3)
4306         (compare:CC (match_dup 0)
4307                     (const_int 0)))]
4308   ""
4309   [(set_attr "type" "shift")
4310    (set_attr "maybe_var_shift" "yes")
4311    (set_attr "dot" "yes")
4312    (set_attr "length" "4,8")])
4314 (define_insn_and_split "*ashl<mode>3_dot2"
4315   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4316         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4317                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4318                     (const_int 0)))
4319    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4320         (ashift:GPR (match_dup 1)
4321                     (match_dup 2)))]
4322   "<MODE>mode == Pmode"
4323   "@
4324    sl<wd>%I2. %0,%1,%<hH>2
4325    #"
4326   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4327   [(set (match_dup 0)
4328         (ashift:GPR (match_dup 1)
4329                     (match_dup 2)))
4330    (set (match_dup 3)
4331         (compare:CC (match_dup 0)
4332                     (const_int 0)))]
4333   ""
4334   [(set_attr "type" "shift")
4335    (set_attr "maybe_var_shift" "yes")
4336    (set_attr "dot" "yes")
4337    (set_attr "length" "4,8")])
4339 ;; Pretend we have a memory form of extswsli until register allocation is done
4340 ;; so that we use LWZ to load the value from memory, instead of LWA.
4341 (define_insn_and_split "ashdi3_extswsli"
4342   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4343         (ashift:DI
4344          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4345          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4346   "TARGET_EXTSWSLI"
4347   "@
4348    extswsli %0,%1,%2
4349    #"
4350   "&& reload_completed && MEM_P (operands[1])"
4351   [(set (match_dup 3)
4352         (match_dup 1))
4353    (set (match_dup 0)
4354         (ashift:DI (sign_extend:DI (match_dup 3))
4355                    (match_dup 2)))]
4357   operands[3] = gen_lowpart (SImode, operands[0]);
4359   [(set_attr "type" "shift")
4360    (set_attr "maybe_var_shift" "no")])
4363 (define_insn_and_split "ashdi3_extswsli_dot"
4364   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4365         (compare:CC
4366          (ashift:DI
4367           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4368           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4369          (const_int 0)))
4370    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4371   "TARGET_EXTSWSLI"
4372   "@
4373    extswsli. %0,%1,%2
4374    #
4375    #
4376    #"
4377   "&& reload_completed
4378    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4379        || memory_operand (operands[1], SImode))"
4380   [(pc)]
4382   rtx dest = operands[0];
4383   rtx src = operands[1];
4384   rtx shift = operands[2];
4385   rtx cr = operands[3];
4386   rtx src2;
4388   if (!MEM_P (src))
4389     src2 = src;
4390   else
4391     {
4392       src2 = gen_lowpart (SImode, dest);
4393       emit_move_insn (src2, src);
4394     }
4396   if (REGNO (cr) == CR0_REGNO)
4397     {
4398       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4399       DONE;
4400     }
4402   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4403   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4404   DONE;
4406   [(set_attr "type" "shift")
4407    (set_attr "maybe_var_shift" "no")
4408    (set_attr "dot" "yes")
4409    (set_attr "length" "4,8,8,12")])
4411 (define_insn_and_split "ashdi3_extswsli_dot2"
4412   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4413         (compare:CC
4414          (ashift:DI
4415           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4416           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4417          (const_int 0)))
4418    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4419         (ashift:DI (sign_extend:DI (match_dup 1))
4420                    (match_dup 2)))]
4421   "TARGET_EXTSWSLI"
4422   "@
4423    extswsli. %0,%1,%2
4424    #
4425    #
4426    #"
4427   "&& reload_completed
4428    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4429        || memory_operand (operands[1], SImode))"
4430   [(pc)]
4432   rtx dest = operands[0];
4433   rtx src = operands[1];
4434   rtx shift = operands[2];
4435   rtx cr = operands[3];
4436   rtx src2;
4438   if (!MEM_P (src))
4439     src2 = src;
4440   else
4441     {
4442       src2 = gen_lowpart (SImode, dest);
4443       emit_move_insn (src2, src);
4444     }
4446   if (REGNO (cr) == CR0_REGNO)
4447     {
4448       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4449       DONE;
4450     }
4452   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4453   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4454   DONE;
4456   [(set_attr "type" "shift")
4457    (set_attr "maybe_var_shift" "no")
4458    (set_attr "dot" "yes")
4459    (set_attr "length" "4,8,8,12")])
4461 (define_insn "lshr<mode>3"
4462   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4463         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4464                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4465   ""
4466   "sr<wd>%I2 %0,%1,%<hH>2"
4467   [(set_attr "type" "shift")
4468    (set_attr "maybe_var_shift" "yes")])
4470 (define_insn "*lshrsi3_64"
4471   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4472         (zero_extend:DI
4473             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4474                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4475   "TARGET_POWERPC64"
4476   "srw%I2 %0,%1,%h2"
4477   [(set_attr "type" "shift")
4478    (set_attr "maybe_var_shift" "yes")])
4480 (define_insn_and_split "*lshr<mode>3_dot"
4481   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4482         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4483                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4484                     (const_int 0)))
4485    (clobber (match_scratch:GPR 0 "=r,r"))]
4486   "<MODE>mode == Pmode"
4487   "@
4488    sr<wd>%I2. %0,%1,%<hH>2
4489    #"
4490   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4491   [(set (match_dup 0)
4492         (lshiftrt:GPR (match_dup 1)
4493                       (match_dup 2)))
4494    (set (match_dup 3)
4495         (compare:CC (match_dup 0)
4496                     (const_int 0)))]
4497   ""
4498   [(set_attr "type" "shift")
4499    (set_attr "maybe_var_shift" "yes")
4500    (set_attr "dot" "yes")
4501    (set_attr "length" "4,8")])
4503 (define_insn_and_split "*lshr<mode>3_dot2"
4504   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4505         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4506                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4507                     (const_int 0)))
4508    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4509         (lshiftrt:GPR (match_dup 1)
4510                       (match_dup 2)))]
4511   "<MODE>mode == Pmode"
4512   "@
4513    sr<wd>%I2. %0,%1,%<hH>2
4514    #"
4515   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4516   [(set (match_dup 0)
4517         (lshiftrt:GPR (match_dup 1)
4518                       (match_dup 2)))
4519    (set (match_dup 3)
4520         (compare:CC (match_dup 0)
4521                     (const_int 0)))]
4522   ""
4523   [(set_attr "type" "shift")
4524    (set_attr "maybe_var_shift" "yes")
4525    (set_attr "dot" "yes")
4526    (set_attr "length" "4,8")])
4529 (define_insn "ashr<mode>3"
4530   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4531         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4532                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4533    (clobber (reg:GPR CA_REGNO))]
4534   ""
4535   "sra<wd>%I2 %0,%1,%<hH>2"
4536   [(set_attr "type" "shift")
4537    (set_attr "maybe_var_shift" "yes")])
4539 (define_insn "*ashrsi3_64"
4540   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4541         (sign_extend:DI
4542             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4543                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4544    (clobber (reg:SI CA_REGNO))]
4545   "TARGET_POWERPC64"
4546   "sraw%I2 %0,%1,%h2"
4547   [(set_attr "type" "shift")
4548    (set_attr "maybe_var_shift" "yes")])
4550 (define_insn_and_split "*ashr<mode>3_dot"
4551   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4552         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4553                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4554                     (const_int 0)))
4555    (clobber (match_scratch:GPR 0 "=r,r"))
4556    (clobber (reg:GPR CA_REGNO))]
4557   "<MODE>mode == Pmode"
4558   "@
4559    sra<wd>%I2. %0,%1,%<hH>2
4560    #"
4561   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4562   [(parallel [(set (match_dup 0)
4563                    (ashiftrt:GPR (match_dup 1)
4564                                  (match_dup 2)))
4565               (clobber (reg:GPR CA_REGNO))])
4566    (set (match_dup 3)
4567         (compare:CC (match_dup 0)
4568                     (const_int 0)))]
4569   ""
4570   [(set_attr "type" "shift")
4571    (set_attr "maybe_var_shift" "yes")
4572    (set_attr "dot" "yes")
4573    (set_attr "length" "4,8")])
4575 (define_insn_and_split "*ashr<mode>3_dot2"
4576   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4577         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4578                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4579                     (const_int 0)))
4580    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4581         (ashiftrt:GPR (match_dup 1)
4582                       (match_dup 2)))
4583    (clobber (reg:GPR CA_REGNO))]
4584   "<MODE>mode == Pmode"
4585   "@
4586    sra<wd>%I2. %0,%1,%<hH>2
4587    #"
4588   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4589   [(parallel [(set (match_dup 0)
4590                    (ashiftrt:GPR (match_dup 1)
4591                                  (match_dup 2)))
4592               (clobber (reg:GPR CA_REGNO))])
4593    (set (match_dup 3)
4594         (compare:CC (match_dup 0)
4595                     (const_int 0)))]
4596   ""
4597   [(set_attr "type" "shift")
4598    (set_attr "maybe_var_shift" "yes")
4599    (set_attr "dot" "yes")
4600    (set_attr "length" "4,8")])
4602 ;; Builtins to replace a division to generate FRE reciprocal estimate
4603 ;; instructions and the necessary fixup instructions
4604 (define_expand "recip<mode>3"
4605   [(match_operand:RECIPF 0 "gpc_reg_operand")
4606    (match_operand:RECIPF 1 "gpc_reg_operand")
4607    (match_operand:RECIPF 2 "gpc_reg_operand")]
4608   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4610    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4611    DONE;
4614 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4615 ;; hardware division.  This is only done before register allocation and with
4616 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4617 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4618 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4619 (define_split
4620   [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4621         (div:RECIPF (match_operand 1 "gpc_reg_operand")
4622                     (match_operand 2 "gpc_reg_operand")))]
4623   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4624    && can_create_pseudo_p () && flag_finite_math_only
4625    && !flag_trapping_math && flag_reciprocal_math"
4626   [(const_int 0)]
4628   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4629   DONE;
4632 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4633 ;; appropriate fixup.
4634 (define_expand "rsqrt<mode>2"
4635   [(match_operand:RECIPF 0 "gpc_reg_operand")
4636    (match_operand:RECIPF 1 "gpc_reg_operand")]
4637   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4639   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4640   DONE;
4643 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4644 ;; modes here, and also add in conditional vsx/power8-vector support to access
4645 ;; values in the traditional Altivec registers if the appropriate
4646 ;; -mupper-regs-{df,sf} option is enabled.
4648 (define_expand "abs<mode>2"
4649   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4650         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4651   "TARGET_HARD_FLOAT"
4652   "")
4654 (define_insn "*abs<mode>2_fpr"
4655   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4656         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4657   "TARGET_HARD_FLOAT"
4658   "@
4659    fabs %0,%1
4660    xsabsdp %x0,%x1"
4661   [(set_attr "type" "fpsimple")])
4663 (define_insn "*nabs<mode>2_fpr"
4664   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4665         (neg:SFDF
4666          (abs:SFDF
4667           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4668   "TARGET_HARD_FLOAT"
4669   "@
4670    fnabs %0,%1
4671    xsnabsdp %x0,%x1"
4672   [(set_attr "type" "fpsimple")])
4674 (define_expand "neg<mode>2"
4675   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4676         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4677   "TARGET_HARD_FLOAT"
4678   "")
4680 (define_insn "*neg<mode>2_fpr"
4681   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4682         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4683   "TARGET_HARD_FLOAT"
4684   "@
4685    fneg %0,%1
4686    xsnegdp %x0,%x1"
4687   [(set_attr "type" "fpsimple")])
4689 (define_expand "add<mode>3"
4690   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4691         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4692                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4693   "TARGET_HARD_FLOAT"
4694   "")
4696 (define_insn "*add<mode>3_fpr"
4697   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4698         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4699                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4700   "TARGET_HARD_FLOAT"
4701   "@
4702    fadd<s> %0,%1,%2
4703    xsadd<sd>p %x0,%x1,%x2"
4704   [(set_attr "type" "fp")
4705    (set_attr "isa" "*,<Fisa>")])
4707 (define_expand "sub<mode>3"
4708   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4709         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4710                     (match_operand:SFDF 2 "gpc_reg_operand")))]
4711   "TARGET_HARD_FLOAT"
4712   "")
4714 (define_insn "*sub<mode>3_fpr"
4715   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4716         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4717                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4718   "TARGET_HARD_FLOAT"
4719   "@
4720    fsub<s> %0,%1,%2
4721    xssub<sd>p %x0,%x1,%x2"
4722   [(set_attr "type" "fp")
4723    (set_attr "isa" "*,<Fisa>")])
4725 (define_expand "mul<mode>3"
4726   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4727         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4728                    (match_operand:SFDF 2 "gpc_reg_operand")))]
4729   "TARGET_HARD_FLOAT"
4730   "")
4732 (define_insn "*mul<mode>3_fpr"
4733   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4734         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4735                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4736   "TARGET_HARD_FLOAT"
4737   "@
4738    fmul<s> %0,%1,%2
4739    xsmul<sd>p %x0,%x1,%x2"
4740   [(set_attr "type" "dmul")
4741    (set_attr "isa" "*,<Fisa>")])
4743 (define_expand "div<mode>3"
4744   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4745         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4746                   (match_operand:SFDF 2 "gpc_reg_operand")))]
4747   "TARGET_HARD_FLOAT"
4749   if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4750       && can_create_pseudo_p () && flag_finite_math_only
4751       && !flag_trapping_math && flag_reciprocal_math)
4752     {
4753       rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4754       DONE;
4755     }
4758 (define_insn "*div<mode>3_fpr"
4759   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4760         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4761                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4762   "TARGET_HARD_FLOAT"
4763   "@
4764    fdiv<s> %0,%1,%2
4765    xsdiv<sd>p %x0,%x1,%x2"
4766   [(set_attr "type" "<sd>div")
4767    (set_attr "isa" "*,<Fisa>")])
4769 (define_insn "*sqrt<mode>2_internal"
4770   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4771         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4772   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4773   "@
4774    fsqrt<s> %0,%1
4775    xssqrt<sd>p %x0,%x1"
4776   [(set_attr "type" "<sd>sqrt")
4777    (set_attr "isa" "*,<Fisa>")])
4779 (define_expand "sqrt<mode>2"
4780   [(set (match_operand:SFDF 0 "gpc_reg_operand")
4781         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4782   "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4784   if (<MODE>mode == SFmode
4785       && TARGET_RECIP_PRECISION
4786       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4787       && !optimize_function_for_size_p (cfun)
4788       && flag_finite_math_only && !flag_trapping_math
4789       && flag_unsafe_math_optimizations)
4790     {
4791       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4792       DONE;
4793     }
4796 ;; Floating point reciprocal approximation
4797 (define_insn "fre<sd>"
4798   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4799         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4800                      UNSPEC_FRES))]
4801   "TARGET_<FFRE>"
4802   "@
4803    fre<s> %0,%1
4804    xsre<sd>p %x0,%x1"
4805   [(set_attr "type" "fp")
4806    (set_attr "isa" "*,<Fisa>")])
4808 (define_insn "*rsqrt<mode>2"
4809   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4810         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4811                      UNSPEC_RSQRT))]
4812   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4813   "@
4814    frsqrte<s> %0,%1
4815    xsrsqrte<sd>p %x0,%x1"
4816   [(set_attr "type" "fp")
4817    (set_attr "isa" "*,<Fisa>")])
4819 ;; Floating point comparisons
4820 (define_insn "*cmp<mode>_fpr"
4821   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4822         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4823                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4824   "TARGET_HARD_FLOAT"
4825   "@
4826    fcmpu %0,%1,%2
4827    xscmpudp %0,%x1,%x2"
4828   [(set_attr "type" "fpcompare")
4829    (set_attr "isa" "*,<Fisa>")])
4831 ;; Floating point conversions
4832 (define_expand "extendsfdf2"
4833   [(set (match_operand:DF 0 "gpc_reg_operand")
4834         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4835   "TARGET_HARD_FLOAT"
4837   if (HONOR_SNANS (SFmode))
4838     operands[1] = force_reg (SFmode, operands[1]);
4841 (define_insn_and_split "*extendsfdf2_fpr"
4842   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4843         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4844   "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4845   "@
4846    #
4847    fmr %0,%1
4848    lfs%U1%X1 %0,%1
4849    #
4850    xscpsgndp %x0,%x1,%x1
4851    lxsspx %x0,%y1
4852    lxssp %0,%1"
4853   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4854   [(const_int 0)]
4856   emit_note (NOTE_INSN_DELETED);
4857   DONE;
4859   [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4860    (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4862 (define_insn "*extendsfdf2_snan"
4863   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4864         (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4865   "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4866   "@
4867    frsp %0,%1
4868    xsrsp %x0,%x1"
4869   [(set_attr "type" "fp")
4870    (set_attr "isa" "*,p8v")])
4872 (define_expand "truncdfsf2"
4873   [(set (match_operand:SF 0 "gpc_reg_operand")
4874         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4875   "TARGET_HARD_FLOAT"
4876   "")
4878 (define_insn "*truncdfsf2_fpr"
4879   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4880         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4881   "TARGET_HARD_FLOAT"
4882   "@
4883    frsp %0,%1
4884    xsrsp %x0,%x1"
4885   [(set_attr "type" "fp")
4886    (set_attr "isa" "*,p8v")])
4888 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4889 ;; builtins.c and optabs.c that are not correct for IBM long double
4890 ;; when little-endian.
4891 (define_expand "signbit<mode>2"
4892   [(set (match_dup 2)
4893         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4894    (set (match_dup 3)
4895         (subreg:DI (match_dup 2) 0))
4896    (set (match_dup 4)
4897         (match_dup 5))
4898    (set (match_operand:SI 0 "gpc_reg_operand")
4899         (match_dup 6))]
4900   "TARGET_HARD_FLOAT
4901    && (!FLOAT128_IEEE_P (<MODE>mode)
4902        || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4904   if (FLOAT128_IEEE_P (<MODE>mode))
4905     {
4906       rtx dest = operands[0];
4907       rtx src = operands[1];
4908       rtx tmp = gen_reg_rtx (DImode);
4909       rtx dest_di = gen_lowpart (DImode, dest);
4911       emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4912       emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4913       DONE;
4914     }
4915   operands[2] = gen_reg_rtx (DFmode);
4916   operands[3] = gen_reg_rtx (DImode);
4917   if (TARGET_POWERPC64)
4918     {
4919       operands[4] = gen_reg_rtx (DImode);
4920       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4921       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4922                                     WORDS_BIG_ENDIAN ? 4 : 0);
4923     }
4924   else
4925     {
4926       operands[4] = gen_reg_rtx (SImode);
4927       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4928                                     WORDS_BIG_ENDIAN ? 0 : 4);
4929       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4930     }
4933 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4934 ;; multiple direct moves.  If we used a SUBREG:DI of the Floa128 type, the
4935 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4936 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4938 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4939 ;; split allows the post reload phases to eliminate the move, and do the shift
4940 ;; directly with the register that contains the signbit.
4941 (define_insn_and_split "@signbit<mode>2_dm"
4942   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4943         (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4944                    UNSPEC_SIGNBIT))]
4945   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4946   "@
4947    mfvsrd %0,%x1
4948    #"
4949   "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4950   [(set (match_dup 0)
4951         (match_dup 2))]
4953   operands[2] = gen_highpart (DImode, operands[1]);
4955  [(set_attr "type" "mftgpr,*")])
4957 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4958 ;; register and then doing a direct move if the value comes from memory.  On
4959 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4960 (define_insn_and_split "*signbit<mode>2_dm_mem"
4961   [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4962         (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4963                    UNSPEC_SIGNBIT))]
4964   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4965   "#"
4966   "&& 1"
4967   [(set (match_dup 0)
4968         (match_dup 2))]
4970   rtx dest = operands[0];
4971   rtx src = operands[1];
4972   rtx addr = XEXP (src, 0);
4974   if (WORDS_BIG_ENDIAN)
4975     operands[2] = adjust_address (src, DImode, 0);
4977   else if (REG_P (addr) || SUBREG_P (addr))
4978     operands[2] = adjust_address (src, DImode, 8);
4980   else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4981            && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4982     operands[2] = adjust_address (src, DImode, 8);
4984   else
4985     {
4986       rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4987       emit_insn (gen_rtx_SET (tmp, addr));
4988       operands[2] = change_address (src, DImode,
4989                                     gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4990     }
4993 (define_expand "copysign<mode>3"
4994   [(set (match_dup 3)
4995         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4996    (set (match_dup 4)
4997         (neg:SFDF (abs:SFDF (match_dup 1))))
4998    (set (match_operand:SFDF 0 "gpc_reg_operand")
4999         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5000                                (match_dup 5))
5001                          (match_dup 3)
5002                          (match_dup 4)))]
5003   "TARGET_HARD_FLOAT
5004    && ((TARGET_PPC_GFXOPT
5005         && !HONOR_NANS (<MODE>mode)
5006         && !HONOR_SIGNED_ZEROS (<MODE>mode))
5007        || TARGET_CMPB
5008        || VECTOR_UNIT_VSX_P (<MODE>mode))"
5010   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5011     {
5012       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5013                                              operands[2]));
5014       DONE;
5015     }
5017    operands[3] = gen_reg_rtx (<MODE>mode);
5018    operands[4] = gen_reg_rtx (<MODE>mode);
5019    operands[5] = CONST0_RTX (<MODE>mode);
5020   })
5022 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5023 ;; compiler from optimizing -0.0
5024 (define_insn "copysign<mode>3_fcpsgn"
5025   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5026         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5027                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5028                      UNSPEC_COPYSIGN))]
5029   "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5030   "@
5031    fcpsgn %0,%2,%1
5032    xscpsgndp %x0,%x2,%x1"
5033   [(set_attr "type" "fpsimple")])
5035 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5036 ;; fsel instruction and some auxiliary computations.  Then we just have a
5037 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5038 ;; combine.
5039 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5040 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5041 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
5042 ;; define_splits to make them if made by combine.  On VSX machines we have the
5043 ;; min/max instructions.
5045 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5046 ;; to allow either DF/SF to use only traditional registers.
5048 (define_expand "s<minmax><mode>3"
5049   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5050         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5051                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5052   "TARGET_MINMAX"
5054   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5055   DONE;
5058 (define_insn "*s<minmax><mode>3_vsx"
5059   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5060         (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5061                         (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5062   "TARGET_VSX && TARGET_HARD_FLOAT"
5064   return (TARGET_P9_MINMAX
5065           ? "xs<minmax>cdp %x0,%x1,%x2"
5066           : "xs<minmax>dp %x0,%x1,%x2");
5068   [(set_attr "type" "fp")])
5070 ;; The conditional move instructions allow us to perform max and min operations
5071 ;; even when we don't have the appropriate max/min instruction using the FSEL
5072 ;; instruction.
5074 (define_insn_and_split "*s<minmax><mode>3_fpr"
5075   [(set (match_operand:SFDF 0 "gpc_reg_operand")
5076         (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5077                         (match_operand:SFDF 2 "gpc_reg_operand")))]
5078   "!TARGET_VSX && TARGET_MINMAX"
5079   "#"
5080   "&& 1"
5081   [(const_int 0)]
5083   rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5084   DONE;
5087 (define_expand "mov<mode>cc"
5088    [(set (match_operand:GPR 0 "gpc_reg_operand")
5089          (if_then_else:GPR (match_operand 1 "comparison_operator")
5090                            (match_operand:GPR 2 "gpc_reg_operand")
5091                            (match_operand:GPR 3 "gpc_reg_operand")))]
5092   "TARGET_ISEL"
5094   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5095     DONE;
5096   else
5097     FAIL;
5100 ;; We use the BASE_REGS for the isel input operands because, if rA is
5101 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5102 ;; because we may switch the operands and rB may end up being rA.
5104 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
5105 ;; leave out the mode in operand 4 and use one pattern, but reload can
5106 ;; change the mode underneath our feet and then gets confused trying
5107 ;; to reload the value.
5108 (define_mode_iterator CCEITHER [CC CCUNS])
5109 (define_mode_attr un [(CC "") (CCUNS "un")])
5110 (define_insn "isel_<un>signed_<GPR:mode>"
5111   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5112         (if_then_else:GPR
5113          (match_operator 1 "scc_comparison_operator"
5114                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5115                           (const_int 0)])
5116          (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5117          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5118   "TARGET_ISEL"
5119   "isel %0,%2,%3,%j1"
5120   [(set_attr "type" "isel")])
5122 ;; These patterns can be useful for combine; they let combine know that
5123 ;; isel can handle reversed comparisons so long as the operands are
5124 ;; registers.
5126 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5127   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5128         (if_then_else:GPR
5129          (match_operator 1 "scc_rev_comparison_operator"
5130                          [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5131                           (const_int 0)])
5132          (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5133          (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5134   "TARGET_ISEL"
5136   PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5137   return "isel %0,%3,%2,%j1";
5139   [(set_attr "type" "isel")])
5141 ;; Floating point conditional move
5142 (define_expand "mov<mode>cc"
5143    [(set (match_operand:SFDF 0 "gpc_reg_operand")
5144          (if_then_else:SFDF (match_operand 1 "comparison_operator")
5145                             (match_operand:SFDF 2 "gpc_reg_operand")
5146                             (match_operand:SFDF 3 "gpc_reg_operand")))]
5147   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5149   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5150     DONE;
5151   else
5152     FAIL;
5155 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5156   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5157         (if_then_else:SFDF
5158          (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5159              (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5160          (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5161          (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5162   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5163   "fsel %0,%1,%2,%3"
5164   [(set_attr "type" "fp")])
5166 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5167   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5168         (if_then_else:SFDF
5169          (match_operator:CCFP 1 "fpmask_comparison_operator"
5170                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5171                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5172          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5173          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5174    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5175   "TARGET_P9_MINMAX"
5176   "#"
5177   ""
5178   [(set (match_dup 6)
5179         (if_then_else:V2DI (match_dup 1)
5180                            (match_dup 7)
5181                            (match_dup 8)))
5182    (set (match_dup 0)
5183         (if_then_else:SFDF (ne (match_dup 6)
5184                                (match_dup 8))
5185                            (match_dup 4)
5186                            (match_dup 5)))]
5188   if (GET_CODE (operands[6]) == SCRATCH)
5189     operands[6] = gen_reg_rtx (V2DImode);
5191   operands[7] = CONSTM1_RTX (V2DImode);
5192   operands[8] = CONST0_RTX (V2DImode);
5194  [(set_attr "length" "8")
5195   (set_attr "type" "vecperm")])
5197 ;; Handle inverting the fpmask comparisons.
5198 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5199   [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5200         (if_then_else:SFDF
5201          (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5202                 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5203                  (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5204          (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5205          (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5206    (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5207   "TARGET_P9_MINMAX"
5208   "#"
5209   "&& 1"
5210   [(set (match_dup 6)
5211         (if_then_else:V2DI (match_dup 9)
5212                            (match_dup 7)
5213                            (match_dup 8)))
5214    (set (match_dup 0)
5215         (if_then_else:SFDF (ne (match_dup 6)
5216                                (match_dup 8))
5217                            (match_dup 5)
5218                            (match_dup 4)))]
5220   rtx op1 = operands[1];
5221   enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5223   if (GET_CODE (operands[6]) == SCRATCH)
5224     operands[6] = gen_reg_rtx (V2DImode);
5226   operands[7] = CONSTM1_RTX (V2DImode);
5227   operands[8] = CONST0_RTX (V2DImode);
5229   operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5231  [(set_attr "length" "8")
5232   (set_attr "type" "vecperm")])
5234 (define_insn "*fpmask<mode>"
5235   [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5236         (if_then_else:V2DI
5237          (match_operator:CCFP 1 "fpmask_comparison_operator"
5238                 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5239                  (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5240          (match_operand:V2DI 4 "all_ones_constant" "")
5241          (match_operand:V2DI 5 "zero_constant" "")))]
5242   "TARGET_P9_MINMAX"
5243   "xscmp%V1dp %x0,%x2,%x3"
5244   [(set_attr "type" "fpcompare")])
5246 (define_insn "*xxsel<mode>"
5247   [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5248         (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5249                                (match_operand:V2DI 2 "zero_constant" ""))
5250                            (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5251                            (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5252   "TARGET_P9_MINMAX"
5253   "xxsel %x0,%x4,%x3,%x1"
5254   [(set_attr "type" "vecmove")])
5257 ;; Conversions to and from floating-point.
5259 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5260 ; don't want to support putting SImode in FPR registers.
5261 (define_insn "lfiwax"
5262   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5263         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5264                    UNSPEC_LFIWAX))]
5265   "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5266   "@
5267    lfiwax %0,%y1
5268    lxsiwax %x0,%y1
5269    mtvsrwa %x0,%1
5270    vextsw2d %0,%1"
5271   [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5272    (set_attr "isa" "*,p8v,p8v,p9v")])
5274 ; This split must be run before register allocation because it allocates the
5275 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
5276 ; it earlier to allow for the combiner to merge insns together where it might
5277 ; not be needed and also in case the insns are deleted as dead code.
5279 (define_insn_and_split "floatsi<mode>2_lfiwax"
5280   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5281         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5282    (clobber (match_scratch:DI 2 "=d,wa"))]
5283   "TARGET_HARD_FLOAT && TARGET_LFIWAX
5284    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5285   "#"
5286   ""
5287   [(pc)]
5289   rtx dest = operands[0];
5290   rtx src = operands[1];
5291   rtx tmp;
5293   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5294     tmp = convert_to_mode (DImode, src, false);
5295   else
5296     {
5297       tmp = operands[2];
5298       if (GET_CODE (tmp) == SCRATCH)
5299         tmp = gen_reg_rtx (DImode);
5300       if (MEM_P (src))
5301         {
5302           src = rs6000_force_indexed_or_indirect_mem (src);
5303           emit_insn (gen_lfiwax (tmp, src));
5304         }
5305       else
5306         {
5307           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5308           emit_move_insn (stack, src);
5309           emit_insn (gen_lfiwax (tmp, stack));
5310         }
5311     }
5312   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5313   DONE;
5315   [(set_attr "length" "12")
5316    (set_attr "type" "fpload")])
5318 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5319   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5320         (float:SFDF
5321          (sign_extend:DI
5322           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5323    (clobber (match_scratch:DI 2 "=d,wa"))]
5324   "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5325   "#"
5326   ""
5327   [(pc)]
5329   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5330   if (GET_CODE (operands[2]) == SCRATCH)
5331     operands[2] = gen_reg_rtx (DImode);
5332   if (TARGET_P8_VECTOR)
5333     emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5334   else
5335     emit_insn (gen_lfiwax (operands[2], operands[1]));
5336   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5337   DONE;
5339   [(set_attr "length" "8")
5340    (set_attr "type" "fpload")])
5342 (define_insn "lfiwzx"
5343   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5344         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5345                    UNSPEC_LFIWZX))]
5346   "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5347   "@
5348    lfiwzx %0,%y1
5349    lxsiwzx %x0,%y1
5350    mtvsrwz %x0,%1
5351    xxextractuw %x0,%x1,4"
5352   [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5353    (set_attr "isa" "*,p8v,p8v,p9v")])
5355 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5356   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5357         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5358    (clobber (match_scratch:DI 2 "=d,wa"))]
5359   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5360   "#"
5361   ""
5362   [(pc)]
5364   rtx dest = operands[0];
5365   rtx src = operands[1];
5366   rtx tmp;
5368   if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5369     tmp = convert_to_mode (DImode, src, true);
5370   else
5371     {
5372       tmp = operands[2];
5373       if (GET_CODE (tmp) == SCRATCH)
5374         tmp = gen_reg_rtx (DImode);
5375       if (MEM_P (src))
5376         {
5377           src = rs6000_force_indexed_or_indirect_mem (src);
5378           emit_insn (gen_lfiwzx (tmp, src));
5379         }
5380       else
5381         {
5382           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5383           emit_move_insn (stack, src);
5384           emit_insn (gen_lfiwzx (tmp, stack));
5385         }
5386     }
5387   emit_insn (gen_floatdi<mode>2 (dest, tmp));
5388   DONE;
5390   [(set_attr "length" "12")
5391    (set_attr "type" "fpload")])
5393 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5394   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5395         (unsigned_float:SFDF
5396          (zero_extend:DI
5397           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5398    (clobber (match_scratch:DI 2 "=d,wa"))]
5399   "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5400   "#"
5401   ""
5402   [(pc)]
5404   operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5405   if (GET_CODE (operands[2]) == SCRATCH)
5406     operands[2] = gen_reg_rtx (DImode);
5407   if (TARGET_P8_VECTOR)
5408     emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5409   else
5410     emit_insn (gen_lfiwzx (operands[2], operands[1]));
5411   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5412   DONE;
5414   [(set_attr "length" "8")
5415    (set_attr "type" "fpload")])
5417 ; For each of these conversions, there is a define_expand, a define_insn
5418 ; with a '#' template, and a define_split (with C code).  The idea is
5419 ; to allow constant folding with the template of the define_insn,
5420 ; then to have the insns split later (between sched1 and final).
5422 (define_expand "floatsidf2"
5423   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5424                    (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5425               (use (match_dup 2))
5426               (use (match_dup 3))
5427               (clobber (match_dup 4))
5428               (clobber (match_dup 5))
5429               (clobber (match_dup 6))])]
5430   "TARGET_HARD_FLOAT"
5432   if (TARGET_LFIWAX && TARGET_FCFID)
5433     {
5434       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5435       DONE;
5436     }
5437   else if (TARGET_FCFID)
5438     {
5439       rtx dreg = operands[1];
5440       if (!REG_P (dreg))
5441         dreg = force_reg (SImode, dreg);
5442       dreg = convert_to_mode (DImode, dreg, false);
5443       emit_insn (gen_floatdidf2 (operands[0], dreg));
5444       DONE;
5445     }
5447   if (!REG_P (operands[1]))
5448     operands[1] = force_reg (SImode, operands[1]);
5449   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5450   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5451   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5452   operands[5] = gen_reg_rtx (DFmode);
5453   operands[6] = gen_reg_rtx (SImode);
5456 (define_insn_and_split "*floatsidf2_internal"
5457   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5458         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5459    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5460    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5461    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5462    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5463    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5464   "!TARGET_FCFID && TARGET_HARD_FLOAT"
5465   "#"
5466   ""
5467   [(pc)]
5469   rtx lowword, highword;
5470   gcc_assert (MEM_P (operands[4]));
5471   highword = adjust_address (operands[4], SImode, 0);
5472   lowword = adjust_address (operands[4], SImode, 4);
5473   if (! WORDS_BIG_ENDIAN)
5474     std::swap (lowword, highword);
5476   emit_insn (gen_xorsi3 (operands[6], operands[1],
5477                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5478   emit_move_insn (lowword, operands[6]);
5479   emit_move_insn (highword, operands[2]);
5480   emit_move_insn (operands[5], operands[4]);
5481   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5482   DONE;
5484   [(set_attr "length" "24")
5485    (set_attr "type" "fp")])
5487 ;; If we don't have a direct conversion to single precision, don't enable this
5488 ;; conversion for 32-bit without fast math, because we don't have the insn to
5489 ;; generate the fixup swizzle to avoid double rounding problems.
5490 (define_expand "floatunssisf2"
5491   [(set (match_operand:SF 0 "gpc_reg_operand")
5492         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5493   "TARGET_HARD_FLOAT
5494    && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5495        || (TARGET_FCFID
5496            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5498   if (TARGET_LFIWZX && TARGET_FCFIDUS)
5499     {
5500       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5501       DONE;
5502     }
5503   else
5504     {
5505       rtx dreg = operands[1];
5506       if (!REG_P (dreg))
5507         dreg = force_reg (SImode, dreg);
5508       dreg = convert_to_mode (DImode, dreg, true);
5509       emit_insn (gen_floatdisf2 (operands[0], dreg));
5510       DONE;
5511     }
5514 (define_expand "floatunssidf2"
5515   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5516                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5517               (use (match_dup 2))
5518               (use (match_dup 3))
5519               (clobber (match_dup 4))
5520               (clobber (match_dup 5))])]
5521   "TARGET_HARD_FLOAT"
5523   if (TARGET_LFIWZX && TARGET_FCFID)
5524     {
5525       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5526       DONE;
5527     }
5528   else if (TARGET_FCFID)
5529     {
5530       rtx dreg = operands[1];
5531       if (!REG_P (dreg))
5532         dreg = force_reg (SImode, dreg);
5533       dreg = convert_to_mode (DImode, dreg, true);
5534       emit_insn (gen_floatdidf2 (operands[0], dreg));
5535       DONE;
5536     }
5538   if (!REG_P (operands[1]))
5539     operands[1] = force_reg (SImode, operands[1]);
5540   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5541   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5542   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5543   operands[5] = gen_reg_rtx (DFmode);
5546 (define_insn_and_split "*floatunssidf2_internal"
5547   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5548         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5549    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5550    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5551    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5552    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5553   "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5554    && !(TARGET_FCFID && TARGET_POWERPC64)"
5555   "#"
5556   ""
5557   [(pc)]
5559   rtx lowword, highword;
5560   gcc_assert (MEM_P (operands[4]));
5561   highword = adjust_address (operands[4], SImode, 0);
5562   lowword = adjust_address (operands[4], SImode, 4);
5563   if (! WORDS_BIG_ENDIAN)
5564     std::swap (lowword, highword);
5566   emit_move_insn (lowword, operands[1]);
5567   emit_move_insn (highword, operands[2]);
5568   emit_move_insn (operands[5], operands[4]);
5569   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5570   DONE;
5572   [(set_attr "length" "20")
5573    (set_attr "type" "fp")])
5575 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5576 ;; vector registers.  These insns favor doing the sign/zero extension in
5577 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5578 ;; extension and then a direct move.
5580 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5581   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5582                    (float:FP_ISA3
5583                     (match_operand:QHI 1 "input_operand")))
5584               (clobber (match_scratch:DI 2))
5585               (clobber (match_scratch:DI 3))
5586               (clobber (match_scratch:<QHI:MODE> 4))])]
5587   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5589   if (MEM_P (operands[1]))
5590     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5593 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5594   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5595         (float:FP_ISA3
5596          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5597    (clobber (match_scratch:DI 2 "=v,wa,v"))
5598    (clobber (match_scratch:DI 3 "=X,r,X"))
5599    (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5600   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5601   "#"
5602   "&& reload_completed"
5603   [(const_int 0)]
5605   rtx result = operands[0];
5606   rtx input = operands[1];
5607   rtx di = operands[2];
5609   if (!MEM_P (input))
5610     {
5611       rtx tmp = operands[3];
5612       if (altivec_register_operand (input, <QHI:MODE>mode))
5613         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5614       else if (GET_CODE (tmp) == SCRATCH)
5615         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5616       else
5617         {
5618           emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5619           emit_move_insn (di, tmp);
5620         }
5621     }
5622   else
5623     {
5624       rtx tmp = operands[4];
5625       emit_move_insn (tmp, input);
5626       emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5627     }
5629   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5630   DONE;
5632   [(set_attr "isa" "p9v,*,p9v")])
5634 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5635   [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5636                    (unsigned_float:FP_ISA3
5637                     (match_operand:QHI 1 "input_operand")))
5638               (clobber (match_scratch:DI 2))
5639               (clobber (match_scratch:DI 3))])]
5640   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5642   if (MEM_P (operands[1]))
5643     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5646 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5647   [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5648         (unsigned_float:FP_ISA3
5649          (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5650    (clobber (match_scratch:DI 2 "=v,wa,wa"))
5651    (clobber (match_scratch:DI 3 "=X,r,X"))]
5652   "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5653   "#"
5654   "&& reload_completed"
5655   [(const_int 0)]
5657   rtx result = operands[0];
5658   rtx input = operands[1];
5659   rtx di = operands[2];
5661   if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5662     emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5663   else
5664     {
5665       rtx tmp = operands[3];
5666       if (GET_CODE (tmp) == SCRATCH)
5667         emit_insn (gen_extend<QHI:mode>di2 (di, input));
5668       else
5669         {
5670           emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5671           emit_move_insn (di, tmp);
5672         }
5673     }
5675   emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5676   DONE;
5678   [(set_attr "isa" "p9v,*,p9v")])
5680 (define_expand "fix_trunc<mode>si2"
5681   [(set (match_operand:SI 0 "gpc_reg_operand")
5682         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5683   "TARGET_HARD_FLOAT"
5685   if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5686     {
5687       rtx src = force_reg (<MODE>mode, operands[1]);
5689       if (TARGET_STFIWX)
5690         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5691       else
5692         {
5693           rtx tmp = gen_reg_rtx (DImode);
5694           rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5695           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5696                                                       tmp, stack));
5697         }
5698       DONE;
5699     }
5702 ; Like the convert to float patterns, this insn must be split before
5703 ; register allocation so that it can allocate the memory slot if it
5704 ; needed
5705 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5706   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5707         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5708    (clobber (match_scratch:DI 2 "=d"))]
5709   "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5710    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5711   "#"
5712   ""
5713   [(pc)]
5715   rtx dest = operands[0];
5716   rtx src = operands[1];
5717   rtx tmp = operands[2];
5719   if (GET_CODE (tmp) == SCRATCH)
5720     tmp = gen_reg_rtx (DImode);
5722   emit_insn (gen_fctiwz_<mode> (tmp, src));
5723   if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5724     {
5725       dest = rs6000_force_indexed_or_indirect_mem (dest);
5726       emit_insn (gen_stfiwx (dest, tmp));
5727       DONE;
5728     }
5729   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5730     {
5731       dest = gen_lowpart (DImode, dest);
5732       emit_move_insn (dest, tmp);
5733       DONE;
5734     }
5735   else
5736     {
5737       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5738       emit_insn (gen_stfiwx (stack, tmp));
5739       emit_move_insn (dest, stack);
5740       DONE;
5741     }
5743   [(set_attr "length" "12")
5744    (set_attr "type" "fp")])
5746 (define_insn_and_split "fix_trunc<mode>si2_internal"
5747   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5748         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5749    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5750    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5751   "TARGET_HARD_FLOAT
5752    && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5753   "#"
5754   ""
5755   [(pc)]
5757   rtx lowword;
5758   gcc_assert (MEM_P (operands[3]));
5759   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5761   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5762   emit_move_insn (operands[3], operands[2]);
5763   emit_move_insn (operands[0], lowword);
5764   DONE;
5766   [(set_attr "length" "16")
5767    (set_attr "type" "fp")])
5769 (define_expand "fix_trunc<mode>di2"
5770   [(set (match_operand:DI 0 "gpc_reg_operand")
5771         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5772   "TARGET_HARD_FLOAT && TARGET_FCFID"
5773   "")
5775 (define_insn "*fix_trunc<mode>di2_fctidz"
5776   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5777         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5778   "TARGET_HARD_FLOAT && TARGET_FCFID"
5779   "@
5780    fctidz %0,%1
5781    xscvdpsxds %x0,%x1"
5782   [(set_attr "type" "fp")])
5784 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5785 ;; registers.  If we have ISA 2.07, we don't allow QI/HImode values in the
5786 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5787 ;; values can go in VSX registers.  Keeping the direct move part through
5788 ;; register allocation prevents the register allocator from doing a direct move
5789 ;; of the SImode value to a GPR, and then a store/load.
5790 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5791   [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5792         (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5793    (clobber (match_scratch:SI 2 "=X,X,wa"))]
5794   "TARGET_DIRECT_MOVE"
5795   "@
5796    fctiw<u>z %0,%1
5797    xscvdp<su>xws %x0,%x1
5798    #"
5799   "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5800   [(set (match_dup 2)
5801         (any_fix:SI (match_dup 1)))
5802    (set (match_dup 3)
5803         (match_dup 2))]
5805   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5807   [(set_attr "type" "fp")
5808    (set_attr "length" "4,4,8")
5809    (set_attr "isa" "p9v,p9v,*")])
5811 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5812   [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5813         (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5814   "TARGET_DIRECT_MOVE"
5815   "@
5816    fctiw<u>z %0,%1
5817    xscvdp<su>xws %x0,%x1"
5818   [(set_attr "type" "fp")])
5820 ;; Keep the convert and store together through register allocation to prevent
5821 ;; the register allocator from getting clever and doing a direct move to a GPR
5822 ;; and then store for reg+offset stores.
5823 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5824   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5825         (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5826    (clobber (match_scratch:SI 2 "=wa"))]
5827     "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5828   "#"
5829   "&& reload_completed"
5830   [(set (match_dup 2)
5831         (any_fix:SI (match_dup 1)))
5832    (set (match_dup 0)
5833         (match_dup 3))]
5835   operands[3] = (<QHSI:MODE>mode == SImode
5836                  ? operands[2]
5837                  : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5840 (define_expand "fixuns_trunc<mode>si2"
5841   [(set (match_operand:SI 0 "gpc_reg_operand")
5842         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5843   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5845   if (!TARGET_P8_VECTOR)
5846     {
5847       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5848       DONE;
5849     }
5852 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5853   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5854         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5855    (clobber (match_scratch:DI 2 "=d"))]
5856   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5857    && TARGET_STFIWX && can_create_pseudo_p ()
5858    && !TARGET_P8_VECTOR"
5859   "#"
5860   ""
5861   [(pc)]
5863   rtx dest = operands[0];
5864   rtx src = operands[1];
5865   rtx tmp = operands[2];
5867   if (GET_CODE (tmp) == SCRATCH)
5868     tmp = gen_reg_rtx (DImode);
5870   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5871   if (MEM_P (dest))
5872     {
5873       dest = rs6000_force_indexed_or_indirect_mem (dest);
5874       emit_insn (gen_stfiwx (dest, tmp));
5875       DONE;
5876     }
5877   else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5878     {
5879       dest = gen_lowpart (DImode, dest);
5880       emit_move_insn (dest, tmp);
5881       DONE;
5882     }
5883   else
5884     {
5885       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5886       emit_insn (gen_stfiwx (stack, tmp));
5887       emit_move_insn (dest, stack);
5888       DONE;
5889     }
5891   [(set_attr "length" "12")
5892    (set_attr "type" "fp")])
5894 (define_insn "fixuns_trunc<mode>di2"
5895   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5896         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5897   "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5898   "@
5899    fctiduz %0,%1
5900    xscvdpuxds %x0,%x1"
5901   [(set_attr "type" "fp")])
5903 (define_insn "rs6000_mtfsb0"
5904   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5905                     UNSPECV_MTFSB0)]
5906   "TARGET_HARD_FLOAT"
5907   "mtfsb0 %0"
5908   [(set_attr "type" "fp")])
5910 (define_insn "rs6000_mtfsb1"
5911   [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5912                     UNSPECV_MTFSB1)]
5913   "TARGET_HARD_FLOAT"
5914   "mtfsb1 %0"
5915   [(set_attr "type" "fp")])
5917 (define_insn "rs6000_mffscrn"
5918   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5919         (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5920                             UNSPECV_MFFSCRN))]
5921    "TARGET_P9_MISC"
5922    "mffscrn %0,%1"
5923   [(set_attr "type" "fp")])
5925 (define_insn "rs6000_mffscdrn"
5926   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5927    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5928    (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5929   "TARGET_P9_MISC"
5930   "mffscdrn %0,%1"
5931   [(set_attr "type" "fp")])
5933 (define_expand "rs6000_set_fpscr_rn"
5934  [(match_operand:DI 0 "reg_or_cint_operand")]
5935   "TARGET_HARD_FLOAT"
5937   rtx tmp_df = gen_reg_rtx (DFmode);
5939   /* The floating point rounding control bits are FPSCR[62:63]. Put the
5940      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
5941   if (TARGET_P9_MISC)
5942     {
5943       rtx src_df = force_reg (DImode, operands[0]);
5944       src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5945       emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5946       DONE;
5947     }
5949   if (CONST_INT_P (operands[0]))
5950     {
5951       if ((INTVAL (operands[0]) & 0x1) == 0x1)
5952         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5953       else
5954         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5956       if ((INTVAL (operands[0]) & 0x2) == 0x2)
5957         emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5958       else
5959         emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5960     }
5961   else
5962     {
5963       rtx tmp_rn = gen_reg_rtx (DImode);
5964       rtx tmp_di = gen_reg_rtx (DImode);
5966       /* Extract new RN mode from operand.  */
5967       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5969       /* Insert new RN mode into FSCPR.  */
5970       emit_insn (gen_rs6000_mffs (tmp_df));
5971       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5972       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5973       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5975       /* Need to write to field k=15.  The fields are [0:15].  Hence with
5976          L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W).  FLM is an
5977          8-bit field[0:7]. Need to set the bit that corresponds to the
5978          value of i that you want [0:7].  */
5979       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5980       emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5981     }
5982   DONE;
5985 (define_expand "rs6000_set_fpscr_drn"
5986   [(match_operand:DI 0  "gpc_reg_operand")]
5987   "TARGET_HARD_FLOAT"
5989   rtx tmp_df = gen_reg_rtx (DFmode);
5991   /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5992      new rounding mode bits from operands[0][61:63] into FPSCR[29:31].  */
5993   if (TARGET_P9_MISC)
5994     {
5995       rtx src_df = gen_reg_rtx (DFmode);
5997       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5998       src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5999       emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6000     }
6001   else
6002     {
6003       rtx tmp_rn = gen_reg_rtx (DImode);
6004       rtx tmp_di = gen_reg_rtx (DImode);
6006       /* Extract new DRN mode from operand.  */
6007       emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6008       emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6010       /* Insert new RN mode into FSCPR.  */
6011       emit_insn (gen_rs6000_mffs (tmp_df));
6012       tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6013       emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6014       emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6016       /* Need to write to field 7.  The fields are [0:15].  The equation to
6017          select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6018          i to 0x1 to get field 7 where i selects the field.  */
6019       tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6020       emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6021     }
6022   DONE;
6025 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6026 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6027 ;; because the first makes it clear that operand 0 is not live
6028 ;; before the instruction.
6029 (define_insn "fctiwz_<mode>"
6030   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6031         (unspec:DI [(fix:SI
6032                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6033                    UNSPEC_FCTIWZ))]
6034   "TARGET_HARD_FLOAT"
6035   "@
6036    fctiwz %0,%1
6037    xscvdpsxws %x0,%x1"
6038   [(set_attr "type" "fp")])
6040 (define_insn "fctiwuz_<mode>"
6041   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6042         (unspec:DI [(unsigned_fix:SI
6043                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6044                    UNSPEC_FCTIWUZ))]
6045   "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6046   "@
6047    fctiwuz %0,%1
6048    xscvdpuxws %x0,%x1"
6049   [(set_attr "type" "fp")])
6051 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6052 ;; since the friz instruction does not truncate the value if the floating
6053 ;; point value is < LONG_MIN or > LONG_MAX.
6054 (define_insn "*friz"
6055   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6056         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6057   "TARGET_HARD_FLOAT && TARGET_FPRND
6058    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6059   "@
6060    friz %0,%1
6061    xsrdpiz %x0,%x1"
6062   [(set_attr "type" "fp")])
6064 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode.  This
6065 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6066 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6067 ;; extend it, store it back on the stack from the GPR, load it back into the
6068 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6069 ;; disable using store and load to sign/zero extend the value.
6070 (define_insn_and_split "*round32<mode>2_fprs"
6071   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6072         (float:SFDF
6073          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6074    (clobber (match_scratch:DI 2 "=d"))
6075    (clobber (match_scratch:DI 3 "=d"))]
6076   "TARGET_HARD_FLOAT
6077    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6078    && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6079   "#"
6080   ""
6081   [(pc)]
6083   rtx dest = operands[0];
6084   rtx src = operands[1];
6085   rtx tmp1 = operands[2];
6086   rtx tmp2 = operands[3];
6087   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6089   if (GET_CODE (tmp1) == SCRATCH)
6090     tmp1 = gen_reg_rtx (DImode);
6091   if (GET_CODE (tmp2) == SCRATCH)
6092     tmp2 = gen_reg_rtx (DImode);
6094   emit_insn (gen_fctiwz_<mode> (tmp1, src));
6095   emit_insn (gen_stfiwx (stack, tmp1));
6096   emit_insn (gen_lfiwax (tmp2, stack));
6097   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6098   DONE;
6100   [(set_attr "type" "fpload")
6101    (set_attr "length" "16")])
6103 (define_insn_and_split "*roundu32<mode>2_fprs"
6104   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6105         (unsigned_float:SFDF
6106          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6107    (clobber (match_scratch:DI 2 "=d"))
6108    (clobber (match_scratch:DI 3 "=d"))]
6109   "TARGET_HARD_FLOAT
6110    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6111    && can_create_pseudo_p ()"
6112   "#"
6113   ""
6114   [(pc)]
6116   rtx dest = operands[0];
6117   rtx src = operands[1];
6118   rtx tmp1 = operands[2];
6119   rtx tmp2 = operands[3];
6120   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6122   if (GET_CODE (tmp1) == SCRATCH)
6123     tmp1 = gen_reg_rtx (DImode);
6124   if (GET_CODE (tmp2) == SCRATCH)
6125     tmp2 = gen_reg_rtx (DImode);
6127   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6128   emit_insn (gen_stfiwx (stack, tmp1));
6129   emit_insn (gen_lfiwzx (tmp2, stack));
6130   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6131   DONE;
6133   [(set_attr "type" "fpload")
6134    (set_attr "length" "16")])
6136 ;; No VSX equivalent to fctid
6137 (define_insn "lrint<mode>di2"
6138   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6139         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6140                    UNSPEC_FCTID))]
6141   "TARGET_HARD_FLOAT && TARGET_FPRND"
6142   "fctid %0,%1"
6143   [(set_attr "type" "fp")])
6145 (define_insn "btrunc<mode>2"
6146   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6147         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6148                      UNSPEC_FRIZ))]
6149   "TARGET_HARD_FLOAT && TARGET_FPRND"
6150   "@
6151    friz %0,%1
6152    xsrdpiz %x0,%x1"
6153   [(set_attr "type" "fp")])
6155 (define_insn "ceil<mode>2"
6156   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6157         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6158                      UNSPEC_FRIP))]
6159   "TARGET_HARD_FLOAT && TARGET_FPRND"
6160   "@
6161    frip %0,%1
6162    xsrdpip %x0,%x1"
6163   [(set_attr "type" "fp")])
6165 (define_insn "floor<mode>2"
6166   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6167         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6168                      UNSPEC_FRIM))]
6169   "TARGET_HARD_FLOAT && TARGET_FPRND"
6170   "@
6171    frim %0,%1
6172    xsrdpim %x0,%x1"
6173   [(set_attr "type" "fp")])
6175 ;; No VSX equivalent to frin
6176 (define_insn "round<mode>2"
6177   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6178         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6179                      UNSPEC_FRIN))]
6180   "TARGET_HARD_FLOAT && TARGET_FPRND"
6181   "frin %0,%1"
6182   [(set_attr "type" "fp")])
6184 (define_insn "*xsrdpi<mode>2"
6185   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6186         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6187                      UNSPEC_XSRDPI))]
6188   "TARGET_HARD_FLOAT && TARGET_VSX"
6189   "xsrdpi %x0,%x1"
6190   [(set_attr "type" "fp")])
6192 (define_expand "lround<mode>di2"
6193   [(set (match_dup 2)
6194         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6195                      UNSPEC_XSRDPI))
6196    (set (match_operand:DI 0 "gpc_reg_operand")
6197         (unspec:DI [(match_dup 2)]
6198                    UNSPEC_FCTID))]
6199   "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6201   operands[2] = gen_reg_rtx (<MODE>mode);
6204 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6205 (define_insn "stfiwx"
6206   [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6207         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6208                    UNSPEC_STFIWX))]
6209   "TARGET_PPC_GFXOPT"
6210   "@
6211    stfiwx %1,%y0
6212    stxsiwx %x1,%y0"
6213   [(set_attr "type" "fpstore")
6214    (set_attr "isa" "*,p8v")])
6216 ;; If we don't have a direct conversion to single precision, don't enable this
6217 ;; conversion for 32-bit without fast math, because we don't have the insn to
6218 ;; generate the fixup swizzle to avoid double rounding problems.
6219 (define_expand "floatsisf2"
6220   [(set (match_operand:SF 0 "gpc_reg_operand")
6221         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6222   "TARGET_HARD_FLOAT
6223    && ((TARGET_FCFIDS && TARGET_LFIWAX)
6224        || (TARGET_FCFID
6225            && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6227   if (TARGET_FCFIDS && TARGET_LFIWAX)
6228     {
6229       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6230       DONE;
6231     }
6232   else if (TARGET_FCFID && TARGET_LFIWAX)
6233     {
6234       rtx dfreg = gen_reg_rtx (DFmode);
6235       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6236       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6237       DONE;
6238     }
6239   else
6240     {
6241       rtx dreg = operands[1];
6242       if (!REG_P (dreg))
6243         dreg = force_reg (SImode, dreg);
6244       dreg = convert_to_mode (DImode, dreg, false);
6245       emit_insn (gen_floatdisf2 (operands[0], dreg));
6246       DONE;
6247     }
6250 (define_insn "floatdidf2"
6251   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6252         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6253   "TARGET_FCFID && TARGET_HARD_FLOAT"
6254   "@
6255    fcfid %0,%1
6256    xscvsxddp %x0,%x1"
6257   [(set_attr "type" "fp")])
6259 ; Allow the combiner to merge source memory operands to the conversion so that
6260 ; the optimizer/register allocator doesn't try to load the value too early in a
6261 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6262 ; hit.  We will split after reload to avoid the trip through the GPRs
6264 (define_insn_and_split "*floatdidf2_mem"
6265   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6266         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6267    (clobber (match_scratch:DI 2 "=d,wa"))]
6268   "TARGET_HARD_FLOAT && TARGET_FCFID"
6269   "#"
6270   "&& reload_completed"
6271   [(set (match_dup 2) (match_dup 1))
6272    (set (match_dup 0) (float:DF (match_dup 2)))]
6273   ""
6274   [(set_attr "length" "8")
6275    (set_attr "type" "fpload")])
6277 (define_expand "floatunsdidf2"
6278   [(set (match_operand:DF 0 "gpc_reg_operand")
6279         (unsigned_float:DF
6280          (match_operand:DI 1 "gpc_reg_operand")))]
6281   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6282   "")
6284 (define_insn "*floatunsdidf2_fcfidu"
6285   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6286         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6287   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6288   "@
6289    fcfidu %0,%1
6290    xscvuxddp %x0,%x1"
6291   [(set_attr "type" "fp")])
6293 (define_insn_and_split "*floatunsdidf2_mem"
6294   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6295         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6296    (clobber (match_scratch:DI 2 "=d,wa"))]
6297   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6298   "#"
6299   "&& reload_completed"
6300   [(set (match_dup 2) (match_dup 1))
6301    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6302   ""
6303   [(set_attr "length" "8")
6304    (set_attr "type" "fpload")])
6306 (define_expand "floatdisf2"
6307   [(set (match_operand:SF 0 "gpc_reg_operand")
6308         (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6309   "TARGET_FCFID && TARGET_HARD_FLOAT
6310    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6312   if (!TARGET_FCFIDS)
6313     {
6314       rtx val = operands[1];
6315       if (!flag_unsafe_math_optimizations)
6316         {
6317           rtx label = gen_label_rtx ();
6318           val = gen_reg_rtx (DImode);
6319           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6320           emit_label (label);
6321         }
6322       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6323       DONE;
6324     }
6327 (define_insn "floatdisf2_fcfids"
6328   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6329         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6330   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6331   "@
6332    fcfids %0,%1
6333    xscvsxdsp %x0,%x1"
6334   [(set_attr "type" "fp")
6335    (set_attr "isa" "*,p8v")])
6337 (define_insn_and_split "*floatdisf2_mem"
6338   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6339         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6340    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6341   "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6342   "#"
6343   "&& reload_completed"
6344   [(pc)]
6346   emit_move_insn (operands[2], operands[1]);
6347   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6348   DONE;
6350   [(set_attr "length" "8")
6351    (set_attr "isa" "*,p8v,p8v")])
6353 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6354 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6355 ;; from double rounding.
6356 ;; Instead of creating a new cpu type for two FP operations, just use fp
6357 (define_insn_and_split "floatdisf2_internal1"
6358   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6359         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6360    (clobber (match_scratch:DF 2 "=d"))]
6361   "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6362   "#"
6363   "&& reload_completed"
6364   [(set (match_dup 2)
6365         (float:DF (match_dup 1)))
6366    (set (match_dup 0)
6367         (float_truncate:SF (match_dup 2)))]
6368   ""
6369   [(set_attr "length" "8")
6370    (set_attr "type" "fp")])
6372 ;; Twiddles bits to avoid double rounding.
6373 ;; Bits that might be truncated when converting to DFmode are replaced
6374 ;; by a bit that won't be lost at that stage, but is below the SFmode
6375 ;; rounding position.
6376 (define_expand "floatdisf2_internal2"
6377   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6378                                               (const_int 53)))
6379               (clobber (reg:DI CA_REGNO))])
6380    (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6381                                         (const_int 2047)))
6382    (set (match_dup 3) (plus:DI (match_dup 3)
6383                                (const_int 1)))
6384    (set (match_dup 0) (plus:DI (match_dup 0)
6385                                (const_int 2047)))
6386    (set (match_dup 4) (compare:CCUNS (match_dup 3)
6387                                      (const_int 2)))
6388    (set (match_dup 0) (ior:DI (match_dup 0)
6389                               (match_dup 1)))
6390    (set (match_dup 0) (and:DI (match_dup 0)
6391                               (const_int -2048)))
6392    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6393                            (label_ref (match_operand:DI 2 ""))
6394                            (pc)))
6395    (set (match_dup 0) (match_dup 1))]
6396   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6398   operands[3] = gen_reg_rtx (DImode);
6399   operands[4] = gen_reg_rtx (CCUNSmode);
6402 (define_expand "floatunsdisf2"
6403   [(set (match_operand:SF 0 "gpc_reg_operand")
6404         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6405   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6406   "")
6408 (define_insn "floatunsdisf2_fcfidus"
6409   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6410         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6411   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6412   "@
6413    fcfidus %0,%1
6414    xscvuxdsp %x0,%x1"
6415   [(set_attr "type" "fp")
6416    (set_attr "isa" "*,p8v")])
6418 (define_insn_and_split "*floatunsdisf2_mem"
6419   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6420         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6421    (clobber (match_scratch:DI 2 "=d,d,wa"))]
6422   "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6423   "#"
6424   "&& reload_completed"
6425   [(pc)]
6427   emit_move_insn (operands[2], operands[1]);
6428   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6429   DONE;
6431   [(set_attr "type" "fpload")
6432    (set_attr "length" "8")
6433    (set_attr "isa" "*,p8v,p8v")])
6435 ;; Define the TImode operations that can be done in a small number
6436 ;; of instructions.  The & constraints are to prevent the register
6437 ;; allocator from allocating registers that overlap with the inputs
6438 ;; (for example, having an input in 7,8 and an output in 6,7).  We
6439 ;; also allow for the output being the same as one of the inputs.
6441 (define_expand "addti3"
6442   [(set (match_operand:TI 0 "gpc_reg_operand")
6443         (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6444                  (match_operand:TI 2 "reg_or_short_operand")))]
6445   "TARGET_64BIT"
6447   rtx lo0 = gen_lowpart (DImode, operands[0]);
6448   rtx lo1 = gen_lowpart (DImode, operands[1]);
6449   rtx lo2 = gen_lowpart (DImode, operands[2]);
6450   rtx hi0 = gen_highpart (DImode, operands[0]);
6451   rtx hi1 = gen_highpart (DImode, operands[1]);
6452   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6454   if (!reg_or_short_operand (lo2, DImode))
6455     lo2 = force_reg (DImode, lo2);
6456   if (!adde_operand (hi2, DImode))
6457     hi2 = force_reg (DImode, hi2);
6459   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6460   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6461   DONE;
6464 (define_expand "subti3"
6465   [(set (match_operand:TI 0 "gpc_reg_operand")
6466         (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6467                   (match_operand:TI 2 "gpc_reg_operand")))]
6468   "TARGET_64BIT"
6470   rtx lo0 = gen_lowpart (DImode, operands[0]);
6471   rtx lo1 = gen_lowpart (DImode, operands[1]);
6472   rtx lo2 = gen_lowpart (DImode, operands[2]);
6473   rtx hi0 = gen_highpart (DImode, operands[0]);
6474   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6475   rtx hi2 = gen_highpart (DImode, operands[2]);
6477   if (!reg_or_short_operand (lo1, DImode))
6478     lo1 = force_reg (DImode, lo1);
6479   if (!adde_operand (hi1, DImode))
6480     hi1 = force_reg (DImode, hi1);
6482   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6483   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6484   DONE;
6487 ;; 128-bit logical operations expanders
6489 (define_expand "and<mode>3"
6490   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6491         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6492                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6493   ""
6494   "")
6496 (define_expand "ior<mode>3"
6497   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6498         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6499                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6500   ""
6501   "")
6503 (define_expand "xor<mode>3"
6504   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6505         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6506                       (match_operand:BOOL_128 2 "vlogical_operand")))]
6507   ""
6508   "")
6510 (define_expand "nor<mode>3"
6511   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6512         (and:BOOL_128
6513          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6514          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6515   ""
6516   "")
6518 (define_expand "andc<mode>3"
6519   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6520         (and:BOOL_128
6521          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6522          (match_operand:BOOL_128 1 "vlogical_operand")))]
6523   ""
6524   "")
6526 ;; Power8 vector logical instructions.
6527 (define_expand "eqv<mode>3"
6528   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6529         (not:BOOL_128
6530          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6531                        (match_operand:BOOL_128 2 "vlogical_operand"))))]
6532   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6533   "")
6535 ;; Rewrite nand into canonical form
6536 (define_expand "nand<mode>3"
6537   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6538         (ior:BOOL_128
6539          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6540          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6541   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6542   "")
6544 ;; The canonical form is to have the negated element first, so we need to
6545 ;; reverse arguments.
6546 (define_expand "orc<mode>3"
6547   [(set (match_operand:BOOL_128 0 "vlogical_operand")
6548         (ior:BOOL_128
6549          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6550          (match_operand:BOOL_128 1 "vlogical_operand")))]
6551   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6552   "")
6554 ;; 128-bit logical operations insns and split operations
6555 (define_insn_and_split "*and<mode>3_internal"
6556   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6557         (and:BOOL_128
6558          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6559          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6560   ""
6562   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6563     return "xxland %x0,%x1,%x2";
6565   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6566     return "vand %0,%1,%2";
6568   return "#";
6570   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6571   [(const_int 0)]
6573   rs6000_split_logical (operands, AND, false, false, false);
6574   DONE;
6576   [(set (attr "type")
6577       (if_then_else
6578         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6579         (const_string "veclogical")
6580         (const_string "integer")))
6581    (set (attr "length")
6582       (if_then_else
6583         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6584         (const_string "4")
6585         (if_then_else
6586          (match_test "TARGET_POWERPC64")
6587          (const_string "8")
6588          (const_string "16"))))])
6590 ;; 128-bit IOR/XOR
6591 (define_insn_and_split "*bool<mode>3_internal"
6592   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6593         (match_operator:BOOL_128 3 "boolean_or_operator"
6594          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6595           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6596   ""
6598   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6599     return "xxl%q3 %x0,%x1,%x2";
6601   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6602     return "v%q3 %0,%1,%2";
6604   return "#";
6606   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6607   [(const_int 0)]
6609   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6610   DONE;
6612   [(set (attr "type")
6613       (if_then_else
6614         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6615         (const_string "veclogical")
6616         (const_string "integer")))
6617    (set (attr "length")
6618       (if_then_else
6619         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6620         (const_string "4")
6621         (if_then_else
6622          (match_test "TARGET_POWERPC64")
6623          (const_string "8")
6624          (const_string "16"))))])
6626 ;; 128-bit ANDC/ORC
6627 (define_insn_and_split "*boolc<mode>3_internal1"
6628   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6629         (match_operator:BOOL_128 3 "boolean_operator"
6630          [(not:BOOL_128
6631            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6632           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6633   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6635   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6636     return "xxl%q3 %x0,%x1,%x2";
6638   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6639     return "v%q3 %0,%1,%2";
6641   return "#";
6643   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6644    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6645   [(const_int 0)]
6647   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6648   DONE;
6650   [(set (attr "type")
6651       (if_then_else
6652         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6653         (const_string "veclogical")
6654         (const_string "integer")))
6655    (set (attr "length")
6656       (if_then_else
6657         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6658         (const_string "4")
6659         (if_then_else
6660          (match_test "TARGET_POWERPC64")
6661          (const_string "8")
6662          (const_string "16"))))])
6664 (define_insn_and_split "*boolc<mode>3_internal2"
6665   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6666         (match_operator:TI2 3 "boolean_operator"
6667          [(not:TI2
6668            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6669           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6670   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6671   "#"
6672   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6673   [(const_int 0)]
6675   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6676   DONE;
6678   [(set_attr "type" "integer")
6679    (set (attr "length")
6680         (if_then_else
6681          (match_test "TARGET_POWERPC64")
6682          (const_string "8")
6683          (const_string "16")))])
6685 ;; 128-bit NAND/NOR
6686 (define_insn_and_split "*boolcc<mode>3_internal1"
6687   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6688         (match_operator:BOOL_128 3 "boolean_operator"
6689          [(not:BOOL_128
6690            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6691           (not:BOOL_128
6692            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6693   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6695   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6696     return "xxl%q3 %x0,%x1,%x2";
6698   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6699     return "v%q3 %0,%1,%2";
6701   return "#";
6703   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6704    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6705   [(const_int 0)]
6707   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6708   DONE;
6710   [(set (attr "type")
6711       (if_then_else
6712         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6713         (const_string "veclogical")
6714         (const_string "integer")))
6715    (set (attr "length")
6716       (if_then_else
6717         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6718         (const_string "4")
6719         (if_then_else
6720          (match_test "TARGET_POWERPC64")
6721          (const_string "8")
6722          (const_string "16"))))])
6724 (define_insn_and_split "*boolcc<mode>3_internal2"
6725   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6726         (match_operator:TI2 3 "boolean_operator"
6727          [(not:TI2
6728            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6729           (not:TI2
6730            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6731   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6732   "#"
6733   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6734   [(const_int 0)]
6736   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6737   DONE;
6739   [(set_attr "type" "integer")
6740    (set (attr "length")
6741         (if_then_else
6742          (match_test "TARGET_POWERPC64")
6743          (const_string "8")
6744          (const_string "16")))])
6747 ;; 128-bit EQV
6748 (define_insn_and_split "*eqv<mode>3_internal1"
6749   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6750         (not:BOOL_128
6751          (xor:BOOL_128
6752           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6753           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6754   "TARGET_P8_VECTOR"
6756   if (vsx_register_operand (operands[0], <MODE>mode))
6757     return "xxleqv %x0,%x1,%x2";
6759   return "#";
6761   "TARGET_P8_VECTOR && reload_completed
6762    && int_reg_operand (operands[0], <MODE>mode)"
6763   [(const_int 0)]
6765   rs6000_split_logical (operands, XOR, true, false, false);
6766   DONE;
6768   [(set (attr "type")
6769       (if_then_else
6770         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6771         (const_string "veclogical")
6772         (const_string "integer")))
6773    (set (attr "length")
6774       (if_then_else
6775         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6776         (const_string "4")
6777         (if_then_else
6778          (match_test "TARGET_POWERPC64")
6779          (const_string "8")
6780          (const_string "16"))))])
6782 (define_insn_and_split "*eqv<mode>3_internal2"
6783   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6784         (not:TI2
6785          (xor:TI2
6786           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6787           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6788   "!TARGET_P8_VECTOR"
6789   "#"
6790   "reload_completed && !TARGET_P8_VECTOR"
6791   [(const_int 0)]
6793   rs6000_split_logical (operands, XOR, true, false, false);
6794   DONE;
6796   [(set_attr "type" "integer")
6797    (set (attr "length")
6798         (if_then_else
6799          (match_test "TARGET_POWERPC64")
6800          (const_string "8")
6801          (const_string "16")))])
6803 ;; 128-bit one's complement
6804 (define_insn_and_split "one_cmpl<mode>2"
6805   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6806         (not:BOOL_128
6807           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6808   ""
6810   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6811     return "xxlnor %x0,%x1,%x1";
6813   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6814     return "vnor %0,%1,%1";
6816   return "#";
6818   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6819   [(const_int 0)]
6821   rs6000_split_logical (operands, NOT, false, false, false);
6822   DONE;
6824   [(set (attr "type")
6825       (if_then_else
6826         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6827         (const_string "veclogical")
6828         (const_string "integer")))
6829    (set (attr "length")
6830       (if_then_else
6831         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6832         (const_string "4")
6833         (if_then_else
6834          (match_test "TARGET_POWERPC64")
6835          (const_string "8")
6836          (const_string "16"))))])
6839 ;; Now define ways of moving data around.
6841 ;; Set up a register with a value from the GOT table
6843 (define_expand "movsi_got"
6844   [(set (match_operand:SI 0 "gpc_reg_operand")
6845         (unspec:SI [(match_operand:SI 1 "got_operand")
6846                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6847   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6849   if (GET_CODE (operands[1]) == CONST)
6850     {
6851       rtx offset = const0_rtx;
6852       HOST_WIDE_INT value;
6854       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6855       value = INTVAL (offset);
6856       if (value != 0)
6857         {
6858           rtx tmp = (!can_create_pseudo_p ()
6859                      ? operands[0]
6860                      : gen_reg_rtx (Pmode));
6861           emit_insn (gen_movsi_got (tmp, operands[1]));
6862           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6863           DONE;
6864         }
6865     }
6867   operands[2] = rs6000_got_register (operands[1]);
6870 (define_insn "*movsi_got_internal"
6871   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6872         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6873                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6874                    UNSPEC_MOVSI_GOT))]
6875   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6876   "lwz %0,%a1@got(%2)"
6877   [(set_attr "type" "load")])
6879 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6880 ;; didn't get allocated to a hard register.
6881 (define_split
6882   [(set (match_operand:SI 0 "gpc_reg_operand")
6883         (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6884                     (match_operand:SI 2 "memory_operand")]
6885                    UNSPEC_MOVSI_GOT))]
6886   "DEFAULT_ABI == ABI_V4
6887     && flag_pic == 1
6888     && reload_completed"
6889   [(set (match_dup 0) (match_dup 2))
6890    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6891                                  UNSPEC_MOVSI_GOT))]
6892   "")
6894 ;;         MR          LA
6895 ;;         LWZ         LFIWZX      LXSIWZX
6896 ;;         STW         STFIWX      STXSIWX
6897 ;;         LI          LIS         PLI         #
6898 ;;         XXLOR       XXSPLTIB 0  XXSPLTIB -1 VSPLTISW
6899 ;;         XXLXOR 0    XXLORC -1   P9 const
6900 ;;         MTVSRWZ     MFVSRWZ
6901 ;;         MF%1        MT%0        NOP
6903 (define_insn "*movsi_internal1"
6904   [(set (match_operand:SI 0 "nonimmediate_operand"
6905           "=r,         r,
6906            r,          d,          v,
6907            m,          Z,          Z,
6908            r,          r,          r,          r,
6909            wa,         wa,         wa,         v,
6910            wa,         v,          v,
6911            wa,         r,
6912            r,          *h,         *h")
6913         (match_operand:SI 1 "input_operand"
6914           "r,          U,
6915            m,          Z,          Z,
6916            r,          d,          v,
6917            I,          L,          eI,         n,
6918            wa,         O,          wM,         wB,
6919            O,          wM,         wS,
6920            r,          wa,
6921            *h,         r,          0"))]
6922   "gpc_reg_operand (operands[0], SImode)
6923    || gpc_reg_operand (operands[1], SImode)"
6924   "@
6925    mr %0,%1
6926    la %0,%a1
6927    lwz%U1%X1 %0,%1
6928    lfiwzx %0,%y1
6929    lxsiwzx %x0,%y1
6930    stw%U0%X0 %1,%0
6931    stfiwx %1,%y0
6932    stxsiwx %x1,%y0
6933    li %0,%1
6934    lis %0,%v1
6935    li %0,%1
6936    #
6937    xxlor %x0,%x1,%x1
6938    xxspltib %x0,0
6939    xxspltib %x0,255
6940    vspltisw %0,%1
6941    xxlxor %x0,%x0,%x0
6942    xxlorc %x0,%x0,%x0
6943    #
6944    mtvsrwz %x0,%1
6945    mfvsrwz %0,%x1
6946    mf%1 %0
6947    mt%0 %1
6948    nop"
6949   [(set_attr "type"
6950           "*,          *,
6951            load,       fpload,     fpload,
6952            store,      fpstore,    fpstore,
6953            *,          *,          *,          *,
6954            veclogical, vecsimple,  vecsimple,  vecsimple,
6955            veclogical, veclogical, vecsimple,
6956            mffgpr,     mftgpr,
6957            *,          *,          *")
6958    (set_attr "length"
6959           "*,          *,
6960            *,          *,          *,
6961            *,          *,          *,
6962            *,          *,          *,          8,
6963            *,          *,          *,          *,
6964            *,          *,          8,
6965            *,          *,
6966            *,          *,          *")
6967    (set_attr "isa"
6968           "*,          *,
6969            *,          p8v,        p8v,
6970            *,          p8v,        p8v,
6971            *,          *,          fut,        *,
6972            p8v,        p9v,        p9v,        p8v,
6973            p9v,        p8v,        p9v,
6974            p8v,        p8v,
6975            *,          *,          *")])
6977 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6978 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6980 ;; Because SF values are actually stored as DF values within the vector
6981 ;; registers, we need to convert the value to the vector SF format when
6982 ;; we need to use the bits in a union or similar cases.  We only need
6983 ;; to do this transformation when the value is a vector register.  Loads,
6984 ;; stores, and transfers within GPRs are assumed to be safe.
6986 ;; This is a more general case of reload_gpr_from_vsxsf.  That insn must have
6987 ;; no alternatives, because the call is created as part of secondary_reload,
6988 ;; and operand #2's register class is used to allocate the temporary register.
6989 ;; This function is called before reload, and it creates the temporary as
6990 ;; needed.
6992 ;;              MR           LWZ          LFIWZX       LXSIWZX   STW
6993 ;;              STFS         STXSSP       STXSSPX      VSX->GPR  VSX->VSX
6994 ;;              MTVSRWZ
6996 (define_insn_and_split "movsi_from_sf"
6997   [(set (match_operand:SI 0 "nonimmediate_operand"
6998                 "=r,         r,           ?*d,         ?*v,      m,
6999                  m,          wY,          Z,           r,        ?*wa,
7000                  wa")
7001         (unspec:SI [(match_operand:SF 1 "input_operand"
7002                 "r,          m,           Z,           Z,        r,
7003                  f,          v,           wa,          wa,       wa,
7004                  r")]
7005                     UNSPEC_SI_FROM_SF))
7006    (clobber (match_scratch:V4SF 2
7007                 "=X,         X,           X,           X,        X,
7008                  X,          X,           X,           wa,       X,
7009                  X"))]
7010   "TARGET_NO_SF_SUBREG
7011    && (register_operand (operands[0], SImode)
7012        || register_operand (operands[1], SFmode))"
7013   "@
7014    mr %0,%1
7015    lwz%U1%X1 %0,%1
7016    lfiwzx %0,%y1
7017    lxsiwzx %x0,%y1
7018    stw%U0%X0 %1,%0
7019    stfs%U0%X0 %1,%0
7020    stxssp %1,%0
7021    stxsspx %x1,%y0
7022    #
7023    xscvdpspn %x0,%x1
7024    mtvsrwz %x0,%1"
7025   "&& reload_completed
7026    && int_reg_operand (operands[0], SImode)
7027    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7028   [(const_int 0)]
7030   rtx op0 = operands[0];
7031   rtx op1 = operands[1];
7032   rtx op2 = operands[2];
7033   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7034   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7036   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7037   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7038   DONE;
7040   [(set_attr "type"
7041                 "*,          load,        fpload,      fpload,   store,
7042                  fpstore,    fpstore,     fpstore,     mftgpr,   fp,
7043                  mffgpr")
7044    (set_attr "length"
7045                 "*,          *,           *,           *,        *,
7046                  *,          *,           *,           8,        *,
7047                  *")
7048    (set_attr "isa"
7049                 "*,          *,           p8v,         p8v,      *,
7050                  *,          p9v,         p8v,         p8v,      p8v,
7051                  p8v")])
7053 ;; movsi_from_sf with zero extension
7055 ;;              RLDICL       LWZ          LFIWZX       LXSIWZX   VSX->GPR
7056 ;;              VSX->VSX     MTVSRWZ
7058 (define_insn_and_split "*movdi_from_sf_zero_ext"
7059   [(set (match_operand:DI 0 "gpc_reg_operand"
7060                 "=r,         r,           ?*d,         ?*v,      r,
7061                  ?v,         wa")
7062         (zero_extend:DI
7063          (unspec:SI [(match_operand:SF 1 "input_operand"
7064                 "r,          m,           Z,           Z,        wa,
7065                  wa,         r")]
7066                     UNSPEC_SI_FROM_SF)))
7067    (clobber (match_scratch:V4SF 2
7068                 "=X,         X,           X,           X,        wa,
7069                  wa,         X"))]
7070   "TARGET_DIRECT_MOVE_64BIT
7071    && (register_operand (operands[0], DImode)
7072        || register_operand (operands[1], SImode))"
7073   "@
7074    rldicl %0,%1,0,32
7075    lwz%U1%X1 %0,%1
7076    lfiwzx %0,%y1
7077    lxsiwzx %x0,%y1
7078    #
7079    #
7080    mtvsrwz %x0,%1"
7081   "&& reload_completed
7082    && register_operand (operands[0], DImode)
7083    && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7084   [(const_int 0)]
7086   rtx op0 = operands[0];
7087   rtx op1 = operands[1];
7088   rtx op2 = operands[2];
7089   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7091   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7092   emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7093   DONE;
7095   [(set_attr "type"
7096                 "*,          load,        fpload,      fpload,   two,
7097                  two,        mffgpr")
7098    (set_attr "length"
7099                 "*,          *,           *,           *,        8,
7100                  8,          *")
7101    (set_attr "isa"
7102                 "*,          *,           p8v,         p8v,      p8v,
7103                  p9v,        p8v")])
7105 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7106 ;; moving it to SImode.  We cannot do a SFmode store without having to do the
7107 ;; conversion explicitly since that doesn't work in most cases if the input
7108 ;; isn't representable as SF.  Use XSCVDPSP instead of XSCVDPSPN, since the
7109 ;; former handles cases where the input will not fit in a SFmode, and the
7110 ;; latter assumes the value has already been rounded.
7111 (define_insn "*movsi_from_df"
7112   [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7113         (unspec:SI [(float_truncate:SF
7114                      (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7115                     UNSPEC_SI_FROM_SF))]
7116   "TARGET_NO_SF_SUBREG"
7117   "xscvdpsp %x0,%x1"
7118   [(set_attr "type" "fp")])
7120 ;; Split a load of a large constant into the appropriate two-insn
7121 ;; sequence.
7123 (define_split
7124   [(set (match_operand:SI 0 "gpc_reg_operand")
7125         (match_operand:SI 1 "const_int_operand"))]
7126   "num_insns_constant (operands[1], SImode) > 1"
7127   [(set (match_dup 0)
7128         (match_dup 2))
7129    (set (match_dup 0)
7130         (ior:SI (match_dup 0)
7131                 (match_dup 3)))]
7133   if (rs6000_emit_set_const (operands[0], operands[1]))
7134     DONE;
7135   else
7136     FAIL;
7139 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7140 (define_split
7141   [(set (match_operand:DI 0 "altivec_register_operand")
7142         (match_operand:DI 1 "xxspltib_constant_split"))]
7143   "TARGET_P9_VECTOR && reload_completed"
7144   [(const_int 0)]
7146   rtx op0 = operands[0];
7147   rtx op1 = operands[1];
7148   int r = REGNO (op0);
7149   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7151   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7152   emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7153   DONE;
7156 (define_insn "*mov<mode>_internal2"
7157   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7158         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7159                     (const_int 0)))
7160    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7161   ""
7162   "@
7163    cmp<wd>i %2,%0,0
7164    mr. %0,%1
7165    #"
7166   [(set_attr "type" "cmp,logical,cmp")
7167    (set_attr "dot" "yes")
7168    (set_attr "length" "4,4,8")])
7170 (define_split
7171   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7172         (compare:CC (match_operand:P 1 "gpc_reg_operand")
7173                     (const_int 0)))
7174    (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7175   "reload_completed"
7176   [(set (match_dup 0) (match_dup 1))
7177    (set (match_dup 2)
7178         (compare:CC (match_dup 0)
7179                     (const_int 0)))]
7180   "")
7182 (define_expand "mov<mode>"
7183   [(set (match_operand:INT 0 "general_operand")
7184         (match_operand:INT 1 "any_operand"))]
7185   ""
7187   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7188   DONE;
7191 ;;              MR          LHZ/LBZ    LXSI*ZX    STH/STB    STXSI*X    LI
7192 ;;              XXLOR       load 0     load -1    VSPLTI*    #          MFVSRWZ
7193 ;;              MTVSRWZ     MF%1       MT%1       NOP
7194 (define_insn "*mov<mode>_internal"
7195   [(set (match_operand:QHI 0 "nonimmediate_operand"
7196                 "=r,        r,         wa,        m,         Z,         r,
7197                  wa,        wa,        wa,        v,         ?v,        r,
7198                  wa,        r,         *c*l,      *h")
7199         (match_operand:QHI 1 "input_operand"
7200                 "r,         m,         Z,         r,         wa,        i,
7201                  wa,        O,         wM,        wB,        wS,        wa,
7202                  r,         *h,        r,         0"))]
7203   "gpc_reg_operand (operands[0], <MODE>mode)
7204    || gpc_reg_operand (operands[1], <MODE>mode)"
7205   "@
7206    mr %0,%1
7207    l<wd>z%U1%X1 %0,%1
7208    lxsi<wd>zx %x0,%y1
7209    st<wd>%U0%X0 %1,%0
7210    stxsi<wd>x %x1,%y0
7211    li %0,%1
7212    xxlor %x0,%x1,%x1
7213    xxspltib %x0,0
7214    xxspltib %x0,255
7215    vspltis<wd> %0,%1
7216    #
7217    mfvsrwz %0,%x1
7218    mtvsrwz %x0,%1
7219    mf%1 %0
7220    mt%0 %1
7221    nop"
7222   [(set_attr "type"
7223                 "*,         load,      fpload,    store,     fpstore,   *,
7224                  vecsimple, vecperm,   vecperm,   vecperm,   vecperm,   mftgpr,
7225                  mffgpr,    mfjmpr,    mtjmpr,    *")
7226    (set_attr "length"
7227                 "*,         *,         *,         *,         *,         *,
7228                  *,         *,         *,         *,         8,         *,
7229                  *,         *,         *,         *")
7230    (set_attr "isa"
7231                 "*,         *,         p9v,       *,         p9v,       *,
7232                  p9v,       p9v,       p9v,       p9v,       p9v,       p9v,
7233                  p9v,       *,         *,         *")])
7236 ;; Here is how to move condition codes around.  When we store CC data in
7237 ;; an integer register or memory, we store just the high-order 4 bits.
7238 ;; This lets us not shift in the most common case of CR0.
7239 (define_expand "movcc"
7240   [(set (match_operand:CC 0 "nonimmediate_operand")
7241         (match_operand:CC 1 "nonimmediate_operand"))]
7242   ""
7243   "")
7245 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7247 (define_insn "*movcc_<mode>"
7248   [(set (match_operand:CC_any 0 "nonimmediate_operand"
7249                                 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7250         (match_operand:CC_any 1 "general_operand"
7251                                 " y,r, r,O,x,y,r,I,*h,   r,m,r"))]
7252   "register_operand (operands[0], <MODE>mode)
7253    || register_operand (operands[1], <MODE>mode)"
7254   "@
7255    mcrf %0,%1
7256    mtcrf 128,%1
7257    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7258    crxor %0,%0,%0
7259    mfcr %0%Q1
7260    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7261    mr %0,%1
7262    li %0,%1
7263    mf%1 %0
7264    mt%0 %1
7265    lwz%U1%X1 %0,%1
7266    stw%U0%X0 %1,%0"
7267   [(set_attr_alternative "type"
7268      [(const_string "cr_logical")
7269       (const_string "mtcr")
7270       (const_string "mtcr")
7271       (const_string "cr_logical")
7272       (if_then_else (match_test "TARGET_MFCRF")
7273                     (const_string "mfcrf") (const_string "mfcr"))
7274       (if_then_else (match_test "TARGET_MFCRF")
7275                     (const_string "mfcrf") (const_string "mfcr"))
7276       (const_string "integer")
7277       (const_string "integer")
7278       (const_string "mfjmpr")
7279       (const_string "mtjmpr")
7280       (const_string "load")
7281       (const_string "store")])
7282    (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7284 ;; For floating-point, we normally deal with the floating-point registers
7285 ;; unless -msoft-float is used.  The sole exception is that parameter passing
7286 ;; can produce floating-point values in fixed-point registers.  Unless the
7287 ;; value is a simple constant or already in memory, we deal with this by
7288 ;; allocating memory and copying the value explicitly via that memory location.
7290 ;; Move 32-bit binary/decimal floating point
7291 (define_expand "mov<mode>"
7292   [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7293         (match_operand:FMOVE32 1 "any_operand"))]
7294   "<fmove_ok>"
7296   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7297   DONE;
7300 (define_split
7301   [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7302         (match_operand:FMOVE32 1 "const_double_operand"))]
7303   "reload_completed
7304    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7305        || (SUBREG_P (operands[0])
7306            && REG_P (SUBREG_REG (operands[0]))
7307            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7308   [(set (match_dup 2) (match_dup 3))]
7310   long l;
7312   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7314   if (! TARGET_POWERPC64)
7315     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7316   else
7317     operands[2] = gen_lowpart (SImode, operands[0]);
7319   operands[3] = gen_int_mode (l, SImode);
7322 ;; Originally, we tried to keep movsf and movsd common, but the differences
7323 ;; addressing was making it rather difficult to hide with mode attributes.  In
7324 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7325 ;; before the VSX stores meant that the register allocator would tend to do a
7326 ;; direct move to the GPR (which involves conversion from scalar to
7327 ;; vector/memory formats) to save values in the traditional Altivec registers,
7328 ;; while SDmode had problems on power6 if the GPR store was not first due to
7329 ;; the power6 not having an integer store operation.
7331 ;;      LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
7332 ;;      STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
7333 ;;      MR           MT<x>      MF<x>       NOP
7335 (define_insn "movsf_hardfloat"
7336   [(set (match_operand:SF 0 "nonimmediate_operand"
7337          "=!r,       f,         v,          wa,        m,         wY,
7338           Z,         m,         wa,         !r,        f,         wa,
7339           !r,        *c*l,      !r,         *h")
7340         (match_operand:SF 1 "input_operand"
7341          "m,         m,         wY,         Z,         f,         v,
7342           wa,        r,         j,          j,         f,         wa,
7343           r,         r,         *h,         0"))]
7344   "(register_operand (operands[0], SFmode)
7345    || register_operand (operands[1], SFmode))
7346    && TARGET_HARD_FLOAT
7347    && (TARGET_ALLOW_SF_SUBREG
7348        || valid_sf_si_move (operands[0], operands[1], SFmode))"
7349   "@
7350    lwz%U1%X1 %0,%1
7351    lfs%U1%X1 %0,%1
7352    lxssp %0,%1
7353    lxsspx %x0,%y1
7354    stfs%U0%X0 %1,%0
7355    stxssp %1,%0
7356    stxsspx %x1,%y0
7357    stw%U0%X0 %1,%0
7358    xxlxor %x0,%x0,%x0
7359    li %0,0
7360    fmr %0,%1
7361    xscpsgndp %x0,%x1,%x1
7362    mr %0,%1
7363    mt%0 %1
7364    mf%1 %0
7365    nop"
7366   [(set_attr "type"
7367         "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
7368          fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
7369          *,          mtjmpr,    mfjmpr,     *")
7370    (set_attr "isa"
7371         "*,          *,         p9v,        p8v,       *,         p9v,
7372          p8v,        *,         *,          *,         *,         *,
7373          *,          *,         *,          *")])
7375 ;;      LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
7376 ;;      FMR          MR         MT%0       MF%1       NOP
7377 (define_insn "movsd_hardfloat"
7378   [(set (match_operand:SD 0 "nonimmediate_operand"
7379          "=!r,       d,         m,         Z,         ?d,        ?r,
7380           f,         !r,        *c*l,      !r,        *h")
7381         (match_operand:SD 1 "input_operand"
7382          "m,         Z,         r,         wx,        r,         d,
7383           f,         r,         r,         *h,        0"))]
7384   "(register_operand (operands[0], SDmode)
7385    || register_operand (operands[1], SDmode))
7386    && TARGET_HARD_FLOAT"
7387   "@
7388    lwz%U1%X1 %0,%1
7389    lfiwzx %0,%y1
7390    stw%U0%X0 %1,%0
7391    stfiwx %1,%y0
7392    mtvsrwz %x0,%1
7393    mfvsrwz %0,%x1
7394    fmr %0,%1
7395    mr %0,%1
7396    mt%0 %1
7397    mf%1 %0
7398    nop"
7399   [(set_attr "type"
7400         "load,       fpload,    store,     fpstore,   mffgpr,    mftgpr,
7401          fpsimple,   *,         mtjmpr,    mfjmpr,    *")
7402    (set_attr "isa"
7403         "*,          p7,        *,         *,         p8v,       p8v,
7404          *,          *,         *,         *,         *")])
7406 ;;      MR           MT%0       MF%0       LWZ        STW        LI
7407 ;;      LIS          G-const.   F/n-const  NOP
7408 (define_insn "*mov<mode>_softfloat"
7409   [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7410         "=r,         *c*l,      r,         r,         m,         r,
7411           r,         r,         r,         *h")
7413         (match_operand:FMOVE32 1 "input_operand"
7414          "r,         r,         *h,        m,         r,         I,
7415           L,         G,         Fn,        0"))]
7417   "(gpc_reg_operand (operands[0], <MODE>mode)
7418    || gpc_reg_operand (operands[1], <MODE>mode))
7419    && TARGET_SOFT_FLOAT"
7420   "@
7421    mr %0,%1
7422    mt%0 %1
7423    mf%1 %0
7424    lwz%U1%X1 %0,%1
7425    stw%U0%X0 %1,%0
7426    li %0,%1
7427    lis %0,%v1
7428    #
7429    #
7430    nop"
7431   [(set_attr "type"
7432         "*,          mtjmpr,    mfjmpr,    load,      store,     *,
7433          *,          *,         *,         *")
7435    (set_attr "length"
7436         "*,          *,         *,         *,         *,         *,
7437          *,          *,         8,         *")])
7439 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7440 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7442 ;; Because SF values are actually stored as DF values within the vector
7443 ;; registers, we need to convert the value to the vector SF format when
7444 ;; we need to use the bits in a union or similar cases.  We only need
7445 ;; to do this transformation when the value is a vector register.  Loads,
7446 ;; stores, and transfers within GPRs are assumed to be safe.
7448 ;; This is a more general case of reload_vsx_from_gprsf.  That insn must have
7449 ;; no alternatives, because the call is created as part of secondary_reload,
7450 ;; and operand #2's register class is used to allocate the temporary register.
7451 ;; This function is called before reload, and it creates the temporary as
7452 ;; needed.
7454 ;;          LWZ          LFS        LXSSP      LXSSPX     STW        STFIWX
7455 ;;          STXSIWX      GPR->VSX   VSX->GPR   GPR->GPR
7456 (define_insn_and_split "movsf_from_si"
7457   [(set (match_operand:SF 0 "nonimmediate_operand"
7458             "=!r,       f,         v,         wa,        m,         Z,
7459              Z,         wa,        ?r,        !r")
7460         (unspec:SF [(match_operand:SI 1 "input_operand" 
7461             "m,         m,         wY,        Z,         r,         f,
7462              wa,        r,         wa,        r")]
7463                    UNSPEC_SF_FROM_SI))
7464    (clobber (match_scratch:DI 2
7465             "=X,        X,         X,         X,         X,         X,
7466              X,         r,         X,         X"))]
7467   "TARGET_NO_SF_SUBREG
7468    && (register_operand (operands[0], SFmode)
7469        || register_operand (operands[1], SImode))"
7470   "@
7471    lwz%U1%X1 %0,%1
7472    lfs%U1%X1 %0,%1
7473    lxssp %0,%1
7474    lxsspx %x0,%y1
7475    stw%U0%X0 %1,%0
7476    stfiwx %1,%y0
7477    stxsiwx %x1,%y0
7478    #
7479    mfvsrwz %0,%x1
7480    mr %0,%1"
7482   "&& reload_completed
7483    && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7484    && int_reg_operand_not_pseudo (operands[1], SImode)"
7485   [(const_int 0)]
7487   rtx op0 = operands[0];
7488   rtx op1 = operands[1];
7489   rtx op2 = operands[2];
7490   rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7492   /* Move SF value to upper 32-bits for xscvspdpn.  */
7493   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7494   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7495   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7496   DONE;
7498   [(set_attr "length"
7499             "*,          *,         *,         *,         *,         *,
7500              *,          12,        *,         *")
7501    (set_attr "type"
7502             "load,       fpload,    fpload,    fpload,    store,     fpstore,
7503              fpstore,    vecfloat,  mffgpr,    *")
7504    (set_attr "isa"
7505             "*,          *,         p9v,       p8v,       *,         *,
7506              p8v,        p8v,       p8v,       *")])
7509 ;; Move 64-bit binary/decimal floating point
7510 (define_expand "mov<mode>"
7511   [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7512         (match_operand:FMOVE64 1 "any_operand"))]
7513   ""
7515   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7516   DONE;
7519 (define_split
7520   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7521         (match_operand:FMOVE64 1 "const_int_operand"))]
7522   "! TARGET_POWERPC64 && reload_completed
7523    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7524        || (SUBREG_P (operands[0])
7525            && REG_P (SUBREG_REG (operands[0]))
7526            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7527   [(set (match_dup 2) (match_dup 4))
7528    (set (match_dup 3) (match_dup 1))]
7530   int endian = (WORDS_BIG_ENDIAN == 0);
7531   HOST_WIDE_INT value = INTVAL (operands[1]);
7533   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7534   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7535   operands[4] = GEN_INT (value >> 32);
7536   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7539 (define_split
7540   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7541         (match_operand:FMOVE64 1 "const_double_operand"))]
7542   "! TARGET_POWERPC64 && reload_completed
7543    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7544        || (SUBREG_P (operands[0])
7545            && REG_P (SUBREG_REG (operands[0]))
7546            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7547   [(set (match_dup 2) (match_dup 4))
7548    (set (match_dup 3) (match_dup 5))]
7550   int endian = (WORDS_BIG_ENDIAN == 0);
7551   long l[2];
7553   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7555   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7556   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7557   operands[4] = gen_int_mode (l[endian], SImode);
7558   operands[5] = gen_int_mode (l[1 - endian], SImode);
7561 (define_split
7562   [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7563         (match_operand:FMOVE64 1 "const_double_operand"))]
7564   "TARGET_POWERPC64 && reload_completed
7565    && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7566        || (SUBREG_P (operands[0])
7567            && REG_P (SUBREG_REG (operands[0]))
7568            && REGNO (SUBREG_REG (operands[0])) <= 31))"
7569   [(set (match_dup 2) (match_dup 3))]
7571   int endian = (WORDS_BIG_ENDIAN == 0);
7572   long l[2];
7573   HOST_WIDE_INT val;
7575   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7577   operands[2] = gen_lowpart (DImode, operands[0]);
7578   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
7579   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7580          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7582   operands[3] = gen_int_mode (val, DImode);
7585 ;; Don't have reload use general registers to load a constant.  It is
7586 ;; less efficient than loading the constant into an FP register, since
7587 ;; it will probably be used there.
7589 ;; The move constraints are ordered to prefer floating point registers before
7590 ;; general purpose registers to avoid doing a store and a load to get the value
7591 ;; into a floating point register when it is needed for a floating point
7592 ;; operation.  Prefer traditional floating point registers over VSX registers,
7593 ;; since the D-form version of the memory instructions does not need a GPR for
7594 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7595 ;; registers.
7597 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7598 ;; except for 0.0 which can be created on VSX with an xor instruction.
7600 ;;           STFD         LFD         FMR         LXSD        STXSD
7601 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
7602 ;;           LWZ          STW         MR
7605 (define_insn "*mov<mode>_hardfloat32"
7606   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7607             "=m,          d,          d,          <f64_p9>,   wY,
7608               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
7609               Y,          r,          !r")
7610         (match_operand:FMOVE64 1 "input_operand"
7611              "d,          m,          d,          wY,         <f64_p9>,
7612               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7613               r,          Y,          r"))]
7614   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7615    && (gpc_reg_operand (operands[0], <MODE>mode)
7616        || gpc_reg_operand (operands[1], <MODE>mode))"
7617   "@
7618    stfd%U0%X0 %1,%0
7619    lfd%U1%X1 %0,%1
7620    fmr %0,%1
7621    lxsd %0,%1
7622    stxsd %1,%0
7623    lxsdx %x0,%y1
7624    stxsdx %x1,%y0
7625    xxlor %x0,%x1,%x1
7626    xxlxor %x0,%x0,%x0
7627    #
7628    #
7629    #
7630    #"
7631   [(set_attr "type"
7632             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7633              fpload,      fpstore,    veclogical, veclogical, two,
7634              store,       load,       two")
7635    (set_attr "size" "64")
7636    (set_attr "length"
7637             "*,           *,          *,          *,          *,
7638              *,           *,          *,          *,          8,
7639              8,           8,          8")
7640    (set_attr "isa"
7641             "*,           *,          *,          p9v,        p9v,
7642              p7v,         p7v,        *,          *,          *,
7643              *,           *,          *")])
7645 ;;           STW      LWZ     MR      G-const H-const F-const
7647 (define_insn "*mov<mode>_softfloat32"
7648   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7649            "=Y,       r,      r,      r,      r,      r")
7651         (match_operand:FMOVE64 1 "input_operand"
7652             "r,       Y,      r,      G,      H,      F"))]
7654   "!TARGET_POWERPC64
7655    && (gpc_reg_operand (operands[0], <MODE>mode)
7656        || gpc_reg_operand (operands[1], <MODE>mode))"
7657   "#"
7658   [(set_attr "type"
7659             "store,   load,   two,    *,      *,      *")
7661    (set_attr "length"
7662              "8,      8,      8,      8,      12,     16")])
7664 ; ld/std require word-aligned displacements -> 'Y' constraint.
7665 ; List Y->r and r->Y before r->r for reload.
7667 ;;           STFD         LFD         FMR         LXSD        STXSD
7668 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
7669 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
7670 ;;           NOP          MFVSRD      MTVSRD
7672 (define_insn "*mov<mode>_hardfloat64"
7673   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7674            "=m,           d,          d,          <f64_p9>,   wY,
7675              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
7676              YZ,          r,          !r,         *c*l,       !r,
7677             *h,           r,          <f64_dm>")
7678         (match_operand:FMOVE64 1 "input_operand"
7679             "d,           m,          d,          wY,         <f64_p9>,
7680              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
7681              r,           YZ,         r,          r,          *h,
7682              0,           <f64_dm>,   r"))]
7683   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7684    && (gpc_reg_operand (operands[0], <MODE>mode)
7685        || gpc_reg_operand (operands[1], <MODE>mode))"
7686   "@
7687    stfd%U0%X0 %1,%0
7688    lfd%U1%X1 %0,%1
7689    fmr %0,%1
7690    lxsd %0,%1
7691    stxsd %1,%0
7692    lxsdx %x0,%y1
7693    stxsdx %x1,%y0
7694    xxlor %x0,%x1,%x1
7695    xxlxor %x0,%x0,%x0
7696    li %0,0
7697    std%U0%X0 %1,%0
7698    ld%U1%X1 %0,%1
7699    mr %0,%1
7700    mt%0 %1
7701    mf%1 %0
7702    nop
7703    mfvsrd %0,%x1
7704    mtvsrd %x0,%1"
7705   [(set_attr "type"
7706             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
7707              fpload,      fpstore,    veclogical, veclogical, integer,
7708              store,       load,       *,          mtjmpr,     mfjmpr,
7709              *,           mftgpr,     mffgpr")
7710    (set_attr "size" "64")
7711    (set_attr "isa"
7712             "*,           *,          *,          p9v,        p9v,
7713              p7v,         p7v,        *,          *,          *,
7714              *,           *,          *,          *,          *,
7715              *,           p8v,        p8v")])
7717 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
7718 ;;           H-const  F-const  Special
7720 (define_insn "*mov<mode>_softfloat64"
7721   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7722            "=Y,       r,      r,      *c*l,   r,      r,
7723              r,       r,      *h")
7725         (match_operand:FMOVE64 1 "input_operand"
7726             "r,       Y,      r,      r,      *h,     G,
7727              H,       F,      0"))]
7729   "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7730    && (gpc_reg_operand (operands[0], <MODE>mode)
7731        || gpc_reg_operand (operands[1], <MODE>mode))"
7732   "@
7733    std%U0%X0 %1,%0
7734    ld%U1%X1 %0,%1
7735    mr %0,%1
7736    mt%0 %1
7737    mf%1 %0
7738    #
7739    #
7740    #
7741    nop"
7742   [(set_attr "type"
7743             "store,   load,   *,      mtjmpr, mfjmpr, *,
7744              *,       *,      *")
7746    (set_attr "length"
7747             "*,       *,      *,      *,      *,      8,
7748              12,      16,     *")])
7750 (define_expand "mov<mode>"
7751   [(set (match_operand:FMOVE128 0 "general_operand")
7752         (match_operand:FMOVE128 1 "any_operand"))]
7753   ""
7755   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7756   DONE;
7759 ;; It's important to list Y->r and r->Y before r->r because otherwise
7760 ;; reload, given m->r, will try to pick r->r and reload it, which
7761 ;; doesn't make progress.
7763 ;; We can't split little endian direct moves of TDmode, because the words are
7764 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
7765 ;; problematical.  Don't allow direct move for this case.
7767 ;;              FPR load    FPR store   FPR move    FPR zero    GPR load
7768 ;;              GPR zero    GPR store   GPR move    MFVSRD      MTVSRD
7770 (define_insn_and_split "*mov<mode>_64bit_dm"
7771   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7772                 "=m,        d,          d,          d,          Y,
7773                  r,         r,          r,          r,          d")
7775         (match_operand:FMOVE128_FPR 1 "input_operand"
7776                 "d,         m,          d,          <zero_fp>,  r,
7777                  <zero_fp>, Y,          r,          d,          r"))]
7779   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7780    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7781    && (gpc_reg_operand (operands[0], <MODE>mode)
7782        || gpc_reg_operand (operands[1], <MODE>mode))"
7783   "#"
7784   "&& reload_completed"
7785   [(pc)]
7787   rs6000_split_multireg_move (operands[0], operands[1]);
7788   DONE;
7790   [(set_attr "length" "8")
7791    (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7792    (set_attr "max_prefixed_insns" "2")
7793    (set_attr "num_insns" "2")])
7795 (define_insn_and_split "*movtd_64bit_nodm"
7796   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7797         (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7798   "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7799    && (gpc_reg_operand (operands[0], TDmode)
7800        || gpc_reg_operand (operands[1], TDmode))"
7801   "#"
7802   "&& reload_completed"
7803   [(pc)]
7805   rs6000_split_multireg_move (operands[0], operands[1]);
7806   DONE;
7808   [(set_attr "length" "8,8,8,12,12,8")
7809    (set_attr "max_prefixed_insns" "2")
7810    (set_attr "num_insns" "2,2,2,3,3,2")])
7812 (define_insn_and_split "*mov<mode>_32bit"
7813   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7814         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7815   "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7816    && (FLOAT128_2REG_P (<MODE>mode)
7817        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7818        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7819    && (gpc_reg_operand (operands[0], <MODE>mode)
7820        || gpc_reg_operand (operands[1], <MODE>mode))"
7821   "#"
7822   "&& reload_completed"
7823   [(pc)]
7825   rs6000_split_multireg_move (operands[0], operands[1]);
7826   DONE;
7828   [(set_attr "length" "8,8,8,8,20,20,16")])
7830 (define_insn_and_split "*mov<mode>_softfloat"
7831   [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7832         (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7833   "TARGET_SOFT_FLOAT
7834    && (gpc_reg_operand (operands[0], <MODE>mode)
7835        || gpc_reg_operand (operands[1], <MODE>mode))"
7836   "#"
7837   "&& reload_completed"
7838   [(pc)]
7840   rs6000_split_multireg_move (operands[0], operands[1]);
7841   DONE;
7843   [(set_attr_alternative "length"
7844        [(if_then_else (match_test "TARGET_POWERPC64")
7845             (const_string "8")
7846             (const_string "16"))
7847         (if_then_else (match_test "TARGET_POWERPC64")
7848             (const_string "8")
7849             (const_string "16"))
7850         (if_then_else (match_test "TARGET_POWERPC64")
7851             (const_string "16")
7852             (const_string "32"))
7853         (if_then_else (match_test "TARGET_POWERPC64")
7854             (const_string "8")
7855             (const_string "16"))])])
7857 (define_expand "@extenddf<mode>2"
7858   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7859         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7860   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7862   if (FLOAT128_IEEE_P (<MODE>mode))
7863     rs6000_expand_float128_convert (operands[0], operands[1], false);
7864   else if (TARGET_VSX)
7865     emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7866   else
7867     {
7868       rtx zero = gen_reg_rtx (DFmode);
7869       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7871       emit_insn (gen_extenddf2_fprs (<MODE>mode,
7872                                      operands[0], operands[1], zero));
7873     }
7874   DONE;
7877 ;; Allow memory operands for the source to be created by the combiner.
7878 (define_insn_and_split "@extenddf<mode>2_fprs"
7879   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7880         (float_extend:IBM128
7881          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7882    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7883   "!TARGET_VSX && TARGET_HARD_FLOAT
7884    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7885   "#"
7886   "&& reload_completed"
7887   [(set (match_dup 3) (match_dup 1))
7888    (set (match_dup 4) (match_dup 2))]
7890   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7891   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7893   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7894   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7897 (define_insn_and_split "@extenddf<mode>2_vsx"
7898   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7899         (float_extend:IBM128
7900          (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7901   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7902   "#"
7903   "&& reload_completed"
7904   [(set (match_dup 2) (match_dup 1))
7905    (set (match_dup 3) (match_dup 4))]
7907   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7908   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7910   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7911   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7912   operands[4] = CONST0_RTX (DFmode);
7915 (define_expand "extendsf<mode>2"
7916   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7917         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7918   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7920   if (FLOAT128_IEEE_P (<MODE>mode))
7921     rs6000_expand_float128_convert (operands[0], operands[1], false);
7922   else
7923     {
7924       rtx tmp = gen_reg_rtx (DFmode);
7925       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7926       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7927     }
7928   DONE;
7931 (define_expand "trunc<mode>df2"
7932   [(set (match_operand:DF 0 "gpc_reg_operand")
7933         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7934   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7936   if (FLOAT128_IEEE_P (<MODE>mode))
7937     {
7938       rs6000_expand_float128_convert (operands[0], operands[1], false);
7939       DONE;
7940     }
7943 (define_insn_and_split "trunc<mode>df2_internal1"
7944   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7945         (float_truncate:DF
7946          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7947   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7948    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7949   "@
7950    #
7951    fmr %0,%1"
7952   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7953   [(const_int 0)]
7955   emit_note (NOTE_INSN_DELETED);
7956   DONE;
7958   [(set_attr "type" "fpsimple")])
7960 (define_insn "trunc<mode>df2_internal2"
7961   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7962         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7963   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7964    && TARGET_LONG_DOUBLE_128"
7965   "fadd %0,%1,%L1"
7966   [(set_attr "type" "fp")])
7968 (define_expand "trunc<mode>sf2"
7969   [(set (match_operand:SF 0 "gpc_reg_operand")
7970         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7971   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7973   if (FLOAT128_IEEE_P (<MODE>mode))
7974     rs6000_expand_float128_convert (operands[0], operands[1], false);
7975   else
7976     {
7977       rtx tmp = gen_reg_rtx (DFmode);
7978       emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7979       emit_insn (gen_truncdfsf2 (operands[0], tmp));
7980     }
7981   DONE;
7984 (define_expand "floatsi<mode>2"
7985   [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7986                    (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7987               (clobber (match_scratch:DI 2))])]
7988   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7990   rtx op0 = operands[0];
7991   rtx op1 = operands[1];
7993   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7994     ;
7995   else if (FLOAT128_IEEE_P (<MODE>mode))
7996     {
7997       rs6000_expand_float128_convert (op0, op1, false);
7998       DONE;
7999     }
8000   else
8001     {
8002       rtx tmp = gen_reg_rtx (DFmode);
8003       expand_float (tmp, op1, false);
8004       emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8005       DONE;
8006     }
8009 ; fadd, but rounding towards zero.
8010 ; This is probably not the optimal code sequence.
8011 (define_insn "fix_trunc_helper<mode>"
8012   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8013         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8014                    UNSPEC_FIX_TRUNC_TF))
8015    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8016   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8017   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8018   [(set_attr "type" "fp")
8019    (set_attr "length" "20")])
8021 (define_expand "fix_trunc<mode>si2"
8022   [(set (match_operand:SI 0 "gpc_reg_operand")
8023         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8024   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8026   rtx op0 = operands[0];
8027   rtx op1 = operands[1];
8029   if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8030     ;
8031   else
8032     {
8033       if (FLOAT128_IEEE_P (<MODE>mode))
8034         rs6000_expand_float128_convert (op0, op1, false);
8035       else
8036         emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8037       DONE;
8038     }
8041 (define_expand "@fix_trunc<mode>si2_fprs"
8042   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8043                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8044               (clobber (match_dup 2))
8045               (clobber (match_dup 3))
8046               (clobber (match_dup 4))
8047               (clobber (match_dup 5))])]
8048   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8050   operands[2] = gen_reg_rtx (DFmode);
8051   operands[3] = gen_reg_rtx (DFmode);
8052   operands[4] = gen_reg_rtx (DImode);
8053   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8056 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8057   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8058         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8059    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8060    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8061    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8062    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8063   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8064   "#"
8065   ""
8066   [(pc)]
8068   rtx lowword;
8069   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8070                                          operands[3]));
8072   gcc_assert (MEM_P (operands[5]));
8073   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8075   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8076   emit_move_insn (operands[5], operands[4]);
8077   emit_move_insn (operands[0], lowword);
8078   DONE;
8081 (define_expand "fix_trunc<mode>di2"
8082   [(set (match_operand:DI 0 "gpc_reg_operand")
8083         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8084   "TARGET_FLOAT128_TYPE"
8086   if (!TARGET_FLOAT128_HW)
8087     {
8088       rs6000_expand_float128_convert (operands[0], operands[1], false);
8089       DONE;
8090     }
8093 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8094   [(set (match_operand:SDI 0 "gpc_reg_operand")
8095         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8096   "TARGET_FLOAT128_TYPE"
8098   rs6000_expand_float128_convert (operands[0], operands[1], true);
8099   DONE;
8102 (define_expand "floatdi<mode>2"
8103   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8104         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8105   "TARGET_FLOAT128_TYPE"
8107   if (!TARGET_FLOAT128_HW)
8108     {
8109       rs6000_expand_float128_convert (operands[0], operands[1], false);
8110       DONE;
8111     }
8114 (define_expand "floatunsdi<IEEE128:mode>2"
8115   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8116         (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8117   "TARGET_FLOAT128_TYPE"
8119   if (!TARGET_FLOAT128_HW)
8120     {
8121       rs6000_expand_float128_convert (operands[0], operands[1], true);
8122       DONE;
8123     }
8126 (define_expand "floatuns<IEEE128:mode>2"
8127   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8128         (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8129   "TARGET_FLOAT128_TYPE"
8131   rtx op0 = operands[0];
8132   rtx op1 = operands[1];
8134   if (TARGET_FLOAT128_HW)
8135     emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8136   else
8137     rs6000_expand_float128_convert (op0, op1, true);
8138   DONE;
8141 (define_expand "neg<mode>2"
8142   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8143         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8144   "FLOAT128_IEEE_P (<MODE>mode)
8145    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8147   if (FLOAT128_IEEE_P (<MODE>mode))
8148     {
8149       if (TARGET_FLOAT128_HW)
8150         emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8151       else if (TARGET_FLOAT128_TYPE)
8152         emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8153                                              operands[0], operands[1]));
8154       else
8155         {
8156           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8157           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8158                                                 <MODE>mode,
8159                                                 operands[1], <MODE>mode);
8161           if (target && !rtx_equal_p (target, operands[0]))
8162             emit_move_insn (operands[0], target);
8163         }
8164       DONE;
8165     }
8168 (define_insn "neg<mode>2_internal"
8169   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8170         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8171   "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8173   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8174     return "fneg %L0,%L1\;fneg %0,%1";
8175   else
8176     return "fneg %0,%1\;fneg %L0,%L1";
8178   [(set_attr "type" "fpsimple")
8179    (set_attr "length" "8")])
8181 (define_expand "abs<mode>2"
8182   [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8183         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8184   "FLOAT128_IEEE_P (<MODE>mode)
8185    || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8187   rtx label;
8189   if (FLOAT128_IEEE_P (<MODE>mode))
8190     {
8191       if (TARGET_FLOAT128_HW)
8192         {
8193           emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8194           DONE;
8195         }
8196       else if (TARGET_FLOAT128_TYPE)
8197         {
8198           emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8199                                                operands[0], operands[1]));
8200           DONE;
8201         }
8202       else
8203         FAIL;
8204     }
8206   label = gen_label_rtx ();
8207   emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8208   emit_label (label);
8209   DONE;
8212 (define_expand "@abs<mode>2_internal"
8213   [(set (match_operand:IBM128 0 "gpc_reg_operand")
8214         (match_operand:IBM128 1 "gpc_reg_operand"))
8215    (set (match_dup 3) (match_dup 5))
8216    (set (match_dup 5) (abs:DF (match_dup 5)))
8217    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8218    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8219                            (label_ref (match_operand 2 ""))
8220                            (pc)))
8221    (set (match_dup 6) (neg:DF (match_dup 6)))]
8222   "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8224   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8225   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8226   operands[3] = gen_reg_rtx (DFmode);
8227   operands[4] = gen_reg_rtx (CCFPmode);
8228   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8229   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8233 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8234 ;; register
8236 (define_expand "ieee_128bit_negative_zero"
8237   [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8238   "TARGET_FLOAT128_TYPE"
8240   rtvec v = rtvec_alloc (16);
8241   int i, high;
8243   for (i = 0; i < 16; i++)
8244     RTVEC_ELT (v, i) = const0_rtx;
8246   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8247   RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8249   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8250   DONE;
8253 ;; IEEE 128-bit negate
8255 ;; We have 2 insns here for negate and absolute value.  The first uses
8256 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8257 ;; insns, and second insn after the first split pass loads up the bit to
8258 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
8259 ;; neg/abs to create the constant just once.
8261 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8262   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8263         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8264    (clobber (match_scratch:V16QI 2 "=v"))]
8265   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8266   "#"
8267   "&& 1"
8268   [(parallel [(set (match_dup 0)
8269                    (neg:IEEE128 (match_dup 1)))
8270               (use (match_dup 2))])]
8272   if (GET_CODE (operands[2]) == SCRATCH)
8273     operands[2] = gen_reg_rtx (V16QImode);
8275   operands[3] = gen_reg_rtx (V16QImode);
8276   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8278   [(set_attr "length" "8")
8279    (set_attr "type" "vecsimple")])
8281 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8282   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8283         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8284    (use (match_operand:V16QI 2 "register_operand" "v"))]
8285   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8286   "xxlxor %x0,%x1,%x2"
8287   [(set_attr "type" "veclogical")])
8289 ;; IEEE 128-bit absolute value
8290 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8291   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8292         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8293    (clobber (match_scratch:V16QI 2 "=v"))]
8294   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8295   "#"
8296   "&& 1"
8297   [(parallel [(set (match_dup 0)
8298                    (abs:IEEE128 (match_dup 1)))
8299               (use (match_dup 2))])]
8301   if (GET_CODE (operands[2]) == SCRATCH)
8302     operands[2] = gen_reg_rtx (V16QImode);
8304   operands[3] = gen_reg_rtx (V16QImode);
8305   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8307   [(set_attr "length" "8")
8308    (set_attr "type" "vecsimple")])
8310 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8311   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8312         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8313    (use (match_operand:V16QI 2 "register_operand" "v"))]
8314   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8315   "xxlandc %x0,%x1,%x2"
8316   [(set_attr "type" "veclogical")])
8318 ;; IEEE 128-bit negative absolute value
8319 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8320   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8321         (neg:IEEE128
8322          (abs:IEEE128
8323           (match_operand:IEEE128 1 "register_operand" "wa"))))
8324    (clobber (match_scratch:V16QI 2 "=v"))]
8325   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8326    && FLOAT128_IEEE_P (<MODE>mode)"
8327   "#"
8328   "&& 1"
8329   [(parallel [(set (match_dup 0)
8330                    (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8331               (use (match_dup 2))])]
8333   if (GET_CODE (operands[2]) == SCRATCH)
8334     operands[2] = gen_reg_rtx (V16QImode);
8336   operands[3] = gen_reg_rtx (V16QImode);
8337   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8339   [(set_attr "length" "8")
8340    (set_attr "type" "vecsimple")])
8342 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8343   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8344         (neg:IEEE128
8345          (abs:IEEE128
8346           (match_operand:IEEE128 1 "register_operand" "wa"))))
8347    (use (match_operand:V16QI 2 "register_operand" "v"))]
8348   "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8349   "xxlor %x0,%x1,%x2"
8350   [(set_attr "type" "veclogical")])
8352 ;; Float128 conversion functions.  These expand to library function calls.
8353 ;; We use expand to convert from IBM double double to IEEE 128-bit
8354 ;; and trunc for the opposite.
8355 (define_expand "extendiftf2"
8356   [(set (match_operand:TF 0 "gpc_reg_operand")
8357         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8358   "TARGET_FLOAT128_TYPE"
8360   rs6000_expand_float128_convert (operands[0], operands[1], false);
8361   DONE;
8364 (define_expand "extendifkf2"
8365   [(set (match_operand:KF 0 "gpc_reg_operand")
8366         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8367   "TARGET_FLOAT128_TYPE"
8369   rs6000_expand_float128_convert (operands[0], operands[1], false);
8370   DONE;
8373 (define_expand "extendtfkf2"
8374   [(set (match_operand:KF 0 "gpc_reg_operand")
8375         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8376   "TARGET_FLOAT128_TYPE"
8378   rs6000_expand_float128_convert (operands[0], operands[1], false);
8379   DONE;
8382 (define_expand "extendtfif2"
8383   [(set (match_operand:IF 0 "gpc_reg_operand")
8384         (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8385   "TARGET_FLOAT128_TYPE"
8387   rs6000_expand_float128_convert (operands[0], operands[1], false);
8388   DONE;
8391 (define_expand "trunciftf2"
8392   [(set (match_operand:TF 0 "gpc_reg_operand")
8393         (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8394   "TARGET_FLOAT128_TYPE"
8396   rs6000_expand_float128_convert (operands[0], operands[1], false);
8397   DONE;
8400 (define_expand "truncifkf2"
8401   [(set (match_operand:KF 0 "gpc_reg_operand")
8402         (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8403   "TARGET_FLOAT128_TYPE"
8405   rs6000_expand_float128_convert (operands[0], operands[1], false);
8406   DONE;
8409 (define_expand "trunckftf2"
8410   [(set (match_operand:TF 0 "gpc_reg_operand")
8411         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8412   "TARGET_FLOAT128_TYPE"
8414   rs6000_expand_float128_convert (operands[0], operands[1], false);
8415   DONE;
8418 (define_expand "trunctfif2"
8419   [(set (match_operand:IF 0 "gpc_reg_operand")
8420         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8421   "TARGET_FLOAT128_TYPE"
8423   rs6000_expand_float128_convert (operands[0], operands[1], false);
8424   DONE;
8427 (define_insn_and_split "*extend<mode>tf2_internal"
8428   [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8429         (float_extend:TF
8430          (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8431    "TARGET_FLOAT128_TYPE
8432     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8433   "#"
8434   "&& reload_completed"
8435   [(set (match_dup 0) (match_dup 2))]
8437   operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8440 (define_insn_and_split "*extendtf<mode>2_internal"
8441   [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8442         (float_extend:IFKF
8443          (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8444    "TARGET_FLOAT128_TYPE
8445     && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8446   "#"
8447   "&& reload_completed"
8448   [(set (match_dup 0) (match_dup 2))]
8450   operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8454 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
8455 ;; must have 3 arguments, and scratch register constraint must be a single
8456 ;; constraint.
8458 ;; Reload patterns to support gpr load/store with misaligned mem.
8459 ;; and multiple gpr load/store at offset >= 0xfffc
8460 (define_expand "reload_<mode>_store"
8461   [(parallel [(match_operand 0 "memory_operand" "=m")
8462               (match_operand 1 "gpc_reg_operand" "r")
8463               (match_operand:GPR 2 "register_operand" "=&b")])]
8464   ""
8466   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8467   DONE;
8470 (define_expand "reload_<mode>_load"
8471   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8472               (match_operand 1 "memory_operand" "m")
8473               (match_operand:GPR 2 "register_operand" "=b")])]
8474   ""
8476   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8477   DONE;
8481 ;; Reload patterns for various types using the vector registers.  We may need
8482 ;; an additional base register to convert the reg+offset addressing to reg+reg
8483 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8484 ;; index register for gpr registers.
8485 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8486   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8487               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8488               (match_operand:P 2 "register_operand" "=b")])]
8489   "<P:tptrsize>"
8491   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8492   DONE;
8495 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8496   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8497               (match_operand:RELOAD 1 "memory_operand" "m")
8498               (match_operand:P 2 "register_operand" "=b")])]
8499   "<P:tptrsize>"
8501   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8502   DONE;
8506 ;; Reload sometimes tries to move the address to a GPR, and can generate
8507 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
8508 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8510 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8511   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8512         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8513                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
8514                (const_int -16)))]
8515   "TARGET_ALTIVEC && reload_completed"
8516   "#"
8517   "&& reload_completed"
8518   [(set (match_dup 0)
8519         (plus:P (match_dup 1)
8520                 (match_dup 2)))
8521    (set (match_dup 0)
8522         (and:P (match_dup 0)
8523                (const_int -16)))])
8525 ;; Power8 merge instructions to allow direct move to/from floating point
8526 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
8527 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
8528 ;; value, since it is allocated in reload and not all of the flow information
8529 ;; is setup for it.  We have two patterns to do the two moves between gprs and
8530 ;; fprs.  There isn't a dependancy between the two, but we could potentially
8531 ;; schedule other instructions between the two instructions.
8533 (define_insn "p8_fmrgow_<mode>"
8534   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8535         (unspec:FMOVE64X [
8536                 (match_operand:DF 1 "register_operand" "d")
8537                 (match_operand:DF 2 "register_operand" "d")]
8538                          UNSPEC_P8V_FMRGOW))]
8539   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8540   "fmrgow %0,%1,%2"
8541   [(set_attr "type" "fpsimple")])
8543 (define_insn "p8_mtvsrwz"
8544   [(set (match_operand:DF 0 "register_operand" "=d")
8545         (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8546                    UNSPEC_P8V_MTVSRWZ))]
8547   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8548   "mtvsrwz %x0,%1"
8549   [(set_attr "type" "mftgpr")])
8551 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8552   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8553         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8554                          UNSPEC_P8V_RELOAD_FROM_GPR))
8555    (clobber (match_operand:IF 2 "register_operand" "=d"))]
8556   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8557   "#"
8558   "&& reload_completed"
8559   [(const_int 0)]
8561   rtx dest = operands[0];
8562   rtx src = operands[1];
8563   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8564   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8565   rtx gpr_hi_reg = gen_highpart (SImode, src);
8566   rtx gpr_lo_reg = gen_lowpart (SImode, src);
8568   emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8569   emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8570   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8571   DONE;
8573   [(set_attr "length" "12")
8574    (set_attr "type" "three")])
8576 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8577 (define_insn "p8_mtvsrd_df"
8578   [(set (match_operand:DF 0 "register_operand" "=wa")
8579         (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8580                    UNSPEC_P8V_MTVSRD))]
8581   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8582   "mtvsrd %x0,%1"
8583   [(set_attr "type" "mftgpr")])
8585 (define_insn "p8_xxpermdi_<mode>"
8586   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8587         (unspec:FMOVE128_GPR [
8588                 (match_operand:DF 1 "register_operand" "wa")
8589                 (match_operand:DF 2 "register_operand" "wa")]
8590                 UNSPEC_P8V_XXPERMDI))]
8591   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8592   "xxpermdi %x0,%x1,%x2,0"
8593   [(set_attr "type" "vecperm")])
8595 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8596   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8597         (unspec:FMOVE128_GPR
8598          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8599          UNSPEC_P8V_RELOAD_FROM_GPR))
8600    (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8601   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8602   "#"
8603   "&& reload_completed"
8604   [(const_int 0)]
8606   rtx dest = operands[0];
8607   rtx src = operands[1];
8608   /* You might think that we could use op0 as one temp and a DF clobber
8609      as op2, but you'd be wrong.  Secondary reload move patterns don't
8610      check for overlap of the clobber and the destination.  */
8611   rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8612   rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8613   rtx gpr_hi_reg = gen_highpart (DImode, src);
8614   rtx gpr_lo_reg = gen_lowpart (DImode, src);
8616   emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8617   emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8618   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8619   DONE;
8621   [(set_attr "length" "12")
8622    (set_attr "type" "three")])
8624 (define_split
8625   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8626         (match_operand:FMOVE128_GPR 1 "input_operand"))]
8627   "reload_completed
8628    && (int_reg_operand (operands[0], <MODE>mode)
8629        || int_reg_operand (operands[1], <MODE>mode))
8630    && (!TARGET_DIRECT_MOVE_128
8631        || (!vsx_register_operand (operands[0], <MODE>mode)
8632            && !vsx_register_operand (operands[1], <MODE>mode)))"
8633   [(pc)]
8635   rs6000_split_multireg_move (operands[0], operands[1]);
8636   DONE;
8639 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
8640 ;; type is stored internally as double precision in the VSX registers, we have
8641 ;; to convert it from the vector format.
8642 (define_insn "p8_mtvsrd_sf"
8643   [(set (match_operand:SF 0 "register_operand" "=wa")
8644         (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8645                    UNSPEC_P8V_MTVSRD))]
8646   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8647   "mtvsrd %x0,%1"
8648   [(set_attr "type" "mftgpr")])
8650 (define_insn_and_split "reload_vsx_from_gprsf"
8651   [(set (match_operand:SF 0 "register_operand" "=wa")
8652         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8653                    UNSPEC_P8V_RELOAD_FROM_GPR))
8654    (clobber (match_operand:DI 2 "register_operand" "=r"))]
8655   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8656   "#"
8657   "&& reload_completed"
8658   [(const_int 0)]
8660   rtx op0 = operands[0];
8661   rtx op1 = operands[1];
8662   rtx op2 = operands[2];
8663   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8665   /* Move SF value to upper 32-bits for xscvspdpn.  */
8666   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8667   emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8668   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8669   DONE;
8671   [(set_attr "length" "8")
8672    (set_attr "type" "two")])
8674 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8675 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8676 ;; and then doing a move of that.
8677 (define_insn "p8_mfvsrd_3_<mode>"
8678   [(set (match_operand:DF 0 "register_operand" "=r")
8679         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8680                    UNSPEC_P8V_RELOAD_FROM_VSX))]
8681   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8682   "mfvsrd %0,%x1"
8683   [(set_attr "type" "mftgpr")])
8685 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8686   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8687         (unspec:FMOVE128_GPR
8688          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8689          UNSPEC_P8V_RELOAD_FROM_VSX))
8690    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8691   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8692   "#"
8693   "&& reload_completed"
8694   [(const_int 0)]
8696   rtx dest = operands[0];
8697   rtx src = operands[1];
8698   rtx tmp = operands[2];
8699   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8700   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8702   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8703   emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8704   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8705   DONE;
8707   [(set_attr "length" "12")
8708    (set_attr "type" "three")])
8710 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
8711 ;; type is stored internally as double precision, we have to convert it to the
8712 ;; vector format.
8714 (define_insn_and_split "reload_gpr_from_vsxsf"
8715   [(set (match_operand:SF 0 "register_operand" "=r")
8716         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8717                    UNSPEC_P8V_RELOAD_FROM_VSX))
8718    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8719   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8720   "#"
8721   "&& reload_completed"
8722   [(const_int 0)]
8724   rtx op0 = operands[0];
8725   rtx op1 = operands[1];
8726   rtx op2 = operands[2];
8727   rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8728   rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8730   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8731   emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8732   DONE;
8734   [(set_attr "length" "8")
8735    (set_attr "type" "two")
8736    (set_attr "isa" "p8v")])
8738 ;; Next come the multi-word integer load and store and the load and store
8739 ;; multiple insns.
8741 ;; List r->r after r->Y, otherwise reload will try to reload a
8742 ;; non-offsettable address by using r->r which won't make progress.
8743 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8744 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8746 ;;        GPR store  GPR load   GPR move   FPR store  FPR load   FPR move
8747 ;;        GPR const  AVX store  AVX store  AVX load   AVX load   VSX move
8748 ;;        P9 0       P9 -1      AVX 0/-1   VSX 0      VSX -1     P9 const
8749 ;;        AVX const  
8751 (define_insn "*movdi_internal32"
8752   [(set (match_operand:DI 0 "nonimmediate_operand"
8753          "=Y,        r,         r,         m,         ^d,        ^d,
8754           r,         wY,        Z,         ^v,        $v,        ^wa,
8755           wa,        wa,        v,         wa,        *i,        v,
8756           v")
8757         (match_operand:DI 1 "input_operand"
8758          "r,         Y,         r,         ^d,        m,         ^d,
8759           IJKnF,     ^v,        $v,        wY,        Z,         ^wa,
8760           Oj,        wM,        OjwM,      Oj,        wM,        wS,
8761           wB"))]
8762   "! TARGET_POWERPC64
8763    && (gpc_reg_operand (operands[0], DImode)
8764        || gpc_reg_operand (operands[1], DImode))"
8765   "@
8766    #
8767    #
8768    #
8769    stfd%U0%X0 %1,%0
8770    lfd%U1%X1 %0,%1
8771    fmr %0,%1
8772    #
8773    stxsd %1,%0
8774    stxsdx %x1,%y0
8775    lxsd %0,%1
8776    lxsdx %x0,%y1
8777    xxlor %x0,%x1,%x1
8778    xxspltib %x0,0
8779    xxspltib %x0,255
8780    vspltisw %0,%1
8781    xxlxor %x0,%x0,%x0
8782    xxlorc %x0,%x0,%x0
8783    #
8784    #"
8785   [(set_attr "type"
8786          "store,     load,      *,         fpstore,   fpload,    fpsimple,
8787           *,         fpstore,   fpstore,   fpload,    fpload,    veclogical,
8788           vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8789           vecsimple")
8790    (set_attr "size" "64")
8791    (set_attr "length"
8792          "8,         8,         8,         *,         *,         *,
8793           16,        *,         *,         *,         *,         *,
8794           *,         *,         *,         *,         *,         8,
8795           *")
8796    (set_attr "isa"
8797          "*,         *,         *,         *,         *,         *,
8798           *,         p9v,       p7v,       p9v,       p7v,       *,
8799           p9v,       p9v,       p7v,       *,         *,         p7v,
8800           p7v")])
8802 (define_split
8803   [(set (match_operand:DI 0 "gpc_reg_operand")
8804         (match_operand:DI 1 "const_int_operand"))]
8805   "! TARGET_POWERPC64 && reload_completed
8806    && gpr_or_gpr_p (operands[0], operands[1])
8807    && !direct_move_p (operands[0], operands[1])"
8808   [(set (match_dup 2) (match_dup 4))
8809    (set (match_dup 3) (match_dup 1))]
8811   HOST_WIDE_INT value = INTVAL (operands[1]);
8812   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8813                                        DImode);
8814   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8815                                        DImode);
8816   operands[4] = GEN_INT (value >> 32);
8817   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8820 (define_split
8821   [(set (match_operand:DIFD 0 "nonimmediate_operand")
8822         (match_operand:DIFD 1 "input_operand"))]
8823   "reload_completed && !TARGET_POWERPC64
8824    && gpr_or_gpr_p (operands[0], operands[1])
8825    && !direct_move_p (operands[0], operands[1])"
8826   [(pc)]
8828   rs6000_split_multireg_move (operands[0], operands[1]);
8829   DONE;
8832 ;;         GPR store   GPR load    GPR move
8833 ;;         GPR li      GPR lis     GPR pli     GPR #
8834 ;;         FPR store   FPR load    FPR move
8835 ;;         AVX store   AVX store   AVX load    AVX load    VSX move
8836 ;;         P9 0        P9 -1       AVX 0/-1    VSX 0       VSX -1
8837 ;;         P9 const    AVX const
8838 ;;         From SPR    To SPR      SPR<->SPR
8839 ;;         VSX->GPR    GPR->VSX
8840 (define_insn "*movdi_internal64"
8841   [(set (match_operand:DI 0 "nonimmediate_operand"
8842           "=YZ,        r,          r,
8843            r,          r,          r,          r,
8844            m,          ^d,         ^d,
8845            wY,         Z,          $v,         $v,         ^wa,
8846            wa,         wa,         v,          wa,         wa,
8847            v,          v,
8848            r,          *h,         *h,
8849            ?r,         ?wa")
8850         (match_operand:DI 1 "input_operand"
8851           "r,          YZ,         r,
8852            I,          L,          eI,         nF,
8853            ^d,         m,          ^d,
8854            ^v,         $v,         wY,         Z,          ^wa,
8855            Oj,         wM,         OjwM,       Oj,         wM,
8856            wS,         wB,
8857            *h,         r,          0,
8858            wa,         r"))]
8859   "TARGET_POWERPC64
8860    && (gpc_reg_operand (operands[0], DImode)
8861        || gpc_reg_operand (operands[1], DImode))"
8862   "@
8863    std%U0%X0 %1,%0
8864    ld%U1%X1 %0,%1
8865    mr %0,%1
8866    li %0,%1
8867    lis %0,%v1
8868    li %0,%1
8869    #
8870    stfd%U0%X0 %1,%0
8871    lfd%U1%X1 %0,%1
8872    fmr %0,%1
8873    stxsd %1,%0
8874    stxsdx %x1,%y0
8875    lxsd %0,%1
8876    lxsdx %x0,%y1
8877    xxlor %x0,%x1,%x1
8878    xxspltib %x0,0
8879    xxspltib %x0,255
8880    #
8881    xxlxor %x0,%x0,%x0
8882    xxlorc %x0,%x0,%x0
8883    #
8884    #
8885    mf%1 %0
8886    mt%0 %1
8887    nop
8888    mfvsrd %0,%x1
8889    mtvsrd %x0,%1"
8890   [(set_attr "type"
8891           "store,      load,       *,
8892            *,          *,          *,          *,
8893            fpstore,    fpload,     fpsimple,
8894            fpstore,    fpstore,    fpload,     fpload,     veclogical,
8895            vecsimple,  vecsimple,  vecsimple,  veclogical, veclogical,
8896            vecsimple,  vecsimple,
8897            mfjmpr,     mtjmpr,     *,
8898            mftgpr,     mffgpr")
8899    (set_attr "size" "64")
8900    (set_attr "length"
8901           "*,          *,          *,
8902            *,          *,          *,          20,
8903            *,          *,          *,
8904            *,          *,          *,          *,          *,
8905            *,          *,          *,          *,          *,
8906            8,          *,
8907            *,          *,          *,
8908            *,          *")
8909    (set_attr "isa"
8910           "*,          *,          *,
8911            *,          *,          fut,        *,
8912            *,          *,          *,
8913            p9v,        p7v,        p9v,        p7v,        *,
8914            p9v,        p9v,        p7v,        *,          *,
8915            p7v,        p7v,
8916            *,          *,          *,
8917            p8v,        p8v")])
8919 ; Some DImode loads are best done as a load of -1 followed by a mask
8920 ; instruction.
8921 (define_split
8922   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8923         (match_operand:DI 1 "const_int_operand"))]
8924   "TARGET_POWERPC64
8925    && num_insns_constant (operands[1], DImode) > 1
8926    && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8927    && rs6000_is_valid_and_mask (operands[1], DImode)"
8928   [(set (match_dup 0)
8929         (const_int -1))
8930    (set (match_dup 0)
8931         (and:DI (match_dup 0)
8932                 (match_dup 1)))]
8933   "")
8935 ;; Split a load of a large constant into the appropriate five-instruction
8936 ;; sequence.  Handle anything in a constant number of insns.
8937 ;; When non-easy constants can go in the TOC, this should use
8938 ;; easy_fp_constant predicate.
8939 (define_split
8940   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8941         (match_operand:DI 1 "const_int_operand"))]
8942   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8943   [(set (match_dup 0) (match_dup 2))
8944    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8946   if (rs6000_emit_set_const (operands[0], operands[1]))
8947     DONE;
8948   else
8949     FAIL;
8952 (define_split
8953   [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8954         (match_operand:DI 1 "const_scalar_int_operand"))]
8955   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8956   [(set (match_dup 0) (match_dup 2))
8957    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8959   if (rs6000_emit_set_const (operands[0], operands[1]))
8960     DONE;
8961   else
8962     FAIL;
8965 (define_split
8966   [(set (match_operand:DI 0 "altivec_register_operand")
8967         (match_operand:DI 1 "s5bit_cint_operand"))]
8968   "TARGET_VSX && reload_completed"
8969   [(const_int 0)]
8971   rtx op0 = operands[0];
8972   rtx op1 = operands[1];
8973   int r = REGNO (op0);
8974   rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8976   emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8977   if (op1 != const0_rtx && op1 != constm1_rtx)
8978     {
8979       rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8980       emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8981     }
8982   DONE;
8985 ;; Split integer constants that can be loaded with XXSPLTIB and a
8986 ;; sign extend operation.
8987 (define_split
8988   [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8989         (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8990   "TARGET_P9_VECTOR && reload_completed"
8991   [(const_int 0)]
8993   rtx op0 = operands[0];
8994   rtx op1 = operands[1];
8995   int r = REGNO (op0);
8996   rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8998   emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8999   if (<MODE>mode == DImode)
9000     emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9001   else if (<MODE>mode == SImode)
9002     emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9003   else if (<MODE>mode == HImode)
9004     {
9005       rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9006       emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9007     }
9008   DONE;
9012 ;; TImode/PTImode is similar, except that we usually want to compute the
9013 ;; address into a register and use lsi/stsi (the exception is during reload).
9015 (define_insn "*mov<mode>_string"
9016   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9017         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9018   "! TARGET_POWERPC64
9019    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9020    && (gpc_reg_operand (operands[0], <MODE>mode)
9021        || gpc_reg_operand (operands[1], <MODE>mode))"
9022   "#"
9023   [(set_attr "type" "store,store,load,load,*,*")
9024    (set_attr "update" "yes")
9025    (set_attr "indexed" "yes")
9026    (set_attr "cell_micro" "conditional")])
9028 (define_insn "*mov<mode>_ppc64"
9029   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9030         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9031   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9032    && (gpc_reg_operand (operands[0], <MODE>mode)
9033        || gpc_reg_operand (operands[1], <MODE>mode)))"
9035   return rs6000_output_move_128bit (operands);
9037   [(set_attr "type" "store,store,load,load,*,*")
9038    (set_attr "length" "8")
9039    (set_attr "max_prefixed_insns" "2")])
9041 (define_split
9042   [(set (match_operand:TI2 0 "int_reg_operand")
9043         (match_operand:TI2 1 "const_scalar_int_operand"))]
9044   "TARGET_POWERPC64
9045    && (VECTOR_MEM_NONE_P (<MODE>mode)
9046        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9047   [(set (match_dup 2) (match_dup 4))
9048    (set (match_dup 3) (match_dup 5))]
9050   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9051                                        <MODE>mode);
9052   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9053                                        <MODE>mode);
9054   if (CONST_WIDE_INT_P (operands[1]))
9055     {
9056       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9057       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9058     }
9059   else if (CONST_INT_P (operands[1]))
9060     {
9061       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9062       operands[5] = operands[1];
9063     }
9064   else
9065     FAIL;
9068 (define_split
9069   [(set (match_operand:TI2 0 "nonimmediate_operand")
9070         (match_operand:TI2 1 "input_operand"))]
9071   "reload_completed
9072    && gpr_or_gpr_p (operands[0], operands[1])
9073    && !direct_move_p (operands[0], operands[1])
9074    && !quad_load_store_p (operands[0], operands[1])"
9075   [(pc)]
9077   rs6000_split_multireg_move (operands[0], operands[1]);
9078   DONE;
9081 (define_expand "setmemsi"
9082   [(parallel [(set (match_operand:BLK 0 "")
9083                    (match_operand 2 "const_int_operand"))
9084               (use (match_operand:SI 1 ""))
9085               (use (match_operand:SI 3 ""))])]
9086   ""
9088   /* If value to set is not zero, use the library routine.  */
9089   if (operands[2] != const0_rtx)
9090     FAIL;
9092   if (expand_block_clear (operands))
9093     DONE;
9094   else
9095     FAIL;
9098 ;; String compare N insn.
9099 ;; Argument 0 is the target (result)
9100 ;; Argument 1 is the destination
9101 ;; Argument 2 is the source
9102 ;; Argument 3 is the length
9103 ;; Argument 4 is the alignment
9105 (define_expand "cmpstrnsi"
9106   [(parallel [(set (match_operand:SI 0)
9107                (compare:SI (match_operand:BLK 1)
9108                            (match_operand:BLK 2)))
9109               (use (match_operand:SI 3))
9110               (use (match_operand:SI 4))])]
9111   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9113   if (optimize_insn_for_size_p ())
9114     FAIL;
9116   if (expand_strn_compare (operands, 0))
9117     DONE;
9118   else  
9119     FAIL;
9122 ;; String compare insn.
9123 ;; Argument 0 is the target (result)
9124 ;; Argument 1 is the destination
9125 ;; Argument 2 is the source
9126 ;; Argument 3 is the alignment
9128 (define_expand "cmpstrsi"
9129   [(parallel [(set (match_operand:SI 0)
9130                (compare:SI (match_operand:BLK 1)
9131                            (match_operand:BLK 2)))
9132               (use (match_operand:SI 3))])]
9133   "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9135   if (optimize_insn_for_size_p ())
9136     FAIL;
9138   if (expand_strn_compare (operands, 1))
9139     DONE;
9140   else  
9141     FAIL;
9144 ;; Block compare insn.
9145 ;; Argument 0 is the target (result)
9146 ;; Argument 1 is the destination
9147 ;; Argument 2 is the source
9148 ;; Argument 3 is the length
9149 ;; Argument 4 is the alignment
9151 (define_expand "cmpmemsi"
9152   [(parallel [(set (match_operand:SI 0)
9153                (compare:SI (match_operand:BLK 1)
9154                            (match_operand:BLK 2)))
9155               (use (match_operand:SI 3))
9156               (use (match_operand:SI 4))])]
9157   "TARGET_POPCNTD"
9159   if (expand_block_compare (operands))
9160     DONE;
9161   else
9162     FAIL;
9165 ;; String/block copy insn (source and destination must not overlap).
9166 ;; Argument 0 is the destination
9167 ;; Argument 1 is the source
9168 ;; Argument 2 is the length
9169 ;; Argument 3 is the alignment
9171 (define_expand "cpymemsi"
9172   [(parallel [(set (match_operand:BLK 0 "")
9173                    (match_operand:BLK 1 ""))
9174               (use (match_operand:SI 2 ""))
9175               (use (match_operand:SI 3 ""))])]
9176   ""
9178   if (expand_block_move (operands, false))
9179     DONE;
9180   else
9181     FAIL;
9184 ;; String/block move insn (source and destination may overlap).
9185 ;; Argument 0 is the destination
9186 ;; Argument 1 is the source
9187 ;; Argument 2 is the length
9188 ;; Argument 3 is the alignment
9190 (define_expand "movmemsi"
9191   [(parallel [(set (match_operand:BLK 0 "")
9192                    (match_operand:BLK 1 ""))
9193               (use (match_operand:SI 2 ""))
9194               (use (match_operand:SI 3 ""))])]
9195   ""
9197   if (expand_block_move (operands, true))
9198     DONE;
9199   else
9200     FAIL;
9204 ;; Define insns that do load or store with update.  Some of these we can
9205 ;; get by using pre-decrement or pre-increment, but the hardware can also
9206 ;; do cases where the increment is not the size of the object.
9208 ;; In all these cases, we use operands 0 and 1 for the register being
9209 ;; incremented because those are the operands that local-alloc will
9210 ;; tie and these are the pair most likely to be tieable (and the ones
9211 ;; that will benefit the most).
9213 (define_insn "*movdi_update1"
9214   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9215         (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9216                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9217    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9218         (plus:P (match_dup 1) (match_dup 2)))]
9219   "TARGET_POWERPC64 && TARGET_UPDATE
9220    && (!avoiding_indexed_address_p (DImode)
9221        || !gpc_reg_operand (operands[2], Pmode))"
9222   "@
9223    ldux %3,%0,%2
9224    ldu %3,%2(%0)"
9225   [(set_attr "type" "load")
9226    (set_attr "update" "yes")
9227    (set_attr "indexed" "yes,no")])
9229 (define_insn "movdi_<mode>_update"
9230   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9231                         (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9232         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9233    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9234         (plus:P (match_dup 1) (match_dup 2)))]
9235   "TARGET_POWERPC64 && TARGET_UPDATE
9236    && (!avoiding_indexed_address_p (DImode)
9237        || !gpc_reg_operand (operands[2], Pmode)
9238        || (REG_P (operands[0])
9239            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9240   "@
9241    stdux %3,%0,%2
9242    stdu %3,%2(%0)"
9243   [(set_attr "type" "store")
9244    (set_attr "update" "yes")
9245    (set_attr "indexed" "yes,no")])
9247 ;; This pattern is only conditional on TARGET_64BIT, as it is
9248 ;; needed for stack allocation, even if the user passes -mno-update.
9249 (define_insn "movdi_update_stack"
9250   [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9251                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9252         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9253    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9254         (plus:DI (match_dup 1) (match_dup 2)))]
9255   "TARGET_64BIT"
9256   "@
9257    stdux %3,%0,%2
9258    stdu %3,%2(%0)"
9259   [(set_attr "type" "store")
9260    (set_attr "update" "yes")
9261    (set_attr "indexed" "yes,no")])
9263 (define_insn "*movsi_update1"
9264   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9265         (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9266                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9267    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9268         (plus:P (match_dup 1) (match_dup 2)))]
9269   "TARGET_UPDATE
9270    && (!avoiding_indexed_address_p (SImode)
9271        || !gpc_reg_operand (operands[2], Pmode))"
9272   "@
9273    lwzux %3,%0,%2
9274    lwzu %3,%2(%0)"
9275   [(set_attr "type" "load")
9276    (set_attr "update" "yes")
9277    (set_attr "indexed" "yes,no")])
9279 (define_insn "*movsi_update2"
9280   [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9281         (sign_extend:EXTSI
9282          (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9283                          (match_operand:P 2 "gpc_reg_operand" "r")))))
9284    (set (match_operand:P 0 "gpc_reg_operand" "=b")
9285         (plus:P (match_dup 1) (match_dup 2)))]
9286   "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9287   "lwaux %3,%0,%2"
9288   [(set_attr "type" "load")
9289    (set_attr "sign_extend" "yes")
9290    (set_attr "update" "yes")
9291    (set_attr "indexed" "yes")])
9293 (define_insn "movsi_<mode>_update"
9294   [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9295                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9296         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9297    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9298         (plus:P (match_dup 1) (match_dup 2)))]
9299   "TARGET_UPDATE
9300    && (!avoiding_indexed_address_p (SImode)
9301        || !gpc_reg_operand (operands[2], Pmode)
9302        || (REG_P (operands[0])
9303            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9304   "@
9305    stwux %3,%0,%2
9306    stwu %3,%2(%0)"
9307   [(set_attr "type" "store")
9308    (set_attr "update" "yes")
9309    (set_attr "indexed" "yes,no")])
9311 ;; This is an unconditional pattern; needed for stack allocation, even
9312 ;; if the user passes -mno-update.
9313 (define_insn "movsi_update_stack"
9314   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9315                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9316         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9317    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9318         (plus:SI (match_dup 1) (match_dup 2)))]
9319   "TARGET_32BIT"
9320   "@
9321    stwux %3,%0,%2
9322    stwu %3,%2(%0)"
9323   [(set_attr "type" "store")
9324    (set_attr "update" "yes")
9325    (set_attr "indexed" "yes,no")])
9327 (define_insn "*movhi_update1"
9328   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9329         (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9330                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9331    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9332         (plus:P (match_dup 1) (match_dup 2)))]
9333   "TARGET_UPDATE
9334    && (!avoiding_indexed_address_p (HImode)
9335        || !gpc_reg_operand (operands[2], SImode))"
9336   "@
9337    lhzux %3,%0,%2
9338    lhzu %3,%2(%0)"
9339   [(set_attr "type" "load")
9340    (set_attr "update" "yes")
9341    (set_attr "indexed" "yes,no")])
9343 (define_insn "*movhi_update2"
9344   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9345         (zero_extend:EXTHI
9346          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9347                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9348    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9349         (plus:P (match_dup 1) (match_dup 2)))]
9350   "TARGET_UPDATE
9351    && (!avoiding_indexed_address_p (HImode)
9352        || !gpc_reg_operand (operands[2], Pmode))"
9353   "@
9354    lhzux %3,%0,%2
9355    lhzu %3,%2(%0)"
9356   [(set_attr "type" "load")
9357    (set_attr "update" "yes")
9358    (set_attr "indexed" "yes,no")])
9360 (define_insn "*movhi_update3"
9361   [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9362         (sign_extend:EXTHI
9363          (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9364                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9365    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9366         (plus:P (match_dup 1) (match_dup 2)))]
9367   "TARGET_UPDATE
9368    && !(avoiding_indexed_address_p (HImode)
9369         && gpc_reg_operand (operands[2], Pmode))"
9370   "@
9371    lhaux %3,%0,%2
9372    lhau %3,%2(%0)"
9373   [(set_attr "type" "load")
9374    (set_attr "sign_extend" "yes")
9375    (set_attr "update" "yes")
9376    (set_attr "indexed" "yes,no")])
9378 (define_insn "*movhi_update4"
9379   [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9380                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9381         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9382    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9383         (plus:P (match_dup 1) (match_dup 2)))]
9384   "TARGET_UPDATE
9385    && (!avoiding_indexed_address_p (HImode)
9386        || !gpc_reg_operand (operands[2], Pmode))"
9387   "@
9388    sthux %3,%0,%2
9389    sthu %3,%2(%0)"
9390   [(set_attr "type" "store")
9391    (set_attr "update" "yes")
9392    (set_attr "indexed" "yes,no")])
9394 (define_insn "*movqi_update1"
9395   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9396         (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9397                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9398    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9399         (plus:P (match_dup 1) (match_dup 2)))]
9400   "TARGET_UPDATE
9401    && (!avoiding_indexed_address_p (QImode)
9402        || !gpc_reg_operand (operands[2], Pmode))"
9403   "@
9404    lbzux %3,%0,%2
9405    lbzu %3,%2(%0)"
9406   [(set_attr "type" "load")
9407    (set_attr "update" "yes")
9408    (set_attr "indexed" "yes,no")])
9410 (define_insn "*movqi_update2"
9411   [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9412         (zero_extend:EXTQI
9413          (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9414                          (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9415    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9416         (plus:P (match_dup 1) (match_dup 2)))]
9417   "TARGET_UPDATE
9418    && (!avoiding_indexed_address_p (QImode)
9419        || !gpc_reg_operand (operands[2], Pmode))"
9420   "@
9421    lbzux %3,%0,%2
9422    lbzu %3,%2(%0)"
9423   [(set_attr "type" "load")
9424    (set_attr "update" "yes")
9425    (set_attr "indexed" "yes,no")])
9427 (define_insn "*movqi_update3"
9428   [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9429                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9430         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9431    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9432         (plus:P (match_dup 1) (match_dup 2)))]
9433   "TARGET_UPDATE
9434    && (!avoiding_indexed_address_p (QImode)
9435        || !gpc_reg_operand (operands[2], Pmode))"
9436   "@
9437    stbux %3,%0,%2
9438    stbu %3,%2(%0)"
9439   [(set_attr "type" "store")
9440    (set_attr "update" "yes")
9441    (set_attr "indexed" "yes,no")])
9443 (define_insn "*mov<SFDF:mode>_update1"
9444   [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9445         (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9446                           (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9447    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9448         (plus:P (match_dup 1) (match_dup 2)))]
9449   "TARGET_HARD_FLOAT && TARGET_UPDATE
9450    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9451        || !gpc_reg_operand (operands[2], Pmode))"
9452   "@
9453    lf<sd>ux %3,%0,%2
9454    lf<sd>u %3,%2(%0)"
9455   [(set_attr "type" "fpload")
9456    (set_attr "update" "yes")
9457    (set_attr "indexed" "yes,no")
9458    (set_attr "size" "<SFDF:bits>")])
9460 (define_insn "*mov<SFDF:mode>_update2"
9461   [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9462                           (match_operand:P 2 "reg_or_short_operand" "r,I")))
9463         (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9464    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9465         (plus:P (match_dup 1) (match_dup 2)))]
9466   "TARGET_HARD_FLOAT && TARGET_UPDATE
9467    && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9468        || !gpc_reg_operand (operands[2], Pmode))"
9469   "@
9470    stf<sd>ux %3,%0,%2
9471    stf<sd>u %3,%2(%0)"
9472   [(set_attr "type" "fpstore")
9473    (set_attr "update" "yes")
9474    (set_attr "indexed" "yes,no")
9475    (set_attr "size" "<SFDF:bits>")])
9477 (define_insn "*movsf_update3"
9478   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9479         (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9480                         (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9481    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9482         (plus:P (match_dup 1) (match_dup 2)))]
9483   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9484    && (!avoiding_indexed_address_p (SFmode)
9485        || !gpc_reg_operand (operands[2], Pmode))"
9486   "@
9487    lwzux %3,%0,%2
9488    lwzu %3,%2(%0)"
9489   [(set_attr "type" "load")
9490    (set_attr "update" "yes")
9491    (set_attr "indexed" "yes,no")])
9493 (define_insn "*movsf_update4"
9494   [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9495                         (match_operand:P 2 "reg_or_short_operand" "r,I")))
9496         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9497    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9498         (plus:P (match_dup 1) (match_dup 2)))]
9499   "TARGET_SOFT_FLOAT && TARGET_UPDATE
9500    && (!avoiding_indexed_address_p (SFmode)
9501        || !gpc_reg_operand (operands[2], Pmode))"
9502   "@
9503    stwux %3,%0,%2
9504    stwu %3,%2(%0)"
9505   [(set_attr "type" "store")
9506    (set_attr "update" "yes")
9507    (set_attr "indexed" "yes,no")])
9510 ;; After inserting conditional returns we can sometimes have
9511 ;; unnecessary register moves.  Unfortunately we cannot have a
9512 ;; modeless peephole here, because some single SImode sets have early
9513 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
9514 ;; sequences, using get_attr_length here will smash the operands
9515 ;; array.  Neither is there an early_cobbler_p predicate.
9516 ;; Also this optimization interferes with scalars going into
9517 ;; altivec registers (the code does reloading through the FPRs).
9518 (define_peephole2
9519   [(set (match_operand:DF 0 "gpc_reg_operand")
9520         (match_operand:DF 1 "any_operand"))
9521    (set (match_operand:DF 2 "gpc_reg_operand")
9522         (match_dup 0))]
9523   "!TARGET_VSX
9524    && peep2_reg_dead_p (2, operands[0])"
9525   [(set (match_dup 2) (match_dup 1))])
9527 (define_peephole2
9528   [(set (match_operand:SF 0 "gpc_reg_operand")
9529         (match_operand:SF 1 "any_operand"))
9530    (set (match_operand:SF 2 "gpc_reg_operand")
9531         (match_dup 0))]
9532   "!TARGET_P8_VECTOR
9533    && peep2_reg_dead_p (2, operands[0])"
9534   [(set (match_dup 2) (match_dup 1))])
9537 ;; TLS support.
9539 (define_insn "*tls_gd_pcrel<bits>"
9540   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9541         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9542                    (const_int 0)]
9543                   UNSPEC_TLSGD))]
9544   "HAVE_AS_TLS && TARGET_ELF"
9545   "la %0,%1@got@tlsgd@pcrel"
9546   [(set_attr "prefixed" "yes")])
9548 (define_insn_and_split "*tls_gd<bits>"
9549   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9550         (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9551                    (match_operand:P 2 "gpc_reg_operand" "b")]
9552                   UNSPEC_TLSGD))]
9553   "HAVE_AS_TLS && TARGET_ELF"
9554   "addi %0,%2,%1@got@tlsgd"
9555   "&& TARGET_CMODEL != CMODEL_SMALL"
9556   [(set (match_dup 3)
9557         (high:P
9558             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9559    (set (match_dup 0)
9560         (lo_sum:P (match_dup 3)
9561             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9563   operands[3] = gen_reg_rtx (<MODE>mode);
9565   [(set (attr "length")
9566      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9567                    (const_int 8)
9568                    (const_int 4)))])
9570 (define_insn "*tls_gd_high<bits>"
9571   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9572      (high:P
9573        (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9574                   (match_operand:P 2 "gpc_reg_operand" "b")]
9575                  UNSPEC_TLSGD)))]
9576   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9577   "addis %0,%2,%1@got@tlsgd@ha")
9579 (define_insn "*tls_gd_low<bits>"
9580   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9581      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9582        (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9583                   (match_operand:P 3 "gpc_reg_operand" "b")]
9584                  UNSPEC_TLSGD)))]
9585   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9586   "addi %0,%1,%2@got@tlsgd@l")
9588 (define_insn "*tls_ld_pcrel<bits>"
9589   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9590         (unspec:P [(const_int 0)]
9591                   UNSPEC_TLSLD))]
9592   "HAVE_AS_TLS && TARGET_ELF"
9593   "la %0,%&@got@tlsld@pcrel"
9594   [(set_attr "prefixed" "yes")])
9596 (define_insn_and_split "*tls_ld<bits>"
9597   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9598         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9599                   UNSPEC_TLSLD))]
9600   "HAVE_AS_TLS && TARGET_ELF"
9601   "addi %0,%1,%&@got@tlsld"
9602   "&& TARGET_CMODEL != CMODEL_SMALL"
9603   [(set (match_dup 2)
9604         (high:P
9605             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9606    (set (match_dup 0)
9607         (lo_sum:P (match_dup 2)
9608             (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9610   operands[2] = gen_reg_rtx (<MODE>mode);
9612   [(set (attr "length")
9613      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9614                    (const_int 8)
9615                    (const_int 4)))])
9617 (define_insn "*tls_ld_high<bits>"
9618   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9619      (high:P
9620        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9621                  UNSPEC_TLSLD)))]
9622   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9623   "addis %0,%1,%&@got@tlsld@ha")
9625 (define_insn "*tls_ld_low<bits>"
9626   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9627      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9628        (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9629                  UNSPEC_TLSLD)))]
9630   "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9631   "addi %0,%1,%&@got@tlsld@l")
9633 (define_insn "tls_dtprel_<bits>"
9634   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9635         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9636                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9637                   UNSPEC_TLSDTPREL))]
9638   "HAVE_AS_TLS"
9639   "addi %0,%1,%2@dtprel"
9640   [(set (attr "prefixed")
9641         (if_then_else (match_test "rs6000_tls_size == 16")
9642                       (const_string "no")
9643                       (const_string "yes")))])
9645 (define_insn "tls_dtprel_ha_<bits>"
9646   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9647         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9648                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9649                   UNSPEC_TLSDTPRELHA))]
9650   "HAVE_AS_TLS"
9651   "addis %0,%1,%2@dtprel@ha")
9653 (define_insn "tls_dtprel_lo_<bits>"
9654   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9655         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9656                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9657                   UNSPEC_TLSDTPRELLO))]
9658   "HAVE_AS_TLS"
9659   "addi %0,%1,%2@dtprel@l")
9661 (define_insn_and_split "tls_got_dtprel_<bits>"
9662   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9663         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9664                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9665                   UNSPEC_TLSGOTDTPREL))]
9666   "HAVE_AS_TLS"
9667   "<ptrload> %0,%2@got@dtprel(%1)"
9668   "&& TARGET_CMODEL != CMODEL_SMALL"
9669   [(set (match_dup 3)
9670         (high:P
9671             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9672    (set (match_dup 0)
9673         (lo_sum:P (match_dup 3)
9674             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9676   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9678   [(set (attr "length")
9679      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9680                    (const_int 8)
9681                    (const_int 4)))])
9683 (define_insn "*tls_got_dtprel_high<bits>"
9684   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9685      (high:P
9686        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9687                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9688                  UNSPEC_TLSGOTDTPREL)))]
9689   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9690   "addis %0,%1,%2@got@dtprel@ha")
9692 (define_insn "*tls_got_dtprel_low<bits>"
9693   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9694      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9695          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9696                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9697                    UNSPEC_TLSGOTDTPREL)))]
9698   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9699   "<ptrload> %0,%2@got@dtprel@l(%1)")
9701 (define_insn "tls_tprel_<bits>"
9702   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9703         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9704                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9705                   UNSPEC_TLSTPREL))]
9706   "HAVE_AS_TLS"
9707   "addi %0,%1,%2@tprel"
9708   [(set (attr "prefixed")
9709         (if_then_else (match_test "rs6000_tls_size == 16")
9710                       (const_string "no")
9711                       (const_string "yes")))])
9713 (define_insn "tls_tprel_ha_<bits>"
9714   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9715         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9716                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9717                   UNSPEC_TLSTPRELHA))]
9718   "HAVE_AS_TLS"
9719   "addis %0,%1,%2@tprel@ha")
9721 (define_insn "tls_tprel_lo_<bits>"
9722   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9723         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9724                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9725                   UNSPEC_TLSTPRELLO))]
9726   "HAVE_AS_TLS"
9727   "addi %0,%1,%2@tprel@l")
9729 (define_insn "*tls_got_tprel_pcrel_<bits>"
9730   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9731         (unspec:P [(const_int 0)
9732                    (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9733                   UNSPEC_TLSGOTTPREL))]
9734   "HAVE_AS_TLS"
9735   "<ptrload> %0,%1@got@tprel@pcrel"
9736   [(set_attr "prefixed" "yes")])
9738 ;; "b" output constraint here and on tls_tls input to support linker tls
9739 ;; optimization.  The linker may edit the instructions emitted by a
9740 ;; tls_got_tprel/tls_tls pair to addis,addi.
9741 (define_insn_and_split "tls_got_tprel_<bits>"
9742   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9743         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9744                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9745                   UNSPEC_TLSGOTTPREL))]
9746   "HAVE_AS_TLS"
9747   "<ptrload> %0,%2@got@tprel(%1)"
9748   "&& TARGET_CMODEL != CMODEL_SMALL"
9749   [(set (match_dup 3)
9750         (high:P
9751             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9752    (set (match_dup 0)
9753         (lo_sum:P (match_dup 3)
9754             (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9756   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9758   [(set (attr "length")
9759      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9760                    (const_int 8)
9761                    (const_int 4)))])
9763 (define_insn "*tls_got_tprel_high<bits>"
9764   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9765      (high:P
9766        (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9767                   (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9768                  UNSPEC_TLSGOTTPREL)))]
9769   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9770   "addis %0,%1,%2@got@tprel@ha")
9772 (define_insn "*tls_got_tprel_low<bits>"
9773   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9774      (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9775          (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9776                     (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9777                    UNSPEC_TLSGOTTPREL)))]
9778   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9779   "<ptrload> %0,%2@got@tprel@l(%1)")
9781 (define_insn "tls_tls_pcrel_<bits>"
9782   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9783         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9784                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9785                   UNSPEC_TLSTLS_PCREL))]
9786   "TARGET_ELF && HAVE_AS_TLS"
9787   "add %0,%1,%2@tls@pcrel")
9789 (define_insn "tls_tls_<bits>"
9790   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9791         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9792                    (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9793                   UNSPEC_TLSTLS))]
9794   "TARGET_ELF && HAVE_AS_TLS"
9795   "add %0,%1,%2@tls")
9797 (define_expand "tls_get_tpointer"
9798   [(set (match_operand:SI 0 "gpc_reg_operand")
9799         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9800   "TARGET_XCOFF && HAVE_AS_TLS"
9802   emit_insn (gen_tls_get_tpointer_internal ());
9803   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9804   DONE;
9807 (define_insn "tls_get_tpointer_internal"
9808   [(set (reg:SI 3)
9809         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9810    (clobber (reg:SI LR_REGNO))]
9811   "TARGET_XCOFF && HAVE_AS_TLS"
9812   "bla __get_tpointer")
9814 (define_expand "tls_get_addr<mode>"
9815   [(set (match_operand:P 0 "gpc_reg_operand")
9816         (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9817                    (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9818   "TARGET_XCOFF && HAVE_AS_TLS"
9820   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9821   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9822   emit_insn (gen_tls_get_addr_internal<mode> ());
9823   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9824   DONE;
9827 (define_insn "tls_get_addr_internal<mode>"
9828   [(set (reg:P 3)
9829         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9830    (clobber (reg:P 0))
9831    (clobber (reg:P 4))
9832    (clobber (reg:P 5))
9833    (clobber (reg:P 11))
9834    (clobber (reg:CC CR0_REGNO))
9835    (clobber (reg:P LR_REGNO))]
9836   "TARGET_XCOFF && HAVE_AS_TLS"
9837   "bla __tls_get_addr")
9839 ;; Next come insns related to the calling sequence.
9841 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9842 ;; We move the back-chain and decrement the stack pointer.
9844 ;; Operand1 is more naturally reg_or_short_operand.  However, for a large
9845 ;; constant alloca, using that predicate will force the generic code to put
9846 ;; the constant size into a register before calling the expander.
9848 ;; As a result the expander would not have the constant size information
9849 ;; in those cases and would have to generate less efficient code.
9851 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9852 ;; the constant size.  The value is forced into a register if necessary.
9854 (define_expand "allocate_stack"
9855   [(set (match_operand 0 "gpc_reg_operand")
9856         (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9857    (set (reg 1)
9858         (minus (reg 1) (match_dup 1)))]
9859   ""
9861   rtx chain = gen_reg_rtx (Pmode);
9862   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9863   rtx neg_op0;
9864   rtx insn, par, set, mem;
9866   /* By allowing reg_or_cint_operand as the predicate we can get
9867      better code for stack-clash-protection because we do not lose
9868      size information.  But the rest of the code expects the operand
9869      to be reg_or_short_operand.  If it isn't, then force it into
9870      a register.  */
9871   rtx orig_op1 = operands[1];
9872   if (!reg_or_short_operand (operands[1], Pmode))
9873     operands[1] = force_reg (Pmode, operands[1]);
9875   emit_move_insn (chain, stack_bot);
9877   /* Check stack bounds if necessary.  */
9878   if (crtl->limit_stack)
9879     {
9880       rtx available;
9881       available = expand_binop (Pmode, sub_optab,
9882                                 stack_pointer_rtx, stack_limit_rtx,
9883                                 NULL_RTX, 1, OPTAB_WIDEN);
9884       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9885     }
9887   /* Allocate and probe if requested.
9888      This may look similar to the loop we use for prologue allocations,
9889      but it is critically different.  For the former we know the loop
9890      will iterate, but do not know that generally here.  The former
9891      uses that knowledge to rotate the loop.  Combining them would be
9892      possible with some performance cost.  */
9893   if (flag_stack_clash_protection)
9894     {
9895       rtx rounded_size, last_addr, residual;
9896       HOST_WIDE_INT probe_interval;
9897       compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9898                                                 &residual, &probe_interval,
9899                                                 orig_op1);
9900       
9901       /* We do occasionally get in here with constant sizes, we might
9902          as well do a reasonable job when we obviously can.  */
9903       if (rounded_size != const0_rtx)
9904         {
9905           rtx loop_lab, end_loop;
9906           bool rotated = CONST_INT_P (rounded_size);
9907           rtx update = GEN_INT (-probe_interval);
9908           if (probe_interval > 32768)
9909             update = force_reg (Pmode, update);
9911           emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9912                                                         last_addr, rotated);
9914           if (TARGET_32BIT)
9915             emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9916                                                stack_pointer_rtx,
9917                                                update, chain));
9918           else
9919             emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9920                                                stack_pointer_rtx,
9921                                                update, chain));
9922           emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9923                                                       last_addr, rotated);
9924         }
9926       /* Now handle residuals.  We just have to set operands[1] correctly
9927          and let the rest of the expander run.  */
9928       operands[1] = residual;
9929     }
9931   if (!(CONST_INT_P (operands[1])
9932         && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9933     {
9934       operands[1] = force_reg (Pmode, operands[1]);
9935       neg_op0 = gen_reg_rtx (Pmode);
9936       emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9937     }
9938   else
9939     neg_op0 = GEN_INT (-INTVAL (operands[1]));
9941   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9942                                        : gen_movdi_update_stack))
9943                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9944                          chain));
9945   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9946      it now and set the alias set/attributes. The above gen_*_update
9947      calls will generate a PARALLEL with the MEM set being the first
9948      operation. */
9949   par = PATTERN (insn);
9950   gcc_assert (GET_CODE (par) == PARALLEL);
9951   set = XVECEXP (par, 0, 0);
9952   gcc_assert (GET_CODE (set) == SET);
9953   mem = SET_DEST (set);
9954   gcc_assert (MEM_P (mem));
9955   MEM_NOTRAP_P (mem) = 1;
9956   set_mem_alias_set (mem, get_frame_alias_set ());
9958   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9959   DONE;
9962 ;; These patterns say how to save and restore the stack pointer.  We need not
9963 ;; save the stack pointer at function level since we are careful to
9964 ;; preserve the backchain.  At block level, we have to restore the backchain
9965 ;; when we restore the stack pointer.
9967 ;; For nonlocal gotos, we must save both the stack pointer and its
9968 ;; backchain and restore both.  Note that in the nonlocal case, the
9969 ;; save area is a memory location.
9971 (define_expand "save_stack_function"
9972   [(match_operand 0 "any_operand")
9973    (match_operand 1 "any_operand")]
9974   ""
9975   "DONE;")
9977 (define_expand "restore_stack_function"
9978   [(match_operand 0 "any_operand")
9979    (match_operand 1 "any_operand")]
9980   ""
9981   "DONE;")
9983 ;; Adjust stack pointer (op0) to a new value (op1).
9984 ;; First copy old stack backchain to new location, and ensure that the
9985 ;; scheduler won't reorder the sp assignment before the backchain write.
9986 (define_expand "restore_stack_block"
9987   [(set (match_dup 2) (match_dup 3))
9988    (set (match_dup 4) (match_dup 2))
9989    (match_dup 5)
9990    (set (match_operand 0 "register_operand")
9991         (match_operand 1 "register_operand"))]
9992   ""
9994   rtvec p;
9996   operands[1] = force_reg (Pmode, operands[1]);
9997   operands[2] = gen_reg_rtx (Pmode);
9998   operands[3] = gen_frame_mem (Pmode, operands[0]);
9999   operands[4] = gen_frame_mem (Pmode, operands[1]);
10000   p = rtvec_alloc (1);
10001   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10002                                   const0_rtx);
10003   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10006 (define_expand "save_stack_nonlocal"
10007   [(set (match_dup 3) (match_dup 4))
10008    (set (match_operand 0 "memory_operand") (match_dup 3))
10009    (set (match_dup 2) (match_operand 1 "register_operand"))]
10010   ""
10012   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10014   /* Copy the backchain to the first word, sp to the second.  */
10015   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10016   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10017   operands[3] = gen_reg_rtx (Pmode);
10018   operands[4] = gen_frame_mem (Pmode, operands[1]);
10021 (define_expand "restore_stack_nonlocal"
10022   [(set (match_dup 2) (match_operand 1 "memory_operand"))
10023    (set (match_dup 3) (match_dup 4))
10024    (set (match_dup 5) (match_dup 2))
10025    (match_dup 6)
10026    (set (match_operand 0 "register_operand") (match_dup 3))]
10027   ""
10029   int units_per_word = (TARGET_32BIT) ? 4 : 8;
10030   rtvec p;
10032   /* Restore the backchain from the first word, sp from the second.  */
10033   operands[2] = gen_reg_rtx (Pmode);
10034   operands[3] = gen_reg_rtx (Pmode);
10035   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10036   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10037   operands[5] = gen_frame_mem (Pmode, operands[3]);
10038   p = rtvec_alloc (1);
10039   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10040                                   const0_rtx);
10041   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10044 ;; Load up a PC-relative address.  Print_operand_address will append a @pcrel
10045 ;; to the symbol or label.
10046 (define_insn "*pcrel_local_addr"
10047   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10048         (match_operand:DI 1 "pcrel_local_address"))]
10049   "TARGET_PCREL"
10050   "la %0,%a1"
10051   [(set_attr "prefixed" "yes")])
10053 ;; Load up a PC-relative address to an external symbol.  If the symbol and the
10054 ;; program are both defined in the main program, the linker will optimize this
10055 ;; to a PADDI.  Otherwise, it will create a GOT address that is relocated by
10056 ;; the dynamic linker and loaded up.  Print_operand_address will append a
10057 ;; @got@pcrel to the symbol.
10058 (define_insn "*pcrel_extern_addr"
10059   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10060         (match_operand:DI 1 "pcrel_external_address"))]
10061   "TARGET_PCREL"
10062   "ld %0,%a1"
10063   [(set_attr "prefixed" "yes")
10064    (set_attr "type" "load")])
10066 ;; TOC register handling.
10068 ;; Code to initialize the TOC register...
10070 (define_insn "load_toc_aix_si"
10071   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10072                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
10073               (use (reg:SI 2))])]
10074   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10076   char buf[30];
10077   extern int need_toc_init;
10078   need_toc_init = 1;
10079   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10080   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10081   operands[2] = gen_rtx_REG (Pmode, 2);
10082   return "lwz %0,%1(%2)";
10084   [(set_attr "type" "load")
10085    (set_attr "update" "no")
10086    (set_attr "indexed" "no")])
10088 (define_insn "load_toc_aix_di"
10089   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10090                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
10091               (use (reg:DI 2))])]
10092   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10094   char buf[30];
10095   extern int need_toc_init;
10096   need_toc_init = 1;
10097   ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10098                                !TARGET_ELF || !TARGET_MINIMAL_TOC);
10099   if (TARGET_ELF)
10100     strcat (buf, "@toc");
10101   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10102   operands[2] = gen_rtx_REG (Pmode, 2);
10103   return "ld %0,%1(%2)";
10105   [(set_attr "type" "load")
10106    (set_attr "update" "no")
10107    (set_attr "indexed" "no")])
10109 (define_insn "load_toc_v4_pic_si"
10110   [(set (reg:SI LR_REGNO)
10111         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10112   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10113   "bl _GLOBAL_OFFSET_TABLE_@local-4"
10114   [(set_attr "type" "branch")])
10116 (define_expand "load_toc_v4_PIC_1"
10117   [(parallel [(set (reg:SI LR_REGNO)
10118                    (match_operand:SI 0 "immediate_operand" "s"))
10119               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10120   "TARGET_ELF && DEFAULT_ABI == ABI_V4
10121    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10122   "")
10124 (define_insn "load_toc_v4_PIC_1_normal"
10125   [(set (reg:SI LR_REGNO)
10126         (match_operand:SI 0 "immediate_operand" "s"))
10127    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10128   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10129    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10130   "bcl 20,31,%0\n%0:"
10131   [(set_attr "type" "branch")
10132    (set_attr "cannot_copy" "yes")])
10134 (define_insn "load_toc_v4_PIC_1_476"
10135   [(set (reg:SI LR_REGNO)
10136         (match_operand:SI 0 "immediate_operand" "s"))
10137    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10138   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10139    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10141   char name[32];
10142   static char templ[32];
10144   get_ppc476_thunk_name (name);
10145   sprintf (templ, "bl %s\n%%0:", name);
10146   return templ;
10148   [(set_attr "type" "branch")
10149    (set_attr "cannot_copy" "yes")])
10151 (define_expand "load_toc_v4_PIC_1b"
10152   [(parallel [(set (reg:SI LR_REGNO)
10153                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10154                                (label_ref (match_operand 1 ""))]
10155                            UNSPEC_TOCPTR))
10156               (match_dup 1)])]
10157   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10158   "")
10160 (define_insn "load_toc_v4_PIC_1b_normal"
10161   [(set (reg:SI LR_REGNO)
10162         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10163                     (label_ref (match_operand 1 "" ""))]
10164                 UNSPEC_TOCPTR))
10165    (match_dup 1)]
10166   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10167   "bcl 20,31,$+8\;.long %0-$"
10168   [(set_attr "type" "branch")
10169    (set_attr "length" "8")])
10171 (define_insn "load_toc_v4_PIC_1b_476"
10172   [(set (reg:SI LR_REGNO)
10173         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10174                     (label_ref (match_operand 1 "" ""))]
10175                 UNSPEC_TOCPTR))
10176    (match_dup 1)]
10177   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10179   char name[32];
10180   static char templ[32];
10182   get_ppc476_thunk_name (name);
10183   sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10184   return templ;
10186   [(set_attr "type" "branch")
10187    (set_attr "length" "16")])
10189 (define_insn "load_toc_v4_PIC_2"
10190   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10191         (mem:SI (plus:SI
10192                   (match_operand:SI 1 "gpc_reg_operand" "b")
10193                   (const
10194                     (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10195                               (match_operand:SI 3 "immediate_operand" "s"))))))]
10196   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10197   "lwz %0,%2-%3(%1)"
10198   [(set_attr "type" "load")])
10200 (define_insn "load_toc_v4_PIC_3b"
10201   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10202         (plus:SI
10203           (match_operand:SI 1 "gpc_reg_operand" "b")
10204           (high:SI
10205             (const
10206               (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10207                         (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10208   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10209   "addis %0,%1,%2-%3@ha")
10211 (define_insn "load_toc_v4_PIC_3c"
10212   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10213         (lo_sum:SI
10214           (match_operand:SI 1 "gpc_reg_operand" "b")
10215           (const
10216             (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10217                       (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10218   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10219   "addi %0,%1,%2-%3@l")
10221 ;; If the TOC is shared over a translation unit, as happens with all
10222 ;; the kinds of PIC that we support, we need to restore the TOC
10223 ;; pointer only when jumping over units of translation.
10224 ;; On Darwin, we need to reload the picbase.
10226 (define_expand "builtin_setjmp_receiver"
10227   [(use (label_ref (match_operand 0 "")))]
10228   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10229    || (TARGET_TOC && TARGET_MINIMAL_TOC)
10230    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10232 #if TARGET_MACHO
10233   if (DEFAULT_ABI == ABI_DARWIN)
10234     {
10235       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10236       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10237       rtx tmplabrtx;
10238       char tmplab[20];
10240       crtl->uses_pic_offset_table = 1;
10241       ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10242                                   CODE_LABEL_NUMBER (operands[0]));
10243       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10245       emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10246       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10247       emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10248                                         picrtx, tmplabrtx));
10249     }
10250   else
10251 #endif
10252     rs6000_emit_load_toc_table (FALSE);
10253   DONE;
10256 ;; Largetoc support
10257 (define_insn "*largetoc_high"
10258   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10259         (high:DI
10260           (unspec [(match_operand:DI 1 "" "")
10261                    (match_operand:DI 2 "gpc_reg_operand" "b")]
10262                   UNSPEC_TOCREL)))]
10263    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10264    "addis %0,%2,%1@toc@ha")
10266 (define_insn "*largetoc_high_aix<mode>"
10267   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10268         (high:P
10269           (unspec [(match_operand:P 1 "" "")
10270                    (match_operand:P 2 "gpc_reg_operand" "b")]
10271                   UNSPEC_TOCREL)))]
10272    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10273    "addis %0,%1@u(%2)")
10275 (define_insn "*largetoc_high_plus"
10276   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10277         (high:DI
10278           (plus:DI
10279             (unspec [(match_operand:DI 1 "" "")
10280                      (match_operand:DI 2 "gpc_reg_operand" "b")]
10281                     UNSPEC_TOCREL)
10282             (match_operand:DI 3 "add_cint_operand" "n"))))]
10283    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10284    "addis %0,%2,%1+%3@toc@ha")
10286 (define_insn "*largetoc_high_plus_aix<mode>"
10287   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10288         (high:P
10289           (plus:P
10290             (unspec [(match_operand:P 1 "" "")
10291                      (match_operand:P 2 "gpc_reg_operand" "b")]
10292                     UNSPEC_TOCREL)
10293             (match_operand:P 3 "add_cint_operand" "n"))))]
10294    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10295    "addis %0,%1+%3@u(%2)")
10297 (define_insn "*largetoc_low"
10298   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10299         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10300                    (match_operand:DI 2 "" "")))]
10301    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10302    "addi %0,%1,%2@l")
10304 (define_insn "*largetoc_low_aix<mode>"
10305   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10306         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10307                    (match_operand:P 2 "" "")))]
10308    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10309    "la %0,%2@l(%1)")
10311 (define_insn_and_split "*tocref<mode>"
10312   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10313         (match_operand:P 1 "small_toc_ref" "R"))]
10314    "TARGET_TOC
10315     && legitimate_constant_pool_address_p (operands[1], QImode, false)"
10316    "la %0,%a1"
10317    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10318   [(set (match_dup 0) (high:P (match_dup 1)))
10319    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10321 ;; Elf specific ways of loading addresses for non-PIC code.
10322 ;; The output of this could be r0, but we make a very strong
10323 ;; preference for a base register because it will usually
10324 ;; be needed there.
10325 (define_insn "elf_high"
10326   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10327         (high:SI (match_operand 1 "" "")))]
10328   "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10329   "lis %0,%1@ha")
10331 (define_insn "elf_low"
10332   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10333         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10334                    (match_operand 2 "" "")))]
10335    "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10336    "la %0,%2@l(%1)")
10338 (define_insn "*pltseq_tocsave_<mode>"
10339   [(set (match_operand:P 0 "memory_operand" "=m")
10340         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10341                    (match_operand:P 2 "symbol_ref_operand" "s")
10342                    (match_operand:P 3 "" "")]
10343                   UNSPEC_PLTSEQ))]
10344   "TARGET_PLTSEQ
10345    && DEFAULT_ABI == ABI_ELFv2"
10347   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10350 (define_insn "*pltseq_plt16_ha_<mode>"
10351   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10352         (unspec:P [(match_operand:P 1 "" "")
10353                    (match_operand:P 2 "symbol_ref_operand" "s")
10354                    (match_operand:P 3 "" "")]
10355                   UNSPEC_PLT16_HA))]
10356   "TARGET_PLTSEQ"
10358   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10361 (define_insn "*pltseq_plt16_lo_<mode>"
10362   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10363         (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
10364                             (match_operand:P 2 "symbol_ref_operand" "s")
10365                             (match_operand:P 3 "" "")]
10366                            UNSPECV_PLT16_LO))]
10367   "TARGET_PLTSEQ"
10369   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10371   [(set_attr "type" "load")])
10373 (define_insn "*pltseq_mtctr_<mode>"
10374   [(set (match_operand:P 0 "register_operand" "=c")
10375         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10376                    (match_operand:P 2 "symbol_ref_operand" "s")
10377                    (match_operand:P 3 "" "")]
10378                   UNSPEC_PLTSEQ))]
10379   "TARGET_PLTSEQ"
10381   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10384 (define_insn "*pltseq_plt_pcrel<mode>"
10385   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10386         (unspec_volatile:P [(match_operand:P 1 "" "")
10387                             (match_operand:P 2 "symbol_ref_operand" "s")
10388                             (match_operand:P 3 "" "")]
10389                            UNSPECV_PLT_PCREL))]
10390   "HAVE_AS_PLTSEQ && TARGET_ELF
10391    && rs6000_pcrel_p (cfun)"
10393   return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10395   [(set_attr "type" "load")
10396    (set_attr "length" "12")])
10398 ;; Call and call_value insns
10399 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10400 (define_expand "call"
10401   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10402                     (match_operand 1 ""))
10403               (use (match_operand 2 ""))
10404               (clobber (reg:SI LR_REGNO))])]
10405   ""
10407 #if TARGET_MACHO
10408   if (MACHOPIC_INDIRECT)
10409     operands[0] = machopic_indirect_call_target (operands[0]);
10410 #endif
10412   gcc_assert (MEM_P (operands[0]));
10414   operands[0] = XEXP (operands[0], 0);
10416   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10417     rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10418   else if (DEFAULT_ABI == ABI_V4)
10419     rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10420   else if (DEFAULT_ABI == ABI_DARWIN)
10421     rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10422   else
10423     gcc_unreachable ();
10425   DONE;
10428 (define_expand "call_value"
10429   [(parallel [(set (match_operand 0 "")
10430                    (call (mem:SI (match_operand 1 "address_operand"))
10431                          (match_operand 2 "")))
10432               (use (match_operand 3 ""))
10433               (clobber (reg:SI LR_REGNO))])]
10434   ""
10436 #if TARGET_MACHO
10437   if (MACHOPIC_INDIRECT)
10438     operands[1] = machopic_indirect_call_target (operands[1]);
10439 #endif
10441   gcc_assert (MEM_P (operands[1]));
10443   operands[1] = XEXP (operands[1], 0);
10445   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10446     rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10447   else if (DEFAULT_ABI == ABI_V4)
10448     rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10449   else if (DEFAULT_ABI == ABI_DARWIN)
10450     rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10451   else
10452     gcc_unreachable ();
10454   DONE;
10457 ;; Call to function in current module.  No TOC pointer reload needed.
10458 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10459 ;; either the function was not prototyped, or it was prototyped as a
10460 ;; variable argument function.  It is > 0 if FP registers were passed
10461 ;; and < 0 if they were not.
10463 (define_insn "*call_local<mode>"
10464   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
10465          (match_operand 1))
10466    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10467    (clobber (reg:P LR_REGNO))]
10468   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10470   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10471     output_asm_insn ("crxor 6,6,6", operands);
10473   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10474     output_asm_insn ("creqv 6,6,6", operands);
10476   if (rs6000_pcrel_p (cfun))
10477     return "bl %z0@notoc";
10478   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10480   [(set_attr "type" "branch")
10481    (set_attr "length" "4,8")])
10483 (define_insn "*call_value_local<mode>"
10484   [(set (match_operand 0 "" "")
10485         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
10486               (match_operand 2)))
10487    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10488    (clobber (reg:P LR_REGNO))]
10489   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10491   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10492     output_asm_insn ("crxor 6,6,6", operands);
10494   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10495     output_asm_insn ("creqv 6,6,6", operands);
10497   if (rs6000_pcrel_p (cfun))
10498     return "bl %z1@notoc";
10499   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10501   [(set_attr "type" "branch")
10502    (set_attr "length" "4,8")])
10505 ;; A function pointer under System V is just a normal pointer
10506 ;; operands[0] is the function pointer
10507 ;; operands[1] is the tls call arg
10508 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10509 ;; which indicates how to set cr1
10511 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10512   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10513          (match_operand 1))
10514    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10515    (clobber (reg:P LR_REGNO))]
10516   "DEFAULT_ABI == ABI_V4
10517    || DEFAULT_ABI == ABI_DARWIN"
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_indirect_call_template (operands, 0);
10527   [(set_attr "type" "jmpreg")
10528    (set (attr "length")
10529         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10530                          (match_test "which_alternative != 1"))
10531                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10532                   (const_string "12")
10533                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10534                          (match_test "which_alternative != 1"))
10535                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10536                   (const_string "8")]
10537               (const_string "4")))])
10539 (define_insn "*call_nonlocal_sysv<mode>"
10540   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10541          (match_operand 1))
10542    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10543    (clobber (reg:P LR_REGNO))]
10544   "(DEFAULT_ABI == ABI_DARWIN
10545    || (DEFAULT_ABI == ABI_V4
10546        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10548   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10549     output_asm_insn ("crxor 6,6,6", operands);
10551   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10552     output_asm_insn ("creqv 6,6,6", operands);
10554   return rs6000_call_template (operands, 0);
10556   [(set_attr "type" "branch,branch")
10557    (set_attr "length" "4,8")])
10559 (define_insn "*call_nonlocal_sysv_secure<mode>"
10560   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10561          (match_operand 1))
10562    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10563    (use (match_operand:SI 3 "register_operand" "r,r"))
10564    (clobber (reg:P LR_REGNO))]
10565   "(DEFAULT_ABI == ABI_V4
10566     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10567     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10569   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10570     output_asm_insn ("crxor 6,6,6", operands);
10572   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10573     output_asm_insn ("creqv 6,6,6", operands);
10575   return rs6000_call_template (operands, 0);
10577   [(set_attr "type" "branch,branch")
10578    (set_attr "length" "4,8")])
10580 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10581   [(set (match_operand 0 "" "")
10582         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10583               (match_operand:P 2 "unspec_tls" "")))
10584    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10585    (clobber (reg:P LR_REGNO))]
10586   "DEFAULT_ABI == ABI_V4
10587    || DEFAULT_ABI == ABI_DARWIN"
10589   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10590     output_asm_insn ("crxor 6,6,6", operands);
10592   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10593     output_asm_insn ("creqv 6,6,6", operands);
10595   return rs6000_indirect_call_template (operands, 1);
10597   [(set_attr "type" "jmpreg")
10598    (set (attr "length")
10599         (plus
10600           (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10601             (const_int 4)
10602             (const_int 0))
10603           (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10604                              (match_test "which_alternative != 1"))
10605             (const_int 8)
10606             (const_int 4))))])
10608 (define_insn "*call_value_nonlocal_sysv<mode>"
10609   [(set (match_operand 0 "" "")
10610         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10611               (match_operand:P 2 "unspec_tls" "")))
10612    (use (match_operand:SI 3 "immediate_operand" "n"))
10613    (clobber (reg:P LR_REGNO))]
10614   "(DEFAULT_ABI == ABI_DARWIN
10615     || (DEFAULT_ABI == ABI_V4
10616         && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10618   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10619     output_asm_insn ("crxor 6,6,6", operands);
10621   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10622     output_asm_insn ("creqv 6,6,6", operands);
10624   return rs6000_call_template (operands, 1);
10626   [(set_attr "type" "branch")
10627    (set (attr "length")
10628         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10629           (const_int 8)
10630           (const_int 4)))])
10632 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10633   [(set (match_operand 0 "" "")
10634         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10635               (match_operand:P 2 "unspec_tls" "")))
10636    (use (match_operand:SI 3 "immediate_operand" "n"))
10637    (use (match_operand:SI 4 "register_operand" "r"))
10638    (clobber (reg:P LR_REGNO))]
10639   "(DEFAULT_ABI == ABI_V4
10640     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10641     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10643   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10644     output_asm_insn ("crxor 6,6,6", operands);
10646   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10647     output_asm_insn ("creqv 6,6,6", operands);
10649   return rs6000_call_template (operands, 1);
10651   [(set_attr "type" "branch")
10652    (set (attr "length")
10653         (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10654           (const_int 8)
10655           (const_int 4)))])
10657 ;; Call to AIX abi function which may be in another module.
10658 ;; Restore the TOC pointer (r2) after the call.
10660 (define_insn "*call_nonlocal_aix<mode>"
10661   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10662          (match_operand 1))
10663    (use (match_operand:SI 2 "immediate_operand" "n"))
10664    (clobber (reg:P LR_REGNO))]
10665   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10666    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10668   return rs6000_call_template (operands, 0);
10670   [(set_attr "type" "branch")
10671    (set (attr "length")
10672         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10673           (const_int 4)
10674           (const_int 8)))])
10676 (define_insn "*call_value_nonlocal_aix<mode>"
10677   [(set (match_operand 0 "" "")
10678         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10679               (match_operand:P 2 "unspec_tls" "")))
10680    (use (match_operand:SI 3 "immediate_operand" "n"))
10681    (clobber (reg:P LR_REGNO))]
10682   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10683    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10685   return rs6000_call_template (operands, 1);
10687   [(set_attr "type" "branch")
10688    (set (attr "length")
10689         (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10690             (const_int 4)
10691             (const_int 8)))])
10693 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10694 ;; Operand0 is the addresss of the function to call
10695 ;; Operand3 is the location in the function descriptor to load r2 from
10696 ;; Operand4 is the offset of the stack location holding the current TOC pointer
10698 (define_insn "*call_indirect_aix<mode>"
10699   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10700          (match_operand 1))
10701    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10702    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10703    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10704    (clobber (reg:P LR_REGNO))]
10705   "DEFAULT_ABI == ABI_AIX"
10707   return rs6000_indirect_call_template (operands, 0);
10709   [(set_attr "type" "jmpreg")
10710    (set (attr "length")
10711         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10712                            (match_test "which_alternative != 1"))
10713                       (const_string "16")
10714                       (const_string "12")))])
10716 (define_insn "*call_value_indirect_aix<mode>"
10717   [(set (match_operand 0 "" "")
10718         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10719               (match_operand:P 2 "unspec_tls" "")))
10720    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10721    (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10722    (set (reg:P TOC_REGNUM)
10723         (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
10724                   UNSPEC_TOCSLOT))
10725    (clobber (reg:P LR_REGNO))]
10726   "DEFAULT_ABI == ABI_AIX"
10728   return rs6000_indirect_call_template (operands, 1);
10730   [(set_attr "type" "jmpreg")
10731    (set (attr "length")
10732         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10733                            (match_test "which_alternative != 1"))
10734             (const_string "16")
10735             (const_string "12")))])
10737 ;; Call to indirect functions with the ELFv2 ABI.
10738 ;; Operand0 is the addresss of the function to call
10739 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10741 (define_insn "*call_indirect_elfv2<mode>"
10742   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10743          (match_operand 1))
10744    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10745    (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10746    (clobber (reg:P LR_REGNO))]
10747   "DEFAULT_ABI == ABI_ELFv2"
10749   return rs6000_indirect_call_template (operands, 0);
10751   [(set_attr "type" "jmpreg")
10752    (set (attr "length")
10753         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10754                            (match_test "which_alternative != 1"))
10755                       (const_string "12")
10756                       (const_string "8")))])
10758 (define_insn "*call_indirect_pcrel<mode>"
10759   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10760          (match_operand 1))
10761    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10762    (clobber (reg:P LR_REGNO))]
10763   "rs6000_pcrel_p (cfun)"
10765   return rs6000_indirect_call_template (operands, 0);
10767   [(set_attr "type" "jmpreg")
10768    (set (attr "length")
10769         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10770                            (match_test "which_alternative != 1"))
10771                       (const_string "8")
10772                       (const_string "4")))])
10774 (define_insn "*call_value_indirect_elfv2<mode>"
10775   [(set (match_operand 0 "" "")
10776         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10777               (match_operand:P 2 "unspec_tls" "")))
10778    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10779    (set (reg:P TOC_REGNUM)
10780         (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10781                   UNSPEC_TOCSLOT))
10782    (clobber (reg:P LR_REGNO))]
10783   "DEFAULT_ABI == ABI_ELFv2"
10785   return rs6000_indirect_call_template (operands, 1);
10787   [(set_attr "type" "jmpreg")
10788    (set (attr "length")
10789         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10790                            (match_test "which_alternative != 1"))
10791             (const_string "12")
10792             (const_string "8")))])
10794 (define_insn "*call_value_indirect_pcrel<mode>"
10795   [(set (match_operand 0 "" "")
10796         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10797               (match_operand:P 2 "unspec_tls" "")))
10798    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10799    (clobber (reg:P LR_REGNO))]
10800   "rs6000_pcrel_p (cfun)"
10802   return rs6000_indirect_call_template (operands, 1);
10804   [(set_attr "type" "jmpreg")
10805    (set (attr "length")
10806         (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10807                            (match_test "which_alternative != 1"))
10808             (const_string "8")
10809             (const_string "4")))])
10811 ;; Call subroutine returning any type.
10812 (define_expand "untyped_call"
10813   [(parallel [(call (match_operand 0 "")
10814                     (const_int 0))
10815               (match_operand 1 "")
10816               (match_operand 2 "")])]
10817   ""
10819   int i;
10821   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10823   for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10824     emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
10825   emit_insn (gen_blockage ());
10827   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10828     {
10829       rtx set = XVECEXP (operands[2], 0, i);
10830       emit_move_insn (SET_DEST (set), SET_SRC (set));
10831     }
10833   /* The optimizer does not know that the call sets the function value
10834      registers we stored in the result block.  We avoid problems by
10835      claiming that all hard registers are used and clobbered at this
10836      point.  */
10837   emit_insn (gen_blockage ());
10839   DONE;
10842 ;; sibling call patterns
10843 (define_expand "sibcall"
10844   [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10845                     (match_operand 1 ""))
10846               (use (match_operand 2 ""))
10847               (simple_return)])]
10848   ""
10850 #if TARGET_MACHO
10851   if (MACHOPIC_INDIRECT)
10852     operands[0] = machopic_indirect_call_target (operands[0]);
10853 #endif
10855   gcc_assert (MEM_P (operands[0]));
10856   gcc_assert (CONST_INT_P (operands[1]));
10858   operands[0] = XEXP (operands[0], 0);
10860   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10861     rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10862   else if (DEFAULT_ABI == ABI_V4)
10863     rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10864   else if (DEFAULT_ABI == ABI_DARWIN)
10865     rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10866   else
10867     gcc_unreachable ();
10869   DONE;
10872 (define_expand "sibcall_value"
10873   [(parallel [(set (match_operand 0 "register_operand")
10874                 (call (mem:SI (match_operand 1 "address_operand"))
10875                       (match_operand 2 "")))
10876               (use (match_operand 3 ""))
10877               (simple_return)])]
10878   ""
10880 #if TARGET_MACHO
10881   if (MACHOPIC_INDIRECT)
10882     operands[1] = machopic_indirect_call_target (operands[1]);
10883 #endif
10885   gcc_assert (MEM_P (operands[1]));
10886   gcc_assert (CONST_INT_P (operands[2]));
10888   operands[1] = XEXP (operands[1], 0);
10890   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10891     rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10892   else if (DEFAULT_ABI == ABI_V4)
10893     rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10894   else if (DEFAULT_ABI == ABI_DARWIN)
10895     rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10896   else
10897     gcc_unreachable ();
10899   DONE;
10902 (define_insn "*sibcall_local32"
10903   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10904          (match_operand 1))
10905    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10906    (simple_return)]
10907   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10909   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10910     output_asm_insn ("crxor 6,6,6", operands);
10912   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10913     output_asm_insn ("creqv 6,6,6", operands);
10915   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10917   [(set_attr "type" "branch")
10918    (set_attr "length" "4,8")])
10920 (define_insn "*sibcall_local64"
10921   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10922          (match_operand 1))
10923    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10924    (simple_return)]
10925   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10927   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10928     output_asm_insn ("crxor 6,6,6", operands);
10930   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10931     output_asm_insn ("creqv 6,6,6", operands);
10933   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10935   [(set_attr "type" "branch")
10936    (set_attr "length" "4,8")])
10938 (define_insn "*sibcall_value_local32"
10939   [(set (match_operand 0 "" "")
10940         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10941               (match_operand 2)))
10942    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10943    (simple_return)]
10944   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10946   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10947     output_asm_insn ("crxor 6,6,6", operands);
10949   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10950     output_asm_insn ("creqv 6,6,6", operands);
10952   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10954   [(set_attr "type" "branch")
10955    (set_attr "length" "4,8")])
10957 (define_insn "*sibcall_value_local64"
10958   [(set (match_operand 0 "" "")
10959         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10960               (match_operand 2)))
10961    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10962    (simple_return)]
10963   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10965   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10966     output_asm_insn ("crxor 6,6,6", operands);
10968   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10969     output_asm_insn ("creqv 6,6,6", operands);
10971   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10973   [(set_attr "type" "branch")
10974    (set_attr "length" "4,8")])
10976 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10977   [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10978          (match_operand 1))
10979    (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10980    (simple_return)]
10981   "DEFAULT_ABI == ABI_V4
10982    || DEFAULT_ABI == ABI_DARWIN"
10984   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10985     output_asm_insn ("crxor 6,6,6", operands);
10987   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10988     output_asm_insn ("creqv 6,6,6", operands);
10990   return rs6000_indirect_sibcall_template (operands, 0);
10992   [(set_attr "type" "jmpreg")
10993    (set (attr "length")
10994         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10995                          (match_test "which_alternative != 1"))
10996                     (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10997                   (const_string "12")
10998                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10999                          (match_test "which_alternative != 1"))
11000                    (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11001                   (const_string "8")]
11002               (const_string "4")))])
11004 (define_insn "*sibcall_nonlocal_sysv<mode>"
11005   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11006          (match_operand 1))
11007    (use (match_operand 2 "immediate_operand" "O,n"))
11008    (simple_return)]
11009   "(DEFAULT_ABI == ABI_DARWIN
11010     || DEFAULT_ABI == ABI_V4)
11011    && (INTVAL (operands[2]) & CALL_LONG) == 0"
11013   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11014     output_asm_insn ("crxor 6,6,6", operands);
11016   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11017     output_asm_insn ("creqv 6,6,6", operands);
11019   return rs6000_sibcall_template (operands, 0);
11021   [(set_attr "type" "branch")
11022    (set_attr "length" "4,8")])
11024 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11025   [(set (match_operand 0 "" "")
11026         (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11027               (match_operand 2)))
11028    (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11029    (simple_return)]
11030   "DEFAULT_ABI == ABI_V4
11031    || DEFAULT_ABI == ABI_DARWIN"
11033   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11034     output_asm_insn ("crxor 6,6,6", operands);
11036   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11037     output_asm_insn ("creqv 6,6,6", operands);
11039   return rs6000_indirect_sibcall_template (operands, 1);
11041   [(set_attr "type" "jmpreg")
11042    (set (attr "length")
11043         (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11044                          (match_test "which_alternative != 1"))
11045                     (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11046                   (const_string "12")
11047                (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11048                          (match_test "which_alternative != 1"))
11049                    (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11050                   (const_string "8")]
11051               (const_string "4")))])
11053 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11054   [(set (match_operand 0 "" "")
11055         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11056               (match_operand 2)))
11057    (use (match_operand:SI 3 "immediate_operand" "O,n"))
11058    (simple_return)]
11059   "(DEFAULT_ABI == ABI_DARWIN
11060     || DEFAULT_ABI == ABI_V4)
11061    && (INTVAL (operands[3]) & CALL_LONG) == 0"
11063   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11064     output_asm_insn ("crxor 6,6,6", operands);
11066   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11067     output_asm_insn ("creqv 6,6,6", operands);
11069   return rs6000_sibcall_template (operands, 1);
11071   [(set_attr "type" "branch")
11072    (set_attr "length" "4,8")])
11074 ;; AIX ABI sibling call patterns.
11076 (define_insn "*sibcall_aix<mode>"
11077   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11078          (match_operand 1))
11079    (simple_return)]
11080   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11082   if (which_alternative == 0)
11083     return rs6000_sibcall_template (operands, 0);
11084   else
11085     return "b%T0";
11087   [(set_attr "type" "branch")])
11089 (define_insn "*sibcall_value_aix<mode>"
11090   [(set (match_operand 0 "" "")
11091         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11092               (match_operand 2)))
11093    (simple_return)]
11094   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11096   if (which_alternative == 0)
11097     return rs6000_sibcall_template (operands, 1);
11098   else
11099     return "b%T1";
11101   [(set_attr "type" "branch")])
11103 (define_expand "sibcall_epilogue"
11104   [(use (const_int 0))]
11105   ""
11107   if (!TARGET_SCHED_PROLOG)
11108     emit_insn (gen_blockage ());
11109   rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11110   DONE;
11113 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11114 ;; all of memory.  This blocks insns from being moved across this point.
11116 (define_insn "blockage"
11117   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11118   ""
11119   ""
11120   [(set_attr "length" "0")])
11122 (define_expand "probe_stack_address"
11123   [(use (match_operand 0 "address_operand"))]
11124   ""
11126   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11127   MEM_VOLATILE_P (operands[0]) = 1;
11129   if (TARGET_64BIT)
11130     emit_insn (gen_probe_stack_di (operands[0]));
11131   else
11132     emit_insn (gen_probe_stack_si (operands[0]));
11133   DONE;
11136 (define_insn "probe_stack_<mode>"
11137   [(set (match_operand:P 0 "memory_operand" "=m")
11138         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11139   ""
11141   operands[1] = gen_rtx_REG (Pmode, 0);
11142   return "st<wd>%U0%X0 %1,%0";
11144   [(set_attr "type" "store")
11145    (set (attr "update")
11146         (if_then_else (match_operand 0 "update_address_mem")
11147                       (const_string "yes")
11148                       (const_string "no")))
11149    (set (attr "indexed")
11150         (if_then_else (match_operand 0 "indexed_address_mem")
11151                       (const_string "yes")
11152                       (const_string "no")))])
11154 (define_insn "probe_stack_range<P:mode>"
11155   [(set (match_operand:P 0 "register_operand" "=&r")
11156         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11157                             (match_operand:P 2 "register_operand" "r")
11158                             (match_operand:P 3 "register_operand" "r")]
11159                            UNSPECV_PROBE_STACK_RANGE))]
11160   ""
11161   "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11162   [(set_attr "type" "three")])
11164 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
11165 ;; signed & unsigned, and one type of branch.
11167 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11168 ;; insns, and branches.
11170 (define_expand "cbranch<mode>4"
11171   [(use (match_operator 0 "comparison_operator"
11172          [(match_operand:GPR 1 "gpc_reg_operand")
11173           (match_operand:GPR 2 "reg_or_short_operand")]))
11174    (use (match_operand 3))]
11175   ""
11177   /* Take care of the possibility that operands[2] might be negative but
11178      this might be a logical operation.  That insn doesn't exist.  */
11179   if (CONST_INT_P (operands[2])
11180       && INTVAL (operands[2]) < 0)
11181     {
11182       operands[2] = force_reg (<MODE>mode, operands[2]);
11183       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11184                                     GET_MODE (operands[0]),
11185                                     operands[1], operands[2]);
11186    }
11188   rs6000_emit_cbranch (<MODE>mode, operands);
11189   DONE;
11192 (define_expand "cbranch<mode>4"
11193   [(use (match_operator 0 "comparison_operator"
11194          [(match_operand:FP 1 "gpc_reg_operand")
11195           (match_operand:FP 2 "gpc_reg_operand")]))
11196    (use (match_operand 3))]
11197   ""
11199   rs6000_emit_cbranch (<MODE>mode, operands);
11200   DONE;
11203 (define_expand "cstore<mode>4_signed"
11204   [(use (match_operator 1 "signed_comparison_operator"
11205          [(match_operand:P 2 "gpc_reg_operand")
11206           (match_operand:P 3 "gpc_reg_operand")]))
11207    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11208   ""
11210   enum rtx_code cond_code = GET_CODE (operands[1]);
11212   rtx op0 = operands[0];
11213   rtx op1 = operands[2];
11214   rtx op2 = operands[3];
11216   if (cond_code == GE || cond_code == LT)
11217     {
11218       cond_code = swap_condition (cond_code);
11219       std::swap (op1, op2);
11220     }
11222   rtx tmp1 = gen_reg_rtx (<MODE>mode);
11223   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11224   rtx tmp3 = gen_reg_rtx (<MODE>mode);
11226   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11227   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11228   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11230   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11232   if (cond_code == LE)
11233     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11234   else
11235     {
11236       rtx tmp4 = gen_reg_rtx (<MODE>mode);
11237       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11238       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11239     }
11241   DONE;
11244 (define_expand "cstore<mode>4_unsigned"
11245   [(use (match_operator 1 "unsigned_comparison_operator"
11246          [(match_operand:P 2 "gpc_reg_operand")
11247           (match_operand:P 3 "reg_or_short_operand")]))
11248    (clobber (match_operand:P 0 "gpc_reg_operand"))]
11249   ""
11251   enum rtx_code cond_code = GET_CODE (operands[1]);
11253   rtx op0 = operands[0];
11254   rtx op1 = operands[2];
11255   rtx op2 = operands[3];
11257   if (cond_code == GEU || cond_code == LTU)
11258     {
11259       cond_code = swap_condition (cond_code);
11260       std::swap (op1, op2);
11261     }
11263   if (!gpc_reg_operand (op1, <MODE>mode))
11264     op1 = force_reg (<MODE>mode, op1);
11265   if (!reg_or_short_operand (op2, <MODE>mode))
11266     op2 = force_reg (<MODE>mode, op2);
11268   rtx tmp = gen_reg_rtx (<MODE>mode);
11269   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11271   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11272   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11274   if (cond_code == LEU)
11275     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11276   else
11277     emit_insn (gen_neg<mode>2 (op0, tmp2));
11279   DONE;
11282 (define_expand "cstore_si_as_di"
11283   [(use (match_operator 1 "unsigned_comparison_operator"
11284          [(match_operand:SI 2 "gpc_reg_operand")
11285           (match_operand:SI 3 "reg_or_short_operand")]))
11286    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11287   ""
11289   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11290   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11292   operands[2] = force_reg (SImode, operands[2]);
11293   operands[3] = force_reg (SImode, operands[3]);
11294   rtx op1 = gen_reg_rtx (DImode);
11295   rtx op2 = gen_reg_rtx (DImode);
11296   convert_move (op1, operands[2], uns_flag);
11297   convert_move (op2, operands[3], uns_flag);
11299   if (cond_code == GT || cond_code == LE)
11300     {
11301       cond_code = swap_condition (cond_code);
11302       std::swap (op1, op2);
11303     }
11305   rtx tmp = gen_reg_rtx (DImode);
11306   rtx tmp2 = gen_reg_rtx (DImode);
11307   emit_insn (gen_subdi3 (tmp, op1, op2));
11308   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11310   rtx tmp3;
11311   switch (cond_code)
11312     {
11313     default:
11314       gcc_unreachable ();
11315     case LT:
11316       tmp3 = tmp2;
11317       break;
11318     case GE:
11319       tmp3 = gen_reg_rtx (DImode);
11320       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11321       break;
11322     }
11324   convert_move (operands[0], tmp3, 1);
11326   DONE;
11329 (define_expand "cstore<mode>4_signed_imm"
11330   [(use (match_operator 1 "signed_comparison_operator"
11331          [(match_operand:GPR 2 "gpc_reg_operand")
11332           (match_operand:GPR 3 "immediate_operand")]))
11333    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11334   ""
11336   bool invert = false;
11338   enum rtx_code cond_code = GET_CODE (operands[1]);
11340   rtx op0 = operands[0];
11341   rtx op1 = operands[2];
11342   HOST_WIDE_INT val = INTVAL (operands[3]);
11344   if (cond_code == GE || cond_code == GT)
11345     {
11346       cond_code = reverse_condition (cond_code);
11347       invert = true;
11348     }
11350   if (cond_code == LE)
11351     val++;
11353   rtx tmp = gen_reg_rtx (<MODE>mode);
11354   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11355   rtx x = gen_reg_rtx (<MODE>mode);
11356   if (val < 0)
11357     emit_insn (gen_and<mode>3 (x, op1, tmp));
11358   else
11359     emit_insn (gen_ior<mode>3 (x, op1, tmp));
11361   if (invert)
11362     {
11363       rtx tmp = gen_reg_rtx (<MODE>mode);
11364       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11365       x = tmp;
11366     }
11368   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11369   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11371   DONE;
11374 (define_expand "cstore<mode>4_unsigned_imm"
11375   [(use (match_operator 1 "unsigned_comparison_operator"
11376          [(match_operand:GPR 2 "gpc_reg_operand")
11377           (match_operand:GPR 3 "immediate_operand")]))
11378    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11379   ""
11381   bool invert = false;
11383   enum rtx_code cond_code = GET_CODE (operands[1]);
11385   rtx op0 = operands[0];
11386   rtx op1 = operands[2];
11387   HOST_WIDE_INT val = INTVAL (operands[3]);
11389   if (cond_code == GEU || cond_code == GTU)
11390     {
11391       cond_code = reverse_condition (cond_code);
11392       invert = true;
11393     }
11395   if (cond_code == LEU)
11396     val++;
11398   rtx tmp = gen_reg_rtx (<MODE>mode);
11399   rtx tmp2 = gen_reg_rtx (<MODE>mode);
11400   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11401   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11402   rtx x = gen_reg_rtx (<MODE>mode);
11403   if (val < 0)
11404     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11405   else
11406     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11408   if (invert)
11409     {
11410       rtx tmp = gen_reg_rtx (<MODE>mode);
11411       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11412       x = tmp;
11413     }
11415   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11416   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11418   DONE;
11421 (define_expand "cstore<mode>4"
11422   [(use (match_operator 1 "comparison_operator"
11423          [(match_operand:GPR 2 "gpc_reg_operand")
11424           (match_operand:GPR 3 "reg_or_short_operand")]))
11425    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11426   ""
11428   /* Expanding EQ and NE directly to some machine instructions does not help
11429      but does hurt combine.  So don't.  */
11430   if (GET_CODE (operands[1]) == EQ)
11431     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11432   else if (<MODE>mode == Pmode
11433            && GET_CODE (operands[1]) == NE)
11434     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11435   else if (GET_CODE (operands[1]) == NE)
11436     {
11437       rtx tmp = gen_reg_rtx (<MODE>mode);
11438       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11439       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11440     }
11442   /* If ISEL is fast, expand to it.  */
11443   else if (TARGET_ISEL)
11444     rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11446   /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11447      etc. combinations magically work out just right.  */
11448   else if (<MODE>mode == Pmode
11449            && unsigned_comparison_operator (operands[1], VOIDmode))
11450     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11451                                            operands[2], operands[3]));
11453   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
11454   else if (<MODE>mode == SImode && Pmode == DImode)
11455     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11456                                     operands[2], operands[3]));
11458   /* For signed comparisons against a constant, we can do some simple
11459      bit-twiddling.  */
11460   else if (signed_comparison_operator (operands[1], VOIDmode)
11461            && CONST_INT_P (operands[3]))
11462     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11463                                              operands[2], operands[3]));
11465   /* And similarly for unsigned comparisons.  */
11466   else if (unsigned_comparison_operator (operands[1], VOIDmode)
11467            && CONST_INT_P (operands[3]))
11468     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11469                                                operands[2], operands[3]));
11471   /* We also do not want to use mfcr for signed comparisons.  */
11472   else if (<MODE>mode == Pmode
11473            && signed_comparison_operator (operands[1], VOIDmode))
11474     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11475                                          operands[2], operands[3]));
11477   /* Everything else, use the mfcr brute force.  */
11478   else
11479     rs6000_emit_sCOND (<MODE>mode, operands);
11481   DONE;
11484 (define_expand "cstore<mode>4"
11485   [(use (match_operator 1 "comparison_operator"
11486          [(match_operand:FP 2 "gpc_reg_operand")
11487           (match_operand:FP 3 "gpc_reg_operand")]))
11488    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11489   ""
11491   rs6000_emit_sCOND (<MODE>mode, operands);
11492   DONE;
11496 (define_expand "stack_protect_set"
11497   [(match_operand 0 "memory_operand")
11498    (match_operand 1 "memory_operand")]
11499   ""
11501   if (rs6000_stack_protector_guard == SSP_TLS)
11502     {
11503       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11504       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11505       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11506       operands[1] = gen_rtx_MEM (Pmode, addr);
11507     }
11509   if (TARGET_64BIT)
11510     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11511   else
11512     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11514   DONE;
11517 (define_insn "stack_protect_setsi"
11518   [(set (match_operand:SI 0 "memory_operand" "=m")
11519         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11520    (set (match_scratch:SI 2 "=&r") (const_int 0))]
11521   "TARGET_32BIT"
11522   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11523   [(set_attr "type" "three")
11524    (set_attr "length" "12")])
11526 ;; We can't use the prefixed attribute here because there are two memory
11527 ;; instructions.  We can't split the insn due to the fact that this operation
11528 ;; needs to be done in one piece.
11529 (define_insn "stack_protect_setdi"
11530   [(set (match_operand:DI 0 "memory_operand" "=Y")
11531         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11532    (set (match_scratch:DI 2 "=&r") (const_int 0))]
11533   "TARGET_64BIT"
11535   if (prefixed_memory (operands[1], DImode))
11536     output_asm_insn ("pld %2,%1", operands);
11537   else
11538     output_asm_insn ("ld%U1%X1 %2,%1", operands);
11540   if (prefixed_memory (operands[0], DImode))
11541     output_asm_insn ("pstd %2,%0", operands);
11542   else
11543     output_asm_insn ("std%U0%X0 %2,%0", operands);
11545   return "li %2,0";
11547   [(set_attr "type" "three")
11549   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11550   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in 4 bytes for
11551   ;; the LI 0 at the end.
11552    (set_attr "prefixed" "no")
11553    (set_attr "num_insns" "3")
11554    (set (attr "length")
11555         (cond [(and (match_operand 0 "prefixed_memory")
11556                     (match_operand 1 "prefixed_memory"))
11557                (const_int 24)
11559                (ior (match_operand 0 "prefixed_memory")
11560                     (match_operand 1 "prefixed_memory"))
11561                (const_int 20)]
11563               (const_int 12)))])
11565 (define_expand "stack_protect_test"
11566   [(match_operand 0 "memory_operand")
11567    (match_operand 1 "memory_operand")
11568    (match_operand 2 "")]
11569   ""
11571   rtx guard = operands[1];
11573   if (rs6000_stack_protector_guard == SSP_TLS)
11574     {
11575       rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11576       rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11577       rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11578       guard = gen_rtx_MEM (Pmode, addr);
11579     }
11581   operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11582   rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11583   rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11584   emit_jump_insn (jump);
11586   DONE;
11589 (define_insn "stack_protect_testsi"
11590   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11591         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11592                       (match_operand:SI 2 "memory_operand" "m,m")]
11593                      UNSPEC_SP_TEST))
11594    (set (match_scratch:SI 4 "=r,r") (const_int 0))
11595    (clobber (match_scratch:SI 3 "=&r,&r"))]
11596   "TARGET_32BIT"
11597   "@
11598    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11599    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11600   [(set_attr "length" "16,20")])
11602 ;; We can't use the prefixed attribute here because there are two memory
11603 ;; instructions.  We can't split the insn due to the fact that this operation
11604 ;; needs to be done in one piece.
11605 (define_insn "stack_protect_testdi"
11606   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11607         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11608                       (match_operand:DI 2 "memory_operand" "Y,Y")]
11609                      UNSPEC_SP_TEST))
11610    (set (match_scratch:DI 4 "=r,r") (const_int 0))
11611    (clobber (match_scratch:DI 3 "=&r,&r"))]
11612   "TARGET_64BIT"
11614   if (prefixed_memory (operands[1], DImode))
11615     output_asm_insn ("pld %3,%1", operands);
11616   else
11617     output_asm_insn ("ld%U1%X1 %3,%1", operands);
11619   if (prefixed_memory (operands[2], DImode))
11620     output_asm_insn ("pld %4,%2", operands);
11621   else
11622     output_asm_insn ("ld%U2%X2 %4,%2", operands);
11624   if (which_alternative == 0)
11625     output_asm_insn ("xor. %3,%3,%4", operands);
11626   else
11627     output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11629   return "li %4,0";
11631   ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11632   ;; prefixed instruction + 4 bytes for the possible NOP).  Add in either 4 or
11633   ;; 8 bytes to do the test.
11634   [(set_attr "prefixed" "no")
11635    (set_attr "num_insns" "4,5")
11636    (set (attr "length")
11637         (cond [(and (match_operand 1 "prefixed_memory")
11638                     (match_operand 2 "prefixed_memory"))
11639                (if_then_else (eq_attr "alternative" "0")
11640                              (const_int 28)
11641                              (const_int 32))
11643                (ior (match_operand 1 "prefixed_memory")
11644                     (match_operand 2 "prefixed_memory"))
11645                (if_then_else (eq_attr "alternative" "0")
11646                              (const_int 20)
11647                              (const_int 24))]
11649               (if_then_else (eq_attr "alternative" "0")
11650                             (const_int 16)
11651                             (const_int 20))))])
11654 ;; Here are the actual compare insns.
11655 (define_insn "*cmp<mode>_signed"
11656   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11657         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11658                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11659   ""
11660   "cmp<wd>%I2 %0,%1,%2"
11661   [(set_attr "type" "cmp")])
11663 (define_insn "*cmp<mode>_unsigned"
11664   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11665         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11666                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11667   ""
11668   "cmpl<wd>%I2 %0,%1,%2"
11669   [(set_attr "type" "cmp")])
11671 ;; If we are comparing a register for equality with a large constant,
11672 ;; we can do this with an XOR followed by a compare.  But this is profitable
11673 ;; only if the large constant is only used for the comparison (and in this
11674 ;; case we already have a register to reuse as scratch).
11676 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11677 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11679 (define_peephole2
11680   [(set (match_operand:SI 0 "register_operand")
11681         (match_operand:SI 1 "logical_const_operand"))
11682    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11683                        [(match_dup 0)
11684                         (match_operand:SI 2 "logical_const_operand")]))
11685    (set (match_operand:CC 4 "cc_reg_operand")
11686         (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11687                     (match_dup 0)))
11688    (set (pc)
11689         (if_then_else (match_operator 6 "equality_operator"
11690                        [(match_dup 4) (const_int 0)])
11691                       (match_operand 7 "")
11692                       (match_operand 8 "")))]
11693   "peep2_reg_dead_p (3, operands[0])
11694    && peep2_reg_dead_p (4, operands[4])
11695    && REGNO (operands[0]) != REGNO (operands[5])"
11696  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11697   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11698   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11701   /* Get the constant we are comparing against, and see what it looks like
11702      when sign-extended from 16 to 32 bits.  Then see what constant we could
11703      XOR with SEXTC to get the sign-extended value.  */
11704   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11705                                               SImode,
11706                                               operands[1], operands[2]);
11707   HOST_WIDE_INT c = INTVAL (cnst);
11708   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11709   HOST_WIDE_INT xorv = c ^ sextc;
11711   operands[9] = GEN_INT (xorv);
11712   operands[10] = GEN_INT (sextc);
11715 ;; Only need to compare second words if first words equal
11716 (define_insn "*cmp<mode>_internal1"
11717   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11718         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11719                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11720   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11721    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11722   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11723   [(set_attr "type" "fpcompare")
11724    (set_attr "length" "12")])
11726 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11727   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11728         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11729                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11730     (clobber (match_scratch:DF 3 "=d"))
11731     (clobber (match_scratch:DF 4 "=d"))
11732     (clobber (match_scratch:DF 5 "=d"))
11733     (clobber (match_scratch:DF 6 "=d"))
11734     (clobber (match_scratch:DF 7 "=d"))
11735     (clobber (match_scratch:DF 8 "=d"))
11736     (clobber (match_scratch:DF 9 "=d"))
11737     (clobber (match_scratch:DF 10 "=d"))
11738     (clobber (match_scratch:GPR 11 "=b"))]
11739   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11740    && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11741   "#"
11742   "&& reload_completed"
11743   [(set (match_dup 3) (match_dup 14))
11744    (set (match_dup 4) (match_dup 15))
11745    (set (match_dup 9) (abs:DF (match_dup 5)))
11746    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11747    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11748                            (label_ref (match_dup 12))
11749                            (pc)))
11750    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11751    (set (pc) (label_ref (match_dup 13)))
11752    (match_dup 12)
11753    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11754    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11755    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11756    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11757    (match_dup 13)]
11759   REAL_VALUE_TYPE rv;
11760   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11761   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11763   operands[5] = simplify_gen_subreg (DFmode, operands[1],
11764                                      <IBM128:MODE>mode, hi_word);
11765   operands[6] = simplify_gen_subreg (DFmode, operands[1],
11766                                      <IBM128:MODE>mode, lo_word);
11767   operands[7] = simplify_gen_subreg (DFmode, operands[2],
11768                                      <IBM128:MODE>mode, hi_word);
11769   operands[8] = simplify_gen_subreg (DFmode, operands[2],
11770                                      <IBM128:MODE>mode, lo_word);
11771   operands[12] = gen_label_rtx ();
11772   operands[13] = gen_label_rtx ();
11773   real_inf (&rv);
11774   operands[14] = force_const_mem (DFmode,
11775                                   const_double_from_real_value (rv, DFmode));
11776   operands[15] = force_const_mem (DFmode,
11777                                   const_double_from_real_value (dconst0,
11778                                                                 DFmode));
11779   if (TARGET_TOC)
11780     {
11781       rtx tocref;
11782       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11783       operands[14] = gen_const_mem (DFmode, tocref);
11784       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11785       operands[15] = gen_const_mem (DFmode, tocref);
11786       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11787       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11788     }
11791 ;; Now we have the scc insns.  We can do some combinations because of the
11792 ;; way the machine works.
11794 ;; Note that this is probably faster if we can put an insn between the
11795 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11796 ;; cases the insns below which don't use an intermediate CR field will
11797 ;; be used instead.
11798 (define_insn "set<mode>_cc"
11799   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11800         (match_operator:GPR 1 "scc_comparison_operator"
11801                             [(match_operand 2 "cc_reg_operand" "y")
11802                              (const_int 0)]))]
11803   ""
11804   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11805   [(set (attr "type")
11806      (cond [(match_test "TARGET_MFCRF")
11807                 (const_string "mfcrf")
11808            ]
11809         (const_string "mfcr")))
11810    (set_attr "length" "8")])
11813 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11814 (define_code_attr UNS [(eq "CC")
11815                        (ne "CC")
11816                        (lt "CC") (ltu "CCUNS")
11817                        (gt "CC") (gtu "CCUNS")
11818                        (le "CC") (leu "CCUNS")
11819                        (ge "CC") (geu "CCUNS")])
11820 (define_code_attr UNSu_ [(eq "")
11821                          (ne "")
11822                          (lt "") (ltu "u_")
11823                          (gt "") (gtu "u_")
11824                          (le "") (leu "u_")
11825                          (ge "") (geu "u_")])
11826 (define_code_attr UNSIK [(eq "I")
11827                          (ne "I")
11828                          (lt "I") (ltu "K")
11829                          (gt "I") (gtu "K")
11830                          (le "I") (leu "K")
11831                          (ge "I") (geu "K")])
11833 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11834   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11835         (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11836                  (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11837    (clobber (match_scratch:GPR 3 "=r"))
11838    (clobber (match_scratch:GPR 4 "=r"))
11839    (clobber (match_scratch:<UNS> 5 "=y"))]
11840   "TARGET_ISEL
11841    && !(<CODE> == EQ && operands[2] == const0_rtx)
11842    && !(<CODE> == NE && operands[2] == const0_rtx
11843         && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11844   "#"
11845   "&& 1"
11846   [(pc)]
11848   rtx_code code = <CODE>;
11849   if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11850     {
11851       HOST_WIDE_INT val = INTVAL (operands[2]);
11852       if (code == LT && val != -0x8000)
11853         {
11854           code = LE;
11855           val--;
11856         }
11857       if (code == GT && val != 0x7fff)
11858         {
11859           code = GE;
11860           val++;
11861         }
11862       if (code == LTU && val != 0)
11863         {
11864           code = LEU;
11865           val--;
11866         }
11867       if (code == GTU && val != 0xffff)
11868         {
11869           code = GEU;
11870           val++;
11871         }
11872       operands[2] = GEN_INT (val);
11873     }
11875   if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11876     operands[3] = const0_rtx;
11877   else
11878     {
11879       if (GET_CODE (operands[3]) == SCRATCH)
11880         operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11881       emit_move_insn (operands[3], const0_rtx);
11882     }
11884   if (GET_CODE (operands[4]) == SCRATCH)
11885     operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11886   emit_move_insn (operands[4], const1_rtx);
11888   if (GET_CODE (operands[5]) == SCRATCH)
11889     operands[5] = gen_reg_rtx (<UNS>mode);
11891   rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11892   emit_insn (gen_rtx_SET (operands[5], c1));
11894   rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11895   rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11896   emit_move_insn (operands[0], x);
11898   DONE;
11900   [(set (attr "cost")
11901         (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11902                                    || <CODE> == NE
11903                                    || <CODE> == LE || <CODE> == GE
11904                                    || <CODE> == LEU || <CODE> == GEU")
11905                       (const_string "9")
11906                       (const_string "10")))])
11908 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11909                               (DI "rKJI")])
11911 (define_expand "eq<mode>3"
11912   [(parallel [
11913      (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11914           (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11915                   (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11916      (clobber (match_scratch:GPR 3 "=r"))
11917      (clobber (match_scratch:GPR 4 "=r"))])]
11918   ""
11920   if (TARGET_ISEL && operands[2] != const0_rtx)
11921     {
11922       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11923                                            operands[2]));
11924       DONE;
11925     }
11928 (define_insn_and_split "*eq<mode>3"
11929   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11930         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11931                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11932    (clobber (match_scratch:GPR 3 "=r"))
11933    (clobber (match_scratch:GPR 4 "=r"))]
11934   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11935   "#"
11936   "&& 1"
11937   [(set (match_dup 4)
11938         (clz:GPR (match_dup 3)))
11939    (set (match_dup 0)
11940         (lshiftrt:GPR (match_dup 4)
11941                       (match_dup 5)))]
11943   operands[3] = rs6000_emit_eqne (<MODE>mode,
11944                                   operands[1], operands[2], operands[3]);
11946   if (GET_CODE (operands[4]) == SCRATCH)
11947     operands[4] = gen_reg_rtx (<MODE>mode);
11949   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11951   [(set (attr "length")
11952         (if_then_else (match_test "operands[2] == const0_rtx")
11953                       (const_string "8")
11954                       (const_string "12")))])
11956 (define_expand "ne<mode>3"
11957   [(parallel [
11958      (set (match_operand:P 0 "gpc_reg_operand" "=r")
11959           (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11960                 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11961      (clobber (match_scratch:P 3 "=r"))
11962      (clobber (match_scratch:P 4 "=r"))
11963      (clobber (reg:P CA_REGNO))])]
11964   ""
11966   if (TARGET_ISEL && operands[2] != const0_rtx)
11967     {
11968       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11969                                            operands[2]));
11970       DONE;
11971     }
11974 (define_insn_and_split "*ne<mode>3"
11975   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11976         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11977               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11978    (clobber (match_scratch:P 3 "=r"))
11979    (clobber (match_scratch:P 4 "=r"))
11980    (clobber (reg:P CA_REGNO))]
11981   "!(TARGET_ISEL && operands[2] != const0_rtx)"
11982   "#"
11983   "&& 1"
11984   [(parallel [(set (match_dup 4)
11985                    (plus:P (match_dup 3)
11986                            (const_int -1)))
11987               (set (reg:P CA_REGNO)
11988                    (ne:P (match_dup 3)
11989                          (const_int 0)))])
11990    (parallel [(set (match_dup 0)
11991                    (plus:P (plus:P (not:P (match_dup 4))
11992                                    (reg:P CA_REGNO))
11993                            (match_dup 3)))
11994               (clobber (reg:P CA_REGNO))])]
11996   operands[3] = rs6000_emit_eqne (<MODE>mode,
11997                                   operands[1], operands[2], operands[3]);
11999   if (GET_CODE (operands[4]) == SCRATCH)
12000     operands[4] = gen_reg_rtx (<MODE>mode);
12002   [(set (attr "length")
12003         (if_then_else (match_test "operands[2] == const0_rtx")
12004                       (const_string "8")
12005                       (const_string "12")))])
12007 (define_insn_and_split "*neg_eq_<mode>"
12008   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12009         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12010                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12011    (clobber (match_scratch:P 3 "=r"))
12012    (clobber (match_scratch:P 4 "=r"))
12013    (clobber (reg:P CA_REGNO))]
12014   ""
12015   "#"
12016   ""
12017   [(parallel [(set (match_dup 4)
12018                    (plus:P (match_dup 3)
12019                            (const_int -1)))
12020               (set (reg:P CA_REGNO)
12021                    (ne:P (match_dup 3)
12022                          (const_int 0)))])
12023    (parallel [(set (match_dup 0)
12024                    (plus:P (reg:P CA_REGNO)
12025                            (const_int -1)))
12026               (clobber (reg:P CA_REGNO))])]
12028   operands[3] = rs6000_emit_eqne (<MODE>mode,
12029                                   operands[1], operands[2], operands[3]);
12031   if (GET_CODE (operands[4]) == SCRATCH)
12032     operands[4] = gen_reg_rtx (<MODE>mode);
12034   [(set (attr "length")
12035         (if_then_else (match_test "operands[2] == const0_rtx")
12036                       (const_string "8")
12037                       (const_string "12")))])
12039 (define_insn_and_split "*neg_ne_<mode>"
12040   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12041         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12042                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12043    (clobber (match_scratch:P 3 "=r"))
12044    (clobber (match_scratch:P 4 "=r"))
12045    (clobber (reg:P CA_REGNO))]
12046   ""
12047   "#"
12048   ""
12049   [(parallel [(set (match_dup 4)
12050                    (neg:P (match_dup 3)))
12051               (set (reg:P CA_REGNO)
12052                    (eq:P (match_dup 3)
12053                          (const_int 0)))])
12054    (parallel [(set (match_dup 0)
12055                    (plus:P (reg:P CA_REGNO)
12056                            (const_int -1)))
12057               (clobber (reg:P CA_REGNO))])]
12059   operands[3] = rs6000_emit_eqne (<MODE>mode,
12060                                   operands[1], operands[2], operands[3]);
12062   if (GET_CODE (operands[4]) == SCRATCH)
12063     operands[4] = gen_reg_rtx (<MODE>mode);
12065   [(set (attr "length")
12066         (if_then_else (match_test "operands[2] == const0_rtx")
12067                       (const_string "8")
12068                       (const_string "12")))])
12070 (define_insn_and_split "*plus_eq_<mode>"
12071   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12072         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12073                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12074                 (match_operand:P 3 "gpc_reg_operand" "r")))
12075    (clobber (match_scratch:P 4 "=r"))
12076    (clobber (match_scratch:P 5 "=r"))
12077    (clobber (reg:P CA_REGNO))]
12078   ""
12079   "#"
12080   ""
12081   [(parallel [(set (match_dup 5)
12082                    (neg:P (match_dup 4)))
12083               (set (reg:P CA_REGNO)
12084                    (eq:P (match_dup 4)
12085                          (const_int 0)))])
12086    (parallel [(set (match_dup 0)
12087                    (plus:P (match_dup 3)
12088                            (reg:P CA_REGNO)))
12089               (clobber (reg:P CA_REGNO))])]
12091   operands[4] = rs6000_emit_eqne (<MODE>mode,
12092                                   operands[1], operands[2], operands[4]);
12094   if (GET_CODE (operands[5]) == SCRATCH)
12095     operands[5] = gen_reg_rtx (<MODE>mode);
12097   [(set (attr "length")
12098         (if_then_else (match_test "operands[2] == const0_rtx")
12099                       (const_string "8")
12100                       (const_string "12")))])
12102 (define_insn_and_split "*plus_ne_<mode>"
12103   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12104         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12105                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12106                 (match_operand:P 3 "gpc_reg_operand" "r")))
12107    (clobber (match_scratch:P 4 "=r"))
12108    (clobber (match_scratch:P 5 "=r"))
12109    (clobber (reg:P CA_REGNO))]
12110   ""
12111   "#"
12112   ""
12113   [(parallel [(set (match_dup 5)
12114                    (plus:P (match_dup 4)
12115                            (const_int -1)))
12116               (set (reg:P CA_REGNO)
12117                    (ne:P (match_dup 4)
12118                          (const_int 0)))])
12119    (parallel [(set (match_dup 0)
12120                    (plus:P (match_dup 3)
12121                            (reg:P CA_REGNO)))
12122               (clobber (reg:P CA_REGNO))])]
12124   operands[4] = rs6000_emit_eqne (<MODE>mode,
12125                                   operands[1], operands[2], operands[4]);
12127   if (GET_CODE (operands[5]) == SCRATCH)
12128     operands[5] = gen_reg_rtx (<MODE>mode);
12130   [(set (attr "length")
12131         (if_then_else (match_test "operands[2] == const0_rtx")
12132                       (const_string "8")
12133                       (const_string "12")))])
12135 (define_insn_and_split "*minus_eq_<mode>"
12136   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12137         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12138                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12139                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12140    (clobber (match_scratch:P 4 "=r"))
12141    (clobber (match_scratch:P 5 "=r"))
12142    (clobber (reg:P CA_REGNO))]
12143   ""
12144   "#"
12145   ""
12146   [(parallel [(set (match_dup 5)
12147                    (plus:P (match_dup 4)
12148                            (const_int -1)))
12149               (set (reg:P CA_REGNO)
12150                    (ne:P (match_dup 4)
12151                          (const_int 0)))])
12152    (parallel [(set (match_dup 0)
12153                    (plus:P (plus:P (match_dup 3)
12154                                    (reg:P CA_REGNO))
12155                            (const_int -1)))
12156               (clobber (reg:P CA_REGNO))])]
12158   operands[4] = rs6000_emit_eqne (<MODE>mode,
12159                                   operands[1], operands[2], operands[4]);
12161   if (GET_CODE (operands[5]) == SCRATCH)
12162     operands[5] = gen_reg_rtx (<MODE>mode);
12164   [(set (attr "length")
12165         (if_then_else (match_test "operands[2] == const0_rtx")
12166                       (const_string "8")
12167                       (const_string "12")))])
12169 (define_insn_and_split "*minus_ne_<mode>"
12170   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12171         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12172                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12173                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12174    (clobber (match_scratch:P 4 "=r"))
12175    (clobber (match_scratch:P 5 "=r"))
12176    (clobber (reg:P CA_REGNO))]
12177   ""
12178   "#"
12179   ""
12180   [(parallel [(set (match_dup 5)
12181                    (neg:P (match_dup 4)))
12182               (set (reg:P CA_REGNO)
12183                    (eq:P (match_dup 4)
12184                          (const_int 0)))])
12185    (parallel [(set (match_dup 0)
12186                    (plus:P (plus:P (match_dup 3)
12187                                    (reg:P CA_REGNO))
12188                            (const_int -1)))
12189               (clobber (reg:P CA_REGNO))])]
12191   operands[4] = rs6000_emit_eqne (<MODE>mode,
12192                                   operands[1], operands[2], operands[4]);
12194   if (GET_CODE (operands[5]) == SCRATCH)
12195     operands[5] = gen_reg_rtx (<MODE>mode);
12197   [(set (attr "length")
12198         (if_then_else (match_test "operands[2] == const0_rtx")
12199                       (const_string "8")
12200                       (const_string "12")))])
12202 (define_insn_and_split "*eqsi3_ext<mode>"
12203   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12204         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12205                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12206    (clobber (match_scratch:SI 3 "=r"))
12207    (clobber (match_scratch:SI 4 "=r"))]
12208   ""
12209   "#"
12210   ""
12211   [(set (match_dup 4)
12212         (clz:SI (match_dup 3)))
12213    (set (match_dup 0)
12214         (zero_extend:EXTSI
12215           (lshiftrt:SI (match_dup 4)
12216                        (const_int 5))))]
12218   operands[3] = rs6000_emit_eqne (SImode,
12219                                   operands[1], operands[2], operands[3]);
12221   if (GET_CODE (operands[4]) == SCRATCH)
12222     operands[4] = gen_reg_rtx (SImode);
12224   [(set (attr "length")
12225         (if_then_else (match_test "operands[2] == const0_rtx")
12226                       (const_string "8")
12227                       (const_string "12")))])
12229 (define_insn_and_split "*nesi3_ext<mode>"
12230   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12231         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12232                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12233    (clobber (match_scratch:SI 3 "=r"))
12234    (clobber (match_scratch:SI 4 "=r"))
12235    (clobber (match_scratch:EXTSI 5 "=r"))]
12236   "!TARGET_ISEL"
12237   "#"
12238   "&& 1"
12239   [(set (match_dup 4)
12240         (clz:SI (match_dup 3)))
12241    (set (match_dup 5)
12242         (zero_extend:EXTSI
12243           (lshiftrt:SI (match_dup 4)
12244                        (const_int 5))))
12245    (set (match_dup 0)
12246         (xor:EXTSI (match_dup 5)
12247                    (const_int 1)))]
12249   operands[3] = rs6000_emit_eqne (SImode,
12250                                   operands[1], operands[2], operands[3]);
12252   if (GET_CODE (operands[4]) == SCRATCH)
12253     operands[4] = gen_reg_rtx (SImode);
12254   if (GET_CODE (operands[5]) == SCRATCH)
12255     operands[5] = gen_reg_rtx (<MODE>mode);
12257   [(set (attr "length")
12258         (if_then_else (match_test "operands[2] == const0_rtx")
12259                       (const_string "12")
12260                       (const_string "16")))])
12263 (define_code_iterator fp_rev [ordered ne unle unge])
12264 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12266 (define_insn_and_split "*<code><mode>_cc"
12267   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12268         (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12269                     (const_int 0)))]
12270   "!flag_finite_math_only"
12271   "#"
12272   "&& 1"
12273   [(pc)]
12275   rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12276   rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12277   rtx tmp = gen_reg_rtx (<MODE>mode);
12278   emit_move_insn (tmp, eq);
12279   emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12280   DONE;
12282   [(set_attr "length" "12")])
12284 (define_insn_and_split "*<code><mode>_cc"
12285   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12286         (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12287                   (const_int 0)))]
12288   "!flag_finite_math_only"
12289   "#"
12290   "&& 1"
12291   [(pc)]
12293   rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12295   emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12296   DONE;
12298   [(set_attr "length" "12")])
12300 ;; Conditional branches.
12301 ;; These either are a single bc insn, or a bc around a b.
12303 (define_insn "*cbranch"
12304   [(set (pc)
12305         (if_then_else (match_operator 1 "branch_comparison_operator"
12306                                       [(match_operand 2 "cc_reg_operand" "y")
12307                                        (const_int 0)])
12308                       (label_ref (match_operand 0))
12309                       (pc)))]
12310   ""
12312   return output_cbranch (operands[1], "%l0", 0, insn);
12314   [(set_attr "type" "branch")
12315    (set (attr "length")
12316         (if_then_else (and (ge (minus (match_dup 0) (pc))
12317                                (const_int -32768))
12318                            (lt (minus (match_dup 0) (pc))
12319                                (const_int 32764)))
12320                       (const_int 4)
12321                       (const_int 8)))])
12323 (define_insn_and_split "*cbranch_2insn"
12324   [(set (pc)
12325         (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12326                                       [(match_operand 2 "cc_reg_operand" "y")
12327                                        (const_int 0)])
12328                       (label_ref (match_operand 0))
12329                       (pc)))]
12330   "!flag_finite_math_only"
12331   "#"
12332   "&& 1"
12333   [(pc)]
12335   rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12337   rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12339   rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12340   rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12341   rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12342   emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12344   if (note)
12345     {
12346       profile_probability prob
12347         = profile_probability::from_reg_br_prob_note (XINT (note, 0));
12349       add_reg_br_prob_note (get_last_insn (), prob);
12350     }
12352   DONE;
12354   [(set_attr "type" "branch")
12355    (set (attr "length")
12356         (if_then_else (and (ge (minus (match_dup 0) (pc))
12357                                (const_int -32764))
12358                            (lt (minus (match_dup 0) (pc))
12359                                (const_int 32760)))
12360                       (const_int 8)
12361                       (const_int 16)))])
12363 ;; Conditional return.
12364 (define_insn "*creturn"
12365   [(set (pc)
12366         (if_then_else (match_operator 0 "branch_comparison_operator"
12367                                       [(match_operand 1 "cc_reg_operand" "y")
12368                                        (const_int 0)])
12369                       (any_return)
12370                       (pc)))]
12371   "<return_pred>"
12373   return output_cbranch (operands[0], NULL, 0, insn);
12375   [(set_attr "type" "jmpreg")])
12377 ;; Logic on condition register values.
12379 ; This pattern matches things like
12380 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12381 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
12382 ;                                  (const_int 1)))
12383 ; which are generated by the branch logic.
12384 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12386 (define_insn "@cceq_ior_compare_<mode>"
12387   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12388         (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12389                         [(match_operator:GPR 2
12390                                       "branch_positive_comparison_operator"
12391                                       [(match_operand 3
12392                                                       "cc_reg_operand" "y,y")
12393                                        (const_int 0)])
12394                          (match_operator:GPR 4
12395                                       "branch_positive_comparison_operator"
12396                                       [(match_operand 5
12397                                                       "cc_reg_operand" "0,y")
12398                                        (const_int 0)])])
12399                       (const_int 1)))]
12400   ""
12401   "cr%q1 %E0,%j2,%j4"
12402   [(set_attr "type" "cr_logical")
12403    (set_attr "cr_logical_3op" "no,yes")])
12405 ; Why is the constant -1 here, but 1 in the previous pattern?
12406 ; Because ~1 has all but the low bit set.
12407 (define_insn "cceq_ior_compare_complement"
12408   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12409         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12410                         [(not:SI (match_operator:SI 2
12411                                       "branch_positive_comparison_operator"
12412                                       [(match_operand 3
12413                                                       "cc_reg_operand" "y,y")
12414                                        (const_int 0)]))
12415                          (match_operator:SI 4
12416                                 "branch_positive_comparison_operator"
12417                                 [(match_operand 5
12418                                                 "cc_reg_operand" "0,y")
12419                                  (const_int 0)])])
12420                       (const_int -1)))]
12421   ""
12422   "cr%q1 %E0,%j2,%j4"
12423   [(set_attr "type" "cr_logical")
12424    (set_attr "cr_logical_3op" "no,yes")])
12426 (define_insn "@cceq_rev_compare_<mode>"
12427   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12428         (compare:CCEQ (match_operator:GPR 1
12429                                       "branch_positive_comparison_operator"
12430                                       [(match_operand 2
12431                                                       "cc_reg_operand" "0,y")
12432                                        (const_int 0)])
12433                       (const_int 0)))]
12434   ""
12435   "crnot %E0,%j1"
12436   [(set_attr "type" "cr_logical")
12437    (set_attr "cr_logical_3op" "no,yes")])
12439 ;; If we are comparing the result of two comparisons, this can be done
12440 ;; using creqv or crxor.
12442 (define_insn_and_split ""
12443   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12444         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12445                               [(match_operand 2 "cc_reg_operand" "y")
12446                                (const_int 0)])
12447                       (match_operator 3 "branch_comparison_operator"
12448                               [(match_operand 4 "cc_reg_operand" "y")
12449                                (const_int 0)])))]
12450   ""
12451   "#"
12452   ""
12453   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12454                                     (match_dup 5)))]
12456   int positive_1, positive_2;
12458   positive_1 = branch_positive_comparison_operator (operands[1],
12459                                                     GET_MODE (operands[1]));
12460   positive_2 = branch_positive_comparison_operator (operands[3],
12461                                                     GET_MODE (operands[3]));
12463   if (! positive_1)
12464     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12465                                                             GET_CODE (operands[1])),
12466                                   SImode,
12467                                   operands[2], const0_rtx);
12468   else if (GET_MODE (operands[1]) != SImode)
12469     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12470                                   operands[2], const0_rtx);
12472   if (! positive_2)
12473     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12474                                                             GET_CODE (operands[3])),
12475                                   SImode,
12476                                   operands[4], const0_rtx);
12477   else if (GET_MODE (operands[3]) != SImode)
12478     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12479                                   operands[4], const0_rtx);
12481   if (positive_1 == positive_2)
12482     {
12483       operands[1] = gen_rtx_NOT (SImode, operands[1]);
12484       operands[5] = constm1_rtx;
12485     }
12486   else
12487     {
12488       operands[5] = const1_rtx;
12489     }
12492 ;; Unconditional branch and return.
12494 (define_insn "jump"
12495   [(set (pc)
12496         (label_ref (match_operand 0)))]
12497   ""
12498   "b %l0"
12499   [(set_attr "type" "branch")])
12501 (define_insn "<return_str>return"
12502   [(any_return)]
12503   "<return_pred>"
12504   "blr"
12505   [(set_attr "type" "jmpreg")])
12507 (define_expand "indirect_jump"
12508   [(set (pc) (match_operand 0 "register_operand"))]
12509  ""
12511   if (!rs6000_speculate_indirect_jumps) {
12512     rtx ccreg = gen_reg_rtx (CCmode);
12513     emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12514     DONE;
12515   }
12518 (define_insn "*indirect_jump<mode>"
12519   [(set (pc)
12520         (match_operand:P 0 "register_operand" "c,*l"))]
12521   "rs6000_speculate_indirect_jumps"
12522   "b%T0"
12523   [(set_attr "type" "jmpreg")])
12525 (define_insn "@indirect_jump<mode>_nospec"
12526   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12527    (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12528   "!rs6000_speculate_indirect_jumps"
12529   "crset %E1\;beq%T0- %1\;b $"
12530   [(set_attr "type" "jmpreg")
12531    (set_attr "length" "12")])
12533 ;; Table jump for switch statements:
12534 (define_expand "tablejump"
12535   [(use (match_operand 0))
12536    (use (label_ref (match_operand 1)))]
12537   ""
12539   if (rs6000_speculate_indirect_jumps)
12540     {
12541       if (TARGET_32BIT)
12542         emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12543       else
12544         emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12545     }
12546   else
12547     {
12548       rtx ccreg = gen_reg_rtx (CCmode);
12549       rtx jump;
12550       if (TARGET_32BIT)
12551         jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12552       else
12553         jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12554       emit_jump_insn (jump);
12555     }
12556   DONE;
12559 (define_expand "tablejumpsi"
12560   [(set (match_dup 3)
12561         (plus:SI (match_operand:SI 0)
12562                  (match_dup 2)))
12563    (parallel [(set (pc)
12564                    (match_dup 3))
12565               (use (label_ref (match_operand 1)))])]
12566   "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12568   operands[0] = force_reg (SImode, operands[0]);
12569   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12570   operands[3] = gen_reg_rtx (SImode);
12573 (define_expand "tablejumpsi_nospec"
12574   [(set (match_dup 4)
12575         (plus:SI (match_operand:SI 0)
12576                  (match_dup 3)))
12577    (parallel [(set (pc)
12578                    (match_dup 4))
12579               (use (label_ref (match_operand 1)))
12580               (clobber (match_operand 2))])]
12581   "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12583   operands[0] = force_reg (SImode, operands[0]);
12584   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12585   operands[4] = gen_reg_rtx (SImode);
12588 (define_expand "tablejumpdi"
12589   [(set (match_dup 4)
12590         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12591    (set (match_dup 3)
12592         (plus:DI (match_dup 4)
12593                  (match_dup 2)))
12594    (parallel [(set (pc)
12595                    (match_dup 3))
12596               (use (label_ref (match_operand 1)))])]
12597   "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12599   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12600   operands[3] = gen_reg_rtx (DImode);
12601   operands[4] = gen_reg_rtx (DImode);
12604 (define_expand "tablejumpdi_nospec"
12605   [(set (match_dup 5)
12606         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12607    (set (match_dup 4)
12608         (plus:DI (match_dup 5)
12609                  (match_dup 3)))
12610    (parallel [(set (pc)
12611                    (match_dup 4))
12612               (use (label_ref (match_operand 1)))
12613               (clobber (match_operand 2))])]
12614   "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12616   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12617   operands[4] = gen_reg_rtx (DImode);
12618   operands[5] = gen_reg_rtx (DImode);
12621 (define_insn "*tablejump<mode>_internal1"
12622   [(set (pc)
12623         (match_operand:P 0 "register_operand" "c,*l"))
12624    (use (label_ref (match_operand 1)))]
12625   "rs6000_speculate_indirect_jumps"
12626   "b%T0"
12627   [(set_attr "type" "jmpreg")])
12629 (define_insn "*tablejump<mode>_internal1_nospec"
12630   [(set (pc)
12631         (match_operand:P 0 "register_operand" "c,*l"))
12632    (use (label_ref (match_operand 1)))
12633    (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12634   "!rs6000_speculate_indirect_jumps"
12635   "crset %E2\;beq%T0- %2\;b $"
12636   [(set_attr "type" "jmpreg")
12637    (set_attr "length" "12")])
12639 (define_insn "nop"
12640   [(unspec [(const_int 0)] UNSPEC_NOP)]
12641   ""
12642   "nop")
12644 (define_insn "group_ending_nop"
12645   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12646   ""
12648   operands[0] = gen_rtx_REG (Pmode,
12649                              rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12650   return "ori %0,%0,0";
12653 (define_insn "speculation_barrier"
12654   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12655   ""
12657   operands[0] = gen_rtx_REG (Pmode, 31);
12658   return "ori %0,%0,0";
12661 ;; Define the subtract-one-and-jump insns, starting with the template
12662 ;; so loop.c knows what to generate.
12664 (define_expand "doloop_end"
12665   [(use (match_operand 0))      ; loop pseudo
12666    (use (match_operand 1))]     ; label
12667   ""
12669   if (GET_MODE (operands[0]) != Pmode)
12670     FAIL;
12672   emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12673   DONE;
12676 (define_expand "@ctr<mode>"
12677   [(parallel [(set (pc)
12678                    (if_then_else (ne (match_operand:P 0 "register_operand")
12679                                      (const_int 1))
12680                                  (label_ref (match_operand 1))
12681                                  (pc)))
12682               (set (match_dup 0)
12683                    (plus:P (match_dup 0)
12684                             (const_int -1)))
12685               (clobber (match_scratch:CC 2))
12686               (clobber (match_scratch:P 3))])]
12687   ""
12688   "")
12690 ;; We need to be able to do this for any operand, including MEM, or we
12691 ;; will cause reload to blow up since we don't allow output reloads on
12692 ;; JUMP_INSNs.
12693 ;; For the length attribute to be calculated correctly, the
12694 ;; label MUST be operand 0.
12695 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12696 ;; the ctr<mode> insns.
12698 (define_code_iterator eqne [eq ne])
12699 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12700 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12702 (define_insn "<bd>_<mode>"
12703   [(set (pc)
12704         (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12705                           (const_int 1))
12706                       (label_ref (match_operand 0))
12707                       (pc)))
12708    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12709         (plus:P (match_dup 1)
12710                 (const_int -1)))
12711    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12712    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12713   ""
12715   if (which_alternative != 0)
12716     return "#";
12717   else if (get_attr_length (insn) == 4)
12718     return "<bd> %l0";
12719   else
12720     return "<bd_neg> $+8\;b %l0";
12722   [(set_attr "type" "branch")
12723    (set_attr_alternative "length"
12724      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12725                              (const_int -32768))
12726                          (lt (minus (match_dup 0) (pc))
12727                              (const_int 32764)))
12728                     (const_int 4)
12729                     (const_int 8))
12730       (const_string "16")
12731       (const_string "20")
12732       (const_string "20")])])
12734 ;; Now the splitter if we could not allocate the CTR register
12735 (define_split
12736   [(set (pc)
12737         (if_then_else (match_operator 2 "comparison_operator"
12738                                       [(match_operand:P 1 "gpc_reg_operand")
12739                                        (const_int 1)])
12740                       (match_operand 5)
12741                       (match_operand 6)))
12742    (set (match_operand:P 0 "nonimmediate_operand")
12743         (plus:P (match_dup 1)
12744                 (const_int -1)))
12745    (clobber (match_scratch:CC 3))
12746    (clobber (match_scratch:P 4))]
12747   "reload_completed"
12748   [(set (pc)
12749         (if_then_else (match_dup 7)
12750                       (match_dup 5)
12751                       (match_dup 6)))]
12753   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12754                                 const0_rtx);
12755   emit_insn (gen_rtx_SET (operands[3],
12756                           gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12757   if (int_reg_operand (operands[0], <MODE>mode))
12758     emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12759   else
12760     {
12761       emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12762       emit_move_insn (operands[0], operands[4]);
12763     } 
12764     /* No DONE so branch comes from the pattern.  */
12767 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12768 ;; Note that in the case of long branches we have to decompose this into
12769 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12770 ;; and the CR bit, which means there is no way to conveniently invert the
12771 ;; comparison as is done with plain bdnz/bdz.
12773 (define_insn "<bd>tf_<mode>"
12774   [(set (pc)
12775         (if_then_else
12776           (and
12777              (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12778                    (const_int 1))
12779              (match_operator 3 "branch_comparison_operator"
12780                       [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12781                        (const_int 0)]))
12782           (label_ref (match_operand 0))
12783           (pc)))
12784    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12785         (plus:P (match_dup 1)
12786                 (const_int -1)))
12787    (clobber (match_scratch:P 5 "=X,X,&r,r"))
12788    (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12789    (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12790   ""
12792   if (which_alternative != 0)
12793     return "#";
12794   else if (get_attr_length (insn) == 4)
12795     {
12796       if (branch_positive_comparison_operator (operands[3],
12797                                                GET_MODE (operands[3])))
12798         return "<bd>t %j3,%l0";
12799       else
12800         return "<bd>f %j3,%l0";
12801     }
12802   else
12803     {
12804       static char seq[96];
12805       char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12806       sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12807       return seq;
12808     }
12810   [(set_attr "type" "branch")
12811    (set_attr_alternative "length"
12812      [(if_then_else (and (ge (minus (match_dup 0) (pc))
12813                              (const_int -32768))
12814                          (lt (minus (match_dup 0) (pc))
12815                              (const_int 32764)))
12816                     (const_int 4)
12817                     (const_int 8))
12818       (const_string "16")
12819       (const_string "20")
12820       (const_string "20")])])
12822 ;; Now the splitter if we could not allocate the CTR register
12823 (define_split
12824   [(set (pc)
12825         (if_then_else
12826           (and
12827              (match_operator 1 "comparison_operator"
12828                              [(match_operand:P 0 "gpc_reg_operand")
12829                               (const_int 1)])
12830              (match_operator 3 "branch_comparison_operator"
12831                       [(match_operand 2 "cc_reg_operand")
12832                        (const_int 0)]))
12833           (match_operand 4)
12834           (match_operand 5)))
12835    (set (match_operand:P 6 "nonimmediate_operand")
12836         (plus:P (match_dup 0)
12837                 (const_int -1)))
12838    (clobber (match_scratch:P 7))
12839    (clobber (match_scratch:CC 8))
12840    (clobber (match_scratch:CCEQ 9))]
12841   "reload_completed"
12842 [(pc)]
12844   rtx ctr = operands[0];
12845   rtx ctrcmp = operands[1];
12846   rtx ccin = operands[2];
12847   rtx cccmp = operands[3];
12848   rtx dst1 = operands[4];
12849   rtx dst2 = operands[5];
12850   rtx ctrout = operands[6];
12851   rtx ctrtmp = operands[7];
12852   enum rtx_code cmpcode = GET_CODE (ctrcmp);
12853   bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12854   if (!ispos)
12855     cmpcode = reverse_condition (cmpcode);
12856   /* Generate crand/crandc here.  */
12857   emit_insn (gen_rtx_SET (operands[8],
12858                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12859   rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12861   rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12862   if (ispos)
12863      emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
12864                                       operands[8], cccmp, ccin));
12865   else
12866      emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12867                                                  operands[8], cccmp, ccin));
12868   if (int_reg_operand (ctrout, <MODE>mode))
12869      emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12870   else
12871     {
12872       emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12873       emit_move_insn (ctrout, ctrtmp);
12874     }
12875   rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12876   emit_jump_insn (gen_rtx_SET (pc_rtx,
12877                                gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12878                                                      dst1, dst2)));
12879   DONE;
12883 (define_insn "trap"
12884   [(trap_if (const_int 1) (const_int 0))]
12885   ""
12886   "trap"
12887   [(set_attr "type" "trap")])
12889 (define_expand "ctrap<mode>4"
12890   [(trap_if (match_operator 0 "ordered_comparison_operator"
12891                             [(match_operand:GPR 1 "register_operand")
12892                              (match_operand:GPR 2 "reg_or_short_operand")])
12893             (match_operand 3 "zero_constant" ""))]
12894   ""
12895   "")
12897 (define_insn ""
12898   [(trap_if (match_operator 0 "ordered_comparison_operator"
12899                             [(match_operand:GPR 1 "register_operand" "r")
12900                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12901             (const_int 0))]
12902   ""
12903   "t<wd>%V0%I2 %1,%2"
12904   [(set_attr "type" "trap")])
12906 ;; Insns related to generating the function prologue and epilogue.
12908 (define_expand "prologue"
12909   [(use (const_int 0))]
12910   ""
12912   rs6000_emit_prologue ();
12913   if (!TARGET_SCHED_PROLOG)
12914     emit_insn (gen_blockage ());
12915   DONE;
12918 (define_insn "*movesi_from_cr_one"
12919   [(match_parallel 0 "mfcr_operation"
12920                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12921                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12922                                      (match_operand 3 "immediate_operand" "n")]
12923                           UNSPEC_MOVESI_FROM_CR))])]
12924   "TARGET_MFCRF"
12926   int mask = 0;
12927   int i;
12928   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12929   {
12930     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12931     operands[4] = GEN_INT (mask);
12932     output_asm_insn ("mfcr %1,%4", operands);
12933   }
12934   return "";
12936   [(set_attr "type" "mfcrf")])
12938 ;; Don't include the volatile CRs since their values are not used wrt CR save
12939 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12940 ;; prologue past an insn (early exit test) that defines a register used in the
12941 ;; prologue.
12942 (define_insn "prologue_movesi_from_cr"
12943   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12944         (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12945                     (reg:CC CR4_REGNO)]
12946                    UNSPEC_MOVESI_FROM_CR))]
12947   ""
12948   "mfcr %0"
12949   [(set_attr "type" "mfcr")])
12951 (define_insn "*crsave"
12952   [(match_parallel 0 "crsave_operation"
12953                    [(set (match_operand:SI 1 "memory_operand" "=m")
12954                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12955   ""
12956   "stw %2,%1"
12957   [(set_attr "type" "store")])
12959 (define_insn "*stmw"
12960   [(match_parallel 0 "stmw_operation"
12961                    [(set (match_operand:SI 1 "memory_operand" "=m")
12962                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12963   "TARGET_MULTIPLE"
12964   "stmw %2,%1"
12965   [(set_attr "type" "store")
12966    (set_attr "update" "yes")
12967    (set_attr "indexed" "yes")])
12969 ; The following comment applies to:
12970 ;     save_gpregs_*
12971 ;     save_fpregs_*
12972 ;     restore_gpregs*
12973 ;     return_and_restore_gpregs*
12974 ;     return_and_restore_fpregs*
12975 ;     return_and_restore_fpregs_aix*
12977 ; The out-of-line save / restore functions expects one input argument.
12978 ; Since those are not standard call_insn's, we must avoid using
12979 ; MATCH_OPERAND for that argument. That way the register rename
12980 ; optimization will not try to rename this register.
12981 ; Each pattern is repeated for each possible register number used in 
12982 ; various ABIs (r11, r1, and for some functions r12)
12984 (define_insn "*save_gpregs_<mode>_r11"
12985   [(match_parallel 0 "any_parallel_operand"
12986                    [(clobber (reg:P LR_REGNO))
12987                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12988                     (use (reg:P 11))
12989                     (set (match_operand:P 2 "memory_operand" "=m")
12990                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12991   ""
12992   "bl %1"
12993   [(set_attr "type" "branch")])
12995 (define_insn "*save_gpregs_<mode>_r12"
12996   [(match_parallel 0 "any_parallel_operand"
12997                    [(clobber (reg:P LR_REGNO))
12998                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12999                     (use (reg:P 12))
13000                     (set (match_operand:P 2 "memory_operand" "=m")
13001                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13002   ""
13003   "bl %1"
13004   [(set_attr "type" "branch")])
13006 (define_insn "*save_gpregs_<mode>_r1"
13007   [(match_parallel 0 "any_parallel_operand"
13008                    [(clobber (reg:P LR_REGNO))
13009                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13010                     (use (reg:P 1))
13011                     (set (match_operand:P 2 "memory_operand" "=m")
13012                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
13013   ""
13014   "bl %1"
13015   [(set_attr "type" "branch")])
13017 (define_insn "*save_fpregs_<mode>_r11"
13018   [(match_parallel 0 "any_parallel_operand"
13019                    [(clobber (reg:P LR_REGNO))
13020                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13021                     (use (reg:P 11))
13022                     (set (match_operand:DF 2 "memory_operand" "=m")
13023                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13024   ""
13025   "bl %1"
13026   [(set_attr "type" "branch")])
13028 (define_insn "*save_fpregs_<mode>_r12"
13029   [(match_parallel 0 "any_parallel_operand"
13030                    [(clobber (reg:P LR_REGNO))
13031                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13032                     (use (reg:P 12))
13033                     (set (match_operand:DF 2 "memory_operand" "=m")
13034                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13035   ""
13036   "bl %1"
13037   [(set_attr "type" "branch")])
13039 (define_insn "*save_fpregs_<mode>_r1"
13040   [(match_parallel 0 "any_parallel_operand"
13041                    [(clobber (reg:P LR_REGNO))
13042                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
13043                     (use (reg:P 1))
13044                     (set (match_operand:DF 2 "memory_operand" "=m")
13045                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13046   ""
13047   "bl %1"
13048   [(set_attr "type" "branch")])
13050 ; This is to explain that changes to the stack pointer should
13051 ; not be moved over loads from or stores to stack memory.
13052 (define_insn "stack_tie"
13053   [(match_parallel 0 "tie_operand"
13054                    [(set (mem:BLK (reg 1)) (const_int 0))])]
13055   ""
13056   ""
13057   [(set_attr "length" "0")])
13059 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13060 ; stay behind all restores from the stack, it cannot be reordered to before
13061 ; one.  See PR77687.  This insn is an add or mr, and a memory clobber.
13062 (define_insn "stack_restore_tie"
13063   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13064         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13065                  (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13066    (set (mem:BLK (scratch)) (const_int 0))]
13067   "TARGET_32BIT"
13068   "@
13069    mr %0,%1
13070    add%I2 %0,%1,%2"
13071   [(set_attr "type" "*,add")])
13073 (define_expand "epilogue"
13074   [(use (const_int 0))]
13075   ""
13077   if (!TARGET_SCHED_PROLOG)
13078     emit_insn (gen_blockage ());
13079   rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13080   DONE;
13083 ; On some processors, doing the mtcrf one CC register at a time is
13084 ; faster (like on the 604e).  On others, doing them all at once is
13085 ; faster; for instance, on the 601 and 750.
13087 (define_expand "movsi_to_cr_one"
13088   [(set (match_operand:CC 0 "cc_reg_operand")
13089         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13090                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13091   ""
13092   "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13094 (define_insn "*movsi_to_cr"
13095   [(match_parallel 0 "mtcrf_operation"
13096                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13097                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13098                                      (match_operand 3 "immediate_operand" "n")]
13099                                     UNSPEC_MOVESI_TO_CR))])]
13100  ""
13102   int mask = 0;
13103   int i;
13104   for (i = 0; i < XVECLEN (operands[0], 0); i++)
13105     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13106   operands[4] = GEN_INT (mask);
13107   return "mtcrf %4,%2";
13109   [(set_attr "type" "mtcr")])
13111 (define_insn "*mtcrfsi"
13112   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13113         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13114                     (match_operand 2 "immediate_operand" "n")]
13115                    UNSPEC_MOVESI_TO_CR))]
13116   "REG_P (operands[0])
13117    && CR_REGNO_P (REGNO (operands[0]))
13118    && CONST_INT_P (operands[2])
13119    && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13120   "mtcrf %R0,%1"
13121   [(set_attr "type" "mtcr")])
13123 ; The load-multiple instructions have similar properties.
13124 ; Note that "load_multiple" is a name known to the machine-independent
13125 ; code that actually corresponds to the PowerPC load-string.
13127 (define_insn "*lmw"
13128   [(match_parallel 0 "lmw_operation"
13129                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13130                          (match_operand:SI 2 "memory_operand" "m"))])]
13131   "TARGET_MULTIPLE"
13132   "lmw %1,%2"
13133   [(set_attr "type" "load")
13134    (set_attr "update" "yes")
13135    (set_attr "indexed" "yes")
13136    (set_attr "cell_micro" "always")])
13138 ; FIXME: "any_parallel_operand" is a bit flexible...
13140 ; The following comment applies to:
13141 ;     save_gpregs_*
13142 ;     save_fpregs_*
13143 ;     restore_gpregs*
13144 ;     return_and_restore_gpregs*
13145 ;     return_and_restore_fpregs*
13146 ;     return_and_restore_fpregs_aix*
13148 ; The out-of-line save / restore functions expects one input argument.
13149 ; Since those are not standard call_insn's, we must avoid using
13150 ; MATCH_OPERAND for that argument. That way the register rename
13151 ; optimization will not try to rename this register.
13152 ; Each pattern is repeated for each possible register number used in 
13153 ; various ABIs (r11, r1, and for some functions r12)
13155 (define_insn "*restore_gpregs_<mode>_r11"
13156  [(match_parallel 0 "any_parallel_operand"
13157                   [(clobber (reg:P LR_REGNO))
13158                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13159                    (use (reg:P 11))
13160                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13161                         (match_operand:P 3 "memory_operand" "m"))])]
13162  ""
13163  "bl %1"
13164  [(set_attr "type" "branch")])
13166 (define_insn "*restore_gpregs_<mode>_r12"
13167  [(match_parallel 0 "any_parallel_operand"
13168                   [(clobber (reg:P LR_REGNO))
13169                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13170                    (use (reg:P 12))
13171                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13172                         (match_operand:P 3 "memory_operand" "m"))])]
13173  ""
13174  "bl %1"
13175  [(set_attr "type" "branch")])
13177 (define_insn "*restore_gpregs_<mode>_r1"
13178  [(match_parallel 0 "any_parallel_operand"
13179                   [(clobber (reg:P LR_REGNO))
13180                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13181                    (use (reg:P 1))
13182                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13183                         (match_operand:P 3 "memory_operand" "m"))])]
13184  ""
13185  "bl %1"
13186  [(set_attr "type" "branch")])
13188 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13189  [(match_parallel 0 "any_parallel_operand"
13190                   [(return)
13191                    (clobber (reg:P LR_REGNO))
13192                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13193                    (use (reg:P 11))
13194                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13195                         (match_operand:P 3 "memory_operand" "m"))])]
13196  ""
13197  "b %1"
13198  [(set_attr "type" "branch")])
13200 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13201  [(match_parallel 0 "any_parallel_operand"
13202                   [(return)
13203                    (clobber (reg:P LR_REGNO))
13204                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13205                    (use (reg:P 12))
13206                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13207                         (match_operand:P 3 "memory_operand" "m"))])]
13208  ""
13209  "b %1"
13210  [(set_attr "type" "branch")])
13212 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13213  [(match_parallel 0 "any_parallel_operand"
13214                   [(return)
13215                    (clobber (reg:P LR_REGNO))
13216                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13217                    (use (reg:P 1))
13218                    (set (match_operand:P 2 "gpc_reg_operand" "=r")
13219                         (match_operand:P 3 "memory_operand" "m"))])]
13220  ""
13221  "b %1"
13222  [(set_attr "type" "branch")])
13224 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13225  [(match_parallel 0 "any_parallel_operand"
13226                   [(return)
13227                    (clobber (reg:P LR_REGNO))
13228                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13229                    (use (reg:P 11))
13230                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13231                         (match_operand:DF 3 "memory_operand" "m"))])]
13232  ""
13233  "b %1"
13234  [(set_attr "type" "branch")])
13236 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13237  [(match_parallel 0 "any_parallel_operand"
13238                   [(return)
13239                    (clobber (reg:P LR_REGNO))
13240                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13241                    (use (reg:P 12))
13242                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13243                         (match_operand:DF 3 "memory_operand" "m"))])]
13244  ""
13245  "b %1"
13246  [(set_attr "type" "branch")])
13248 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13249  [(match_parallel 0 "any_parallel_operand"
13250                   [(return)
13251                    (clobber (reg:P LR_REGNO))
13252                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13253                    (use (reg:P 1))
13254                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13255                         (match_operand:DF 3 "memory_operand" "m"))])]
13256  ""
13257  "b %1"
13258  [(set_attr "type" "branch")])
13260 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13261  [(match_parallel 0 "any_parallel_operand"
13262                   [(return)
13263                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13264                    (use (reg:P 11))
13265                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13266                         (match_operand:DF 3 "memory_operand" "m"))])]
13267  ""
13268  "b %1"
13269  [(set_attr "type" "branch")])
13271 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13272  [(match_parallel 0 "any_parallel_operand"
13273                   [(return)
13274                    (use (match_operand:P 1 "symbol_ref_operand" "s"))
13275                    (use (reg:P 1))
13276                    (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13277                         (match_operand:DF 3 "memory_operand" "m"))])]
13278  ""
13279  "b %1"
13280  [(set_attr "type" "branch")])
13282 ; This is used in compiling the unwind routines.
13283 (define_expand "eh_return"
13284   [(use (match_operand 0 "general_operand"))]
13285   ""
13287   emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13288   DONE;
13291 ; We can't expand this before we know where the link register is stored.
13292 (define_insn_and_split "@eh_set_lr_<mode>"
13293   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13294    (clobber (match_scratch:P 1 "=&b"))]
13295   ""
13296   "#"
13297   "reload_completed"
13298   [(const_int 0)]
13300   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13301   DONE;
13304 (define_insn "prefetch"
13305   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13306              (match_operand:SI 1 "const_int_operand" "n")
13307              (match_operand:SI 2 "const_int_operand" "n"))]
13308   ""
13312   /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13313      AIX does not support the dcbtstt and dcbtt extended mnemonics.
13314      The AIX assembler does not support the three operand form of dcbt
13315      and dcbtst on Power 7 (-mpwr7).  */
13316   int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13318   if (REG_P (operands[0]))
13319     {
13320       if (INTVAL (operands[1]) == 0)
13321         return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13322       else
13323         return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13324     }
13325   else
13326     {
13327       if (INTVAL (operands[1]) == 0)
13328         return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13329       else
13330         return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13331     }
13333   [(set_attr "type" "load")])
13335 ;; Handle -fsplit-stack.
13337 (define_expand "split_stack_prologue"
13338   [(const_int 0)]
13339   ""
13341   rs6000_expand_split_stack_prologue ();
13342   DONE;
13345 (define_expand "load_split_stack_limit"
13346   [(set (match_operand 0)
13347         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13348   ""
13350   emit_insn (gen_rtx_SET (operands[0],
13351                           gen_rtx_UNSPEC (Pmode,
13352                                           gen_rtvec (1, const0_rtx),
13353                                           UNSPEC_STACK_CHECK)));
13354   DONE;
13357 (define_insn "load_split_stack_limit_di"
13358   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13359         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13360   "TARGET_64BIT"
13361   "ld %0,-0x7040(13)"
13362   [(set_attr "type" "load")
13363    (set_attr "update" "no")
13364    (set_attr "indexed" "no")])
13366 (define_insn "load_split_stack_limit_si"
13367   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13368         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13369   "!TARGET_64BIT"
13370   "lwz %0,-0x7020(2)"
13371   [(set_attr "type" "load")
13372    (set_attr "update" "no")
13373    (set_attr "indexed" "no")])
13375 ;; A return instruction which the middle-end doesn't see.
13376 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13377 ;; after the call to __morestack.
13378 (define_insn "split_stack_return"
13379   [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13380   ""
13381   "blr"
13382   [(set_attr "type" "jmpreg")])
13384 ;; If there are operand 0 bytes available on the stack, jump to
13385 ;; operand 1.
13386 (define_expand "split_stack_space_check"
13387   [(set (match_dup 2)
13388         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13389    (set (match_dup 3)
13390         (minus (reg STACK_POINTER_REGNUM)
13391                (match_operand 0)))
13392    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13393    (set (pc) (if_then_else
13394               (geu (match_dup 4) (const_int 0))
13395               (label_ref (match_operand 1))
13396               (pc)))]
13397   ""
13399   rs6000_split_stack_space_check (operands[0], operands[1]);
13400   DONE;
13403 (define_insn "bpermd_<mode>"
13404   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13405         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13406                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13407   "TARGET_POPCNTD"
13408   "bpermd %0,%1,%2"
13409   [(set_attr "type" "popcnt")])
13412 ;; Builtin fma support.  Handle 
13413 ;; Note that the conditions for expansion are in the FMA_F iterator.
13415 (define_expand "fma<mode>4"
13416   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13417         (fma:FMA_F
13418           (match_operand:FMA_F 1 "gpc_reg_operand")
13419           (match_operand:FMA_F 2 "gpc_reg_operand")
13420           (match_operand:FMA_F 3 "gpc_reg_operand")))]
13421   ""
13422   "")
13424 (define_insn "*fma<mode>4_fpr"
13425   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13426         (fma:SFDF
13427           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13428           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13429           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13430   "TARGET_HARD_FLOAT"
13431   "@
13432    fmadd<s> %0,%1,%2,%3
13433    xsmadda<sd>p %x0,%x1,%x2
13434    xsmaddm<sd>p %x0,%x1,%x3"
13435   [(set_attr "type" "fp")
13436    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13438 ; Altivec only has fma and nfms.
13439 (define_expand "fms<mode>4"
13440   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13441         (fma:FMA_F
13442           (match_operand:FMA_F 1 "gpc_reg_operand")
13443           (match_operand:FMA_F 2 "gpc_reg_operand")
13444           (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13445   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13446   "")
13448 (define_insn "*fms<mode>4_fpr"
13449   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13450         (fma:SFDF
13451          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13452          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13453          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13454   "TARGET_HARD_FLOAT"
13455   "@
13456    fmsub<s> %0,%1,%2,%3
13457    xsmsuba<sd>p %x0,%x1,%x2
13458    xsmsubm<sd>p %x0,%x1,%x3"
13459   [(set_attr "type" "fp")
13460    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13462 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13463 (define_expand "fnma<mode>4"
13464   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13465         (neg:FMA_F
13466           (fma:FMA_F
13467             (match_operand:FMA_F 1 "gpc_reg_operand")
13468             (match_operand:FMA_F 2 "gpc_reg_operand")
13469             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13470   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13471   "")
13473 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13474 (define_expand "fnms<mode>4"
13475   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13476         (neg:FMA_F
13477           (fma:FMA_F
13478             (match_operand:FMA_F 1 "gpc_reg_operand")
13479             (match_operand:FMA_F 2 "gpc_reg_operand")
13480             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13481   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13482   "")
13484 ; Not an official optab name, but used from builtins.
13485 (define_expand "nfma<mode>4"
13486   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13487         (neg:FMA_F
13488           (fma:FMA_F
13489             (match_operand:FMA_F 1 "gpc_reg_operand")
13490             (match_operand:FMA_F 2 "gpc_reg_operand")
13491             (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13492   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13493   "")
13495 (define_insn "*nfma<mode>4_fpr"
13496   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13497         (neg:SFDF
13498          (fma:SFDF
13499           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13500           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13501           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13502   "TARGET_HARD_FLOAT"
13503   "@
13504    fnmadd<s> %0,%1,%2,%3
13505    xsnmadda<sd>p %x0,%x1,%x2
13506    xsnmaddm<sd>p %x0,%x1,%x3"
13507   [(set_attr "type" "fp")
13508    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13510 ; Not an official optab name, but used from builtins.
13511 (define_expand "nfms<mode>4"
13512   [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13513         (neg:FMA_F
13514           (fma:FMA_F
13515             (match_operand:FMA_F 1 "gpc_reg_operand")
13516             (match_operand:FMA_F 2 "gpc_reg_operand")
13517             (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13518   ""
13519   "")
13521 (define_insn "*nfmssf4_fpr"
13522   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13523         (neg:SFDF
13524          (fma:SFDF
13525           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13526           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13527           (neg:SFDF
13528            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13529   "TARGET_HARD_FLOAT"
13530   "@
13531    fnmsub<s> %0,%1,%2,%3
13532    xsnmsuba<sd>p %x0,%x1,%x2
13533    xsnmsubm<sd>p %x0,%x1,%x3"
13534   [(set_attr "type" "fp")
13535    (set_attr "isa" "*,<Fisa>,<Fisa>")])
13537 (define_expand "rs6000_get_timebase"
13538   [(use (match_operand:DI 0 "gpc_reg_operand"))]
13539   ""
13541   if (TARGET_POWERPC64)
13542     emit_insn (gen_rs6000_mftb_di (operands[0]));
13543   else
13544     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13545   DONE;
13548 (define_insn "rs6000_get_timebase_ppc32"
13549   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13550         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13551    (clobber (match_scratch:SI 1 "=r"))
13552    (clobber (match_scratch:CC 2 "=y"))]
13553   "!TARGET_POWERPC64"
13555   if (WORDS_BIG_ENDIAN)
13556     if (TARGET_MFCRF)
13557       {
13558         return "mfspr %0,269\;"
13559                "mfspr %L0,268\;"
13560                "mfspr %1,269\;"
13561                "cmpw %2,%0,%1\;"
13562                "bne- %2,$-16";
13563       }
13564     else
13565       {
13566         return "mftbu %0\;"
13567                "mftb %L0\;"
13568                "mftbu %1\;"
13569                "cmpw %2,%0,%1\;"
13570                "bne- %2,$-16";
13571       }
13572   else
13573     if (TARGET_MFCRF)
13574       {
13575         return "mfspr %L0,269\;"
13576                "mfspr %0,268\;"
13577                "mfspr %1,269\;"
13578                "cmpw %2,%L0,%1\;"
13579                "bne- %2,$-16";
13580       }
13581     else
13582       {
13583         return "mftbu %L0\;"
13584                "mftb %0\;"
13585                "mftbu %1\;"
13586                "cmpw %2,%L0,%1\;"
13587                "bne- %2,$-16";
13588       }
13590   [(set_attr "length" "20")])
13592 (define_insn "rs6000_mftb_<mode>"
13593   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13594         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13595   ""
13597   if (TARGET_MFCRF)
13598     return "mfspr %0,268";
13599   else
13600     return "mftb %0";
13604 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13605 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13606 (define_insn "rs6000_mffsl_hw"
13607   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13608         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13609   "TARGET_HARD_FLOAT"
13610   "mffsl %0")
13612 (define_expand "rs6000_mffsl"
13613   [(set (match_operand:DF 0 "gpc_reg_operand")
13614         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13615   "TARGET_HARD_FLOAT"
13617   /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13618      otherwise fall back to the older mffs instruction to emulate the mffsl
13619      instruction.  */
13621   if (!TARGET_P9_MISC)
13622     {
13623       rtx tmp1 = gen_reg_rtx (DFmode);
13625       /* The mffs instruction reads the entire FPSCR.  Emulate the mffsl
13626          instruction using the mffs instruction and masking the result.  */
13627       emit_insn (gen_rs6000_mffs (tmp1));
13629       rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
13630       rtx tmp2 = gen_reg_rtx (DImode);
13631       emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
13633       rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
13634       emit_move_insn (operands[0], tmp2df);
13635       DONE;
13636     }
13638     emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13639     DONE;
13642 (define_insn "rs6000_mffs"
13643   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13644         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13645   "TARGET_HARD_FLOAT"
13646   "mffs %0")
13648 (define_insn "rs6000_mtfsf"
13649   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13650                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13651                     UNSPECV_MTFSF)]
13652   "TARGET_HARD_FLOAT"
13653   "mtfsf %0,%1")
13655 (define_insn "rs6000_mtfsf_hi"
13656   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13657                      (match_operand:DF 1 "gpc_reg_operand" "d")]
13658                     UNSPECV_MTFSF_HI)]
13659   "TARGET_HARD_FLOAT"
13660   "mtfsf %0,%1,0,1")
13663 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13664 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
13665 ;; register that is being loaded.  The fused ops must be physically adjacent.
13667 ;; On Power8 GPR loads, we try to use the register that is being load.  The
13668 ;; peephole2 then gathers any other fused possibilities that it can find after
13669 ;; register allocation.  If power9 fusion is selected, we also fuse floating
13670 ;; point loads/stores.
13672 ;; Find cases where the addis that feeds into a load instruction is either used
13673 ;; once or is the same as the target register, and replace it with the fusion
13674 ;; insn
13676 (define_peephole2
13677   [(set (match_operand:P 0 "base_reg_operand")
13678         (match_operand:P 1 "fusion_gpr_addis"))
13679    (set (match_operand:INT1 2 "base_reg_operand")
13680         (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13681   "TARGET_P8_FUSION
13682    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13683                          operands[3])"
13684   [(const_int 0)]
13686   expand_fusion_gpr_load (operands);
13687   DONE;
13690 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13691 ;; reload)
13693 (define_insn "*fusion_gpr_load_<mode>"
13694   [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13695         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13696                      UNSPEC_FUSION_GPR))]
13697   "TARGET_P8_FUSION"
13699   return emit_fusion_gpr_load (operands[0], operands[1]);
13701   [(set_attr "type" "load")
13702    (set_attr "length" "8")])
13705 ;; Optimize cases where we want to do a D-form load (register+offset) on
13706 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13707 ;; has generated:
13708 ;;      LFD 0,32(3)
13709 ;;      XXLOR 32,0,0
13711 ;; and we change this to:
13712 ;;      LI 0,32
13713 ;;      LXSDX 32,3,9
13715 (define_peephole2
13716   [(match_scratch:P 0 "b")
13717    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13718         (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13719    (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13720         (match_dup 1))]
13721   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13722   [(set (match_dup 0)
13723         (match_dup 4))
13724    (set (match_dup 3)
13725         (match_dup 5))]
13727   rtx tmp_reg = operands[0];
13728   rtx mem = operands[2];
13729   rtx addr = XEXP (mem, 0);
13730   rtx add_op0, add_op1, new_addr;
13732   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13733   add_op0 = XEXP (addr, 0);
13734   add_op1 = XEXP (addr, 1);
13735   gcc_assert (REG_P (add_op0));
13736   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13738   operands[4] = add_op1;
13739   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13742 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13743 ;; Altivec register, and the register allocator has generated:
13744 ;;      XXLOR 0,32,32
13745 ;;      STFD 0,32(3)
13747 ;; and we change this to:
13748 ;;      LI 0,32
13749 ;;      STXSDX 32,3,9
13751 (define_peephole2
13752   [(match_scratch:P 0 "b")
13753    (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13754         (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13755    (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13756         (match_dup 1))]
13757   "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13758   [(set (match_dup 0)
13759         (match_dup 4))
13760    (set (match_dup 5)
13761         (match_dup 2))]
13763   rtx tmp_reg = operands[0];
13764   rtx mem = operands[3];
13765   rtx addr = XEXP (mem, 0);
13766   rtx add_op0, add_op1, new_addr;
13768   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13769   add_op0 = XEXP (addr, 0);
13770   add_op1 = XEXP (addr, 1);
13771   gcc_assert (REG_P (add_op0));
13772   new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13774   operands[4] = add_op1;
13775   operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13777    
13779 ;; Miscellaneous ISA 2.06 (power7) instructions
13780 (define_insn "addg6s"
13781   [(set (match_operand:SI 0 "register_operand" "=r")
13782         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13783                     (match_operand:SI 2 "register_operand" "r")]
13784                    UNSPEC_ADDG6S))]
13785   "TARGET_POPCNTD"
13786   "addg6s %0,%1,%2"
13787   [(set_attr "type" "integer")])
13789 (define_insn "cdtbcd"
13790   [(set (match_operand:SI 0 "register_operand" "=r")
13791         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13792                    UNSPEC_CDTBCD))]
13793   "TARGET_POPCNTD"
13794   "cdtbcd %0,%1"
13795   [(set_attr "type" "integer")])
13797 (define_insn "cbcdtd"
13798   [(set (match_operand:SI 0 "register_operand" "=r")
13799         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13800                    UNSPEC_CBCDTD))]
13801   "TARGET_POPCNTD"
13802   "cbcdtd %0,%1"
13803   [(set_attr "type" "integer")])
13805 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13806                                         UNSPEC_DIVEU])
13808 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13809                              (UNSPEC_DIVEU      "eu")])
13811 (define_insn "div<div_extend>_<mode>"
13812   [(set (match_operand:GPR 0 "register_operand" "=r")
13813         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13814                      (match_operand:GPR 2 "register_operand" "r")]
13815                     UNSPEC_DIV_EXTEND))]
13816   "TARGET_POPCNTD"
13817   "div<wd><div_extend> %0,%1,%2"
13818   [(set_attr "type" "div")
13819    (set_attr "size" "<bits>")])
13822 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13824 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13825 (define_mode_attr FP128_64 [(TF "DF")
13826                             (IF "DF")
13827                             (TD "DI")
13828                             (KF "DI")])
13830 (define_expand "unpack<mode>"
13831   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13832         (unspec:<FP128_64>
13833          [(match_operand:FMOVE128 1 "register_operand")
13834           (match_operand:QI 2 "const_0_to_1_operand")]
13835          UNSPEC_UNPACK_128BIT))]
13836   "FLOAT128_2REG_P (<MODE>mode)"
13837   "")
13839 (define_insn_and_split "unpack<mode>_dm"
13840   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13841         (unspec:<FP128_64>
13842          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13843           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13844          UNSPEC_UNPACK_128BIT))]
13845   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13846   "#"
13847   "&& reload_completed"
13848   [(set (match_dup 0) (match_dup 3))]
13850   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13852   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13853     {
13854       emit_note (NOTE_INSN_DELETED);
13855       DONE;
13856     }
13858   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13860   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13862 (define_insn_and_split "unpack<mode>_nodm"
13863   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13864         (unspec:<FP128_64>
13865          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13866           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13867          UNSPEC_UNPACK_128BIT))]
13868   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13869   "#"
13870   "&& reload_completed"
13871   [(set (match_dup 0) (match_dup 3))]
13873   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13875   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13876     {
13877       emit_note (NOTE_INSN_DELETED);
13878       DONE;
13879     }
13881   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13883   [(set_attr "type" "fp,fpstore")])
13885 (define_insn_and_split "pack<mode>"
13886   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13887         (unspec:FMOVE128
13888          [(match_operand:<FP128_64> 1 "register_operand" "d")
13889           (match_operand:<FP128_64> 2 "register_operand" "d")]
13890          UNSPEC_PACK_128BIT))]
13891   "FLOAT128_2REG_P (<MODE>mode)"
13892   "#"
13893   "&& reload_completed"
13894   [(set (match_dup 3) (match_dup 1))
13895    (set (match_dup 4) (match_dup 2))]
13897   unsigned dest_hi = REGNO (operands[0]);
13898   unsigned dest_lo = dest_hi + 1;
13900   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13901   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13903   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13904   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13906   [(set_attr "type" "fp")
13907    (set_attr "length" "8")])
13909 (define_insn "unpack<mode>"
13910   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13911         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13912                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13913          UNSPEC_UNPACK_128BIT))]
13914   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13916   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13917     return ASM_COMMENT_START " xxpermdi to same register";
13919   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13920   return "xxpermdi %x0,%x1,%x1,%3";
13922   [(set_attr "type" "vecperm")])
13924 (define_insn "pack<mode>"
13925   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13926         (unspec:FMOVE128_VSX
13927          [(match_operand:DI 1 "register_operand" "wa")
13928           (match_operand:DI 2 "register_operand" "wa")]
13929          UNSPEC_PACK_128BIT))]
13930   "TARGET_VSX"
13931   "xxpermdi %x0,%x1,%x2,0"
13932   [(set_attr "type" "vecperm")])
13936 ;; ISA 2.08 IEEE 128-bit floating point support.
13938 (define_insn "add<mode>3"
13939   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13940         (plus:IEEE128
13941          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13942          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13943   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13944   "xsaddqp %0,%1,%2"
13945   [(set_attr "type" "vecfloat")
13946    (set_attr "size" "128")])
13948 (define_insn "sub<mode>3"
13949   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13950         (minus:IEEE128
13951          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13952          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13953   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13954   "xssubqp %0,%1,%2"
13955   [(set_attr "type" "vecfloat")
13956    (set_attr "size" "128")])
13958 (define_insn "mul<mode>3"
13959   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13960         (mult:IEEE128
13961          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13962          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13963   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13964   "xsmulqp %0,%1,%2"
13965   [(set_attr "type" "qmul")
13966    (set_attr "size" "128")])
13968 (define_insn "div<mode>3"
13969   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13970         (div:IEEE128
13971          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13972          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13973   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13974   "xsdivqp %0,%1,%2"
13975   [(set_attr "type" "vecdiv")
13976    (set_attr "size" "128")])
13978 (define_insn "sqrt<mode>2"
13979   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13980         (sqrt:IEEE128
13981          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13982   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13983    "xssqrtqp %0,%1"
13984   [(set_attr "type" "vecdiv")
13985    (set_attr "size" "128")])
13987 (define_expand "copysign<mode>3"
13988   [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13989    (use (match_operand:IEEE128 1 "altivec_register_operand"))
13990    (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13991   "FLOAT128_IEEE_P (<MODE>mode)"
13993   if (TARGET_FLOAT128_HW)
13994     emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13995                                          operands[2]));
13996   else
13997     emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13998                                          operands[2]));
13999   DONE;
14002 (define_insn "copysign<mode>3_hard"
14003   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14004         (unspec:IEEE128
14005          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14006           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14007          UNSPEC_COPYSIGN))]
14008   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14009    "xscpsgnqp %0,%2,%1"
14010   [(set_attr "type" "vecmove")
14011    (set_attr "size" "128")])
14013 (define_insn "copysign<mode>3_soft"
14014   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14015         (unspec:IEEE128
14016          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14017           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14018          UNSPEC_COPYSIGN))
14019    (clobber (match_scratch:IEEE128 3 "=&v"))]
14020   "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14021    "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14022   [(set_attr "type" "veccomplex")
14023    (set_attr "length" "8")])
14025 (define_insn "@neg<mode>2_hw"
14026   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14027         (neg:IEEE128
14028          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14029   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14030   "xsnegqp %0,%1"
14031   [(set_attr "type" "vecmove")
14032    (set_attr "size" "128")])
14035 (define_insn "@abs<mode>2_hw"
14036   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14037         (abs:IEEE128
14038          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14039   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14040   "xsabsqp %0,%1"
14041   [(set_attr "type" "vecmove")
14042    (set_attr "size" "128")])
14045 (define_insn "*nabs<mode>2_hw"
14046   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14047         (neg:IEEE128
14048          (abs:IEEE128
14049           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14050   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14051   "xsnabsqp %0,%1"
14052   [(set_attr "type" "vecmove")
14053    (set_attr "size" "128")])
14055 ;; Initially don't worry about doing fusion
14056 (define_insn "fma<mode>4_hw"
14057   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14058         (fma:IEEE128
14059          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14060          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14061          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14062   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14063   "xsmaddqp %0,%1,%2"
14064   [(set_attr "type" "qmul")
14065    (set_attr "size" "128")])
14067 (define_insn "*fms<mode>4_hw"
14068   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14069         (fma:IEEE128
14070          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14071          (match_operand:IEEE128 2 "altivec_register_operand" "v")
14072          (neg:IEEE128
14073           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14074   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14075   "xsmsubqp %0,%1,%2"
14076   [(set_attr "type" "qmul")
14077    (set_attr "size" "128")])
14079 (define_insn "*nfma<mode>4_hw"
14080   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14081         (neg:IEEE128
14082          (fma:IEEE128
14083           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14084           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14085           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14086   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14087   "xsnmaddqp %0,%1,%2"
14088   [(set_attr "type" "qmul")
14089    (set_attr "size" "128")])
14091 (define_insn "*nfms<mode>4_hw"
14092   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14093         (neg:IEEE128
14094          (fma:IEEE128
14095           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14096           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14097           (neg:IEEE128
14098            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14099   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14100   "xsnmsubqp %0,%1,%2"
14101   [(set_attr "type" "qmul")
14102    (set_attr "size" "128")])
14104 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14105   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14106         (float_extend:IEEE128
14107          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14108   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14109   "xscvdpqp %0,%1"
14110   [(set_attr "type" "vecfloat")
14111    (set_attr "size" "128")])
14113 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14114 ;; point is a simple copy.
14115 (define_insn_and_split "extendkftf2"
14116   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14117         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14118   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14119   "@
14120    #
14121    xxlor %x0,%x1,%x1"
14122   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14123   [(const_int 0)]
14125   emit_note (NOTE_INSN_DELETED);
14126   DONE;
14128   [(set_attr "type" "*,veclogical")
14129    (set_attr "length" "0,4")])
14131 (define_insn_and_split "trunctfkf2"
14132   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14133         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14134   "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14135   "@
14136    #
14137    xxlor %x0,%x1,%x1"
14138   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
14139   [(const_int 0)]
14141   emit_note (NOTE_INSN_DELETED);
14142   DONE;
14144   [(set_attr "type" "*,veclogical")
14145    (set_attr "length" "0,4")])
14147 (define_insn "trunc<mode>df2_hw"
14148   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14149         (float_truncate:DF
14150          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14151   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14152   "xscvqpdp %0,%1"
14153   [(set_attr "type" "vecfloat")
14154    (set_attr "size" "128")])
14156 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14157 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14158 ;; conversion
14159 (define_insn_and_split "trunc<mode>sf2_hw"
14160   [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14161         (float_truncate:SF
14162          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14163    (clobber (match_scratch:DF 2 "=v"))]
14164   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14165   "#"
14166   "&& 1"
14167   [(set (match_dup 2)
14168         (unspec:DF [(match_dup 1)]
14169                    UNSPEC_TRUNC_ROUND_TO_ODD))
14170    (set (match_dup 0)
14171         (float_truncate:SF (match_dup 2)))]
14173   if (GET_CODE (operands[2]) == SCRATCH)
14174     operands[2] = gen_reg_rtx (DFmode);
14176   [(set_attr "type" "vecfloat")
14177    (set_attr "length" "8")
14178    (set_attr "isa" "p8v")])
14180 ;; Conversion between IEEE 128-bit and integer types
14182 ;; The fix function for DImode and SImode was declared earlier as a
14183 ;; define_expand.  It calls into rs6000_expand_float128_convert if we don't
14184 ;; have IEEE 128-bit hardware support.  QImode and HImode are not provided
14185 ;; unless we have the IEEE 128-bit hardware.
14187 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14188 ;; to provide a GPR target that used direct move and a conversion in the GPR
14189 ;; which works around QImode/HImode not being allowed in vector registers in
14190 ;; ISA 2.07 (power8).
14191 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14192   [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14193         (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14194   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14195   "xscvqp<su><wd>z %0,%1"
14196   [(set_attr "type" "vecfloat")
14197    (set_attr "size" "128")])
14199 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14200   [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14201         (any_fix:QHI
14202          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14203   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14204   "xscvqp<su>wz %0,%1"
14205   [(set_attr "type" "vecfloat")
14206    (set_attr "size" "128")])
14208 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14209 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14210 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14211   [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14212         (any_fix:QHSI
14213          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14214    (clobber (match_scratch:QHSI 2 "=v"))]
14215   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14216   "#"
14217   "&& reload_completed"
14218   [(set (match_dup 2)
14219         (any_fix:QHSI (match_dup 1)))
14220    (set (match_dup 0)
14221         (match_dup 2))])
14223 (define_insn "float_<mode>di2_hw"
14224   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14225         (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14226   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14227   "xscvsdqp %0,%1"
14228   [(set_attr "type" "vecfloat")
14229    (set_attr "size" "128")])
14231 (define_insn_and_split "float_<mode>si2_hw"
14232   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14233         (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14234    (clobber (match_scratch:DI 2 "=v"))]
14235   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14236   "#"
14237   "&& 1"
14238   [(set (match_dup 2)
14239         (sign_extend:DI (match_dup 1)))
14240    (set (match_dup 0)
14241         (float:IEEE128 (match_dup 2)))]
14243   if (GET_CODE (operands[2]) == SCRATCH)
14244     operands[2] = gen_reg_rtx (DImode);
14246   if (MEM_P (operands[1]))
14247     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14250 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14251   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14252         (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14253    (clobber (match_scratch:DI 2 "=X,r,X"))]
14254   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14255   "#"
14256   "&& reload_completed"
14257   [(const_int 0)]
14259   rtx dest = operands[0];
14260   rtx src = operands[1];
14261   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14263   if (altivec_register_operand (src, <QHI:MODE>mode))
14264     emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14265   else if (int_reg_operand (src, <QHI:MODE>mode))
14266     {
14267       rtx ext_di = operands[2];
14268       emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14269       emit_move_insn (dest_di, ext_di);
14270     }
14271   else if (MEM_P (src))
14272     {
14273       rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14274       emit_move_insn (dest_qhi, src);
14275       emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14276     }
14277   else
14278     gcc_unreachable ();
14280   emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14281   DONE;
14283   [(set_attr "length" "8,12,12")
14284    (set_attr "type" "vecfloat")
14285    (set_attr "size" "128")])
14287 (define_insn "floatuns_<mode>di2_hw"
14288   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14289         (unsigned_float:IEEE128
14290          (match_operand:DI 1 "altivec_register_operand" "v")))]
14291   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14292   "xscvudqp %0,%1"
14293   [(set_attr "type" "vecfloat")
14294    (set_attr "size" "128")])
14296 (define_insn_and_split "floatuns_<mode>si2_hw"
14297   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298         (unsigned_float:IEEE128
14299          (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14300    (clobber (match_scratch:DI 2 "=v"))]
14301   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14302   "#"
14303   "&& 1"
14304   [(set (match_dup 2)
14305         (zero_extend:DI (match_dup 1)))
14306    (set (match_dup 0)
14307         (float:IEEE128 (match_dup 2)))]
14309   if (GET_CODE (operands[2]) == SCRATCH)
14310     operands[2] = gen_reg_rtx (DImode);
14312   if (MEM_P (operands[1]))
14313     operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14316 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14317   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14318         (unsigned_float:IEEE128
14319          (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14320    (clobber (match_scratch:DI 2 "=X,r,X"))]
14321   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14322   "#"
14323   "&& reload_completed"
14324   [(const_int 0)]
14326   rtx dest = operands[0];
14327   rtx src = operands[1];
14328   rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14330   if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14331     emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14332   else if (int_reg_operand (src, <QHI:MODE>mode))
14333     {
14334       rtx ext_di = operands[2];
14335       emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14336       emit_move_insn (dest_di, ext_di);
14337     }
14338   else
14339     gcc_unreachable ();
14341   emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14342   DONE;
14344   [(set_attr "length" "8,12,8")
14345    (set_attr "type" "vecfloat")
14346    (set_attr "size" "128")])
14348 ;; IEEE 128-bit round to integer built-in functions
14349 (define_insn "floor<mode>2"
14350   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14351         (unspec:IEEE128
14352          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14353          UNSPEC_FRIM))]
14354   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14355   "xsrqpi 1,%0,%1,3"
14356   [(set_attr "type" "vecfloat")
14357    (set_attr "size" "128")])
14359 (define_insn "ceil<mode>2"
14360   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14361         (unspec:IEEE128
14362          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14363          UNSPEC_FRIP))]
14364   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14365   "xsrqpi 1,%0,%1,2"
14366   [(set_attr "type" "vecfloat")
14367    (set_attr "size" "128")])
14369 (define_insn "btrunc<mode>2"
14370   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14371         (unspec:IEEE128
14372          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14373          UNSPEC_FRIZ))]
14374   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14375   "xsrqpi 1,%0,%1,1"
14376   [(set_attr "type" "vecfloat")
14377    (set_attr "size" "128")])
14379 (define_insn "round<mode>2"
14380   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14381         (unspec:IEEE128
14382          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14383          UNSPEC_FRIN))]
14384   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14385   "xsrqpi 0,%0,%1,0"
14386   [(set_attr "type" "vecfloat")
14387    (set_attr "size" "128")])
14389 ;; IEEE 128-bit instructions with round to odd semantics
14390 (define_insn "add<mode>3_odd"
14391   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14392         (unspec:IEEE128
14393          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14394           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14395          UNSPEC_ADD_ROUND_TO_ODD))]
14396   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14397   "xsaddqpo %0,%1,%2"
14398   [(set_attr "type" "vecfloat")
14399    (set_attr "size" "128")])
14401 (define_insn "sub<mode>3_odd"
14402   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14403         (unspec:IEEE128
14404          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14405           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14406          UNSPEC_SUB_ROUND_TO_ODD))]
14407   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14408   "xssubqpo %0,%1,%2"
14409   [(set_attr "type" "vecfloat")
14410    (set_attr "size" "128")])
14412 (define_insn "mul<mode>3_odd"
14413   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14414         (unspec:IEEE128
14415          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14416           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14417          UNSPEC_MUL_ROUND_TO_ODD))]
14418   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14419   "xsmulqpo %0,%1,%2"
14420   [(set_attr "type" "qmul")
14421    (set_attr "size" "128")])
14423 (define_insn "div<mode>3_odd"
14424   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14425         (unspec:IEEE128
14426          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14427           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14428          UNSPEC_DIV_ROUND_TO_ODD))]
14429   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14430   "xsdivqpo %0,%1,%2"
14431   [(set_attr "type" "vecdiv")
14432    (set_attr "size" "128")])
14434 (define_insn "sqrt<mode>2_odd"
14435   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14436         (unspec:IEEE128
14437          [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14438          UNSPEC_SQRT_ROUND_TO_ODD))]
14439   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14440    "xssqrtqpo %0,%1"
14441   [(set_attr "type" "vecdiv")
14442    (set_attr "size" "128")])
14444 (define_insn "fma<mode>4_odd"
14445   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14446         (unspec:IEEE128
14447          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14448           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14449           (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14450          UNSPEC_FMA_ROUND_TO_ODD))]
14451   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14452   "xsmaddqpo %0,%1,%2"
14453   [(set_attr "type" "qmul")
14454    (set_attr "size" "128")])
14456 (define_insn "*fms<mode>4_odd"
14457   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14458         (unspec:IEEE128
14459          [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14460           (match_operand:IEEE128 2 "altivec_register_operand" "v")
14461           (neg:IEEE128
14462            (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14463          UNSPEC_FMA_ROUND_TO_ODD))]
14464   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14465   "xsmsubqpo %0,%1,%2"
14466   [(set_attr "type" "qmul")
14467    (set_attr "size" "128")])
14469 (define_insn "*nfma<mode>4_odd"
14470   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14471         (neg:IEEE128
14472          (unspec:IEEE128
14473           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14474            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14475            (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14476           UNSPEC_FMA_ROUND_TO_ODD)))]
14477   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14478   "xsnmaddqpo %0,%1,%2"
14479   [(set_attr "type" "qmul")
14480    (set_attr "size" "128")])
14482 (define_insn "*nfms<mode>4_odd"
14483   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14484         (neg:IEEE128
14485          (unspec:IEEE128
14486           [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14487            (match_operand:IEEE128 2 "altivec_register_operand" "v")
14488            (neg:IEEE128
14489             (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14490           UNSPEC_FMA_ROUND_TO_ODD)))]
14491   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14492   "xsnmsubqpo %0,%1,%2"
14493   [(set_attr "type" "qmul")
14494    (set_attr "size" "128")])
14496 (define_insn "trunc<mode>df2_odd"
14497   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14498         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14499                    UNSPEC_TRUNC_ROUND_TO_ODD))]
14500   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14501   "xscvqpdpo %0,%1"
14502   [(set_attr "type" "vecfloat")
14503    (set_attr "size" "128")])
14505 ;; IEEE 128-bit comparisons
14506 (define_insn "*cmp<mode>_hw"
14507   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14508         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14509                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14510   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14511    "xscmpuqp %0,%1,%2"
14512   [(set_attr "type" "veccmp")
14513    (set_attr "size" "128")])
14515 ;; Miscellaneous ISA 3.0 (power9) instructions
14517 (define_insn "darn_32"
14518   [(set (match_operand:SI 0 "register_operand" "=r")
14519         (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14520   "TARGET_P9_MISC"
14521   "darn %0,0"
14522   [(set_attr "type" "integer")])
14524 (define_insn "darn_raw"
14525   [(set (match_operand:DI 0 "register_operand" "=r")
14526         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14527   "TARGET_P9_MISC && TARGET_64BIT"
14528   "darn %0,2"
14529   [(set_attr "type" "integer")])
14531 (define_insn "darn"
14532   [(set (match_operand:DI 0 "register_operand" "=r")
14533         (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14534   "TARGET_P9_MISC && TARGET_64BIT"
14535   "darn %0,1"
14536   [(set_attr "type" "integer")])
14538 ;; Test byte within range.
14540 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14541 ;; represents a byte whose value is ignored in this context and
14542 ;; vv, the least significant byte, holds the byte value that is to
14543 ;; be tested for membership within the range specified by operand 2.
14544 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14546 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14547 ;; vv <= hi.  Otherwise, set register operand 0 to 0.
14549 ;; Though the instructions to which this expansion maps operate on
14550 ;; 64-bit registers, the current implementation only operates on
14551 ;; SI-mode operands as the high-order bits provide no information
14552 ;; that is not already available in the low-order bits.  To avoid the
14553 ;; costs of data widening operations, future enhancements might allow
14554 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14555 (define_expand "cmprb"
14556   [(set (match_dup 3)
14557         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14558                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14559          UNSPEC_CMPRB))
14560    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14561         (if_then_else:SI (lt (match_dup 3)
14562                              (const_int 0))
14563                          (const_int -1)
14564                          (if_then_else (gt (match_dup 3)
14565                                            (const_int 0))
14566                                        (const_int 1)
14567                                        (const_int 0))))]
14568   "TARGET_P9_MISC"
14570   operands[3] = gen_reg_rtx (CCmode);
14573 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14574 ;; represents a byte whose value is ignored in this context and
14575 ;; vv, the least significant byte, holds the byte value that is to
14576 ;; be tested for membership within the range specified by operand 2.
14577 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14579 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14580 ;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
14581 ;; 3 bits of the target CR register are all set to 0.
14582 (define_insn "*cmprb_internal"
14583   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14584         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14585                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14586          UNSPEC_CMPRB))]
14587   "TARGET_P9_MISC"
14588   "cmprb %0,0,%1,%2"
14589   [(set_attr "type" "logical")])
14591 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14592 ;; register operand 1 is on.  Otherwise, set operand 0 register to 1
14593 ;; if the GT bit (0x4) of condition register operand 1 is on.
14594 ;; Otherwise, set operand 0 to 0.  Note that the result stored into
14595 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14596 ;; within condition register operand 1.
14597 (define_insn "setb_signed"
14598    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14599          (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14600                               (const_int 0))
14601                           (const_int -1)
14602                           (if_then_else (gt (match_dup 1)
14603                                             (const_int 0))
14604                                         (const_int 1)
14605                                         (const_int 0))))]
14606   "TARGET_P9_MISC"
14607   "setb %0,%1"
14608   [(set_attr "type" "logical")])
14610 (define_insn "setb_unsigned"
14611    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14612          (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14613                               (const_int 0))
14614                           (const_int -1)
14615                           (if_then_else (gtu (match_dup 1)
14616                                             (const_int 0))
14617                                         (const_int 1)
14618                                         (const_int 0))))]
14619   "TARGET_P9_MISC"
14620   "setb %0,%1"
14621   [(set_attr "type" "logical")])
14623 ;; Test byte within two ranges.
14625 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14626 ;; represents a byte whose value is ignored in this context and
14627 ;; vv, the least significant byte, holds the byte value that is to
14628 ;; be tested for membership within the range specified by operand 2.
14629 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14631 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14632 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
14633 ;; operand 0 to 0.
14635 ;; Though the instructions to which this expansion maps operate on
14636 ;; 64-bit registers, the current implementation only operates on
14637 ;; SI-mode operands as the high-order bits provide no information
14638 ;; that is not already available in the low-order bits.  To avoid the
14639 ;; costs of data widening operations, future enhancements might allow
14640 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14641 (define_expand "cmprb2"
14642   [(set (match_dup 3)
14643         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14644                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14645          UNSPEC_CMPRB2))
14646    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14647         (if_then_else:SI (lt (match_dup 3)
14648                              (const_int 0))
14649                          (const_int -1)
14650                          (if_then_else (gt (match_dup 3)
14651                                            (const_int 0))
14652                                        (const_int 1)
14653                                        (const_int 0))))]
14654   "TARGET_P9_MISC"
14656   operands[3] = gen_reg_rtx (CCmode);
14659 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14660 ;; represents a byte whose value is ignored in this context and
14661 ;; vv, the least significant byte, holds the byte value that is to
14662 ;; be tested for membership within the ranges specified by operand 2.
14663 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14665 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14666 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14667 ;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
14668 ;; CR register are all set to 0.
14669 (define_insn "*cmprb2_internal"
14670   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14671         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14672                     (match_operand:SI 2 "gpc_reg_operand" "r")]
14673          UNSPEC_CMPRB2))]
14674   "TARGET_P9_MISC"
14675   "cmprb %0,1,%1,%2"
14676   [(set_attr "type" "logical")])
14678 ;; Test byte membership within set of 8 bytes.
14680 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14681 ;; represents a byte whose value is ignored in this context and
14682 ;; vv, the least significant byte, holds the byte value that is to
14683 ;; be tested for membership within the set specified by operand 2.
14684 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14686 ;; Return in target register operand 0 a value of 1 if vv equals one
14687 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
14688 ;; register operand 0 to 0.  Note that the 8 byte values held within
14689 ;; operand 2 need not be unique.
14691 ;; Though the instructions to which this expansion maps operate on
14692 ;; 64-bit registers, the current implementation requires that operands
14693 ;; 0 and 1 have mode SI as the high-order bits provide no information
14694 ;; that is not already available in the low-order bits.  To avoid the
14695 ;; costs of data widening operations, future enhancements might allow
14696 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14697 (define_expand "cmpeqb"
14698   [(set (match_dup 3)
14699         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14700                     (match_operand:DI 2 "gpc_reg_operand" "r")]
14701          UNSPEC_CMPEQB))
14702    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14703         (if_then_else:SI (lt (match_dup 3)
14704                              (const_int 0))
14705                          (const_int -1)
14706                          (if_then_else (gt (match_dup 3)
14707                                            (const_int 0))
14708                                        (const_int 1)
14709                                        (const_int 0))))]
14710   "TARGET_P9_MISC && TARGET_64BIT"
14712   operands[3] = gen_reg_rtx (CCmode);
14715 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14716 ;; represents a byte whose value is ignored in this context and
14717 ;; vv, the least significant byte, holds the byte value that is to
14718 ;; be tested for membership within the set specified by operand 2.
14719 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14721 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14722 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
14723 ;; set the GT bit to zero.  The other 3 bits of the target CR register
14724 ;; are all set to 0.
14725 (define_insn "*cmpeqb_internal"
14726   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14727          (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14728                      (match_operand:DI 2 "gpc_reg_operand" "r")]
14729           UNSPEC_CMPEQB))]
14730   "TARGET_P9_MISC && TARGET_64BIT"
14731   "cmpeqb %0,%1,%2"
14732   [(set_attr "type" "logical")])
14735 (include "sync.md")
14736 (include "vector.md")
14737 (include "vsx.md")
14738 (include "altivec.md")
14739 (include "dfp.md")
14740 (include "crypto.md")
14741 (include "htm.md")